Merge tag 'pull-target-arm-20240215' of https://git.linaro.org/people/pmaydell/qemu-arm into staging

target-arm queue:
 * hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
 * linux-user/aarch64: Choose SYNC as the preferred MTE mode
 * Fix some errors in SVE/SME handling of MTE tags
 * hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
 * hw/block/tc58128: Don't emit deprecation warning under qtest
 * tests/qtest: Fix handling of npcm7xx and GMAC tests
 * hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
 * tests/qtest/npcm7xx_emc-test: Connect all NICs to a backend
 * Don't assert on vmload/vmsave of M-profile CPUs
 * hw/arm/smmuv3: add support for stage 1 access fault
 * hw/arm/stellaris: QOM cleanups
 * Use new CBAR encoding for all v8 CPUs, not all aarch64 CPUs
 * Improve Cortex_R52 IMPDEF sysreg modelling
 * Allow access to SPSR_hyp from hyp mode
 * New board model mps3-an536 (Cortex-R52)

# -----BEGIN PGP SIGNATURE-----
#
# iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmXOStQZHHBldGVyLm1h
# eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3vlDD/9HCq1B6e4hWQBlHrWG5nCK
# zBYRZ3GuuYCFB9FJt4EyXjUZ8ohDhLrpXvjhzSF6IqoPo0c0rQnfipeuj8Lu/hAV
# JrtHE4jQnE5Q9dwSz3A6oh0z5iIkFB/C1hW6fBDwvgAJUZ5xh5MBcxOvKq1s3WKv
# 3JngHC/KJrjgIKbcCV3Nd+OdyIZ7QZNXPwcBX9Zzt2eDkdEzOjcJYF4lisWdGav5
# JVXUeCXtClmFUZrxiGCLeTxb5X+TptxC+kAcPC7F5GjtVSy2800Z9sit2FTqd9Vd
# Y+rdA5IIBbZWPQ3OOHbaR69X4tWmc+BIT3nbQlESfV3odg0toQhe7aqn9UPIEU0K
# JRrzfodD7r7HK36lZm7ehmevLQnZgO6+MYL4Wrr0pUCNUxqVYlIyaqfsFSaknRg1
# 85L6agJlPYxtvrQtfhIV5m1V3IfyIiC7ECqMFe+QLdbR0ZxS3sI7sJ3O58xmcbDm
# SGVLl+xjAW3ZdgOb+k4B/BlPqasiJpuLe7So2e+cvDWN7OM0iJBxFAVz3yhJKGTP
# t9adJ1j0SI9XNrRuQkCX1T07Ciiuvr/mM4eY6YK+6TOq1zXks9st51ydbvEKdNW9
# YMFpWwUbYKKmUTEW06Xg5iNatse5kp4MUASF5BERkaGuyhRqLl/8p6jt6Q+9/D1S
# 5y8MFjUcdg8t4KcSJgdopw==
# =X+zR
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 15 Feb 2024 17:33:08 GMT
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate]
# gpg:                 aka "Peter Maydell <peter@archaic.org.uk>" [ultimate]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* tag 'pull-target-arm-20240215' of https://git.linaro.org/people/pmaydell/qemu-arm: (35 commits)
  docs: Add documentation for the mps3-an536 board
  hw/arm/mps3r: Add remaining devices
  hw/arm/mps3r: Add GPIO, watchdog, dual-timer, I2C devices
  hw/arm/mps3r: Add UARTs
  hw/arm/mps3r: Add CPUs, GIC, and per-CPU RAM
  hw/arm/mps3r: Initial skeleton for mps3-an536 board
  hw/misc/mps2-scc: Make changes needed for AN536 FPGA image
  hw/misc/mps2-scc: Factor out which-board conditionals
  hw/misc/mps2-scc: Fix condition for CFG3 register
  target/arm: Allow access to SPSR_hyp from hyp mode
  target/arm: Add Cortex-R52 IMPDEF sysregs
  target/arm: The Cortex-R52 has a read-only CBAR
  target/arm: Use new CBAR encoding for all v8 CPUs, not all aarch64 CPUs
  hw/arm/stellaris: Add missing QOM 'SoC' parent
  hw/arm/stellaris: Add missing QOM 'machine' parent
  hw/arm/stellaris: Convert I2C controller to Resettable interface
  hw/arm/stellaris: Convert ADC controller to Resettable interface
  hw/arm/smmuv3: add support for stage 1 access fault
  tests/qtest: Fix GMAC test to run on a machine in upstream QEMU
  target/arm: Don't get MDCR_EL2 in pmu_counter_enabled() before checking ARM_FEATURE_PMU
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2024-02-15 17:36:30 +00:00
36 changed files with 1184 additions and 222 deletions
+2 -1
View File
@@ -819,12 +819,13 @@ F: include/hw/misc/imx7_*.h
F: hw/pci-host/designware.c
F: include/hw/pci-host/designware.h
MPS2
MPS2 / MPS3
M: Peter Maydell <peter.maydell@linaro.org>
L: qemu-arm@nongnu.org
S: Maintained
F: hw/arm/mps2.c
F: hw/arm/mps2-tz.c
F: hw/arm/mps3r.c
F: hw/misc/mps2-*.c
F: include/hw/misc/mps2-*.h
F: hw/arm/armsse.c
+1
View File
@@ -13,6 +13,7 @@ CONFIG_ARM_VIRT=y
# CONFIG_INTEGRATOR=n
# CONFIG_FSL_IMX31=n
# CONFIG_MUSICPAL=n
# CONFIG_MPS3R=n
# CONFIG_MUSCA=n
# CONFIG_CHEETAH=n
# CONFIG_SX1=n
+34 -3
View File
@@ -1,7 +1,7 @@
Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an547``)
=========================================================================================================================================================
Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an536``, ``mps3-an547``)
=========================================================================================================================================================================
These board models all use Arm M-profile CPUs.
These board models use Arm M-profile or R-profile CPUs.
The Arm MPS2, MPS2+ and MPS3 dev boards are FPGA based (the 2+ has a
bigger FPGA but is otherwise the same as the 2; the 3 has a bigger
@@ -13,6 +13,8 @@ FPGA image.
QEMU models the following FPGA images:
FPGA images using M-profile CPUs:
``mps2-an385``
Cortex-M3 as documented in Arm Application Note AN385
``mps2-an386``
@@ -30,6 +32,11 @@ QEMU models the following FPGA images:
``mps3-an547``
Cortex-M55 on an MPS3, as documented in Arm Application Note AN547
FPGA images using R-profile CPUs:
``mps3-an536``
Dual Cortex-R52 on an MPS3, as documented in Arm Application Note AN536
Differences between QEMU and real hardware:
- AN385/AN386 remapping of low 16K of memory to either ZBT SSRAM1 or to
@@ -45,6 +52,30 @@ Differences between QEMU and real hardware:
flash, but only as simple ROM, so attempting to rewrite the flash
from the guest will fail
- QEMU does not model the USB controller in MPS3 boards
- AN536 does not support runtime control of CPU reset and halt via
the SCC CFG_REG0 register.
- AN536 does not support enabling or disabling the flash and ATCM
interfaces via the SCC CFG_REG1 register.
- AN536 does not support setting of the initial vector table
base address via the SCC CFG_REG6 and CFG_REG7 register config,
and does not provide a mechanism for specifying these values at
startup, so all guest images must be built to start from TCM
(i.e. to expect the interrupt vector base at 0 from reset).
- AN536 defaults to only creating a single CPU; this is the equivalent
of the way the real FPGA image usually runs with the second Cortex-R52
held in halt via the initial SCC CFG_REG0 register setting. You can
create the second CPU with ``-smp 2``; both CPUs will then start
execution immediately on startup.
Note that for the AN536 the first UART is accessible only by
CPU0, and the second UART is accessible only by CPU1. The
first UART accessible shared between both CPUs is the third
UART. Guest software might therefore be built to use either
the first UART or the third UART; if you don't see any output
from the UART you are looking at, try one of the others.
(Even if the AN536 machine is started with a single CPU and so
no "CPU1-only UART", the UART numbering remains the same,
with the third UART being the first of the shared ones.)
Machine-specific options
""""""""""""""""""""""""
+5
View File
@@ -106,6 +106,11 @@ config MAINSTONE
select PFLASH_CFI01
select SMC91C111
config MPS3R
bool
default y
depends on TCG && ARM
config MUSCA
bool
default y
+1
View File
@@ -8,6 +8,7 @@ arm_ss.add(when: 'CONFIG_HIGHBANK', if_true: files('highbank.c'))
arm_ss.add(when: 'CONFIG_INTEGRATOR', if_true: files('integratorcp.c'))
arm_ss.add(when: 'CONFIG_MAINSTONE', if_true: files('mainstone.c'))
arm_ss.add(when: 'CONFIG_MICROBIT', if_true: files('microbit.c'))
arm_ss.add(when: 'CONFIG_MPS3R', if_true: files('mps3r.c'))
arm_ss.add(when: 'CONFIG_MUSICPAL', if_true: files('musicpal.c'))
arm_ss.add(when: 'CONFIG_NETDUINOPLUS2', if_true: files('netduinoplus2.c'))
arm_ss.add(when: 'CONFIG_OLIMEX_STM32_H405', if_true: files('olimex-stm32-h405.c'))
+640
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -710,6 +710,7 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
for (i = 0; i < ARRAY_SIZE(s->gmac); i++) {
SysBusDevice *sbd = SYS_BUS_DEVICE(&s->gmac[i]);
qemu_configure_nic_device(DEVICE(sbd), false, NULL);
/*
* The device exists regardless of whether it's connected to a QEMU
* netdev backend. So always instantiate it even if there is no
+11
View File
@@ -364,6 +364,17 @@ static int smmu_ptw_64_s1(SMMUTransCfg *cfg,
pte_addr, pte, iova, gpa,
block_size >> 20);
}
/*
* QEMU does not currently implement HTTU, so if AFFD and PTE.AF
* are 0 we take an Access flag fault. (5.4. Context Descriptor)
* An Access flag fault takes priority over a Permission fault.
*/
if (!PTE_AF(pte) && !cfg->affd) {
info->type = SMMU_PTW_ERR_ACCESS;
goto error;
}
ap = PTE_AP(pte);
if (is_permission_fault(ap, perm)) {
info->type = SMMU_PTW_ERR_PERMISSION;
+1
View File
@@ -624,6 +624,7 @@ static inline int pa_range(STE *ste)
#define CD_EPD(x, sel) extract32((x)->word[0], (16 * (sel)) + 14, 1)
#define CD_ENDI(x) extract32((x)->word[0], 15, 1)
#define CD_IPS(x) extract32((x)->word[1], 0 , 3)
#define CD_AFFD(x) extract32((x)->word[1], 3 , 1)
#define CD_TBI(x) extract32((x)->word[1], 6 , 2)
#define CD_HD(x) extract32((x)->word[1], 10 , 1)
#define CD_HA(x) extract32((x)->word[1], 11 , 1)
+1
View File
@@ -684,6 +684,7 @@ static int decode_cd(SMMUTransCfg *cfg, CD *cd, SMMUEventInfo *event)
cfg->oas = MIN(oas2bits(SMMU_IDR5_OAS), cfg->oas);
cfg->tbi = CD_TBI(cd);
cfg->asid = CD_ASID(cd);
cfg->affd = CD_AFFD(cd);
trace_smmuv3_decode_cd(cfg->oas);
+40 -7
View File
@@ -462,7 +462,10 @@ static void stellaris_sys_instance_init(Object *obj)
s->sysclk = qdev_init_clock_out(DEVICE(s), "SYSCLK");
}
/* I2C controller. */
/*
* I2C controller.
* ??? For now we only implement the master interface.
*/
#define TYPE_STELLARIS_I2C "stellaris-i2c"
OBJECT_DECLARE_SIMPLE_TYPE(stellaris_i2c_state, STELLARIS_I2C)
@@ -607,10 +610,17 @@ static void stellaris_i2c_write(void *opaque, hwaddr offset,
stellaris_i2c_update(s);
}
static void stellaris_i2c_reset(stellaris_i2c_state *s)
static void stellaris_i2c_reset_enter(Object *obj, ResetType type)
{
stellaris_i2c_state *s = STELLARIS_I2C(obj);
if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
i2c_end_transfer(s->bus);
}
static void stellaris_i2c_reset_hold(Object *obj)
{
stellaris_i2c_state *s = STELLARIS_I2C(obj);
s->msa = 0;
s->mcs = 0;
@@ -619,6 +629,12 @@ static void stellaris_i2c_reset(stellaris_i2c_state *s)
s->mimr = 0;
s->mris = 0;
s->mcr = 0;
}
static void stellaris_i2c_reset_exit(Object *obj)
{
stellaris_i2c_state *s = STELLARIS_I2C(obj);
stellaris_i2c_update(s);
}
@@ -658,8 +674,6 @@ static void stellaris_i2c_init(Object *obj)
memory_region_init_io(&s->iomem, obj, &stellaris_i2c_ops, s,
"i2c", 0x1000);
sysbus_init_mmio(sbd, &s->iomem);
/* ??? For now we only implement the master interface. */
stellaris_i2c_reset(s);
}
/* Analogue to Digital Converter. This is only partially implemented,
@@ -773,8 +787,9 @@ static void stellaris_adc_trigger(void *opaque, int irq, int level)
}
}
static void stellaris_adc_reset(StellarisADCState *s)
static void stellaris_adc_reset_hold(Object *obj)
{
StellarisADCState *s = STELLARIS_ADC(obj);
int n;
for (n = 0; n < 4; n++) {
@@ -946,7 +961,6 @@ static void stellaris_adc_init(Object *obj)
memory_region_init_io(&s->iomem, obj, &stellaris_adc_ops, s,
"adc", 0x1000);
sysbus_init_mmio(sbd, &s->iomem);
stellaris_adc_reset(s);
qdev_init_gpio_in(dev, stellaris_adc_trigger, 1);
}
@@ -1017,6 +1031,7 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
* 400fe000 system control
*/
Object *soc_container;
DeviceState *gpio_dev[7], *nvic;
qemu_irq gpio_in[7][8];
qemu_irq gpio_out[7][8];
@@ -1038,6 +1053,9 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
flash_size = (((board->dc0 & 0xffff) + 1) << 1) * 1024;
sram_size = ((board->dc0 >> 18) + 1) * 1024;
soc_container = object_new("container");
object_property_add_child(OBJECT(ms), "soc", soc_container);
/* Flash programming is done via the SCU, so pretend it is ROM. */
memory_region_init_rom(flash, NULL, "stellaris.flash", flash_size,
&error_fatal);
@@ -1052,6 +1070,7 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
* need its sysclk output.
*/
ssys_dev = qdev_new(TYPE_STELLARIS_SYS);
object_property_add_child(soc_container, "sys", OBJECT(ssys_dev));
/*
* Most devices come preprogrammed with a MAC address in the user data.
@@ -1078,6 +1097,7 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
sysbus_realize_and_unref(SYS_BUS_DEVICE(ssys_dev), &error_fatal);
nvic = qdev_new(TYPE_ARMV7M);
object_property_add_child(soc_container, "v7m", OBJECT(nvic));
qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES);
qdev_prop_set_uint8(nvic, "num-prio-bits", NUM_PRIO_BITS);
qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type);
@@ -1111,6 +1131,7 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
dev = qdev_new(TYPE_STELLARIS_GPTM);
sbd = SYS_BUS_DEVICE(dev);
object_property_add_child(soc_container, "gptm[*]", OBJECT(dev));
qdev_connect_clock_in(dev, "clk",
qdev_get_clock_out(ssys_dev, "SYSCLK"));
sysbus_realize_and_unref(sbd, &error_fatal);
@@ -1124,7 +1145,7 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
if (board->dc1 & (1 << 3)) { /* watchdog present */
dev = qdev_new(TYPE_LUMINARY_WATCHDOG);
object_property_add_child(soc_container, "wdg", OBJECT(dev));
qdev_connect_clock_in(dev, "WDOGCLK",
qdev_get_clock_out(ssys_dev, "SYSCLK"));
@@ -1164,6 +1185,7 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
SysBusDevice *sbd;
dev = qdev_new("pl011_luminary");
object_property_add_child(soc_container, "uart[*]", OBJECT(dev));
sbd = SYS_BUS_DEVICE(dev);
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
sysbus_realize_and_unref(sbd, &error_fatal);
@@ -1257,10 +1279,13 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
&error_fatal);
ssddev = qdev_new("ssd0323");
object_property_add_child(OBJECT(ms), "oled", OBJECT(ssddev));
qdev_prop_set_uint8(ssddev, "cs", 1);
qdev_realize_and_unref(ssddev, bus, &error_fatal);
gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
object_property_add_child(OBJECT(ms), "splitter",
OBJECT(gpio_d_splitter));
qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
qdev_realize_and_unref(gpio_d_splitter, NULL, &error_fatal);
qdev_connect_gpio_out(
@@ -1281,6 +1306,7 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
DeviceState *enet;
enet = qdev_new("stellaris_enet");
object_property_add_child(soc_container, "enet", OBJECT(enet));
if (nd) {
qdev_set_nic_properties(enet, nd);
} else {
@@ -1300,6 +1326,7 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
DeviceState *gpad;
gpad = qdev_new(TYPE_STELLARIS_GAMEPAD);
object_property_add_child(OBJECT(ms), "gamepad", OBJECT(gpad));
for (i = 0; i < ARRAY_SIZE(gpad_keycode); i++) {
qlist_append_int(gpad_keycode_list, gpad_keycode[i]);
}
@@ -1396,7 +1423,11 @@ type_init(stellaris_machine_init)
static void stellaris_i2c_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
ResettableClass *rc = RESETTABLE_CLASS(klass);
rc->phases.enter = stellaris_i2c_reset_enter;
rc->phases.hold = stellaris_i2c_reset_hold;
rc->phases.exit = stellaris_i2c_reset_exit;
dc->vmsd = &vmstate_stellaris_i2c;
}
@@ -1411,7 +1442,9 @@ static const TypeInfo stellaris_i2c_info = {
static void stellaris_adc_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
ResettableClass *rc = RESETTABLE_CLASS(klass);
rc->phases.hold = stellaris_adc_reset_hold;
dc->vmsd = &vmstate_stellaris_adc;
}
+14 -6
View File
@@ -533,8 +533,8 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
}
/*
* ACPI spec, Revision 5.1
* 5.2.24 Generic Timer Description Table (GTDT)
* ACPI spec, Revision 6.5
* 5.2.25 Generic Timer Description Table (GTDT)
*/
static void
build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
@@ -548,7 +548,7 @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
uint32_t irqflags = vmc->claim_edge_triggered_timers ?
1 : /* Interrupt is Edge triggered */
0; /* Interrupt is Level triggered */
AcpiTable table = { .sig = "GTDT", .rev = 2, .oem_id = vms->oem_id,
AcpiTable table = { .sig = "GTDT", .rev = 3, .oem_id = vms->oem_id,
.oem_table_id = vms->oem_table_id };
acpi_table_begin(&table, table_data);
@@ -584,7 +584,15 @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
build_append_int_noprefix(table_data, 0, 4);
/* Platform Timer Offset */
build_append_int_noprefix(table_data, 0, 4);
if (vms->ns_el2_virt_timer_irq) {
/* Virtual EL2 Timer GSIV */
build_append_int_noprefix(table_data, ARCH_TIMER_NS_EL2_VIRT_IRQ, 4);
/* Virtual EL2 Timer Flags */
build_append_int_noprefix(table_data, irqflags, 4);
} else {
build_append_int_noprefix(table_data, 0, 4);
build_append_int_noprefix(table_data, 0, 4);
}
acpi_table_end(linker, &table);
}
@@ -771,10 +779,10 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
static void build_fadt_rev6(GArray *table_data, BIOSLinker *linker,
VirtMachineState *vms, unsigned dsdt_tbl_offset)
{
/* ACPI v6.0 */
/* ACPI v6.3 */
AcpiFadtData fadt = {
.rev = 6,
.minor_ver = 0,
.minor_ver = 3,
.flags = 1 << ACPI_FADT_F_HW_REDUCED_ACPI,
.xdsdt_tbl_offset = &dsdt_tbl_offset,
};
+51 -9
View File
@@ -221,6 +221,20 @@ static void create_randomness(MachineState *ms, const char *node)
qemu_fdt_setprop(ms->fdt, node, "rng-seed", seed.rng, sizeof(seed.rng));
}
/*
* The CPU object always exposes the NS EL2 virt timer IRQ line,
* but we don't want to advertise it to the guest in the dtb or ACPI
* table unless it's really going to do something.
*/
static bool ns_el2_virt_timer_present(void)
{
ARMCPU *cpu = ARM_CPU(qemu_get_cpu(0));
CPUARMState *env = &cpu->env;
return arm_feature(env, ARM_FEATURE_AARCH64) &&
arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu);
}
static void create_fdt(VirtMachineState *vms)
{
MachineState *ms = MACHINE(vms);
@@ -338,15 +352,29 @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
"arm,armv7-timer");
}
qemu_fdt_setprop(ms->fdt, "/timer", "always-on", NULL, 0);
qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
GIC_FDT_IRQ_TYPE_PPI,
INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
GIC_FDT_IRQ_TYPE_PPI,
INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
GIC_FDT_IRQ_TYPE_PPI,
INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
GIC_FDT_IRQ_TYPE_PPI,
INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
if (vms->ns_el2_virt_timer_irq) {
qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
GIC_FDT_IRQ_TYPE_PPI,
INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
GIC_FDT_IRQ_TYPE_PPI,
INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
GIC_FDT_IRQ_TYPE_PPI,
INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
GIC_FDT_IRQ_TYPE_PPI,
INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags,
GIC_FDT_IRQ_TYPE_PPI,
INTID_TO_PPI(ARCH_TIMER_NS_EL2_VIRT_IRQ), irqflags);
} else {
qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
GIC_FDT_IRQ_TYPE_PPI,
INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
GIC_FDT_IRQ_TYPE_PPI,
INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
GIC_FDT_IRQ_TYPE_PPI,
INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
GIC_FDT_IRQ_TYPE_PPI,
INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
}
}
static void fdt_add_cpu_nodes(const VirtMachineState *vms)
@@ -789,6 +817,7 @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
[GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
[GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
[GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
[GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
};
for (unsigned irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
@@ -2222,6 +2251,11 @@ static void machvirt_init(MachineState *machine)
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
object_unref(cpuobj);
}
/* Now we've created the CPUs we can see if they have the hypvirt timer */
vms->ns_el2_virt_timer_irq = ns_el2_virt_timer_present() &&
!vmc->no_ns_el2_virt_timer_irq;
fdt_add_timer_nodes(vms);
fdt_add_cpu_nodes(vms);
@@ -3179,8 +3213,16 @@ DEFINE_VIRT_MACHINE_AS_LATEST(9, 0)
static void virt_machine_8_2_options(MachineClass *mc)
{
VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
virt_machine_9_0_options(mc);
compat_props_add(mc->compat_props, hw_compat_8_2, hw_compat_8_2_len);
/*
* Don't expose NS_EL2_VIRT timer IRQ in DTB on ACPI on 8.2 and
* earlier machines. (Exposing it tickles a bug in older EDK2
* guest BIOS binaries.)
*/
vmc->no_ns_el2_virt_timer_irq = true;
}
DEFINE_VIRT_MACHINE(8, 2)
+2
View File
@@ -243,6 +243,8 @@ static void zynq_init(MachineState *machine)
sysbus_mmio_map(busdev, 0, MPCORE_PERIPHBASE);
sysbus_connect_irq(busdev, 0,
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
sysbus_connect_irq(busdev, 1,
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ));
for (n = 0; n < 64; n++) {
pic[n] = qdev_get_gpio_in(dev, n);
+3 -1
View File
@@ -202,7 +202,9 @@ static sh7750_io_device tc58128 = {
int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2)
{
warn_report_once("The TC58128 flash device is deprecated");
if (!qtest_enabled()) {
warn_report_once("The TC58128 flash device is deprecated");
}
init_dev(&tc58128_devs[0], zone1);
init_dev(&tc58128_devs[1], zone2);
return sh7750_register_io_device(s, &tc58128);
+118 -20
View File
@@ -37,6 +37,7 @@ REG32(CFG3, 0xc)
REG32(CFG4, 0x10)
REG32(CFG5, 0x14)
REG32(CFG6, 0x18)
REG32(CFG7, 0x1c)
REG32(CFGDATA_RTN, 0xa0)
REG32(CFGDATA_OUT, 0xa4)
REG32(CFGCTRL, 0xa8)
@@ -59,6 +60,51 @@ static int scc_partno(MPS2SCC *s)
return extract32(s->id, 4, 8);
}
/* Is CFG_REG2 present? */
static bool have_cfg2(MPS2SCC *s)
{
return scc_partno(s) == 0x524 || scc_partno(s) == 0x547 ||
scc_partno(s) == 0x536;
}
/* Is CFG_REG3 present? */
static bool have_cfg3(MPS2SCC *s)
{
return scc_partno(s) != 0x524 && scc_partno(s) != 0x547 &&
scc_partno(s) != 0x536;
}
/* Is CFG_REG5 present? */
static bool have_cfg5(MPS2SCC *s)
{
return scc_partno(s) == 0x524 || scc_partno(s) == 0x547 ||
scc_partno(s) == 0x536;
}
/* Is CFG_REG6 present? */
static bool have_cfg6(MPS2SCC *s)
{
return scc_partno(s) == 0x524 || scc_partno(s) == 0x536;
}
/* Is CFG_REG7 present? */
static bool have_cfg7(MPS2SCC *s)
{
return scc_partno(s) == 0x536;
}
/* Does CFG_REG0 drive the 'remap' GPIO output? */
static bool cfg0_is_remap(MPS2SCC *s)
{
return scc_partno(s) != 0x536;
}
/* Is CFG_REG1 driving a set of LEDs? */
static bool cfg1_is_leds(MPS2SCC *s)
{
return scc_partno(s) != 0x536;
}
/* Handle a write via the SYS_CFG channel to the specified function/device.
* Return false on error (reported to guest via SYS_CFGCTRL ERROR bit).
*/
@@ -111,19 +157,25 @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
r = s->cfg1;
break;
case A_CFG2:
if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
/* CFG2 reserved on other boards */
if (!have_cfg2(s)) {
goto bad_offset;
}
r = s->cfg2;
break;
case A_CFG3:
if (scc_partno(s) == 0x524 && scc_partno(s) == 0x547) {
/* CFG3 reserved on AN524 */
if (!have_cfg3(s)) {
goto bad_offset;
}
/* These are user-settable DIP switches on the board. We don't
/*
* These are user-settable DIP switches on the board. We don't
* model that, so just return zeroes.
*
* TODO: for AN536 this is MCC_MSB_ADDR "additional MCC addressing
* bits". These change which part of the DDR4 the motherboard
* configuration controller can see in its memory map (see the
* appnote section 2.4). QEMU doesn't model the MCC at all, so these
* bits are not interesting to us; read-as-zero is as good as anything
* else.
*/
r = 0;
break;
@@ -131,19 +183,23 @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
r = s->cfg4;
break;
case A_CFG5:
if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
/* CFG5 reserved on other boards */
if (!have_cfg5(s)) {
goto bad_offset;
}
r = s->cfg5;
break;
case A_CFG6:
if (scc_partno(s) != 0x524) {
/* CFG6 reserved on other boards */
if (!have_cfg6(s)) {
goto bad_offset;
}
r = s->cfg6;
break;
case A_CFG7:
if (!have_cfg7(s)) {
goto bad_offset;
}
r = s->cfg7;
break;
case A_CFGDATA_RTN:
r = s->cfgdata_rtn;
break;
@@ -191,38 +247,58 @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
* we always reflect bit 0 in the 'remap' GPIO output line,
* and let the board wire it up or not as it chooses.
* TODO on some boards bit 1 is CPU_WAIT.
*
* TODO: on the AN536 this register controls reset and halt
* for both CPUs. For the moment we don't implement this, so the
* register just reads as written.
*/
s->cfg0 = value;
qemu_set_irq(s->remap, s->cfg0 & 1);
if (cfg0_is_remap(s)) {
qemu_set_irq(s->remap, s->cfg0 & 1);
}
break;
case A_CFG1:
s->cfg1 = value;
for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
led_set_state(s->led[i], extract32(value, i, 1));
/*
* On most boards this register drives LEDs.
*
* TODO: for AN536 this controls whether flash and ATCM are
* enabled or disabled on reset. QEMU doesn't model this, and
* always wires up RAM in the ATCM area and ROM in the flash area.
*/
if (cfg1_is_leds(s)) {
for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
led_set_state(s->led[i], extract32(value, i, 1));
}
}
break;
case A_CFG2:
if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
/* CFG2 reserved on other boards */
if (!have_cfg2(s)) {
goto bad_offset;
}
/* AN524: QSPI Select signal */
/* AN524, AN536: QSPI Select signal */
s->cfg2 = value;
break;
case A_CFG5:
if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
/* CFG5 reserved on other boards */
if (!have_cfg5(s)) {
goto bad_offset;
}
/* AN524: ACLK frequency in Hz */
/* AN524, AN536: ACLK frequency in Hz */
s->cfg5 = value;
break;
case A_CFG6:
if (scc_partno(s) != 0x524) {
/* CFG6 reserved on other boards */
if (!have_cfg6(s)) {
goto bad_offset;
}
/* AN524: Clock divider for BRAM */
/* AN536: Core 0 vector table base address */
s->cfg6 = value;
break;
case A_CFG7:
if (!have_cfg7(s)) {
goto bad_offset;
}
/* AN536: Core 1 vector table base address */
s->cfg6 = value;
break;
case A_CFGDATA_OUT:
@@ -336,6 +412,24 @@ static void mps2_scc_finalize(Object *obj)
g_free(s->oscclk_reset);
}
static bool cfg7_needed(void *opaque)
{
MPS2SCC *s = opaque;
return have_cfg7(s);
}
static const VMStateDescription vmstate_cfg7 = {
.name = "mps2-scc/cfg7",
.version_id = 1,
.minimum_version_id = 1,
.needed = cfg7_needed,
.fields = (const VMStateField[]) {
VMSTATE_UINT32(cfg7, MPS2SCC),
VMSTATE_END_OF_LIST()
}
};
static const VMStateDescription mps2_scc_vmstate = {
.name = "mps2-scc",
.version_id = 3,
@@ -355,6 +449,10 @@ static const VMStateDescription mps2_scc_vmstate = {
VMSTATE_VARRAY_UINT32(oscclk, MPS2SCC, num_oscclk,
0, vmstate_info_uint32, uint32_t),
VMSTATE_END_OF_LIST()
},
.subsections = (const VMStateDescription * const []) {
&vmstate_cfg7,
NULL
}
};
+1
View File
@@ -200,6 +200,7 @@ static const MemoryRegionOps raven_io_ops = {
.write = raven_io_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.impl.max_access_size = 4,
.impl.unaligned = true,
.valid.unaligned = true,
};
+1
View File
@@ -92,6 +92,7 @@ typedef struct SMMUTransCfg {
bool disabled; /* smmu is disabled */
bool bypassed; /* translation is bypassed */
bool aborted; /* translation is aborted */
bool affd; /* AF fault disable */
uint32_t iotlb_hits; /* counts IOTLB hits */
uint32_t iotlb_misses; /* counts IOTLB misses*/
/* Used by stage-1 only. */
+2
View File
@@ -130,6 +130,7 @@ struct VirtMachineClass {
/* Machines < 6.2 have no support for describing cpu topology to guest */
bool no_cpu_topology;
bool no_tcg_lpa2;
bool no_ns_el2_virt_timer_irq;
};
struct VirtMachineState {
@@ -173,6 +174,7 @@ struct VirtMachineState {
PCIBus *bus;
char *oem_id;
char *oem_table_id;
bool ns_el2_virt_timer_irq;
};
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
+1
View File
@@ -51,6 +51,7 @@ struct MPS2SCC {
uint32_t cfg4;
uint32_t cfg5;
uint32_t cfg6;
uint32_t cfg7;
uint32_t cfgdata_rtn;
uint32_t cfgdata_out;
uint32_t cfgctrl;

Some files were not shown because too many files have changed in this diff Show More