aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configs/targets/or1k-softmmu.mak1
-rw-r--r--docs/about/deprecated.rst7
-rw-r--r--docs/about/removed-features.rst5
-rw-r--r--docs/system/arm/aspeed.rst1
-rw-r--r--hw/arm/aspeed.c98
-rw-r--r--hw/arm/aspeed_ast2600.c9
-rw-r--r--hw/misc/aspeed_sbc.c141
-rw-r--r--hw/misc/aspeed_sdmc.c2
-rw-r--r--hw/misc/meson.build1
-rw-r--r--hw/misc/trace-events4
-rw-r--r--hw/openrisc/meson.build2
-rw-r--r--hw/openrisc/openrisc_sim.c308
-rw-r--r--hw/ppc/spapr_rtc.c6
-rw-r--r--hw/rtc/mc146818rtc.c5
-rw-r--r--hw/rtc/meson.build2
-rw-r--r--hw/rtc/pl031.c5
-rw-r--r--hw/ssi/aspeed_smc.c11
-rw-r--r--include/hw/arm/aspeed_soc.h3
-rw-r--r--include/hw/misc/aspeed_sbc.h32
-rw-r--r--include/hw/ssi/aspeed_smc.h1
-rw-r--r--qapi/compat.json2
-rw-r--r--qapi/migration.json10
-rw-r--r--qapi/misc-target.json33
-rw-r--r--qapi/misc.json26
-rw-r--r--qapi/qapi-util.c2
-rw-r--r--scripts/qapi/commands.py2
-rw-r--r--scripts/qapi/pylintrc16
-rw-r--r--scripts/qapi/types.py6
-rw-r--r--scripts/qapi/visit.py6
-rw-r--r--util/keyval.c4
30 files changed, 586 insertions, 165 deletions
diff --git a/configs/targets/or1k-softmmu.mak b/configs/targets/or1k-softmmu.mak
index 1dfb93e46d..9e1d4a1fb1 100644
--- a/configs/targets/or1k-softmmu.mak
+++ b/configs/targets/or1k-softmmu.mak
@@ -1,2 +1,3 @@
TARGET_ARCH=openrisc
TARGET_WORDS_BIGENDIAN=y
+TARGET_NEED_FDT=y
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index 26d00812ba..85773db631 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -315,13 +315,6 @@ Use the more generic event ``DEVICE_UNPLUG_GUEST_ERROR`` instead.
System emulator machines
------------------------
-Aspeed ``swift-bmc`` machine (since 6.1)
-''''''''''''''''''''''''''''''''''''''''
-
-This machine is deprecated because we have enough AST2500 based OpenPOWER
-machines. It can be easily replaced by the ``witherspoon-bmc`` or the
-``romulus-bmc`` machines.
-
PPC 405 ``taihu`` machine (since 7.0)
'''''''''''''''''''''''''''''''''''''
diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst
index cb0575fd49..4b831ea291 100644
--- a/docs/about/removed-features.rst
+++ b/docs/about/removed-features.rst
@@ -588,6 +588,11 @@ The Raspberry Pi machines come in various models (A, A+, B, B+). To be able
to distinguish which model QEMU is implementing, the ``raspi2`` and ``raspi3``
machines have been renamed ``raspi2b`` and ``raspi3b``.
+Aspeed ``swift-bmc`` machine (removed in 7.0)
+'''''''''''''''''''''''''''''''''''''''''''''
+
+This machine was removed because it was unused. Alternative AST2500 based
+OpenPOWER machines are ``witherspoon-bmc`` and ``romulus-bmc``.
linux-user mode CPUs
--------------------
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
index d8b102fa0a..60ed94f187 100644
--- a/docs/system/arm/aspeed.rst
+++ b/docs/system/arm/aspeed.rst
@@ -22,7 +22,6 @@ AST2500 SoC based machines :
- ``romulus-bmc`` OpenPOWER Romulus POWER9 BMC
- ``witherspoon-bmc`` OpenPOWER Witherspoon POWER9 BMC
- ``sonorapass-bmc`` OCP SonoraPass BMC
-- ``swift-bmc`` OpenPOWER Swift BMC POWER9 (to be removed in v7.0)
- ``fp5280g2-bmc`` Inspur FP5280G2 BMC
- ``g220a-bmc`` Bytedance G220A BMC
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index d911dc904f..11558b327b 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -106,17 +106,6 @@ struct AspeedMachineState {
SCU_HW_STRAP_VGA_SIZE_SET(VGA_16M_DRAM) | \
SCU_AST2500_HW_STRAP_RESERVED1)
-/* Swift hardware value: 0xF11AD206 */
-#define SWIFT_BMC_HW_STRAP1 ( \
- AST2500_HW_STRAP1_DEFAULTS | \
- SCU_AST2500_HW_STRAP_SPI_AUTOFETCH_ENABLE | \
- SCU_AST2500_HW_STRAP_GPIO_STRAP_ENABLE | \
- SCU_AST2500_HW_STRAP_UART_DEBUG | \
- SCU_AST2500_HW_STRAP_DDR4_ENABLE | \
- SCU_H_PLL_BYPASS_EN | \
- SCU_AST2500_HW_STRAP_ACPI_ENABLE | \
- SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_MASTER))
-
#define G220A_BMC_HW_STRAP1 ( \
SCU_AST2500_HW_STRAP_SPI_AUTOFETCH_ENABLE | \
SCU_AST2500_HW_STRAP_GPIO_STRAP_ENABLE | \
@@ -171,8 +160,8 @@ struct AspeedMachineState {
#define TACOMA_BMC_HW_STRAP2 0x00000040
/* Rainier hardware value: (QEMU prototype) */
-#define RAINIER_BMC_HW_STRAP1 0x00000000
-#define RAINIER_BMC_HW_STRAP2 0x00000000
+#define RAINIER_BMC_HW_STRAP1 0x00422016
+#define RAINIER_BMC_HW_STRAP2 0x80000848
/* Fuji hardware value */
#define FUJI_BMC_HW_STRAP1 0x00000000
@@ -544,33 +533,10 @@ static void romulus_bmc_i2c_init(AspeedMachineState *bmc)
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 11), "ds1338", 0x32);
}
-static void swift_bmc_i2c_init(AspeedMachineState *bmc)
+static void create_pca9552(AspeedSoCState *soc, int bus_id, int addr)
{
- AspeedSoCState *soc = &bmc->soc;
-
- i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 3), "pca9552", 0x60);
-
- /* The swift board expects a TMP275 but a TMP105 is compatible */
- i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7), "tmp105", 0x48);
- /* The swift board expects a pca9551 but a pca9552 is compatible */
- i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7), "pca9552", 0x60);
-
- /* The swift board expects an Epson RX8900 RTC but a ds1338 is compatible */
- i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 8), "ds1338", 0x32);
- i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 8), "pca9552", 0x60);
-
- i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 9), "tmp423", 0x4c);
- /* The swift board expects a pca9539 but a pca9552 is compatible */
- i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 9), "pca9552", 0x74);
-
- i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 10), "tmp423", 0x4c);
- /* The swift board expects a pca9539 but a pca9552 is compatible */
- i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 10), "pca9552",
- 0x74);
-
- /* The swift board expects a TMP275 but a TMP105 is compatible */
- i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 12), "tmp105", 0x48);
- i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 12), "tmp105", 0x4a);
+ i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, bus_id),
+ TYPE_PCA9552, addr);
}
static void sonorapass_bmc_i2c_init(AspeedMachineState *bmc)
@@ -589,9 +555,9 @@ static void sonorapass_bmc_i2c_init(AspeedMachineState *bmc)
smbus_eeprom_init_one(aspeed_i2c_get_bus(&soc->i2c, 4), 0x54,
eeprom4_54);
/* PCA9539 @ 0x76, but PCA9552 is compatible */
- i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 4), "pca9552", 0x76);
+ create_pca9552(soc, 4, 0x76);
/* PCA9539 @ 0x77, but PCA9552 is compatible */
- i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 4), "pca9552", 0x77);
+ create_pca9552(soc, 4, 0x77);
/* bus 6 : */
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 6), "tmp105", 0x48);
@@ -602,8 +568,8 @@ static void sonorapass_bmc_i2c_init(AspeedMachineState *bmc)
uint8_t *eeprom8_56 = g_malloc0(8 * 1024);
smbus_eeprom_init_one(aspeed_i2c_get_bus(&soc->i2c, 8), 0x56,
eeprom8_56);
- i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 8), "pca9552", 0x60);
- i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 8), "pca9552", 0x61);
+ create_pca9552(soc, 8, 0x60);
+ create_pca9552(soc, 8, 0x61);
/* bus 8 : adc128d818 @ 0x1d */
/* bus 8 : adc128d818 @ 0x1f */
@@ -741,8 +707,7 @@ static void fp5280g2_bmc_i2c_init(AspeedMachineState *bmc)
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 4), "ds1338", 0x68);
/* It expects a pca9555 but a pca9552 is compatible */
- i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 8), TYPE_PCA9552,
- 0x20);
+ create_pca9552(soc, 8, 0x30);
}
static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
@@ -752,6 +717,8 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
aspeed_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 0), 0x51, 32 * KiB);
+ create_pca9552(soc, 3, 0x61);
+
/* The rainier expects a TMP275 but a TMP105 is compatible */
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 4), TYPE_TMP105,
0x48);
@@ -764,11 +731,14 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x52, 64 * KiB);
+ create_pca9552(soc, 4, 0x60);
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 5), TYPE_TMP105,
0x48);
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 5), TYPE_TMP105,
0x49);
+ create_pca9552(soc, 5, 0x60);
+ create_pca9552(soc, 5, 0x61);
i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 5),
"pca9546", 0x70);
aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
@@ -787,8 +757,13 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x50, 64 * KiB);
aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 0x51, 64 * KiB);
+ create_pca9552(soc, 7, 0x30);
+ create_pca9552(soc, 7, 0x31);
+ create_pca9552(soc, 7, 0x32);
+ create_pca9552(soc, 7, 0x33);
/* Bus 7: TODO max31785@52 */
- i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7), "pca9552", 0x61);
+ create_pca9552(soc, 7, 0x60);
+ create_pca9552(soc, 7, 0x61);
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7), "dps310", 0x76);
/* Bus 7: TODO si7021-a20@20 */
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7), TYPE_TMP105,
@@ -802,7 +777,8 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
0x4a);
aspeed_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 8), 0x50, 64 * KiB);
aspeed_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 8), 0x51, 64 * KiB);
- i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 8), "pca9552", 0x61);
+ create_pca9552(soc, 8, 0x60);
+ create_pca9552(soc, 8, 0x61);
/* Bus 8: ucd90320@11 */
/* Bus 8: ucd90320@b */
/* Bus 8: ucd90320@c */
@@ -823,13 +799,17 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
"pca9546", 0x70);
aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
+ create_pca9552(soc, 11, 0x60);
aspeed_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 13), 0x50, 64 * KiB);
+ create_pca9552(soc, 13, 0x60);
aspeed_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 14), 0x50, 64 * KiB);
+ create_pca9552(soc, 14, 0x60);
aspeed_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 15), 0x50, 64 * KiB);
+ create_pca9552(soc, 15, 0x60);
}
static void get_pca9548_channels(I2CBus *bus, uint8_t mux_addr,
@@ -1102,26 +1082,6 @@ static void aspeed_machine_sonorapass_class_init(ObjectClass *oc, void *data)
aspeed_soc_num_cpus(amc->soc_name);
};
-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;
- mc->default_cpus = mc->min_cpus = mc->max_cpus =
- aspeed_soc_num_cpus(amc->soc_name);
-
- mc->deprecation_reason = "redundant system. Please use a similar "
- "OpenPOWER BMC, Witherspoon or Romulus.";
-};
-
static void aspeed_machine_witherspoon_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
@@ -1278,10 +1238,6 @@ static const TypeInfo aspeed_machine_types[] = {
.parent = TYPE_ASPEED_MACHINE,
.class_init = aspeed_machine_romulus_class_init,
}, {
- .name = MACHINE_TYPE_NAME("swift-bmc"),
- .parent = TYPE_ASPEED_MACHINE,
- .class_init = aspeed_machine_swift_class_init,
- }, {
.name = MACHINE_TYPE_NAME("sonorapass-bmc"),
.parent = TYPE_ASPEED_MACHINE,
.class_init = aspeed_machine_sonorapass_class_init,
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index 12f6edc081..21cd3342c5 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -47,6 +47,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
[ASPEED_DEV_XDMA] = 0x1E6E7000,
[ASPEED_DEV_ADC] = 0x1E6E9000,
[ASPEED_DEV_DP] = 0x1E6EB000,
+ [ASPEED_DEV_SBC] = 0x1E6F2000,
[ASPEED_DEV_VIDEO] = 0x1E700000,
[ASPEED_DEV_SDHCI] = 0x1E740000,
[ASPEED_DEV_EMMC] = 0x1E750000,
@@ -227,6 +228,8 @@ static void aspeed_soc_ast2600_init(Object *obj)
object_initialize_child(obj, "hace", &s->hace, typename);
object_initialize_child(obj, "i3c", &s->i3c, TYPE_ASPEED_I3C);
+
+ object_initialize_child(obj, "sbc", &s->sbc, TYPE_ASPEED_SBC);
}
/*
@@ -539,6 +542,12 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
/* The AST2600 I3C controller has one IRQ per bus. */
sysbus_connect_irq(SYS_BUS_DEVICE(&s->i3c.devices[i]), 0, irq);
}
+
+ /* Secure Boot Controller */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->sbc), errp)) {
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->sbc), 0, sc->memmap[ASPEED_DEV_SBC]);
}
static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
diff --git a/hw/misc/aspeed_sbc.c b/hw/misc/aspeed_sbc.c
new file mode 100644
index 0000000000..40f2a8c631
--- /dev/null
+++ b/hw/misc/aspeed_sbc.c
@@ -0,0 +1,141 @@
+/*
+ * ASPEED Secure Boot Controller
+ *
+ * Copyright (C) 2021-2022 IBM Corp.
+ *
+ * Joel Stanley <joel@jms.id.au>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "hw/misc/aspeed_sbc.h"
+#include "qapi/error.h"
+#include "migration/vmstate.h"
+
+#define R_PROT (0x000 / 4)
+#define R_STATUS (0x014 / 4)
+
+static uint64_t aspeed_sbc_read(void *opaque, hwaddr addr, unsigned int size)
+{
+ AspeedSBCState *s = ASPEED_SBC(opaque);
+
+ addr >>= 2;
+
+ if (addr >= ASPEED_SBC_NR_REGS) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
+ __func__, addr << 2);
+ return 0;
+ }
+
+ return s->regs[addr];
+}
+
+static void aspeed_sbc_write(void *opaque, hwaddr addr, uint64_t data,
+ unsigned int size)
+{
+ AspeedSBCState *s = ASPEED_SBC(opaque);
+
+ addr >>= 2;
+
+ if (addr >= ASPEED_SBC_NR_REGS) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
+ __func__, addr << 2);
+ return;
+ }
+
+ switch (addr) {
+ case R_STATUS:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: write to read only register 0x%" HWADDR_PRIx "\n",
+ __func__, addr << 2);
+ return;
+ default:
+ break;
+ }
+
+ s->regs[addr] = data;
+}
+
+static const MemoryRegionOps aspeed_sbc_ops = {
+ .read = aspeed_sbc_read,
+ .write = aspeed_sbc_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 1,
+ .max_access_size = 4,
+ },
+};
+
+static void aspeed_sbc_reset(DeviceState *dev)
+{
+ struct AspeedSBCState *s = ASPEED_SBC(dev);
+
+ memset(s->regs, 0, sizeof(s->regs));
+
+ /* Set secure boot enabled, and boot from emmc/spi */
+ s->regs[R_STATUS] = 1 << 6 | 1 << 5;
+}
+
+static void aspeed_sbc_realize(DeviceState *dev, Error **errp)
+{
+ AspeedSBCState *s = ASPEED_SBC(dev);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+
+ memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_sbc_ops, s,
+ TYPE_ASPEED_SBC, 0x1000);
+
+ sysbus_init_mmio(sbd, &s->iomem);
+}
+
+static const VMStateDescription vmstate_aspeed_sbc = {
+ .name = TYPE_ASPEED_SBC,
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(regs, AspeedSBCState, ASPEED_SBC_NR_REGS),
+ VMSTATE_END_OF_LIST(),
+ }
+};
+
+static void aspeed_sbc_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->realize = aspeed_sbc_realize;
+ dc->reset = aspeed_sbc_reset;
+ dc->vmsd = &vmstate_aspeed_sbc;
+}
+
+static const TypeInfo aspeed_sbc_info = {
+ .name = TYPE_ASPEED_SBC,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(AspeedSBCState),
+ .class_init = aspeed_sbc_class_init,
+ .class_size = sizeof(AspeedSBCClass)
+};
+
+static void aspeed_ast2600_sbc_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->desc = "AST2600 Secure Boot Controller";
+}
+
+static const TypeInfo aspeed_ast2600_sbc_info = {
+ .name = TYPE_ASPEED_AST2600_SBC,
+ .parent = TYPE_ASPEED_SBC,
+ .class_init = aspeed_ast2600_sbc_class_init,
+};
+
+static void aspeed_sbc_register_types(void)
+{
+ type_register_static(&aspeed_ast2600_sbc_info);
+ type_register_static(&aspeed_sbc_info);
+}
+
+type_init(aspeed_sbc_register_types);
diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
index 08f856cbda..d2a3931033 100644
--- a/hw/misc/aspeed_sdmc.c
+++ b/hw/misc/aspeed_sdmc.c
@@ -130,6 +130,7 @@ static uint64_t aspeed_sdmc_read(void *opaque, hwaddr addr, unsigned size)
return 0;
}
+ trace_aspeed_sdmc_read(addr, s->regs[addr]);
return s->regs[addr];
}
@@ -148,6 +149,7 @@ static void aspeed_sdmc_write(void *opaque, hwaddr addr, uint64_t data,
return;
}
+ trace_aspeed_sdmc_write(addr, data);
asc->write(s, addr, data);
}
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 6dcbe044f3..645585371a 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -111,6 +111,7 @@ softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files(
'aspeed_i3c.c',
'aspeed_lpc.c',
'aspeed_scu.c',
+ 'aspeed_sbc.c',
'aspeed_sdmc.c',
'aspeed_xdma.c'))
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index 1c373dd0a4..fb5a389780 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -205,6 +205,10 @@ aspeed_i3c_write(uint64_t offset, uint64_t data) "I3C write: offset 0x%" PRIx64
aspeed_i3c_device_read(uint32_t deviceid, uint64_t offset, uint64_t data) "I3C Dev[%u] read: offset 0x%" PRIx64 " data 0x%" PRIx64
aspeed_i3c_device_write(uint32_t deviceid, uint64_t offset, uint64_t data) "I3C Dev[%u] write: offset 0x%" PRIx64 " data 0x%" PRIx64
+# aspeed_sdmc.c
+aspeed_sdmc_write(uint64_t reg, uint64_t data) "reg @0x%" PRIx64 " data: 0x%" PRIx64
+aspeed_sdmc_read(uint64_t reg, uint64_t data) "reg @0x%" PRIx64 " data: 0x%" PRIx64
+
# bcm2835_property.c
bcm2835_mbox_property(uint32_t tag, uint32_t bufsize, size_t resplen) "mbox property tag:0x%08x in_sz:%u out_sz:%zu"
diff --git a/hw/openrisc/meson.build b/hw/openrisc/meson.build
index 947f63ee08..ec48172c9d 100644
--- a/hw/openrisc/meson.build
+++ b/hw/openrisc/meson.build
@@ -1,5 +1,5 @@
openrisc_ss = ss.source_set()
openrisc_ss.add(files('cputimer.c'))
-openrisc_ss.add(when: 'CONFIG_OR1K_SIM', if_true: files('openrisc_sim.c'))
+openrisc_ss.add(when: 'CONFIG_OR1K_SIM', if_true: [files('openrisc_sim.c'), fdt])
hw_arch += {'openrisc': openrisc_ss}
diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index 73fe383c2d..8184caa60b 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -29,16 +29,61 @@
#include "net/net.h"
#include "hw/loader.h"
#include "hw/qdev-properties.h"
+#include "exec/address-spaces.h"
+#include "sysemu/device_tree.h"
#include "sysemu/sysemu.h"
#include "hw/sysbus.h"
#include "sysemu/qtest.h"
#include "sysemu/reset.h"
#include "hw/core/split-irq.h"
+#include <libfdt.h>
+
#define KERNEL_LOAD_ADDR 0x100
+#define OR1KSIM_CPUS_MAX 4
+#define OR1KSIM_CLK_MHZ 20000000
+
+#define TYPE_OR1KSIM_MACHINE MACHINE_TYPE_NAME("or1k-sim")
+#define OR1KSIM_MACHINE(obj) \
+ OBJECT_CHECK(Or1ksimState, (obj), TYPE_OR1KSIM_MACHINE)
+
+typedef struct Or1ksimState {
+ /*< private >*/
+ MachineState parent_obj;
+
+ /*< public >*/
+ void *fdt;
+ int fdt_size;
+
+} Or1ksimState;
+
+enum {
+ OR1KSIM_DRAM,
+ OR1KSIM_UART,
+ OR1KSIM_ETHOC,
+ OR1KSIM_OMPIC,
+};
+
+enum {
+ OR1KSIM_OMPIC_IRQ = 1,
+ OR1KSIM_UART_IRQ = 2,
+ OR1KSIM_ETHOC_IRQ = 4,
+};
+
+static const struct MemmapEntry {
+ hwaddr base;
+ hwaddr size;
+} or1ksim_memmap[] = {
+ [OR1KSIM_DRAM] = { 0x00000000, 0 },
+ [OR1KSIM_UART] = { 0x90000000, 0x100 },
+ [OR1KSIM_ETHOC] = { 0x92000000, 0x800 },
+ [OR1KSIM_OMPIC] = { 0x98000000, 16 },
+};
+
static struct openrisc_boot_info {
uint32_t bootstrap_pc;
+ uint32_t fdt_addr;
} boot_info;
static void main_cpu_reset(void *opaque)
@@ -49,6 +94,7 @@ static void main_cpu_reset(void *opaque)
cpu_reset(CPU(cpu));
cpu_set_pc(cs, boot_info.bootstrap_pc);
+ cpu_set_gpr(&cpu->env, 3, boot_info.fdt_addr);
}
static qemu_irq get_cpu_irq(OpenRISCCPU *cpus[], int cpunum, int irq_pin)
@@ -56,12 +102,77 @@ static qemu_irq get_cpu_irq(OpenRISCCPU *cpus[], int cpunum, int irq_pin)
return qdev_get_gpio_in_named(DEVICE(cpus[cpunum]), "IRQ", irq_pin);
}
-static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
+static void openrisc_create_fdt(Or1ksimState *state,
+ const struct MemmapEntry *memmap,
+ int num_cpus, uint64_t mem_size,
+ const char *cmdline)
+{
+ void *fdt;
+ int cpu;
+ char *nodename;
+ int pic_ph;
+
+ fdt = state->fdt = create_device_tree(&state->fdt_size);
+ if (!fdt) {
+ error_report("create_device_tree() failed");
+ exit(1);
+ }
+
+ qemu_fdt_setprop_string(fdt, "/", "compatible", "opencores,or1ksim");
+ qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x1);
+ qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x1);
+
+ nodename = g_strdup_printf("/memory@%" HWADDR_PRIx,
+ memmap[OR1KSIM_DRAM].base);
+ qemu_fdt_add_subnode(fdt, nodename);
+ qemu_fdt_setprop_cells(fdt, nodename, "reg",
+ memmap[OR1KSIM_DRAM].base, mem_size);
+ qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
+ g_free(nodename);
+
+ qemu_fdt_add_subnode(fdt, "/cpus");
+ qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
+ qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
+
+ for (cpu = 0; cpu < num_cpus; cpu++) {
+ nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
+ qemu_fdt_add_subnode(fdt, nodename);
+ qemu_fdt_setprop_string(fdt, nodename, "compatible",
+ "opencores,or1200-rtlsvn481");
+ qemu_fdt_setprop_cell(fdt, nodename, "reg", cpu);
+ qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
+ OR1KSIM_CLK_MHZ);
+ g_free(nodename);
+ }
+
+ nodename = (char *)"/pic";
+ qemu_fdt_add_subnode(fdt, nodename);
+ pic_ph = qemu_fdt_alloc_phandle(fdt);
+ qemu_fdt_setprop_string(fdt, nodename, "compatible",
+ "opencores,or1k-pic-level");
+ qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", 1);
+ qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
+ qemu_fdt_setprop_cell(fdt, nodename, "phandle", pic_ph);
+
+ qemu_fdt_setprop_cell(fdt, "/", "interrupt-parent", pic_ph);
+
+ qemu_fdt_add_subnode(fdt, "/chosen");
+ if (cmdline) {
+ qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
+ }
+
+ /* Create aliases node for use by devices. */
+ qemu_fdt_add_subnode(fdt, "/aliases");
+}
+
+static void openrisc_sim_net_init(Or1ksimState *state, hwaddr base, hwaddr size,
int num_cpus, OpenRISCCPU *cpus[],
int irq_pin, NICInfo *nd)
{
+ void *fdt = state->fdt;
DeviceState *dev;
SysBusDevice *s;
+ char *nodename;
int i;
dev = qdev_new("open_eth");
@@ -81,14 +192,28 @@ static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
sysbus_connect_irq(s, 0, get_cpu_irq(cpus, 0, irq_pin));
}
sysbus_mmio_map(s, 0, base);
- sysbus_mmio_map(s, 1, descriptors);
+ sysbus_mmio_map(s, 1, base + 0x400);
+
+ /* Init device tree node for ethoc. */
+ nodename = g_strdup_printf("/ethoc@%" HWADDR_PRIx, base);
+ qemu_fdt_add_subnode(fdt, nodename);
+ qemu_fdt_setprop_string(fdt, nodename, "compatible", "opencores,ethoc");
+ qemu_fdt_setprop_cells(fdt, nodename, "reg", base, size);
+ qemu_fdt_setprop_cell(fdt, nodename, "interrupts", irq_pin);
+ qemu_fdt_setprop(fdt, nodename, "big-endian", NULL, 0);
+
+ qemu_fdt_setprop_string(fdt, "/aliases", "enet0", nodename);
+ g_free(nodename);
}
-static void openrisc_sim_ompic_init(hwaddr base, int num_cpus,
+static void openrisc_sim_ompic_init(Or1ksimState *state, hwaddr base,
+ hwaddr size, int num_cpus,
OpenRISCCPU *cpus[], int irq_pin)
{
+ void *fdt = state->fdt;
DeviceState *dev;
SysBusDevice *s;
+ char *nodename;
int i;
dev = qdev_new("or1k-ompic");
@@ -100,28 +225,79 @@ static void openrisc_sim_ompic_init(hwaddr base, int num_cpus,
sysbus_connect_irq(s, i, get_cpu_irq(cpus, i, irq_pin));
}
sysbus_mmio_map(s, 0, base);
+
+ /* Add device tree node for ompic. */
+ nodename = g_strdup_printf("/ompic@%" HWADDR_PRIx, base);
+ qemu_fdt_add_subnode(fdt, nodename);
+ qemu_fdt_setprop_string(fdt, nodename, "compatible", "openrisc,ompic");
+ qemu_fdt_setprop_cells(fdt, nodename, "reg", base, size);
+ qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
+ qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", 0);
+ qemu_fdt_setprop_cell(fdt, nodename, "interrupts", irq_pin);
+ g_free(nodename);
}
-static void openrisc_load_kernel(ram_addr_t ram_size,
- const char *kernel_filename)
+static void openrisc_sim_serial_init(Or1ksimState *state, hwaddr base,
+ hwaddr size, int num_cpus,
+ OpenRISCCPU *cpus[], int irq_pin)
+{
+ void *fdt = state->fdt;
+ char *nodename;
+ qemu_irq serial_irq;
+ int i;
+
+ if (num_cpus > 1) {
+ DeviceState *splitter = qdev_new(TYPE_SPLIT_IRQ);
+ qdev_prop_set_uint32(splitter, "num-lines", num_cpus);
+ qdev_realize_and_unref(splitter, NULL, &error_fatal);
+ for (i = 0; i < num_cpus; i++) {
+ qdev_connect_gpio_out(splitter, i, get_cpu_irq(cpus, i, irq_pin));
+ }
+ serial_irq = qdev_get_gpio_in(splitter, 0);
+ } else {
+ serial_irq = get_cpu_irq(cpus, 0, irq_pin);
+ }
+ serial_mm_init(get_system_memory(), base, 0, serial_irq, 115200,
+ serial_hd(0), DEVICE_NATIVE_ENDIAN);
+
+ /* Add device tree node for serial. */
+ nodename = g_strdup_printf("/serial@%" HWADDR_PRIx, base);
+ qemu_fdt_add_subnode(fdt, nodename);
+ qemu_fdt_setprop_string(fdt, nodename, "compatible", "ns16550a");
+ qemu_fdt_setprop_cells(fdt, nodename, "reg", base, size);
+ qemu_fdt_setprop_cell(fdt, nodename, "interrupts", irq_pin);
+ qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency", OR1KSIM_CLK_MHZ);
+ qemu_fdt_setprop(fdt, nodename, "big-endian", NULL, 0);
+
+ /* The /chosen node is created during fdt creation. */
+ qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename);
+ qemu_fdt_setprop_string(fdt, "/aliases", "uart0", nodename);
+ g_free(nodename);
+}
+
+static hwaddr openrisc_load_kernel(ram_addr_t ram_size,
+ const char *kernel_filename)
{
long kernel_size;
uint64_t elf_entry;
+ uint64_t high_addr;
hwaddr entry;
if (kernel_filename && !qtest_enabled()) {
kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
- &elf_entry, NULL, NULL, NULL, 1, EM_OPENRISC,
- 1, 0);
+ &elf_entry, NULL, &high_addr, NULL, 1,
+ EM_OPENRISC, 1, 0);
entry = elf_entry;
if (kernel_size < 0) {
kernel_size = load_uimage(kernel_filename,
&entry, NULL, NULL, NULL, NULL);
+ high_addr = entry + kernel_size;
}
if (kernel_size < 0) {
kernel_size = load_image_targphys(kernel_filename,
KERNEL_LOAD_ADDR,
ram_size - KERNEL_LOAD_ADDR);
+ high_addr = KERNEL_LOAD_ADDR + kernel_size;
}
if (entry <= 0) {
@@ -133,20 +309,79 @@ static void openrisc_load_kernel(ram_addr_t ram_size,
exit(1);
}
boot_info.bootstrap_pc = entry;
+
+ return high_addr;
}
+ return 0;
+}
+
+static hwaddr openrisc_load_initrd(Or1ksimState *state, const char *filename,
+ hwaddr load_start, uint64_t mem_size)
+{
+ void *fdt = state->fdt;
+ int size;
+ hwaddr start;
+
+ /* We put the initrd right after the kernel; page aligned. */
+ start = TARGET_PAGE_ALIGN(load_start);
+
+ size = load_ramdisk(filename, start, mem_size - start);
+ if (size < 0) {
+ size = load_image_targphys(filename, start, mem_size - start);
+ if (size < 0) {
+ error_report("could not load ramdisk '%s'", filename);
+ exit(1);
+ }
+ }
+
+ qemu_fdt_setprop_cell(fdt, "/chosen",
+ "linux,initrd-start", start);
+ qemu_fdt_setprop_cell(fdt, "/chosen",
+ "linux,initrd-end", start + size);
+
+ return start + size;
+}
+
+static uint32_t openrisc_load_fdt(Or1ksimState *state, hwaddr load_start,
+ uint64_t mem_size)
+{
+ void *fdt = state->fdt;
+ uint32_t fdt_addr;
+ int ret;
+ int fdtsize = fdt_totalsize(fdt);
+
+ if (fdtsize <= 0) {
+ error_report("invalid device-tree");
+ exit(1);
+ }
+
+ /* We put fdt right after the kernel and/or initrd. */
+ fdt_addr = ROUND_UP(load_start, 4);
+
+ ret = fdt_pack(fdt);
+ /* Should only fail if we've built a corrupted tree */
+ g_assert(ret == 0);
+ /* copy in the device tree */
+ qemu_fdt_dumpdtb(fdt, fdtsize);
+
+ rom_add_blob_fixed_as("fdt", fdt, fdtsize, fdt_addr,
+ &address_space_memory);
+
+ return fdt_addr;
}
static void openrisc_sim_init(MachineState *machine)
{
ram_addr_t ram_size = machine->ram_size;
const char *kernel_filename = machine->kernel_filename;
- OpenRISCCPU *cpus[2] = {};
+ OpenRISCCPU *cpus[OR1KSIM_CPUS_MAX] = {};
+ Or1ksimState *state = OR1KSIM_MACHINE(machine);
MemoryRegion *ram;
- qemu_irq serial_irq;
+ hwaddr load_addr;
int n;
unsigned int smp_cpus = machine->smp.cpus;
- assert(smp_cpus >= 1 && smp_cpus <= 2);
+ assert(smp_cpus >= 1 && smp_cpus <= OR1KSIM_CPUS_MAX);
for (n = 0; n < smp_cpus; n++) {
cpus[n] = OPENRISC_CPU(cpu_create(machine->cpu_type));
if (cpus[n] == NULL) {
@@ -163,33 +398,58 @@ static void openrisc_sim_init(MachineState *machine)
memory_region_init_ram(ram, NULL, "openrisc.ram", ram_size, &error_fatal);
memory_region_add_subregion(get_system_memory(), 0, ram);
+ openrisc_create_fdt(state, or1ksim_memmap, smp_cpus, machine->ram_size,
+ machine->kernel_cmdline);
+
if (nd_table[0].used) {
- openrisc_sim_net_init(0x92000000, 0x92000400, smp_cpus,
- cpus, 4, nd_table);
+ openrisc_sim_net_init(state, or1ksim_memmap[OR1KSIM_ETHOC].base,
+ or1ksim_memmap[OR1KSIM_ETHOC].size,
+ smp_cpus, cpus,
+ OR1KSIM_ETHOC_IRQ, nd_table);
}
if (smp_cpus > 1) {
- openrisc_sim_ompic_init(0x98000000, smp_cpus, cpus, 1);
-
- serial_irq = qemu_irq_split(get_cpu_irq(cpus, 0, 2),
- get_cpu_irq(cpus, 1, 2));
- } else {
- serial_irq = get_cpu_irq(cpus, 0, 2);
+ openrisc_sim_ompic_init(state, or1ksim_memmap[OR1KSIM_OMPIC].base,
+ or1ksim_memmap[OR1KSIM_UART].size,
+ smp_cpus, cpus, OR1KSIM_OMPIC_IRQ);
}
- serial_mm_init(get_system_memory(), 0x90000000, 0, serial_irq,
- 115200, serial_hd(0), DEVICE_NATIVE_ENDIAN);
+ openrisc_sim_serial_init(state, or1ksim_memmap[OR1KSIM_UART].base,
+ or1ksim_memmap[OR1KSIM_UART].size, smp_cpus, cpus,
+ OR1KSIM_UART_IRQ);
- openrisc_load_kernel(ram_size, kernel_filename);
+ load_addr = openrisc_load_kernel(ram_size, kernel_filename);
+ if (load_addr > 0) {
+ if (machine->initrd_filename) {
+ load_addr = openrisc_load_initrd(state, machine->initrd_filename,
+ load_addr, machine->ram_size);
+ }
+ boot_info.fdt_addr = openrisc_load_fdt(state, load_addr,
+ machine->ram_size);
+ }
}
-static void openrisc_sim_machine_init(MachineClass *mc)
+static void openrisc_sim_machine_init(ObjectClass *oc, void *data)
{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
mc->desc = "or1k simulation";
mc->init = openrisc_sim_init;
- mc->max_cpus = 2;
+ mc->max_cpus = OR1KSIM_CPUS_MAX;
mc->is_default = true;
mc->default_cpu_type = OPENRISC_CPU_TYPE_NAME("or1200");
}
-DEFINE_MACHINE("or1k-sim", openrisc_sim_machine_init)
+static const TypeInfo or1ksim_machine_typeinfo = {
+ .name = TYPE_OR1KSIM_MACHINE,
+ .parent = TYPE_MACHINE,
+ .class_init = openrisc_sim_machine_init,
+ .instance_size = sizeof(Or1ksimState),
+};
+
+static void or1ksim_machine_init_register_types(void)
+{
+ type_register_static(&or1ksim_machine_typeinfo);
+}
+
+type_init(or1ksim_machine_init_register_types)
diff --git a/hw/ppc/spapr_rtc.c b/hw/ppc/spapr_rtc.c
index 94a5510e4e..d55b4b0c50 100644
--- a/hw/ppc/spapr_rtc.c
+++ b/hw/ppc/spapr_rtc.c
@@ -32,7 +32,7 @@
#include "hw/ppc/spapr.h"
#include "migration/vmstate.h"
#include "qapi/error.h"
-#include "qapi/qapi-events-misc-target.h"
+#include "qapi/qapi-events-misc.h"
#include "qemu/cutils.h"
#include "qemu/module.h"
@@ -97,6 +97,7 @@ static void rtas_set_time_of_day(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t nret, target_ulong rets)
{
SpaprRtcState *rtc = &spapr->rtc;
+ g_autofree const char *qom_path = NULL;
struct tm tm;
time_t new_s;
int64_t host_ns;
@@ -120,7 +121,8 @@ static void rtas_set_time_of_day(PowerPCCPU *cpu, SpaprMachineState *spapr,
}
/* Generate a monitor event for the change */
- qapi_event_send_rtc_change(qemu_timedate_diff(&tm));
+ qom_path = object_get_canonical_path(OBJECT(rtc));
+ qapi_event_send_rtc_change(qemu_timedate_diff(&tm), qom_path);
host_ns = qemu_clock_get_ns(rtc_clock);
diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c
index e61a0cced4..ac9a60c90e 100644
--- a/hw/rtc/mc146818rtc.c
+++ b/hw/rtc/mc146818rtc.c
@@ -40,7 +40,7 @@
#include "hw/rtc/mc146818rtc_regs.h"
#include "migration/vmstate.h"
#include "qapi/error.h"
-#include "qapi/qapi-events-misc-target.h"
+#include "qapi/qapi-events-misc.h"
#include "qapi/visitor.h"
#include "hw/rtc/mc146818rtc_regs.h"
@@ -611,12 +611,13 @@ static void rtc_get_time(RTCState *s, struct tm *tm)
static void rtc_set_time(RTCState *s)
{
struct tm tm;
+ g_autofree const char *qom_path = object_get_canonical_path(OBJECT(s));
rtc_get_time(s, &tm);
s->base_rtc = mktimegm(&tm);
s->last_update = qemu_clock_get_ns(rtc_clock);
- qapi_event_send_rtc_change(qemu_timedate_diff(&tm));
+ qapi_event_send_rtc_change(qemu_timedate_diff(&tm), qom_path);
}
static void rtc_set_cmos(RTCState *s, const struct tm *tm)
diff --git a/hw/rtc/meson.build b/hw/rtc/meson.build
index 8fd8d8f9a7..7cecdee5dd 100644
--- a/hw/rtc/meson.build
+++ b/hw/rtc/meson.build
@@ -2,7 +2,7 @@
softmmu_ss.add(when: 'CONFIG_DS1338', if_true: files('ds1338.c'))
softmmu_ss.add(when: 'CONFIG_M41T80', if_true: files('m41t80.c'))
softmmu_ss.add(when: 'CONFIG_M48T59', if_true: files('m48t59.c'))
-specific_ss.add(when: 'CONFIG_PL031', if_true: files('pl031.c'))
+softmmu_ss.add(when: 'CONFIG_PL031', if_true: files('pl031.c'))
softmmu_ss.add(when: 'CONFIG_TWL92230', if_true: files('twl92230.c'))
softmmu_ss.add(when: ['CONFIG_ISA_BUS', 'CONFIG_M48T59'], if_true: files('m48t59-isa.c'))
softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP', if_true: files('xlnx-zynqmp-rtc.c'))
diff --git a/hw/rtc/pl031.c b/hw/rtc/pl031.c
index 38d9d3c2f3..b01d0e75d1 100644
--- a/hw/rtc/pl031.c
+++ b/hw/rtc/pl031.c
@@ -24,7 +24,7 @@
#include "qemu/log.h"
#include "qemu/module.h"
#include "trace.h"
-#include "qapi/qapi-events-misc-target.h"
+#include "qapi/qapi-events-misc.h"
#define RTC_DR 0x00 /* Data read register */
#define RTC_MR 0x04 /* Match register */
@@ -138,12 +138,13 @@ static void pl031_write(void * opaque, hwaddr offset,
switch (offset) {
case RTC_LR: {
+ g_autofree const char *qom_path = object_get_canonical_path(opaque);
struct tm tm;
s->tick_offset += value - pl031_get_count(s);
qemu_get_timedate(&tm, s->tick_offset);
- qapi_event_send_rtc_change(qemu_timedate_diff(&tm));
+ qapi_event_send_rtc_change(qemu_timedate_diff(&tm), qom_path);
pl031_set_alarm(s);
break;
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index ff154eb84f..d899be17fd 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -259,6 +259,10 @@ static void aspeed_smc_flash_set_segment_region(AspeedSMCState *s, int cs,
memory_region_set_enabled(&fl->mmio, !!seg.size);
memory_region_transaction_commit();
+ if (asc->segment_addr_mask) {
+ regval &= asc->segment_addr_mask;
+ }
+
s->regs[R_SEG_ADDR0 + cs] = regval;
}
@@ -1364,6 +1368,7 @@ static void aspeed_2400_fmc_class_init(ObjectClass *klass, void *data)
asc->conf_enable_w0 = CONF_ENABLE_W0;
asc->max_peripherals = 5;
asc->segments = aspeed_2400_fmc_segments;
+ asc->segment_addr_mask = 0xffff0000;
asc->resets = aspeed_2400_fmc_resets;
asc->flash_window_base = 0x20000000;
asc->flash_window_size = 0x10000000;
@@ -1446,6 +1451,7 @@ static void aspeed_2500_fmc_class_init(ObjectClass *klass, void *data)
asc->conf_enable_w0 = CONF_ENABLE_W0;
asc->max_peripherals = 3;
asc->segments = aspeed_2500_fmc_segments;
+ asc->segment_addr_mask = 0xffff0000;
asc->resets = aspeed_2500_fmc_resets;
asc->flash_window_base = 0x20000000;
asc->flash_window_size = 0x10000000;
@@ -1483,6 +1489,7 @@ static void aspeed_2500_spi1_class_init(ObjectClass *klass, void *data)
asc->conf_enable_w0 = CONF_ENABLE_W0;
asc->max_peripherals = 2;
asc->segments = aspeed_2500_spi1_segments;
+ asc->segment_addr_mask = 0xffff0000;
asc->flash_window_base = 0x30000000;
asc->flash_window_size = 0x8000000;
asc->features = 0x0;
@@ -1517,6 +1524,7 @@ static void aspeed_2500_spi2_class_init(ObjectClass *klass, void *data)
asc->conf_enable_w0 = CONF_ENABLE_W0;
asc->max_peripherals = 2;
asc->segments = aspeed_2500_spi2_segments;
+ asc->segment_addr_mask = 0xffff0000;
asc->flash_window_base = 0x38000000;
asc->flash_window_size = 0x8000000;
asc->features = 0x0;
@@ -1598,6 +1606,7 @@ static void aspeed_2600_fmc_class_init(ObjectClass *klass, void *data)
asc->conf_enable_w0 = CONF_ENABLE_W0;
asc->max_peripherals = 3;
asc->segments = aspeed_2600_fmc_segments;
+ asc->segment_addr_mask = 0x0ff00ff0;
asc->resets = aspeed_2600_fmc_resets;
asc->flash_window_base = 0x20000000;
asc->flash_window_size = 0x10000000;
@@ -1636,6 +1645,7 @@ static void aspeed_2600_spi1_class_init(ObjectClass *klass, void *data)
asc->conf_enable_w0 = CONF_ENABLE_W0;
asc->max_peripherals = 2;
asc->segments = aspeed_2600_spi1_segments;
+ asc->segment_addr_mask = 0x0ff00ff0;
asc->flash_window_base = 0x30000000;
asc->flash_window_size = 0x10000000;
asc->features = ASPEED_SMC_FEATURE_DMA |
@@ -1674,6 +1684,7 @@ static void aspeed_2600_spi2_class_init(ObjectClass *klass, void *data)
asc->conf_enable_w0 = CONF_ENABLE_W0;
asc->max_peripherals = 3;
asc->segments = aspeed_2600_spi2_segments;
+ asc->segment_addr_mask = 0x0ff00ff0;
asc->flash_window_base = 0x50000000;
asc->flash_window_size = 0x10000000;
asc->features = ASPEED_SMC_FEATURE_DMA |
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index cae9906684..da043dcb45 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -24,6 +24,7 @@
#include "hw/misc/aspeed_i3c.h"
#include "hw/ssi/aspeed_smc.h"
#include "hw/misc/aspeed_hace.h"
+#include "hw/misc/aspeed_sbc.h"
#include "hw/watchdog/wdt_aspeed.h"
#include "hw/net/ftgmac100.h"
#include "target/arm/cpu.h"
@@ -60,6 +61,7 @@ struct AspeedSoCState {
AspeedSMCState fmc;
AspeedSMCState spi[ASPEED_SPIS_NUM];
EHCISysBusState ehci[ASPEED_EHCIS_NUM];
+ AspeedSBCState sbc;
AspeedSDMCState sdmc;
AspeedWDTState wdt[ASPEED_WDTS_NUM];
FTGMAC100State ftgmac100[ASPEED_MACS_NUM];
@@ -109,6 +111,7 @@ enum {
ASPEED_DEV_SDMC,
ASPEED_DEV_SCU,
ASPEED_DEV_ADC,
+ ASPEED_DEV_SBC,
ASPEED_DEV_VIDEO,
ASPEED_DEV_SRAM,
ASPEED_DEV_SDHCI,
diff --git a/include/hw/misc/aspeed_sbc.h b/include/hw/misc/aspeed_sbc.h
new file mode 100644
index 0000000000..651747e28f
--- /dev/null
+++ b/include/hw/misc/aspeed_sbc.h
@@ -0,0 +1,32 @@
+/*
+ * ASPEED Secure Boot Controller
+ *
+ * Copyright (C) 2021-2022 IBM Corp.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef ASPEED_SBC_H
+#define ASPEED_SBC_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_ASPEED_SBC "aspeed.sbc"
+#define TYPE_ASPEED_AST2600_SBC TYPE_ASPEED_SBC "-ast2600"
+OBJECT_DECLARE_TYPE(AspeedSBCState, AspeedSBCClass, ASPEED_SBC)
+
+#define ASPEED_SBC_NR_REGS (0x93c >> 2)
+
+struct AspeedSBCState {
+ SysBusDevice parent;
+
+ MemoryRegion iomem;
+
+ uint32_t regs[ASPEED_SBC_NR_REGS];
+};
+
+struct AspeedSBCClass {
+ SysBusDeviceClass parent_class;
+};
+
+#endif /* _ASPEED_SBC_H_ */
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
index e265555819..cad73ddc13 100644
--- a/include/hw/ssi/aspeed_smc.h
+++ b/include/hw/ssi/aspeed_smc.h
@@ -99,6 +99,7 @@ struct AspeedSMCClass {
uint8_t max_peripherals;
const uint32_t *resets;
const AspeedSegments *segments;
+ uint32_t segment_addr_mask;
hwaddr flash_window_base;
uint32_t flash_window_size;
uint32_t features;
diff --git a/qapi/compat.json b/qapi/compat.json
index c53b69fe3f..39b52872d5 100644
--- a/qapi/compat.json
+++ b/qapi/compat.json
@@ -41,7 +41,7 @@
#
# Limitation: covers only syntactic aspects of QMP, i.e. stuff tagged
# with feature 'deprecated'. We may want to extend it to cover
-# semantic aspects, CLI, and experimental features.
+# semantic aspects and CLI.
#
# Limitation: deprecated-output policy @hide is not implemented for
# enumeration values. They behave the same as with policy @accept.
diff --git a/qapi/migration.json b/qapi/migration.json
index 5975a0e104..18e2610e88 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1843,8 +1843,8 @@
# Since: 5.2
#
# Example:
-# {"command": "calc-dirty-rate", "data": {"calc-time": 1,
-# 'sample-pages': 512} }
+# {"command": "calc-dirty-rate", "arguments": {"calc-time": 1,
+# 'sample-pages': 512} }
#
##
{ 'command': 'calc-dirty-rate', 'data': {'calc-time': 'int64',
@@ -1888,7 +1888,7 @@
# Example:
#
# -> { "execute": "snapshot-save",
-# "data": {
+# "arguments": {
# "job-id": "snapsave0",
# "tag": "my-snap",
# "vmstate": "disk0",
@@ -1949,7 +1949,7 @@
# Example:
#
# -> { "execute": "snapshot-load",
-# "data": {
+# "arguments": {
# "job-id": "snapload0",
# "tag": "my-snap",
# "vmstate": "disk0",
@@ -2002,7 +2002,7 @@
# Example:
#
# -> { "execute": "snapshot-delete",
-# "data": {
+# "arguments": {
# "job-id": "snapdelete0",
# "tag": "my-snap",
# "devices": ["disk0", "disk1"]
diff --git a/qapi/misc-target.json b/qapi/misc-target.json
index 4bc45d2474..036c5e4a91 100644
--- a/qapi/misc-target.json
+++ b/qapi/misc-target.json
@@ -3,39 +3,6 @@
#
##
-# @RTC_CHANGE:
-#
-# Emitted when the guest changes the RTC time.
-#
-# @offset: offset between base RTC clock (as specified by -rtc base), and
-# new RTC clock value
-#
-# Note: This event is rate-limited.
-#
-# Since: 0.13
-#
-# Example:
-#
-# <- { "event": "RTC_CHANGE",
-# "data": { "offset": 78 },
-# "timestamp": { "seconds": 1267020223, "microseconds": 435656 } }
-#
-##
-{ 'event': 'RTC_CHANGE',
- 'data': { 'offset': 'int' },
- 'if': { 'any': [ 'TARGET_ALPHA',
- 'TARGET_ARM',
- 'TARGET_HPPA',
- 'TARGET_I386',
- 'TARGET_MIPS',
- 'TARGET_MIPS64',
- 'TARGET_PPC',
- 'TARGET_PPC64',
- 'TARGET_S390X',
- 'TARGET_SH4',
- 'TARGET_SPARC' ] } }
-
-##
# @rtc-reset-reinjection:
#
# This command will reset the RTC interrupt reinjection backlog.
diff --git a/qapi/misc.json b/qapi/misc.json
index e8054f415b..b83cc39029 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -527,3 +527,29 @@
'data': { '*option': 'str' },
'returns': ['CommandLineOptionInfo'],
'allow-preconfig': true }
+
+##
+# @RTC_CHANGE:
+#
+# Emitted when the guest changes the RTC time.
+#
+# @offset: offset in seconds between base RTC clock (as specified
+# by -rtc base), and new RTC clock value
+#
+# @qom-path: path to the RTC object in the QOM tree
+#
+# Note: This event is rate-limited.
+# It is not guaranteed that the RTC in the system implements
+# this event, or even that the system has an RTC at all.
+#
+# Since: 0.13
+#
+# Example:
+#
+# <- { "event": "RTC_CHANGE",
+# "data": { "offset": 78 },
+# "timestamp": { "seconds": 1267020223, "microseconds": 435656 } }
+#
+##
+{ 'event': 'RTC_CHANGE',
+ 'data': { 'offset': 'int', 'qom-path': 'str' } }
diff --git a/qapi/qapi-util.c b/qapi/qapi-util.c
index fda7044539..63596e11c5 100644
--- a/qapi/qapi-util.c
+++ b/qapi/qapi-util.c
@@ -113,7 +113,7 @@ bool qapi_bool_parse(const char *name, const char *value, bool *obj, Error **err
* may contain only letters, digits, hyphen and period.
* The special exception for enumeration names is not implemented.
* See docs/devel/qapi-code-gen.txt for more on QAPI naming rules.
- * Keep this consistent with scripts/qapi.py!
+ * Keep this consistent with scripts/qapi-gen.py!
* If @complete, the parse fails unless it consumes @str completely.
* Return its length on success, -1 on failure.
*/
diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py
index 869d799ed2..38ca38a7b9 100644
--- a/scripts/qapi/commands.py
+++ b/scripts/qapi/commands.py
@@ -25,8 +25,8 @@ from .gen import (
QAPIGenC,
QAPISchemaModularCVisitor,
build_params,
- ifcontext,
gen_special_features,
+ ifcontext,
)
from .schema import (
QAPISchema,
diff --git a/scripts/qapi/pylintrc b/scripts/qapi/pylintrc
index b259531a72..a724628203 100644
--- a/scripts/qapi/pylintrc
+++ b/scripts/qapi/pylintrc
@@ -34,16 +34,12 @@ disable=fixme,
[BASIC]
-# Good variable names which should always be accepted, separated by a comma.
-good-names=i,
- j,
- k,
- ex,
- Run,
- _,
- fp, # fp = open(...)
- fd, # fd = os.open(...)
- ch,
+# Good variable names regexes, separated by a comma. If names match any regex,
+# they will always be accepted.
+#
+# Suppress complaints about short names. PEP-8 is cool with them,
+# and so are we.
+good-names-rgxs=^[_a-z][_a-z0-9]?$
[VARIABLES]
diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py
index 3013329c24..477d027001 100644
--- a/scripts/qapi/types.py
+++ b/scripts/qapi/types.py
@@ -16,7 +16,11 @@ This work is licensed under the terms of the GNU GPL, version 2.
from typing import List, Optional
from .common import c_enum_const, c_name, mcgen
-from .gen import QAPISchemaModularCVisitor, gen_special_features, ifcontext
+from .gen import (
+ QAPISchemaModularCVisitor,
+ gen_special_features,
+ ifcontext,
+)
from .schema import (
QAPISchema,
QAPISchemaEnumMember,
diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py
index e13bbe4292..380fa197f5 100644
--- a/scripts/qapi/visit.py
+++ b/scripts/qapi/visit.py
@@ -21,7 +21,11 @@ from .common import (
indent,
mcgen,
)
-from .gen import QAPISchemaModularCVisitor, gen_special_features, ifcontext
+from .gen import (
+ QAPISchemaModularCVisitor,
+ gen_special_features,
+ ifcontext,
+)
from .schema import (
QAPISchema,
QAPISchemaEnumMember,
diff --git a/util/keyval.c b/util/keyval.c
index 904337c8a1..0cf2e84dc8 100644
--- a/util/keyval.c
+++ b/util/keyval.c
@@ -16,7 +16,9 @@
* key-vals = [ key-val { ',' key-val } [ ',' ] ]
* key-val = key '=' val | help
* key = key-fragment { '.' key-fragment }
- * key-fragment = / [^=,.]+ /
+ * key-fragment = qapi-name | index
+ * qapi-name = '__' / [a-z0-9.-]+ / '_' / [A-Za-z][A-Za-z0-9_-]* /
+ * index = / [0-9]+ /
* val = { / [^,]+ / | ',,' }
* help = 'help' | '?'
*