summaryrefslogtreecommitdiff
path: root/hw/arm
diff options
context:
space:
mode:
authorSeokYeon Hwang <syeon.hwang@samsung.com>2017-06-28 16:20:50 +0900
committerSeokYeon Hwang <syeon.hwang@samsung.com>2017-06-28 16:21:16 +0900
commite6230f92c2a7c924f4092b877ee70a74f76e6841 (patch)
tree3f6f4a364da163b80c9669f903eda6f8aeb4d19b /hw/arm
parente9775ba331166fc2de29a387b1070281c8ec0985 (diff)
parent6ca9395b240883513b16a1875a7080b081612c57 (diff)
downloadqemu-e6230f92c2a7c924f4092b877ee70a74f76e6841.tar.gz
qemu-e6230f92c2a7c924f4092b877ee70a74f76e6841.tar.bz2
qemu-e6230f92c2a7c924f4092b877ee70a74f76e6841.zip
Merge spin into tizen
Change-Id: I00f8d0dbf2d26f3c9c6754b9f1d986355037f5bb
Diffstat (limited to 'hw/arm')
-rw-r--r--hw/arm/Makefile.objs2
-rw-r--r--hw/arm/aspeed.c197
-rw-r--r--hw/arm/aspeed_soc.c276
-rw-r--r--hw/arm/ast2400.c214
-rw-r--r--hw/arm/boot.c21
-rw-r--r--hw/arm/cubieboard.c1
-rw-r--r--hw/arm/fsl-imx25.c2
-rw-r--r--hw/arm/fsl-imx31.c2
-rw-r--r--hw/arm/fsl-imx6.c2
-rw-r--r--hw/arm/integratorcp.c35
-rw-r--r--hw/arm/mainstone.c5
-rw-r--r--hw/arm/musicpal.c90
-rw-r--r--hw/arm/nseries.c3
-rw-r--r--hw/arm/omap2.c18
-rw-r--r--hw/arm/palmetto-bmc.c102
-rw-r--r--hw/arm/pxa2xx.c27
-rw-r--r--hw/arm/pxa2xx_gpio.c25
-rw-r--r--hw/arm/spitz.c13
-rw-r--r--hw/arm/stm32f205_soc.c92
-rw-r--r--hw/arm/strongarm.c39
-rw-r--r--hw/arm/sysbus-fdt.c4
-rw-r--r--hw/arm/tosa.c12
-rw-r--r--hw/arm/versatilepb.c9
-rw-r--r--hw/arm/virt-acpi-build.c93
-rw-r--r--hw/arm/virt.c103
-rw-r--r--hw/arm/xlnx-zynqmp.c2
26 files changed, 902 insertions, 487 deletions
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index f36884a23a..65022d0df2 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -45,4 +45,4 @@ obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
-obj-$(CONFIG_ASPEED_SOC) += ast2400.o palmetto-bmc.o
+obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
new file mode 100644
index 0000000000..c7206fda6d
--- /dev/null
+++ b/hw/arm/aspeed.c
@@ -0,0 +1,197 @@
+/*
+ * OpenPOWER Palmetto BMC
+ *
+ * Andrew Jeffery <andrew@aj.id.au>
+ *
+ * Copyright 2016 IBM Corp.
+ *
+ * This code is licensed under the GPL version 2 or later. See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "cpu.h"
+#include "exec/address-spaces.h"
+#include "hw/arm/arm.h"
+#include "hw/arm/aspeed_soc.h"
+#include "hw/boards.h"
+#include "qemu/log.h"
+#include "sysemu/block-backend.h"
+#include "sysemu/blockdev.h"
+
+static struct arm_boot_info aspeed_board_binfo = {
+ .board_id = -1, /* device-tree-only board */
+ .nb_cpus = 1,
+};
+
+typedef struct AspeedBoardState {
+ AspeedSoCState soc;
+ MemoryRegion ram;
+} AspeedBoardState;
+
+typedef struct AspeedBoardConfig {
+ const char *soc_name;
+ uint32_t hw_strap1;
+} AspeedBoardConfig;
+
+enum {
+ PALMETTO_BMC,
+ AST2500_EVB,
+};
+
+#define PALMETTO_BMC_HW_STRAP1 ( \
+ SCU_AST2400_HW_STRAP_DRAM_SIZE(DRAM_SIZE_256MB) | \
+ SCU_AST2400_HW_STRAP_DRAM_CONFIG(2 /* DDR3 with CL=6, CWL=5 */) | \
+ SCU_AST2400_HW_STRAP_ACPI_DIS | \
+ SCU_AST2400_HW_STRAP_SET_CLK_SOURCE(AST2400_CLK_48M_IN) | \
+ SCU_HW_STRAP_VGA_CLASS_CODE | \
+ SCU_HW_STRAP_LPC_RESET_PIN | \
+ SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_M_S_EN) | \
+ SCU_AST2400_HW_STRAP_SET_CPU_AHB_RATIO(AST2400_CPU_AHB_RATIO_2_1) | \
+ SCU_HW_STRAP_SPI_WIDTH | \
+ SCU_HW_STRAP_VGA_SIZE_SET(VGA_16M_DRAM) | \
+ SCU_AST2400_HW_STRAP_BOOT_MODE(AST2400_SPI_BOOT))
+
+#define AST2500_EVB_HW_STRAP1 (( \
+ AST2500_HW_STRAP1_DEFAULTS | \
+ SCU_AST2500_HW_STRAP_SPI_AUTOFETCH_ENABLE | \
+ SCU_AST2500_HW_STRAP_GPIO_STRAP_ENABLE | \
+ SCU_AST2500_HW_STRAP_UART_DEBUG | \
+ SCU_AST2500_HW_STRAP_DDR4_ENABLE | \
+ SCU_HW_STRAP_MAC1_RGMII | \
+ SCU_HW_STRAP_MAC0_RGMII) & \
+ ~SCU_HW_STRAP_2ND_BOOT_WDT)
+
+static const AspeedBoardConfig aspeed_boards[] = {
+ [PALMETTO_BMC] = { "ast2400-a0", PALMETTO_BMC_HW_STRAP1 },
+ [AST2500_EVB] = { "ast2500-a1", AST2500_EVB_HW_STRAP1 },
+};
+
+static void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
+ Error **errp)
+{
+ int i ;
+
+ for (i = 0; i < s->num_cs; ++i) {
+ AspeedSMCFlash *fl = &s->flashes[i];
+ DriveInfo *dinfo = drive_get_next(IF_MTD);
+ qemu_irq cs_line;
+
+ /*
+ * FIXME: check that we are not using a flash module exceeding
+ * the controller segment size
+ */
+ fl->flash = ssi_create_slave_no_init(s->spi, flashtype);
+ if (dinfo) {
+ qdev_prop_set_drive(fl->flash, "drive", blk_by_legacy_dinfo(dinfo),
+ errp);
+ }
+ qdev_init_nofail(fl->flash);
+
+ cs_line = qdev_get_gpio_in_named(fl->flash, SSI_GPIO_CS, 0);
+ sysbus_connect_irq(SYS_BUS_DEVICE(s), i + 1, cs_line);
+ }
+}
+
+static void aspeed_board_init(MachineState *machine,
+ const AspeedBoardConfig *cfg)
+{
+ AspeedBoardState *bmc;
+ AspeedSoCClass *sc;
+
+ bmc = g_new0(AspeedBoardState, 1);
+ object_initialize(&bmc->soc, (sizeof(bmc->soc)), cfg->soc_name);
+ object_property_add_child(OBJECT(machine), "soc", OBJECT(&bmc->soc),
+ &error_abort);
+
+ sc = ASPEED_SOC_GET_CLASS(&bmc->soc);
+
+ object_property_set_int(OBJECT(&bmc->soc), ram_size, "ram-size",
+ &error_abort);
+ object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap1, "hw-strap1",
+ &error_abort);
+ object_property_set_bool(OBJECT(&bmc->soc), true, "realized",
+ &error_abort);
+
+ /*
+ * Allocate RAM after the memory controller has checked the size
+ * was valid. If not, a default value is used.
+ */
+ ram_size = object_property_get_int(OBJECT(&bmc->soc), "ram-size",
+ &error_abort);
+
+ memory_region_allocate_system_memory(&bmc->ram, NULL, "ram", ram_size);
+ memory_region_add_subregion(get_system_memory(), sc->info->sdram_base,
+ &bmc->ram);
+ object_property_add_const_link(OBJECT(&bmc->soc), "ram", OBJECT(&bmc->ram),
+ &error_abort);
+
+ aspeed_board_init_flashes(&bmc->soc.fmc, "n25q256a", &error_abort);
+ aspeed_board_init_flashes(&bmc->soc.spi[0], "mx25l25635e", &error_abort);
+
+ aspeed_board_binfo.kernel_filename = machine->kernel_filename;
+ aspeed_board_binfo.initrd_filename = machine->initrd_filename;
+ aspeed_board_binfo.kernel_cmdline = machine->kernel_cmdline;
+ aspeed_board_binfo.ram_size = ram_size;
+ aspeed_board_binfo.loader_start = sc->info->sdram_base;
+
+ arm_load_kernel(ARM_CPU(first_cpu), &aspeed_board_binfo);
+}
+
+static void palmetto_bmc_init(MachineState *machine)
+{
+ aspeed_board_init(machine, &aspeed_boards[PALMETTO_BMC]);
+}
+
+static void palmetto_bmc_class_init(ObjectClass *oc, void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
+ mc->desc = "OpenPOWER Palmetto BMC (ARM926EJ-S)";
+ mc->init = palmetto_bmc_init;
+ mc->max_cpus = 1;
+ mc->no_sdcard = 1;
+ mc->no_floppy = 1;
+ mc->no_cdrom = 1;
+ mc->no_parallel = 1;
+}
+
+static const TypeInfo palmetto_bmc_type = {
+ .name = MACHINE_TYPE_NAME("palmetto-bmc"),
+ .parent = TYPE_MACHINE,
+ .class_init = palmetto_bmc_class_init,
+};
+
+static void ast2500_evb_init(MachineState *machine)
+{
+ aspeed_board_init(machine, &aspeed_boards[AST2500_EVB]);
+}
+
+static void ast2500_evb_class_init(ObjectClass *oc, void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
+ mc->desc = "Aspeed AST2500 EVB (ARM1176)";
+ mc->init = ast2500_evb_init;
+ mc->max_cpus = 1;
+ mc->no_sdcard = 1;
+ mc->no_floppy = 1;
+ mc->no_cdrom = 1;
+ mc->no_parallel = 1;
+}
+
+static const TypeInfo ast2500_evb_type = {
+ .name = MACHINE_TYPE_NAME("ast2500-evb"),
+ .parent = TYPE_MACHINE,
+ .class_init = ast2500_evb_class_init,
+};
+
+static void aspeed_machine_init(void)
+{
+ type_register_static(&palmetto_bmc_type);
+ type_register_static(&ast2500_evb_type);
+}
+
+type_init(aspeed_machine_init)
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
new file mode 100644
index 0000000000..e14f5c217e
--- /dev/null
+++ b/hw/arm/aspeed_soc.c
@@ -0,0 +1,276 @@
+/*
+ * ASPEED SoC family
+ *
+ * Andrew Jeffery <andrew@aj.id.au>
+ * Jeremy Kerr <jk@ozlabs.org>
+ *
+ * Copyright 2016 IBM Corp.
+ *
+ * This code is licensed under the GPL version 2 or later. See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "cpu.h"
+#include "exec/address-spaces.h"
+#include "hw/arm/aspeed_soc.h"
+#include "hw/char/serial.h"
+#include "qemu/log.h"
+#include "hw/i2c/aspeed_i2c.h"
+
+#define ASPEED_SOC_UART_5_BASE 0x00184000
+#define ASPEED_SOC_IOMEM_SIZE 0x00200000
+#define ASPEED_SOC_IOMEM_BASE 0x1E600000
+#define ASPEED_SOC_FMC_BASE 0x1E620000
+#define ASPEED_SOC_SPI_BASE 0x1E630000
+#define ASPEED_SOC_SPI2_BASE 0x1E631000
+#define ASPEED_SOC_VIC_BASE 0x1E6C0000
+#define ASPEED_SOC_SDMC_BASE 0x1E6E0000
+#define ASPEED_SOC_SCU_BASE 0x1E6E2000
+#define ASPEED_SOC_TIMER_BASE 0x1E782000
+#define ASPEED_SOC_I2C_BASE 0x1E78A000
+
+static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
+static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
+
+#define AST2400_SDRAM_BASE 0x40000000
+#define AST2500_SDRAM_BASE 0x80000000
+
+static const hwaddr aspeed_soc_ast2400_spi_bases[] = { ASPEED_SOC_SPI_BASE };
+static const char *aspeed_soc_ast2400_typenames[] = { "aspeed.smc.spi" };
+
+static const hwaddr aspeed_soc_ast2500_spi_bases[] = { ASPEED_SOC_SPI_BASE,
+ ASPEED_SOC_SPI2_BASE};
+static const char *aspeed_soc_ast2500_typenames[] = {
+ "aspeed.smc.ast2500-spi1", "aspeed.smc.ast2500-spi2" };
+
+static const AspeedSoCInfo aspeed_socs[] = {
+ { "ast2400-a0", "arm926", AST2400_A0_SILICON_REV, AST2400_SDRAM_BASE,
+ 1, aspeed_soc_ast2400_spi_bases,
+ "aspeed.smc.fmc", aspeed_soc_ast2400_typenames },
+ { "ast2400", "arm926", AST2400_A0_SILICON_REV, AST2400_SDRAM_BASE,
+ 1, aspeed_soc_ast2400_spi_bases,
+ "aspeed.smc.fmc", aspeed_soc_ast2400_typenames },
+ { "ast2500-a1", "arm1176", AST2500_A1_SILICON_REV, AST2500_SDRAM_BASE,
+ 2, aspeed_soc_ast2500_spi_bases,
+ "aspeed.smc.ast2500-fmc", aspeed_soc_ast2500_typenames },
+};
+
+/*
+ * IO handlers: simply catch any reads/writes to IO addresses that aren't
+ * handled by a device mapping.
+ */
+
+static uint64_t aspeed_soc_io_read(void *p, hwaddr offset, unsigned size)
+{
+ qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n",
+ __func__, offset, size);
+ return 0;
+}
+
+static void aspeed_soc_io_write(void *opaque, hwaddr offset, uint64_t value,
+ unsigned size)
+{
+ qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " <- 0x%" PRIx64 " [%u]\n",
+ __func__, offset, value, size);
+}
+
+static const MemoryRegionOps aspeed_soc_io_ops = {
+ .read = aspeed_soc_io_read,
+ .write = aspeed_soc_io_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void aspeed_soc_init(Object *obj)
+{
+ AspeedSoCState *s = ASPEED_SOC(obj);
+ AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+ int i;
+
+ s->cpu = cpu_arm_init(sc->info->cpu_model);
+
+ object_initialize(&s->vic, sizeof(s->vic), TYPE_ASPEED_VIC);
+ object_property_add_child(obj, "vic", OBJECT(&s->vic), NULL);
+ qdev_set_parent_bus(DEVICE(&s->vic), sysbus_get_default());
+
+ object_initialize(&s->timerctrl, sizeof(s->timerctrl), TYPE_ASPEED_TIMER);
+ object_property_add_child(obj, "timerctrl", OBJECT(&s->timerctrl), NULL);
+ qdev_set_parent_bus(DEVICE(&s->timerctrl), sysbus_get_default());
+
+ object_initialize(&s->i2c, sizeof(s->i2c), TYPE_ASPEED_I2C);
+ object_property_add_child(obj, "i2c", OBJECT(&s->i2c), NULL);
+ qdev_set_parent_bus(DEVICE(&s->i2c), sysbus_get_default());
+
+ object_initialize(&s->scu, sizeof(s->scu), TYPE_ASPEED_SCU);
+ object_property_add_child(obj, "scu", OBJECT(&s->scu), NULL);
+ qdev_set_parent_bus(DEVICE(&s->scu), sysbus_get_default());
+ qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev",
+ sc->info->silicon_rev);
+ object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu),
+ "hw-strap1", &error_abort);
+ object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu),
+ "hw-strap2", &error_abort);
+
+ object_initialize(&s->fmc, sizeof(s->fmc), sc->info->fmc_typename);
+ object_property_add_child(obj, "fmc", OBJECT(&s->fmc), NULL);
+ qdev_set_parent_bus(DEVICE(&s->fmc), sysbus_get_default());
+
+ for (i = 0; i < sc->info->spis_num; i++) {
+ object_initialize(&s->spi[i], sizeof(s->spi[i]),
+ sc->info->spi_typename[i]);
+ object_property_add_child(obj, "spi", OBJECT(&s->spi[i]), NULL);
+ qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
+ }
+
+ object_initialize(&s->sdmc, sizeof(s->sdmc), TYPE_ASPEED_SDMC);
+ object_property_add_child(obj, "sdmc", OBJECT(&s->sdmc), NULL);
+ qdev_set_parent_bus(DEVICE(&s->sdmc), sysbus_get_default());
+ qdev_prop_set_uint32(DEVICE(&s->sdmc), "silicon-rev",
+ sc->info->silicon_rev);
+ object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
+ "ram-size", &error_abort);
+}
+
+static void aspeed_soc_realize(DeviceState *dev, Error **errp)
+{
+ int i;
+ AspeedSoCState *s = ASPEED_SOC(dev);
+ AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+ Error *err = NULL, *local_err = NULL;
+
+ /* IO space */
+ memory_region_init_io(&s->iomem, NULL, &aspeed_soc_io_ops, NULL,
+ "aspeed_soc.io", ASPEED_SOC_IOMEM_SIZE);
+ memory_region_add_subregion_overlap(get_system_memory(),
+ ASPEED_SOC_IOMEM_BASE, &s->iomem, -1);
+
+ /* VIC */
+ object_property_set_bool(OBJECT(&s->vic), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, ASPEED_SOC_VIC_BASE);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0,
+ qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1,
+ qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
+
+ /* Timer */
+ object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0, ASPEED_SOC_TIMER_BASE);
+ for (i = 0; i < ARRAY_SIZE(timer_irqs); i++) {
+ qemu_irq irq = qdev_get_gpio_in(DEVICE(&s->vic), timer_irqs[i]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
+ }
+
+ /* SCU */
+ object_property_set_bool(OBJECT(&s->scu), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, ASPEED_SOC_SCU_BASE);
+
+ /* UART - attach an 8250 to the IO space as our UART5 */
+ if (serial_hds[0]) {
+ qemu_irq uart5 = qdev_get_gpio_in(DEVICE(&s->vic), uart_irqs[4]);
+ serial_mm_init(&s->iomem, ASPEED_SOC_UART_5_BASE, 2,
+ uart5, 38400, serial_hds[0], DEVICE_LITTLE_ENDIAN);
+ }
+
+ /* I2C */
+ object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, ASPEED_SOC_I2C_BASE);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0,
+ qdev_get_gpio_in(DEVICE(&s->vic), 12));
+
+ /* FMC */
+ object_property_set_int(OBJECT(&s->fmc), 1, "num-cs", &err);
+ object_property_set_bool(OBJECT(&s->fmc), true, "realized", &local_err);
+ error_propagate(&err, local_err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, ASPEED_SOC_FMC_BASE);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1,
+ s->fmc.ctrl->flash_window_base);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0,
+ qdev_get_gpio_in(DEVICE(&s->vic), 19));
+
+ /* SPI */
+ for (i = 0; i < sc->info->spis_num; i++) {
+ object_property_set_int(OBJECT(&s->spi[i]), 1, "num-cs", &err);
+ object_property_set_bool(OBJECT(&s->spi[i]), true, "realized",
+ &local_err);
+ error_propagate(&err, local_err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, sc->info->spi_bases[i]);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 1,
+ s->spi[i].ctrl->flash_window_base);
+ }
+
+ /* SDMC - SDRAM Memory Controller */
+ object_property_set_bool(OBJECT(&s->sdmc), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, ASPEED_SOC_SDMC_BASE);
+}
+
+static void aspeed_soc_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc);
+
+ sc->info = (AspeedSoCInfo *) data;
+ dc->realize = aspeed_soc_realize;
+
+ /*
+ * Reason: creates an ARM CPU, thus use after free(), see
+ * arm_cpu_class_init()
+ */
+ dc->cannot_destroy_with_object_finalize_yet = true;
+}
+
+static const TypeInfo aspeed_soc_type_info = {
+ .name = TYPE_ASPEED_SOC,
+ .parent = TYPE_DEVICE,
+ .instance_init = aspeed_soc_init,
+ .instance_size = sizeof(AspeedSoCState),
+ .class_size = sizeof(AspeedSoCClass),
+ .abstract = true,
+};
+
+static void aspeed_soc_register_types(void)
+{
+ int i;
+
+ type_register_static(&aspeed_soc_type_info);
+ for (i = 0; i < ARRAY_SIZE(aspeed_socs); ++i) {
+ TypeInfo ti = {
+ .name = aspeed_socs[i].name,
+ .parent = TYPE_ASPEED_SOC,
+ .class_init = aspeed_soc_class_init,
+ .class_data = (void *) &aspeed_socs[i],
+ };
+ type_register(&ti);
+ }
+}
+
+type_init(aspeed_soc_register_types)
diff --git a/hw/arm/ast2400.c b/hw/arm/ast2400.c
deleted file mode 100644
index 326fdb36ee..0000000000
--- a/hw/arm/ast2400.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * AST2400 SoC
- *
- * Andrew Jeffery <andrew@aj.id.au>
- * Jeremy Kerr <jk@ozlabs.org>
- *
- * Copyright 2016 IBM Corp.
- *
- * This code is licensed under the GPL version 2 or later. See
- * the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "exec/address-spaces.h"
-#include "hw/arm/ast2400.h"
-#include "hw/char/serial.h"
-#include "qemu/log.h"
-#include "hw/i2c/aspeed_i2c.h"
-
-#define AST2400_UART_5_BASE 0x00184000
-#define AST2400_IOMEM_SIZE 0x00200000
-#define AST2400_IOMEM_BASE 0x1E600000
-#define AST2400_SMC_BASE AST2400_IOMEM_BASE /* Legacy SMC */
-#define AST2400_FMC_BASE 0X1E620000
-#define AST2400_SPI_BASE 0X1E630000
-#define AST2400_VIC_BASE 0x1E6C0000
-#define AST2400_SCU_BASE 0x1E6E2000
-#define AST2400_TIMER_BASE 0x1E782000
-#define AST2400_I2C_BASE 0x1E78A000
-
-#define AST2400_FMC_FLASH_BASE 0x20000000
-#define AST2400_SPI_FLASH_BASE 0x30000000
-
-static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
-static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
-
-/*
- * IO handlers: simply catch any reads/writes to IO addresses that aren't
- * handled by a device mapping.
- */
-
-static uint64_t ast2400_io_read(void *p, hwaddr offset, unsigned size)
-{
- qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n",
- __func__, offset, size);
- return 0;
-}
-
-static void ast2400_io_write(void *opaque, hwaddr offset, uint64_t value,
- unsigned size)
-{
- qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " <- 0x%" PRIx64 " [%u]\n",
- __func__, offset, value, size);
-}
-
-static const MemoryRegionOps ast2400_io_ops = {
- .read = ast2400_io_read,
- .write = ast2400_io_write,
- .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-static void ast2400_init(Object *obj)
-{
- AST2400State *s = AST2400(obj);
-
- s->cpu = cpu_arm_init("arm926");
-
- object_initialize(&s->vic, sizeof(s->vic), TYPE_ASPEED_VIC);
- object_property_add_child(obj, "vic", OBJECT(&s->vic), NULL);
- qdev_set_parent_bus(DEVICE(&s->vic), sysbus_get_default());
-
- object_initialize(&s->timerctrl, sizeof(s->timerctrl), TYPE_ASPEED_TIMER);
- object_property_add_child(obj, "timerctrl", OBJECT(&s->timerctrl), NULL);
- qdev_set_parent_bus(DEVICE(&s->timerctrl), sysbus_get_default());
-
- object_initialize(&s->i2c, sizeof(s->i2c), TYPE_ASPEED_I2C);
- object_property_add_child(obj, "i2c", OBJECT(&s->i2c), NULL);
- qdev_set_parent_bus(DEVICE(&s->i2c), sysbus_get_default());
-
- object_initialize(&s->scu, sizeof(s->scu), TYPE_ASPEED_SCU);
- object_property_add_child(obj, "scu", OBJECT(&s->scu), NULL);
- qdev_set_parent_bus(DEVICE(&s->scu), sysbus_get_default());
- qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev",
- AST2400_A0_SILICON_REV);
- object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu),
- "hw-strap1", &error_abort);
- object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu),
- "hw-strap2", &error_abort);
-
- object_initialize(&s->smc, sizeof(s->smc), "aspeed.smc.fmc");
- object_property_add_child(obj, "smc", OBJECT(&s->smc), NULL);
- qdev_set_parent_bus(DEVICE(&s->smc), sysbus_get_default());
-
- object_initialize(&s->spi, sizeof(s->spi), "aspeed.smc.spi");
- object_property_add_child(obj, "spi", OBJECT(&s->spi), NULL);
- qdev_set_parent_bus(DEVICE(&s->spi), sysbus_get_default());
-}
-
-static void ast2400_realize(DeviceState *dev, Error **errp)
-{
- int i;
- AST2400State *s = AST2400(dev);
- Error *err = NULL, *local_err = NULL;
-
- /* IO space */
- memory_region_init_io(&s->iomem, NULL, &ast2400_io_ops, NULL,
- "ast2400.io", AST2400_IOMEM_SIZE);
- memory_region_add_subregion_overlap(get_system_memory(), AST2400_IOMEM_BASE,
- &s->iomem, -1);
-
- /* VIC */
- object_property_set_bool(OBJECT(&s->vic), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, AST2400_VIC_BASE);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0,
- qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1,
- qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
-
- /* Timer */
- object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0, AST2400_TIMER_BASE);
- for (i = 0; i < ARRAY_SIZE(timer_irqs); i++) {
- qemu_irq irq = qdev_get_gpio_in(DEVICE(&s->vic), timer_irqs[i]);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
- }
-
- /* SCU */
- object_property_set_bool(OBJECT(&s->scu), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, AST2400_SCU_BASE);
-
- /* UART - attach an 8250 to the IO space as our UART5 */
- if (serial_hds[0]) {
- qemu_irq uart5 = qdev_get_gpio_in(DEVICE(&s->vic), uart_irqs[4]);
- serial_mm_init(&s->iomem, AST2400_UART_5_BASE, 2,
- uart5, 38400, serial_hds[0], DEVICE_LITTLE_ENDIAN);
- }
-
- /* I2C */
- object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, AST2400_I2C_BASE);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0,
- qdev_get_gpio_in(DEVICE(&s->vic), 12));
-
- /* SMC */
- object_property_set_int(OBJECT(&s->smc), 1, "num-cs", &err);
- object_property_set_bool(OBJECT(&s->smc), true, "realized", &local_err);
- error_propagate(&err, local_err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->smc), 0, AST2400_FMC_BASE);
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->smc), 1, AST2400_FMC_FLASH_BASE);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->smc), 0,
- qdev_get_gpio_in(DEVICE(&s->vic), 19));
-
- /* SPI */
- object_property_set_int(OBJECT(&s->spi), 1, "num-cs", &err);
- object_property_set_bool(OBJECT(&s->spi), true, "realized", &local_err);
- error_propagate(&err, local_err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi), 0, AST2400_SPI_BASE);
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi), 1, AST2400_SPI_FLASH_BASE);
-}
-
-static void ast2400_class_init(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
-
- dc->realize = ast2400_realize;
-
- /*
- * Reason: creates an ARM CPU, thus use after free(), see
- * arm_cpu_class_init()
- */
- dc->cannot_destroy_with_object_finalize_yet = true;
-}
-
-static const TypeInfo ast2400_type_info = {
- .name = TYPE_AST2400,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(AST2400State),
- .instance_init = ast2400_init,
- .class_init = ast2400_class_init,
-};
-
-static void ast2400_register_types(void)
-{
- type_register_static(&ast2400_type_info);
-}
-
-type_init(ast2400_register_types)
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 1b913a43ca..ff621e4b6a 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -9,6 +9,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
+#include <libfdt.h>
#include "hw/hw.h"
#include "hw/arm/arm.h"
#include "hw/arm/linux-boot-if.h"
@@ -486,6 +487,17 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
g_free(nodename);
}
} else {
+ Error *err = NULL;
+
+ rc = fdt_path_offset(fdt, "/memory");
+ if (rc < 0) {
+ qemu_fdt_add_subnode(fdt, "/memory");
+ }
+
+ if (!qemu_fdt_getprop(fdt, "/memory", "device_type", NULL, &err)) {
+ qemu_fdt_setprop_string(fdt, "/memory", "device_type", "memory");
+ }
+
rc = qemu_fdt_setprop_sized_cells(fdt, "/memory", "reg",
acells, binfo->loader_start,
scells, binfo->ram_size);
@@ -495,6 +507,11 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
}
}
+ rc = fdt_path_offset(fdt, "/chosen");
+ if (rc < 0) {
+ qemu_fdt_add_subnode(fdt, "/chosen");
+ }
+
if (binfo->kernel_cmdline && *binfo->kernel_cmdline) {
rc = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
binfo->kernel_cmdline);
@@ -773,6 +790,8 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
*/
assert(!(info->secure_board_setup && kvm_enabled()));
+ info->dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
+
/* Load the kernel. */
if (!info->kernel_filename || info->firmware_loaded) {
@@ -833,8 +852,6 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
elf_machine = EM_ARM;
}
- info->dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
-
if (!info->secondary_cpu_reset_hook) {
info->secondary_cpu_reset_hook = default_reset_secondary;
}
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
index fbd78ed01c..dd19ba3c99 100644
--- a/hw/arm/cubieboard.c
+++ b/hw/arm/cubieboard.c
@@ -74,6 +74,7 @@ static void cubieboard_init(MachineState *machine)
cubieboard_binfo.ram_size = machine->ram_size;
cubieboard_binfo.kernel_filename = machine->kernel_filename;
cubieboard_binfo.kernel_cmdline = machine->kernel_cmdline;
+ cubieboard_binfo.initrd_filename = machine->initrd_filename;
arm_load_kernel(&s->a10->cpu, &cubieboard_binfo);
}
diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index b4e358db65..7bb7be76b6 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -125,7 +125,7 @@ static void fsl_imx25_realize(DeviceState *dev, Error **errp)
if (!chr) {
char label[20];
snprintf(label, sizeof(label), "imx31.uart%d", i);
- chr = qemu_chr_new(label, "null", NULL);
+ chr = qemu_chr_new(label, "null");
}
qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", chr);
diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c
index fe204ace62..f23672b222 100644
--- a/hw/arm/fsl-imx31.c
+++ b/hw/arm/fsl-imx31.c
@@ -114,7 +114,7 @@ static void fsl_imx31_realize(DeviceState *dev, Error **errp)
if (!chr) {
char label[20];
snprintf(label, sizeof(label), "imx31.uart%d", i);
- chr = qemu_chr_new(label, "null", NULL);
+ chr = qemu_chr_new(label, "null");
}
qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", chr);
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
index 6a1bf263a5..e93532fb57 100644
--- a/hw/arm/fsl-imx6.c
+++ b/hw/arm/fsl-imx6.c
@@ -193,7 +193,7 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
if (!chr) {
char *label = g_strdup_printf("imx6.uart%d", i + 1);
- chr = qemu_chr_new(label, "null", NULL);
+ chr = qemu_chr_new(label, "null");
g_free(label);
serial_hds[i] = chr;
}
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index 96dc150025..039812a3fd 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -252,6 +252,26 @@ static void integratorcm_init(Object *obj)
/* ??? What should the high bits of this value be? */
s->cm_auxosc = 0x0007feff;
s->cm_sdram = 0x00011122;
+ memcpy(integrator_spd + 73, "QEMU-MEMORY", 11);
+ s->cm_init = 0x00000112;
+ s->cm_refcnt_offset = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24,
+ 1000);
+ memory_region_init_ram(&s->flash, obj, "integrator.flash", 0x100000,
+ &error_fatal);
+ vmstate_register_ram_global(&s->flash);
+
+ memory_region_init_io(&s->iomem, obj, &integratorcm_ops, s,
+ "integratorcm", 0x00800000);
+ sysbus_init_mmio(dev, &s->iomem);
+
+ integratorcm_do_remap(s);
+ /* ??? Save/restore. */
+}
+
+static void integratorcm_realize(DeviceState *d, Error **errp)
+{
+ IntegratorCMState *s = INTEGRATOR_CM(d);
+
if (s->memsz >= 256) {
integrator_spd[31] = 64;
s->cm_sdram |= 0x10;
@@ -267,20 +287,6 @@ static void integratorcm_init(Object *obj)
} else {
integrator_spd[31] = 2;
}
- memcpy(integrator_spd + 73, "QEMU-MEMORY", 11);
- s->cm_init = 0x00000112;
- s->cm_refcnt_offset = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24,
- 1000);
- memory_region_init_ram(&s->flash, obj, "integrator.flash", 0x100000,
- &error_fatal);
- vmstate_register_ram_global(&s->flash);
-
- memory_region_init_io(&s->iomem, obj, &integratorcm_ops, s,
- "integratorcm", 0x00800000);
- sysbus_init_mmio(dev, &s->iomem);
-
- integratorcm_do_remap(s);
- /* ??? Save/restore. */
}
/* Integrator/CP hardware emulation. */
@@ -633,6 +639,7 @@ static void core_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
dc->props = core_properties;
+ dc->realize = integratorcm_realize;
}
static const TypeInfo core_info = {
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
index 454acc5d2b..f962236cf4 100644
--- a/hw/arm/mainstone.c
+++ b/hw/arm/mainstone.c
@@ -73,8 +73,10 @@ static const struct keymap map[0xE0] = {
[0x2f] = {3,3}, /* v */
[0x11] = {3,4}, /* w */
[0x2d] = {3,5}, /* x */
+ [0x34] = {4,0}, /* . */
[0x15] = {4,2}, /* y */
[0x2c] = {4,3}, /* z */
+ [0x35] = {4,4}, /* / */
[0xc7] = {5,0}, /* Home */
[0x2a] = {5,1}, /* shift */
/*
@@ -88,7 +90,8 @@ static const struct keymap map[0xE0] = {
* Matrix position {5,4} and other keys are missing here.
* TODO: Compare with Linux code and test real hardware.
*/
- [0x1c] = {5,5}, /* enter (TODO: might be wrong) */
+ [0x1c] = {5,4}, /* enter */
+ [0x0e] = {5,5}, /* backspace */
[0xc8] = {6,0}, /* up */
[0xd0] = {6,1}, /* down */
[0xcb] = {6,2}, /* left */
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index cc50ace13d..cbbca4e17a 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -384,18 +384,24 @@ static NetClientInfo net_mv88w8618_info = {
.cleanup = eth_cleanup,
};
-static int mv88w8618_eth_init(SysBusDevice *sbd)
+static void mv88w8618_eth_init(Object *obj)
{
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
DeviceState *dev = DEVICE(sbd);
mv88w8618_eth_state *s = MV88W8618_ETH(dev);
sysbus_init_irq(sbd, &s->irq);
- s->nic = qemu_new_nic(&net_mv88w8618_info, &s->conf,
- object_get_typename(OBJECT(dev)), dev->id, s);
- memory_region_init_io(&s->iomem, OBJECT(s), &mv88w8618_eth_ops, s,
+ memory_region_init_io(&s->iomem, obj, &mv88w8618_eth_ops, s,
"mv88w8618-eth", MP_ETH_SIZE);
sysbus_init_mmio(sbd, &s->iomem);
- return 0;
+}
+
+static void mv88w8618_eth_realize(DeviceState *dev, Error **errp)
+{
+ mv88w8618_eth_state *s = MV88W8618_ETH(dev);
+
+ s->nic = qemu_new_nic(&net_mv88w8618_info, &s->conf,
+ object_get_typename(OBJECT(dev)), dev->id, s);
}
static const VMStateDescription mv88w8618_eth_vmsd = {
@@ -423,17 +429,17 @@ static Property mv88w8618_eth_properties[] = {
static void mv88w8618_eth_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = mv88w8618_eth_init;
dc->vmsd = &mv88w8618_eth_vmsd;
dc->props = mv88w8618_eth_properties;
+ dc->realize = mv88w8618_eth_realize;
}
static const TypeInfo mv88w8618_eth_info = {
.name = TYPE_MV88W8618_ETH,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(mv88w8618_eth_state),
+ .instance_init = mv88w8618_eth_init,
.class_init = mv88w8618_eth_class_init,
};
@@ -615,23 +621,26 @@ static const GraphicHwOps musicpal_gfx_ops = {
.gfx_update = lcd_refresh,
};
-static int musicpal_lcd_init(SysBusDevice *sbd)
+static void musicpal_lcd_realize(DeviceState *dev, Error **errp)
+{
+ musicpal_lcd_state *s = MUSICPAL_LCD(dev);
+ s->con = graphic_console_init(dev, 0, &musicpal_gfx_ops, s);
+ qemu_console_resize(s->con, 128 * 3, 64 * 3);
+}
+
+static void musicpal_lcd_init(Object *obj)
{
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
DeviceState *dev = DEVICE(sbd);
musicpal_lcd_state *s = MUSICPAL_LCD(dev);
s->brightness = 7;
- memory_region_init_io(&s->iomem, OBJECT(s), &musicpal_lcd_ops, s,
+ memory_region_init_io(&s->iomem, obj, &musicpal_lcd_ops, s,
"musicpal-lcd", MP_LCD_SIZE);
sysbus_init_mmio(sbd, &s->iomem);
- s->con = graphic_console_init(dev, 0, &musicpal_gfx_ops, s);
- qemu_console_resize(s->con, 128*3, 64*3);
-
qdev_init_gpio_in(dev, musicpal_lcd_gpio_brightness_in, 3);
-
- return 0;
}
static const VMStateDescription musicpal_lcd_vmsd = {
@@ -652,16 +661,16 @@ static const VMStateDescription musicpal_lcd_vmsd = {
static void musicpal_lcd_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = musicpal_lcd_init;
dc->vmsd = &musicpal_lcd_vmsd;
+ dc->realize = musicpal_lcd_realize;
}
static const TypeInfo musicpal_lcd_info = {
.name = TYPE_MUSICPAL_LCD,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(musicpal_lcd_state),
+ .instance_init = musicpal_lcd_init,
.class_init = musicpal_lcd_class_init,
};
@@ -748,16 +757,16 @@ static const MemoryRegionOps mv88w8618_pic_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
-static int mv88w8618_pic_init(SysBusDevice *dev)
+static void mv88w8618_pic_init(Object *obj)
{
+ SysBusDevice *dev = SYS_BUS_DEVICE(obj);
mv88w8618_pic_state *s = MV88W8618_PIC(dev);
qdev_init_gpio_in(DEVICE(dev), mv88w8618_pic_set_irq, 32);
sysbus_init_irq(dev, &s->parent_irq);
- memory_region_init_io(&s->iomem, OBJECT(s), &mv88w8618_pic_ops, s,
+ memory_region_init_io(&s->iomem, obj, &mv88w8618_pic_ops, s,
"musicpal-pic", MP_PIC_SIZE);
sysbus_init_mmio(dev, &s->iomem);
- return 0;
}
static const VMStateDescription mv88w8618_pic_vmsd = {
@@ -774,9 +783,7 @@ static const VMStateDescription mv88w8618_pic_vmsd = {
static void mv88w8618_pic_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = mv88w8618_pic_init;
dc->reset = mv88w8618_pic_reset;
dc->vmsd = &mv88w8618_pic_vmsd;
}
@@ -785,6 +792,7 @@ static const TypeInfo mv88w8618_pic_info = {
.name = TYPE_MV88W8618_PIC,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(mv88w8618_pic_state),
+ .instance_init = mv88w8618_pic_init,
.class_init = mv88w8618_pic_class_init,
};
@@ -837,7 +845,7 @@ static void mv88w8618_timer_init(SysBusDevice *dev, mv88w8618_timer_state *s,
s->freq = freq;
bh = qemu_bh_new(mv88w8618_timer_tick, s);
- s->ptimer = ptimer_init(bh);
+ s->ptimer = ptimer_init(bh, PTIMER_POLICY_DEFAULT);
}
static uint64_t mv88w8618_pit_read(void *opaque, hwaddr offset,
@@ -913,8 +921,9 @@ static const MemoryRegionOps mv88w8618_pit_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
-static int mv88w8618_pit_init(SysBusDevice *dev)
+static void mv88w8618_pit_init(Object *obj)
{
+ SysBusDevice *dev = SYS_BUS_DEVICE(obj);
mv88w8618_pit_state *s = MV88W8618_PIT(dev);
int i;
@@ -924,10 +933,9 @@ static int mv88w8618_pit_init(SysBusDevice *dev)
mv88w8618_timer_init(dev, &s->timer[i], 1000000);
}
- memory_region_init_io(&s->iomem, OBJECT(s), &mv88w8618_pit_ops, s,
+ memory_region_init_io(&s->iomem, obj, &mv88w8618_pit_ops, s,
"musicpal-pit", MP_PIT_SIZE);
sysbus_init_mmio(dev, &s->iomem);
- return 0;
}
static const VMStateDescription mv88w8618_timer_vmsd = {
@@ -955,9 +963,7 @@ static const VMStateDescription mv88w8618_pit_vmsd = {
static void mv88w8618_pit_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = mv88w8618_pit_init;
dc->reset = mv88w8618_pit_reset;
dc->vmsd = &mv88w8618_pit_vmsd;
}
@@ -966,6 +972,7 @@ static const TypeInfo mv88w8618_pit_info = {
.name = TYPE_MV88W8618_PIT,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(mv88w8618_pit_state),
+ .instance_init = mv88w8618_pit_init,
.class_init = mv88w8618_pit_class_init,
};
@@ -1018,15 +1025,15 @@ static const MemoryRegionOps mv88w8618_flashcfg_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
-static int mv88w8618_flashcfg_init(SysBusDevice *dev)
+static void mv88w8618_flashcfg_init(Object *obj)
{
+ SysBusDevice *dev = SYS_BUS_DEVICE(obj);
mv88w8618_flashcfg_state *s = MV88W8618_FLASHCFG(dev);
s->cfgr0 = 0xfffe4285; /* Default as set by U-Boot for 8 MB flash */
- memory_region_init_io(&s->iomem, OBJECT(s), &mv88w8618_flashcfg_ops, s,
+ memory_region_init_io(&s->iomem, obj, &mv88w8618_flashcfg_ops, s,
"musicpal-flashcfg", MP_FLASHCFG_SIZE);
sysbus_init_mmio(dev, &s->iomem);
- return 0;
}
static const VMStateDescription mv88w8618_flashcfg_vmsd = {
@@ -1042,9 +1049,7 @@ static const VMStateDescription mv88w8618_flashcfg_vmsd = {
static void mv88w8618_flashcfg_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = mv88w8618_flashcfg_init;
dc->vmsd = &mv88w8618_flashcfg_vmsd;
}
@@ -1052,6 +1057,7 @@ static const TypeInfo mv88w8618_flashcfg_info = {
.name = TYPE_MV88W8618_FLASHCFG,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(mv88w8618_flashcfg_state),
+ .instance_init = mv88w8618_flashcfg_init,
.class_init = mv88w8618_flashcfg_class_init,
};
@@ -1350,22 +1356,21 @@ static void musicpal_gpio_reset(DeviceState *d)
s->isr = 0;
}
-static int musicpal_gpio_init(SysBusDevice *sbd)
+static void musicpal_gpio_init(Object *obj)
{
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
DeviceState *dev = DEVICE(sbd);
musicpal_gpio_state *s = MUSICPAL_GPIO(dev);
sysbus_init_irq(sbd, &s->irq);
- memory_region_init_io(&s->iomem, OBJECT(s), &musicpal_gpio_ops, s,
+ memory_region_init_io(&s->iomem, obj, &musicpal_gpio_ops, s,
"musicpal-gpio", MP_GPIO_SIZE);
sysbus_init_mmio(sbd, &s->iomem);
qdev_init_gpio_out(dev, s->out, ARRAY_SIZE(s->out));
qdev_init_gpio_in(dev, musicpal_gpio_pin_event, 32);
-
- return 0;
}
static const VMStateDescription musicpal_gpio_vmsd = {
@@ -1386,9 +1391,7 @@ static const VMStateDescription musicpal_gpio_vmsd = {
static void musicpal_gpio_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = musicpal_gpio_init;
dc->reset = musicpal_gpio_reset;
dc->vmsd = &musicpal_gpio_vmsd;
}
@@ -1397,6 +1400,7 @@ static const TypeInfo musicpal_gpio_info = {
.name = TYPE_MUSICPAL_GPIO,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(musicpal_gpio_state),
+ .instance_init = musicpal_gpio_init,
.class_init = musicpal_gpio_class_init,
};
@@ -1516,12 +1520,13 @@ static void musicpal_key_event(void *opaque, int keycode)
s->kbd_extended = 0;
}
-static int musicpal_key_init(SysBusDevice *sbd)
+static void musicpal_key_init(Object *obj)
{
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
DeviceState *dev = DEVICE(sbd);
musicpal_key_state *s = MUSICPAL_KEY(dev);
- memory_region_init(&s->iomem, OBJECT(s), "dummy", 0);
+ memory_region_init(&s->iomem, obj, "dummy", 0);
sysbus_init_mmio(sbd, &s->iomem);
s->kbd_extended = 0;
@@ -1530,8 +1535,6 @@ static int musicpal_key_init(SysBusDevice *sbd)
qdev_init_gpio_out(dev, s->out, ARRAY_SIZE(s->out));
qemu_add_kbd_event_handler(musicpal_key_event, s);
-
- return 0;
}
static const VMStateDescription musicpal_key_vmsd = {
@@ -1548,9 +1551,7 @@ static const VMStateDescription musicpal_key_vmsd = {
static void musicpal_key_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = musicpal_key_init;
dc->vmsd = &musicpal_key_vmsd;
}
@@ -1558,6 +1559,7 @@ static const TypeInfo musicpal_key_info = {
.name = TYPE_MUSICPAL_KEY,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(musicpal_key_state),
+ .instance_init = musicpal_key_init,
.class_init = musicpal_key_class_init,
};
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
index fea911e3e3..c86cf80514 100644
--- a/hw/arm/nseries.c
+++ b/hw/arm/nseries.c
@@ -786,8 +786,7 @@ static void n8x0_cbus_setup(struct n800_s *s)
static void n8x0_uart_setup(struct n800_s *s)
{
- CharDriverState *radio = uart_hci_init(
- qdev_get_gpio_in(s->mpu->gpio, N8X0_BT_HOST_WKUP_GPIO));
+ CharDriverState *radio = uart_hci_init();
qdev_connect_gpio_out(s->mpu->gpio, N8X0_BT_RESET_GPIO,
csrhci_pins_get(radio)[csrhci_pin_reset]);
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
index 3a0d77714a..6f05c98d3e 100644
--- a/hw/arm/omap2.c
+++ b/hw/arm/omap2.c
@@ -621,7 +621,7 @@ struct omap_sti_s {
qemu_irq irq;
MemoryRegion iomem;
MemoryRegion iomem_fifo;
- CharDriverState *chr;
+ CharBackend chr;
uint32_t sysconfig;
uint32_t systest;
@@ -769,14 +769,17 @@ static void omap_sti_fifo_write(void *opaque, hwaddr addr,
if (ch == STI_TRACE_CONTROL_CHANNEL) {
/* Flush channel <i>value</i>. */
- qemu_chr_fe_write(s->chr, (const uint8_t *) "\r", 1);
+ /* XXX this blocks entire thread. Rewrite to use
+ * qemu_chr_fe_write and background I/O callbacks */
+ qemu_chr_fe_write_all(&s->chr, (const uint8_t *) "\r", 1);
} else if (ch == STI_TRACE_CONSOLE_CHANNEL || 1) {
if (value == 0xc0 || value == 0xc3) {
/* Open channel <i>ch</i>. */
- } else if (value == 0x00)
- qemu_chr_fe_write(s->chr, (const uint8_t *) "\n", 1);
- else
- qemu_chr_fe_write(s->chr, &byte, 1);
+ } else if (value == 0x00) {
+ qemu_chr_fe_write_all(&s->chr, (const uint8_t *) "\n", 1);
+ } else {
+ qemu_chr_fe_write_all(&s->chr, &byte, 1);
+ }
}
}
@@ -796,7 +799,8 @@ static struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta,
s->irq = irq;
omap_sti_reset(s);
- s->chr = chr ?: qemu_chr_new("null", "null", NULL);
+ qemu_chr_fe_init(&s->chr, chr ?: qemu_chr_new("null", "null"),
+ &error_abort);
memory_region_init_io(&s->iomem, NULL, &omap_sti_ops, s, "omap.sti",
omap_l4_region_size(ta, 0));
diff --git a/hw/arm/palmetto-bmc.c b/hw/arm/palmetto-bmc.c
deleted file mode 100644
index 54e29a865d..0000000000
--- a/hw/arm/palmetto-bmc.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * OpenPOWER Palmetto BMC
- *
- * Andrew Jeffery <andrew@aj.id.au>
- *
- * Copyright 2016 IBM Corp.
- *
- * This code is licensed under the GPL version 2 or later. See
- * the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "exec/address-spaces.h"
-#include "hw/arm/arm.h"
-#include "hw/arm/ast2400.h"
-#include "hw/boards.h"
-#include "qemu/log.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
-
-static struct arm_boot_info palmetto_bmc_binfo = {
- .loader_start = AST2400_SDRAM_BASE,
- .board_id = 0,
- .nb_cpus = 1,
-};
-
-typedef struct PalmettoBMCState {
- AST2400State soc;
- MemoryRegion ram;
-} PalmettoBMCState;
-
-static void palmetto_bmc_init_flashes(AspeedSMCState *s, const char *flashtype,
- Error **errp)
-{
- int i ;
-
- for (i = 0; i < s->num_cs; ++i) {
- AspeedSMCFlash *fl = &s->flashes[i];
- DriveInfo *dinfo = drive_get_next(IF_MTD);
- qemu_irq cs_line;
-
- /*
- * FIXME: check that we are not using a flash module exceeding
- * the controller segment size
- */
- fl->flash = ssi_create_slave_no_init(s->spi, flashtype);
- if (dinfo) {
- qdev_prop_set_drive(fl->flash, "drive", blk_by_legacy_dinfo(dinfo),
- errp);
- }
- qdev_init_nofail(fl->flash);
-
- cs_line = qdev_get_gpio_in_named(fl->flash, SSI_GPIO_CS, 0);
- sysbus_connect_irq(SYS_BUS_DEVICE(s), i + 1, cs_line);
- }
-}
-
-static void palmetto_bmc_init(MachineState *machine)
-{
- PalmettoBMCState *bmc;
-
- bmc = g_new0(PalmettoBMCState, 1);
- object_initialize(&bmc->soc, (sizeof(bmc->soc)), TYPE_AST2400);
- object_property_add_child(OBJECT(machine), "soc", OBJECT(&bmc->soc),
- &error_abort);
-
- memory_region_allocate_system_memory(&bmc->ram, NULL, "ram", ram_size);
- memory_region_add_subregion(get_system_memory(), AST2400_SDRAM_BASE,
- &bmc->ram);
- object_property_add_const_link(OBJECT(&bmc->soc), "ram", OBJECT(&bmc->ram),
- &error_abort);
- object_property_set_int(OBJECT(&bmc->soc), 0x120CE416, "hw-strap1",
- &error_abort);
- object_property_set_bool(OBJECT(&bmc->soc), true, "realized",
- &error_abort);
-
- palmetto_bmc_init_flashes(&bmc->soc.smc, "n25q256a", &error_abort);
- palmetto_bmc_init_flashes(&bmc->soc.spi, "mx25l25635e", &error_abort);
-
- palmetto_bmc_binfo.kernel_filename = machine->kernel_filename;
- palmetto_bmc_binfo.initrd_filename = machine->initrd_filename;
- palmetto_bmc_binfo.kernel_cmdline = machine->kernel_cmdline;
- palmetto_bmc_binfo.ram_size = ram_size;
- arm_load_kernel(ARM_CPU(first_cpu), &palmetto_bmc_binfo);
-}
-
-static void palmetto_bmc_machine_init(MachineClass *mc)
-{
- mc->desc = "OpenPOWER Palmetto BMC";
- mc->init = palmetto_bmc_init;
- mc->max_cpus = 1;
- mc->no_sdcard = 1;
- mc->no_floppy = 1;
- mc->no_cdrom = 1;
- mc->no_sdcard = 1;
- mc->no_parallel = 1;
-}
-
-DEFINE_MACHINE("palmetto-bmc", palmetto_bmc_machine_init);
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index cb55704687..21ea1d6210 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -1505,7 +1505,7 @@ static void pxa2xx_i2c_initfn(Object *obj)
PXA2xxI2CState *s = PXA2XX_I2C(obj);
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
- s->bus = i2c_init_bus(dev, "i2c");
+ s->bus = i2c_init_bus(dev, NULL);
memory_region_init_io(&s->iomem, obj, &pxa2xx_i2c_ops, s,
"pxa2xx-i2c", s->region_size);
@@ -1764,7 +1764,7 @@ struct PXA2xxFIrState {
qemu_irq rx_dma;
qemu_irq tx_dma;
uint32_t enable;
- CharDriverState *chr;
+ CharBackend chr;
uint8_t control[3];
uint8_t status[2];
@@ -1898,12 +1898,16 @@ static void pxa2xx_fir_write(void *opaque, hwaddr addr,
pxa2xx_fir_update(s);
break;
case ICDR:
- if (s->control[2] & (1 << 2)) /* TXP */
+ if (s->control[2] & (1 << 2)) { /* TXP */
ch = value;
- else
+ } else {
ch = ~value;
- if (s->chr && s->enable && (s->control[0] & (1 << 3))) /* TXE */
- qemu_chr_fe_write(s->chr, &ch, 1);
+ }
+ if (s->enable && (s->control[0] & (1 << 3))) { /* TXE */
+ /* XXX this blocks entire thread. Rewrite to use
+ * qemu_chr_fe_write and background I/O callbacks */
+ qemu_chr_fe_write_all(&s->chr, &ch, 1);
+ }
break;
case ICSR0:
s->status[0] &= ~(value & 0x66);
@@ -1971,11 +1975,8 @@ static void pxa2xx_fir_realize(DeviceState *dev, Error **errp)
{
PXA2xxFIrState *s = PXA2XX_FIR(dev);
- if (s->chr) {
- qemu_chr_fe_claim_no_fail(s->chr);
- qemu_chr_add_handlers(s->chr, pxa2xx_fir_is_empty,
- pxa2xx_fir_rx, pxa2xx_fir_event, s);
- }
+ qemu_chr_fe_set_handlers(&s->chr, pxa2xx_fir_is_empty,
+ pxa2xx_fir_rx, pxa2xx_fir_event, s, NULL, true);
}
static bool pxa2xx_fir_vmstate_validate(void *opaque, int version_id)
@@ -2266,7 +2267,9 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
qdev_get_gpio_in(s->pic, PXA2XX_PIC_LCD));
s->cm_base = 0x41300000;
- s->cm_regs[CCCR >> 2] = 0x02000210; /* 416.0 MHz */
+ s->cm_regs[CCCR >> 2] = 0x00000121; /* from datasheet */
+ s->cm_regs[CKEN >> 2] = 0x00017def; /* from datasheet */
+
s->clkcfg = 0x00000009; /* Turbo mode active */
memory_region_init_io(&s->cm_iomem, NULL, &pxa2xx_cm_ops, s, "pxa2xx-cm", 0x1000);
memory_region_add_subregion(address_space, s->cm_base, &s->cm_iomem);
diff --git a/hw/arm/pxa2xx_gpio.c b/hw/arm/pxa2xx_gpio.c
index 576a8eb91f..521dbad039 100644
--- a/hw/arm/pxa2xx_gpio.c
+++ b/hw/arm/pxa2xx_gpio.c
@@ -280,23 +280,28 @@ DeviceState *pxa2xx_gpio_init(hwaddr base,
return dev;
}
-static int pxa2xx_gpio_initfn(SysBusDevice *sbd)
+static void pxa2xx_gpio_initfn(Object *obj)
{
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
DeviceState *dev = DEVICE(sbd);
PXA2xxGPIOInfo *s = PXA2XX_GPIO(dev);
- s->cpu = ARM_CPU(qemu_get_cpu(s->ncpu));
-
- qdev_init_gpio_in(dev, pxa2xx_gpio_set, s->lines);
- qdev_init_gpio_out(dev, s->handler, s->lines);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &pxa_gpio_ops, s, "pxa2xx-gpio", 0x1000);
+ memory_region_init_io(&s->iomem, obj, &pxa_gpio_ops,
+ s, "pxa2xx-gpio", 0x1000);
sysbus_init_mmio(sbd, &s->iomem);
sysbus_init_irq(sbd, &s->irq0);
sysbus_init_irq(sbd, &s->irq1);
sysbus_init_irq(sbd, &s->irqX);
+}
- return 0;
+static void pxa2xx_gpio_realize(DeviceState *dev, Error **errp)
+{
+ PXA2xxGPIOInfo *s = PXA2XX_GPIO(dev);
+
+ s->cpu = ARM_CPU(qemu_get_cpu(s->ncpu));
+
+ qdev_init_gpio_in(dev, pxa2xx_gpio_set, s->lines);
+ qdev_init_gpio_out(dev, s->handler, s->lines);
}
/*
@@ -336,18 +341,18 @@ static Property pxa2xx_gpio_properties[] = {
static void pxa2xx_gpio_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = pxa2xx_gpio_initfn;
dc->desc = "PXA2xx GPIO controller";
dc->props = pxa2xx_gpio_properties;
dc->vmsd = &vmstate_pxa2xx_gpio_regs;
+ dc->realize = pxa2xx_gpio_realize;
}
static const TypeInfo pxa2xx_gpio_info = {
.name = TYPE_PXA2XX_GPIO,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(PXA2xxGPIOInfo),
+ .instance_init = pxa2xx_gpio_initfn,
.class_init = pxa2xx_gpio_class_init,
};
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index 41cc2eeeb1..949a15ae64 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -29,6 +29,7 @@
#include "sysemu/block-backend.h"
#include "hw/sysbus.h"
#include "exec/address-spaces.h"
+#include "sysemu/sysemu.h"
#undef REG_FMT
#define REG_FMT "0x%02lx"
@@ -844,9 +845,18 @@ static void spitz_lcd_hsync_handler(void *opaque, int line, int level)
spitz_hsync ^= 1;
}
+static void spitz_reset(void *opaque, int line, int level)
+{
+ if (level) {
+ qemu_system_reset_request();
+ }
+}
+
static void spitz_gpio_setup(PXA2xxState *cpu, int slots)
{
qemu_irq lcd_hsync;
+ qemu_irq reset;
+
/*
* Bad hack: We toggle the LCD hsync GPIO on every GPIO status
* read to satisfy broken guests that poll-wait for hsync.
@@ -867,7 +877,8 @@ static void spitz_gpio_setup(PXA2xxState *cpu, int slots)
qemu_irq_raise(qdev_get_gpio_in(cpu->gpio, SPITZ_GPIO_BAT_COVER));
/* Handle reset */
- qdev_connect_gpio_out(cpu->gpio, SPITZ_GPIO_ON_RESET, cpu->reset);
+ reset = qemu_allocate_irq(spitz_reset, cpu, 0);
+ qdev_connect_gpio_out(cpu->gpio, SPITZ_GPIO_ON_RESET, reset);
/* PCMCIA signals: card's IRQ and Card-Detect */
if (slots >= 1)
diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
index de26b8caff..38425bda6c 100644
--- a/hw/arm/stm32f205_soc.c
+++ b/hw/arm/stm32f205_soc.c
@@ -34,9 +34,15 @@ static const uint32_t timer_addr[STM_NUM_TIMERS] = { 0x40000000, 0x40000400,
0x40000800, 0x40000C00 };
static const uint32_t usart_addr[STM_NUM_USARTS] = { 0x40011000, 0x40004400,
0x40004800, 0x40004C00, 0x40005000, 0x40011400 };
+static const uint32_t adc_addr[STM_NUM_ADCS] = { 0x40012000, 0x40012100,
+ 0x40012200 };
+static const uint32_t spi_addr[STM_NUM_SPIS] = { 0x40013000, 0x40003800,
+ 0x40003C00 };
static const int timer_irq[STM_NUM_TIMERS] = {28, 29, 30, 50};
static const int usart_irq[STM_NUM_USARTS] = {37, 38, 39, 52, 53, 71};
+#define ADC_IRQ 18
+static const int spi_irq[STM_NUM_SPIS] = {35, 36, 51};
static void stm32f205_soc_initfn(Object *obj)
{
@@ -57,13 +63,27 @@ static void stm32f205_soc_initfn(Object *obj)
TYPE_STM32F2XX_TIMER);
qdev_set_parent_bus(DEVICE(&s->timer[i]), sysbus_get_default());
}
+
+ s->adc_irqs = OR_IRQ(object_new(TYPE_OR_IRQ));
+
+ for (i = 0; i < STM_NUM_ADCS; i++) {
+ object_initialize(&s->adc[i], sizeof(s->adc[i]),
+ TYPE_STM32F2XX_ADC);
+ qdev_set_parent_bus(DEVICE(&s->adc[i]), sysbus_get_default());
+ }
+
+ for (i = 0; i < STM_NUM_SPIS; i++) {
+ object_initialize(&s->spi[i], sizeof(s->spi[i]),
+ TYPE_STM32F2XX_SPI);
+ qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
+ }
}
static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
{
STM32F205State *s = STM32F205_SOC(dev_soc);
- DeviceState *syscfgdev, *usartdev, *timerdev, *nvic;
- SysBusDevice *syscfgbusdev, *usartbusdev, *timerbusdev;
+ DeviceState *dev, *nvic;
+ SysBusDevice *busdev;
Error *err = NULL;
int i;
@@ -94,44 +114,80 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
s->kernel_filename, s->cpu_model);
/* System configuration controller */
- syscfgdev = DEVICE(&s->syscfg);
+ dev = DEVICE(&s->syscfg);
object_property_set_bool(OBJECT(&s->syscfg), true, "realized", &err);
if (err != NULL) {
error_propagate(errp, err);
return;
}
- syscfgbusdev = SYS_BUS_DEVICE(syscfgdev);
- sysbus_mmio_map(syscfgbusdev, 0, 0x40013800);
- sysbus_connect_irq(syscfgbusdev, 0, qdev_get_gpio_in(nvic, 71));
+ busdev = SYS_BUS_DEVICE(dev);
+ sysbus_mmio_map(busdev, 0, 0x40013800);
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(nvic, 71));
/* Attach UART (uses USART registers) and USART controllers */
for (i = 0; i < STM_NUM_USARTS; i++) {
- usartdev = DEVICE(&(s->usart[i]));
- qdev_prop_set_chr(usartdev, "chardev", i < MAX_SERIAL_PORTS ? serial_hds[i] : NULL);
+ dev = DEVICE(&(s->usart[i]));
+ qdev_prop_set_chr(dev, "chardev",
+ i < MAX_SERIAL_PORTS ? serial_hds[i] : NULL);
object_property_set_bool(OBJECT(&s->usart[i]), true, "realized", &err);
if (err != NULL) {
error_propagate(errp, err);
return;
}
- usartbusdev = SYS_BUS_DEVICE(usartdev);
- sysbus_mmio_map(usartbusdev, 0, usart_addr[i]);
- sysbus_connect_irq(usartbusdev, 0,
- qdev_get_gpio_in(nvic, usart_irq[i]));
+ busdev = SYS_BUS_DEVICE(dev);
+ sysbus_mmio_map(busdev, 0, usart_addr[i]);
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(nvic, usart_irq[i]));
}
/* Timer 2 to 5 */
for (i = 0; i < STM_NUM_TIMERS; i++) {
- timerdev = DEVICE(&(s->timer[i]));
- qdev_prop_set_uint64(timerdev, "clock-frequency", 1000000000);
+ dev = DEVICE(&(s->timer[i]));
+ qdev_prop_set_uint64(dev, "clock-frequency", 1000000000);
object_property_set_bool(OBJECT(&s->timer[i]), true, "realized", &err);
if (err != NULL) {
error_propagate(errp, err);
return;
}
- timerbusdev = SYS_BUS_DEVICE(timerdev);
- sysbus_mmio_map(timerbusdev, 0, timer_addr[i]);
- sysbus_connect_irq(timerbusdev, 0,
- qdev_get_gpio_in(nvic, timer_irq[i]));
+ busdev = SYS_BUS_DEVICE(dev);
+ sysbus_mmio_map(busdev, 0, timer_addr[i]);
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(nvic, timer_irq[i]));
+ }
+
+ /* ADC 1 to 3 */
+ object_property_set_int(OBJECT(s->adc_irqs), STM_NUM_ADCS,
+ "num-lines", &err);
+ object_property_set_bool(OBJECT(s->adc_irqs), true, "realized", &err);
+ if (err != NULL) {
+ error_propagate(errp, err);
+ return;
+ }
+ qdev_connect_gpio_out(DEVICE(s->adc_irqs), 0,
+ qdev_get_gpio_in(nvic, ADC_IRQ));
+
+ for (i = 0; i < STM_NUM_ADCS; i++) {
+ dev = DEVICE(&(s->adc[i]));
+ object_property_set_bool(OBJECT(&s->adc[i]), true, "realized", &err);
+ if (err != NULL) {
+ error_propagate(errp, err);
+ return;
+ }
+ busdev = SYS_BUS_DEVICE(dev);
+ sysbus_mmio_map(busdev, 0, adc_addr[i]);
+ sysbus_connect_irq(busdev, 0,
+ qdev_get_gpio_in(DEVICE(s->adc_irqs), i));
+ }
+
+ /* SPI 1 and 2 */
+ for (i = 0; i < STM_NUM_SPIS; i++) {
+ dev = DEVICE(&(s->spi[i]));
+ object_property_set_bool(OBJECT(&s->spi[i]), true, "realized", &err);
+ if (err != NULL) {
+ error_propagate(errp, err);
+ return;
+ }
+ busdev = SYS_BUS_DEVICE(dev);
+ sysbus_mmio_map(busdev, 0, spi_addr[i]);
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(nvic, spi_irq[i]));
}
}
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
index f1b2c6c966..3311cc38a4 100644
--- a/hw/arm/strongarm.c
+++ b/hw/arm/strongarm.c
@@ -912,7 +912,7 @@ typedef struct StrongARMUARTState {
SysBusDevice parent_obj;
MemoryRegion iomem;
- CharDriverState *chr;
+ CharBackend chr;
qemu_irq irq;
uint8_t utcr0;
@@ -1020,9 +1020,7 @@ static void strongarm_uart_update_parameters(StrongARMUARTState *s)
ssp.data_bits = data_bits;
ssp.stop_bits = stop_bits;
s->char_transmit_time = (NANOSECONDS_PER_SECOND / speed) * frame_size;
- if (s->chr) {
- qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
- }
+ qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
DPRINTF(stderr, "%s speed=%d parity=%c data=%d stop=%d\n", s->chr->label,
speed, parity, data_bits, stop_bits);
@@ -1107,8 +1105,10 @@ static void strongarm_uart_tx(void *opaque)
if (s->utcr3 & UTCR3_LBM) /* loopback */ {
strongarm_uart_receive(s, &s->tx_fifo[s->tx_start], 1);
- } else if (s->chr) {
- qemu_chr_fe_write(s->chr, &s->tx_fifo[s->tx_start], 1);
+ } else if (qemu_chr_fe_get_driver(&s->chr)) {
+ /* XXX this blocks entire thread. Rewrite to use
+ * qemu_chr_fe_write and background I/O callbacks */
+ qemu_chr_fe_write_all(&s->chr, &s->tx_fifo[s->tx_start], 1);
}
s->tx_start = (s->tx_start + 1) % 8;
@@ -1236,14 +1236,17 @@ static void strongarm_uart_init(Object *obj)
s->rx_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_rx_to, s);
s->tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_tx, s);
+}
- if (s->chr) {
- qemu_chr_add_handlers(s->chr,
- strongarm_uart_can_receive,
- strongarm_uart_receive,
- strongarm_uart_event,
- s);
- }
+static void strongarm_uart_realize(DeviceState *dev, Error **errp)
+{
+ StrongARMUARTState *s = STRONGARM_UART(dev);
+
+ qemu_chr_fe_set_handlers(&s->chr,
+ strongarm_uart_can_receive,
+ strongarm_uart_receive,
+ strongarm_uart_event,
+ s, NULL, true);
}
static void strongarm_uart_reset(DeviceState *dev)
@@ -1318,6 +1321,7 @@ static void strongarm_uart_class_init(ObjectClass *klass, void *data)
dc->reset = strongarm_uart_reset;
dc->vmsd = &vmstate_strongarm_uart_regs;
dc->props = strongarm_uart_properties;
+ dc->realize = strongarm_uart_realize;
}
static const TypeInfo strongarm_uart_info = {
@@ -1518,19 +1522,19 @@ static int strongarm_ssp_post_load(void *opaque, int version_id)
return 0;
}
-static int strongarm_ssp_init(SysBusDevice *sbd)
+static void strongarm_ssp_init(Object *obj)
{
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
DeviceState *dev = DEVICE(sbd);
StrongARMSSPState *s = STRONGARM_SSP(dev);
sysbus_init_irq(sbd, &s->irq);
- memory_region_init_io(&s->iomem, OBJECT(s), &strongarm_ssp_ops, s,
+ memory_region_init_io(&s->iomem, obj, &strongarm_ssp_ops, s,
"ssp", 0x1000);
sysbus_init_mmio(sbd, &s->iomem);
s->bus = ssi_create_bus(dev, "ssi");
- return 0;
}
static void strongarm_ssp_reset(DeviceState *dev)
@@ -1560,9 +1564,7 @@ static const VMStateDescription vmstate_strongarm_ssp_regs = {
static void strongarm_ssp_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = strongarm_ssp_init;
dc->desc = "StrongARM SSP controller";
dc->reset = strongarm_ssp_reset;
dc->vmsd = &vmstate_strongarm_ssp_regs;
@@ -1572,6 +1574,7 @@ static const TypeInfo strongarm_ssp_info = {
.name = TYPE_STRONGARM_SSP,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(StrongARMSSPState),
+ .instance_init = strongarm_ssp_init,
.class_init = strongarm_ssp_class_init,
};
diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
index 5debb3348c..d68e3dcdbd 100644
--- a/hw/arm/sysbus-fdt.c
+++ b/hw/arm/sysbus-fdt.c
@@ -436,7 +436,7 @@ static const NodeCreationPair add_fdt_node_functions[] = {
* are dynamically instantiable and if so call the node creation
* function.
*/
-static int add_fdt_node(SysBusDevice *sbdev, void *opaque)
+static void add_fdt_node(SysBusDevice *sbdev, void *opaque)
{
int i, ret;
@@ -445,7 +445,7 @@ static int add_fdt_node(SysBusDevice *sbdev, void *opaque)
add_fdt_node_functions[i].typename)) {
ret = add_fdt_node_functions[i].add_fdt_node_fn(sbdev, opaque);
assert(!ret);
- return 0;
+ return;
}
}
error_report("Device %s can not be dynamically instantiated",
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
index 2db66508b5..1ee12f49b3 100644
--- a/hw/arm/tosa.c
+++ b/hw/arm/tosa.c
@@ -25,6 +25,7 @@
#include "sysemu/block-backend.h"
#include "hw/sysbus.h"
#include "exec/address-spaces.h"
+#include "sysemu/sysemu.h"
#define TOSA_RAM 0x04000000
#define TOSA_ROM 0x00800000
@@ -86,6 +87,12 @@ static void tosa_out_switch(void *opaque, int line, int level)
}
}
+static void tosa_reset(void *opaque, int line, int level)
+{
+ if (level) {
+ qemu_system_reset_request();
+ }
+}
static void tosa_gpio_setup(PXA2xxState *cpu,
DeviceState *scp0,
@@ -93,13 +100,16 @@ static void tosa_gpio_setup(PXA2xxState *cpu,
TC6393xbState *tmio)
{
qemu_irq *outsignals = qemu_allocate_irqs(tosa_out_switch, cpu, 4);
+ qemu_irq reset;
+
/* MMC/SD host */
pxa2xx_mmci_handlers(cpu->mmc,
qdev_get_gpio_in(scp0, TOSA_GPIO_SD_WP),
qemu_irq_invert(qdev_get_gpio_in(cpu->gpio, TOSA_GPIO_nSD_DETECT)));
/* Handle reset */
- qdev_connect_gpio_out(cpu->gpio, TOSA_GPIO_ON_RESET, cpu->reset);
+ reset = qemu_allocate_irq(tosa_reset, cpu, 0);
+ qdev_connect_gpio_out(cpu->gpio, TOSA_GPIO_ON_RESET, reset);
/* PCMCIA signals: card's IRQ and Card-Detect */
pxa2xx_pcmcia_set_irq_cb(cpu->pcmcia[0],
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index 8ae5392bcc..7b5cb36d5a 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -198,6 +198,15 @@ static void versatile_init(MachineState *machine, int board_id)
int done_smc = 0;
DriveInfo *dinfo;
+ if (machine->ram_size > 0x10000000) {
+ /* Device starting at address 0x10000000,
+ * and memory cannot overlap with devices.
+ * Refuse to run rather than behaving very confusingly.
+ */
+ error_report("versatilepb: memory size must not exceed 256MB");
+ exit(1);
+ }
+
if (!machine->cpu_model) {
machine->cpu_model = "arm926";
}
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 28fc59c665..d4160dfa7d 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -44,6 +44,7 @@
#include "hw/pci/pcie_host.h"
#include "hw/pci/pci.h"
#include "sysemu/numa.h"
+#include "kvm_arm.h"
#define ARM_SPI_BASE 32
#define ACPI_POWER_BUTTON_DEVICE "PWRB"
@@ -53,7 +54,7 @@ static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus)
uint16_t i;
for (i = 0; i < smp_cpus; i++) {
- Aml *dev = aml_device("C%03x", i);
+ Aml *dev = aml_device("C%.03X", i);
aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0007")));
aml_append(dev, aml_name_decl("_UID", aml_int(i)));
aml_append(scope, dev);
@@ -383,6 +384,61 @@ build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset)
}
static void
+build_iort(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
+{
+ int iort_start = table_data->len;
+ AcpiIortIdMapping *idmap;
+ AcpiIortItsGroup *its;
+ AcpiIortTable *iort;
+ size_t node_size, iort_length;
+ AcpiIortRC *rc;
+
+ iort = acpi_data_push(table_data, sizeof(*iort));
+
+ iort_length = sizeof(*iort);
+ iort->node_count = cpu_to_le32(2); /* RC and ITS nodes */
+ iort->node_offset = cpu_to_le32(sizeof(*iort));
+
+ /* ITS group node */
+ node_size = sizeof(*its) + sizeof(uint32_t);
+ iort_length += node_size;
+ its = acpi_data_push(table_data, node_size);
+
+ its->type = ACPI_IORT_NODE_ITS_GROUP;
+ its->length = cpu_to_le16(node_size);
+ its->its_count = cpu_to_le32(1);
+ its->identifiers[0] = 0; /* MADT translation_id */
+
+ /* Root Complex Node */
+ node_size = sizeof(*rc) + sizeof(*idmap);
+ iort_length += node_size;
+ rc = acpi_data_push(table_data, node_size);
+
+ rc->type = ACPI_IORT_NODE_PCI_ROOT_COMPLEX;
+ rc->length = cpu_to_le16(node_size);
+ rc->mapping_count = cpu_to_le32(1);
+ rc->mapping_offset = cpu_to_le32(sizeof(*rc));
+
+ /* fully coherent device */
+ rc->memory_properties.cache_coherency = cpu_to_le32(1);
+ rc->memory_properties.memory_flags = 0x3; /* CCA = CPM = DCAS = 1 */
+ rc->pci_segment_number = 0; /* MCFG pci_segment */
+
+ /* Identity RID mapping covering the whole input RID range */
+ idmap = &rc->id_mapping_array[0];
+ idmap->input_base = 0;
+ idmap->id_count = cpu_to_le32(0xFFFF);
+ idmap->output_base = 0;
+ /* output IORT node is the ITS group node (the first node) */
+ idmap->output_reference = cpu_to_le32(iort->node_offset);
+
+ iort->length = cpu_to_le32(iort_length);
+
+ build_header(linker, table_data, (void *)(table_data->data + iort_start),
+ "IORT", table_data->len - iort_start, 0, NULL, NULL);
+}
+
+static void
build_spcr(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
{
AcpiSerialPortConsoleRedirection *spcr;
@@ -426,11 +482,9 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
uint32_t *cpu_node = g_malloc0(guest_info->smp_cpus * sizeof(uint32_t));
for (i = 0; i < guest_info->smp_cpus; i++) {
- for (j = 0; j < nb_numa_nodes; j++) {
- if (test_bit(i, numa_info[j].node_cpu)) {
+ j = numa_get_node_for_cpu(i);
+ if (j < nb_numa_nodes) {
cpu_node[i] = j;
- break;
- }
}
}
@@ -540,12 +594,13 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
gicc->uid = i;
gicc->flags = cpu_to_le32(ACPI_GICC_ENABLED);
- if (armcpu->has_pmu) {
+ if (arm_feature(&armcpu->env, ARM_FEATURE_PMU)) {
gicc->performance_interrupt = cpu_to_le32(PPI(VIRTUAL_PMU_IRQ));
}
}
if (guest_info->gic_version == 3) {
+ AcpiMadtGenericTranslator *gic_its;
AcpiMadtGenericRedistributor *gicr = acpi_data_push(table_data,
sizeof *gicr);
@@ -553,6 +608,14 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
gicr->length = sizeof(*gicr);
gicr->base_address = cpu_to_le64(memmap[VIRT_GIC_REDIST].base);
gicr->range_length = cpu_to_le32(memmap[VIRT_GIC_REDIST].size);
+
+ if (its_class_name() && !guest_info->no_its) {
+ gic_its = acpi_data_push(table_data, sizeof *gic_its);
+ gic_its->type = ACPI_APIC_GENERIC_TRANSLATOR;
+ gic_its->length = sizeof(*gic_its);
+ gic_its->translation_id = 0;
+ gic_its->base_address = cpu_to_le64(memmap[VIRT_GIC_ITS].base);
+ }
} else {
gic_msi = acpi_data_push(table_data, sizeof *gic_msi);
gic_msi->type = ACPI_APIC_GENERIC_MSI_FRAME;
@@ -659,17 +722,6 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
ACPI_BUILD_TABLE_FILE, tables_blob,
64, false /* high memory */);
- /*
- * The ACPI v5.1 tables for Hardware-reduced ACPI platform are:
- * RSDP
- * RSDT
- * FADT
- * GTDT
- * MADT
- * MCFG
- * DSDT
- */
-
/* DSDT is pointed to by FADT */
dsdt = tables_blob->len;
build_dsdt(tables_blob, tables->linker, guest_info);
@@ -695,6 +747,11 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
build_srat(tables_blob, tables->linker, guest_info);
}
+ if (its_class_name() && !guest_info->no_its) {
+ acpi_add_table(table_offsets, tables_blob);
+ build_iort(tables_blob, tables->linker, guest_info);
+ }
+
/* RSDT is pointed to by RSDP */
rsdt = tables_blob->len;
build_rsdt(tables_blob, tables->linker, table_offsets, NULL, NULL);
@@ -752,7 +809,7 @@ static MemoryRegion *acpi_add_rom_blob(AcpiBuildState *build_state,
uint64_t max_size)
{
return rom_add_blob(name, blob->data, acpi_data_len(blob), max_size, -1,
- name, virt_acpi_build_update, build_state);
+ name, virt_acpi_build_update, build_state, NULL);
}
static const VMStateDescription vmstate_virt_acpi_build = {
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index a193b5a95b..d04e4acbd9 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -76,7 +76,7 @@ typedef struct VirtBoardInfo {
int fdt_size;
uint32_t clock_phandle;
uint32_t gic_phandle;
- uint32_t v2m_phandle;
+ uint32_t msi_phandle;
bool using_psci;
} VirtBoardInfo;
@@ -84,6 +84,8 @@ typedef struct {
MachineClass parent;
VirtBoardInfo *daughterboard;
bool disallow_affinity_adjustment;
+ bool no_its;
+ bool no_pmu;
} VirtMachineClass;
typedef struct {
@@ -413,19 +415,31 @@ static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
armcpu->mp_affinity);
}
- for (i = 0; i < nb_numa_nodes; i++) {
- if (test_bit(cpu, numa_info[i].node_cpu)) {
- qemu_fdt_setprop_cell(vbi->fdt, nodename, "numa-node-id", i);
- }
+ i = numa_get_node_for_cpu(cpu);
+ if (i < nb_numa_nodes) {
+ qemu_fdt_setprop_cell(vbi->fdt, nodename, "numa-node-id", i);
}
g_free(nodename);
}
}
+static void fdt_add_its_gic_node(VirtBoardInfo *vbi)
+{
+ vbi->msi_phandle = qemu_fdt_alloc_phandle(vbi->fdt);
+ qemu_fdt_add_subnode(vbi->fdt, "/intc/its");
+ qemu_fdt_setprop_string(vbi->fdt, "/intc/its", "compatible",
+ "arm,gic-v3-its");
+ qemu_fdt_setprop(vbi->fdt, "/intc/its", "msi-controller", NULL, 0);
+ qemu_fdt_setprop_sized_cells(vbi->fdt, "/intc/its", "reg",
+ 2, vbi->memmap[VIRT_GIC_ITS].base,
+ 2, vbi->memmap[VIRT_GIC_ITS].size);
+ qemu_fdt_setprop_cell(vbi->fdt, "/intc/its", "phandle", vbi->msi_phandle);
+}
+
static void fdt_add_v2m_gic_node(VirtBoardInfo *vbi)
{
- vbi->v2m_phandle = qemu_fdt_alloc_phandle(vbi->fdt);
+ vbi->msi_phandle = qemu_fdt_alloc_phandle(vbi->fdt);
qemu_fdt_add_subnode(vbi->fdt, "/intc/v2m");
qemu_fdt_setprop_string(vbi->fdt, "/intc/v2m", "compatible",
"arm,gic-v2m-frame");
@@ -433,7 +447,7 @@ static void fdt_add_v2m_gic_node(VirtBoardInfo *vbi)
qemu_fdt_setprop_sized_cells(vbi->fdt, "/intc/v2m", "reg",
2, vbi->memmap[VIRT_GIC_V2M].base,
2, vbi->memmap[VIRT_GIC_V2M].size);
- qemu_fdt_setprop_cell(vbi->fdt, "/intc/v2m", "phandle", vbi->v2m_phandle);
+ qemu_fdt_setprop_cell(vbi->fdt, "/intc/v2m", "phandle", vbi->msi_phandle);
}
static void fdt_add_gic_node(VirtBoardInfo *vbi, int type)
@@ -477,7 +491,7 @@ static void fdt_add_pmu_nodes(const VirtBoardInfo *vbi, int gictype)
CPU_FOREACH(cpu) {
armcpu = ARM_CPU(cpu);
- if (!armcpu->has_pmu ||
+ if (!arm_feature(&armcpu->env, ARM_FEATURE_PMU) ||
!kvm_arm_pmu_create(cpu, PPI(VIRTUAL_PMU_IRQ))) {
return;
}
@@ -500,6 +514,26 @@ static void fdt_add_pmu_nodes(const VirtBoardInfo *vbi, int gictype)
}
}
+static void create_its(VirtBoardInfo *vbi, DeviceState *gicdev)
+{
+ const char *itsclass = its_class_name();
+ DeviceState *dev;
+
+ if (!itsclass) {
+ /* Do nothing if not supported */
+ return;
+ }
+
+ dev = qdev_create(NULL, itsclass);
+
+ object_property_set_link(OBJECT(dev), OBJECT(gicdev), "parent-gicv3",
+ &error_abort);
+ qdev_init_nofail(dev);
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vbi->memmap[VIRT_GIC_ITS].base);
+
+ fdt_add_its_gic_node(vbi);
+}
+
static void create_v2m(VirtBoardInfo *vbi, qemu_irq *pic)
{
int i;
@@ -519,7 +553,8 @@ static void create_v2m(VirtBoardInfo *vbi, qemu_irq *pic)
fdt_add_v2m_gic_node(vbi);
}
-static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic, int type, bool secure)
+static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic, int type,
+ bool secure, bool no_its)
{
/* We create a standalone GIC */
DeviceState *gicdev;
@@ -583,7 +618,9 @@ static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic, int type, bool secure)
fdt_add_gic_node(vbi, type);
- if (type == 2) {
+ if (type == 3 && !no_its) {
+ create_its(vbi, gicdev);
+ } else if (type == 2) {
create_v2m(vbi, pic);
}
}
@@ -892,9 +929,11 @@ static void create_fw_cfg(const VirtBoardInfo *vbi, AddressSpace *as)
{
hwaddr base = vbi->memmap[VIRT_FW_CFG].base;
hwaddr size = vbi->memmap[VIRT_FW_CFG].size;
+ FWCfgState *fw_cfg;
char *nodename;
- fw_cfg_init_mem_wide(base + 8, base, 8, base + 16, as);
+ fw_cfg = fw_cfg_init_mem_wide(base + 8, base, 8, base + 16, as);
+ fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
nodename = g_strdup_printf("/fw-cfg@%" PRIx64, base);
qemu_fdt_add_subnode(vbi->fdt, nodename);
@@ -1025,9 +1064,9 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic,
nr_pcie_buses - 1);
qemu_fdt_setprop(vbi->fdt, nodename, "dma-coherent", NULL, 0);
- if (vbi->v2m_phandle) {
+ if (vbi->msi_phandle) {
qemu_fdt_setprop_cells(vbi->fdt, nodename, "msi-parent",
- vbi->v2m_phandle);
+ vbi->msi_phandle);
}
qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
@@ -1317,6 +1356,10 @@ static void machvirt_init(MachineState *machine)
}
}
+ if (vmc->no_pmu && object_property_find(cpuobj, "pmu", NULL)) {
+ object_property_set_bool(cpuobj, false, "pmu", NULL);
+ }
+
if (object_property_find(cpuobj, "reset-cbar", NULL)) {
object_property_set_int(cpuobj, vbi->memmap[VIRT_CPUPERIPHS].base,
"reset-cbar", &error_abort);
@@ -1341,7 +1384,7 @@ static void machvirt_init(MachineState *machine)
create_flash(vbi, sysmem, secure_sysmem ? secure_sysmem : sysmem);
- create_gic(vbi, pic, gic_version, vms->secure);
+ create_gic(vbi, pic, gic_version, vms->secure, vmc->no_its);
fdt_add_pmu_nodes(vbi, gic_version);
@@ -1373,6 +1416,7 @@ static void machvirt_init(MachineState *machine)
guest_info->irqmap = vbi->irqmap;
guest_info->use_highmem = vms->highmem;
guest_info->gic_version = gic_version;
+ guest_info->no_its = vmc->no_its;
guest_info_state->machine_done.notify = virt_guest_info_machine_done;
qemu_add_machine_init_done_notifier(&guest_info_state->machine_done);
@@ -1457,11 +1501,13 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
* it later in machvirt_init, where we have more information about the
* configuration of the particular instance.
*/
- mc->max_cpus = MAX_CPUMASK_BITS;
+ mc->max_cpus = 255;
mc->has_dynamic_sysbus = true;
mc->block_default_type = IF_VIRTIO;
mc->no_cdrom = 1;
mc->pci_allow_0_address = true;
+ /* We know we will never create a pre-ARMv7 CPU which needs 1K pages */
+ mc->minimum_page_bits = 12;
}
static const TypeInfo virt_machine_info = {
@@ -1479,7 +1525,7 @@ static void machvirt_machine_init(void)
}
type_init(machvirt_machine_init);
-static void virt_2_7_instance_init(Object *obj)
+static void virt_2_8_instance_init(Object *obj)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -1512,10 +1558,31 @@ static void virt_2_7_instance_init(Object *obj)
"Valid values are 2, 3 and host", NULL);
}
+static void virt_machine_2_8_options(MachineClass *mc)
+{
+}
+DEFINE_VIRT_MACHINE_AS_LATEST(2, 8)
+
+#define VIRT_COMPAT_2_7 \
+ HW_COMPAT_2_7
+
+static void virt_2_7_instance_init(Object *obj)
+{
+ virt_2_8_instance_init(obj);
+}
+
static void virt_machine_2_7_options(MachineClass *mc)
{
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
+
+ virt_machine_2_8_options(mc);
+ SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_7);
+ /* ITS was introduced with 2.8 */
+ vmc->no_its = true;
+ /* Stick with 1K pages for migration compatibility */
+ mc->minimum_page_bits = 0;
}
-DEFINE_VIRT_MACHINE_AS_LATEST(2, 7)
+DEFINE_VIRT_MACHINE(2, 7)
#define VIRT_COMPAT_2_6 \
HW_COMPAT_2_6
@@ -1532,5 +1599,7 @@ static void virt_machine_2_6_options(MachineClass *mc)
virt_machine_2_7_options(mc);
SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_6);
vmc->disallow_affinity_adjustment = true;
+ /* Disable PMU for 2.6 as PMU support was first introduced in 2.7 */
+ vmc->no_pmu = true;
}
DEFINE_VIRT_MACHINE(2, 6)
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
index 23c7199867..0d86ba35ae 100644
--- a/hw/arm/xlnx-zynqmp.c
+++ b/hw/arm/xlnx-zynqmp.c
@@ -332,6 +332,8 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
qdev_set_nic_properties(DEVICE(&s->gem[i]), nd);
}
+ object_property_set_int(OBJECT(&s->gem[i]), 2, "num-priority-queues",
+ &error_abort);
object_property_set_bool(OBJECT(&s->gem[i]), true, "realized", &err);
if (err) {
error_propagate(errp, err);