diff options
Diffstat (limited to 'hw')
33 files changed, 1191 insertions, 565 deletions
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index 028191ff36..cc06af4fbb 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -92,6 +92,10 @@ struct AspeedBoardState { #define AST2600_EVB_HW_STRAP1 0x000000C0 #define AST2600_EVB_HW_STRAP2 0x00000003 +/* Tacoma hardware value */ +#define TACOMA_BMC_HW_STRAP1 0x00000000 +#define TACOMA_BMC_HW_STRAP2 0x00000000 + /* * The max ram region is for firmwares that scan the address space * with load/store to guess how much RAM the SoC has. @@ -167,10 +171,10 @@ static void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype, } } -static void aspeed_board_init(MachineState *machine, - const AspeedBoardConfig *cfg) +static void aspeed_machine_init(MachineState *machine) { AspeedBoardState *bmc; + AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine); AspeedSoCClass *sc; DriveInfo *drive0 = drive_get(IF_MTD, 0, 0); ram_addr_t max_ram_size; @@ -182,18 +186,18 @@ static void aspeed_board_init(MachineState *machine, UINT32_MAX); object_initialize_child(OBJECT(machine), "soc", &bmc->soc, - (sizeof(bmc->soc)), cfg->soc_name, &error_abort, + (sizeof(bmc->soc)), amc->soc_name, &error_abort, NULL); sc = ASPEED_SOC_GET_CLASS(&bmc->soc); object_property_set_uint(OBJECT(&bmc->soc), ram_size, "ram-size", &error_abort); - object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap1, "hw-strap1", + object_property_set_int(OBJECT(&bmc->soc), amc->hw_strap1, "hw-strap1", &error_abort); - object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap2, "hw-strap2", + object_property_set_int(OBJECT(&bmc->soc), amc->hw_strap2, "hw-strap2", &error_abort); - object_property_set_int(OBJECT(&bmc->soc), cfg->num_cs, "num-cs", + object_property_set_int(OBJECT(&bmc->soc), amc->num_cs, "num-cs", &error_abort); object_property_set_int(OBJECT(&bmc->soc), machine->smp.cpus, "num-cpus", &error_abort); @@ -230,8 +234,8 @@ static void aspeed_board_init(MachineState *machine, "max_ram", max_ram_size - ram_size); memory_region_add_subregion(&bmc->ram_container, ram_size, &bmc->max_ram); - aspeed_board_init_flashes(&bmc->soc.fmc, cfg->fmc_model, &error_abort); - aspeed_board_init_flashes(&bmc->soc.spi[0], cfg->spi_model, &error_abort); + aspeed_board_init_flashes(&bmc->soc.fmc, amc->fmc_model, &error_abort); + aspeed_board_init_flashes(&bmc->soc.spi[0], amc->spi_model, &error_abort); /* Install first FMC flash content as a boot rom. */ if (drive0) { @@ -255,8 +259,8 @@ static void aspeed_board_init(MachineState *machine, aspeed_board_binfo.loader_start = sc->memmap[ASPEED_SDRAM]; aspeed_board_binfo.nb_cpus = bmc->soc.num_cpus; - if (cfg->i2c_init) { - cfg->i2c_init(bmc); + if (amc->i2c_init) { + amc->i2c_init(bmc); } for (i = 0; i < ARRAY_SIZE(bmc->soc.sdhci.slots); i++) { @@ -363,6 +367,9 @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc) AspeedSoCState *soc = &bmc->soc; uint8_t *eeprom_buf = g_malloc0(8 * 1024); + /* Bus 3: TODO bmp280@77 */ + /* Bus 3: TODO max31785@52 */ + /* Bus 3: TODO dps310@76 */ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), TYPE_PCA9552, 0x60); @@ -381,120 +388,164 @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc) eeprom_buf); i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), TYPE_PCA9552, 0x60); -} - -static void aspeed_machine_init(MachineState *machine) -{ - AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine); - - aspeed_board_init(machine, amc->board); + /* Bus 11: TODO ucd90160@64 */ } static void aspeed_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); - AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); - const AspeedBoardConfig *board = data; - mc->desc = board->desc; mc->init = aspeed_machine_init; mc->max_cpus = ASPEED_CPUS_NUM; mc->no_floppy = 1; mc->no_cdrom = 1; mc->no_parallel = 1; - if (board->ram) { - mc->default_ram_size = board->ram; - } - amc->board = board; } -static const TypeInfo aspeed_machine_type = { - .name = TYPE_ASPEED_MACHINE, - .parent = TYPE_MACHINE, - .instance_size = sizeof(AspeedMachine), - .class_size = sizeof(AspeedMachineClass), - .abstract = true, +static void aspeed_machine_palmetto_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); + + mc->desc = "OpenPOWER Palmetto BMC (ARM926EJ-S)"; + amc->soc_name = "ast2400-a1"; + amc->hw_strap1 = PALMETTO_BMC_HW_STRAP1; + amc->fmc_model = "n25q256a"; + amc->spi_model = "mx25l25635e"; + amc->num_cs = 1; + amc->i2c_init = palmetto_bmc_i2c_init; + mc->default_ram_size = 256 * MiB; +}; + +static void aspeed_machine_ast2500_evb_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); + + mc->desc = "Aspeed AST2500 EVB (ARM1176)"; + amc->soc_name = "ast2500-a1"; + amc->hw_strap1 = AST2500_EVB_HW_STRAP1; + amc->fmc_model = "w25q256"; + amc->spi_model = "mx25l25635e"; + amc->num_cs = 1; + amc->i2c_init = ast2500_evb_i2c_init; + mc->default_ram_size = 512 * MiB; +}; + +static void aspeed_machine_romulus_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); + + mc->desc = "OpenPOWER Romulus BMC (ARM1176)"; + amc->soc_name = "ast2500-a1"; + amc->hw_strap1 = ROMULUS_BMC_HW_STRAP1; + amc->fmc_model = "n25q256a"; + amc->spi_model = "mx66l1g45g"; + amc->num_cs = 2; + amc->i2c_init = romulus_bmc_i2c_init; + mc->default_ram_size = 512 * MiB; +}; + +static void aspeed_machine_swift_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); + + mc->desc = "OpenPOWER Swift BMC (ARM1176)"; + amc->soc_name = "ast2500-a1"; + amc->hw_strap1 = SWIFT_BMC_HW_STRAP1; + amc->fmc_model = "mx66l1g45g"; + amc->spi_model = "mx66l1g45g"; + amc->num_cs = 2; + amc->i2c_init = swift_bmc_i2c_init; + mc->default_ram_size = 512 * MiB; +}; + +static void aspeed_machine_witherspoon_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); + + mc->desc = "OpenPOWER Witherspoon BMC (ARM1176)"; + amc->soc_name = "ast2500-a1"; + amc->hw_strap1 = WITHERSPOON_BMC_HW_STRAP1; + amc->fmc_model = "mx25l25635e"; + amc->spi_model = "mx66l1g45g"; + amc->num_cs = 2; + amc->i2c_init = witherspoon_bmc_i2c_init; + mc->default_ram_size = 512 * MiB; +}; + +static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); + + mc->desc = "Aspeed AST2600 EVB (Cortex A7)"; + amc->soc_name = "ast2600-a0"; + amc->hw_strap1 = AST2600_EVB_HW_STRAP1; + amc->hw_strap2 = AST2600_EVB_HW_STRAP2; + amc->fmc_model = "w25q512jv"; + amc->spi_model = "mx66u51235f"; + amc->num_cs = 1; + amc->i2c_init = ast2600_evb_i2c_init; + mc->default_ram_size = 1 * GiB; }; -static const AspeedBoardConfig aspeed_boards[] = { +static void aspeed_machine_tacoma_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); + + mc->desc = "Aspeed AST2600 EVB (Cortex A7)"; + amc->soc_name = "ast2600-a0"; + amc->hw_strap1 = TACOMA_BMC_HW_STRAP1; + amc->hw_strap2 = TACOMA_BMC_HW_STRAP2; + amc->fmc_model = "mx66l1g45g"; + amc->spi_model = "mx66l1g45g"; + amc->num_cs = 2; + amc->i2c_init = witherspoon_bmc_i2c_init; /* Same board layout */ + mc->default_ram_size = 1 * GiB; +}; + +static const TypeInfo aspeed_machine_types[] = { { - .name = MACHINE_TYPE_NAME("palmetto-bmc"), - .desc = "OpenPOWER Palmetto BMC (ARM926EJ-S)", - .soc_name = "ast2400-a1", - .hw_strap1 = PALMETTO_BMC_HW_STRAP1, - .fmc_model = "n25q256a", - .spi_model = "mx25l25635e", - .num_cs = 1, - .i2c_init = palmetto_bmc_i2c_init, - .ram = 256 * MiB, + .name = MACHINE_TYPE_NAME("palmetto-bmc"), + .parent = TYPE_ASPEED_MACHINE, + .class_init = aspeed_machine_palmetto_class_init, }, { - .name = MACHINE_TYPE_NAME("ast2500-evb"), - .desc = "Aspeed AST2500 EVB (ARM1176)", - .soc_name = "ast2500-a1", - .hw_strap1 = AST2500_EVB_HW_STRAP1, - .fmc_model = "w25q256", - .spi_model = "mx25l25635e", - .num_cs = 1, - .i2c_init = ast2500_evb_i2c_init, - .ram = 512 * MiB, + .name = MACHINE_TYPE_NAME("ast2500-evb"), + .parent = TYPE_ASPEED_MACHINE, + .class_init = aspeed_machine_ast2500_evb_class_init, }, { - .name = MACHINE_TYPE_NAME("romulus-bmc"), - .desc = "OpenPOWER Romulus BMC (ARM1176)", - .soc_name = "ast2500-a1", - .hw_strap1 = ROMULUS_BMC_HW_STRAP1, - .fmc_model = "n25q256a", - .spi_model = "mx66l1g45g", - .num_cs = 2, - .i2c_init = romulus_bmc_i2c_init, - .ram = 512 * MiB, + .name = MACHINE_TYPE_NAME("romulus-bmc"), + .parent = TYPE_ASPEED_MACHINE, + .class_init = aspeed_machine_romulus_class_init, }, { - .name = MACHINE_TYPE_NAME("swift-bmc"), - .desc = "OpenPOWER Swift BMC (ARM1176)", - .soc_name = "ast2500-a1", - .hw_strap1 = SWIFT_BMC_HW_STRAP1, - .fmc_model = "mx66l1g45g", - .spi_model = "mx66l1g45g", - .num_cs = 2, - .i2c_init = swift_bmc_i2c_init, - .ram = 512 * MiB, + .name = MACHINE_TYPE_NAME("swift-bmc"), + .parent = TYPE_ASPEED_MACHINE, + .class_init = aspeed_machine_swift_class_init, }, { - .name = MACHINE_TYPE_NAME("witherspoon-bmc"), - .desc = "OpenPOWER Witherspoon BMC (ARM1176)", - .soc_name = "ast2500-a1", - .hw_strap1 = WITHERSPOON_BMC_HW_STRAP1, - .fmc_model = "mx25l25635e", - .spi_model = "mx66l1g45g", - .num_cs = 2, - .i2c_init = witherspoon_bmc_i2c_init, - .ram = 512 * MiB, + .name = MACHINE_TYPE_NAME("witherspoon-bmc"), + .parent = TYPE_ASPEED_MACHINE, + .class_init = aspeed_machine_witherspoon_class_init, }, { - .name = MACHINE_TYPE_NAME("ast2600-evb"), - .desc = "Aspeed AST2600 EVB (Cortex A7)", - .soc_name = "ast2600-a0", - .hw_strap1 = AST2600_EVB_HW_STRAP1, - .hw_strap2 = AST2600_EVB_HW_STRAP2, - .fmc_model = "w25q512jv", - .spi_model = "mx66u51235f", - .num_cs = 1, - .i2c_init = ast2600_evb_i2c_init, - .ram = 1 * GiB, - }, -}; - -static void aspeed_machine_types(void) -{ - int i; - - type_register_static(&aspeed_machine_type); - for (i = 0; i < ARRAY_SIZE(aspeed_boards); ++i) { - TypeInfo ti = { - .name = aspeed_boards[i].name, - .parent = TYPE_ASPEED_MACHINE, - .class_init = aspeed_machine_class_init, - .class_data = (void *)&aspeed_boards[i], - }; - type_register(&ti); + .name = MACHINE_TYPE_NAME("ast2600-evb"), + .parent = TYPE_ASPEED_MACHINE, + .class_init = aspeed_machine_ast2600_evb_class_init, + }, { + .name = MACHINE_TYPE_NAME("tacoma-bmc"), + .parent = TYPE_ASPEED_MACHINE, + .class_init = aspeed_machine_tacoma_class_init, + }, { + .name = TYPE_ASPEED_MACHINE, + .parent = TYPE_MACHINE, + .instance_size = sizeof(AspeedMachine), + .class_size = sizeof(AspeedMachineClass), + .class_init = aspeed_machine_class_init, + .abstract = true, } -} +}; -type_init(aspeed_machine_types) +DEFINE_TYPES(aspeed_machine_types) diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c index 931887ac68..be88005dab 100644 --- a/hw/arm/aspeed_ast2600.c +++ b/hw/arm/aspeed_ast2600.c @@ -146,8 +146,6 @@ static void aspeed_soc_ast2600_init(Object *obj) snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname); sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl), sizeof(s->timerctrl), typename); - object_property_add_const_link(OBJECT(&s->timerctrl), "scu", - OBJECT(&s->scu), &error_abort); snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname); sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c), @@ -158,8 +156,6 @@ static void aspeed_soc_ast2600_init(Object *obj) typename); object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs", &error_abort); - object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram", - &error_abort); for (i = 0; i < sc->spis_num; i++) { snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname); @@ -179,8 +175,6 @@ static void aspeed_soc_ast2600_init(Object *obj) snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname); sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]), sizeof(s->wdt[i]), typename); - object_property_add_const_link(OBJECT(&s->wdt[i]), "scu", - OBJECT(&s->scu), &error_abort); } for (i = 0; i < sc->macs_num; i++) { @@ -189,9 +183,6 @@ static void aspeed_soc_ast2600_init(Object *obj) sysbus_init_child_obj(obj, "mii[*]", &s->mii[i], sizeof(s->mii[i]), TYPE_ASPEED_MII); - object_property_add_const_link(OBJECT(&s->mii[i]), "nic", - OBJECT(&s->ftgmac100[i]), - &error_abort); } sysbus_init_child_obj(obj, "xdma", OBJECT(&s->xdma), sizeof(s->xdma), @@ -325,6 +316,8 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp) aspeed_soc_get_irq(s, ASPEED_RTC)); /* Timer */ + object_property_set_link(OBJECT(&s->timerctrl), + OBJECT(&s->scu), "scu", &error_abort); object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err); if (err) { error_propagate(errp, err); @@ -345,6 +338,11 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp) } /* I2C */ + object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", &err); + if (err) { + error_propagate(errp, err); + return; + } object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err); if (err) { error_propagate(errp, err); @@ -362,6 +360,11 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp) } /* FMC, The number of CS is set at the board level */ + object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", &err); + if (err) { + error_propagate(errp, err); + return; + } object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM], "sdram-base", &err); if (err) { @@ -407,6 +410,8 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp) for (i = 0; i < sc->wdts_num; i++) { AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]); + object_property_set_link(OBJECT(&s->wdt[i]), + OBJECT(&s->scu), "scu", &error_abort); object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err); if (err) { error_propagate(errp, err); @@ -433,6 +438,8 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp) sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0, aspeed_soc_get_irq(s, ASPEED_ETH1 + i)); + object_property_set_link(OBJECT(&s->mii[i]), OBJECT(&s->ftgmac100[i]), + "nic", &error_abort); object_property_set_bool(OBJECT(&s->mii[i]), true, "realized", &err); if (err) { diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c index f4fe243458..a6237e5940 100644 --- a/hw/arm/aspeed_soc.c +++ b/hw/arm/aspeed_soc.c @@ -163,8 +163,6 @@ static void aspeed_soc_init(Object *obj) snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname); sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl), sizeof(s->timerctrl), typename); - object_property_add_const_link(OBJECT(&s->timerctrl), "scu", - OBJECT(&s->scu), &error_abort); snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname); sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c), @@ -175,8 +173,6 @@ static void aspeed_soc_init(Object *obj) typename); object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs", &error_abort); - object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram", - &error_abort); for (i = 0; i < sc->spis_num; i++) { snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname); @@ -196,8 +192,6 @@ static void aspeed_soc_init(Object *obj) snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname); sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]), sizeof(s->wdt[i]), typename); - object_property_add_const_link(OBJECT(&s->wdt[i]), "scu", - OBJECT(&s->scu), &error_abort); } for (i = 0; i < sc->macs_num; i++) { @@ -293,6 +287,8 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp) aspeed_soc_get_irq(s, ASPEED_RTC)); /* Timer */ + object_property_set_link(OBJECT(&s->timerctrl), + OBJECT(&s->scu), "scu", &error_abort); object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err); if (err) { error_propagate(errp, err); @@ -313,6 +309,11 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp) } /* I2C */ + object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", &err); + if (err) { + error_propagate(errp, err); + return; + } object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err); if (err) { error_propagate(errp, err); @@ -323,6 +324,11 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp) aspeed_soc_get_irq(s, ASPEED_I2C)); /* FMC, The number of CS is set at the board level */ + object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", &err); + if (err) { + error_propagate(errp, err); + return; + } object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM], "sdram-base", &err); if (err) { @@ -368,6 +374,8 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp) for (i = 0; i < sc->wdts_num; i++) { AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]); + object_property_set_link(OBJECT(&s->wdt[i]), + OBJECT(&s->scu), "scu", &error_abort); object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err); if (err) { error_propagate(errp, err); @@ -429,6 +437,8 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp) } static Property aspeed_soc_properties[] = { DEFINE_PROP_UINT32("num-cpus", AspeedSoCState, num_cpus, 0), + DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION, + MemoryRegion *), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c index 27046cc284..5853bdee5c 100644 --- a/hw/arm/sbsa-ref.c +++ b/hw/arm/sbsa-ref.c @@ -89,6 +89,7 @@ typedef struct { void *fdt; int fdt_size; int psci_conduit; + DeviceState *gic; PFlashCFI01 *flash[2]; } SBSAMachineState; @@ -328,10 +329,9 @@ static void create_secure_ram(SBSAMachineState *sms, memory_region_add_subregion(secure_sysmem, base, secram); } -static void create_gic(SBSAMachineState *sms, qemu_irq *pic) +static void create_gic(SBSAMachineState *sms) { unsigned int smp_cpus = MACHINE(sms)->smp.cpus; - DeviceState *gicdev; SysBusDevice *gicbusdev; const char *gictype; uint32_t redist0_capacity, redist0_count; @@ -339,25 +339,25 @@ static void create_gic(SBSAMachineState *sms, qemu_irq *pic) gictype = gicv3_class_name(); - gicdev = qdev_create(NULL, gictype); - qdev_prop_set_uint32(gicdev, "revision", 3); - qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus); + sms->gic = qdev_create(NULL, gictype); + qdev_prop_set_uint32(sms->gic, "revision", 3); + qdev_prop_set_uint32(sms->gic, "num-cpu", smp_cpus); /* * Note that the num-irq property counts both internal and external * interrupts; there are always 32 of the former (mandated by GIC spec). */ - qdev_prop_set_uint32(gicdev, "num-irq", NUM_IRQS + 32); - qdev_prop_set_bit(gicdev, "has-security-extensions", true); + qdev_prop_set_uint32(sms->gic, "num-irq", NUM_IRQS + 32); + qdev_prop_set_bit(sms->gic, "has-security-extensions", true); redist0_capacity = sbsa_ref_memmap[SBSA_GIC_REDIST].size / GICV3_REDIST_SIZE; redist0_count = MIN(smp_cpus, redist0_capacity); - qdev_prop_set_uint32(gicdev, "len-redist-region-count", 1); - qdev_prop_set_uint32(gicdev, "redist-region-count[0]", redist0_count); + qdev_prop_set_uint32(sms->gic, "len-redist-region-count", 1); + qdev_prop_set_uint32(sms->gic, "redist-region-count[0]", redist0_count); - qdev_init_nofail(gicdev); - gicbusdev = SYS_BUS_DEVICE(gicdev); + qdev_init_nofail(sms->gic); + gicbusdev = SYS_BUS_DEVICE(sms->gic); sysbus_mmio_map(gicbusdev, 0, sbsa_ref_memmap[SBSA_GIC_DIST].base); sysbus_mmio_map(gicbusdev, 1, sbsa_ref_memmap[SBSA_GIC_REDIST].base); @@ -383,15 +383,15 @@ static void create_gic(SBSAMachineState *sms, qemu_irq *pic) for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) { qdev_connect_gpio_out(cpudev, irq, - qdev_get_gpio_in(gicdev, + qdev_get_gpio_in(sms->gic, ppibase + timer_irq[irq])); } qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 0, - qdev_get_gpio_in(gicdev, ppibase + qdev_get_gpio_in(sms->gic, ppibase + ARCH_GIC_MAINT_IRQ)); qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0, - qdev_get_gpio_in(gicdev, ppibase + qdev_get_gpio_in(sms->gic, ppibase + VIRTUAL_PMU_IRQ)); sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ)); @@ -402,13 +402,9 @@ static void create_gic(SBSAMachineState *sms, qemu_irq *pic) sysbus_connect_irq(gicbusdev, i + 3 * smp_cpus, qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ)); } - - for (i = 0; i < NUM_IRQS; i++) { - pic[i] = qdev_get_gpio_in(gicdev, i); - } } -static void create_uart(const SBSAMachineState *sms, qemu_irq *pic, int uart, +static void create_uart(const SBSAMachineState *sms, int uart, MemoryRegion *mem, Chardev *chr) { hwaddr base = sbsa_ref_memmap[uart].base; @@ -420,15 +416,15 @@ static void create_uart(const SBSAMachineState *sms, qemu_irq *pic, int uart, qdev_init_nofail(dev); memory_region_add_subregion(mem, base, sysbus_mmio_get_region(s, 0)); - sysbus_connect_irq(s, 0, pic[irq]); + sysbus_connect_irq(s, 0, qdev_get_gpio_in(sms->gic, irq)); } -static void create_rtc(const SBSAMachineState *sms, qemu_irq *pic) +static void create_rtc(const SBSAMachineState *sms) { hwaddr base = sbsa_ref_memmap[SBSA_RTC].base; int irq = sbsa_ref_irqmap[SBSA_RTC]; - sysbus_create_simple("pl031", base, pic[irq]); + sysbus_create_simple("pl031", base, qdev_get_gpio_in(sms->gic, irq)); } static DeviceState *gpio_key_dev; @@ -442,13 +438,14 @@ static Notifier sbsa_ref_powerdown_notifier = { .notify = sbsa_ref_powerdown_req }; -static void create_gpio(const SBSAMachineState *sms, qemu_irq *pic) +static void create_gpio(const SBSAMachineState *sms) { DeviceState *pl061_dev; hwaddr base = sbsa_ref_memmap[SBSA_GPIO].base; int irq = sbsa_ref_irqmap[SBSA_GPIO]; - pl061_dev = sysbus_create_simple("pl061", base, pic[irq]); + pl061_dev = sysbus_create_simple("pl061", base, + qdev_get_gpio_in(sms->gic, irq)); gpio_key_dev = sysbus_create_simple("gpio-key", -1, qdev_get_gpio_in(pl061_dev, 3)); @@ -457,7 +454,7 @@ static void create_gpio(const SBSAMachineState *sms, qemu_irq *pic) qemu_register_powerdown_notifier(&sbsa_ref_powerdown_notifier); } -static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic) +static void create_ahci(const SBSAMachineState *sms) { hwaddr base = sbsa_ref_memmap[SBSA_AHCI].base; int irq = sbsa_ref_irqmap[SBSA_AHCI]; @@ -471,7 +468,7 @@ static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic) qdev_prop_set_uint32(dev, "num-ports", NUM_SATA_PORTS); qdev_init_nofail(dev); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irq]); + sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(sms->gic, irq)); sysahci = SYSBUS_AHCI(dev); ahci = &sysahci->ahci; @@ -484,16 +481,16 @@ static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic) } } -static void create_ehci(const SBSAMachineState *sms, qemu_irq *pic) +static void create_ehci(const SBSAMachineState *sms) { hwaddr base = sbsa_ref_memmap[SBSA_EHCI].base; int irq = sbsa_ref_irqmap[SBSA_EHCI]; - sysbus_create_simple("platform-ehci-usb", base, pic[irq]); + sysbus_create_simple("platform-ehci-usb", base, + qdev_get_gpio_in(sms->gic, irq)); } -static void create_smmu(const SBSAMachineState *sms, qemu_irq *pic, - PCIBus *bus) +static void create_smmu(const SBSAMachineState *sms, PCIBus *bus) { hwaddr base = sbsa_ref_memmap[SBSA_SMMU].base; int irq = sbsa_ref_irqmap[SBSA_SMMU]; @@ -507,11 +504,12 @@ static void create_smmu(const SBSAMachineState *sms, qemu_irq *pic, qdev_init_nofail(dev); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); for (i = 0; i < NUM_SMMU_IRQS; i++) { - sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]); + sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, + qdev_get_gpio_in(sms->gic, irq + 1)); } } -static void create_pcie(SBSAMachineState *sms, qemu_irq *pic) +static void create_pcie(SBSAMachineState *sms) { hwaddr base_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].base; hwaddr size_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].size; @@ -555,7 +553,8 @@ static void create_pcie(SBSAMachineState *sms, qemu_irq *pic) sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio); for (i = 0; i < GPEX_NUM_IRQS; i++) { - sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]); + sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, + qdev_get_gpio_in(sms->gic, irq + 1)); gpex_set_irq_num(GPEX_HOST(dev), i, irq + i); } @@ -574,7 +573,7 @@ static void create_pcie(SBSAMachineState *sms, qemu_irq *pic) pci_create_simple(pci->bus, -1, "VGA"); - create_smmu(sms, pic, pci->bus); + create_smmu(sms, pci->bus); } static void *sbsa_ref_dtb(const struct arm_boot_info *binfo, int *fdt_size) @@ -598,7 +597,6 @@ static void sbsa_ref_init(MachineState *machine) bool firmware_loaded; const CPUArchIdList *possible_cpus; int n, sbsa_max_cpus; - qemu_irq pic[NUM_IRQS]; if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a57"))) { error_report("sbsa-ref: CPU type other than the built-in " @@ -695,22 +693,22 @@ static void sbsa_ref_init(MachineState *machine) create_secure_ram(sms, secure_sysmem); - create_gic(sms, pic); + create_gic(sms); - create_uart(sms, pic, SBSA_UART, sysmem, serial_hd(0)); - create_uart(sms, pic, SBSA_SECURE_UART, secure_sysmem, serial_hd(1)); + create_uart(sms, SBSA_UART, sysmem, serial_hd(0)); + create_uart(sms, SBSA_SECURE_UART, secure_sysmem, serial_hd(1)); /* Second secure UART for RAS and MM from EL0 */ - create_uart(sms, pic, SBSA_SECURE_UART_MM, secure_sysmem, serial_hd(2)); + create_uart(sms, SBSA_SECURE_UART_MM, secure_sysmem, serial_hd(2)); - create_rtc(sms, pic); + create_rtc(sms); - create_gpio(sms, pic); + create_gpio(sms); - create_ahci(sms, pic); + create_ahci(sms); - create_ehci(sms, pic); + create_ehci(sms); - create_pcie(sms, pic); + create_pcie(sms); sms->bootinfo.ram_size = machine->ram_size; sms->bootinfo.nb_cpus = smp_cpus; diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 4cd50175e0..bd5f771e9b 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -267,17 +267,22 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3")); aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP"))); aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL"))); - aml_append(ifctx, aml_store(aml_and(aml_name("CTRL"), aml_int(0x1D), NULL), - aml_name("CTRL"))); + + /* + * Allow OS control for all 5 features: + * PCIeHotplug SHPCHotplug PME AER PCIeCapability. + */ + aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1F), + aml_name("CTRL"))); ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1)))); - aml_append(ifctx1, aml_store(aml_or(aml_name("CDW1"), aml_int(0x08), NULL), - aml_name("CDW1"))); + aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x08), + aml_name("CDW1"))); aml_append(ifctx, ifctx1); ifctx1 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), aml_name("CTRL")))); - aml_append(ifctx1, aml_store(aml_or(aml_name("CDW1"), aml_int(0x10), NULL), - aml_name("CDW1"))); + aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x10), + aml_name("CDW1"))); aml_append(ifctx, ifctx1); aml_append(ifctx, aml_store(aml_name("CTRL"), aml_name("CDW3"))); @@ -285,8 +290,8 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, aml_append(method, ifctx); elsectx = aml_else(); - aml_append(elsectx, aml_store(aml_or(aml_name("CDW1"), aml_int(4), NULL), - aml_name("CDW1"))); + aml_append(elsectx, aml_or(aml_name("CDW1"), aml_int(4), + aml_name("CDW1"))); aml_append(elsectx, aml_return(aml_arg(3))); aml_append(method, elsectx); aml_append(dev, method); diff --git a/hw/arm/virt.c b/hw/arm/virt.c index d4bedc2607..39ab5f47e0 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -531,7 +531,7 @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms) } } -static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic) +static inline DeviceState *create_acpi_ged(VirtMachineState *vms) { DeviceState *dev; MachineState *ms = MACHINE(vms); @@ -547,14 +547,14 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic) sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_ACPI_GED].base); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, vms->memmap[VIRT_PCDIMM_ACPI].base); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irq]); + sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(vms->gic, irq)); qdev_init_nofail(dev); return dev; } -static void create_its(VirtMachineState *vms, DeviceState *gicdev) +static void create_its(VirtMachineState *vms) { const char *itsclass = its_class_name(); DeviceState *dev; @@ -566,7 +566,7 @@ static void create_its(VirtMachineState *vms, DeviceState *gicdev) dev = qdev_create(NULL, itsclass); - object_property_set_link(OBJECT(dev), OBJECT(gicdev), "parent-gicv3", + object_property_set_link(OBJECT(dev), OBJECT(vms->gic), "parent-gicv3", &error_abort); qdev_init_nofail(dev); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_GIC_ITS].base); @@ -574,7 +574,7 @@ static void create_its(VirtMachineState *vms, DeviceState *gicdev) fdt_add_its_gic_node(vms); } -static void create_v2m(VirtMachineState *vms, qemu_irq *pic) +static void create_v2m(VirtMachineState *vms) { int i; int irq = vms->irqmap[VIRT_GIC_V2M]; @@ -587,17 +587,17 @@ static void create_v2m(VirtMachineState *vms, qemu_irq *pic) qdev_init_nofail(dev); for (i = 0; i < NUM_GICV2M_SPIS; i++) { - sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]); + sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, + qdev_get_gpio_in(vms->gic, irq + i)); } fdt_add_v2m_gic_node(vms); } -static void create_gic(VirtMachineState *vms, qemu_irq *pic) +static void create_gic(VirtMachineState *vms) { MachineState *ms = MACHINE(vms); /* We create a standalone GIC */ - DeviceState *gicdev; SysBusDevice *gicbusdev; const char *gictype; int type = vms->gic_version, i; @@ -606,15 +606,15 @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic) gictype = (type == 3) ? gicv3_class_name() : gic_class_name(); - gicdev = qdev_create(NULL, gictype); - qdev_prop_set_uint32(gicdev, "revision", type); - qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus); + vms->gic = qdev_create(NULL, gictype); + qdev_prop_set_uint32(vms->gic, "revision", type); + qdev_prop_set_uint32(vms->gic, "num-cpu", smp_cpus); /* Note that the num-irq property counts both internal and external * interrupts; there are always 32 of the former (mandated by GIC spec). */ - qdev_prop_set_uint32(gicdev, "num-irq", NUM_IRQS + 32); + qdev_prop_set_uint32(vms->gic, "num-irq", NUM_IRQS + 32); if (!kvm_irqchip_in_kernel()) { - qdev_prop_set_bit(gicdev, "has-security-extensions", vms->secure); + qdev_prop_set_bit(vms->gic, "has-security-extensions", vms->secure); } if (type == 3) { @@ -624,25 +624,25 @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic) nb_redist_regions = virt_gicv3_redist_region_count(vms); - qdev_prop_set_uint32(gicdev, "len-redist-region-count", + qdev_prop_set_uint32(vms->gic, "len-redist-region-count", nb_redist_regions); - qdev_prop_set_uint32(gicdev, "redist-region-count[0]", redist0_count); + qdev_prop_set_uint32(vms->gic, "redist-region-count[0]", redist0_count); if (nb_redist_regions == 2) { uint32_t redist1_capacity = vms->memmap[VIRT_HIGH_GIC_REDIST2].size / GICV3_REDIST_SIZE; - qdev_prop_set_uint32(gicdev, "redist-region-count[1]", + qdev_prop_set_uint32(vms->gic, "redist-region-count[1]", MIN(smp_cpus - redist0_count, redist1_capacity)); } } else { if (!kvm_irqchip_in_kernel()) { - qdev_prop_set_bit(gicdev, "has-virtualization-extensions", + qdev_prop_set_bit(vms->gic, "has-virtualization-extensions", vms->virt); } } - qdev_init_nofail(gicdev); - gicbusdev = SYS_BUS_DEVICE(gicdev); + qdev_init_nofail(vms->gic); + gicbusdev = SYS_BUS_DEVICE(vms->gic); sysbus_mmio_map(gicbusdev, 0, vms->memmap[VIRT_GIC_DIST].base); if (type == 3) { sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_REDIST].base); @@ -678,23 +678,23 @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic) for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) { qdev_connect_gpio_out(cpudev, irq, - qdev_get_gpio_in(gicdev, + qdev_get_gpio_in(vms->gic, ppibase + timer_irq[irq])); } if (type == 3) { - qemu_irq irq = qdev_get_gpio_in(gicdev, + qemu_irq irq = qdev_get_gpio_in(vms->gic, ppibase + ARCH_GIC_MAINT_IRQ); qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 0, irq); } else if (vms->virt) { - qemu_irq irq = qdev_get_gpio_in(gicdev, + qemu_irq irq = qdev_get_gpio_in(vms->gic, ppibase + ARCH_GIC_MAINT_IRQ); sysbus_connect_irq(gicbusdev, i + 4 * smp_cpus, irq); } qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0, - qdev_get_gpio_in(gicdev, ppibase + qdev_get_gpio_in(vms->gic, ppibase + VIRTUAL_PMU_IRQ)); sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ)); @@ -706,20 +706,16 @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic) qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ)); } - for (i = 0; i < NUM_IRQS; i++) { - pic[i] = qdev_get_gpio_in(gicdev, i); - } - fdt_add_gic_node(vms); if (type == 3 && vms->its) { - create_its(vms, gicdev); + create_its(vms); } else if (type == 2) { - create_v2m(vms, pic); + create_v2m(vms); } } -static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart, +static void create_uart(const VirtMachineState *vms, int uart, MemoryRegion *mem, Chardev *chr) { char *nodename; @@ -735,7 +731,7 @@ static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart, qdev_init_nofail(dev); memory_region_add_subregion(mem, base, sysbus_mmio_get_region(s, 0)); - sysbus_connect_irq(s, 0, pic[irq]); + sysbus_connect_irq(s, 0, qdev_get_gpio_in(vms->gic, irq)); nodename = g_strdup_printf("/pl011@%" PRIx64, base); qemu_fdt_add_subnode(vms->fdt, nodename); @@ -767,7 +763,7 @@ static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart, g_free(nodename); } -static void create_rtc(const VirtMachineState *vms, qemu_irq *pic) +static void create_rtc(const VirtMachineState *vms) { char *nodename; hwaddr base = vms->memmap[VIRT_RTC].base; @@ -775,7 +771,7 @@ static void create_rtc(const VirtMachineState *vms, qemu_irq *pic) int irq = vms->irqmap[VIRT_RTC]; const char compat[] = "arm,pl031\0arm,primecell"; - sysbus_create_simple("pl031", base, pic[irq]); + sysbus_create_simple("pl031", base, qdev_get_gpio_in(vms->gic, irq)); nodename = g_strdup_printf("/pl031@%" PRIx64, base); qemu_fdt_add_subnode(vms->fdt, nodename); @@ -803,7 +799,7 @@ static void virt_powerdown_req(Notifier *n, void *opaque) } } -static void create_gpio(const VirtMachineState *vms, qemu_irq *pic) +static void create_gpio(const VirtMachineState *vms) { char *nodename; DeviceState *pl061_dev; @@ -812,7 +808,8 @@ static void create_gpio(const VirtMachineState *vms, qemu_irq *pic) int irq = vms->irqmap[VIRT_GPIO]; const char compat[] = "arm,pl061\0arm,primecell"; - pl061_dev = sysbus_create_simple("pl061", base, pic[irq]); + pl061_dev = sysbus_create_simple("pl061", base, + qdev_get_gpio_in(vms->gic, irq)); uint32_t phandle = qemu_fdt_alloc_phandle(vms->fdt); nodename = g_strdup_printf("/pl061@%" PRIx64, base); @@ -846,7 +843,7 @@ static void create_gpio(const VirtMachineState *vms, qemu_irq *pic) g_free(nodename); } -static void create_virtio_devices(const VirtMachineState *vms, qemu_irq *pic) +static void create_virtio_devices(const VirtMachineState *vms) { int i; hwaddr size = vms->memmap[VIRT_MMIO].size; @@ -882,7 +879,8 @@ static void create_virtio_devices(const VirtMachineState *vms, qemu_irq *pic) int irq = vms->irqmap[VIRT_MMIO] + i; hwaddr base = vms->memmap[VIRT_MMIO].base + i * size; - sysbus_create_simple("virtio-mmio", base, pic[irq]); + sysbus_create_simple("virtio-mmio", base, + qdev_get_gpio_in(vms->gic, irq)); } /* We add dtb nodes in reverse order so that they appear in the finished @@ -1131,7 +1129,7 @@ static void create_pcie_irq_map(const VirtMachineState *vms, 0x7 /* PCI irq */); } -static void create_smmu(const VirtMachineState *vms, qemu_irq *pic, +static void create_smmu(const VirtMachineState *vms, PCIBus *bus) { char *node; @@ -1154,7 +1152,8 @@ static void create_smmu(const VirtMachineState *vms, qemu_irq *pic, qdev_init_nofail(dev); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); for (i = 0; i < NUM_SMMU_IRQS; i++) { - sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]); + sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, + qdev_get_gpio_in(vms->gic, irq + i)); } node = g_strdup_printf("/smmuv3@%" PRIx64, base); @@ -1181,7 +1180,7 @@ static void create_smmu(const VirtMachineState *vms, qemu_irq *pic, g_free(node); } -static void create_pcie(VirtMachineState *vms, qemu_irq *pic) +static void create_pcie(VirtMachineState *vms) { hwaddr base_mmio = vms->memmap[VIRT_PCIE_MMIO].base; hwaddr size_mmio = vms->memmap[VIRT_PCIE_MMIO].size; @@ -1241,7 +1240,8 @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic) sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio); for (i = 0; i < GPEX_NUM_IRQS; i++) { - sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]); + sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, + qdev_get_gpio_in(vms->gic, irq + i)); gpex_set_irq_num(GPEX_HOST(dev), i, irq + i); } @@ -1301,7 +1301,7 @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic) if (vms->iommu) { vms->iommu_phandle = qemu_fdt_alloc_phandle(vms->fdt); - create_smmu(vms, pic, pci->bus); + create_smmu(vms, pci->bus); qemu_fdt_setprop_cells(vms->fdt, nodename, "iommu-map", 0x0, vms->iommu_phandle, 0x0, 0x10000); @@ -1310,7 +1310,7 @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic) g_free(nodename); } -static void create_platform_bus(VirtMachineState *vms, qemu_irq *pic) +static void create_platform_bus(VirtMachineState *vms) { DeviceState *dev; SysBusDevice *s; @@ -1326,8 +1326,8 @@ static void create_platform_bus(VirtMachineState *vms, qemu_irq *pic) s = SYS_BUS_DEVICE(dev); for (i = 0; i < PLATFORM_BUS_NUM_IRQS; i++) { - int irqn = vms->irqmap[VIRT_PLATFORM_BUS] + i; - sysbus_connect_irq(s, i, pic[irqn]); + int irq = vms->irqmap[VIRT_PLATFORM_BUS] + i; + sysbus_connect_irq(s, i, qdev_get_gpio_in(vms->gic, irq)); } memory_region_add_subregion(sysmem, @@ -1509,7 +1509,6 @@ static void machvirt_init(MachineState *machine) VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(machine); MachineClass *mc = MACHINE_GET_CLASS(machine); const CPUArchIdList *possible_cpus; - qemu_irq pic[NUM_IRQS]; MemoryRegion *sysmem = get_system_memory(); MemoryRegion *secure_sysmem = NULL; int n, virt_max_cpus; @@ -1712,27 +1711,27 @@ static void machvirt_init(MachineState *machine) virt_flash_fdt(vms, sysmem, secure_sysmem ?: sysmem); - create_gic(vms, pic); + create_gic(vms); fdt_add_pmu_nodes(vms); - create_uart(vms, pic, VIRT_UART, sysmem, serial_hd(0)); + create_uart(vms, VIRT_UART, sysmem, serial_hd(0)); if (vms->secure) { create_secure_ram(vms, secure_sysmem); - create_uart(vms, pic, VIRT_SECURE_UART, secure_sysmem, serial_hd(1)); + create_uart(vms, VIRT_SECURE_UART, secure_sysmem, serial_hd(1)); } vms->highmem_ecam &= vms->highmem && (!firmware_loaded || aarch64); - create_rtc(vms, pic); + create_rtc(vms); - create_pcie(vms, pic); + create_pcie(vms); if (has_ged && aarch64 && firmware_loaded && acpi_enabled) { - vms->acpi_dev = create_acpi_ged(vms, pic); + vms->acpi_dev = create_acpi_ged(vms); } else { - create_gpio(vms, pic); + create_gpio(vms); } /* connect powerdown request */ @@ -1743,12 +1742,12 @@ static void machvirt_init(MachineState *machine) * (which will be automatically plugged in to the transports). If * no backend is created the transport will just sit harmlessly idle. */ - create_virtio_devices(vms, pic); + create_virtio_devices(vms); vms->fw_cfg = create_fw_cfg(vms, &address_space_memory); rom_set_fw(vms->fw_cfg); - create_platform_bus(vms, pic); + create_platform_bus(vms); vms->bootinfo.ram_size = machine->ram_size; vms->bootinfo.nb_cpus = smp_cpus; @@ -2147,10 +2146,16 @@ static void machvirt_machine_init(void) } type_init(machvirt_machine_init); +static void virt_machine_5_0_options(MachineClass *mc) +{ +} +DEFINE_VIRT_MACHINE_AS_LATEST(5, 0) + static void virt_machine_4_2_options(MachineClass *mc) { + compat_props_add(mc->compat_props, hw_compat_4_2, hw_compat_4_2_len); } -DEFINE_VIRT_MACHINE_AS_LATEST(4, 2) +DEFINE_VIRT_MACHINE(4, 2) static void virt_machine_4_1_options(MachineClass *mc) { diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 4c357d2928..d62e6377c2 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -991,7 +991,9 @@ static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features, virtio_add_feature(&features, VIRTIO_BLK_F_SCSI); } - if (blk_enable_write_cache(s->blk)) { + if (blk_enable_write_cache(s->blk) || + (s->conf.x_enable_wce_if_config_wce && + virtio_has_feature(features, VIRTIO_BLK_F_CONFIG_WCE))) { virtio_add_feature(&features, VIRTIO_BLK_F_WCE); } if (blk_is_read_only(s->blk)) { @@ -1270,6 +1272,8 @@ static Property virtio_blk_properties[] = { conf.max_discard_sectors, BDRV_REQUEST_MAX_SECTORS), DEFINE_PROP_UINT32("max-write-zeroes-sectors", VirtIOBlock, conf.max_write_zeroes_sectors, BDRV_REQUEST_MAX_SECTORS), + DEFINE_PROP_BOOL("x-enable-wce-if-config-wce", VirtIOBlock, + conf.x_enable_wce_if_config_wce, true), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/core/machine.c b/hw/core/machine.c index 1689ad3bf8..023548b4f3 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -27,6 +27,11 @@ #include "hw/pci/pci.h" #include "hw/mem/nvdimm.h" +GlobalProperty hw_compat_4_2[] = { + { "virtio-blk-device", "x-enable-wce-if-config-wce", "off" }, +}; +const size_t hw_compat_4_2_len = G_N_ELEMENTS(hw_compat_4_2); + GlobalProperty hw_compat_4_1[] = { { "virtio-pci", "x-pcie-flr-init", "off" }, }; diff --git a/hw/display/jazz_led.c b/hw/display/jazz_led.c index 3e0112b1ca..1d845597f9 100644 --- a/hw/display/jazz_led.c +++ b/hw/display/jazz_led.c @@ -90,25 +90,25 @@ static void draw_horizontal_line(DisplaySurface *ds, bpp = (surface_bits_per_pixel(ds) + 7) >> 3; d = surface_data(ds) + surface_stride(ds) * posy + bpp * posx1; - switch(bpp) { - case 1: - for (x = posx1; x <= posx2; x++) { - *((uint8_t *)d) = color; - d++; - } - break; - case 2: - for (x = posx1; x <= posx2; x++) { - *((uint16_t *)d) = color; - d += 2; - } - break; - case 4: - for (x = posx1; x <= posx2; x++) { - *((uint32_t *)d) = color; - d += 4; - } - break; + switch (bpp) { + case 1: + for (x = posx1; x <= posx2; x++) { + *((uint8_t *)d) = color; + d++; + } + break; + case 2: + for (x = posx1; x <= posx2; x++) { + *((uint16_t *)d) = color; + d += 2; + } + break; + case 4: + for (x = posx1; x <= posx2; x++) { + *((uint32_t *)d) = color; + d += 4; + } + break; } } @@ -121,25 +121,25 @@ static void draw_vertical_line(DisplaySurface *ds, bpp = (surface_bits_per_pixel(ds) + 7) >> 3; d = surface_data(ds) + surface_stride(ds) * posy1 + bpp * posx; - switch(bpp) { - case 1: - for (y = posy1; y <= posy2; y++) { - *((uint8_t *)d) = color; - d += surface_stride(ds); - } - break; - case 2: - for (y = posy1; y <= posy2; y++) { - *((uint16_t *)d) = color; - d += surface_stride(ds); - } - break; - case 4: - for (y = posy1; y <= posy2; y++) { - *((uint32_t *)d) = color; - d += surface_stride(ds); - } - break; + switch (bpp) { + case 1: + for (y = posy1; y <= posy2; y++) { + *((uint8_t *)d) = color; + d += surface_stride(ds); + } + break; + case 2: + for (y = posy1; y <= posy2; y++) { + *((uint16_t *)d) = color; + d += surface_stride(ds); + } + break; + case 4: + for (y = posy1; y <= posy2; y++) { + *((uint32_t *)d) = color; + d += surface_stride(ds); + } + break; } } @@ -164,28 +164,28 @@ static void jazz_led_update_display(void *opaque) if (s->state & REDRAW_SEGMENTS) { /* set colors according to bpp */ switch (surface_bits_per_pixel(surface)) { - case 8: - color_segment = rgb_to_pixel8(0xaa, 0xaa, 0xaa); - color_led = rgb_to_pixel8(0x00, 0xff, 0x00); - break; - case 15: - color_segment = rgb_to_pixel15(0xaa, 0xaa, 0xaa); - color_led = rgb_to_pixel15(0x00, 0xff, 0x00); - break; - case 16: - color_segment = rgb_to_pixel16(0xaa, 0xaa, 0xaa); - color_led = rgb_to_pixel16(0x00, 0xff, 0x00); - break; - case 24: - color_segment = rgb_to_pixel24(0xaa, 0xaa, 0xaa); - color_led = rgb_to_pixel24(0x00, 0xff, 0x00); - break; - case 32: - color_segment = rgb_to_pixel32(0xaa, 0xaa, 0xaa); - color_led = rgb_to_pixel32(0x00, 0xff, 0x00); - break; - default: - return; + case 8: + color_segment = rgb_to_pixel8(0xaa, 0xaa, 0xaa); + color_led = rgb_to_pixel8(0x00, 0xff, 0x00); + break; + case 15: + color_segment = rgb_to_pixel15(0xaa, 0xaa, 0xaa); + color_led = rgb_to_pixel15(0x00, 0xff, 0x00); + break; + case 16: + color_segment = rgb_to_pixel16(0xaa, 0xaa, 0xaa); + color_led = rgb_to_pixel16(0x00, 0xff, 0x00); + break; + case 24: + color_segment = rgb_to_pixel24(0xaa, 0xaa, 0xaa); + color_led = rgb_to_pixel24(0x00, 0xff, 0x00); + break; + case 32: + color_segment = rgb_to_pixel32(0xaa, 0xaa, 0xaa); + color_led = rgb_to_pixel32(0x00, 0xff, 0x00); + break; + default: + return; } /* display segments */ @@ -205,8 +205,9 @@ static void jazz_led_update_display(void *opaque) (s->segments & 0x80) ? color_segment : 0); /* display led */ - if (!(s->segments & 0x01)) + if (!(s->segments & 0x01)) { color_led = 0; /* black */ + } draw_horizontal_line(surface, 68, 50, 50, color_led); draw_horizontal_line(surface, 69, 49, 51, color_led); draw_horizontal_line(surface, 70, 48, 52, color_led); diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c index d54e296d3a..c4cf8236f4 100644 --- a/hw/dma/rc4030.c +++ b/hw/dma/rc4030.c @@ -397,10 +397,11 @@ static void update_jazz_irq(rc4030State *s) pending = s->isr_jazz & s->imr_jazz; - if (pending != 0) + if (pending != 0) { qemu_irq_raise(s->jazz_bus_irq); - else + } else { qemu_irq_lower(s->jazz_bus_irq); + } } static void rc4030_irq_jazz_request(void *opaque, int irq, int level) @@ -588,7 +589,8 @@ static const VMStateDescription vmstate_rc4030 = { } }; -static void rc4030_do_dma(void *opaque, int n, uint8_t *buf, int len, int is_write) +static void rc4030_do_dma(void *opaque, int n, uint8_t *buf, + int len, int is_write) { rc4030State *s = opaque; hwaddr dma_addr; @@ -643,8 +645,8 @@ static rc4030_dma *rc4030_allocate_dmas(void *opaque, int n) struct rc4030DMAState *p; int i; - s = (rc4030_dma *)g_malloc0(sizeof(rc4030_dma) * n); - p = (struct rc4030DMAState *)g_malloc0(sizeof(struct rc4030DMAState) * n); + s = (rc4030_dma *)g_new0(rc4030_dma, n); + p = (struct rc4030DMAState *)g_new0(struct rc4030DMAState, n); for (i = 0; i < n; i++) { p->opaque = opaque; p->n = i; diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c index 7acc5fa8e2..41e11ea9b0 100644 --- a/hw/gpio/aspeed_gpio.c +++ b/hw/gpio/aspeed_gpio.c @@ -876,6 +876,7 @@ static void aspeed_gpio_init(Object *obj) pin_idx % GPIOS_PER_GROUP); object_property_add(obj, name, "bool", aspeed_gpio_get_pin, aspeed_gpio_set_pin, NULL, NULL, NULL); + g_free(name); } } diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c index 06c119f385..2da04a4bff 100644 --- a/hw/i2c/aspeed_i2c.c +++ b/hw/i2c/aspeed_i2c.c @@ -23,20 +23,25 @@ #include "migration/vmstate.h" #include "qemu/log.h" #include "qemu/module.h" +#include "qemu/error-report.h" +#include "qapi/error.h" #include "hw/i2c/aspeed_i2c.h" #include "hw/irq.h" +#include "hw/qdev-properties.h" +#include "trace.h" /* I2C Global Register */ #define I2C_CTRL_STATUS 0x00 /* Device Interrupt Status */ #define I2C_CTRL_ASSIGN 0x08 /* Device Interrupt Target Assignment */ +#define I2C_CTRL_GLOBAL 0x0C /* Global Control Register */ +#define I2C_CTRL_SRAM_EN BIT(0) /* I2C Device (Bus) Register */ #define I2CD_FUN_CTRL_REG 0x00 /* I2CD Function Control */ -#define I2CD_BUFF_SEL_MASK (0x7 << 20) -#define I2CD_BUFF_SEL(x) (x << 20) +#define I2CD_POOL_PAGE_SEL(x) (((x) >> 20) & 0x7) /* AST2400 */ #define I2CD_M_SDA_LOCK_EN (0x1 << 16) #define I2CD_MULTI_MASTER_DIS (0x1 << 15) #define I2CD_M_SCL_DRIVE_EN (0x1 << 14) @@ -113,10 +118,12 @@ #define I2CD_SCL_O_OUT_DIR (0x1 << 12) #define I2CD_BUS_RECOVER_CMD_EN (0x1 << 11) #define I2CD_S_ALT_EN (0x1 << 10) -#define I2CD_RX_DMA_ENABLE (0x1 << 9) -#define I2CD_TX_DMA_ENABLE (0x1 << 8) /* Command Bit */ +#define I2CD_RX_DMA_ENABLE (0x1 << 9) +#define I2CD_TX_DMA_ENABLE (0x1 << 8) +#define I2CD_RX_BUFF_ENABLE (0x1 << 7) +#define I2CD_TX_BUFF_ENABLE (0x1 << 6) #define I2CD_M_STOP_CMD (0x1 << 5) #define I2CD_M_S_RX_CMD_LAST (0x1 << 4) #define I2CD_M_RX_CMD (0x1 << 3) @@ -125,13 +132,18 @@ #define I2CD_M_START_CMD (0x1) #define I2CD_DEV_ADDR_REG 0x18 /* Slave Device Address */ -#define I2CD_BUF_CTRL_REG 0x1c /* Pool Buffer Control */ +#define I2CD_POOL_CTRL_REG 0x1c /* Pool Buffer Control */ +#define I2CD_POOL_RX_COUNT(x) (((x) >> 24) & 0xff) +#define I2CD_POOL_RX_SIZE(x) ((((x) >> 16) & 0xff) + 1) +#define I2CD_POOL_TX_COUNT(x) ((((x) >> 8) & 0xff) + 1) +#define I2CD_POOL_OFFSET(x) (((x) & 0x3f) << 2) /* AST2400 */ #define I2CD_BYTE_BUF_REG 0x20 /* Transmit/Receive Byte Buffer */ #define I2CD_BYTE_BUF_TX_SHIFT 0 #define I2CD_BYTE_BUF_TX_MASK 0xff #define I2CD_BYTE_BUF_RX_SHIFT 8 #define I2CD_BYTE_BUF_RX_MASK 0xff - +#define I2CD_DMA_ADDR 0x24 /* DMA Buffer Address */ +#define I2CD_DMA_LEN 0x28 /* DMA Transfer Length < 4KB */ static inline bool aspeed_i2c_bus_is_master(AspeedI2CBus *bus) { @@ -147,6 +159,13 @@ static inline void aspeed_i2c_bus_raise_interrupt(AspeedI2CBus *bus) { AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller); + trace_aspeed_i2c_bus_raise_interrupt(bus->intr_status, + bus->intr_status & I2CD_INTR_TX_NAK ? "nak|" : "", + bus->intr_status & I2CD_INTR_TX_ACK ? "ack|" : "", + bus->intr_status & I2CD_INTR_RX_DONE ? "done|" : "", + bus->intr_status & I2CD_INTR_NORMAL_STOP ? "normal|" : "", + bus->intr_status & I2CD_INTR_ABNORMAL ? "abnormal" : ""); + bus->intr_status &= bus->intr_ctrl; if (bus->intr_status) { bus->controller->intr_status |= 1 << bus->id; @@ -158,27 +177,58 @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset, unsigned size) { AspeedI2CBus *bus = opaque; + AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller); + uint64_t value = -1; switch (offset) { case I2CD_FUN_CTRL_REG: - return bus->ctrl; + value = bus->ctrl; + break; case I2CD_AC_TIMING_REG1: - return bus->timing[0]; + value = bus->timing[0]; + break; case I2CD_AC_TIMING_REG2: - return bus->timing[1]; + value = bus->timing[1]; + break; case I2CD_INTR_CTRL_REG: - return bus->intr_ctrl; + value = bus->intr_ctrl; + break; case I2CD_INTR_STS_REG: - return bus->intr_status; + value = bus->intr_status; + break; + case I2CD_POOL_CTRL_REG: + value = bus->pool_ctrl; + break; case I2CD_BYTE_BUF_REG: - return bus->buf; + value = bus->buf; + break; case I2CD_CMD_REG: - return bus->cmd | (i2c_bus_busy(bus->bus) << 16); + value = bus->cmd | (i2c_bus_busy(bus->bus) << 16); + break; + case I2CD_DMA_ADDR: + if (!aic->has_dma) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__); + break; + } + value = bus->dma_addr; + break; + case I2CD_DMA_LEN: + if (!aic->has_dma) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__); + break; + } + value = bus->dma_len; + break; + default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, offset); - return -1; + value = -1; + break; } + + trace_aspeed_i2c_bus_read(bus->id, offset, size, value); + return value; } static void aspeed_i2c_set_state(AspeedI2CBus *bus, uint8_t state) @@ -192,14 +242,114 @@ static uint8_t aspeed_i2c_get_state(AspeedI2CBus *bus) return (bus->cmd >> I2CD_TX_STATE_SHIFT) & I2CD_TX_STATE_MASK; } -static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus) +static int aspeed_i2c_dma_read(AspeedI2CBus *bus, uint8_t *data) { - uint8_t ret; + MemTxResult result; + AspeedI2CState *s = bus->controller; + + result = address_space_read(&s->dram_as, bus->dma_addr, + MEMTXATTRS_UNSPECIFIED, data, 1); + if (result != MEMTX_OK) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM read failed @%08x\n", + __func__, bus->dma_addr); + return -1; + } + bus->dma_addr++; + bus->dma_len--; + return 0; +} + +static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start) +{ + AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller); + int ret = -1; + int i; + + if (bus->cmd & I2CD_TX_BUFF_ENABLE) { + for (i = pool_start; i < I2CD_POOL_TX_COUNT(bus->pool_ctrl); i++) { + uint8_t *pool_base = aic->bus_pool_base(bus); + + trace_aspeed_i2c_bus_send("BUF", i + 1, + I2CD_POOL_TX_COUNT(bus->pool_ctrl), + pool_base[i]); + ret = i2c_send(bus->bus, pool_base[i]); + if (ret) { + break; + } + } + bus->cmd &= ~I2CD_TX_BUFF_ENABLE; + } else if (bus->cmd & I2CD_TX_DMA_ENABLE) { + while (bus->dma_len) { + uint8_t data; + aspeed_i2c_dma_read(bus, &data); + trace_aspeed_i2c_bus_send("DMA", bus->dma_len, bus->dma_len, data); + ret = i2c_send(bus->bus, data); + if (ret) { + break; + } + } + bus->cmd &= ~I2CD_TX_DMA_ENABLE; + } else { + trace_aspeed_i2c_bus_send("BYTE", pool_start, 1, bus->buf); + ret = i2c_send(bus->bus, bus->buf); + } + + return ret; +} + +static void aspeed_i2c_bus_recv(AspeedI2CBus *bus) +{ + AspeedI2CState *s = bus->controller; + AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s); + uint8_t data; + int i; + + if (bus->cmd & I2CD_RX_BUFF_ENABLE) { + uint8_t *pool_base = aic->bus_pool_base(bus); + + for (i = 0; i < I2CD_POOL_RX_SIZE(bus->pool_ctrl); i++) { + pool_base[i] = i2c_recv(bus->bus); + trace_aspeed_i2c_bus_recv("BUF", i + 1, + I2CD_POOL_RX_SIZE(bus->pool_ctrl), + pool_base[i]); + } + + /* Update RX count */ + bus->pool_ctrl &= ~(0xff << 24); + bus->pool_ctrl |= (i & 0xff) << 24; + bus->cmd &= ~I2CD_RX_BUFF_ENABLE; + } else if (bus->cmd & I2CD_RX_DMA_ENABLE) { + uint8_t data; + + while (bus->dma_len) { + MemTxResult result; + + data = i2c_recv(bus->bus); + trace_aspeed_i2c_bus_recv("DMA", bus->dma_len, bus->dma_len, data); + result = address_space_write(&s->dram_as, bus->dma_addr, + MEMTXATTRS_UNSPECIFIED, &data, 1); + if (result != MEMTX_OK) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM write failed @%08x\n", + __func__, bus->dma_addr); + return; + } + bus->dma_addr++; + bus->dma_len--; + } + bus->cmd &= ~I2CD_RX_DMA_ENABLE; + } else { + data = i2c_recv(bus->bus); + trace_aspeed_i2c_bus_recv("BYTE", 1, 1, bus->buf); + bus->buf = (data & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT; + } +} + +static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus) +{ aspeed_i2c_set_state(bus, I2CD_MRXD); - ret = i2c_recv(bus->bus); + aspeed_i2c_bus_recv(bus); bus->intr_status |= I2CD_INTR_RX_DONE; - bus->buf = (ret & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT; if (bus->cmd & I2CD_M_S_RX_CMD_LAST) { i2c_nack(bus->bus); } @@ -207,31 +357,133 @@ static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus) aspeed_i2c_set_state(bus, I2CD_MACTIVE); } +static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus) +{ + AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller); + + if (bus->cmd & I2CD_TX_BUFF_ENABLE) { + uint8_t *pool_base = aic->bus_pool_base(bus); + + return pool_base[0]; + } else if (bus->cmd & I2CD_TX_DMA_ENABLE) { + uint8_t data; + + aspeed_i2c_dma_read(bus, &data); + return data; + } else { + return bus->buf; + } +} + +static bool aspeed_i2c_check_sram(AspeedI2CBus *bus) +{ + AspeedI2CState *s = bus->controller; + AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s); + + if (!aic->check_sram) { + return true; + } + + /* + * AST2500: SRAM must be enabled before using the Buffer Pool or + * DMA mode. + */ + if (!(s->ctrl_global & I2C_CTRL_SRAM_EN) && + (bus->cmd & (I2CD_RX_DMA_ENABLE | I2CD_TX_DMA_ENABLE | + I2CD_RX_BUFF_ENABLE | I2CD_TX_BUFF_ENABLE))) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: SRAM is not enabled\n", __func__); + return false; + } + + return true; +} + +static void aspeed_i2c_bus_cmd_dump(AspeedI2CBus *bus) +{ + g_autofree char *cmd_flags; + uint32_t count; + + if (bus->cmd & (I2CD_RX_BUFF_ENABLE | I2CD_RX_BUFF_ENABLE)) { + count = I2CD_POOL_TX_COUNT(bus->pool_ctrl); + } else if (bus->cmd & (I2CD_RX_DMA_ENABLE | I2CD_RX_DMA_ENABLE)) { + count = bus->dma_len; + } else { /* BYTE mode */ + count = 1; + } + + cmd_flags = g_strdup_printf("%s%s%s%s%s%s%s%s%s", + bus->cmd & I2CD_M_START_CMD ? "start|" : "", + bus->cmd & I2CD_RX_DMA_ENABLE ? "rxdma|" : "", + bus->cmd & I2CD_TX_DMA_ENABLE ? "txdma|" : "", + bus->cmd & I2CD_RX_BUFF_ENABLE ? "rxbuf|" : "", + bus->cmd & I2CD_TX_BUFF_ENABLE ? "txbuf|" : "", + bus->cmd & I2CD_M_TX_CMD ? "tx|" : "", + bus->cmd & I2CD_M_RX_CMD ? "rx|" : "", + bus->cmd & I2CD_M_S_RX_CMD_LAST ? "last|" : "", + bus->cmd & I2CD_M_STOP_CMD ? "stop" : ""); + + trace_aspeed_i2c_bus_cmd(bus->cmd, cmd_flags, count, bus->intr_status); +} + /* * The state machine needs some refinement. It is only used to track * invalid STOP commands for the moment. */ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value) { + uint8_t pool_start = 0; + bus->cmd &= ~0xFFFF; bus->cmd |= value & 0xFFFF; + if (!aspeed_i2c_check_sram(bus)) { + return; + } + + if (trace_event_get_state_backends(TRACE_ASPEED_I2C_BUS_CMD)) { + aspeed_i2c_bus_cmd_dump(bus); + } + if (bus->cmd & I2CD_M_START_CMD) { uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ? I2CD_MSTARTR : I2CD_MSTART; + uint8_t addr; aspeed_i2c_set_state(bus, state); - if (i2c_start_transfer(bus->bus, extract32(bus->buf, 1, 7), - extract32(bus->buf, 0, 1))) { + addr = aspeed_i2c_get_addr(bus); + + if (i2c_start_transfer(bus->bus, extract32(addr, 1, 7), + extract32(addr, 0, 1))) { bus->intr_status |= I2CD_INTR_TX_NAK; } else { bus->intr_status |= I2CD_INTR_TX_ACK; } - /* START command is also a TX command, as the slave address is - * sent on the bus */ - bus->cmd &= ~(I2CD_M_START_CMD | I2CD_M_TX_CMD); + bus->cmd &= ~I2CD_M_START_CMD; + + /* + * The START command is also a TX command, as the slave + * address is sent on the bus. Drop the TX flag if nothing + * else needs to be sent in this sequence. + */ + if (bus->cmd & I2CD_TX_BUFF_ENABLE) { + if (I2CD_POOL_TX_COUNT(bus->pool_ctrl) == 1) { + bus->cmd &= ~I2CD_M_TX_CMD; + } else { + /* + * Increase the start index in the TX pool buffer to + * skip the address byte. + */ + pool_start++; + } + } else if (bus->cmd & I2CD_TX_DMA_ENABLE) { + if (bus->dma_len == 0) { + bus->cmd &= ~I2CD_M_TX_CMD; + } + } else { + bus->cmd &= ~I2CD_M_TX_CMD; + } /* No slave found */ if (!i2c_bus_busy(bus->bus)) { @@ -242,7 +494,7 @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value) if (bus->cmd & I2CD_M_TX_CMD) { aspeed_i2c_set_state(bus, I2CD_MTXD); - if (i2c_send(bus->bus, bus->buf)) { + if (aspeed_i2c_bus_send(bus, pool_start)) { bus->intr_status |= (I2CD_INTR_TX_NAK); i2c_end_transfer(bus->bus); } else { @@ -278,6 +530,8 @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset, AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller); bool handle_rx; + trace_aspeed_i2c_bus_write(bus->id, offset, size, value); + switch (offset) { case I2CD_FUN_CTRL_REG: if (value & I2CD_SLAVE_EN) { @@ -313,6 +567,11 @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset, qemu_log_mask(LOG_UNIMP, "%s: slave mode not implemented\n", __func__); break; + case I2CD_POOL_CTRL_REG: + bus->pool_ctrl &= ~0xffffff; + bus->pool_ctrl |= (value & 0xffffff); + break; + case I2CD_BYTE_BUF_REG: bus->buf = (value & I2CD_BYTE_BUF_TX_MASK) << I2CD_BYTE_BUF_TX_SHIFT; break; @@ -327,9 +586,35 @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset, break; } + if (!aic->has_dma && + value & (I2CD_RX_DMA_ENABLE | I2CD_TX_DMA_ENABLE)) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__); + break; + } + aspeed_i2c_bus_handle_cmd(bus, value); aspeed_i2c_bus_raise_interrupt(bus); break; + case I2CD_DMA_ADDR: + if (!aic->has_dma) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__); + break; + } + + bus->dma_addr = value & 0xfffffffc; + break; + + case I2CD_DMA_LEN: + if (!aic->has_dma) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__); + break; + } + + bus->dma_len = value & 0xfff; + if (!bus->dma_len) { + qemu_log_mask(LOG_UNIMP, "%s: invalid DMA length\n", __func__); + } + break; default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n", @@ -345,6 +630,8 @@ static uint64_t aspeed_i2c_ctrl_read(void *opaque, hwaddr offset, switch (offset) { case I2C_CTRL_STATUS: return s->intr_status; + case I2C_CTRL_GLOBAL: + return s->ctrl_global; default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, offset); @@ -357,7 +644,12 @@ static uint64_t aspeed_i2c_ctrl_read(void *opaque, hwaddr offset, static void aspeed_i2c_ctrl_write(void *opaque, hwaddr offset, uint64_t value, unsigned size) { + AspeedI2CState *s = opaque; + switch (offset) { + case I2C_CTRL_GLOBAL: + s->ctrl_global = value; + break; case I2C_CTRL_STATUS: default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n", @@ -378,10 +670,45 @@ static const MemoryRegionOps aspeed_i2c_ctrl_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; +static uint64_t aspeed_i2c_pool_read(void *opaque, hwaddr offset, + unsigned size) +{ + AspeedI2CState *s = opaque; + uint64_t ret = 0; + int i; + + for (i = 0; i < size; i++) { + ret |= (uint64_t) s->pool[offset + i] << (8 * i); + } + + return ret; +} + +static void aspeed_i2c_pool_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + AspeedI2CState *s = opaque; + int i; + + for (i = 0; i < size; i++) { + s->pool[offset + i] = (value >> (8 * i)) & 0xFF; + } +} + +static const MemoryRegionOps aspeed_i2c_pool_ops = { + .read = aspeed_i2c_pool_read, + .write = aspeed_i2c_pool_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 1, + .max_access_size = 4, + }, +}; + static const VMStateDescription aspeed_i2c_bus_vmstate = { .name = TYPE_ASPEED_I2C, - .version_id = 1, - .minimum_version_id = 1, + .version_id = 3, + .minimum_version_id = 3, .fields = (VMStateField[]) { VMSTATE_UINT8(id, AspeedI2CBus), VMSTATE_UINT32(ctrl, AspeedI2CBus), @@ -390,19 +717,23 @@ static const VMStateDescription aspeed_i2c_bus_vmstate = { VMSTATE_UINT32(intr_status, AspeedI2CBus), VMSTATE_UINT32(cmd, AspeedI2CBus), VMSTATE_UINT32(buf, AspeedI2CBus), + VMSTATE_UINT32(pool_ctrl, AspeedI2CBus), + VMSTATE_UINT32(dma_addr, AspeedI2CBus), + VMSTATE_UINT32(dma_len, AspeedI2CBus), VMSTATE_END_OF_LIST() } }; static const VMStateDescription aspeed_i2c_vmstate = { .name = TYPE_ASPEED_I2C, - .version_id = 1, - .minimum_version_id = 1, + .version_id = 2, + .minimum_version_id = 2, .fields = (VMStateField[]) { VMSTATE_UINT32(intr_status, AspeedI2CState), VMSTATE_STRUCT_ARRAY(busses, AspeedI2CState, ASPEED_I2C_NR_BUSSES, 1, aspeed_i2c_bus_vmstate, AspeedI2CBus), + VMSTATE_UINT8_ARRAY(pool, AspeedI2CState, ASPEED_I2C_MAX_POOL_SIZE), VMSTATE_END_OF_LIST() } }; @@ -420,6 +751,8 @@ static void aspeed_i2c_reset(DeviceState *dev) s->busses[i].intr_status = 0; s->busses[i].cmd = 0; s->busses[i].buf = 0; + s->busses[i].dma_addr = 0; + s->busses[i].dma_len = 0; i2c_end_transfer(s->busses[i].bus); } } @@ -472,14 +805,34 @@ static void aspeed_i2c_realize(DeviceState *dev, Error **errp) memory_region_add_subregion(&s->iomem, aic->reg_size * (i + offset), &s->busses[i].mr); } + + memory_region_init_io(&s->pool_iomem, OBJECT(s), &aspeed_i2c_pool_ops, s, + "aspeed.i2c-pool", aic->pool_size); + memory_region_add_subregion(&s->iomem, aic->pool_base, &s->pool_iomem); + + if (aic->has_dma) { + if (!s->dram_mr) { + error_setg(errp, TYPE_ASPEED_I2C ": 'dram' link not set"); + return; + } + + address_space_init(&s->dram_as, s->dram_mr, "dma-dram"); + } } +static Property aspeed_i2c_properties[] = { + DEFINE_PROP_LINK("dram", AspeedI2CState, dram_mr, + TYPE_MEMORY_REGION, MemoryRegion *), + DEFINE_PROP_END_OF_LIST(), +}; + static void aspeed_i2c_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->vmsd = &aspeed_i2c_vmstate; dc->reset = aspeed_i2c_reset; + dc->props = aspeed_i2c_properties; dc->realize = aspeed_i2c_realize; dc->desc = "Aspeed I2C Controller"; } @@ -498,6 +851,14 @@ static qemu_irq aspeed_2400_i2c_bus_get_irq(AspeedI2CBus *bus) return bus->controller->irq; } +static uint8_t *aspeed_2400_i2c_bus_pool_base(AspeedI2CBus *bus) +{ + uint8_t *pool_page = + &bus->controller->pool[I2CD_POOL_PAGE_SEL(bus->ctrl) * 0x100]; + + return &pool_page[I2CD_POOL_OFFSET(bus->pool_ctrl)]; +} + static void aspeed_2400_i2c_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -509,6 +870,9 @@ static void aspeed_2400_i2c_class_init(ObjectClass *klass, void *data) aic->reg_size = 0x40; aic->gap = 7; aic->bus_get_irq = aspeed_2400_i2c_bus_get_irq; + aic->pool_size = 0x800; + aic->pool_base = 0x800; + aic->bus_pool_base = aspeed_2400_i2c_bus_pool_base; } static const TypeInfo aspeed_2400_i2c_info = { @@ -522,6 +886,11 @@ static qemu_irq aspeed_2500_i2c_bus_get_irq(AspeedI2CBus *bus) return bus->controller->irq; } +static uint8_t *aspeed_2500_i2c_bus_pool_base(AspeedI2CBus *bus) +{ + return &bus->controller->pool[bus->id * 0x10]; +} + static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -533,6 +902,11 @@ static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data) aic->reg_size = 0x40; aic->gap = 7; aic->bus_get_irq = aspeed_2500_i2c_bus_get_irq; + aic->pool_size = 0x100; + aic->pool_base = 0x200; + aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base; + aic->check_sram = true; + aic->has_dma = true; } static const TypeInfo aspeed_2500_i2c_info = { @@ -546,6 +920,11 @@ static qemu_irq aspeed_2600_i2c_bus_get_irq(AspeedI2CBus *bus) return bus->irq; } +static uint8_t *aspeed_2600_i2c_bus_pool_base(AspeedI2CBus *bus) +{ + return &bus->controller->pool[bus->id * 0x20]; +} + static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -557,6 +936,10 @@ static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data) aic->reg_size = 0x80; aic->gap = -1; /* no gap */ aic->bus_get_irq = aspeed_2600_i2c_bus_get_irq; + aic->pool_size = 0x200; + aic->pool_base = 0xC00; + aic->bus_pool_base = aspeed_2600_i2c_bus_pool_base; + aic->has_dma = true; } static const TypeInfo aspeed_2600_i2c_info = { diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events index e1c810d5bd..08db8fa689 100644 --- a/hw/i2c/trace-events +++ b/hw/i2c/trace-events @@ -5,3 +5,12 @@ i2c_event(const char *event, uint8_t address) "%s(addr:0x%02x)" i2c_send(uint8_t address, uint8_t data) "send(addr:0x%02x) data:0x%02x" i2c_recv(uint8_t address, uint8_t data) "recv(addr:0x%02x) data:0x%02x" + +# aspeed_i2c.c + +aspeed_i2c_bus_cmd(uint32_t cmd, const char *cmd_flags, uint32_t count, uint32_t intr_status) "handling cmd=0x%x %s count=%d intr=0x%x" +aspeed_i2c_bus_raise_interrupt(uint32_t intr_status, const char *str1, const char *str2, const char *str3, const char *str4, const char *str5) "handled intr=0x%x %s%s%s%s%s" +aspeed_i2c_bus_read(uint32_t busid, uint64_t offset, unsigned size, uint64_t value) "bus[%d]: To 0x%" PRIx64 " of size %u: 0x%" PRIx64 +aspeed_i2c_bus_write(uint32_t busid, uint64_t offset, unsigned size, uint64_t value) "bus[%d]: To 0x%" PRIx64 " of size %u: 0x%" PRIx64 +aspeed_i2c_bus_send(const char *mode, int i, int count, uint8_t byte) "%s send %d/%d 0x%02x" +aspeed_i2c_bus_recv(const char *mode, int i, int count, uint8_t byte) "%s recv %d/%d 0x%02x" diff --git a/hw/i386/pc.c b/hw/i386/pc.c index ac08e63604..58867f987d 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -103,6 +103,9 @@ struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX}; +GlobalProperty pc_compat_4_2[] = {}; +const size_t pc_compat_4_2_len = G_N_ELEMENTS(pc_compat_4_2); + GlobalProperty pc_compat_4_1[] = {}; const size_t pc_compat_4_1_len = G_N_ELEMENTS(pc_compat_4_1); diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 1bd70d1abb..ffb30c32ce 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -424,13 +424,26 @@ static void pc_i440fx_machine_options(MachineClass *m) machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE); } -static void pc_i440fx_4_2_machine_options(MachineClass *m) +static void pc_i440fx_5_0_machine_options(MachineClass *m) { PCMachineClass *pcmc = PC_MACHINE_CLASS(m); pc_i440fx_machine_options(m); m->alias = "pc"; m->is_default = 1; pcmc->default_cpu_version = 1; + compat_props_add(m->compat_props, hw_compat_4_2, hw_compat_4_2_len); +} + +DEFINE_I440FX_MACHINE(v5_0, "pc-i440fx-5.0", NULL, + pc_i440fx_5_0_machine_options); + +static void pc_i440fx_4_2_machine_options(MachineClass *m) +{ + pc_i440fx_5_0_machine_options(m); + m->alias = NULL; + m->is_default = 0; + compat_props_add(m->compat_props, hw_compat_4_2, hw_compat_4_2_len); + compat_props_add(m->compat_props, pc_compat_4_2, pc_compat_4_2_len); } DEFINE_I440FX_MACHINE(v4_2, "pc-i440fx-4.2", NULL, diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 385e5cffb1..7398d7baa2 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -348,12 +348,24 @@ static void pc_q35_machine_options(MachineClass *m) m->max_cpus = 288; } -static void pc_q35_4_2_machine_options(MachineClass *m) +static void pc_q35_5_0_machine_options(MachineClass *m) { PCMachineClass *pcmc = PC_MACHINE_CLASS(m); pc_q35_machine_options(m); m->alias = "q35"; pcmc->default_cpu_version = 1; + compat_props_add(m->compat_props, hw_compat_4_2, hw_compat_4_2_len); +} + +DEFINE_Q35_MACHINE(v5_0, "pc-q35-5.0", NULL, + pc_q35_5_0_machine_options); + +static void pc_q35_4_2_machine_options(MachineClass *m) +{ + pc_q35_5_0_machine_options(m); + m->alias = NULL; + compat_props_add(m->compat_props, hw_compat_4_2, hw_compat_4_2_len); + compat_props_add(m->compat_props, pc_compat_4_2, pc_compat_4_2_len); } DEFINE_Q35_MACHINE(v4_2, "pc-q35-4.2", NULL, diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c index a1b699b6ba..9a84d8522e 100644 --- a/hw/intc/exynos4210_gic.c +++ b/hw/intc/exynos4210_gic.c @@ -293,6 +293,7 @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp) char cpu_alias_name[sizeof(cpu_prefix) + 3]; char dist_alias_name[sizeof(cpu_prefix) + 3]; SysBusDevice *gicbusdev; + uint32_t n = s->num_cpu; uint32_t i; s->gic = qdev_create(NULL, "arm_gic"); @@ -313,7 +314,13 @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp) memory_region_init(&s->dist_container, obj, "exynos4210-dist-container", EXYNOS4210_EXT_GIC_DIST_REGION_SIZE); - for (i = 0; i < s->num_cpu; i++) { + /* + * This clues in gcc that our on-stack buffers do, in fact have + * enough room for the cpu numbers. gcc 9.2.1 on 32-bit x86 + * doesn't figure this out, otherwise and gives spurious warnings. + */ + assert(n <= EXYNOS4210_NCPUS); + for (i = 0; i < n; i++) { /* Map CPU interface per SMP Core */ sprintf(cpu_alias_name, "%s%x", cpu_prefix, i); memory_region_init_alias(&s->cpu_alias[i], obj, diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 616f67f347..f828708b1d 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -27,7 +27,7 @@ #include "qemu/timer.h" #include "exec/address-spaces.h" -//#define DEBUG_VT82C686B +/* #define DEBUG_VT82C686B */ #ifdef DEBUG_VT82C686B #define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __func__, ##__VA_ARGS__) @@ -35,8 +35,7 @@ #define DPRINTF(fmt, ...) #endif -typedef struct SuperIOConfig -{ +typedef struct SuperIOConfig { uint8_t config[0x100]; uint8_t index; uint8_t data; @@ -102,7 +101,7 @@ static uint64_t superio_ioport_readb(void *opaque, hwaddr addr, unsigned size) SuperIOConfig *superio_conf = opaque; DPRINTF("superio_ioport_readb address 0x%x\n", addr); - return (superio_conf->config[superio_conf->index]); + return superio_conf->config[superio_conf->index]; } static const MemoryRegionOps superio_ops = { @@ -143,7 +142,7 @@ static void vt82c686b_isa_reset(DeviceState *dev) } /* write config pci function0 registers. PCI-ISA bridge */ -static void vt82c686b_write_config(PCIDevice * d, uint32_t address, +static void vt82c686b_write_config(PCIDevice *d, uint32_t address, uint32_t val, int len) { VT82C686BState *vt686 = VT82C686B_DEVICE(d); @@ -365,7 +364,7 @@ static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp) pci_set_long(pci_conf + 0x48, 0x00000001); /* SMB ports:0xeee0~0xeeef */ - s->smb_io_base =((s->smb_io_base & 0xfff0) + 0x0); + s->smb_io_base = ((s->smb_io_base & 0xfff0) + 0x0); pci_conf[0x90] = s->smb_io_base | 1; pci_conf[0x91] = s->smb_io_base >> 8; pci_conf[0xd2] = 0x90; @@ -462,16 +461,18 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp) wmask = d->wmask; for (i = 0x00; i < 0xff; i++) { - if (i<=0x03 || (i>=0x08 && i<=0x3f)) { - wmask[i] = 0x00; - } + if (i <= 0x03 || (i >= 0x08 && i <= 0x3f)) { + wmask[i] = 0x00; + } } memory_region_init_io(&vt82c->superio, OBJECT(d), &superio_ops, &vt82c->superio_conf, "superio", 2); memory_region_set_enabled(&vt82c->superio, false); - /* The floppy also uses 0x3f0 and 0x3f1. - * But we do not emulate a floppy, so just set it here. */ + /* + * The floppy also uses 0x3f0 and 0x3f1. + * But we do not emulate a floppy, so just set it here. + */ memory_region_add_subregion(isa_bus->address_space_io, 0x3f0, &vt82c->superio); } diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c index d978bb64a0..ac4d7acb2b 100644 --- a/hw/mips/mips_jazz.c +++ b/hw/mips/mips_jazz.c @@ -52,8 +52,7 @@ #include "qemu/error-report.h" #include "qemu/help_option.h" -enum jazz_model_e -{ +enum jazz_model_e { JAZZ_MAGNUM, JAZZ_PICA61, }; @@ -90,16 +89,20 @@ static const MemoryRegionOps rtc_ops = { static uint64_t dma_dummy_read(void *opaque, hwaddr addr, unsigned size) { - /* Nothing to do. That is only to ensure that - * the current DMA acknowledge cycle is completed. */ + /* + * Nothing to do. That is only to ensure that + * the current DMA acknowledge cycle is completed. + */ return 0xff; } static void dma_dummy_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { - /* Nothing to do. That is only to ensure that - * the current DMA acknowledge cycle is completed. */ + /* + * Nothing to do. That is only to ensure that + * the current DMA acknowledge cycle is completed. + */ } static const MemoryRegionOps dma_dummy_ops = { @@ -109,8 +112,8 @@ static const MemoryRegionOps dma_dummy_ops = { }; #define MAGNUM_BIOS_SIZE_MAX 0x7e000 -#define MAGNUM_BIOS_SIZE (BIOS_SIZE < MAGNUM_BIOS_SIZE_MAX ? BIOS_SIZE : MAGNUM_BIOS_SIZE_MAX) - +#define MAGNUM_BIOS_SIZE \ + (BIOS_SIZE < MAGNUM_BIOS_SIZE_MAX ? BIOS_SIZE : MAGNUM_BIOS_SIZE_MAX) static void (*real_do_transaction_failed)(CPUState *cpu, hwaddr physaddr, vaddr addr, unsigned size, MMUAccessType access_type, @@ -201,8 +204,9 @@ static void mips_jazz_init(MachineState *machine, memory_region_add_subregion(address_space, 0xfff00000LL, bios2); /* load the BIOS image. */ - if (bios_name == NULL) + if (bios_name == NULL) { bios_name = BIOS_FILENAME; + } filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { bios_size = load_image_targphys(filename, 0xfff00000LL, @@ -229,7 +233,8 @@ static void mips_jazz_init(MachineState *machine, sysbus_mmio_get_region(sysbus, 0)); memory_region_add_subregion(address_space, 0xf0000000, sysbus_mmio_get_region(sysbus, 1)); - memory_region_init_io(dma_dummy, NULL, &dma_dummy_ops, NULL, "dummy_dma", 0x1000); + memory_region_init_io(dma_dummy, NULL, &dma_dummy_ops, + NULL, "dummy_dma", 0x1000); memory_region_add_subregion(address_space, 0x8000d000, dma_dummy); /* ISA bus: IO space at 0x90000000, mem space at 0x91000000 */ @@ -276,8 +281,9 @@ static void mips_jazz_init(MachineState *machine, /* Network controller */ for (n = 0; n < nb_nics; n++) { nd = &nd_table[n]; - if (!nd->model) + if (!nd->model) { nd->model = g_strdup("dp83932"); + } if (strcmp(nd->model, "dp83932") == 0) { qemu_check_nic_model(nd, "dp83932"); @@ -338,12 +344,12 @@ static void mips_jazz_init(MachineState *machine, /* Serial ports */ if (serial_hd(0)) { serial_mm_init(address_space, 0x80006000, 0, - qdev_get_gpio_in(rc4030, 8), 8000000/16, + qdev_get_gpio_in(rc4030, 8), 8000000 / 16, serial_hd(0), DEVICE_NATIVE_ENDIAN); } if (serial_hd(1)) { serial_mm_init(address_space, 0x80007000, 0, - qdev_get_gpio_in(rc4030, 9), 8000000/16, + qdev_get_gpio_in(rc4030, 9), 8000000 / 16, serial_hd(1), DEVICE_NATIVE_ENDIAN); } diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 92e9ca5bfa..783cd99848 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -137,7 +137,8 @@ static void malta_fpga_update_display(void *opaque) */ #if defined(DEBUG) -# define logout(fmt, ...) fprintf(stderr, "MALTA\t%-24s" fmt, __func__, ## __VA_ARGS__) +# define logout(fmt, ...) \ + fprintf(stderr, "MALTA\t%-24s" fmt, __func__, ## __VA_ARGS__) #else # define logout(fmt, ...) ((void)0) #endif @@ -359,7 +360,6 @@ static uint64_t malta_fpga_read(void *opaque, hwaddr addr, /* SWITCH Register */ case 0x00200: - /* ori a3, a3, low(ram_low_size) */ val = 0x00000000; break; @@ -569,7 +569,7 @@ static MaltaFPGAState *malta_fpga_init(MemoryRegion *address_space, MaltaFPGAState *s; Chardev *chr; - s = (MaltaFPGAState *)g_malloc0(sizeof(MaltaFPGAState)); + s = g_new0(MaltaFPGAState, 1); memory_region_init_io(&s->iomem, NULL, &malta_fpga_ops, s, "malta-fpga", 0x100000); @@ -844,24 +844,24 @@ static void write_bootloader(uint8_t *base, int64_t run_addr, /* Small bootloader */ p = (uint32_t *)base; - stl_p(p++, 0x08000000 | /* j 0x1fc00580 */ + stl_p(p++, 0x08000000 | /* j 0x1fc00580 */ ((run_addr + 0x580) & 0x0fffffff) >> 2); - stl_p(p++, 0x00000000); /* nop */ + stl_p(p++, 0x00000000); /* nop */ /* YAMON service vector */ - stl_p(base + 0x500, run_addr + 0x0580); /* start: */ - stl_p(base + 0x504, run_addr + 0x083c); /* print_count: */ - stl_p(base + 0x520, run_addr + 0x0580); /* start: */ - stl_p(base + 0x52c, run_addr + 0x0800); /* flush_cache: */ - stl_p(base + 0x534, run_addr + 0x0808); /* print: */ - stl_p(base + 0x538, run_addr + 0x0800); /* reg_cpu_isr: */ - stl_p(base + 0x53c, run_addr + 0x0800); /* unred_cpu_isr: */ - stl_p(base + 0x540, run_addr + 0x0800); /* reg_ic_isr: */ - stl_p(base + 0x544, run_addr + 0x0800); /* unred_ic_isr: */ - stl_p(base + 0x548, run_addr + 0x0800); /* reg_esr: */ - stl_p(base + 0x54c, run_addr + 0x0800); /* unreg_esr: */ - stl_p(base + 0x550, run_addr + 0x0800); /* getchar: */ - stl_p(base + 0x554, run_addr + 0x0800); /* syscon_read: */ + stl_p(base + 0x500, run_addr + 0x0580); /* start: */ + stl_p(base + 0x504, run_addr + 0x083c); /* print_count: */ + stl_p(base + 0x520, run_addr + 0x0580); /* start: */ + stl_p(base + 0x52c, run_addr + 0x0800); /* flush_cache: */ + stl_p(base + 0x534, run_addr + 0x0808); /* print: */ + stl_p(base + 0x538, run_addr + 0x0800); /* reg_cpu_isr: */ + stl_p(base + 0x53c, run_addr + 0x0800); /* unred_cpu_isr: */ + stl_p(base + 0x540, run_addr + 0x0800); /* reg_ic_isr: */ + stl_p(base + 0x544, run_addr + 0x0800); /* unred_ic_isr: */ + stl_p(base + 0x548, run_addr + 0x0800); /* reg_esr: */ + stl_p(base + 0x54c, run_addr + 0x0800); /* unreg_esr: */ + stl_p(base + 0x550, run_addr + 0x0800); /* getchar: */ + stl_p(base + 0x554, run_addr + 0x0800); /* syscon_read: */ /* Second part of the bootloader */ @@ -869,9 +869,9 @@ static void write_bootloader(uint8_t *base, int64_t run_addr, if (semihosting_get_argc()) { /* Preserve a0 content as arguments have been passed */ - stl_p(p++, 0x00000000); /* nop */ + stl_p(p++, 0x00000000); /* nop */ } else { - stl_p(p++, 0x24040002); /* addiu a0, zero, 2 */ + stl_p(p++, 0x24040002); /* addiu a0, zero, 2 */ } /* lui sp, high(ENVP_ADDR) */ @@ -892,104 +892,106 @@ static void write_bootloader(uint8_t *base, int64_t run_addr, stl_p(p++, 0x34e70000 | (loaderparams.ram_low_size & 0xffff)); /* Load BAR registers as done by YAMON */ - stl_p(p++, 0x3c09b400); /* lui t1, 0xb400 */ + stl_p(p++, 0x3c09b400); /* lui t1, 0xb400 */ #ifdef TARGET_WORDS_BIGENDIAN - stl_p(p++, 0x3c08df00); /* lui t0, 0xdf00 */ + stl_p(p++, 0x3c08df00); /* lui t0, 0xdf00 */ #else - stl_p(p++, 0x340800df); /* ori t0, r0, 0x00df */ + stl_p(p++, 0x340800df); /* ori t0, r0, 0x00df */ #endif - stl_p(p++, 0xad280068); /* sw t0, 0x0068(t1) */ + stl_p(p++, 0xad280068); /* sw t0, 0x0068(t1) */ - stl_p(p++, 0x3c09bbe0); /* lui t1, 0xbbe0 */ + stl_p(p++, 0x3c09bbe0); /* lui t1, 0xbbe0 */ #ifdef TARGET_WORDS_BIGENDIAN - stl_p(p++, 0x3c08c000); /* lui t0, 0xc000 */ + stl_p(p++, 0x3c08c000); /* lui t0, 0xc000 */ #else - stl_p(p++, 0x340800c0); /* ori t0, r0, 0x00c0 */ + stl_p(p++, 0x340800c0); /* ori t0, r0, 0x00c0 */ #endif - stl_p(p++, 0xad280048); /* sw t0, 0x0048(t1) */ + stl_p(p++, 0xad280048); /* sw t0, 0x0048(t1) */ #ifdef TARGET_WORDS_BIGENDIAN - stl_p(p++, 0x3c084000); /* lui t0, 0x4000 */ + stl_p(p++, 0x3c084000); /* lui t0, 0x4000 */ #else - stl_p(p++, 0x34080040); /* ori t0, r0, 0x0040 */ + stl_p(p++, 0x34080040); /* ori t0, r0, 0x0040 */ #endif - stl_p(p++, 0xad280050); /* sw t0, 0x0050(t1) */ + stl_p(p++, 0xad280050); /* sw t0, 0x0050(t1) */ #ifdef TARGET_WORDS_BIGENDIAN - stl_p(p++, 0x3c088000); /* lui t0, 0x8000 */ + stl_p(p++, 0x3c088000); /* lui t0, 0x8000 */ #else - stl_p(p++, 0x34080080); /* ori t0, r0, 0x0080 */ + stl_p(p++, 0x34080080); /* ori t0, r0, 0x0080 */ #endif - stl_p(p++, 0xad280058); /* sw t0, 0x0058(t1) */ + stl_p(p++, 0xad280058); /* sw t0, 0x0058(t1) */ #ifdef TARGET_WORDS_BIGENDIAN - stl_p(p++, 0x3c083f00); /* lui t0, 0x3f00 */ + stl_p(p++, 0x3c083f00); /* lui t0, 0x3f00 */ #else - stl_p(p++, 0x3408003f); /* ori t0, r0, 0x003f */ + stl_p(p++, 0x3408003f); /* ori t0, r0, 0x003f */ #endif - stl_p(p++, 0xad280060); /* sw t0, 0x0060(t1) */ + stl_p(p++, 0xad280060); /* sw t0, 0x0060(t1) */ #ifdef TARGET_WORDS_BIGENDIAN - stl_p(p++, 0x3c08c100); /* lui t0, 0xc100 */ + stl_p(p++, 0x3c08c100); /* lui t0, 0xc100 */ #else - stl_p(p++, 0x340800c1); /* ori t0, r0, 0x00c1 */ + stl_p(p++, 0x340800c1); /* ori t0, r0, 0x00c1 */ #endif - stl_p(p++, 0xad280080); /* sw t0, 0x0080(t1) */ + stl_p(p++, 0xad280080); /* sw t0, 0x0080(t1) */ #ifdef TARGET_WORDS_BIGENDIAN - stl_p(p++, 0x3c085e00); /* lui t0, 0x5e00 */ + stl_p(p++, 0x3c085e00); /* lui t0, 0x5e00 */ #else - stl_p(p++, 0x3408005e); /* ori t0, r0, 0x005e */ + stl_p(p++, 0x3408005e); /* ori t0, r0, 0x005e */ #endif - stl_p(p++, 0xad280088); /* sw t0, 0x0088(t1) */ + stl_p(p++, 0xad280088); /* sw t0, 0x0088(t1) */ /* Jump to kernel code */ - stl_p(p++, 0x3c1f0000 | ((kernel_entry >> 16) & 0xffff)); /* lui ra, high(kernel_entry) */ - stl_p(p++, 0x37ff0000 | (kernel_entry & 0xffff)); /* ori ra, ra, low(kernel_entry) */ - stl_p(p++, 0x03e00009); /* jalr ra */ - stl_p(p++, 0x00000000); /* nop */ + stl_p(p++, 0x3c1f0000 | + ((kernel_entry >> 16) & 0xffff)); /* lui ra, high(kernel_entry) */ + stl_p(p++, 0x37ff0000 | + (kernel_entry & 0xffff)); /* ori ra, ra, low(kernel_entry) */ + stl_p(p++, 0x03e00009); /* jalr ra */ + stl_p(p++, 0x00000000); /* nop */ /* YAMON subroutines */ p = (uint32_t *) (base + 0x800); - stl_p(p++, 0x03e00009); /* jalr ra */ - stl_p(p++, 0x24020000); /* li v0,0 */ + stl_p(p++, 0x03e00009); /* jalr ra */ + stl_p(p++, 0x24020000); /* li v0,0 */ /* 808 YAMON print */ - stl_p(p++, 0x03e06821); /* move t5,ra */ - stl_p(p++, 0x00805821); /* move t3,a0 */ - stl_p(p++, 0x00a05021); /* move t2,a1 */ - stl_p(p++, 0x91440000); /* lbu a0,0(t2) */ - stl_p(p++, 0x254a0001); /* addiu t2,t2,1 */ - stl_p(p++, 0x10800005); /* beqz a0,834 */ - stl_p(p++, 0x00000000); /* nop */ - stl_p(p++, 0x0ff0021c); /* jal 870 */ - stl_p(p++, 0x00000000); /* nop */ - stl_p(p++, 0x1000fff9); /* b 814 */ - stl_p(p++, 0x00000000); /* nop */ - stl_p(p++, 0x01a00009); /* jalr t5 */ - stl_p(p++, 0x01602021); /* move a0,t3 */ + stl_p(p++, 0x03e06821); /* move t5,ra */ + stl_p(p++, 0x00805821); /* move t3,a0 */ + stl_p(p++, 0x00a05021); /* move t2,a1 */ + stl_p(p++, 0x91440000); /* lbu a0,0(t2) */ + stl_p(p++, 0x254a0001); /* addiu t2,t2,1 */ + stl_p(p++, 0x10800005); /* beqz a0,834 */ + stl_p(p++, 0x00000000); /* nop */ + stl_p(p++, 0x0ff0021c); /* jal 870 */ + stl_p(p++, 0x00000000); /* nop */ + stl_p(p++, 0x1000fff9); /* b 814 */ + stl_p(p++, 0x00000000); /* nop */ + stl_p(p++, 0x01a00009); /* jalr t5 */ + stl_p(p++, 0x01602021); /* move a0,t3 */ /* 0x83c YAMON print_count */ - stl_p(p++, 0x03e06821); /* move t5,ra */ - stl_p(p++, 0x00805821); /* move t3,a0 */ - stl_p(p++, 0x00a05021); /* move t2,a1 */ - stl_p(p++, 0x00c06021); /* move t4,a2 */ - stl_p(p++, 0x91440000); /* lbu a0,0(t2) */ - stl_p(p++, 0x0ff0021c); /* jal 870 */ - stl_p(p++, 0x00000000); /* nop */ - stl_p(p++, 0x254a0001); /* addiu t2,t2,1 */ - stl_p(p++, 0x258cffff); /* addiu t4,t4,-1 */ - stl_p(p++, 0x1580fffa); /* bnez t4,84c */ - stl_p(p++, 0x00000000); /* nop */ - stl_p(p++, 0x01a00009); /* jalr t5 */ - stl_p(p++, 0x01602021); /* move a0,t3 */ + stl_p(p++, 0x03e06821); /* move t5,ra */ + stl_p(p++, 0x00805821); /* move t3,a0 */ + stl_p(p++, 0x00a05021); /* move t2,a1 */ + stl_p(p++, 0x00c06021); /* move t4,a2 */ + stl_p(p++, 0x91440000); /* lbu a0,0(t2) */ + stl_p(p++, 0x0ff0021c); /* jal 870 */ + stl_p(p++, 0x00000000); /* nop */ + stl_p(p++, 0x254a0001); /* addiu t2,t2,1 */ + stl_p(p++, 0x258cffff); /* addiu t4,t4,-1 */ + stl_p(p++, 0x1580fffa); /* bnez t4,84c */ + stl_p(p++, 0x00000000); /* nop */ + stl_p(p++, 0x01a00009); /* jalr t5 */ + stl_p(p++, 0x01602021); /* move a0,t3 */ /* 0x870 */ - stl_p(p++, 0x3c08b800); /* lui t0,0xb400 */ - stl_p(p++, 0x350803f8); /* ori t0,t0,0x3f8 */ - stl_p(p++, 0x91090005); /* lbu t1,5(t0) */ - stl_p(p++, 0x00000000); /* nop */ - stl_p(p++, 0x31290040); /* andi t1,t1,0x40 */ - stl_p(p++, 0x1120fffc); /* beqz t1,878 <outch+0x8> */ - stl_p(p++, 0x00000000); /* nop */ - stl_p(p++, 0x03e00009); /* jalr ra */ - stl_p(p++, 0xa1040000); /* sb a0,0(t0) */ + stl_p(p++, 0x3c08b800); /* lui t0,0xb400 */ + stl_p(p++, 0x350803f8); /* ori t0,t0,0x3f8 */ + stl_p(p++, 0x91090005); /* lbu t1,5(t0) */ + stl_p(p++, 0x00000000); /* nop */ + stl_p(p++, 0x31290040); /* andi t1,t1,0x40 */ + stl_p(p++, 0x1120fffc); /* beqz t1,878 <outch+0x8> */ + stl_p(p++, 0x00000000); /* nop */ + stl_p(p++, 0x03e00009); /* jalr ra */ + stl_p(p++, 0xa1040000); /* sb a0,0(t0) */ } @@ -1242,7 +1244,7 @@ void mips_malta_init(MachineState *machine) /* * The whole address space decoded by the GT-64120A doesn't generate * exception when accessing invalid memory. Create an empty slot to - * emulate this feature.\ + * emulate this feature. */ empty_slot_init(0, 0x20000000); diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c index 70024235ae..3891be657c 100644 --- a/hw/mips/mips_r4k.c +++ b/hw/mips/mips_r4k.c @@ -6,7 +6,7 @@ * ISA memory at the 0x10000000 (PHYS, 16Mb in size). * All peripherial devices are attached to this "bus" with * the standard PC ISA addresses. -*/ + */ #include "qemu/osdep.h" #include "qemu/units.h" @@ -54,17 +54,18 @@ static struct _loaderparams { const char *initrd_filename; } loaderparams; -static void mips_qemu_write (void *opaque, hwaddr addr, - uint64_t val, unsigned size) +static void mips_qemu_write(void *opaque, hwaddr addr, + uint64_t val, unsigned size) { - if ((addr & 0xffff) == 0 && val == 42) + if ((addr & 0xffff) == 0 && val == 42) { qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); - else if ((addr & 0xffff) == 4 && val == 42) + } else if ((addr & 0xffff) == 4 && val == 42) { qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); + } } -static uint64_t mips_qemu_read (void *opaque, hwaddr addr, - unsigned size) +static uint64_t mips_qemu_read(void *opaque, hwaddr addr, + unsigned size) { return 0; } @@ -100,8 +101,9 @@ static int64_t load_kernel(void) (uint64_t *)&kernel_high, big_endian, EM_MIPS, 1, 0); if (kernel_size >= 0) { - if ((entry & ~0x7fffffffULL) == 0x80000000) + if ((entry & ~0x7fffffffULL) == 0x80000000) { entry = (int32_t)entry; + } } else { error_report("could not load kernel '%s': %s", loaderparams.kernel_filename, @@ -113,9 +115,10 @@ static int64_t load_kernel(void) initrd_size = 0; initrd_offset = 0; if (loaderparams.initrd_filename) { - initrd_size = get_image_size (loaderparams.initrd_filename); + initrd_size = get_image_size(loaderparams.initrd_filename); if (initrd_size > 0) { - initrd_offset = (kernel_high + ~INITRD_PAGE_MASK) & INITRD_PAGE_MASK; + initrd_offset = (kernel_high + ~INITRD_PAGE_MASK) & + INITRD_PAGE_MASK; if (initrd_offset + initrd_size > ram_size) { error_report("memory too small for initial ram disk '%s'", loaderparams.initrd_filename); @@ -139,11 +142,13 @@ static int64_t load_kernel(void) params_buf[1] = tswap32(0x12345678); if (initrd_size > 0) { - snprintf((char *)params_buf + 8, 256, "rd_start=0x%" PRIx64 " rd_size=%" PRId64 " %s", + snprintf((char *)params_buf + 8, 256, + "rd_start=0x%" PRIx64 " rd_size=%" PRId64 " %s", cpu_mips_phys_to_kseg0(NULL, initrd_offset), initrd_size, loaderparams.kernel_cmdline); } else { - snprintf((char *)params_buf + 8, 256, "%s", loaderparams.kernel_cmdline); + snprintf((char *)params_buf + 8, 256, + "%s", loaderparams.kernel_cmdline); } rom_add_blob_fixed("params", params_buf, params_size, @@ -207,15 +212,21 @@ void mips_r4k_init(MachineState *machine) memory_region_add_subregion(address_space_mem, 0, ram); - memory_region_init_io(iomem, NULL, &mips_qemu_ops, NULL, "mips-qemu", 0x10000); + memory_region_init_io(iomem, NULL, &mips_qemu_ops, + NULL, "mips-qemu", 0x10000); + memory_region_add_subregion(address_space_mem, 0x1fbf0000, iomem); - /* Try to load a BIOS image. If this fails, we continue regardless, - but initialize the hardware ourselves. When a kernel gets - preloaded we also initialize the hardware, since the BIOS wasn't - run. */ - if (bios_name == NULL) + /* + * Try to load a BIOS image. If this fails, we continue regardless, + * but initialize the hardware ourselves. When a kernel gets + * preloaded we also initialize the hardware, since the BIOS wasn't + * run. + */ + + if (bios_name == NULL) { bios_name = BIOS_FILENAME; + } filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { bios_size = get_image_size(filename); @@ -227,6 +238,7 @@ void mips_r4k_init(MachineState *machine) #else be = 0; #endif + dinfo = drive_get(IF_PFLASH, 0, 0); if ((bios_size > 0) && (bios_size <= BIOS_SIZE)) { bios = g_new(MemoryRegion, 1); memory_region_init_ram(bios, NULL, "mips_r4k.bios", BIOS_SIZE, @@ -235,7 +247,7 @@ void mips_r4k_init(MachineState *machine) memory_region_add_subregion(get_system_memory(), 0x1fc00000, bios); load_image_targphys(filename, 0x1fc00000, BIOS_SIZE); - } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) { + } else if (dinfo != NULL) { uint32_t mips_rom = 0x00400000; if (!pflash_cfi01_register(0x1fc00000, "mips_r4k.bios", mips_rom, blk_by_legacy_dinfo(dinfo), @@ -280,11 +292,12 @@ void mips_r4k_init(MachineState *machine) isa_vga_init(isa_bus); - if (nd_table[0].used) + if (nd_table[0].used) { isa_ne2000_init(isa_bus, 0x300, 9, &nd_table[0]); + } ide_drive_get(hd, ARRAY_SIZE(hd)); - for(i = 0; i < MAX_IDE_BUS; i++) + for (i = 0; i < MAX_IDE_BUS; i++) isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], ide_irq[i], hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]); @@ -294,6 +307,7 @@ void mips_r4k_init(MachineState *machine) static void mips_machine_init(MachineClass *mc) { + mc->deprecation_reason = "use malta machine type instead"; mc->desc = "mips r4k platform"; mc->init = mips_r4k_init; mc->block_default_type = IF_IDE; diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c index 717509bc54..f62fa25e34 100644 --- a/hw/misc/aspeed_scu.c +++ b/hw/misc/aspeed_scu.c @@ -98,7 +98,7 @@ #define AST2600_CLK_STOP_CTRL TO_REG(0x80) #define AST2600_CLK_STOP_CTRL_CLR TO_REG(0x84) #define AST2600_CLK_STOP_CTRL2 TO_REG(0x90) -#define AST2600_CLK_STOP_CTR2L_CLR TO_REG(0x94) +#define AST2600_CLK_STOP_CTRL2_CLR TO_REG(0x94) #define AST2600_SDRAM_HANDSHAKE TO_REG(0x100) #define AST2600_HPLL_PARAM TO_REG(0x200) #define AST2600_HPLL_EXT TO_REG(0x204) @@ -532,11 +532,13 @@ static uint64_t aspeed_ast2600_scu_read(void *opaque, hwaddr offset, return s->regs[reg]; } -static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset, uint64_t data, - unsigned size) +static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset, + uint64_t data64, unsigned size) { AspeedSCUState *s = ASPEED_SCU(opaque); int reg = TO_REG(offset); + /* Truncate here so bitwise operations below behave as expected */ + uint32_t data = data64; if (reg >= ASPEED_AST2600_SCU_NR_REGS) { qemu_log_mask(LOG_GUEST_ERROR, @@ -563,15 +565,22 @@ static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset, uint64_t data, /* fall through */ case AST2600_SYS_RST_CTRL: case AST2600_SYS_RST_CTRL2: + case AST2600_CLK_STOP_CTRL: + case AST2600_CLK_STOP_CTRL2: /* W1S (Write 1 to set) registers */ s->regs[reg] |= data; return; case AST2600_SYS_RST_CTRL_CLR: case AST2600_SYS_RST_CTRL2_CLR: + case AST2600_CLK_STOP_CTRL_CLR: + case AST2600_CLK_STOP_CTRL2_CLR: case AST2600_HW_STRAP1_CLR: case AST2600_HW_STRAP2_CLR: - /* W1C (Write 1 to clear) registers */ - s->regs[reg] &= ~data; + /* + * W1C (Write 1 to clear) registers are offset by one address from + * the data register + */ + s->regs[reg - 1] &= ~data; return; case AST2600_RNG_DATA: diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c index f3a63a2e01..2df3244b53 100644 --- a/hw/misc/aspeed_sdmc.c +++ b/hw/misc/aspeed_sdmc.c @@ -208,10 +208,10 @@ static int ast2600_rambits(AspeedSDMCState *s) } /* use a common default */ - warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 512M", + warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 1024M", s->ram_size); - s->ram_size = 512 << 20; - return ASPEED_SDMC_AST2600_512MB; + s->ram_size = 1024 << 20; + return ASPEED_SDMC_AST2600_1024MB; } static void aspeed_sdmc_reset(DeviceState *dev) diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c index eb8b441461..86ac25894a 100644 --- a/hw/net/ftgmac100.c +++ b/hw/net/ftgmac100.c @@ -1204,17 +1204,8 @@ static void aspeed_mii_realize(DeviceState *dev, Error **errp) { AspeedMiiState *s = ASPEED_MII(dev); SysBusDevice *sbd = SYS_BUS_DEVICE(dev); - Object *obj; - Error *local_err = NULL; - obj = object_property_get_link(OBJECT(dev), "nic", &local_err); - if (!obj) { - error_propagate(errp, local_err); - error_prepend(errp, "required link 'nic' not found: "); - return; - } - - s->nic = FTGMAC100(obj); + assert(s->nic); memory_region_init_io(&s->iomem, OBJECT(dev), &aspeed_mii_ops, s, TYPE_ASPEED_MII, 0x8); @@ -1231,6 +1222,13 @@ static const VMStateDescription vmstate_aspeed_mii = { VMSTATE_END_OF_LIST() } }; + +static Property aspeed_mii_properties[] = { + DEFINE_PROP_LINK("nic", AspeedMiiState, nic, TYPE_FTGMAC100, + FTGMAC100State *), + DEFINE_PROP_END_OF_LIST(), +}; + static void aspeed_mii_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1239,6 +1237,7 @@ static void aspeed_mii_class_init(ObjectClass *klass, void *data) dc->reset = aspeed_mii_reset; dc->realize = aspeed_mii_realize; dc->desc = "Aspeed MII controller"; + dc->props = aspeed_mii_properties; } static const TypeInfo aspeed_mii_info = { diff --git a/hw/net/mipsnet.c b/hw/net/mipsnet.c index f7ae1ced4d..380ff5a5f4 100644 --- a/hw/net/mipsnet.c +++ b/hw/net/mipsnet.c @@ -9,19 +9,19 @@ /* MIPSnet register offsets */ -#define MIPSNET_DEV_ID 0x00 -#define MIPSNET_BUSY 0x08 -#define MIPSNET_RX_DATA_COUNT 0x0c -#define MIPSNET_TX_DATA_COUNT 0x10 -#define MIPSNET_INT_CTL 0x14 -# define MIPSNET_INTCTL_TXDONE 0x00000001 -# define MIPSNET_INTCTL_RXDONE 0x00000002 -# define MIPSNET_INTCTL_TESTBIT 0x80000000 -#define MIPSNET_INTERRUPT_INFO 0x18 -#define MIPSNET_RX_DATA_BUFFER 0x1c -#define MIPSNET_TX_DATA_BUFFER 0x20 - -#define MAX_ETH_FRAME_SIZE 1514 +#define MIPSNET_DEV_ID 0x00 +#define MIPSNET_BUSY 0x08 +#define MIPSNET_RX_DATA_COUNT 0x0c +#define MIPSNET_TX_DATA_COUNT 0x10 +#define MIPSNET_INT_CTL 0x14 +# define MIPSNET_INTCTL_TXDONE 0x00000001 +# define MIPSNET_INTCTL_RXDONE 0x00000002 +# define MIPSNET_INTCTL_TESTBIT 0x80000000 +#define MIPSNET_INTERRUPT_INFO 0x18 +#define MIPSNET_RX_DATA_BUFFER 0x1c +#define MIPSNET_TX_DATA_BUFFER 0x20 + +#define MAX_ETH_FRAME_SIZE 1514 #define TYPE_MIPS_NET "mipsnet" #define MIPS_NET(obj) OBJECT_CHECK(MIPSnetState, (obj), TYPE_MIPS_NET) @@ -64,8 +64,9 @@ static void mipsnet_update_irq(MIPSnetState *s) static int mipsnet_buffer_full(MIPSnetState *s) { - if (s->rx_count >= MAX_ETH_FRAME_SIZE) + if (s->rx_count >= MAX_ETH_FRAME_SIZE) { return 1; + } return 0; } @@ -73,18 +74,21 @@ static int mipsnet_can_receive(NetClientState *nc) { MIPSnetState *s = qemu_get_nic_opaque(nc); - if (s->busy) + if (s->busy) { return 0; + } return !mipsnet_buffer_full(s); } -static ssize_t mipsnet_receive(NetClientState *nc, const uint8_t *buf, size_t size) +static ssize_t mipsnet_receive(NetClientState *nc, + const uint8_t *buf, size_t size) { MIPSnetState *s = qemu_get_nic_opaque(nc); trace_mipsnet_receive(size); - if (!mipsnet_can_receive(nc)) + if (!mipsnet_can_receive(nc)) { return 0; + } if (size >= sizeof(s->rx_buffer)) { return 0; @@ -115,10 +119,10 @@ static uint64_t mipsnet_ioport_read(void *opaque, hwaddr addr, addr &= 0x3f; switch (addr) { case MIPSNET_DEV_ID: - ret = be32_to_cpu(0x4d495053); /* MIPS */ + ret = be32_to_cpu(0x4d495053); /* MIPS */ break; case MIPSNET_DEV_ID + 4: - ret = be32_to_cpu(0x4e455430); /* NET0 */ + ret = be32_to_cpu(0x4e455430); /* NET0 */ break; case MIPSNET_BUSY: ret = s->busy; diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c index ceee463a11..4692d419e5 100644 --- a/hw/pci-host/bonito.c +++ b/hw/pci-host/bonito.c @@ -14,7 +14,8 @@ * fulong 2e mini pc has a bonito north bridge. */ -/* what is the meaning of devfn in qemu and IDSEL in bonito northbridge? +/* + * what is the meaning of devfn in qemu and IDSEL in bonito northbridge? * * devfn pci_slot<<3 + funno * one pci bus can have 32 devices and each device can have 8 functions. @@ -49,7 +50,7 @@ #include "sysemu/runstate.h" #include "exec/address-spaces.h" -//#define DEBUG_BONITO +/* #define DEBUG_BONITO */ #ifdef DEBUG_BONITO #define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __func__, ##__VA_ARGS__) @@ -60,45 +61,45 @@ /* from linux soure code. include/asm-mips/mips-boards/bonito64.h*/ #define BONITO_BOOT_BASE 0x1fc00000 #define BONITO_BOOT_SIZE 0x00100000 -#define BONITO_BOOT_TOP (BONITO_BOOT_BASE+BONITO_BOOT_SIZE-1) +#define BONITO_BOOT_TOP (BONITO_BOOT_BASE + BONITO_BOOT_SIZE - 1) #define BONITO_FLASH_BASE 0x1c000000 #define BONITO_FLASH_SIZE 0x03000000 -#define BONITO_FLASH_TOP (BONITO_FLASH_BASE+BONITO_FLASH_SIZE-1) +#define BONITO_FLASH_TOP (BONITO_FLASH_BASE + BONITO_FLASH_SIZE - 1) #define BONITO_SOCKET_BASE 0x1f800000 #define BONITO_SOCKET_SIZE 0x00400000 -#define BONITO_SOCKET_TOP (BONITO_SOCKET_BASE+BONITO_SOCKET_SIZE-1) +#define BONITO_SOCKET_TOP (BONITO_SOCKET_BASE + BONITO_SOCKET_SIZE - 1) #define BONITO_REG_BASE 0x1fe00000 #define BONITO_REG_SIZE 0x00040000 -#define BONITO_REG_TOP (BONITO_REG_BASE+BONITO_REG_SIZE-1) +#define BONITO_REG_TOP (BONITO_REG_BASE + BONITO_REG_SIZE - 1) #define BONITO_DEV_BASE 0x1ff00000 #define BONITO_DEV_SIZE 0x00100000 -#define BONITO_DEV_TOP (BONITO_DEV_BASE+BONITO_DEV_SIZE-1) +#define BONITO_DEV_TOP (BONITO_DEV_BASE + BONITO_DEV_SIZE - 1) #define BONITO_PCILO_BASE 0x10000000 #define BONITO_PCILO_BASE_VA 0xb0000000 #define BONITO_PCILO_SIZE 0x0c000000 -#define BONITO_PCILO_TOP (BONITO_PCILO_BASE+BONITO_PCILO_SIZE-1) +#define BONITO_PCILO_TOP (BONITO_PCILO_BASE + BONITO_PCILO_SIZE - 1) #define BONITO_PCILO0_BASE 0x10000000 #define BONITO_PCILO1_BASE 0x14000000 #define BONITO_PCILO2_BASE 0x18000000 #define BONITO_PCIHI_BASE 0x20000000 #define BONITO_PCIHI_SIZE 0x20000000 -#define BONITO_PCIHI_TOP (BONITO_PCIHI_BASE+BONITO_PCIHI_SIZE-1) +#define BONITO_PCIHI_TOP (BONITO_PCIHI_BASE + BONITO_PCIHI_SIZE - 1) #define BONITO_PCIIO_BASE 0x1fd00000 #define BONITO_PCIIO_BASE_VA 0xbfd00000 #define BONITO_PCIIO_SIZE 0x00010000 -#define BONITO_PCIIO_TOP (BONITO_PCIIO_BASE+BONITO_PCIIO_SIZE-1) +#define BONITO_PCIIO_TOP (BONITO_PCIIO_BASE + BONITO_PCIIO_SIZE - 1) #define BONITO_PCICFG_BASE 0x1fe80000 #define BONITO_PCICFG_SIZE 0x00080000 -#define BONITO_PCICFG_TOP (BONITO_PCICFG_BASE+BONITO_PCICFG_SIZE-1) +#define BONITO_PCICFG_TOP (BONITO_PCICFG_BASE + BONITO_PCICFG_SIZE - 1) #define BONITO_PCICONFIGBASE 0x00 #define BONITO_REGBASE 0x100 -#define BONITO_PCICONFIG_BASE (BONITO_PCICONFIGBASE+BONITO_REG_BASE) +#define BONITO_PCICONFIG_BASE (BONITO_PCICONFIGBASE + BONITO_REG_BASE) #define BONITO_PCICONFIG_SIZE (0x100) -#define BONITO_INTERNAL_REG_BASE (BONITO_REGBASE+BONITO_REG_BASE) +#define BONITO_INTERNAL_REG_BASE (BONITO_REGBASE + BONITO_REG_BASE) #define BONITO_INTERNAL_REG_SIZE (0x70) #define BONITO_SPCICONFIG_BASE (BONITO_PCICFG_BASE) @@ -111,7 +112,7 @@ #define BONITO_BONPONCFG (0x00 >> 2) /* 0x100 */ #define BONITO_BONGENCFG_OFFSET 0x4 -#define BONITO_BONGENCFG (BONITO_BONGENCFG_OFFSET>>2) /*0x104 */ +#define BONITO_BONGENCFG (BONITO_BONGENCFG_OFFSET >> 2) /*0x104 */ /* 2. IO & IDE configuration */ #define BONITO_IODEVCFG (0x08 >> 2) /* 0x108 */ @@ -177,15 +178,15 @@ /* idsel BIT = pci slot number +12 */ #define PCI_SLOT_BASE 12 #define PCI_IDSEL_VIA686B_BIT (17) -#define PCI_IDSEL_VIA686B (1<<PCI_IDSEL_VIA686B_BIT) +#define PCI_IDSEL_VIA686B (1 << PCI_IDSEL_VIA686B_BIT) -#define PCI_ADDR(busno,devno,funno,regno) \ - ((((busno)<<16)&0xff0000) + (((devno)<<11)&0xf800) + (((funno)<<8)&0x700) + (regno)) +#define PCI_ADDR(busno , devno , funno , regno) \ + ((((busno) << 16) & 0xff0000) + (((devno) << 11) & 0xf800) + \ + (((funno) << 8) & 0x700) + (regno)) typedef struct BonitoState BonitoState; -typedef struct PCIBonitoState -{ +typedef struct PCIBonitoState { PCIDevice dev; BonitoState *pcihost; @@ -239,7 +240,8 @@ static void bonito_writel(void *opaque, hwaddr addr, saddr = addr >> 2; - DPRINTF("bonito_writel "TARGET_FMT_plx" val %x saddr %x\n", addr, val, saddr); + DPRINTF("bonito_writel "TARGET_FMT_plx" val %x saddr %x\n", + addr, val, saddr); switch (saddr) { case BONITO_BONPONCFG: case BONITO_IODEVCFG: @@ -363,7 +365,7 @@ static uint64_t bonito_ldma_readl(void *opaque, hwaddr addr, return 0; } - val = ((uint32_t *)(&s->bonldma))[addr/sizeof(uint32_t)]; + val = ((uint32_t *)(&s->bonldma))[addr / sizeof(uint32_t)]; return val; } @@ -377,7 +379,7 @@ static void bonito_ldma_writel(void *opaque, hwaddr addr, return; } - ((uint32_t *)(&s->bonldma))[addr/sizeof(uint32_t)] = val & 0xffffffff; + ((uint32_t *)(&s->bonldma))[addr / sizeof(uint32_t)] = val & 0xffffffff; } static const MemoryRegionOps bonito_ldma_ops = { @@ -400,7 +402,7 @@ static uint64_t bonito_cop_readl(void *opaque, hwaddr addr, return 0; } - val = ((uint32_t *)(&s->boncop))[addr/sizeof(uint32_t)]; + val = ((uint32_t *)(&s->boncop))[addr / sizeof(uint32_t)]; return val; } @@ -414,7 +416,7 @@ static void bonito_cop_writel(void *opaque, hwaddr addr, return; } - ((uint32_t *)(&s->boncop))[addr/sizeof(uint32_t)] = val & 0xffffffff; + ((uint32_t *)(&s->boncop))[addr / sizeof(uint32_t)] = val & 0xffffffff; } static const MemoryRegionOps bonito_cop_ops = { @@ -446,7 +448,8 @@ static uint32_t bonito_sbridge_pciaddr(void *opaque, hwaddr addr) cfgaddr = addr & 0xffff; cfgaddr |= (s->regs[BONITO_PCIMAP_CFG] & 0xffff) << 16; - idsel = (cfgaddr & BONITO_PCICONF_IDSEL_MASK) >> BONITO_PCICONF_IDSEL_OFFSET; + idsel = (cfgaddr & BONITO_PCICONF_IDSEL_MASK) >> + BONITO_PCICONF_IDSEL_OFFSET; devno = ctz32(idsel); funno = (cfgaddr & BONITO_PCICONF_FUN_MASK) >> BONITO_PCICONF_FUN_OFFSET; regno = (cfgaddr & BONITO_PCICONF_REG_MASK) >> BONITO_PCICONF_REG_OFFSET; @@ -550,7 +553,7 @@ static void pci_bonito_set_irq(void *opaque, int irq_num, int level) } /* map the original irq (0~3) to bonito irq (16~47, but 16~31 are unused) */ -static int pci_bonito_map_irq(PCIDevice * pci_dev, int irq_num) +static int pci_bonito_map_irq(PCIDevice *pci_dev, int irq_num) { int slot; @@ -618,7 +621,10 @@ static void bonito_realize(PCIDevice *dev, Error **errp) SysBusDevice *sysbus = SYS_BUS_DEVICE(s->pcihost); PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost); - /* Bonito North Bridge, built on FPGA, VENDOR_ID/DEVICE_ID are "undefined" */ + /* + * Bonito North Bridge, built on FPGA, + * VENDOR_ID/DEVICE_ID are "undefined" + */ pci_config_set_prog_interface(dev->config, 0x00); /* set the north bridge register mapping */ diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index e076f6023c..3ae7db1563 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -4492,14 +4492,25 @@ static const TypeInfo spapr_machine_info = { type_init(spapr_machine_register_##suffix) /* + * pseries-5.0 + */ +static void spapr_machine_5_0_class_options(MachineClass *mc) +{ + /* Defaults for the latest behaviour inherited from the base class */ +} + +DEFINE_SPAPR_MACHINE(5_0, "5.0", true); + +/* * pseries-4.2 */ static void spapr_machine_4_2_class_options(MachineClass *mc) { - /* Defaults for the latest behaviour inherited from the base class */ + spapr_machine_5_0_class_options(mc); + compat_props_add(mc->compat_props, hw_compat_4_2, hw_compat_4_2_len); } -DEFINE_SPAPR_MACHINE(4_2, "4.2", true); +DEFINE_SPAPR_MACHINE(4_2, "4.2", false); /* * pseries-4.1 diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c index 66205697ae..cdcf9154c4 100644 --- a/hw/s390x/event-facility.c +++ b/hw/s390x/event-facility.c @@ -339,14 +339,16 @@ out: static void sclp_events_bus_realize(BusState *bus, Error **errp) { + Error *err = NULL; BusChild *kid; /* TODO: recursive realization has to be done in common code */ QTAILQ_FOREACH(kid, &bus->children, sibling) { DeviceState *dev = kid->child; - object_property_set_bool(OBJECT(dev), true, "realized", errp); - if (*errp) { + object_property_set_bool(OBJECT(dev), true, "realized", &err); + if (errp) { + error_propagate(errp, err); return; } } diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index d3edeef0ad..e0e28139a2 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -348,6 +348,9 @@ static void s390_machine_reset(MachineState *machine) break; case S390_RESET_LOAD_NORMAL: CPU_FOREACH(t) { + if (t == cs) { + continue; + } run_on_cpu(t, s390_do_cpu_reset, RUN_ON_CPU_NULL); } subsystem_reset(); @@ -639,14 +642,26 @@ bool css_migration_enabled(void) } \ type_init(ccw_machine_register_##suffix) +static void ccw_machine_5_0_instance_options(MachineState *machine) +{ +} + +static void ccw_machine_5_0_class_options(MachineClass *mc) +{ +} +DEFINE_CCW_MACHINE(5_0, "5.0", true); + static void ccw_machine_4_2_instance_options(MachineState *machine) { + ccw_machine_5_0_instance_options(machine); } static void ccw_machine_4_2_class_options(MachineClass *mc) { + ccw_machine_5_0_class_options(mc); + compat_props_add(mc->compat_props, hw_compat_4_2, hw_compat_4_2_len); } -DEFINE_CCW_MACHINE(4_2, "4.2", true); +DEFINE_CCW_MACHINE(4_2, "4.2", false); static void ccw_machine_4_1_instance_options(MachineState *machine) { diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index f0c7bbbad3..7755eca349 100644 --- a/hw/ssi/aspeed_smc.c +++ b/hw/ssi/aspeed_smc.c @@ -137,7 +137,7 @@ /* Checksum Calculation Result */ #define R_DMA_CHECKSUM (0x90 / 4) -/* Misc Control Register #2 */ +/* Read Timing Compensation Register */ #define R_TIMINGS (0x94 / 4) /* SPI controller registers and bits (AST2400) */ @@ -256,6 +256,7 @@ static const AspeedSMCController controllers[] = { .r_ce_ctrl = R_CE_CTRL, .r_ctrl0 = R_CTRL0, .r_timings = R_TIMINGS, + .nregs_timings = 1, .conf_enable_w0 = CONF_ENABLE_W0, .max_slaves = 5, .segments = aspeed_segments_legacy, @@ -271,6 +272,7 @@ static const AspeedSMCController controllers[] = { .r_ce_ctrl = R_CE_CTRL, .r_ctrl0 = R_CTRL0, .r_timings = R_TIMINGS, + .nregs_timings = 1, .conf_enable_w0 = CONF_ENABLE_W0, .max_slaves = 5, .segments = aspeed_segments_fmc, @@ -288,6 +290,7 @@ static const AspeedSMCController controllers[] = { .r_ce_ctrl = 0xff, .r_ctrl0 = R_SPI_CTRL0, .r_timings = R_SPI_TIMINGS, + .nregs_timings = 1, .conf_enable_w0 = SPI_CONF_ENABLE_W0, .max_slaves = 1, .segments = aspeed_segments_spi, @@ -303,6 +306,7 @@ static const AspeedSMCController controllers[] = { .r_ce_ctrl = R_CE_CTRL, .r_ctrl0 = R_CTRL0, .r_timings = R_TIMINGS, + .nregs_timings = 1, .conf_enable_w0 = CONF_ENABLE_W0, .max_slaves = 3, .segments = aspeed_segments_ast2500_fmc, @@ -320,6 +324,7 @@ static const AspeedSMCController controllers[] = { .r_ce_ctrl = R_CE_CTRL, .r_ctrl0 = R_CTRL0, .r_timings = R_TIMINGS, + .nregs_timings = 1, .conf_enable_w0 = CONF_ENABLE_W0, .max_slaves = 2, .segments = aspeed_segments_ast2500_spi1, @@ -335,6 +340,7 @@ static const AspeedSMCController controllers[] = { .r_ce_ctrl = R_CE_CTRL, .r_ctrl0 = R_CTRL0, .r_timings = R_TIMINGS, + .nregs_timings = 1, .conf_enable_w0 = CONF_ENABLE_W0, .max_slaves = 2, .segments = aspeed_segments_ast2500_spi2, @@ -350,6 +356,7 @@ static const AspeedSMCController controllers[] = { .r_ce_ctrl = R_CE_CTRL, .r_ctrl0 = R_CTRL0, .r_timings = R_TIMINGS, + .nregs_timings = 1, .conf_enable_w0 = CONF_ENABLE_W0, .max_slaves = 3, .segments = aspeed_segments_ast2600_fmc, @@ -365,6 +372,7 @@ static const AspeedSMCController controllers[] = { .r_ce_ctrl = R_CE_CTRL, .r_ctrl0 = R_CTRL0, .r_timings = R_TIMINGS, + .nregs_timings = 2, .conf_enable_w0 = CONF_ENABLE_W0, .max_slaves = 2, .segments = aspeed_segments_ast2600_spi1, @@ -380,6 +388,7 @@ static const AspeedSMCController controllers[] = { .r_ce_ctrl = R_CE_CTRL, .r_ctrl0 = R_CTRL0, .r_timings = R_TIMINGS, + .nregs_timings = 3, .conf_enable_w0 = CONF_ENABLE_W0, .max_slaves = 3, .segments = aspeed_segments_ast2600_spi2, @@ -444,8 +453,13 @@ static void aspeed_2600_smc_reg_to_segment(const AspeedSMCState *s, uint32_t start_offset = (reg << 16) & AST2600_SEG_ADDR_MASK; uint32_t end_offset = reg & AST2600_SEG_ADDR_MASK; - seg->addr = s->ctrl->flash_window_base + start_offset; - seg->size = end_offset + MiB - start_offset; + if (reg) { + seg->addr = s->ctrl->flash_window_base + start_offset; + seg->size = end_offset + MiB - start_offset; + } else { + seg->addr = s->ctrl->flash_window_base; + seg->size = 0; + } } static bool aspeed_smc_flash_overlap(const AspeedSMCState *s, @@ -475,10 +489,26 @@ static bool aspeed_smc_flash_overlap(const AspeedSMCState *s, return false; } +static void aspeed_smc_flash_set_segment_region(AspeedSMCState *s, int cs, + uint64_t regval) +{ + AspeedSMCFlash *fl = &s->flashes[cs]; + AspeedSegments seg; + + s->ctrl->reg_to_segment(s, regval, &seg); + + memory_region_transaction_begin(); + memory_region_set_size(&fl->mmio, seg.size); + memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base); + memory_region_set_enabled(&fl->mmio, !!seg.size); + memory_region_transaction_commit(); + + s->regs[R_SEG_ADDR0 + cs] = regval; +} + static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs, uint64_t new) { - AspeedSMCFlash *fl = &s->flashes[cs]; AspeedSegments seg; s->ctrl->reg_to_segment(s, new, &seg); @@ -510,8 +540,9 @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs, } /* Keep the segment in the overall flash window */ - if (seg.addr + seg.size <= s->ctrl->flash_window_base || - seg.addr > s->ctrl->flash_window_base + s->ctrl->flash_window_size) { + if (seg.size && + (seg.addr + seg.size <= s->ctrl->flash_window_base || + seg.addr > s->ctrl->flash_window_base + s->ctrl->flash_window_size)) { qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment for CS%d is invalid : " "[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n", s->ctrl->name, cs, seg.addr, seg.addr + seg.size); @@ -529,13 +560,7 @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs, aspeed_smc_flash_overlap(s, &seg, cs); /* All should be fine now to move the region */ - memory_region_transaction_begin(); - memory_region_set_size(&fl->mmio, seg.size); - memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base); - memory_region_set_enabled(&fl->mmio, true); - memory_region_transaction_commit(); - - s->regs[R_SEG_ADDR0 + cs] = new; + aspeed_smc_flash_set_segment_region(s, cs, new); } static uint64_t aspeed_smc_flash_default_read(void *opaque, hwaddr addr, @@ -897,10 +922,10 @@ static void aspeed_smc_reset(DeviceState *d) qemu_set_irq(s->cs_lines[i], true); } - /* setup default segment register values for all */ + /* setup the default segment register values and regions for all */ for (i = 0; i < s->ctrl->max_slaves; ++i) { - s->regs[R_SEG_ADDR0 + i] = - s->ctrl->segment_to_reg(s, &s->ctrl->segments[i]); + aspeed_smc_flash_set_segment_region(s, i, + s->ctrl->segment_to_reg(s, &s->ctrl->segments[i])); } /* HW strapping flash type for the AST2600 controllers */ @@ -935,7 +960,8 @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size) addr >>= 2; if (addr == s->r_conf || - addr == s->r_timings || + (addr >= s->r_timings && + addr < s->r_timings + s->ctrl->nregs_timings) || addr == s->r_ce_ctrl || addr == R_INTR_CTRL || addr == R_DUMMY_DATA || @@ -1200,7 +1226,8 @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data, addr >>= 2; if (addr == s->r_conf || - addr == s->r_timings || + (addr >= s->r_timings && + addr < s->r_timings + s->ctrl->nregs_timings) || addr == s->r_ce_ctrl) { s->regs[addr] = value; } else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs) { diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c index bcce2192a9..a8c38cc118 100644 --- a/hw/timer/aspeed_timer.c +++ b/hw/timer/aspeed_timer.c @@ -19,6 +19,7 @@ #include "qemu/timer.h" #include "qemu/log.h" #include "qemu/module.h" +#include "hw/qdev-properties.h" #include "trace.h" #define TIMER_NR_REGS 4 @@ -603,15 +604,8 @@ static void aspeed_timer_realize(DeviceState *dev, Error **errp) int i; SysBusDevice *sbd = SYS_BUS_DEVICE(dev); AspeedTimerCtrlState *s = ASPEED_TIMER(dev); - Object *obj; - Error *err = NULL; - obj = object_property_get_link(OBJECT(dev), "scu", &err); - if (!obj) { - error_propagate_prepend(errp, err, "required link 'scu' not found: "); - return; - } - s->scu = ASPEED_SCU(obj); + assert(s->scu); for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) { aspeed_init_one_timer(s, i); @@ -677,6 +671,12 @@ static const VMStateDescription vmstate_aspeed_timer_state = { } }; +static Property aspeed_timer_properties[] = { + DEFINE_PROP_LINK("scu", AspeedTimerCtrlState, scu, TYPE_ASPEED_SCU, + AspeedSCUState *), + DEFINE_PROP_END_OF_LIST(), +}; + static void timer_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -685,6 +685,7 @@ static void timer_class_init(ObjectClass *klass, void *data) dc->reset = aspeed_timer_reset; dc->desc = "ASPEED Timer"; dc->vmsd = &vmstate_aspeed_timer_state; + dc->props = aspeed_timer_properties; } static const TypeInfo aspeed_timer_info = { diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c index 6863f6c69f..3b5520ae75 100644 --- a/hw/vfio/ccw.c +++ b/hw/vfio/ccw.c @@ -102,7 +102,7 @@ again: if (errno == EAGAIN) { goto again; } - error_report("vfio-ccw: wirte I/O region failed with errno=%d", errno); + error_report("vfio-ccw: write I/O region failed with errno=%d", errno); ret = -errno; } else { ret = region->ret_code; diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c index 145be6f99c..f50dab922e 100644 --- a/hw/watchdog/wdt_aspeed.c +++ b/hw/watchdog/wdt_aspeed.c @@ -93,11 +93,11 @@ static uint64_t aspeed_wdt_read(void *opaque, hwaddr offset, unsigned size) } -static void aspeed_wdt_reload(AspeedWDTState *s, bool pclk) +static void aspeed_wdt_reload(AspeedWDTState *s) { uint64_t reload; - if (pclk) { + if (!(s->regs[WDT_CTRL] & WDT_CTRL_1MHZ_CLK)) { reload = muldiv64(s->regs[WDT_RELOAD_VALUE], NANOSECONDS_PER_SECOND, s->pclk_freq); } else { @@ -109,6 +109,16 @@ static void aspeed_wdt_reload(AspeedWDTState *s, bool pclk) } } +static void aspeed_wdt_reload_1mhz(AspeedWDTState *s) +{ + uint64_t reload = s->regs[WDT_RELOAD_VALUE] * 1000ULL; + + if (aspeed_wdt_is_enabled(s)) { + timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + reload); + } +} + + static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data, unsigned size) { @@ -130,13 +140,13 @@ static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data, case WDT_RESTART: if ((data & 0xFFFF) == WDT_RESTART_MAGIC) { s->regs[WDT_STATUS] = s->regs[WDT_RELOAD_VALUE]; - aspeed_wdt_reload(s, !(s->regs[WDT_CTRL] & WDT_CTRL_1MHZ_CLK)); + awc->wdt_reload(s); } break; case WDT_CTRL: if (enable && !aspeed_wdt_is_enabled(s)) { s->regs[WDT_CTRL] = data; - aspeed_wdt_reload(s, !(data & WDT_CTRL_1MHZ_CLK)); + awc->wdt_reload(s); } else if (!enable && aspeed_wdt_is_enabled(s)) { s->regs[WDT_CTRL] = data; timer_del(s->timer); @@ -219,7 +229,8 @@ static void aspeed_wdt_timer_expired(void *dev) return; } - qemu_log_mask(CPU_LOG_RESET, "Watchdog timer expired.\n"); + qemu_log_mask(CPU_LOG_RESET, "Watchdog timer %" HWADDR_PRIx " expired.\n", + s->iomem.addr); watchdog_perform_action(); timer_del(s->timer); } @@ -230,16 +241,8 @@ static void aspeed_wdt_realize(DeviceState *dev, Error **errp) { SysBusDevice *sbd = SYS_BUS_DEVICE(dev); AspeedWDTState *s = ASPEED_WDT(dev); - Error *err = NULL; - Object *obj; - obj = object_property_get_link(OBJECT(dev), "scu", &err); - if (!obj) { - error_propagate(errp, err); - error_prepend(errp, "required link 'scu' not found: "); - return; - } - s->scu = ASPEED_SCU(obj); + assert(s->scu); s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, aspeed_wdt_timer_expired, dev); @@ -253,6 +256,12 @@ static void aspeed_wdt_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(sbd, &s->iomem); } +static Property aspeed_wdt_properties[] = { + DEFINE_PROP_LINK("scu", AspeedWDTState, scu, TYPE_ASPEED_SCU, + AspeedSCUState *), + DEFINE_PROP_END_OF_LIST(), +}; + static void aspeed_wdt_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -262,6 +271,7 @@ static void aspeed_wdt_class_init(ObjectClass *klass, void *data) dc->reset = aspeed_wdt_reset; set_bit(DEVICE_CATEGORY_MISC, dc->categories); dc->vmsd = &vmstate_aspeed_wdt; + dc->props = aspeed_wdt_properties; } static const TypeInfo aspeed_wdt_info = { @@ -282,6 +292,7 @@ static void aspeed_2400_wdt_class_init(ObjectClass *klass, void *data) awc->offset = 0x20; awc->ext_pulse_width_mask = 0xff; awc->reset_ctrl_reg = SCU_RESET_CONTROL1; + awc->wdt_reload = aspeed_wdt_reload; } static const TypeInfo aspeed_2400_wdt_info = { @@ -316,6 +327,7 @@ static void aspeed_2500_wdt_class_init(ObjectClass *klass, void *data) awc->ext_pulse_width_mask = 0xfffff; awc->reset_ctrl_reg = SCU_RESET_CONTROL1; awc->reset_pulse = aspeed_2500_wdt_reset_pulse; + awc->wdt_reload = aspeed_wdt_reload_1mhz; } static const TypeInfo aspeed_2500_wdt_info = { @@ -335,6 +347,7 @@ static void aspeed_2600_wdt_class_init(ObjectClass *klass, void *data) awc->ext_pulse_width_mask = 0xfffff; /* TODO */ awc->reset_ctrl_reg = AST2600_SCU_RESET_CONTROL1; awc->reset_pulse = aspeed_2500_wdt_reset_pulse; + awc->wdt_reload = aspeed_wdt_reload_1mhz; } static const TypeInfo aspeed_2600_wdt_info = { |