diff options
Diffstat (limited to 'hw')
| -rw-r--r-- | hw/arm/aspeed.c | 6 | ||||
| -rw-r--r-- | hw/arm/aspeed_soc.c | 50 | ||||
| -rw-r--r-- | hw/arm/bcm2835_peripherals.c | 61 | ||||
| -rw-r--r-- | hw/arm/digic.c | 17 | ||||
| -rw-r--r-- | hw/arm/imx25_pdk.c | 5 | ||||
| -rw-r--r-- | hw/arm/kzm.c | 5 | ||||
| -rw-r--r-- | hw/arm/mps2-tz.c | 8 | ||||
| -rw-r--r-- | hw/arm/mps2.c | 8 | ||||
| -rw-r--r-- | hw/arm/raspi.c | 7 | ||||
| -rw-r--r-- | hw/arm/sabrelite.c | 5 | ||||
| -rw-r--r-- | hw/arm/xlnx-zcu102.c | 5 | ||||
| -rw-r--r-- | hw/arm/xlnx-zynqmp.c | 8 | ||||
| -rw-r--r-- | hw/intc/armv7m_nvic.c | 6 | ||||
| -rw-r--r-- | hw/microblaze/xlnx-zynqmp-pmu.c | 45 | ||||
| -rw-r--r-- | hw/mips/boston.c | 25 | ||||
| -rw-r--r-- | hw/mips/cps.c | 20 | ||||
| -rw-r--r-- | hw/mips/mips_malta.c | 17 | ||||
| -rw-r--r-- | hw/misc/macio/macio.c | 8 | ||||
| -rw-r--r-- | hw/ppc/pnv.c | 12 | ||||
| -rw-r--r-- | hw/riscv/Makefile.objs | 1 | ||||
| -rw-r--r-- | hw/riscv/sifive_e.c | 28 | ||||
| -rw-r--r-- | hw/riscv/sifive_gpio.c | 388 | ||||
| -rw-r--r-- | hw/riscv/spike.c | 106 | ||||
| -rw-r--r-- | hw/riscv/trace-events | 7 | ||||
| -rw-r--r-- | hw/riscv/virt.c | 4 | ||||
| -rw-r--r-- | hw/virtio/virtio.c | 5 |
26 files changed, 667 insertions, 190 deletions
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index 415cff7a01..33070a6df8 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -160,9 +160,9 @@ static void aspeed_board_init(MachineState *machine, ram_addr_t max_ram_size; 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); + object_initialize_child(OBJECT(machine), "soc", &bmc->soc, + (sizeof(bmc->soc)), cfg->soc_name, &error_abort, + NULL); sc = ASPEED_SOC_GET_CLASS(&bmc->soc); diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c index a27233d487..faff42b84a 100644 --- a/hw/arm/aspeed_soc.c +++ b/hw/arm/aspeed_soc.c @@ -106,12 +106,11 @@ static void aspeed_soc_init(Object *obj) AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); int i; - object_initialize(&s->cpu, sizeof(s->cpu), sc->info->cpu_type); - object_property_add_child(obj, "cpu", OBJECT(&s->cpu), NULL); + object_initialize_child(obj, "cpu", OBJECT(&s->cpu), sizeof(s->cpu), + sc->info->cpu_type, &error_abort, NULL); - 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()); + sysbus_init_child_obj(obj, "scu", OBJECT(&s->scu), sizeof(s->scu), + TYPE_ASPEED_SCU); qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev", sc->info->silicon_rev); object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu), @@ -121,36 +120,29 @@ static void aspeed_soc_init(Object *obj) object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu), "hw-prot-key", &error_abort); - 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()); + sysbus_init_child_obj(obj, "vic", OBJECT(&s->vic), sizeof(s->vic), + TYPE_ASPEED_VIC); - object_initialize(&s->timerctrl, sizeof(s->timerctrl), TYPE_ASPEED_TIMER); - object_property_add_child(obj, "timerctrl", OBJECT(&s->timerctrl), NULL); + sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl), + sizeof(s->timerctrl), TYPE_ASPEED_TIMER); object_property_add_const_link(OBJECT(&s->timerctrl), "scu", OBJECT(&s->scu), &error_abort); - 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()); + sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c), + TYPE_ASPEED_I2C); - 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()); + sysbus_init_child_obj(obj, "fmc", OBJECT(&s->fmc), sizeof(s->fmc), + sc->info->fmc_typename); object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs", &error_abort); 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()); + sysbus_init_child_obj(obj, "spi[*]", OBJECT(&s->spi[i]), + sizeof(s->spi[i]), sc->info->spi_typename[i]); } - 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()); + sysbus_init_child_obj(obj, "sdmc", OBJECT(&s->sdmc), sizeof(s->sdmc), + TYPE_ASPEED_SDMC); qdev_prop_set_uint32(DEVICE(&s->sdmc), "silicon-rev", sc->info->silicon_rev); object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc), @@ -159,16 +151,14 @@ static void aspeed_soc_init(Object *obj) "max-ram-size", &error_abort); for (i = 0; i < sc->info->wdts_num; i++) { - object_initialize(&s->wdt[i], sizeof(s->wdt[i]), TYPE_ASPEED_WDT); - object_property_add_child(obj, "wdt[*]", OBJECT(&s->wdt[i]), NULL); - qdev_set_parent_bus(DEVICE(&s->wdt[i]), sysbus_get_default()); + sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]), + sizeof(s->wdt[i]), TYPE_ASPEED_WDT); qdev_prop_set_uint32(DEVICE(&s->wdt[i]), "silicon-rev", sc->info->silicon_rev); } - object_initialize(&s->ftgmac100, sizeof(s->ftgmac100), TYPE_FTGMAC100); - object_property_add_child(obj, "ftgmac100", OBJECT(&s->ftgmac100), NULL); - qdev_set_parent_bus(DEVICE(&s->ftgmac100), sysbus_get_default()); + sysbus_init_child_obj(obj, "ftgmac100", OBJECT(&s->ftgmac100), + sizeof(s->ftgmac100), TYPE_FTGMAC100); } static void aspeed_soc_realize(DeviceState *dev, Error **errp) diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c index 6be7660e8c..0fb54c7964 100644 --- a/hw/arm/bcm2835_peripherals.c +++ b/hw/arm/bcm2835_peripherals.c @@ -41,44 +41,36 @@ static void bcm2835_peripherals_init(Object *obj) MBOX_CHAN_COUNT << MBOX_AS_CHAN_SHIFT); /* Interrupt Controller */ - object_initialize(&s->ic, sizeof(s->ic), TYPE_BCM2835_IC); - object_property_add_child(obj, "ic", OBJECT(&s->ic), NULL); - qdev_set_parent_bus(DEVICE(&s->ic), sysbus_get_default()); + sysbus_init_child_obj(obj, "ic", &s->ic, sizeof(s->ic), TYPE_BCM2835_IC); /* UART0 */ - s->uart0 = SYS_BUS_DEVICE(object_new("pl011")); - object_property_add_child(obj, "uart0", OBJECT(s->uart0), NULL); - qdev_set_parent_bus(DEVICE(s->uart0), sysbus_get_default()); + sysbus_init_child_obj(obj, "uart0", &s->uart0, sizeof(s->uart0), + TYPE_PL011); /* AUX / UART1 */ - object_initialize(&s->aux, sizeof(s->aux), TYPE_BCM2835_AUX); - object_property_add_child(obj, "aux", OBJECT(&s->aux), NULL); - qdev_set_parent_bus(DEVICE(&s->aux), sysbus_get_default()); + sysbus_init_child_obj(obj, "aux", &s->aux, sizeof(s->aux), + TYPE_BCM2835_AUX); /* Mailboxes */ - object_initialize(&s->mboxes, sizeof(s->mboxes), TYPE_BCM2835_MBOX); - object_property_add_child(obj, "mbox", OBJECT(&s->mboxes), NULL); - qdev_set_parent_bus(DEVICE(&s->mboxes), sysbus_get_default()); + sysbus_init_child_obj(obj, "mbox", &s->mboxes, sizeof(s->mboxes), + TYPE_BCM2835_MBOX); object_property_add_const_link(OBJECT(&s->mboxes), "mbox-mr", OBJECT(&s->mbox_mr), &error_abort); /* Framebuffer */ - object_initialize(&s->fb, sizeof(s->fb), TYPE_BCM2835_FB); - object_property_add_child(obj, "fb", OBJECT(&s->fb), NULL); + sysbus_init_child_obj(obj, "fb", &s->fb, sizeof(s->fb), TYPE_BCM2835_FB); object_property_add_alias(obj, "vcram-size", OBJECT(&s->fb), "vcram-size", &error_abort); - qdev_set_parent_bus(DEVICE(&s->fb), sysbus_get_default()); object_property_add_const_link(OBJECT(&s->fb), "dma-mr", OBJECT(&s->gpu_bus_mr), &error_abort); /* Property channel */ - object_initialize(&s->property, sizeof(s->property), TYPE_BCM2835_PROPERTY); - object_property_add_child(obj, "property", OBJECT(&s->property), NULL); + sysbus_init_child_obj(obj, "property", &s->property, sizeof(s->property), + TYPE_BCM2835_PROPERTY); object_property_add_alias(obj, "board-rev", OBJECT(&s->property), "board-rev", &error_abort); - qdev_set_parent_bus(DEVICE(&s->property), sysbus_get_default()); object_property_add_const_link(OBJECT(&s->property), "fb", OBJECT(&s->fb), &error_abort); @@ -86,32 +78,27 @@ static void bcm2835_peripherals_init(Object *obj) OBJECT(&s->gpu_bus_mr), &error_abort); /* Random Number Generator */ - object_initialize(&s->rng, sizeof(s->rng), TYPE_BCM2835_RNG); - object_property_add_child(obj, "rng", OBJECT(&s->rng), NULL); - qdev_set_parent_bus(DEVICE(&s->rng), sysbus_get_default()); + sysbus_init_child_obj(obj, "rng", &s->rng, sizeof(s->rng), + TYPE_BCM2835_RNG); /* Extended Mass Media Controller */ - object_initialize(&s->sdhci, sizeof(s->sdhci), TYPE_SYSBUS_SDHCI); - object_property_add_child(obj, "sdhci", OBJECT(&s->sdhci), NULL); - qdev_set_parent_bus(DEVICE(&s->sdhci), sysbus_get_default()); + sysbus_init_child_obj(obj, "sdhci", &s->sdhci, sizeof(s->sdhci), + TYPE_SYSBUS_SDHCI); /* SDHOST */ - object_initialize(&s->sdhost, sizeof(s->sdhost), TYPE_BCM2835_SDHOST); - object_property_add_child(obj, "sdhost", OBJECT(&s->sdhost), NULL); - qdev_set_parent_bus(DEVICE(&s->sdhost), sysbus_get_default()); + sysbus_init_child_obj(obj, "sdhost", &s->sdhost, sizeof(s->sdhost), + TYPE_BCM2835_SDHOST); /* DMA Channels */ - object_initialize(&s->dma, sizeof(s->dma), TYPE_BCM2835_DMA); - object_property_add_child(obj, "dma", OBJECT(&s->dma), NULL); - qdev_set_parent_bus(DEVICE(&s->dma), sysbus_get_default()); + sysbus_init_child_obj(obj, "dma", &s->dma, sizeof(s->dma), + TYPE_BCM2835_DMA); object_property_add_const_link(OBJECT(&s->dma), "dma-mr", OBJECT(&s->gpu_bus_mr), &error_abort); /* GPIO */ - object_initialize(&s->gpio, sizeof(s->gpio), TYPE_BCM2835_GPIO); - object_property_add_child(obj, "gpio", OBJECT(&s->gpio), NULL); - qdev_set_parent_bus(DEVICE(&s->gpio), sysbus_get_default()); + sysbus_init_child_obj(obj, "gpio", &s->gpio, sizeof(s->gpio), + TYPE_BCM2835_GPIO); object_property_add_const_link(OBJECT(&s->gpio), "sdbus-sdhci", OBJECT(&s->sdhci.sdbus), &error_abort); @@ -166,16 +153,16 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) sysbus_pass_irq(SYS_BUS_DEVICE(s), SYS_BUS_DEVICE(&s->ic)); /* UART0 */ - qdev_prop_set_chr(DEVICE(s->uart0), "chardev", serial_hd(0)); - object_property_set_bool(OBJECT(s->uart0), true, "realized", &err); + qdev_prop_set_chr(DEVICE(&s->uart0), "chardev", serial_hd(0)); + object_property_set_bool(OBJECT(&s->uart0), true, "realized", &err); if (err) { error_propagate(errp, err); return; } memory_region_add_subregion(&s->peri_mr, UART0_OFFSET, - sysbus_mmio_get_region(s->uart0, 0)); - sysbus_connect_irq(s->uart0, 0, + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->uart0), 0)); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart0), 0, qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, INTERRUPT_UART)); /* AUX / UART1 */ diff --git a/hw/arm/digic.c b/hw/arm/digic.c index 726abb9b48..6ef26c6bac 100644 --- a/hw/arm/digic.c +++ b/hw/arm/digic.c @@ -32,27 +32,22 @@ static void digic_init(Object *obj) { DigicState *s = DIGIC(obj); - DeviceState *dev; int i; - object_initialize(&s->cpu, sizeof(s->cpu), "arm946-" TYPE_ARM_CPU); - object_property_add_child(obj, "cpu", OBJECT(&s->cpu), NULL); + object_initialize_child(obj, "cpu", &s->cpu, sizeof(s->cpu), + "arm946-" TYPE_ARM_CPU, &error_abort, NULL); for (i = 0; i < DIGIC4_NB_TIMERS; i++) { #define DIGIC_TIMER_NAME_MLEN 11 char name[DIGIC_TIMER_NAME_MLEN]; - object_initialize(&s->timer[i], sizeof(s->timer[i]), TYPE_DIGIC_TIMER); - dev = DEVICE(&s->timer[i]); - qdev_set_parent_bus(dev, sysbus_get_default()); snprintf(name, DIGIC_TIMER_NAME_MLEN, "timer[%d]", i); - object_property_add_child(obj, name, OBJECT(&s->timer[i]), NULL); + sysbus_init_child_obj(obj, name, &s->timer[i], sizeof(s->timer[i]), + TYPE_DIGIC_TIMER); } - object_initialize(&s->uart, sizeof(s->uart), TYPE_DIGIC_UART); - dev = DEVICE(&s->uart); - qdev_set_parent_bus(dev, sysbus_get_default()); - object_property_add_child(obj, "uart", OBJECT(&s->uart), NULL); + sysbus_init_child_obj(obj, "uart", &s->uart, sizeof(s->uart), + TYPE_DIGIC_UART); } static void digic_realize(DeviceState *dev, Error **errp) diff --git a/hw/arm/imx25_pdk.c b/hw/arm/imx25_pdk.c index 9f3ee14739..eef1b184b0 100644 --- a/hw/arm/imx25_pdk.c +++ b/hw/arm/imx25_pdk.c @@ -72,9 +72,8 @@ static void imx25_pdk_init(MachineState *machine) unsigned int alias_offset; int i; - object_initialize(&s->soc, sizeof(s->soc), TYPE_FSL_IMX25); - object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc), - &error_abort); + object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc), + TYPE_FSL_IMX25, &error_abort, NULL); object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_fatal); diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c index 139934c4ec..44cba8782b 100644 --- a/hw/arm/kzm.c +++ b/hw/arm/kzm.c @@ -71,9 +71,8 @@ static void kzm_init(MachineState *machine) unsigned int alias_offset; unsigned int i; - object_initialize(&s->soc, sizeof(s->soc), TYPE_FSL_IMX31); - object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc), - &error_abort); + object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc), + TYPE_FSL_IMX31, &error_abort, NULL); object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_fatal); diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c index c167a5fa59..d85dc2c4bd 100644 --- a/hw/arm/mps2-tz.c +++ b/hw/arm/mps2-tz.c @@ -214,9 +214,9 @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque, DeviceState *sccdev; MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms); - object_initialize(scc, sizeof(mms->scc), TYPE_MPS2_SCC); + sysbus_init_child_obj(OBJECT(mms), "scc", scc, + sizeof(mms->scc), TYPE_MPS2_SCC); sccdev = DEVICE(scc); - qdev_set_parent_bus(sccdev, sysbus_get_default()); qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2); qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008); qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id); @@ -229,8 +229,8 @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque, { MPS2FPGAIO *fpgaio = opaque; - object_initialize(fpgaio, sizeof(mms->fpgaio), TYPE_MPS2_FPGAIO); - qdev_set_parent_bus(DEVICE(fpgaio), sysbus_get_default()); + sysbus_init_child_obj(OBJECT(mms), "fpgaio", fpgaio, + sizeof(mms->fpgaio), TYPE_MPS2_FPGAIO); object_property_set_bool(OBJECT(fpgaio), true, "realized", &error_fatal); return sysbus_mmio_get_region(SYS_BUS_DEVICE(fpgaio), 0); } diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c index b74f1378c9..10efff36b2 100644 --- a/hw/arm/mps2.c +++ b/hw/arm/mps2.c @@ -174,9 +174,9 @@ static void mps2_common_init(MachineState *machine) g_assert_not_reached(); } - object_initialize(&mms->armv7m, sizeof(mms->armv7m), TYPE_ARMV7M); + sysbus_init_child_obj(OBJECT(mms), "armv7m", &mms->armv7m, + sizeof(mms->armv7m), TYPE_ARMV7M); armv7m = DEVICE(&mms->armv7m); - qdev_set_parent_bus(armv7m, sysbus_get_default()); switch (mmc->fpga_type) { case FPGA_AN385: qdev_prop_set_uint32(armv7m, "num-irq", 32); @@ -308,9 +308,9 @@ static void mps2_common_init(MachineState *machine) qdev_get_gpio_in(armv7m, 10)); sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000); - object_initialize(&mms->scc, sizeof(mms->scc), TYPE_MPS2_SCC); + sysbus_init_child_obj(OBJECT(mms), "scc", &mms->scc, + sizeof(mms->scc), TYPE_MPS2_SCC); sccdev = DEVICE(&mms->scc); - qdev_set_parent_bus(sccdev, sysbus_get_default()); qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2); qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008); qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id); diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 2b5fe10e2f..8c249fcabb 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -182,10 +182,9 @@ static void raspi_init(MachineState *machine, int version) exit(1); } - object_initialize(&s->soc, sizeof(s->soc), - version == 3 ? TYPE_BCM2837 : TYPE_BCM2836); - object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc), - &error_abort); + object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc), + version == 3 ? TYPE_BCM2837 : TYPE_BCM2836, + &error_abort, NULL); /* Allocate and map RAM */ memory_region_allocate_system_memory(&s->ram, OBJECT(machine), "ram", diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c index ee140e5d9e..f1b00de229 100644 --- a/hw/arm/sabrelite.c +++ b/hw/arm/sabrelite.c @@ -55,9 +55,8 @@ static void sabrelite_init(MachineState *machine) exit(1); } - object_initialize(&s->soc, sizeof(s->soc), TYPE_FSL_IMX6); - object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc), - &error_abort); + object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc), + TYPE_FSL_IMX6, &error_abort, NULL); object_property_set_bool(OBJECT(&s->soc), true, "realized", &err); if (err != NULL) { diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c index b6bc6a93b8..c802f26fbd 100644 --- a/hw/arm/xlnx-zcu102.c +++ b/hw/arm/xlnx-zcu102.c @@ -91,9 +91,8 @@ static void xlnx_zcu102_init(MachineState *machine) memory_region_allocate_system_memory(&s->ddr_ram, NULL, "ddr-ram", ram_size); - object_initialize(&s->soc, sizeof(s->soc), TYPE_XLNX_ZYNQMP); - object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc), - &error_abort); + object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc), + TYPE_XLNX_ZYNQMP, &error_abort, NULL); object_property_set_link(OBJECT(&s->soc), OBJECT(&s->ddr_ram), "ddr-ram", &error_abort); diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c index 4f8bc41d9d..6e99190302 100644 --- a/hw/arm/xlnx-zynqmp.c +++ b/hw/arm/xlnx-zynqmp.c @@ -191,10 +191,10 @@ static void xlnx_zynqmp_create_rpu(XlnxZynqMPState *s, const char *boot_cpu, for (i = 0; i < num_rpus; i++) { char *name; - object_initialize(&s->rpu_cpu[i], sizeof(s->rpu_cpu[i]), - "cortex-r5f-" TYPE_ARM_CPU); - object_property_add_child(OBJECT(&s->rpu_cluster), "rpu-cpu[*]", - OBJECT(&s->rpu_cpu[i]), &error_abort); + object_initialize_child(OBJECT(&s->rpu_cluster), "rpu-cpu[*]", + &s->rpu_cpu[i], sizeof(s->rpu_cpu[i]), + "cortex-r5f-" TYPE_ARM_CPU, &error_abort, + NULL); name = object_get_canonical_path_component(OBJECT(&s->rpu_cpu[i])); if (strcmp(name, boot_cpu)) { diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 815e720cfa..dc2c206d9a 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -2595,9 +2595,9 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp) * as we didn't know then if the CPU had the security extensions; * so we have to do it here. */ - object_initialize(&s->systick[M_REG_S], sizeof(s->systick[M_REG_S]), - TYPE_SYSTICK); - qdev_set_parent_bus(DEVICE(&s->systick[M_REG_S]), sysbus_get_default()); + sysbus_init_child_obj(OBJECT(dev), "systick-reg-s", + &s->systick[M_REG_S], + sizeof(s->systick[M_REG_S]), TYPE_SYSTICK); object_property_set_bool(OBJECT(&s->systick[M_REG_S]), true, "realized", &err); diff --git a/hw/microblaze/xlnx-zynqmp-pmu.c b/hw/microblaze/xlnx-zynqmp-pmu.c index 57dc1ccd42..df6c0048aa 100644 --- a/hw/microblaze/xlnx-zynqmp-pmu.c +++ b/hw/microblaze/xlnx-zynqmp-pmu.c @@ -55,6 +55,7 @@ typedef struct XlnxZynqMPPMUSoCState { /*< public >*/ MicroBlazeCPU cpu; XlnxPMUIOIntc intc; + XlnxZynqMPIPI ipi[XLNX_ZYNQMP_PMU_NUM_IPIS]; } XlnxZynqMPPMUSoCState; @@ -67,6 +68,14 @@ static void xlnx_zynqmp_pmu_soc_init(Object *obj) sysbus_init_child_obj(obj, "intc", &s->intc, sizeof(s->intc), TYPE_XLNX_PMU_IO_INTC); + + /* Create the IPI device */ + for (int i = 0; i < XLNX_ZYNQMP_PMU_NUM_IPIS; i++) { + char *name = g_strdup_printf("ipi%d", i); + sysbus_init_child_obj(obj, name, &s->ipi[i], + sizeof(XlnxZynqMPIPI), TYPE_XLNX_ZYNQMP_IPI); + g_free(name); + } } static void xlnx_zynqmp_pmu_soc_realize(DeviceState *dev, Error **errp) @@ -112,6 +121,15 @@ static void xlnx_zynqmp_pmu_soc_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->intc), 0, XLNX_ZYNQMP_PMU_INTC_ADDR); sysbus_connect_irq(SYS_BUS_DEVICE(&s->intc), 0, qdev_get_gpio_in(DEVICE(&s->cpu), MB_CPU_IRQ)); + + /* Connect the IPI device */ + for (int i = 0; i < XLNX_ZYNQMP_PMU_NUM_IPIS; i++) { + object_property_set_bool(OBJECT(&s->ipi[i]), true, "realized", + &error_abort); + sysbus_mmio_map(SYS_BUS_DEVICE(&s->ipi[i]), 0, ipi_addr[i]); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->ipi[i]), 0, + qdev_get_gpio_in(DEVICE(&s->intc), ipi_irq[i])); + } } static void xlnx_zynqmp_pmu_soc_class_init(ObjectClass *oc, void *data) @@ -144,9 +162,6 @@ static void xlnx_zynqmp_pmu_init(MachineState *machine) MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *pmu_rom = g_new(MemoryRegion, 1); MemoryRegion *pmu_ram = g_new(MemoryRegion, 1); - XlnxZynqMPIPI *ipi[XLNX_ZYNQMP_PMU_NUM_IPIS]; - qemu_irq irq[32]; - int i; /* Create the ROM */ memory_region_init_rom(pmu_rom, NULL, "xlnx-zynqmp-pmu.rom", @@ -161,29 +176,11 @@ static void xlnx_zynqmp_pmu_init(MachineState *machine) pmu_ram); /* Create the PMU device */ - object_initialize(pmu, sizeof(XlnxZynqMPPMUSoCState), TYPE_XLNX_ZYNQMP_PMU_SOC); - object_property_add_child(OBJECT(machine), "pmu", OBJECT(pmu), - &error_abort); + object_initialize_child(OBJECT(machine), "pmu", pmu, + sizeof(XlnxZynqMPPMUSoCState), + TYPE_XLNX_ZYNQMP_PMU_SOC, &error_abort, NULL); object_property_set_bool(OBJECT(pmu), true, "realized", &error_fatal); - for (i = 0; i < 32; i++) { - irq[i] = qdev_get_gpio_in(DEVICE(&pmu->intc), i); - } - - /* Create and connect the IPI device */ - for (i = 0; i < XLNX_ZYNQMP_PMU_NUM_IPIS; i++) { - ipi[i] = g_new0(XlnxZynqMPIPI, 1); - object_initialize(ipi[i], sizeof(XlnxZynqMPIPI), TYPE_XLNX_ZYNQMP_IPI); - qdev_set_parent_bus(DEVICE(ipi[i]), sysbus_get_default()); - } - - for (i = 0; i < XLNX_ZYNQMP_PMU_NUM_IPIS; i++) { - object_property_set_bool(OBJECT(ipi[i]), true, "realized", - &error_abort); - sysbus_mmio_map(SYS_BUS_DEVICE(ipi[i]), 0, ipi_addr[i]); - sysbus_connect_irq(SYS_BUS_DEVICE(ipi[i]), 0, irq[ipi_irq[i]]); - } - /* Load the kernel */ microblaze_load_kernel(&pmu->cpu, XLNX_ZYNQMP_PMU_RAM_ADDR, machine->ram_size, diff --git a/hw/mips/boston.c b/hw/mips/boston.c index a8b29f62f5..1ffccc8da9 100644 --- a/hw/mips/boston.c +++ b/hw/mips/boston.c @@ -49,7 +49,7 @@ typedef struct { SysBusDevice parent_obj; MachineState *mach; - MIPSCPSState *cps; + MIPSCPSState cps; SerialState *uart; CharBackend lcd_display; @@ -188,7 +188,7 @@ static uint64_t boston_platreg_read(void *opaque, hwaddr addr, case PLAT_DDR3_STATUS: return PLAT_DDR3_STATUS_LOCKED | PLAT_DDR3_STATUS_CALIBRATED; case PLAT_MMCM_DIV: - gic_freq = mips_gictimer_get_freq(s->cps->gic.gic_timer) / 1000000; + gic_freq = mips_gictimer_get_freq(s->cps.gic.gic_timer) / 1000000; val = gic_freq << PLAT_MMCM_DIV_INPUT_SHIFT; val |= 1 << PLAT_MMCM_DIV_MUL_SHIFT; val |= 1 << PLAT_MMCM_DIV_CLK0DIV_SHIFT; @@ -455,20 +455,19 @@ static void boston_mach_init(MachineState *machine) is_64b = cpu_supports_isa(machine->cpu_type, ISA_MIPS64); - s->cps = MIPS_CPS(object_new(TYPE_MIPS_CPS)); - qdev_set_parent_bus(DEVICE(s->cps), sysbus_get_default()); - - object_property_set_str(OBJECT(s->cps), machine->cpu_type, "cpu-type", + sysbus_init_child_obj(OBJECT(machine), "cps", OBJECT(&s->cps), + sizeof(s->cps), TYPE_MIPS_CPS); + object_property_set_str(OBJECT(&s->cps), machine->cpu_type, "cpu-type", &err); - object_property_set_int(OBJECT(s->cps), smp_cpus, "num-vp", &err); - object_property_set_bool(OBJECT(s->cps), true, "realized", &err); + object_property_set_int(OBJECT(&s->cps), smp_cpus, "num-vp", &err); + object_property_set_bool(OBJECT(&s->cps), true, "realized", &err); if (err != NULL) { error_report("%s", error_get_pretty(err)); exit(1); } - sysbus_mmio_map_overlap(SYS_BUS_DEVICE(s->cps), 0, 0, 1); + sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->cps), 0, 0, 1); flash = g_new(MemoryRegion, 1); memory_region_init_rom(flash, NULL, "boston.flash", 128 * MiB, &err); @@ -487,17 +486,17 @@ static void boston_mach_init(MachineState *machine) xilinx_pcie_init(sys_mem, 0, 0x10000000, 32 * MiB, 0x40000000, 1 * GiB, - get_cps_irq(s->cps, 2), false); + get_cps_irq(&s->cps, 2), false); xilinx_pcie_init(sys_mem, 1, 0x12000000, 32 * MiB, 0x20000000, 512 * MiB, - get_cps_irq(s->cps, 1), false); + get_cps_irq(&s->cps, 1), false); pcie2 = xilinx_pcie_init(sys_mem, 2, 0x14000000, 32 * MiB, 0x16000000, 1 * MiB, - get_cps_irq(s->cps, 0), true); + get_cps_irq(&s->cps, 0), true); platreg = g_new(MemoryRegion, 1); memory_region_init_io(platreg, NULL, &boston_platreg_ops, s, @@ -505,7 +504,7 @@ static void boston_mach_init(MachineState *machine) memory_region_add_subregion_overlap(sys_mem, 0x17ffd000, platreg, 0); s->uart = serial_mm_init(sys_mem, 0x17ffe000, 2, - get_cps_irq(s->cps, 3), 10000000, + get_cps_irq(&s->cps, 3), 10000000, serial_hd(0), DEVICE_NATIVE_ENDIAN); lcd = g_new(MemoryRegion, 1); diff --git a/hw/mips/cps.c b/hw/mips/cps.c index fc97f59af4..649b35a76c 100644 --- a/hw/mips/cps.c +++ b/hw/mips/cps.c @@ -94,9 +94,8 @@ static void mips_cps_realize(DeviceState *dev, Error **errp) /* Inter-Thread Communication Unit */ if (itu_present) { - object_initialize(&s->itu, sizeof(s->itu), TYPE_MIPS_ITU); - qdev_set_parent_bus(DEVICE(&s->itu), sysbus_get_default()); - + sysbus_init_child_obj(OBJECT(dev), "itu", &s->itu, sizeof(s->itu), + TYPE_MIPS_ITU); object_property_set_int(OBJECT(&s->itu), 16, "num-fifo", &err); object_property_set_int(OBJECT(&s->itu), 16, "num-semaphores", &err); object_property_set_bool(OBJECT(&s->itu), saar_present, "saar-present", @@ -115,9 +114,8 @@ static void mips_cps_realize(DeviceState *dev, Error **errp) } /* Cluster Power Controller */ - object_initialize(&s->cpc, sizeof(s->cpc), TYPE_MIPS_CPC); - qdev_set_parent_bus(DEVICE(&s->cpc), sysbus_get_default()); - + sysbus_init_child_obj(OBJECT(dev), "cpc", &s->cpc, sizeof(s->cpc), + TYPE_MIPS_CPC); object_property_set_int(OBJECT(&s->cpc), s->num_vp, "num-vp", &err); object_property_set_int(OBJECT(&s->cpc), 1, "vp-start-running", &err); object_property_set_bool(OBJECT(&s->cpc), true, "realized", &err); @@ -130,9 +128,8 @@ static void mips_cps_realize(DeviceState *dev, Error **errp) sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpc), 0)); /* Global Interrupt Controller */ - object_initialize(&s->gic, sizeof(s->gic), TYPE_MIPS_GIC); - qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default()); - + sysbus_init_child_obj(OBJECT(dev), "gic", &s->gic, sizeof(s->gic), + TYPE_MIPS_GIC); object_property_set_int(OBJECT(&s->gic), s->num_vp, "num-vp", &err); object_property_set_int(OBJECT(&s->gic), 128, "num-irq", &err); object_property_set_bool(OBJECT(&s->gic), true, "realized", &err); @@ -147,9 +144,8 @@ static void mips_cps_realize(DeviceState *dev, Error **errp) /* Global Configuration Registers */ gcr_base = env->CP0_CMGCRBase << 4; - object_initialize(&s->gcr, sizeof(s->gcr), TYPE_MIPS_GCR); - qdev_set_parent_bus(DEVICE(&s->gcr), sysbus_get_default()); - + sysbus_init_child_obj(OBJECT(dev), "gcr", &s->gcr, sizeof(s->gcr), + TYPE_MIPS_GCR); object_property_set_int(OBJECT(&s->gcr), s->num_vp, "num-vp", &err); object_property_set_int(OBJECT(&s->gcr), 0x800, "gcr-rev", &err); object_property_set_int(OBJECT(&s->gcr), gcr_base, "gcr-base", &err); diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 439665ab45..aff8464f2a 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -94,7 +94,7 @@ typedef struct { typedef struct { SysBusDevice parent_obj; - MIPSCPSState *cps; + MIPSCPSState cps; qemu_irq *i8259; } MaltaState; @@ -1151,20 +1151,19 @@ static void create_cps(MaltaState *s, const char *cpu_type, { Error *err = NULL; - s->cps = MIPS_CPS(object_new(TYPE_MIPS_CPS)); - qdev_set_parent_bus(DEVICE(s->cps), sysbus_get_default()); - - object_property_set_str(OBJECT(s->cps), cpu_type, "cpu-type", &err); - object_property_set_int(OBJECT(s->cps), smp_cpus, "num-vp", &err); - object_property_set_bool(OBJECT(s->cps), true, "realized", &err); + sysbus_init_child_obj(OBJECT(s), "cps", OBJECT(&s->cps), sizeof(s->cps), + TYPE_MIPS_CPS); + object_property_set_str(OBJECT(&s->cps), cpu_type, "cpu-type", &err); + object_property_set_int(OBJECT(&s->cps), smp_cpus, "num-vp", &err); + object_property_set_bool(OBJECT(&s->cps), true, "realized", &err); if (err != NULL) { error_report("%s", error_get_pretty(err)); exit(1); } - sysbus_mmio_map_overlap(SYS_BUS_DEVICE(s->cps), 0, 0, 1); + sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->cps), 0, 0, 1); - *i8259_irq = get_cps_irq(s->cps, 3); + *i8259_irq = get_cps_irq(&s->cps, 3); *cbus_irq = NULL; } diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c index 94da85c8d7..b726c73022 100644 --- a/hw/misc/macio/macio.c +++ b/hw/misc/macio/macio.c @@ -346,12 +346,12 @@ static void macio_newworld_realize(PCIDevice *d, Error **errp) object_property_set_bool(OBJECT(&ns->gpio), true, "realized", &err); /* PMU */ - object_initialize(&s->pmu, sizeof(s->pmu), TYPE_VIA_PMU); + object_initialize_child(OBJECT(s), "pmu", &s->pmu, sizeof(s->pmu), + TYPE_VIA_PMU, &error_abort, NULL); object_property_set_link(OBJECT(&s->pmu), OBJECT(sysbus_dev), "gpio", &error_abort); qdev_prop_set_bit(DEVICE(&s->pmu), "has-adb", ns->has_adb); qdev_set_parent_bus(DEVICE(&s->pmu), BUS(&s->macio_bus)); - object_property_add_child(OBJECT(s), "pmu", OBJECT(&s->pmu), NULL); object_property_set_bool(OBJECT(&s->pmu), true, "realized", &err); if (err) { @@ -365,9 +365,9 @@ static void macio_newworld_realize(PCIDevice *d, Error **errp) sysbus_mmio_get_region(sysbus_dev, 0)); } else { /* CUDA */ - object_initialize(&s->cuda, sizeof(s->cuda), TYPE_CUDA); + object_initialize_child(OBJECT(s), "cuda", &s->cuda, sizeof(s->cuda), + TYPE_CUDA, &error_abort, NULL); qdev_set_parent_bus(DEVICE(&s->cuda), BUS(&s->macio_bus)); - object_property_add_child(OBJECT(s), "cuda", OBJECT(&s->cuda), NULL); qdev_prop_set_uint64(DEVICE(&s->cuda), "timebase-frequency", s->frequency); diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index dfb4ea5742..31aa20ee25 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -994,14 +994,12 @@ static void pnv_chip_quad_realize(Pnv9Chip *chip9, Error **errp) PnvCore *pnv_core = PNV_CORE(chip->cores + (i * 4) * typesize); int core_id = CPU_CORE(pnv_core)->core_id; - object_initialize(eq, sizeof(*eq), TYPE_PNV_QUAD); snprintf(eq_name, sizeof(eq_name), "eq[%d]", core_id); + object_initialize_child(OBJECT(chip), eq_name, eq, sizeof(*eq), + TYPE_PNV_QUAD, &error_fatal, NULL); - object_property_add_child(OBJECT(chip), eq_name, OBJECT(eq), - &error_fatal); object_property_set_int(OBJECT(eq), core_id, "id", &error_fatal); object_property_set_bool(OBJECT(eq), true, "realized", &error_fatal); - object_unref(OBJECT(eq)); pnv_xscom_add_subregion(chip, PNV9_XSCOM_EQ_BASE(eq->id), &eq->xscom_regs); @@ -1165,10 +1163,9 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp) continue; } - object_initialize(pnv_core, typesize, typename); snprintf(core_name, sizeof(core_name), "core[%d]", core_hwid); - object_property_add_child(OBJECT(chip), core_name, OBJECT(pnv_core), - &error_fatal); + object_initialize_child(OBJECT(chip), core_name, pnv_core, typesize, + typename, &error_fatal, NULL); object_property_set_int(OBJECT(pnv_core), smp_threads, "nr-threads", &error_fatal); object_property_set_int(OBJECT(pnv_core), core_hwid, @@ -1180,7 +1177,6 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp) OBJECT(chip), &error_fatal); object_property_set_bool(OBJECT(pnv_core), true, "realized", &error_fatal); - object_unref(OBJECT(pnv_core)); /* Each core has an XSCOM MMIO region */ if (!pnv_chip_is_power9(chip)) { diff --git a/hw/riscv/Makefile.objs b/hw/riscv/Makefile.objs index 79bfb3abf9..a65027304a 100644 --- a/hw/riscv/Makefile.objs +++ b/hw/riscv/Makefile.objs @@ -2,6 +2,7 @@ obj-$(CONFIG_SPIKE) += riscv_htif.o obj-$(CONFIG_HART) += riscv_hart.o obj-$(CONFIG_SIFIVE_E) += sifive_e.o obj-$(CONFIG_SIFIVE) += sifive_clint.o +obj-$(CONFIG_SIFIVE) += sifive_gpio.o obj-$(CONFIG_SIFIVE) += sifive_prci.o obj-$(CONFIG_SIFIVE) += sifive_plic.o obj-$(CONFIG_SIFIVE) += sifive_test.o diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c index b1cd11363c..80ac56fa7d 100644 --- a/hw/riscv/sifive_e.c +++ b/hw/riscv/sifive_e.c @@ -146,11 +146,15 @@ static void riscv_sifive_e_soc_init(Object *obj) &error_abort); object_property_set_int(OBJECT(&s->cpus), smp_cpus, "num-harts", &error_abort); + sysbus_init_child_obj(obj, "riscv.sifive.e.gpio0", + &s->gpio, sizeof(s->gpio), + TYPE_SIFIVE_GPIO); } static void riscv_sifive_e_soc_realize(DeviceState *dev, Error **errp) { const struct MemmapEntry *memmap = sifive_e_memmap; + Error *err = NULL; SiFiveESoCState *s = RISCV_E_SOC(dev); MemoryRegion *sys_mem = get_system_memory(); @@ -184,8 +188,28 @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, Error **errp) sifive_mmio_emulate(sys_mem, "riscv.sifive.e.aon", memmap[SIFIVE_E_AON].base, memmap[SIFIVE_E_AON].size); sifive_prci_create(memmap[SIFIVE_E_PRCI].base); - sifive_mmio_emulate(sys_mem, "riscv.sifive.e.gpio0", - memmap[SIFIVE_E_GPIO0].base, memmap[SIFIVE_E_GPIO0].size); + + /* GPIO */ + + object_property_set_bool(OBJECT(&s->gpio), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + + /* Map GPIO registers */ + sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, memmap[SIFIVE_E_GPIO0].base); + + /* Pass all GPIOs to the SOC layer so they are available to the board */ + qdev_pass_gpios(DEVICE(&s->gpio), dev, NULL); + + /* Connect GPIO interrupts to the PLIC */ + for (int i = 0; i < 32; i++) { + sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), i, + qdev_get_gpio_in(DEVICE(s->plic), + SIFIVE_E_GPIO0_IRQ0 + i)); + } + sifive_uart_create(sys_mem, memmap[SIFIVE_E_UART0].base, serial_hd(0), qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_E_UART0_IRQ)); sifive_mmio_emulate(sys_mem, "riscv.sifive.e.qspi0", diff --git a/hw/riscv/sifive_gpio.c b/hw/riscv/sifive_gpio.c new file mode 100644 index 0000000000..06bd8112d7 --- /dev/null +++ b/hw/riscv/sifive_gpio.c @@ -0,0 +1,388 @@ +/* + * sifive System-on-Chip general purpose input/output register definition + * + * Copyright 2019 AdaCore + * + * Base on nrf51_gpio.c: + * + * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de> + * + * 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 "qemu/log.h" +#include "hw/riscv/sifive_gpio.h" +#include "trace.h" + +static void update_output_irq(SIFIVEGPIOState *s) +{ + + uint32_t pending; + uint32_t pin; + + pending = s->high_ip & s->high_ie; + pending |= s->low_ip & s->low_ie; + pending |= s->rise_ip & s->rise_ie; + pending |= s->fall_ip & s->fall_ie; + + for (int i = 0; i < SIFIVE_GPIO_PINS; i++) { + pin = 1 << i; + qemu_set_irq(s->irq[i], (pending & pin) != 0); + trace_sifive_gpio_update_output_irq(i, (pending & pin) != 0); + } +} + +static void update_state(SIFIVEGPIOState *s) +{ + size_t i; + bool prev_ival, in, in_mask, port, out_xor, pull, output_en, input_en, + rise_ip, fall_ip, low_ip, high_ip, oval, actual_value, ival; + + for (i = 0; i < SIFIVE_GPIO_PINS; i++) { + + prev_ival = extract32(s->value, i, 1); + in = extract32(s->in, i, 1); + in_mask = extract32(s->in_mask, i, 1); + port = extract32(s->port, i, 1); + out_xor = extract32(s->out_xor, i, 1); + pull = extract32(s->pue, i, 1); + output_en = extract32(s->output_en, i, 1); + input_en = extract32(s->input_en, i, 1); + rise_ip = extract32(s->rise_ip, i, 1); + fall_ip = extract32(s->fall_ip, i, 1); + low_ip = extract32(s->low_ip, i, 1); + high_ip = extract32(s->high_ip, i, 1); + + /* Output value (IOF not supported) */ + oval = output_en && (port ^ out_xor); + + /* Pin both driven externally and internally */ + if (output_en && in_mask) { + qemu_log_mask(LOG_GUEST_ERROR, "GPIO pin %zu short circuited\n", i); + } + + if (in_mask) { + /* The pin is driven by external device */ + actual_value = in; + } else if (output_en) { + /* The pin is driven by internal circuit */ + actual_value = oval; + } else { + /* Floating? Apply pull-up resistor */ + actual_value = pull; + } + + qemu_set_irq(s->output[i], actual_value); + + /* Input value */ + ival = input_en && actual_value; + + /* Interrupts */ + high_ip = high_ip || ival; + s->high_ip = deposit32(s->high_ip, i, 1, high_ip); + + low_ip = low_ip || !ival; + s->low_ip = deposit32(s->low_ip, i, 1, low_ip); + + rise_ip = rise_ip || (ival && !prev_ival); + s->rise_ip = deposit32(s->rise_ip, i, 1, rise_ip); + + fall_ip = fall_ip || (!ival && prev_ival); + s->fall_ip = deposit32(s->fall_ip, i, 1, fall_ip); + + /* Update value */ + s->value = deposit32(s->value, i, 1, ival); + } + update_output_irq(s); +} + +static uint64_t sifive_gpio_read(void *opaque, hwaddr offset, unsigned int size) +{ + SIFIVEGPIOState *s = SIFIVE_GPIO(opaque); + uint64_t r = 0; + + switch (offset) { + case SIFIVE_GPIO_REG_VALUE: + r = s->value; + break; + + case SIFIVE_GPIO_REG_INPUT_EN: + r = s->input_en; + break; + + case SIFIVE_GPIO_REG_OUTPUT_EN: + r = s->output_en; + break; + + case SIFIVE_GPIO_REG_PORT: + r = s->port; + break; + + case SIFIVE_GPIO_REG_PUE: + r = s->pue; + break; + + case SIFIVE_GPIO_REG_DS: + r = s->ds; + break; + + case SIFIVE_GPIO_REG_RISE_IE: + r = s->rise_ie; + break; + + case SIFIVE_GPIO_REG_RISE_IP: + r = s->rise_ip; + break; + + case SIFIVE_GPIO_REG_FALL_IE: + r = s->fall_ie; + break; + + case SIFIVE_GPIO_REG_FALL_IP: + r = s->fall_ip; + break; + + case SIFIVE_GPIO_REG_HIGH_IE: + r = s->high_ie; + break; + + case SIFIVE_GPIO_REG_HIGH_IP: + r = s->high_ip; + break; + + case SIFIVE_GPIO_REG_LOW_IE: + r = s->low_ie; + break; + + case SIFIVE_GPIO_REG_LOW_IP: + r = s->low_ip; + break; + + case SIFIVE_GPIO_REG_IOF_EN: + r = s->iof_en; + break; + + case SIFIVE_GPIO_REG_IOF_SEL: + r = s->iof_sel; + break; + + case SIFIVE_GPIO_REG_OUT_XOR: + r = s->out_xor; + break; + + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: bad read offset 0x%" HWADDR_PRIx "\n", + __func__, offset); + } + + trace_sifive_gpio_read(offset, r); + + return r; +} + +static void sifive_gpio_write(void *opaque, hwaddr offset, + uint64_t value, unsigned int size) +{ + SIFIVEGPIOState *s = SIFIVE_GPIO(opaque); + + trace_sifive_gpio_write(offset, value); + + switch (offset) { + + case SIFIVE_GPIO_REG_INPUT_EN: + s->input_en = value; + break; + + case SIFIVE_GPIO_REG_OUTPUT_EN: + s->output_en = value; + break; + + case SIFIVE_GPIO_REG_PORT: + s->port = value; + break; + + case SIFIVE_GPIO_REG_PUE: + s->pue = value; + break; + + case SIFIVE_GPIO_REG_DS: + s->ds = value; + break; + + case SIFIVE_GPIO_REG_RISE_IE: + s->rise_ie = value; + break; + + case SIFIVE_GPIO_REG_RISE_IP: + /* Write 1 to clear */ + s->rise_ip &= ~value; + break; + + case SIFIVE_GPIO_REG_FALL_IE: + s->fall_ie = value; + break; + + case SIFIVE_GPIO_REG_FALL_IP: + /* Write 1 to clear */ + s->fall_ip &= ~value; + break; + + case SIFIVE_GPIO_REG_HIGH_IE: + s->high_ie = value; + break; + + case SIFIVE_GPIO_REG_HIGH_IP: + /* Write 1 to clear */ + s->high_ip &= ~value; + break; + + case SIFIVE_GPIO_REG_LOW_IE: + s->low_ie = value; + break; + + case SIFIVE_GPIO_REG_LOW_IP: + /* Write 1 to clear */ + s->low_ip &= ~value; + break; + + case SIFIVE_GPIO_REG_IOF_EN: + s->iof_en = value; + break; + + case SIFIVE_GPIO_REG_IOF_SEL: + s->iof_sel = value; + break; + + case SIFIVE_GPIO_REG_OUT_XOR: + s->out_xor = value; + break; + + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: bad write offset 0x%" HWADDR_PRIx "\n", + __func__, offset); + } + + update_state(s); +} + +static const MemoryRegionOps gpio_ops = { + .read = sifive_gpio_read, + .write = sifive_gpio_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl.min_access_size = 4, + .impl.max_access_size = 4, +}; + +static void sifive_gpio_set(void *opaque, int line, int value) +{ + SIFIVEGPIOState *s = SIFIVE_GPIO(opaque); + + trace_sifive_gpio_set(line, value); + + assert(line >= 0 && line < SIFIVE_GPIO_PINS); + + s->in_mask = deposit32(s->in_mask, line, 1, value >= 0); + if (value >= 0) { + s->in = deposit32(s->in, line, 1, value != 0); + } + + update_state(s); +} + +static void sifive_gpio_reset(DeviceState *dev) +{ + SIFIVEGPIOState *s = SIFIVE_GPIO(dev); + + s->value = 0; + s->input_en = 0; + s->output_en = 0; + s->port = 0; + s->pue = 0; + s->ds = 0; + s->rise_ie = 0; + s->rise_ip = 0; + s->fall_ie = 0; + s->fall_ip = 0; + s->high_ie = 0; + s->high_ip = 0; + s->low_ie = 0; + s->low_ip = 0; + s->iof_en = 0; + s->iof_sel = 0; + s->out_xor = 0; + s->in = 0; + s->in_mask = 0; + +} + +static const VMStateDescription vmstate_sifive_gpio = { + .name = TYPE_SIFIVE_GPIO, + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32(value, SIFIVEGPIOState), + VMSTATE_UINT32(input_en, SIFIVEGPIOState), + VMSTATE_UINT32(output_en, SIFIVEGPIOState), + VMSTATE_UINT32(port, SIFIVEGPIOState), + VMSTATE_UINT32(pue, SIFIVEGPIOState), + VMSTATE_UINT32(rise_ie, SIFIVEGPIOState), + VMSTATE_UINT32(rise_ip, SIFIVEGPIOState), + VMSTATE_UINT32(fall_ie, SIFIVEGPIOState), + VMSTATE_UINT32(fall_ip, SIFIVEGPIOState), + VMSTATE_UINT32(high_ie, SIFIVEGPIOState), + VMSTATE_UINT32(high_ip, SIFIVEGPIOState), + VMSTATE_UINT32(low_ie, SIFIVEGPIOState), + VMSTATE_UINT32(low_ip, SIFIVEGPIOState), + VMSTATE_UINT32(iof_en, SIFIVEGPIOState), + VMSTATE_UINT32(iof_sel, SIFIVEGPIOState), + VMSTATE_UINT32(out_xor, SIFIVEGPIOState), + VMSTATE_UINT32(in, SIFIVEGPIOState), + VMSTATE_UINT32(in_mask, SIFIVEGPIOState), + VMSTATE_END_OF_LIST() + } +}; + +static void sifive_gpio_init(Object *obj) +{ + SIFIVEGPIOState *s = SIFIVE_GPIO(obj); + + memory_region_init_io(&s->mmio, obj, &gpio_ops, s, + TYPE_SIFIVE_GPIO, SIFIVE_GPIO_SIZE); + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); + + + for (int i = 0; i < SIFIVE_GPIO_PINS; i++) { + sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq[i]); + } + + qdev_init_gpio_in(DEVICE(s), sifive_gpio_set, SIFIVE_GPIO_PINS); + qdev_init_gpio_out(DEVICE(s), s->output, SIFIVE_GPIO_PINS); +} + +static void sifive_gpio_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->vmsd = &vmstate_sifive_gpio; + dc->reset = sifive_gpio_reset; + dc->desc = "sifive GPIO"; +} + +static const TypeInfo sifive_gpio_info = { + .name = TYPE_SIFIVE_GPIO, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(SIFIVEGPIOState), + .instance_init = sifive_gpio_init, + .class_init = sifive_gpio_class_init +}; + +static void sifive_gpio_register_types(void) +{ + type_register_static(&sifive_gpio_info); +} + +type_init(sifive_gpio_register_types) diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index 2a000a5800..5b33d4be3b 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -39,6 +39,7 @@ #include "chardev/char.h" #include "sysemu/arch_init.h" #include "sysemu/device_tree.h" +#include "sysemu/qtest.h" #include "exec/address-spaces.h" #include "elf.h" @@ -160,7 +161,89 @@ static void create_fdt(SpikeState *s, const struct MemmapEntry *memmap, qemu_fdt_add_subnode(fdt, "/chosen"); qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline); } - } +} + +static void spike_board_init(MachineState *machine) +{ + const struct MemmapEntry *memmap = spike_memmap; + + SpikeState *s = g_new0(SpikeState, 1); + MemoryRegion *system_memory = get_system_memory(); + MemoryRegion *main_mem = g_new(MemoryRegion, 1); + MemoryRegion *mask_rom = g_new(MemoryRegion, 1); + int i; + + /* Initialize SOC */ + object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc), + TYPE_RISCV_HART_ARRAY, &error_abort, NULL); + object_property_set_str(OBJECT(&s->soc), machine->cpu_type, "cpu-type", + &error_abort); + object_property_set_int(OBJECT(&s->soc), smp_cpus, "num-harts", + &error_abort); + object_property_set_bool(OBJECT(&s->soc), true, "realized", + &error_abort); + + /* register system main memory (actual RAM) */ + memory_region_init_ram(main_mem, NULL, "riscv.spike.ram", + machine->ram_size, &error_fatal); + memory_region_add_subregion(system_memory, memmap[SPIKE_DRAM].base, + main_mem); + + /* create device tree */ + create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline); + + /* boot rom */ + memory_region_init_rom(mask_rom, NULL, "riscv.spike.mrom", + memmap[SPIKE_MROM].size, &error_fatal); + memory_region_add_subregion(system_memory, memmap[SPIKE_MROM].base, + mask_rom); + + if (machine->kernel_filename) { + load_kernel(machine->kernel_filename); + } + + /* reset vector */ + uint32_t reset_vec[8] = { + 0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */ + 0x02028593, /* addi a1, t0, %pcrel_lo(1b) */ + 0xf1402573, /* csrr a0, mhartid */ +#if defined(TARGET_RISCV32) + 0x0182a283, /* lw t0, 24(t0) */ +#elif defined(TARGET_RISCV64) + 0x0182b283, /* ld t0, 24(t0) */ +#endif + 0x00028067, /* jr t0 */ + 0x00000000, + memmap[SPIKE_DRAM].base, /* start: .dword DRAM_BASE */ + 0x00000000, + /* dtb: */ + }; + + /* copy in the reset vector in little_endian byte order */ + for (i = 0; i < sizeof(reset_vec) >> 2; i++) { + reset_vec[i] = cpu_to_le32(reset_vec[i]); + } + rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), + memmap[SPIKE_MROM].base, &address_space_memory); + + /* copy in the device tree */ + if (fdt_pack(s->fdt) || fdt_totalsize(s->fdt) > + memmap[SPIKE_MROM].size - sizeof(reset_vec)) { + error_report("not enough space to store device-tree"); + exit(1); + } + qemu_fdt_dumpdtb(s->fdt, fdt_totalsize(s->fdt)); + rom_add_blob_fixed_as("mrom.fdt", s->fdt, fdt_totalsize(s->fdt), + memmap[SPIKE_MROM].base + sizeof(reset_vec), + &address_space_memory); + + /* initialize HTIF using symbols found in load_kernel */ + htif_mm_init(system_memory, mask_rom, &s->soc.harts[0].env, serial_hd(0)); + + /* Core Local Interruptor (timer and IPI) */ + sifive_clint_create(memmap[SPIKE_CLINT].base, memmap[SPIKE_CLINT].size, + smp_cpus, SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE); +} static void spike_v1_10_0_board_init(MachineState *machine) { @@ -172,6 +255,12 @@ static void spike_v1_10_0_board_init(MachineState *machine) MemoryRegion *mask_rom = g_new(MemoryRegion, 1); int i; + if (!qtest_enabled()) { + info_report("The Spike v1.10.0 machine has been deprecated. " + "Please use the generic spike machine and specify the ISA " + "versions using -cpu."); + } + /* Initialize SOC */ object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY, &error_abort, NULL); @@ -254,6 +343,12 @@ static void spike_v1_09_1_board_init(MachineState *machine) MemoryRegion *mask_rom = g_new(MemoryRegion, 1); int i; + if (!qtest_enabled()) { + info_report("The Spike v1.09.1 machine has been deprecated. " + "Please use the generic spike machine and specify the ISA " + "versions using -cpu."); + } + /* Initialize SOC */ object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY, &error_abort, NULL); @@ -359,8 +454,17 @@ static void spike_v1_10_0_machine_init(MachineClass *mc) mc->desc = "RISC-V Spike Board (Privileged ISA v1.10)"; mc->init = spike_v1_10_0_board_init; mc->max_cpus = 1; +} + +static void spike_machine_init(MachineClass *mc) +{ + mc->desc = "RISC-V Spike Board"; + mc->init = spike_board_init; + mc->max_cpus = 1; mc->is_default = 1; + mc->default_cpu_type = SPIKE_V1_10_0_CPU; } DEFINE_MACHINE("spike_v1.9.1", spike_v1_09_1_machine_init) DEFINE_MACHINE("spike_v1.10", spike_v1_10_0_machine_init) +DEFINE_MACHINE("spike", spike_machine_init) diff --git a/hw/riscv/trace-events b/hw/riscv/trace-events new file mode 100644 index 0000000000..6d59233e23 --- /dev/null +++ b/hw/riscv/trace-events @@ -0,0 +1,7 @@ +# See docs/devel/tracing.txt for syntax documentation. + +# hw/gpio/sifive_gpio.c +sifive_gpio_read(uint64_t offset, uint64_t r) "offset 0x%" PRIx64 " value 0x%" PRIx64 +sifive_gpio_write(uint64_t offset, uint64_t value) "offset 0x%" PRIx64 " value 0x%" PRIx64 +sifive_gpio_set(int64_t line, int64_t value) "line %" PRIi64 " value %" PRIi64 +sifive_gpio_update_output_irq(int64_t line, int64_t value) "line %" PRIi64 " value %" PRIi64 diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index fc4c6b306e..84d94d0c42 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -29,7 +29,6 @@ #include "hw/sysbus.h" #include "hw/char/serial.h" #include "target/riscv/cpu.h" -#include "hw/riscv/riscv_htif.h" #include "hw/riscv/riscv_hart.h" #include "hw/riscv/sifive_plic.h" #include "hw/riscv/sifive_clint.h" @@ -400,7 +399,7 @@ static void riscv_virt_board_init(MachineState *machine) /* Initialize SOC */ object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY, &error_abort, NULL); - object_property_set_str(OBJECT(&s->soc), VIRT_CPU, "cpu-type", + object_property_set_str(OBJECT(&s->soc), machine->cpu_type, "cpu-type", &error_abort); object_property_set_int(OBJECT(&s->soc), smp_cpus, "num-harts", &error_abort); @@ -526,6 +525,7 @@ static void riscv_virt_board_machine_init(MachineClass *mc) mc->desc = "RISC-V VirtIO Board (Privileged ISA v1.10)"; mc->init = riscv_virt_board_init; mc->max_cpus = 8; /* hardcoded limit in BBL */ + mc->default_cpu_type = VIRT_CPU; } DEFINE_MACHINE("virt", riscv_virt_board_machine_init) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 4805727b53..07f4a64b48 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -2312,9 +2312,8 @@ void virtio_instance_init_common(Object *proxy_obj, void *data, { DeviceState *vdev = data; - object_initialize(vdev, vdev_size, vdev_name); - object_property_add_child(proxy_obj, "virtio-backend", OBJECT(vdev), NULL); - object_unref(OBJECT(vdev)); + object_initialize_child(proxy_obj, "virtio-backend", vdev, vdev_size, + vdev_name, &error_abort, NULL); qdev_alias_all_properties(vdev, proxy_obj); } |