1
The following changes since commit 5767815218efd3cbfd409505ed824d5f356044ae:
1
Hi; here's a target-arm pullreq to go in before softfreeze.
2
This is actually pretty much entirely bugfixes (since the
3
SEL2 timers we implement here are a missing part of a feature
4
we claim to already implement).
2
5
3
Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging (2024-02-14 15:45:52 +0000)
6
thanks
7
-- PMM
8
9
The following changes since commit 98c7362b1efe651327385a25874a73e008c6549e:
10
11
Merge tag 'accel-cpus-20250306' of https://github.com/philmd/qemu into staging (2025-03-07 07:39:49 +0800)
4
12
5
are available in the Git repository at:
13
are available in the Git repository at:
6
14
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240215
15
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20250307
8
16
9
for you to fetch changes up to f780e63fe731b058fe52d43653600d8729a1b5f2:
17
for you to fetch changes up to 0ce0739d46983e5e88fa9c149cb305689c9d8c6f:
10
18
11
docs: Add documentation for the mps3-an536 board (2024-02-15 14:32:39 +0000)
19
target/rx: Remove TCG_CALL_NO_WG from helpers which write env (2025-03-07 15:03:20 +0000)
12
20
13
----------------------------------------------------------------
21
----------------------------------------------------------------
14
target-arm queue:
22
target-arm queue:
15
* hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
23
* hw/arm/smmu-common: Remove the repeated ttb field
16
* linux-user/aarch64: Choose SYNC as the preferred MTE mode
24
* hw/gpio: npcm7xx: fixup out-of-bounds access
17
* Fix some errors in SVE/SME handling of MTE tags
25
* tests/functional/test_arm_sx1: Check whether the serial console is working
18
* hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
26
* target/arm: Fix minor bugs in generic timer register handling
19
* hw/block/tc58128: Don't emit deprecation warning under qtest
27
* target/arm: Implement SEL2 physical and virtual timers
20
* tests/qtest: Fix handling of npcm7xx and GMAC tests
28
* target/arm: Correct STRD, LDRD atomicity and fault behaviour
21
* hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
29
* target/arm: Make dummy debug registers RAZ, not NOP
22
* tests/qtest/npcm7xx_emc-test: Connect all NICs to a backend
30
* util/qemu-timer.c: Don't warp timer from timerlist_rearm()
23
* Don't assert on vmload/vmsave of M-profile CPUs
31
* include/exec/memop.h: Expand comment for MO_ATOM_SUBALIGN
24
* hw/arm/smmuv3: add support for stage 1 access fault
32
* hw/arm/smmu: Introduce smmu_configs_inv_sid_range() helper
25
* hw/arm/stellaris: QOM cleanups
33
* target/rx: Set exception vector base to 0xffffff80
26
* Use new CBAR encoding for all v8 CPUs, not all aarch64 CPUs
34
* target/rx: Remove TCG_CALL_NO_WG from helpers which write env
27
* Improve Cortex_R52 IMPDEF sysreg modelling
28
* Allow access to SPSR_hyp from hyp mode
29
* New board model mps3-an536 (Cortex-R52)
30
35
31
----------------------------------------------------------------
36
----------------------------------------------------------------
32
Luc Michel (1):
37
Alex Bennée (4):
33
hw/arm/smmuv3: add support for stage 1 access fault
38
target/arm: Implement SEL2 physical and virtual timers
39
target/arm: Document the architectural names of our GTIMERs
40
hw/arm: enable secure EL2 timers for virt machine
41
hw/arm: enable secure EL2 timers for sbsa machine
34
42
35
Nabih Estefan (1):
43
JianChunfu (2):
36
tests/qtest: Fix GMAC test to run on a machine in upstream QEMU
44
hw/arm/smmu-common: Remove the repeated ttb field
45
hw/arm/smmu: Introduce smmu_configs_inv_sid_range() helper
37
46
38
Peter Maydell (22):
47
Keith Packard (2):
39
hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
48
target/rx: Set exception vector base to 0xffffff80
40
hw/block/tc58128: Don't emit deprecation warning under qtest
49
target/rx: Remove TCG_CALL_NO_WG from helpers which write env
41
tests/qtest/meson.build: Don't include qtests_npcm7xx in qtests_aarch64
42
tests/qtest/bios-tables-test: Allow changes to virt GTDT
43
hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
44
tests/qtest/bios-tables-tests: Update virt golden reference
45
hw/arm/npcm7xx: Call qemu_configure_nic_device() for GMAC modules
46
tests/qtest/npcm7xx_emc-test: Connect all NICs to a backend
47
target/arm: Don't get MDCR_EL2 in pmu_counter_enabled() before checking ARM_FEATURE_PMU
48
target/arm: Use new CBAR encoding for all v8 CPUs, not all aarch64 CPUs
49
target/arm: The Cortex-R52 has a read-only CBAR
50
target/arm: Add Cortex-R52 IMPDEF sysregs
51
target/arm: Allow access to SPSR_hyp from hyp mode
52
hw/misc/mps2-scc: Fix condition for CFG3 register
53
hw/misc/mps2-scc: Factor out which-board conditionals
54
hw/misc/mps2-scc: Make changes needed for AN536 FPGA image
55
hw/arm/mps3r: Initial skeleton for mps3-an536 board
56
hw/arm/mps3r: Add CPUs, GIC, and per-CPU RAM
57
hw/arm/mps3r: Add UARTs
58
hw/arm/mps3r: Add GPIO, watchdog, dual-timer, I2C devices
59
hw/arm/mps3r: Add remaining devices
60
docs: Add documentation for the mps3-an536 board
61
50
62
Philippe Mathieu-Daudé (5):
51
Patrick Venture (1):
63
hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
52
hw/gpio: npcm7xx: fixup out-of-bounds access
64
hw/arm/stellaris: Convert ADC controller to Resettable interface
65
hw/arm/stellaris: Convert I2C controller to Resettable interface
66
hw/arm/stellaris: Add missing QOM 'machine' parent
67
hw/arm/stellaris: Add missing QOM 'SoC' parent
68
53
69
Richard Henderson (6):
54
Peter Maydell (11):
70
linux-user/aarch64: Choose SYNC as the preferred MTE mode
55
target/arm: Apply correct timer offset when calculating deadlines
71
target/arm: Fix nregs computation in do_{ld,st}_zpa
56
target/arm: Don't apply CNTVOFF_EL2 for EL2_VIRT timer
72
target/arm: Adjust and validate mtedesc sizem1
57
target/arm: Make CNTPS_* UNDEF from Secure EL1 when Secure EL2 is enabled
73
target/arm: Split out make_svemte_desc
58
target/arm: Always apply CNTVOFF_EL2 for CNTV_TVAL_EL02 accesses
74
target/arm: Handle mte in do_ldrq, do_ldro
59
target/arm: Refactor handling of timer offset for direct register accesses
75
target/arm: Fix SVE/SME gross MTE suppression checks
60
target/arm: Correct LDRD atomicity and fault behaviour
61
target/arm: Correct STRD atomicity
62
target/arm: Drop unused address_offset from op_addr_{rr, ri}_post()
63
target/arm: Make dummy debug registers RAZ, not NOP
64
util/qemu-timer.c: Don't warp timer from timerlist_rearm()
65
include/exec/memop.h: Expand comment for MO_ATOM_SUBALIGN
76
66
77
MAINTAINERS | 3 +-
67
Thomas Huth (1):
78
docs/system/arm/mps2.rst | 37 +-
68
tests/functional/test_arm_sx1: Check whether the serial console is working
79
configs/devices/arm-softmmu/default.mak | 1 +
80
hw/arm/smmuv3-internal.h | 1 +
81
include/hw/arm/smmu-common.h | 1 +
82
include/hw/arm/virt.h | 2 +
83
include/hw/misc/mps2-scc.h | 1 +
84
linux-user/aarch64/target_prctl.h | 29 +-
85
target/arm/internals.h | 2 +-
86
target/arm/tcg/translate-a64.h | 2 +
87
hw/arm/mps3r.c | 640 ++++++++++++++++++++++++++++++++
88
hw/arm/npcm7xx.c | 1 +
89
hw/arm/smmu-common.c | 11 +
90
hw/arm/smmuv3.c | 1 +
91
hw/arm/stellaris.c | 47 ++-
92
hw/arm/virt-acpi-build.c | 20 +-
93
hw/arm/virt.c | 60 ++-
94
hw/arm/xilinx_zynq.c | 2 +
95
hw/block/tc58128.c | 4 +-
96
hw/misc/mps2-scc.c | 138 ++++++-
97
hw/pci-host/raven.c | 1 +
98
target/arm/helper.c | 14 +-
99
target/arm/tcg/cpu32.c | 109 ++++++
100
target/arm/tcg/op_helper.c | 43 ++-
101
target/arm/tcg/sme_helper.c | 8 +-
102
target/arm/tcg/sve_helper.c | 12 +-
103
target/arm/tcg/translate-sme.c | 15 +-
104
target/arm/tcg/translate-sve.c | 83 +++--
105
target/arm/tcg/translate.c | 19 +-
106
tests/qtest/npcm7xx_emc-test.c | 5 +-
107
tests/qtest/npcm_gmac-test.c | 84 +----
108
hw/arm/Kconfig | 5 +
109
hw/arm/meson.build | 1 +
110
tests/data/acpi/virt/FACP | Bin 276 -> 276 bytes
111
tests/data/acpi/virt/GTDT | Bin 96 -> 104 bytes
112
tests/qtest/meson.build | 4 +-
113
36 files changed, 1184 insertions(+), 222 deletions(-)
114
create mode 100644 hw/arm/mps3r.c
115
69
70
MAINTAINERS | 1 +
71
hw/arm/smmu-internal.h | 5 -
72
include/exec/memop.h | 8 +-
73
include/hw/arm/bsa.h | 2 +
74
include/hw/arm/smmu-common.h | 7 +-
75
target/arm/cpu.h | 2 +
76
target/arm/gtimer.h | 14 +-
77
target/arm/internals.h | 5 +-
78
target/rx/helper.h | 34 ++--
79
hw/arm/sbsa-ref.c | 2 +
80
hw/arm/smmu-common.c | 21 +++
81
hw/arm/smmuv3.c | 19 +--
82
hw/arm/virt.c | 2 +
83
hw/gpio/npcm7xx_gpio.c | 3 +-
84
target/arm/cpu.c | 4 +
85
target/arm/debug_helper.c | 7 +-
86
target/arm/helper.c | 324 ++++++++++++++++++++++++++++++++-------
87
target/arm/tcg/op_helper.c | 8 +-
88
target/arm/tcg/translate.c | 147 +++++++++++-------
89
target/rx/helper.c | 2 +-
90
util/qemu-timer.c | 4 -
91
hw/arm/trace-events | 3 +-
92
tests/functional/test_arm_sx1.py | 7 +-
93
23 files changed, 455 insertions(+), 176 deletions(-)
94
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: JianChunfu <jansef.jian@hj-micro.com>
2
2
3
QDev objects created with qdev_new() need to manually add
3
SMMUTransCfg->ttb is never used in QEMU, TT base address
4
their parent relationship with object_property_add_child().
4
can be accessed by SMMUTransCfg->tt[i]->ttb.
5
5
6
Since we don't model the SoC, just use a QOM container.
6
Signed-off-by: JianChunfu <jansef.jian@hj-micro.com>
7
7
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20250221031034.69822-1-jansef.jian@hj-micro.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20240213155214.13619-5-philmd@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
hw/arm/stellaris.c | 11 ++++++++++-
11
include/hw/arm/smmu-common.h | 1 -
14
1 file changed, 10 insertions(+), 1 deletion(-)
12
1 file changed, 1 deletion(-)
15
13
16
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
14
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/stellaris.c
16
--- a/include/hw/arm/smmu-common.h
19
+++ b/hw/arm/stellaris.c
17
+++ b/include/hw/arm/smmu-common.h
20
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
18
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUTransCfg {
21
* 400fe000 system control
19
/* Used by stage-1 only. */
22
*/
20
bool aa64; /* arch64 or aarch32 translation table */
23
21
bool record_faults; /* record fault events */
24
+ Object *soc_container;
22
- uint64_t ttb; /* TT base address */
25
DeviceState *gpio_dev[7], *nvic;
23
uint8_t oas; /* output address width */
26
qemu_irq gpio_in[7][8];
24
uint8_t tbi; /* Top Byte Ignore */
27
qemu_irq gpio_out[7][8];
25
int asid;
28
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
29
flash_size = (((board->dc0 & 0xffff) + 1) << 1) * 1024;
30
sram_size = ((board->dc0 >> 18) + 1) * 1024;
31
32
+ soc_container = object_new("container");
33
+ object_property_add_child(OBJECT(ms), "soc", soc_container);
34
+
35
/* Flash programming is done via the SCU, so pretend it is ROM. */
36
memory_region_init_rom(flash, NULL, "stellaris.flash", flash_size,
37
&error_fatal);
38
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
39
* need its sysclk output.
40
*/
41
ssys_dev = qdev_new(TYPE_STELLARIS_SYS);
42
+ object_property_add_child(soc_container, "sys", OBJECT(ssys_dev));
43
44
/*
45
* Most devices come preprogrammed with a MAC address in the user data.
46
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
47
sysbus_realize_and_unref(SYS_BUS_DEVICE(ssys_dev), &error_fatal);
48
49
nvic = qdev_new(TYPE_ARMV7M);
50
+ object_property_add_child(soc_container, "v7m", OBJECT(nvic));
51
qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES);
52
qdev_prop_set_uint8(nvic, "num-prio-bits", NUM_PRIO_BITS);
53
qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type);
54
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
55
56
dev = qdev_new(TYPE_STELLARIS_GPTM);
57
sbd = SYS_BUS_DEVICE(dev);
58
+ object_property_add_child(soc_container, "gptm[*]", OBJECT(dev));
59
qdev_connect_clock_in(dev, "clk",
60
qdev_get_clock_out(ssys_dev, "SYSCLK"));
61
sysbus_realize_and_unref(sbd, &error_fatal);
62
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
63
64
if (board->dc1 & (1 << 3)) { /* watchdog present */
65
dev = qdev_new(TYPE_LUMINARY_WATCHDOG);
66
-
67
+ object_property_add_child(soc_container, "wdg", OBJECT(dev));
68
qdev_connect_clock_in(dev, "WDOGCLK",
69
qdev_get_clock_out(ssys_dev, "SYSCLK"));
70
71
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
72
SysBusDevice *sbd;
73
74
dev = qdev_new("pl011_luminary");
75
+ object_property_add_child(soc_container, "uart[*]", OBJECT(dev));
76
sbd = SYS_BUS_DEVICE(dev);
77
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
78
sysbus_realize_and_unref(sbd, &error_fatal);
79
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
80
DeviceState *enet;
81
82
enet = qdev_new("stellaris_enet");
83
+ object_property_add_child(soc_container, "enet", OBJECT(enet));
84
if (nd) {
85
qdev_set_nic_properties(enet, nd);
86
} else {
87
--
26
--
88
2.34.1
27
2.43.0
89
90
diff view generated by jsdifflib
1
Add the GPIO, watchdog, dual-timer and I2C devices to the mps3-an536
1
From: Patrick Venture <venture@google.com>
2
board. These are all simple devices that just need to be created and
3
wired up.
4
2
3
The reg isn't validated to be a possible register before
4
it's dereferenced for one case. The mmio space registered
5
for the gpio device is 4KiB but there aren't that many
6
registers in the struct.
7
8
Cc: qemu-stable@nongnu.org
9
Fixes: 526dbbe0874 ("hw/gpio: Add GPIO model for Nuvoton NPCM7xx")
10
Signed-off-by: Patrick Venture <venture@google.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Message-id: 20250226024603.493148-1-venture@google.com
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20240206132931.38376-12-peter.maydell@linaro.org
8
---
14
---
9
hw/arm/mps3r.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
15
hw/gpio/npcm7xx_gpio.c | 3 +--
10
1 file changed, 59 insertions(+)
16
1 file changed, 1 insertion(+), 2 deletions(-)
11
17
12
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
18
diff --git a/hw/gpio/npcm7xx_gpio.c b/hw/gpio/npcm7xx_gpio.c
13
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/mps3r.c
20
--- a/hw/gpio/npcm7xx_gpio.c
15
+++ b/hw/arm/mps3r.c
21
+++ b/hw/gpio/npcm7xx_gpio.c
16
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_gpio_regs_write(void *opaque, hwaddr addr, uint64_t v,
17
#include "sysemu/sysemu.h"
23
return;
18
#include "hw/boards.h"
19
#include "hw/or-irq.h"
20
+#include "hw/qdev-clock.h"
21
#include "hw/qdev-properties.h"
22
#include "hw/arm/boot.h"
23
#include "hw/arm/bsa.h"
24
#include "hw/char/cmsdk-apb-uart.h"
25
+#include "hw/i2c/arm_sbcon_i2c.h"
26
#include "hw/intc/arm_gicv3.h"
27
+#include "hw/misc/unimp.h"
28
+#include "hw/timer/cmsdk-apb-dualtimer.h"
29
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
30
31
/* Define the layout of RAM and ROM in a board */
32
typedef struct RAMInfo {
33
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
34
CMSDKAPBUART uart[MPS3R_CPU_MAX + MPS3R_UART_MAX];
35
OrIRQState cpu_uart_oflow[MPS3R_CPU_MAX];
36
OrIRQState uart_oflow;
37
+ CMSDKAPBWatchdog watchdog;
38
+ CMSDKAPBDualTimer dualtimer;
39
+ ArmSbconI2CState i2c[5];
40
+ Clock *clk;
41
};
42
43
#define TYPE_MPS3R_MACHINE "mps3r"
44
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
45
MemoryRegion *sysmem = get_system_memory();
46
DeviceState *gicdev;
47
48
+ mms->clk = clock_new(OBJECT(machine), "CLK");
49
+ clock_set_hz(mms->clk, CLK_FRQ);
50
+
51
for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
52
MemoryRegion *mr = mr_for_raminfo(mms, ri);
53
memory_region_add_subregion(sysmem, ri->base, mr);
54
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
55
qdev_get_gpio_in(gicdev, combirq));
56
}
24
}
57
25
58
+ for (int i = 0; i < 4; i++) {
26
- diff = s->regs[reg] ^ value;
59
+ /* CMSDK GPIO controllers */
27
-
60
+ g_autofree char *s = g_strdup_printf("gpio%d", i);
28
switch (reg) {
61
+ create_unimplemented_device(s, 0xe0000000 + i * 0x1000, 0x1000);
29
case NPCM7XX_GPIO_TLOCK1:
62
+ }
30
case NPCM7XX_GPIO_TLOCK2:
63
+
31
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_gpio_regs_write(void *opaque, hwaddr addr, uint64_t v,
64
+ object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
32
case NPCM7XX_GPIO_PU:
65
+ TYPE_CMSDK_APB_WATCHDOG);
33
case NPCM7XX_GPIO_PD:
66
+ qdev_connect_clock_in(DEVICE(&mms->watchdog), "WDOGCLK", mms->clk);
34
case NPCM7XX_GPIO_IEM:
67
+ sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
35
+ diff = s->regs[reg] ^ value;
68
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->watchdog), 0,
36
s->regs[reg] = value;
69
+ qdev_get_gpio_in(gicdev, 0));
37
npcm7xx_gpio_update_pins(s, diff);
70
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->watchdog), 0, 0xe0100000);
38
break;
71
+
72
+ object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
73
+ TYPE_CMSDK_APB_DUALTIMER);
74
+ qdev_connect_clock_in(DEVICE(&mms->dualtimer), "TIMCLK", mms->clk);
75
+ sysbus_realize(SYS_BUS_DEVICE(&mms->dualtimer), &error_fatal);
76
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
77
+ qdev_get_gpio_in(gicdev, 3));
78
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 1,
79
+ qdev_get_gpio_in(gicdev, 1));
80
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 2,
81
+ qdev_get_gpio_in(gicdev, 2));
82
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0xe0101000);
83
+
84
+ for (int i = 0; i < ARRAY_SIZE(mms->i2c); i++) {
85
+ static const hwaddr i2cbase[] = {0xe0102000, /* Touch */
86
+ 0xe0103000, /* Audio */
87
+ 0xe0107000, /* Shield0 */
88
+ 0xe0108000, /* Shield1 */
89
+ 0xe0109000}; /* DDR4 EEPROM */
90
+ g_autofree char *s = g_strdup_printf("i2c%d", i);
91
+
92
+ object_initialize_child(OBJECT(mms), s, &mms->i2c[i],
93
+ TYPE_ARM_SBCON_I2C);
94
+ sysbus_realize(SYS_BUS_DEVICE(&mms->i2c[i]), &error_fatal);
95
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->i2c[i]), 0, i2cbase[i]);
96
+ if (i != 2 && i != 3) {
97
+ /*
98
+ * internal-only bus: mark it full to avoid user-created
99
+ * i2c devices being plugged into it.
100
+ */
101
+ qbus_mark_full(qdev_get_child_bus(DEVICE(&mms->i2c[i]), "i2c"));
102
+ }
103
+ }
104
+
105
mms->bootinfo.ram_size = machine->ram_size;
106
mms->bootinfo.board_id = -1;
107
mms->bootinfo.loader_start = mmc->loader_start;
108
--
39
--
109
2.34.1
40
2.43.0
110
41
111
42
diff view generated by jsdifflib
1
The AN536 is another FPGA image for the MPS3 development board. Unlike
1
From: Thomas Huth <thuth@redhat.com>
2
the existing FPGA images we already model, this board uses a Cortex-R
3
family CPU, and it does not use any equivalent to the M-profile
4
"Subsystem for Embedded" SoC-equivalent that we model in hw/arm/armsse.c.
5
It's therefore more convenient for us to model it as a completely
6
separate C file.
7
2
8
This commit adds the basic skeleton of the board model, and the
3
The kernel that is used in the sx1 test prints the usual Linux log
9
code to create all the RAM and ROM. We assume that we're probably
4
onto the serial console, but this test currently ignores it. To
10
going to want to add more images in future, so use the same
5
make sure that the serial device is working properly, let's check
11
base class/subclass setup that mps2-tz.c uses, even though at
6
for some strings in the output here.
12
the moment there's only a single subclass.
13
7
14
Following commits will add the CPUs and the peripherals.
8
While we're at it, also add the test to the corresponding section
9
in the MAINTAINERS file.
15
10
11
Signed-off-by: Thomas Huth <thuth@redhat.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Message-id: 20250226104833.1176253-1-thuth@redhat.com
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
18
Message-id: 20240206132931.38376-9-peter.maydell@linaro.org
19
---
15
---
20
MAINTAINERS | 3 +-
16
MAINTAINERS | 1 +
21
configs/devices/arm-softmmu/default.mak | 1 +
17
tests/functional/test_arm_sx1.py | 7 ++++---
22
hw/arm/mps3r.c | 239 ++++++++++++++++++++++++
18
2 files changed, 5 insertions(+), 3 deletions(-)
23
hw/arm/Kconfig | 5 +
24
hw/arm/meson.build | 1 +
25
5 files changed, 248 insertions(+), 1 deletion(-)
26
create mode 100644 hw/arm/mps3r.c
27
19
28
diff --git a/MAINTAINERS b/MAINTAINERS
20
diff --git a/MAINTAINERS b/MAINTAINERS
29
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
30
--- a/MAINTAINERS
22
--- a/MAINTAINERS
31
+++ b/MAINTAINERS
23
+++ b/MAINTAINERS
32
@@ -XXX,XX +XXX,XX @@ F: include/hw/misc/imx7_*.h
24
@@ -XXX,XX +XXX,XX @@ S: Maintained
33
F: hw/pci-host/designware.c
25
F: hw/*/omap*
34
F: include/hw/pci-host/designware.h
26
F: include/hw/arm/omap.h
35
27
F: docs/system/arm/sx1.rst
36
-MPS2
28
+F: tests/functional/test_arm_sx1.py
37
+MPS2 / MPS3
29
38
M: Peter Maydell <peter.maydell@linaro.org>
30
IPack
39
L: qemu-arm@nongnu.org
31
M: Alberto Garcia <berto@igalia.com>
40
S: Maintained
32
diff --git a/tests/functional/test_arm_sx1.py b/tests/functional/test_arm_sx1.py
41
F: hw/arm/mps2.c
33
index XXXXXXX..XXXXXXX 100755
42
F: hw/arm/mps2-tz.c
34
--- a/tests/functional/test_arm_sx1.py
43
+F: hw/arm/mps3r.c
35
+++ b/tests/functional/test_arm_sx1.py
44
F: hw/misc/mps2-*.c
36
@@ -XXX,XX +XXX,XX @@ def test_arm_sx1_initrd(self):
45
F: include/hw/misc/mps2-*.h
37
self.vm.add_args('-append', f'kunit.enable=0 rdinit=/sbin/init {self.CONSOLE_ARGS}')
46
F: hw/arm/armsse.c
38
self.vm.add_args('-no-reboot')
47
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
39
self.launch_kernel(zimage_path,
48
index XXXXXXX..XXXXXXX 100644
40
- initrd=initrd_path)
49
--- a/configs/devices/arm-softmmu/default.mak
41
+ initrd=initrd_path,
50
+++ b/configs/devices/arm-softmmu/default.mak
42
+ wait_for='Boot successful')
51
@@ -XXX,XX +XXX,XX @@ CONFIG_ARM_VIRT=y
43
self.vm.wait(timeout=120)
52
# CONFIG_INTEGRATOR=n
44
53
# CONFIG_FSL_IMX31=n
45
def test_arm_sx1_sd(self):
54
# CONFIG_MUSICPAL=n
46
@@ -XXX,XX +XXX,XX @@ def test_arm_sx1_sd(self):
55
+# CONFIG_MPS3R=n
47
self.vm.add_args('-no-reboot')
56
# CONFIG_MUSCA=n
48
self.vm.add_args('-snapshot')
57
# CONFIG_CHEETAH=n
49
self.vm.add_args('-drive', f'format=raw,if=sd,file={sd_fs_path}')
58
# CONFIG_SX1=n
50
- self.launch_kernel(zimage_path)
59
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
51
+ self.launch_kernel(zimage_path, wait_for='Boot successful')
60
new file mode 100644
52
self.vm.wait(timeout=120)
61
index XXXXXXX..XXXXXXX
53
62
--- /dev/null
54
def test_arm_sx1_flash(self):
63
+++ b/hw/arm/mps3r.c
55
@@ -XXX,XX +XXX,XX @@ def test_arm_sx1_flash(self):
64
@@ -XXX,XX +XXX,XX @@
56
self.vm.add_args('-no-reboot')
65
+/*
57
self.vm.add_args('-snapshot')
66
+ * Arm MPS3 board emulation for Cortex-R-based FPGA images.
58
self.vm.add_args('-drive', f'format=raw,if=pflash,file={flash_path}')
67
+ * (For M-profile images see mps2.c and mps2tz.c.)
59
- self.launch_kernel(zimage_path)
68
+ *
60
+ self.launch_kernel(zimage_path, wait_for='Boot successful')
69
+ * Copyright (c) 2017 Linaro Limited
61
self.vm.wait(timeout=120)
70
+ * Written by Peter Maydell
62
71
+ *
63
if __name__ == '__main__':
72
+ * This program is free software; you can redistribute it and/or modify
73
+ * it under the terms of the GNU General Public License version 2 or
74
+ * (at your option) any later version.
75
+ */
76
+
77
+/*
78
+ * The MPS3 is an FPGA based dev board. This file handles FPGA images
79
+ * which use the Cortex-R CPUs. We model these separately from the
80
+ * M-profile images, because on M-profile the FPGA image is based on
81
+ * a "Subsystem for Embedded" which is similar to an SoC, whereas
82
+ * the R-profile FPGA images don't have that abstraction layer.
83
+ *
84
+ * We model the following FPGA images here:
85
+ * "mps3-an536" -- dual Cortex-R52 as documented in Arm Application Note AN536
86
+ *
87
+ * Application Note AN536:
88
+ * https://developer.arm.com/documentation/dai0536/latest/
89
+ */
90
+
91
+#include "qemu/osdep.h"
92
+#include "qemu/units.h"
93
+#include "qapi/error.h"
94
+#include "exec/address-spaces.h"
95
+#include "cpu.h"
96
+#include "hw/boards.h"
97
+#include "hw/arm/boot.h"
98
+
99
+/* Define the layout of RAM and ROM in a board */
100
+typedef struct RAMInfo {
101
+ const char *name;
102
+ hwaddr base;
103
+ hwaddr size;
104
+ int mrindex; /* index into rams[]; -1 for the system RAM block */
105
+ int flags;
106
+} RAMInfo;
107
+
108
+/*
109
+ * The MPS3 DDR is 3GiB, but on a 32-bit host QEMU doesn't permit
110
+ * emulation of that much guest RAM, so artificially make it smaller.
111
+ */
112
+#if HOST_LONG_BITS == 32
113
+#define MPS3_DDR_SIZE (1 * GiB)
114
+#else
115
+#define MPS3_DDR_SIZE (3 * GiB)
116
+#endif
117
+
118
+/*
119
+ * Flag values:
120
+ * IS_MAIN: this is the main machine RAM
121
+ * IS_ROM: this area is read-only
122
+ */
123
+#define IS_MAIN 1
124
+#define IS_ROM 2
125
+
126
+#define MPS3R_RAM_MAX 9
127
+
128
+typedef enum MPS3RFPGAType {
129
+ FPGA_AN536,
130
+} MPS3RFPGAType;
131
+
132
+struct MPS3RMachineClass {
133
+ MachineClass parent;
134
+ MPS3RFPGAType fpga_type;
135
+ const RAMInfo *raminfo;
136
+};
137
+
138
+struct MPS3RMachineState {
139
+ MachineState parent;
140
+ MemoryRegion ram[MPS3R_RAM_MAX];
141
+};
142
+
143
+#define TYPE_MPS3R_MACHINE "mps3r"
144
+#define TYPE_MPS3R_AN536_MACHINE MACHINE_TYPE_NAME("mps3-an536")
145
+
146
+OBJECT_DECLARE_TYPE(MPS3RMachineState, MPS3RMachineClass, MPS3R_MACHINE)
147
+
148
+static const RAMInfo an536_raminfo[] = {
149
+ {
150
+ .name = "ATCM",
151
+ .base = 0x00000000,
152
+ .size = 0x00008000,
153
+ .mrindex = 0,
154
+ }, {
155
+ /* We model the QSPI flash as simple ROM for now */
156
+ .name = "QSPI",
157
+ .base = 0x08000000,
158
+ .size = 0x00800000,
159
+ .flags = IS_ROM,
160
+ .mrindex = 1,
161
+ }, {
162
+ .name = "BRAM",
163
+ .base = 0x10000000,
164
+ .size = 0x00080000,
165
+ .mrindex = 2,
166
+ }, {
167
+ .name = "DDR",
168
+ .base = 0x20000000,
169
+ .size = MPS3_DDR_SIZE,
170
+ .mrindex = -1,
171
+ }, {
172
+ .name = "ATCM0",
173
+ .base = 0xee000000,
174
+ .size = 0x00008000,
175
+ .mrindex = 3,
176
+ }, {
177
+ .name = "BTCM0",
178
+ .base = 0xee100000,
179
+ .size = 0x00008000,
180
+ .mrindex = 4,
181
+ }, {
182
+ .name = "CTCM0",
183
+ .base = 0xee200000,
184
+ .size = 0x00008000,
185
+ .mrindex = 5,
186
+ }, {
187
+ .name = "ATCM1",
188
+ .base = 0xee400000,
189
+ .size = 0x00008000,
190
+ .mrindex = 6,
191
+ }, {
192
+ .name = "BTCM1",
193
+ .base = 0xee500000,
194
+ .size = 0x00008000,
195
+ .mrindex = 7,
196
+ }, {
197
+ .name = "CTCM1",
198
+ .base = 0xee600000,
199
+ .size = 0x00008000,
200
+ .mrindex = 8,
201
+ }, {
202
+ .name = NULL,
203
+ }
204
+};
205
+
206
+static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
207
+ const RAMInfo *raminfo)
208
+{
209
+ /* Return an initialized MemoryRegion for the RAMInfo. */
210
+ MemoryRegion *ram;
211
+
212
+ if (raminfo->mrindex < 0) {
213
+ /* Means this RAMInfo is for QEMU's "system memory" */
214
+ MachineState *machine = MACHINE(mms);
215
+ assert(!(raminfo->flags & IS_ROM));
216
+ return machine->ram;
217
+ }
218
+
219
+ assert(raminfo->mrindex < MPS3R_RAM_MAX);
220
+ ram = &mms->ram[raminfo->mrindex];
221
+
222
+ memory_region_init_ram(ram, NULL, raminfo->name,
223
+ raminfo->size, &error_fatal);
224
+ if (raminfo->flags & IS_ROM) {
225
+ memory_region_set_readonly(ram, true);
226
+ }
227
+ return ram;
228
+}
229
+
230
+static void mps3r_common_init(MachineState *machine)
231
+{
232
+ MPS3RMachineState *mms = MPS3R_MACHINE(machine);
233
+ MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
234
+ MemoryRegion *sysmem = get_system_memory();
235
+
236
+ for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
237
+ MemoryRegion *mr = mr_for_raminfo(mms, ri);
238
+ memory_region_add_subregion(sysmem, ri->base, mr);
239
+ }
240
+}
241
+
242
+static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
243
+{
244
+ /*
245
+ * Set mc->default_ram_size and default_ram_id from the
246
+ * information in mmc->raminfo.
247
+ */
248
+ MachineClass *mc = MACHINE_CLASS(mmc);
249
+ const RAMInfo *p;
250
+
251
+ for (p = mmc->raminfo; p->name; p++) {
252
+ if (p->mrindex < 0) {
253
+ /* Found the entry for "system memory" */
254
+ mc->default_ram_size = p->size;
255
+ mc->default_ram_id = p->name;
256
+ return;
257
+ }
258
+ }
259
+ g_assert_not_reached();
260
+}
261
+
262
+static void mps3r_class_init(ObjectClass *oc, void *data)
263
+{
264
+ MachineClass *mc = MACHINE_CLASS(oc);
265
+
266
+ mc->init = mps3r_common_init;
267
+}
268
+
269
+static void mps3r_an536_class_init(ObjectClass *oc, void *data)
270
+{
271
+ MachineClass *mc = MACHINE_CLASS(oc);
272
+ MPS3RMachineClass *mmc = MPS3R_MACHINE_CLASS(oc);
273
+ static const char * const valid_cpu_types[] = {
274
+ ARM_CPU_TYPE_NAME("cortex-r52"),
275
+ NULL
276
+ };
277
+
278
+ mc->desc = "ARM MPS3 with AN536 FPGA image for Cortex-R52";
279
+ mc->default_cpus = 2;
280
+ mc->min_cpus = mc->default_cpus;
281
+ mc->max_cpus = mc->default_cpus;
282
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-r52");
283
+ mc->valid_cpu_types = valid_cpu_types;
284
+ mmc->raminfo = an536_raminfo;
285
+ mps3r_set_default_ram_info(mmc);
286
+}
287
+
288
+static const TypeInfo mps3r_machine_types[] = {
289
+ {
290
+ .name = TYPE_MPS3R_MACHINE,
291
+ .parent = TYPE_MACHINE,
292
+ .abstract = true,
293
+ .instance_size = sizeof(MPS3RMachineState),
294
+ .class_size = sizeof(MPS3RMachineClass),
295
+ .class_init = mps3r_class_init,
296
+ }, {
297
+ .name = TYPE_MPS3R_AN536_MACHINE,
298
+ .parent = TYPE_MPS3R_MACHINE,
299
+ .class_init = mps3r_an536_class_init,
300
+ },
301
+};
302
+
303
+DEFINE_TYPES(mps3r_machine_types);
304
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
305
index XXXXXXX..XXXXXXX 100644
306
--- a/hw/arm/Kconfig
307
+++ b/hw/arm/Kconfig
308
@@ -XXX,XX +XXX,XX @@ config MAINSTONE
309
select PFLASH_CFI01
310
select SMC91C111
311
312
+config MPS3R
313
+ bool
314
+ default y
315
+ depends on TCG && ARM
316
+
317
config MUSCA
318
bool
319
default y
320
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
321
index XXXXXXX..XXXXXXX 100644
322
--- a/hw/arm/meson.build
323
+++ b/hw/arm/meson.build
324
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_HIGHBANK', if_true: files('highbank.c'))
325
arm_ss.add(when: 'CONFIG_INTEGRATOR', if_true: files('integratorcp.c'))
326
arm_ss.add(when: 'CONFIG_MAINSTONE', if_true: files('mainstone.c'))
327
arm_ss.add(when: 'CONFIG_MICROBIT', if_true: files('microbit.c'))
328
+arm_ss.add(when: 'CONFIG_MPS3R', if_true: files('mps3r.c'))
329
arm_ss.add(when: 'CONFIG_MUSICPAL', if_true: files('musicpal.c'))
330
arm_ss.add(when: 'CONFIG_NETDUINOPLUS2', if_true: files('netduinoplus2.c'))
331
arm_ss.add(when: 'CONFIG_OLIMEX_STM32_H405', if_true: files('olimex-stm32-h405.c'))
332
--
64
--
333
2.34.1
65
2.43.0
334
66
335
67
diff view generated by jsdifflib
1
This board has a lot of UARTs: there is one UART per CPU in the
1
When we are calculating timer deadlines, the correct definition of
2
per-CPU peripheral part of the address map, whose interrupts are
2
whether or not to apply an offset to the physical count is described
3
connected as per-CPU interrupt lines. Then there are 4 UARTs in the
3
in the Arm ARM DDI4087 rev L.a section D12.2.4.1. This is different
4
normal part of the peripheral space, whose interrupts are shared
4
from when the offset should be applied for a direct read of the
5
peripheral interrupts.
5
counter sysreg.
6
6
7
Connect and wire them all up; this involves some OR gates where
7
We got this right for the EL1 physical timer and for the EL1 virtual
8
multiple overflow interrupts are wired into one GIC input.
8
timer, but got all the rest wrong: they should be using a zero offset
9
always.
9
10
11
Factor the offset calculation out into a function that has a comment
12
documenting exactly which offset it is calculating and which gets the
13
HYP, SEC, and HYPVIRT cases right.
14
15
Cc: qemu-stable@nongnu.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
17
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Message-id: 20240206132931.38376-11-peter.maydell@linaro.org
18
Message-id: 20250204125009.2281315-2-peter.maydell@linaro.org
13
---
19
---
14
hw/arm/mps3r.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++
20
target/arm/helper.c | 29 +++++++++++++++++++++++++++--
15
1 file changed, 94 insertions(+)
21
1 file changed, 27 insertions(+), 2 deletions(-)
16
22
17
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
23
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/mps3r.c
25
--- a/target/arm/helper.c
20
+++ b/hw/arm/mps3r.c
26
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_phys_cnt_offset(CPUARMState *env)
22
#include "qapi/qmp/qlist.h"
28
return gt_phys_raw_cnt_offset(env);
23
#include "exec/address-spaces.h"
24
#include "cpu.h"
25
+#include "sysemu/sysemu.h"
26
#include "hw/boards.h"
27
+#include "hw/or-irq.h"
28
#include "hw/qdev-properties.h"
29
#include "hw/arm/boot.h"
30
#include "hw/arm/bsa.h"
31
+#include "hw/char/cmsdk-apb-uart.h"
32
#include "hw/intc/arm_gicv3.h"
33
34
/* Define the layout of RAM and ROM in a board */
35
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
36
37
#define MPS3R_RAM_MAX 9
38
#define MPS3R_CPU_MAX 2
39
+#define MPS3R_UART_MAX 4 /* shared UART count */
40
41
#define PERIPHBASE 0xf0000000
42
#define NUM_SPIS 96
43
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
44
MemoryRegion sysmem_alias[MPS3R_CPU_MAX];
45
MemoryRegion cpu_ram[MPS3R_CPU_MAX];
46
GICv3State gic;
47
+ /* per-CPU UARTs followed by the shared UARTs */
48
+ CMSDKAPBUART uart[MPS3R_CPU_MAX + MPS3R_UART_MAX];
49
+ OrIRQState cpu_uart_oflow[MPS3R_CPU_MAX];
50
+ OrIRQState uart_oflow;
51
};
52
53
#define TYPE_MPS3R_MACHINE "mps3r"
54
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
55
56
OBJECT_DECLARE_TYPE(MPS3RMachineState, MPS3RMachineClass, MPS3R_MACHINE)
57
58
+/*
59
+ * Main clock frequency CLK in Hz (50MHz). In the image there are also
60
+ * ACLK, MCLK, GPUCLK and PERIPHCLK at the same frequency; for our
61
+ * model we just roll them all into one.
62
+ */
63
+#define CLK_FRQ 50000000
64
+
65
static const RAMInfo an536_raminfo[] = {
66
{
67
.name = "ATCM",
68
@@ -XXX,XX +XXX,XX @@ static void create_gic(MPS3RMachineState *mms, MemoryRegion *sysmem)
69
}
70
}
29
}
71
30
72
+/*
31
+static uint64_t gt_indirect_access_timer_offset(CPUARMState *env, int timeridx)
73
+ * Create UART uartno, and map it into the MemoryRegion mem at address baseaddr.
74
+ * The qemu_irq arguments are where we connect the various IRQs from the UART.
75
+ */
76
+static void create_uart(MPS3RMachineState *mms, int uartno, MemoryRegion *mem,
77
+ hwaddr baseaddr, qemu_irq txirq, qemu_irq rxirq,
78
+ qemu_irq txoverirq, qemu_irq rxoverirq,
79
+ qemu_irq combirq)
80
+{
32
+{
81
+ g_autofree char *s = g_strdup_printf("uart%d", uartno);
33
+ /*
82
+ SysBusDevice *sbd;
34
+ * Return the timer offset to use for indirect accesses to the timer.
83
+
35
+ * This is the Offset value as defined in D12.2.4.1 "Operation of the
84
+ assert(uartno < ARRAY_SIZE(mms->uart));
36
+ * CompareValue views of the timers".
85
+ object_initialize_child(OBJECT(mms), s, &mms->uart[uartno],
37
+ *
86
+ TYPE_CMSDK_APB_UART);
38
+ * The condition here is not always the same as the condition for
87
+ qdev_prop_set_uint32(DEVICE(&mms->uart[uartno]), "pclk-frq", CLK_FRQ);
39
+ * whether to apply an offset register when doing a direct read of
88
+ qdev_prop_set_chr(DEVICE(&mms->uart[uartno]), "chardev", serial_hd(uartno));
40
+ * the counter sysreg; those conditions are described in the
89
+ sbd = SYS_BUS_DEVICE(&mms->uart[uartno]);
41
+ * access pseudocode for each counter register.
90
+ sysbus_realize(sbd, &error_fatal);
42
+ */
91
+ memory_region_add_subregion(mem, baseaddr,
43
+ switch (timeridx) {
92
+ sysbus_mmio_get_region(sbd, 0));
44
+ case GTIMER_PHYS:
93
+ sysbus_connect_irq(sbd, 0, txirq);
45
+ return gt_phys_raw_cnt_offset(env);
94
+ sysbus_connect_irq(sbd, 1, rxirq);
46
+ case GTIMER_VIRT:
95
+ sysbus_connect_irq(sbd, 2, txoverirq);
47
+ return env->cp15.cntvoff_el2;
96
+ sysbus_connect_irq(sbd, 3, rxoverirq);
48
+ case GTIMER_HYP:
97
+ sysbus_connect_irq(sbd, 4, combirq);
49
+ case GTIMER_SEC:
50
+ case GTIMER_HYPVIRT:
51
+ return 0;
52
+ default:
53
+ g_assert_not_reached();
54
+ }
98
+}
55
+}
99
+
56
+
100
static void mps3r_common_init(MachineState *machine)
57
static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
101
{
58
{
102
MPS3RMachineState *mms = MPS3R_MACHINE(machine);
59
ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx];
103
MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
60
@@ -XXX,XX +XXX,XX @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
104
MemoryRegion *sysmem = get_system_memory();
61
* Timer enabled: calculate and set current ISTATUS, irq, and
105
+ DeviceState *gicdev;
62
* reset timer to when ISTATUS next has to change
106
63
*/
107
for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
64
- uint64_t offset = timeridx == GTIMER_VIRT ?
108
MemoryRegion *mr = mr_for_raminfo(mms, ri);
65
- cpu->env.cp15.cntvoff_el2 : gt_phys_raw_cnt_offset(&cpu->env);
109
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
66
+ uint64_t offset = gt_indirect_access_timer_offset(&cpu->env, timeridx);
110
}
67
uint64_t count = gt_get_countervalue(&cpu->env);
111
68
/* Note that this must be unsigned 64 bit arithmetic: */
112
create_gic(mms, sysmem);
69
int istatus = count - offset >= gt->cval;
113
+ gicdev = DEVICE(&mms->gic);
114
+
115
+ /*
116
+ * UARTs 0 and 1 are per-CPU; their interrupts are wired to
117
+ * the relevant CPU's PPI 0..3, aka INTID 16..19
118
+ */
119
+ for (int i = 0; i < machine->smp.cpus; i++) {
120
+ int intidbase = NUM_SPIS + i * GIC_INTERNAL;
121
+ g_autofree char *s = g_strdup_printf("cpu-uart-oflow-orgate%d", i);
122
+ DeviceState *orgate;
123
+
124
+ /* The two overflow IRQs from the UART are ORed together into PPI 3 */
125
+ object_initialize_child(OBJECT(mms), s, &mms->cpu_uart_oflow[i],
126
+ TYPE_OR_IRQ);
127
+ orgate = DEVICE(&mms->cpu_uart_oflow[i]);
128
+ qdev_prop_set_uint32(orgate, "num-lines", 2);
129
+ qdev_realize(orgate, NULL, &error_fatal);
130
+ qdev_connect_gpio_out(orgate, 0,
131
+ qdev_get_gpio_in(gicdev, intidbase + 19));
132
+
133
+ create_uart(mms, i, &mms->cpu_sysmem[i], 0xe7c00000,
134
+ qdev_get_gpio_in(gicdev, intidbase + 17), /* tx */
135
+ qdev_get_gpio_in(gicdev, intidbase + 16), /* rx */
136
+ qdev_get_gpio_in(orgate, 0), /* txover */
137
+ qdev_get_gpio_in(orgate, 1), /* rxover */
138
+ qdev_get_gpio_in(gicdev, intidbase + 18) /* combined */);
139
+ }
140
+ /*
141
+ * UARTs 2 to 5 are whole-system; all overflow IRQs are ORed
142
+ * together into IRQ 17
143
+ */
144
+ object_initialize_child(OBJECT(mms), "uart-oflow-orgate",
145
+ &mms->uart_oflow, TYPE_OR_IRQ);
146
+ qdev_prop_set_uint32(DEVICE(&mms->uart_oflow), "num-lines",
147
+ MPS3R_UART_MAX * 2);
148
+ qdev_realize(DEVICE(&mms->uart_oflow), NULL, &error_fatal);
149
+ qdev_connect_gpio_out(DEVICE(&mms->uart_oflow), 0,
150
+ qdev_get_gpio_in(gicdev, 17));
151
+
152
+ for (int i = 0; i < MPS3R_UART_MAX; i++) {
153
+ hwaddr baseaddr = 0xe0205000 + i * 0x1000;
154
+ int rxirq = 5 + i * 2, txirq = 6 + i * 2, combirq = 13 + i;
155
+
156
+ create_uart(mms, i + MPS3R_CPU_MAX, sysmem, baseaddr,
157
+ qdev_get_gpio_in(gicdev, txirq),
158
+ qdev_get_gpio_in(gicdev, rxirq),
159
+ qdev_get_gpio_in(DEVICE(&mms->uart_oflow), i * 2),
160
+ qdev_get_gpio_in(DEVICE(&mms->uart_oflow), i * 2 + 1),
161
+ qdev_get_gpio_in(gicdev, combirq));
162
+ }
163
164
mms->bootinfo.ram_size = machine->ram_size;
165
mms->bootinfo.board_id = -1;
166
--
70
--
167
2.34.1
71
2.43.0
168
72
169
73
diff view generated by jsdifflib
1
We support two different encodings for the AArch32 IMPDEF
1
The CNTVOFF_EL2 offset register should only be applied for accessses
2
CBAR register -- older cores like the Cortex A9, A7, A15
2
to CNTVCT_EL0 and for the EL1 virtual timer (CNTV_*). We were
3
have this at 4, c15, c0, 0; newer cores like the
3
incorrectly applying it for the EL2 virtual timer (CNTHV_*).
4
Cortex A35, A53, A57 and A72 have it at 1 c15 c0 0.
5
4
6
When we implemented this we picked which encoding to
5
Cc: qemu-stable@nongnu.org
7
use based on whether the CPU set ARM_FEATURE_AARCH64.
8
However this isn't right for three cases:
9
* the qemu-system-arm 'max' CPU, which is supposed to be
10
a variant on a Cortex-A57; it ought to use the same
11
encoding the A57 does and which the AArch64 'max'
12
exposes to AArch32 guest code
13
* the Cortex-R52, which is AArch32-only but has the CBAR
14
at the newer encoding (and where we incorrectly are
15
not yet setting ARM_FEATURE_CBAR_RO anyway)
16
* any possible future support for other v8 AArch32
17
only CPUs, or for supporting "boot the CPU into
18
AArch32 mode" on our existing cores like the A57 etc
19
20
Make the decision of the encoding be based on whether
21
the CPU implements the ARM_FEATURE_V8 flag instead.
22
23
This changes the behaviour only for the qemu-system-arm
24
'-cpu max'. We don't expect anybody to be relying on the
25
old behaviour because:
26
* it's not what the real hardware Cortex-A57 does
27
(and that's what our ID register claims we are)
28
* we don't implement the memory-mapped GICv3 support
29
which is the only thing that exists at the peripheral
30
base address pointed to by the register
31
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
34
Message-id: 20240206132931.38376-2-peter.maydell@linaro.org
8
Message-id: 20250204125009.2281315-3-peter.maydell@linaro.org
35
---
9
---
36
target/arm/helper.c | 2 +-
10
target/arm/helper.c | 2 --
37
1 file changed, 1 insertion(+), 1 deletion(-)
11
1 file changed, 2 deletions(-)
38
12
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
40
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/helper.c
15
--- a/target/arm/helper.c
42
+++ b/target/arm/helper.c
16
+++ b/target/arm/helper.c
43
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
17
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
44
* AArch64 cores we might need to add a specific feature flag
18
45
* to indicate cores with "flavour 2" CBAR.
19
switch (timeridx) {
46
*/
20
case GTIMER_VIRT:
47
- if (arm_feature(env, ARM_FEATURE_AARCH64)) {
21
- case GTIMER_HYPVIRT:
48
+ if (arm_feature(env, ARM_FEATURE_V8)) {
22
offset = gt_virt_cnt_offset(env);
49
/* 32 bit view is [31:18] 0...0 [43:32]. */
23
break;
50
uint32_t cbar32 = (extract64(cpu->reset_cbar, 18, 14) << 18)
24
case GTIMER_PHYS:
51
| extract64(cpu->reset_cbar, 32, 12);
25
@@ -XXX,XX +XXX,XX @@ static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
26
27
switch (timeridx) {
28
case GTIMER_VIRT:
29
- case GTIMER_HYPVIRT:
30
offset = gt_virt_cnt_offset(env);
31
break;
32
case GTIMER_PHYS:
52
--
33
--
53
2.34.1
34
2.43.0
35
36
diff view generated by jsdifflib
1
It doesn't make sense to read the value of MDCR_EL2 on a non-A-profile
1
When we added Secure EL2 support, we missed that this needs an update
2
CPU, and in fact if you try to do it we will assert:
2
to the access code for the EL3 physical timer registers. These are
3
supposed to UNDEF from Secure EL1 when Secure EL2 is enabled.
3
4
4
#6 0x00007ffff4b95e96 in __GI___assert_fail
5
(Note for stable backporting: for backports to branches where
5
(assertion=0x5555565a8c70 "!arm_feature(env, ARM_FEATURE_M)", file=0x5555565a6e5c "../../target/arm/helper.c", line=12600, function=0x5555565a9560 <__PRETTY_FUNCTION__.0> "arm_security_space_below_el3") at ./assert/assert.c:101
6
CP_ACCESS_UNDEFINED is not defined, the old name to use instead
6
#7 0x0000555555ebf412 in arm_security_space_below_el3 (env=0x555557bc8190) at ../../target/arm/helper.c:12600
7
is CP_ACCESS_TRAP_UNCATEGORIZED.)
7
#8 0x0000555555ea6f89 in arm_is_el2_enabled (env=0x555557bc8190) at ../../target/arm/cpu.h:2595
8
#9 0x0000555555ea942f in arm_mdcr_el2_eff (env=0x555557bc8190) at ../../target/arm/internals.h:1512
9
10
We might call pmu_counter_enabled() on an M-profile CPU (for example
11
from the migration pre/post hooks in machine.c); this should always
12
return false because these CPUs don't set ARM_FEATURE_PMU.
13
14
Avoid the assertion by not calling arm_mdcr_el2_eff() before we
15
have done the early return for "PMU not present".
16
17
This fixes an assertion failure if you try to do a loadvm or
18
savevm for an M-profile board.
19
8
20
Cc: qemu-stable@nongnu.org
9
Cc: qemu-stable@nongnu.org
21
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2155
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20250204125009.2281315-4-peter.maydell@linaro.org
25
Message-id: 20240208153346.970021-1-peter.maydell@linaro.org
26
---
13
---
27
target/arm/helper.c | 12 ++++++++++--
14
target/arm/helper.c | 3 +++
28
1 file changed, 10 insertions(+), 2 deletions(-)
15
1 file changed, 3 insertions(+)
29
16
30
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
31
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper.c
19
--- a/target/arm/helper.c
33
+++ b/target/arm/helper.c
20
+++ b/target/arm/helper.c
34
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
21
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gt_stimer_access(CPUARMState *env,
35
bool enabled, prohibited = false, filtered;
22
if (!arm_is_secure(env)) {
36
bool secure = arm_is_secure(env);
23
return CP_ACCESS_UNDEFINED;
37
int el = arm_current_el(env);
24
}
38
- uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
25
+ if (arm_is_el2_enabled(env)) {
39
- uint8_t hpmn = mdcr_el2 & MDCR_HPMN;
26
+ return CP_ACCESS_UNDEFINED;
40
+ uint64_t mdcr_el2;
27
+ }
41
+ uint8_t hpmn;
28
if (!(env->cp15.scr_el3 & SCR_ST)) {
42
29
return CP_ACCESS_TRAP_EL3;
43
+ /*
30
}
44
+ * We might be called for M-profile cores where MDCR_EL2 doesn't
45
+ * exist and arm_mdcr_el2_eff() will assert, so this early-exit check
46
+ * must be before we read that value.
47
+ */
48
if (!arm_feature(env, ARM_FEATURE_PMU)) {
49
return false;
50
}
51
52
+ mdcr_el2 = arm_mdcr_el2_eff(env);
53
+ hpmn = mdcr_el2 & MDCR_HPMN;
54
+
55
if (!arm_feature(env, ARM_FEATURE_EL2) ||
56
(counter < hpmn || counter == 31)) {
57
e = env->cp15.c9_pmcr & PMCRE;
58
--
31
--
59
2.34.1
32
2.43.0
60
33
61
34
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
Currently we handle CNTV_TVAL_EL02 by calling gt_tval_read() for the
2
EL1 virt timer. This is almost correct, but the underlying
3
CNTV_TVAL_EL0 register behaves slightly differently. CNTV_TVAL_EL02
4
always applies the CNTVOFF_EL2 offset; CNTV_TVAL_EL0 doesn't do so if
5
we're at EL2 and HCR_EL2.E2H is 1.
2
6
3
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
7
We were getting this wrong, because we ended up in
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
gt_virt_cnt_offset() and did the E2H check.
5
Message-id: 20240213155214.13619-3-philmd@linaro.org
9
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Factor out the tval read/write calculation from the selection of the
11
offset, so that we can special case gt_virt_tval_read() and
12
gt_virt_tval_write() to unconditionally pass CNTVOFF_EL2.
13
14
Cc: qemu-stable@nongnu.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
17
Message-id: 20250204125009.2281315-5-peter.maydell@linaro.org
8
---
18
---
9
hw/arm/stellaris.c | 26 ++++++++++++++++++++++----
19
target/arm/helper.c | 36 +++++++++++++++++++++++++++---------
10
1 file changed, 22 insertions(+), 4 deletions(-)
20
1 file changed, 27 insertions(+), 9 deletions(-)
11
21
12
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
22
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/stellaris.c
24
--- a/target/arm/helper.c
15
+++ b/hw/arm/stellaris.c
25
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ static void stellaris_sys_instance_init(Object *obj)
26
@@ -XXX,XX +XXX,XX @@ static void gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
17
s->sysclk = qdev_init_clock_out(DEVICE(s), "SYSCLK");
27
gt_recalc_timer(env_archcpu(env), timeridx);
18
}
28
}
19
29
20
-/* I2C controller. */
30
+static uint64_t do_tval_read(CPUARMState *env, int timeridx, uint64_t offset)
21
+/*
31
+{
22
+ * I2C controller.
32
+ return (uint32_t)(env->cp15.c14_timer[timeridx].cval -
23
+ * ??? For now we only implement the master interface.
33
+ (gt_get_countervalue(env) - offset));
24
+ */
25
26
#define TYPE_STELLARIS_I2C "stellaris-i2c"
27
OBJECT_DECLARE_SIMPLE_TYPE(stellaris_i2c_state, STELLARIS_I2C)
28
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_write(void *opaque, hwaddr offset,
29
stellaris_i2c_update(s);
30
}
31
32
-static void stellaris_i2c_reset(stellaris_i2c_state *s)
33
+static void stellaris_i2c_reset_enter(Object *obj, ResetType type)
34
{
35
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
36
+
37
if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
38
i2c_end_transfer(s->bus);
39
+}
34
+}
40
+
35
+
41
+static void stellaris_i2c_reset_hold(Object *obj)
36
static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
42
+{
37
int timeridx)
43
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
38
{
44
39
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
45
s->msa = 0;
40
break;
46
s->mcs = 0;
41
}
47
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_reset(stellaris_i2c_state *s)
42
48
s->mimr = 0;
43
- return (uint32_t)(env->cp15.c14_timer[timeridx].cval -
49
s->mris = 0;
44
- (gt_get_countervalue(env) - offset));
50
s->mcr = 0;
45
+ return do_tval_read(env, timeridx, offset);
51
+}
46
+}
52
+
47
+
53
+static void stellaris_i2c_reset_exit(Object *obj)
48
+static void do_tval_write(CPUARMState *env, int timeridx, uint64_t value,
49
+ uint64_t offset)
54
+{
50
+{
55
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
51
+ trace_arm_gt_tval_write(timeridx, value);
56
+
52
+ env->cp15.c14_timer[timeridx].cval = gt_get_countervalue(env) - offset +
57
stellaris_i2c_update(s);
53
+ sextract64(value, 0, 32);
54
+ gt_recalc_timer(env_archcpu(env), timeridx);
58
}
55
}
59
56
60
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_init(Object *obj)
57
static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
61
memory_region_init_io(&s->iomem, obj, &stellaris_i2c_ops, s,
58
@@ -XXX,XX +XXX,XX @@ static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
62
"i2c", 0x1000);
59
offset = gt_phys_cnt_offset(env);
63
sysbus_init_mmio(sbd, &s->iomem);
60
break;
64
- /* ??? For now we only implement the master interface. */
61
}
65
- stellaris_i2c_reset(s);
62
-
63
- trace_arm_gt_tval_write(timeridx, value);
64
- env->cp15.c14_timer[timeridx].cval = gt_get_countervalue(env) - offset +
65
- sextract64(value, 0, 32);
66
- gt_recalc_timer(env_archcpu(env), timeridx);
67
+ do_tval_write(env, timeridx, value, offset);
66
}
68
}
67
69
68
/* Analogue to Digital Converter. This is only partially implemented,
70
static void gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
69
@@ -XXX,XX +XXX,XX @@ type_init(stellaris_machine_init)
71
@@ -XXX,XX +XXX,XX @@ static void gt_virt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
70
static void stellaris_i2c_class_init(ObjectClass *klass, void *data)
72
73
static uint64_t gt_virt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri)
71
{
74
{
72
DeviceClass *dc = DEVICE_CLASS(klass);
75
- return gt_tval_read(env, ri, GTIMER_VIRT);
73
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
76
+ /*
74
77
+ * This is CNTV_TVAL_EL02; unlike the underlying CNTV_TVAL_EL0
75
+ rc->phases.enter = stellaris_i2c_reset_enter;
78
+ * we always apply CNTVOFF_EL2. Special case that here rather
76
+ rc->phases.hold = stellaris_i2c_reset_hold;
79
+ * than going into the generic gt_tval_read() and then having
77
+ rc->phases.exit = stellaris_i2c_reset_exit;
80
+ * to re-detect that it's this register.
78
dc->vmsd = &vmstate_stellaris_i2c;
81
+ * Note that the accessfn/perms mean we know we're at EL2 or EL3 here.
82
+ */
83
+ return do_tval_read(env, GTIMER_VIRT, env->cp15.cntvoff_el2);
79
}
84
}
80
85
86
static void gt_virt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
87
uint64_t value)
88
{
89
- gt_tval_write(env, ri, GTIMER_VIRT, value);
90
+ /* Similarly for writes to CNTV_TVAL_EL02 */
91
+ do_tval_write(env, GTIMER_VIRT, value, env->cp15.cntvoff_el2);
92
}
93
94
static void gt_virt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
81
--
95
--
82
2.34.1
96
2.43.0
83
97
84
98
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
When reading or writing the timer registers, sometimes we need to
2
2
apply one of the timer offsets. Specifically, this happens for
3
When we added SVE_MTEDESC_SHIFT, we effectively limited the
3
direct reads of the counter registers CNTPCT_EL0 and CNTVCT_EL0 (and
4
maximum size of MTEDESC. Adjust SIZEM1 to consume the remaining
4
their self-synchronized variants CNTVCTSS_EL0 and CNTPCTSS_EL0). It
5
bits (32 - 10 - 5 - 12 == 5). Assert that the data to be stored
5
also applies for direct reads and writes of the CNT*_TVAL_EL*
6
fits within the field (expecting 8 * 4 - 1 == 31, exact fit).
6
registers that provide the 32-bit downcounting view of each timer.
7
8
We currently do this with duplicated code in gt_tval_read() and
9
gt_tval_write() and a special-case in gt_virt_cnt_read() and
10
gt_cnt_read(). Refactor this so that we handle it all in a single
11
function gt_direct_access_timer_offset(), to parallel how we handle
12
the offset for indirect accesses.
13
14
The call in the WFIT helper previously to gt_virt_cnt_offset() is
15
now to gt_direct_access_timer_offset(); this is the correct
16
behaviour, but it's not immediately obvious that it shouldn't be
17
considered an indirect access, so we add an explanatory comment.
18
19
This commit should make no behavioural changes.
20
21
(Cc to stable because the following bugfix commit will
22
depend on this one.)
7
23
8
Cc: qemu-stable@nongnu.org
24
Cc: qemu-stable@nongnu.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
12
Message-id: 20240207025210.8837-4-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
27
Message-id: 20250204125009.2281315-6-peter.maydell@linaro.org
14
---
28
---
15
target/arm/internals.h | 2 +-
29
target/arm/internals.h | 5 +-
16
target/arm/tcg/translate-sve.c | 7 ++++---
30
target/arm/helper.c | 103 +++++++++++++++++++------------------
17
2 files changed, 5 insertions(+), 4 deletions(-)
31
target/arm/tcg/op_helper.c | 8 ++-
32
3 files changed, 62 insertions(+), 54 deletions(-)
18
33
19
diff --git a/target/arm/internals.h b/target/arm/internals.h
34
diff --git a/target/arm/internals.h b/target/arm/internals.h
20
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/internals.h
36
--- a/target/arm/internals.h
22
+++ b/target/arm/internals.h
37
+++ b/target/arm/internals.h
23
@@ -XXX,XX +XXX,XX @@ FIELD(MTEDESC, TBI, 4, 2)
38
@@ -XXX,XX +XXX,XX @@ int delete_hw_watchpoint(target_ulong addr, target_ulong len, int type);
24
FIELD(MTEDESC, TCMA, 6, 2)
39
uint64_t gt_get_countervalue(CPUARMState *env);
25
FIELD(MTEDESC, WRITE, 8, 1)
40
/*
26
FIELD(MTEDESC, ALIGN, 9, 3)
41
* Return the currently applicable offset between the system counter
27
-FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - 12) /* size - 1 */
42
- * and CNTVCT_EL0 (this will be either 0 or the value of CNTVOFF_EL2).
28
+FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - SVE_MTEDESC_SHIFT - 12) /* size - 1 */
43
+ * and the counter for the specified timer, as used for direct register
29
44
+ * accesses.
30
bool mte_probe(CPUARMState *env, uint32_t desc, uint64_t ptr);
45
*/
31
uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra);
46
-uint64_t gt_virt_cnt_offset(CPUARMState *env);
32
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
47
+uint64_t gt_direct_access_timer_offset(CPUARMState *env, int timeridx);
48
49
/*
50
* Return mask of ARMMMUIdxBit values corresponding to an "invalidate
51
diff --git a/target/arm/helper.c b/target/arm/helper.c
33
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/tcg/translate-sve.c
53
--- a/target/arm/helper.c
35
+++ b/target/arm/tcg/translate-sve.c
54
+++ b/target/arm/helper.c
36
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
55
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_phys_raw_cnt_offset(CPUARMState *env)
37
{
56
return 0;
38
unsigned vsz = vec_full_reg_size(s);
57
}
39
TCGv_ptr t_pg;
58
40
+ uint32_t sizem1;
59
-static uint64_t gt_phys_cnt_offset(CPUARMState *env)
41
int desc = 0;
60
-{
42
61
- if (arm_current_el(env) >= 2) {
43
assert(mte_n >= 1 && mte_n <= 4);
62
- return 0;
44
+ sizem1 = (mte_n << dtype_msz(dtype)) - 1;
63
- }
45
+ assert(sizem1 <= R_MTEDESC_SIZEM1_MASK >> R_MTEDESC_SIZEM1_SHIFT);
64
- return gt_phys_raw_cnt_offset(env);
46
if (s->mte_active[0]) {
65
-}
47
- int msz = dtype_msz(dtype);
66
-
48
-
67
static uint64_t gt_indirect_access_timer_offset(CPUARMState *env, int timeridx)
49
desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
68
{
50
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
69
/*
51
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
70
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_indirect_access_timer_offset(CPUARMState *env, int timeridx)
52
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
71
}
53
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (mte_n << msz) - 1);
72
}
54
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, sizem1);
73
55
desc <<= SVE_MTEDESC_SHIFT;
74
+uint64_t gt_direct_access_timer_offset(CPUARMState *env, int timeridx)
56
} else {
75
+{
57
addr = clean_data_tbi(s, addr);
76
+ /*
77
+ * Return the timer offset to use for direct accesses to the
78
+ * counter registers CNTPCT and CNTVCT, and for direct accesses
79
+ * to the CNT*_TVAL registers.
80
+ *
81
+ * This isn't exactly the same as the indirect-access offset,
82
+ * because here we also care about what EL the register access
83
+ * is being made from.
84
+ *
85
+ * This corresponds to the access pseudocode for the registers.
86
+ */
87
+ uint64_t hcr;
88
+
89
+ switch (timeridx) {
90
+ case GTIMER_PHYS:
91
+ if (arm_current_el(env) >= 2) {
92
+ return 0;
93
+ }
94
+ return gt_phys_raw_cnt_offset(env);
95
+ case GTIMER_VIRT:
96
+ switch (arm_current_el(env)) {
97
+ case 2:
98
+ hcr = arm_hcr_el2_eff(env);
99
+ if (hcr & HCR_E2H) {
100
+ return 0;
101
+ }
102
+ break;
103
+ case 0:
104
+ hcr = arm_hcr_el2_eff(env);
105
+ if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
106
+ return 0;
107
+ }
108
+ break;
109
+ }
110
+ return env->cp15.cntvoff_el2;
111
+ case GTIMER_HYP:
112
+ case GTIMER_SEC:
113
+ case GTIMER_HYPVIRT:
114
+ return 0;
115
+ default:
116
+ g_assert_not_reached();
117
+ }
118
+}
119
+
120
static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
121
{
122
ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx];
123
@@ -XXX,XX +XXX,XX @@ static void gt_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri,
124
125
static uint64_t gt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
126
{
127
- return gt_get_countervalue(env) - gt_phys_cnt_offset(env);
128
-}
129
-
130
-uint64_t gt_virt_cnt_offset(CPUARMState *env)
131
-{
132
- uint64_t hcr;
133
-
134
- switch (arm_current_el(env)) {
135
- case 2:
136
- hcr = arm_hcr_el2_eff(env);
137
- if (hcr & HCR_E2H) {
138
- return 0;
139
- }
140
- break;
141
- case 0:
142
- hcr = arm_hcr_el2_eff(env);
143
- if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
144
- return 0;
145
- }
146
- break;
147
- }
148
-
149
- return env->cp15.cntvoff_el2;
150
+ uint64_t offset = gt_direct_access_timer_offset(env, GTIMER_PHYS);
151
+ return gt_get_countervalue(env) - offset;
152
}
153
154
static uint64_t gt_virt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
155
{
156
- return gt_get_countervalue(env) - gt_virt_cnt_offset(env);
157
+ uint64_t offset = gt_direct_access_timer_offset(env, GTIMER_VIRT);
158
+ return gt_get_countervalue(env) - offset;
159
}
160
161
static void gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
162
@@ -XXX,XX +XXX,XX @@ static uint64_t do_tval_read(CPUARMState *env, int timeridx, uint64_t offset)
163
static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
164
int timeridx)
165
{
166
- uint64_t offset = 0;
167
-
168
- switch (timeridx) {
169
- case GTIMER_VIRT:
170
- offset = gt_virt_cnt_offset(env);
171
- break;
172
- case GTIMER_PHYS:
173
- offset = gt_phys_cnt_offset(env);
174
- break;
175
- }
176
+ uint64_t offset = gt_direct_access_timer_offset(env, timeridx);
177
178
return do_tval_read(env, timeridx, offset);
179
}
180
@@ -XXX,XX +XXX,XX @@ static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
181
int timeridx,
182
uint64_t value)
183
{
184
- uint64_t offset = 0;
185
+ uint64_t offset = gt_direct_access_timer_offset(env, timeridx);
186
187
- switch (timeridx) {
188
- case GTIMER_VIRT:
189
- offset = gt_virt_cnt_offset(env);
190
- break;
191
- case GTIMER_PHYS:
192
- offset = gt_phys_cnt_offset(env);
193
- break;
194
- }
195
do_tval_write(env, timeridx, value, offset);
196
}
197
198
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
199
index XXXXXXX..XXXXXXX 100644
200
--- a/target/arm/tcg/op_helper.c
201
+++ b/target/arm/tcg/op_helper.c
202
@@ -XXX,XX +XXX,XX @@ void HELPER(wfit)(CPUARMState *env, uint64_t timeout)
203
int target_el = check_wfx_trap(env, false, &excp);
204
/* The WFIT should time out when CNTVCT_EL0 >= the specified value. */
205
uint64_t cntval = gt_get_countervalue(env);
206
- uint64_t offset = gt_virt_cnt_offset(env);
207
+ /*
208
+ * We want the value that we would get if we read CNTVCT_EL0 from
209
+ * the current exception level, so the direct_access offset, not
210
+ * the indirect_access one. Compare the pseudocode LocalTimeoutEvent(),
211
+ * which calls VirtualCounterTimer().
212
+ */
213
+ uint64_t offset = gt_direct_access_timer_offset(env, GTIMER_VIRT);
214
uint64_t cntvct = cntval - offset;
215
uint64_t nexttick;
216
58
--
217
--
59
2.34.1
218
2.43.0
219
220
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
3
When FEAT_SEL2 was implemented the SEL2 timers were missed. This
4
shows up when building the latest Hafnium with SPMC_AT_EL=2. The
5
actual implementation utilises the same logic as the rest of the
6
timers so all we need to do is:
7
8
- define the timers and their access functions
9
- conditionally add the correct system registers
10
- create a new accessfn as the rules are subtly different to the
11
existing secure timer
12
13
Fixes: e9152ee91c (target/arm: add ARMv8.4-SEL2 system registers)
14
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20240213155214.13619-2-philmd@linaro.org
17
Message-id: 20250204125009.2281315-7-peter.maydell@linaro.org
18
Cc: qemu-stable@nongnu.org
19
Cc: Andrei Homescu <ahomescu@google.com>
20
Cc: Arve Hjønnevåg <arve@google.com>
21
Cc: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
22
[PMM: CP_ACCESS_TRAP_UNCATEGORIZED -> CP_ACCESS_UNDEFINED;
23
offset logic now in gt_{indirect,direct}_access_timer_offset() ]
24
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
26
---
8
hw/arm/stellaris.c | 6 ++++--
27
include/hw/arm/bsa.h | 2 +
9
1 file changed, 4 insertions(+), 2 deletions(-)
28
target/arm/cpu.h | 2 +
10
29
target/arm/gtimer.h | 4 +-
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
30
target/arm/cpu.c | 4 ++
12
index XXXXXXX..XXXXXXX 100644
31
target/arm/helper.c | 163 +++++++++++++++++++++++++++++++++++++++++++
13
--- a/hw/arm/stellaris.c
32
5 files changed, 174 insertions(+), 1 deletion(-)
14
+++ b/hw/arm/stellaris.c
33
15
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_trigger(void *opaque, int irq, int level)
34
diff --git a/include/hw/arm/bsa.h b/include/hw/arm/bsa.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/arm/bsa.h
37
+++ b/include/hw/arm/bsa.h
38
@@ -XXX,XX +XXX,XX @@
39
#define QEMU_ARM_BSA_H
40
41
/* These are architectural INTID values */
42
+#define ARCH_TIMER_S_EL2_VIRT_IRQ 19
43
+#define ARCH_TIMER_S_EL2_IRQ 20
44
#define VIRTUAL_PMU_IRQ 23
45
#define ARCH_GIC_MAINT_IRQ 25
46
#define ARCH_TIMER_NS_EL2_IRQ 26
47
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/cpu.h
50
+++ b/target/arm/cpu.h
51
@@ -XXX,XX +XXX,XX @@ void arm_gt_vtimer_cb(void *opaque);
52
void arm_gt_htimer_cb(void *opaque);
53
void arm_gt_stimer_cb(void *opaque);
54
void arm_gt_hvtimer_cb(void *opaque);
55
+void arm_gt_sel2timer_cb(void *opaque);
56
+void arm_gt_sel2vtimer_cb(void *opaque);
57
58
unsigned int gt_cntfrq_period_ns(ARMCPU *cpu);
59
void gt_rme_post_el_change(ARMCPU *cpu, void *opaque);
60
diff --git a/target/arm/gtimer.h b/target/arm/gtimer.h
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/gtimer.h
63
+++ b/target/arm/gtimer.h
64
@@ -XXX,XX +XXX,XX @@ enum {
65
GTIMER_HYP = 2,
66
GTIMER_SEC = 3,
67
GTIMER_HYPVIRT = 4,
68
-#define NUM_GTIMERS 5
69
+ GTIMER_S_EL2_PHYS = 5, /* CNTHPS_* ; only if FEAT_SEL2 */
70
+ GTIMER_S_EL2_VIRT = 6, /* CNTHVS_* ; only if FEAT_SEL2 */
71
+#define NUM_GTIMERS 7
72
};
73
74
#endif
75
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/arm/cpu.c
78
+++ b/target/arm/cpu.c
79
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
80
arm_gt_stimer_cb, cpu);
81
cpu->gt_timer[GTIMER_HYPVIRT] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
82
arm_gt_hvtimer_cb, cpu);
83
+ cpu->gt_timer[GTIMER_S_EL2_PHYS] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
84
+ arm_gt_sel2timer_cb, cpu);
85
+ cpu->gt_timer[GTIMER_S_EL2_VIRT] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
86
+ arm_gt_sel2vtimer_cb, cpu);
87
}
88
#endif
89
90
diff --git a/target/arm/helper.c b/target/arm/helper.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/helper.c
93
+++ b/target/arm/helper.c
94
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gt_stimer_access(CPUARMState *env,
16
}
95
}
17
}
96
}
18
97
19
-static void stellaris_adc_reset(StellarisADCState *s)
98
+static CPAccessResult gt_sel2timer_access(CPUARMState *env,
20
+static void stellaris_adc_reset_hold(Object *obj)
99
+ const ARMCPRegInfo *ri,
100
+ bool isread)
101
+{
102
+ /*
103
+ * The AArch64 register view of the secure EL2 timers are mostly
104
+ * accessible from EL3 and EL2 although can also be trapped to EL2
105
+ * from EL1 depending on nested virt config.
106
+ */
107
+ switch (arm_current_el(env)) {
108
+ case 0: /* UNDEFINED */
109
+ return CP_ACCESS_UNDEFINED;
110
+ case 1:
111
+ if (!arm_is_secure(env)) {
112
+ /* UNDEFINED */
113
+ return CP_ACCESS_UNDEFINED;
114
+ } else if (arm_hcr_el2_eff(env) & HCR_NV) {
115
+ /* Aarch64.SystemAccessTrap(EL2, 0x18) */
116
+ return CP_ACCESS_TRAP_EL2;
117
+ }
118
+ /* UNDEFINED */
119
+ return CP_ACCESS_UNDEFINED;
120
+ case 2:
121
+ if (!arm_is_secure(env)) {
122
+ /* UNDEFINED */
123
+ return CP_ACCESS_UNDEFINED;
124
+ }
125
+ return CP_ACCESS_OK;
126
+ case 3:
127
+ if (env->cp15.scr_el3 & SCR_EEL2) {
128
+ return CP_ACCESS_OK;
129
+ } else {
130
+ return CP_ACCESS_UNDEFINED;
131
+ }
132
+ default:
133
+ g_assert_not_reached();
134
+ }
135
+}
136
+
137
uint64_t gt_get_countervalue(CPUARMState *env)
21
{
138
{
22
+ StellarisADCState *s = STELLARIS_ADC(obj);
139
ARMCPU *cpu = env_archcpu(env);
23
int n;
140
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_indirect_access_timer_offset(CPUARMState *env, int timeridx)
24
141
case GTIMER_HYP:
25
for (n = 0; n < 4; n++) {
142
case GTIMER_SEC:
26
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_init(Object *obj)
143
case GTIMER_HYPVIRT:
27
memory_region_init_io(&s->iomem, obj, &stellaris_adc_ops, s,
144
+ case GTIMER_S_EL2_PHYS:
28
"adc", 0x1000);
145
+ case GTIMER_S_EL2_VIRT:
29
sysbus_init_mmio(sbd, &s->iomem);
146
return 0;
30
- stellaris_adc_reset(s);
147
default:
31
qdev_init_gpio_in(dev, stellaris_adc_trigger, 1);
148
g_assert_not_reached();
149
@@ -XXX,XX +XXX,XX @@ uint64_t gt_direct_access_timer_offset(CPUARMState *env, int timeridx)
150
case GTIMER_HYP:
151
case GTIMER_SEC:
152
case GTIMER_HYPVIRT:
153
+ case GTIMER_S_EL2_PHYS:
154
+ case GTIMER_S_EL2_VIRT:
155
return 0;
156
default:
157
g_assert_not_reached();
158
@@ -XXX,XX +XXX,XX @@ static void gt_sec_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
159
gt_ctl_write(env, ri, GTIMER_SEC, value);
32
}
160
}
33
161
34
@@ -XXX,XX +XXX,XX @@ static const TypeInfo stellaris_i2c_info = {
162
+static void gt_sec_pel2_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri)
35
static void stellaris_adc_class_init(ObjectClass *klass, void *data)
163
+{
164
+ gt_timer_reset(env, ri, GTIMER_S_EL2_PHYS);
165
+}
166
+
167
+static void gt_sec_pel2_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
168
+ uint64_t value)
169
+{
170
+ gt_cval_write(env, ri, GTIMER_S_EL2_PHYS, value);
171
+}
172
+
173
+static uint64_t gt_sec_pel2_tval_read(CPUARMState *env, const ARMCPRegInfo *ri)
174
+{
175
+ return gt_tval_read(env, ri, GTIMER_S_EL2_PHYS);
176
+}
177
+
178
+static void gt_sec_pel2_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
179
+ uint64_t value)
180
+{
181
+ gt_tval_write(env, ri, GTIMER_S_EL2_PHYS, value);
182
+}
183
+
184
+static void gt_sec_pel2_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
185
+ uint64_t value)
186
+{
187
+ gt_ctl_write(env, ri, GTIMER_S_EL2_PHYS, value);
188
+}
189
+
190
+static void gt_sec_vel2_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri)
191
+{
192
+ gt_timer_reset(env, ri, GTIMER_S_EL2_VIRT);
193
+}
194
+
195
+static void gt_sec_vel2_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
196
+ uint64_t value)
197
+{
198
+ gt_cval_write(env, ri, GTIMER_S_EL2_VIRT, value);
199
+}
200
+
201
+static uint64_t gt_sec_vel2_tval_read(CPUARMState *env, const ARMCPRegInfo *ri)
202
+{
203
+ return gt_tval_read(env, ri, GTIMER_S_EL2_VIRT);
204
+}
205
+
206
+static void gt_sec_vel2_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
207
+ uint64_t value)
208
+{
209
+ gt_tval_write(env, ri, GTIMER_S_EL2_VIRT, value);
210
+}
211
+
212
+static void gt_sec_vel2_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
213
+ uint64_t value)
214
+{
215
+ gt_ctl_write(env, ri, GTIMER_S_EL2_VIRT, value);
216
+}
217
+
218
static void gt_hv_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri)
36
{
219
{
37
DeviceClass *dc = DEVICE_CLASS(klass);
220
gt_timer_reset(env, ri, GTIMER_HYPVIRT);
38
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
221
@@ -XXX,XX +XXX,XX @@ void arm_gt_stimer_cb(void *opaque)
39
222
gt_recalc_timer(cpu, GTIMER_SEC);
40
+ rc->phases.hold = stellaris_adc_reset_hold;
41
dc->vmsd = &vmstate_stellaris_adc;
42
}
223
}
43
224
225
+void arm_gt_sel2timer_cb(void *opaque)
226
+{
227
+ ARMCPU *cpu = opaque;
228
+
229
+ gt_recalc_timer(cpu, GTIMER_S_EL2_PHYS);
230
+}
231
+
232
+void arm_gt_sel2vtimer_cb(void *opaque)
233
+{
234
+ ARMCPU *cpu = opaque;
235
+
236
+ gt_recalc_timer(cpu, GTIMER_S_EL2_VIRT);
237
+}
238
+
239
void arm_gt_hvtimer_cb(void *opaque)
240
{
241
ARMCPU *cpu = opaque;
242
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_sec_cp_reginfo[] = {
243
.access = PL2_RW, .accessfn = sel2_access,
244
.nv2_redirect_offset = 0x48,
245
.fieldoffset = offsetof(CPUARMState, cp15.vstcr_el2) },
246
+#ifndef CONFIG_USER_ONLY
247
+ /* Secure EL2 Physical Timer */
248
+ { .name = "CNTHPS_TVAL_EL2", .state = ARM_CP_STATE_AA64,
249
+ .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 5, .opc2 = 0,
250
+ .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL2_RW,
251
+ .accessfn = gt_sel2timer_access,
252
+ .readfn = gt_sec_pel2_tval_read,
253
+ .writefn = gt_sec_pel2_tval_write,
254
+ .resetfn = gt_sec_pel2_timer_reset,
255
+ },
256
+ { .name = "CNTHPS_CTL_EL2", .state = ARM_CP_STATE_AA64,
257
+ .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 5, .opc2 = 1,
258
+ .type = ARM_CP_IO, .access = PL2_RW,
259
+ .accessfn = gt_sel2timer_access,
260
+ .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_S_EL2_PHYS].ctl),
261
+ .resetvalue = 0,
262
+ .writefn = gt_sec_pel2_ctl_write, .raw_writefn = raw_write,
263
+ },
264
+ { .name = "CNTHPS_CVAL_EL2", .state = ARM_CP_STATE_AA64,
265
+ .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 5, .opc2 = 2,
266
+ .type = ARM_CP_IO, .access = PL2_RW,
267
+ .accessfn = gt_sel2timer_access,
268
+ .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_S_EL2_PHYS].cval),
269
+ .writefn = gt_sec_pel2_cval_write, .raw_writefn = raw_write,
270
+ },
271
+ /* Secure EL2 Virtual Timer */
272
+ { .name = "CNTHVS_TVAL_EL2", .state = ARM_CP_STATE_AA64,
273
+ .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 4, .opc2 = 0,
274
+ .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL2_RW,
275
+ .accessfn = gt_sel2timer_access,
276
+ .readfn = gt_sec_vel2_tval_read,
277
+ .writefn = gt_sec_vel2_tval_write,
278
+ .resetfn = gt_sec_vel2_timer_reset,
279
+ },
280
+ { .name = "CNTHVS_CTL_EL2", .state = ARM_CP_STATE_AA64,
281
+ .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 4, .opc2 = 1,
282
+ .type = ARM_CP_IO, .access = PL2_RW,
283
+ .accessfn = gt_sel2timer_access,
284
+ .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_S_EL2_VIRT].ctl),
285
+ .resetvalue = 0,
286
+ .writefn = gt_sec_vel2_ctl_write, .raw_writefn = raw_write,
287
+ },
288
+ { .name = "CNTHVS_CVAL_EL2", .state = ARM_CP_STATE_AA64,
289
+ .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 4, .opc2 = 2,
290
+ .type = ARM_CP_IO, .access = PL2_RW,
291
+ .accessfn = gt_sel2timer_access,
292
+ .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_S_EL2_VIRT].cval),
293
+ .writefn = gt_sec_vel2_cval_write, .raw_writefn = raw_write,
294
+ },
295
+#endif
296
};
297
298
static CPAccessResult nsacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
44
--
299
--
45
2.34.1
300
2.43.0
46
301
47
302
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
QDev objects created with qdev_new() need to manually add
3
As we are about to add more physical and virtual timers let's make it
4
their parent relationship with object_property_add_child().
4
clear what each timer does.
5
5
6
This commit plug the devices which aren't part of the SoC;
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
they will be plugged into a SoC container in the next one.
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20240213155214.13619-4-philmd@linaro.org
9
Message-id: 20250204125009.2281315-8-peter.maydell@linaro.org
10
[PMM: Add timer register name prefix to each comment]
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
13
---
14
hw/arm/stellaris.c | 4 ++++
14
target/arm/gtimer.h | 10 +++++-----
15
1 file changed, 4 insertions(+)
15
1 file changed, 5 insertions(+), 5 deletions(-)
16
16
17
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
17
diff --git a/target/arm/gtimer.h b/target/arm/gtimer.h
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/stellaris.c
19
--- a/target/arm/gtimer.h
20
+++ b/hw/arm/stellaris.c
20
+++ b/target/arm/gtimer.h
21
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
21
@@ -XXX,XX +XXX,XX @@
22
&error_fatal);
22
#define TARGET_ARM_GTIMER_H
23
23
24
ssddev = qdev_new("ssd0323");
24
enum {
25
+ object_property_add_child(OBJECT(ms), "oled", OBJECT(ssddev));
25
- GTIMER_PHYS = 0,
26
qdev_prop_set_uint8(ssddev, "cs", 1);
26
- GTIMER_VIRT = 1,
27
qdev_realize_and_unref(ssddev, bus, &error_fatal);
27
- GTIMER_HYP = 2,
28
28
- GTIMER_SEC = 3,
29
gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
29
- GTIMER_HYPVIRT = 4,
30
+ object_property_add_child(OBJECT(ms), "splitter",
30
+ GTIMER_PHYS = 0, /* CNTP_* ; EL1 physical timer */
31
+ OBJECT(gpio_d_splitter));
31
+ GTIMER_VIRT = 1, /* CNTV_* ; EL1 virtual timer */
32
qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
32
+ GTIMER_HYP = 2, /* CNTHP_* ; EL2 physical timer */
33
qdev_realize_and_unref(gpio_d_splitter, NULL, &error_fatal);
33
+ GTIMER_SEC = 3, /* CNTPS_* ; EL3 physical timer */
34
qdev_connect_gpio_out(
34
+ GTIMER_HYPVIRT = 4, /* CNTHV_* ; EL2 virtual timer ; only if FEAT_VHE */
35
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
35
GTIMER_S_EL2_PHYS = 5, /* CNTHPS_* ; only if FEAT_SEL2 */
36
DeviceState *gpad;
36
GTIMER_S_EL2_VIRT = 6, /* CNTHVS_* ; only if FEAT_SEL2 */
37
37
#define NUM_GTIMERS 7
38
gpad = qdev_new(TYPE_STELLARIS_GAMEPAD);
39
+ object_property_add_child(OBJECT(ms), "gamepad", OBJECT(gpad));
40
for (i = 0; i < ARRAY_SIZE(gpad_keycode); i++) {
41
qlist_append_int(gpad_keycode_list, gpad_keycode[i]);
42
}
43
--
38
--
44
2.34.1
39
2.43.0
45
40
46
41
diff view generated by jsdifflib
1
Armv8.1+ CPUs have the Virtual Host Extension (VHE) which adds a
1
From: Alex Bennée <alex.bennee@linaro.org>
2
non-secure EL2 virtual timer. We implemented the timer itself in the
3
CPU model, but never wired up its IRQ line to the GIC.
4
2
5
Wire up the IRQ line (this is always safe whether the CPU has the
3
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
6
interrupt or not, since it always creates the outbound IRQ line).
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Report it to the guest via dtb and ACPI if the CPU has the feature.
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Message-id: 20250204125009.2281315-9-peter.maydell@linaro.org
7
Cc: qemu-stable@nongnu.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/arm/virt.c | 2 ++
12
1 file changed, 2 insertions(+)
8
13
9
The DTB binding is documented in the kernel's
10
Documentation/devicetree/bindings/timer/arm\,arch_timer.yaml
11
and the ACPI table entries are documented in the ACPI specification
12
version 6.3 or later.
13
14
Because the IRQ line ACPI binding is new in 6.3, we need to bump the
15
FADT table rev to show that we might be using 6.3 features.
16
17
Note that exposing this IRQ in the DTB will trigger a bug in EDK2
18
versions prior to edk2-stable202311, for users who use the virt board
19
with 'virtualization=on' to enable EL2 emulation and are booting an
20
EDK2 guest BIOS, if that EDK2 has assertions enabled. The effect is
21
that EDK2 will assert on bootup:
22
23
ASSERT [ArmTimerDxe] /home/kraxel/projects/qemu/roms/edk2/ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.c(72): PropSize == 36 || PropSize == 48
24
25
If you see that assertion you should do one of:
26
* update your EDK2 binaries to edk2-stable202311 or newer
27
* use the 'virt-8.2' versioned machine type
28
* not use 'virtualization=on'
29
30
(The versions shipped with QEMU itself have the fix.)
31
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
34
Message-id: 20240122143537.233498-3-peter.maydell@linaro.org
35
---
36
include/hw/arm/virt.h | 2 ++
37
hw/arm/virt-acpi-build.c | 20 ++++++++++----
38
hw/arm/virt.c | 60 ++++++++++++++++++++++++++++++++++------
39
3 files changed, 67 insertions(+), 15 deletions(-)
40
41
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
42
index XXXXXXX..XXXXXXX 100644
43
--- a/include/hw/arm/virt.h
44
+++ b/include/hw/arm/virt.h
45
@@ -XXX,XX +XXX,XX @@ struct VirtMachineClass {
46
/* Machines < 6.2 have no support for describing cpu topology to guest */
47
bool no_cpu_topology;
48
bool no_tcg_lpa2;
49
+ bool no_ns_el2_virt_timer_irq;
50
};
51
52
struct VirtMachineState {
53
@@ -XXX,XX +XXX,XX @@ struct VirtMachineState {
54
PCIBus *bus;
55
char *oem_id;
56
char *oem_table_id;
57
+ bool ns_el2_virt_timer_irq;
58
};
59
60
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
61
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/virt-acpi-build.c
64
+++ b/hw/arm/virt-acpi-build.c
65
@@ -XXX,XX +XXX,XX @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
66
}
67
68
/*
69
- * ACPI spec, Revision 5.1
70
- * 5.2.24 Generic Timer Description Table (GTDT)
71
+ * ACPI spec, Revision 6.5
72
+ * 5.2.25 Generic Timer Description Table (GTDT)
73
*/
74
static void
75
build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
76
@@ -XXX,XX +XXX,XX @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
77
uint32_t irqflags = vmc->claim_edge_triggered_timers ?
78
1 : /* Interrupt is Edge triggered */
79
0; /* Interrupt is Level triggered */
80
- AcpiTable table = { .sig = "GTDT", .rev = 2, .oem_id = vms->oem_id,
81
+ AcpiTable table = { .sig = "GTDT", .rev = 3, .oem_id = vms->oem_id,
82
.oem_table_id = vms->oem_table_id };
83
84
acpi_table_begin(&table, table_data);
85
@@ -XXX,XX +XXX,XX @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
86
build_append_int_noprefix(table_data, 0, 4);
87
/* Platform Timer Offset */
88
build_append_int_noprefix(table_data, 0, 4);
89
-
90
+ if (vms->ns_el2_virt_timer_irq) {
91
+ /* Virtual EL2 Timer GSIV */
92
+ build_append_int_noprefix(table_data, ARCH_TIMER_NS_EL2_VIRT_IRQ, 4);
93
+ /* Virtual EL2 Timer Flags */
94
+ build_append_int_noprefix(table_data, irqflags, 4);
95
+ } else {
96
+ build_append_int_noprefix(table_data, 0, 4);
97
+ build_append_int_noprefix(table_data, 0, 4);
98
+ }
99
acpi_table_end(linker, &table);
100
}
101
102
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
103
static void build_fadt_rev6(GArray *table_data, BIOSLinker *linker,
104
VirtMachineState *vms, unsigned dsdt_tbl_offset)
105
{
106
- /* ACPI v6.0 */
107
+ /* ACPI v6.3 */
108
AcpiFadtData fadt = {
109
.rev = 6,
110
- .minor_ver = 0,
111
+ .minor_ver = 3,
112
.flags = 1 << ACPI_FADT_F_HW_REDUCED_ACPI,
113
.xdsdt_tbl_offset = &dsdt_tbl_offset,
114
};
115
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
14
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
116
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
117
--- a/hw/arm/virt.c
16
--- a/hw/arm/virt.c
118
+++ b/hw/arm/virt.c
17
+++ b/hw/arm/virt.c
119
@@ -XXX,XX +XXX,XX @@ static void create_randomness(MachineState *ms, const char *node)
120
qemu_fdt_setprop(ms->fdt, node, "rng-seed", seed.rng, sizeof(seed.rng));
121
}
122
123
+/*
124
+ * The CPU object always exposes the NS EL2 virt timer IRQ line,
125
+ * but we don't want to advertise it to the guest in the dtb or ACPI
126
+ * table unless it's really going to do something.
127
+ */
128
+static bool ns_el2_virt_timer_present(void)
129
+{
130
+ ARMCPU *cpu = ARM_CPU(qemu_get_cpu(0));
131
+ CPUARMState *env = &cpu->env;
132
+
133
+ return arm_feature(env, ARM_FEATURE_AARCH64) &&
134
+ arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu);
135
+}
136
+
137
static void create_fdt(VirtMachineState *vms)
138
{
139
MachineState *ms = MACHINE(vms);
140
@@ -XXX,XX +XXX,XX @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
141
"arm,armv7-timer");
142
}
143
qemu_fdt_setprop(ms->fdt, "/timer", "always-on", NULL, 0);
144
- qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
145
- GIC_FDT_IRQ_TYPE_PPI,
146
- INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
147
- GIC_FDT_IRQ_TYPE_PPI,
148
- INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
149
- GIC_FDT_IRQ_TYPE_PPI,
150
- INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
151
- GIC_FDT_IRQ_TYPE_PPI,
152
- INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
153
+ if (vms->ns_el2_virt_timer_irq) {
154
+ qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
155
+ GIC_FDT_IRQ_TYPE_PPI,
156
+ INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
157
+ GIC_FDT_IRQ_TYPE_PPI,
158
+ INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
159
+ GIC_FDT_IRQ_TYPE_PPI,
160
+ INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
161
+ GIC_FDT_IRQ_TYPE_PPI,
162
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags,
163
+ GIC_FDT_IRQ_TYPE_PPI,
164
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_VIRT_IRQ), irqflags);
165
+ } else {
166
+ qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
167
+ GIC_FDT_IRQ_TYPE_PPI,
168
+ INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
169
+ GIC_FDT_IRQ_TYPE_PPI,
170
+ INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
171
+ GIC_FDT_IRQ_TYPE_PPI,
172
+ INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
173
+ GIC_FDT_IRQ_TYPE_PPI,
174
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
175
+ }
176
}
177
178
static void fdt_add_cpu_nodes(const VirtMachineState *vms)
179
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
18
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
180
[GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
181
[GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
19
[GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
182
[GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
20
[GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
183
+ [GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
21
[GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
22
+ [GTIMER_S_EL2_PHYS] = ARCH_TIMER_S_EL2_IRQ,
23
+ [GTIMER_S_EL2_VIRT] = ARCH_TIMER_S_EL2_VIRT_IRQ,
184
};
24
};
185
25
186
for (unsigned irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
26
for (unsigned irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
187
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
188
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
189
object_unref(cpuobj);
190
}
191
+
192
+ /* Now we've created the CPUs we can see if they have the hypvirt timer */
193
+ vms->ns_el2_virt_timer_irq = ns_el2_virt_timer_present() &&
194
+ !vmc->no_ns_el2_virt_timer_irq;
195
+
196
fdt_add_timer_nodes(vms);
197
fdt_add_cpu_nodes(vms);
198
199
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(9, 0)
200
201
static void virt_machine_8_2_options(MachineClass *mc)
202
{
203
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
204
+
205
virt_machine_9_0_options(mc);
206
compat_props_add(mc->compat_props, hw_compat_8_2, hw_compat_8_2_len);
207
+ /*
208
+ * Don't expose NS_EL2_VIRT timer IRQ in DTB on ACPI on 8.2 and
209
+ * earlier machines. (Exposing it tickles a bug in older EDK2
210
+ * guest BIOS binaries.)
211
+ */
212
+ vmc->no_ns_el2_virt_timer_irq = true;
213
}
214
DEFINE_VIRT_MACHINE(8, 2)
215
216
--
27
--
217
2.34.1
28
2.43.0
29
30
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
Similarly to commits dadbb58f59..5ae79fe825 for other ARM boards,
3
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
4
connect FIQ output of the GIC CPU interfaces to the CPU.
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20240130152548.17855-1-philmd@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Message-id: 20250204125009.2281315-10-peter.maydell@linaro.org
7
Cc: qemu-stable@nongnu.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
hw/arm/xilinx_zynq.c | 2 ++
10
hw/arm/sbsa-ref.c | 2 ++
12
1 file changed, 2 insertions(+)
11
1 file changed, 2 insertions(+)
13
12
14
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
13
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xilinx_zynq.c
15
--- a/hw/arm/sbsa-ref.c
17
+++ b/hw/arm/xilinx_zynq.c
16
+++ b/hw/arm/sbsa-ref.c
18
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
17
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, MemoryRegion *mem)
19
sysbus_mmio_map(busdev, 0, MPCORE_PERIPHBASE);
18
[GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
20
sysbus_connect_irq(busdev, 0,
19
[GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
21
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
20
[GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
22
+ sysbus_connect_irq(busdev, 1,
21
+ [GTIMER_S_EL2_PHYS] = ARCH_TIMER_S_EL2_IRQ,
23
+ qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ));
22
+ [GTIMER_S_EL2_VIRT] = ARCH_TIMER_S_EL2_VIRT_IRQ,
24
23
};
25
for (n = 0; n < 64; n++) {
24
26
pic[n] = qdev_get_gpio_in(dev, n);
25
for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
27
--
26
--
28
2.34.1
27
2.43.0
29
28
30
29
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
The API does not generate an error for setting ASYNC | SYNC; that merely
4
constrains the selection vs the per-cpu default. For qemu linux-user,
5
choose SYNC as the default.
6
7
Cc: qemu-stable@nongnu.org
8
Reported-by: Gustavo Romero <gustavo.romero@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
11
Message-id: 20240207025210.8837-2-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
linux-user/aarch64/target_prctl.h | 29 +++++++++++++++++------------
15
1 file changed, 17 insertions(+), 12 deletions(-)
16
17
diff --git a/linux-user/aarch64/target_prctl.h b/linux-user/aarch64/target_prctl.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/linux-user/aarch64/target_prctl.h
20
+++ b/linux-user/aarch64/target_prctl.h
21
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_set_tagged_addr_ctrl(CPUArchState *env, abi_long arg2)
22
env->tagged_addr_enable = arg2 & PR_TAGGED_ADDR_ENABLE;
23
24
if (cpu_isar_feature(aa64_mte, cpu)) {
25
- switch (arg2 & PR_MTE_TCF_MASK) {
26
- case PR_MTE_TCF_NONE:
27
- case PR_MTE_TCF_SYNC:
28
- case PR_MTE_TCF_ASYNC:
29
- break;
30
- default:
31
- return -EINVAL;
32
- }
33
-
34
/*
35
* Write PR_MTE_TCF to SCTLR_EL1[TCF0].
36
- * Note that the syscall values are consistent with hw.
37
+ *
38
+ * The kernel has a per-cpu configuration for the sysadmin,
39
+ * /sys/devices/system/cpu/cpu<N>/mte_tcf_preferred,
40
+ * which qemu does not implement.
41
+ *
42
+ * Because there is no performance difference between the modes, and
43
+ * because SYNC is most useful for debugging MTE errors, choose SYNC
44
+ * as the preferred mode. With this preference, and the way the API
45
+ * uses only two bits, there is no way for the program to select
46
+ * ASYMM mode.
47
*/
48
- env->cp15.sctlr_el[1] =
49
- deposit64(env->cp15.sctlr_el[1], 38, 2, arg2 >> PR_MTE_TCF_SHIFT);
50
+ unsigned tcf = 0;
51
+ if (arg2 & PR_MTE_TCF_SYNC) {
52
+ tcf = 1;
53
+ } else if (arg2 & PR_MTE_TCF_ASYNC) {
54
+ tcf = 2;
55
+ }
56
+ env->cp15.sctlr_el[1] = deposit64(env->cp15.sctlr_el[1], 38, 2, tcf);
57
58
/*
59
* Write PR_MTE_TAG to GCR_EL1[Exclude].
60
--
61
2.34.1
diff view generated by jsdifflib
1
Create the CPUs, the GIC, and the per-CPU RAM block for
1
Our LDRD implementation is wrong in two respects:
2
the mps3-an536 board.
3
2
3
* if the address is 4-aligned and the load crosses a page boundary
4
and the second load faults and the first load was to the
5
base register (as in cases like "ldrd r2, r3, [r2]", then we
6
must not update the base register before taking the fault
7
* if the address is 8-aligned the access must be a 64-bit
8
single-copy atomic access, not two 32-bit accesses
9
10
Rewrite the handling of the loads in LDRD to use a single
11
tcg_gen_qemu_ld_i64() and split the result into the destination
12
registers. This allows us to get the atomicity requirements
13
right, and also implicitly means that we won't update the
14
base register too early for the page-crossing case.
15
16
Note that because we no longer increment 'addr' by 4 in the course of
17
performing the LDRD we must change the adjustment value we pass to
18
op_addr_ri_post() and op_addr_rr_post(): it no longer needs to
19
subtract 4 to get the correct value to use if doing base register
20
writeback.
21
22
STRD has the same problem with not getting the atomicity right;
23
we will deal with that in the following commit.
24
25
Cc: qemu-stable@nongnu.org
26
Reported-by: Stu Grossman <stu.grossman@gmail.com>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20240206132931.38376-10-peter.maydell@linaro.org
28
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Message-id: 20250227142746.1698904-2-peter.maydell@linaro.org
6
---
30
---
7
hw/arm/mps3r.c | 180 ++++++++++++++++++++++++++++++++++++++++++++++++-
31
target/arm/tcg/translate.c | 70 +++++++++++++++++++++++++-------------
8
1 file changed, 177 insertions(+), 3 deletions(-)
32
1 file changed, 46 insertions(+), 24 deletions(-)
9
33
10
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
34
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
11
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/arm/mps3r.c
36
--- a/target/arm/tcg/translate.c
13
+++ b/hw/arm/mps3r.c
37
+++ b/target/arm/tcg/translate.c
14
@@ -XXX,XX +XXX,XX @@
38
@@ -XXX,XX +XXX,XX @@ static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
15
#include "qemu/osdep.h"
39
return true;
16
#include "qemu/units.h"
17
#include "qapi/error.h"
18
+#include "qapi/qmp/qlist.h"
19
#include "exec/address-spaces.h"
20
#include "cpu.h"
21
#include "hw/boards.h"
22
+#include "hw/qdev-properties.h"
23
#include "hw/arm/boot.h"
24
+#include "hw/arm/bsa.h"
25
+#include "hw/intc/arm_gicv3.h"
26
27
/* Define the layout of RAM and ROM in a board */
28
typedef struct RAMInfo {
29
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
30
#define IS_ROM 2
31
32
#define MPS3R_RAM_MAX 9
33
+#define MPS3R_CPU_MAX 2
34
+
35
+#define PERIPHBASE 0xf0000000
36
+#define NUM_SPIS 96
37
38
typedef enum MPS3RFPGAType {
39
FPGA_AN536,
40
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineClass {
41
MachineClass parent;
42
MPS3RFPGAType fpga_type;
43
const RAMInfo *raminfo;
44
+ hwaddr loader_start;
45
};
46
47
struct MPS3RMachineState {
48
MachineState parent;
49
+ struct arm_boot_info bootinfo;
50
MemoryRegion ram[MPS3R_RAM_MAX];
51
+ Object *cpu[MPS3R_CPU_MAX];
52
+ MemoryRegion cpu_sysmem[MPS3R_CPU_MAX];
53
+ MemoryRegion sysmem_alias[MPS3R_CPU_MAX];
54
+ MemoryRegion cpu_ram[MPS3R_CPU_MAX];
55
+ GICv3State gic;
56
};
57
58
#define TYPE_MPS3R_MACHINE "mps3r"
59
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
60
return ram;
61
}
40
}
62
41
63
+/*
42
+static void do_ldrd_load(DisasContext *s, TCGv_i32 addr, int rt, int rt2)
64
+ * There is no defined secondary boot protocol for Linux for the AN536,
65
+ * because real hardware has a restriction that atomic operations between
66
+ * the two CPUs do not function correctly, and so true SMP is not
67
+ * possible. Therefore for cases where the user is directly booting
68
+ * a kernel, we treat the system as essentially uniprocessor, and
69
+ * put the secondary CPU into power-off state (as if the user on the
70
+ * real hardware had configured the secondary to be halted via the
71
+ * SCC config registers).
72
+ *
73
+ * Note that the default secondary boot code would not work here anyway
74
+ * as it assumes a GICv2, and we have a GICv3.
75
+ */
76
+static void mps3r_write_secondary_boot(ARMCPU *cpu,
77
+ const struct arm_boot_info *info)
78
+{
43
+{
79
+ /*
44
+ /*
80
+ * Power the secondary CPU off. This means we don't need to write any
45
+ * LDRD is required to be an atomic 64-bit access if the
81
+ * boot code into guest memory. Note that the 'cpu' argument to this
46
+ * address is 8-aligned, two atomic 32-bit accesses if
82
+ * function is the primary CPU we passed to arm_load_kernel(), not
47
+ * it's only 4-aligned, and to give an alignment fault
83
+ * the secondary. Loop around all the other CPUs, as the boot.c
48
+ * if it's not 4-aligned. This is MO_ALIGN_4 | MO_ATOM_SUBALIGN.
84
+ * code does for the "disable secondaries if PSCI is enabled" case.
49
+ * Rt is always the word from the lower address, and Rt2 the
50
+ * data from the higher address, regardless of endianness.
51
+ * So (like gen_load_exclusive) we avoid gen_aa32_ld_i64()
52
+ * so we don't get its SCTLR_B check, and instead do a 64-bit access
53
+ * using MO_BE if appropriate and then split the two halves.
54
+ *
55
+ * For M-profile, and for A-profile before LPAE, the 64-bit
56
+ * atomicity is not required. We could model that using
57
+ * the looser MO_ATOM_IFALIGN_PAIR, but providing a higher
58
+ * level of atomicity than required is harmless (we would not
59
+ * currently generate better code for IFALIGN_PAIR here).
60
+ *
61
+ * This also gives us the correct behaviour of not updating
62
+ * rt if the load of rt2 faults; this is required for cases
63
+ * like "ldrd r2, r3, [r2]" where rt is also the base register.
85
+ */
64
+ */
86
+ for (CPUState *cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
65
+ int mem_idx = get_mem_index(s);
87
+ if (cs != first_cpu) {
66
+ MemOp opc = MO_64 | MO_ALIGN_4 | MO_ATOM_SUBALIGN | s->be_data;
88
+ object_property_set_bool(OBJECT(cs), "start-powered-off", true,
67
+ TCGv taddr = gen_aa32_addr(s, addr, opc);
89
+ &error_abort);
68
+ TCGv_i64 t64 = tcg_temp_new_i64();
90
+ }
69
+ TCGv_i32 tmp = tcg_temp_new_i32();
70
+ TCGv_i32 tmp2 = tcg_temp_new_i32();
71
+
72
+ tcg_gen_qemu_ld_i64(t64, taddr, mem_idx, opc);
73
+ if (s->be_data == MO_BE) {
74
+ tcg_gen_extr_i64_i32(tmp2, tmp, t64);
75
+ } else {
76
+ tcg_gen_extr_i64_i32(tmp, tmp2, t64);
91
+ }
77
+ }
78
+ store_reg(s, rt, tmp);
79
+ store_reg(s, rt2, tmp2);
92
+}
80
+}
93
+
81
+
94
+static void mps3r_secondary_cpu_reset(ARMCPU *cpu,
82
static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
95
+ const struct arm_boot_info *info)
96
+{
97
+ /* We don't need to do anything here because the CPU will be off */
98
+}
99
+
100
+static void create_gic(MPS3RMachineState *mms, MemoryRegion *sysmem)
101
+{
102
+ MachineState *machine = MACHINE(mms);
103
+ DeviceState *gicdev;
104
+ QList *redist_region_count;
105
+
106
+ object_initialize_child(OBJECT(mms), "gic", &mms->gic, TYPE_ARM_GICV3);
107
+ gicdev = DEVICE(&mms->gic);
108
+ qdev_prop_set_uint32(gicdev, "num-cpu", machine->smp.cpus);
109
+ qdev_prop_set_uint32(gicdev, "num-irq", NUM_SPIS + GIC_INTERNAL);
110
+ redist_region_count = qlist_new();
111
+ qlist_append_int(redist_region_count, machine->smp.cpus);
112
+ qdev_prop_set_array(gicdev, "redist-region-count", redist_region_count);
113
+ object_property_set_link(OBJECT(&mms->gic), "sysmem",
114
+ OBJECT(sysmem), &error_fatal);
115
+ sysbus_realize(SYS_BUS_DEVICE(&mms->gic), &error_fatal);
116
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->gic), 0, PERIPHBASE);
117
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->gic), 1, PERIPHBASE + 0x100000);
118
+ /*
119
+ * Wire the outputs from each CPU's generic timer and the GICv3
120
+ * maintenance interrupt signal to the appropriate GIC PPI inputs,
121
+ * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inputs.
122
+ */
123
+ for (int i = 0; i < machine->smp.cpus; i++) {
124
+ DeviceState *cpudev = DEVICE(mms->cpu[i]);
125
+ SysBusDevice *gicsbd = SYS_BUS_DEVICE(&mms->gic);
126
+ int intidbase = NUM_SPIS + i * GIC_INTERNAL;
127
+ int irq;
128
+ /*
129
+ * Mapping from the output timer irq lines from the CPU to the
130
+ * GIC PPI inputs used for this board. This isn't a BSA board,
131
+ * but it uses the standard convention for the PPI numbers.
132
+ */
133
+ const int timer_irq[] = {
134
+ [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ,
135
+ [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
136
+ [GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
137
+ };
138
+
139
+ for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
140
+ qdev_connect_gpio_out(cpudev, irq,
141
+ qdev_get_gpio_in(gicdev,
142
+ intidbase + timer_irq[irq]));
143
+ }
144
+
145
+ qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 0,
146
+ qdev_get_gpio_in(gicdev,
147
+ intidbase + ARCH_GIC_MAINT_IRQ));
148
+
149
+ qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
150
+ qdev_get_gpio_in(gicdev,
151
+ intidbase + VIRTUAL_PMU_IRQ));
152
+
153
+ sysbus_connect_irq(gicsbd, i,
154
+ qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
155
+ sysbus_connect_irq(gicsbd, i + machine->smp.cpus,
156
+ qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
157
+ sysbus_connect_irq(gicsbd, i + 2 * machine->smp.cpus,
158
+ qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
159
+ sysbus_connect_irq(gicsbd, i + 3 * machine->smp.cpus,
160
+ qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
161
+ }
162
+}
163
+
164
static void mps3r_common_init(MachineState *machine)
165
{
83
{
166
MPS3RMachineState *mms = MPS3R_MACHINE(machine);
84
- int mem_idx = get_mem_index(s);
167
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
85
- TCGv_i32 addr, tmp;
168
MemoryRegion *mr = mr_for_raminfo(mms, ri);
86
+ TCGv_i32 addr;
169
memory_region_add_subregion(sysmem, ri->base, mr);
87
88
if (!ENABLE_ARCH_5TE) {
89
return false;
90
@@ -XXX,XX +XXX,XX @@ static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
170
}
91
}
171
+
92
addr = op_addr_rr_pre(s, a);
172
+ assert(machine->smp.cpus <= MPS3R_CPU_MAX);
93
173
+ for (int i = 0; i < machine->smp.cpus; i++) {
94
- tmp = tcg_temp_new_i32();
174
+ g_autofree char *sysmem_name = g_strdup_printf("cpu-%d-memory", i);
95
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
175
+ g_autofree char *ramname = g_strdup_printf("cpu-%d-memory", i);
96
- store_reg(s, a->rt, tmp);
176
+ g_autofree char *alias_name = g_strdup_printf("sysmem-alias-%d", i);
97
-
177
+
98
- tcg_gen_addi_i32(addr, addr, 4);
178
+ /*
99
-
179
+ * Each CPU has some private RAM/peripherals, so create the container
100
- tmp = tcg_temp_new_i32();
180
+ * which will house those, with the whole-machine system memory being
101
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
181
+ * used where there's no CPU-specific device. Note that we need the
102
- store_reg(s, a->rt + 1, tmp);
182
+ * sysmem_alias aliases because we can't put one MR (the original
103
+ do_ldrd_load(s, addr, a->rt, a->rt + 1);
183
+ * 'sysmem') into more than one other MR.
104
184
+ */
105
/* LDRD w/ base writeback is undefined if the registers overlap. */
185
+ memory_region_init(&mms->cpu_sysmem[i], OBJECT(machine),
106
- op_addr_rr_post(s, a, addr, -4);
186
+ sysmem_name, UINT64_MAX);
107
+ op_addr_rr_post(s, a, addr, 0);
187
+ memory_region_init_alias(&mms->sysmem_alias[i], OBJECT(machine),
108
return true;
188
+ alias_name, sysmem, 0, UINT64_MAX);
189
+ memory_region_add_subregion_overlap(&mms->cpu_sysmem[i], 0,
190
+ &mms->sysmem_alias[i], -1);
191
+
192
+ mms->cpu[i] = object_new(machine->cpu_type);
193
+ object_property_set_link(mms->cpu[i], "memory",
194
+ OBJECT(&mms->cpu_sysmem[i]), &error_abort);
195
+ object_property_set_int(mms->cpu[i], "reset-cbar",
196
+ PERIPHBASE, &error_abort);
197
+ qdev_realize(DEVICE(mms->cpu[i]), NULL, &error_fatal);
198
+ object_unref(mms->cpu[i]);
199
+
200
+ /* Per-CPU RAM */
201
+ memory_region_init_ram(&mms->cpu_ram[i], NULL, ramname,
202
+ 0x1000, &error_fatal);
203
+ memory_region_add_subregion(&mms->cpu_sysmem[i], 0xe7c01000,
204
+ &mms->cpu_ram[i]);
205
+ }
206
+
207
+ create_gic(mms, sysmem);
208
+
209
+ mms->bootinfo.ram_size = machine->ram_size;
210
+ mms->bootinfo.board_id = -1;
211
+ mms->bootinfo.loader_start = mmc->loader_start;
212
+ mms->bootinfo.write_secondary_boot = mps3r_write_secondary_boot;
213
+ mms->bootinfo.secondary_cpu_reset_hook = mps3r_secondary_cpu_reset;
214
+ arm_load_kernel(ARM_CPU(mms->cpu[0]), machine, &mms->bootinfo);
215
}
109
}
216
110
217
static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
111
@@ -XXX,XX +XXX,XX @@ static bool op_store_ri(DisasContext *s, arg_ldst_ri *a,
218
@@ -XXX,XX +XXX,XX @@ static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
112
219
/* Found the entry for "system memory" */
113
static bool op_ldrd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
220
mc->default_ram_size = p->size;
114
{
221
mc->default_ram_id = p->name;
115
- int mem_idx = get_mem_index(s);
222
+ mmc->loader_start = p->base;
116
- TCGv_i32 addr, tmp;
223
return;
117
+ TCGv_i32 addr;
224
}
118
225
}
119
addr = op_addr_ri_pre(s, a);
226
@@ -XXX,XX +XXX,XX @@ static void mps3r_an536_class_init(ObjectClass *oc, void *data)
120
227
};
121
- tmp = tcg_temp_new_i32();
228
122
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
229
mc->desc = "ARM MPS3 with AN536 FPGA image for Cortex-R52";
123
- store_reg(s, a->rt, tmp);
230
- mc->default_cpus = 2;
124
-
231
- mc->min_cpus = mc->default_cpus;
125
- tcg_gen_addi_i32(addr, addr, 4);
232
- mc->max_cpus = mc->default_cpus;
126
-
233
+ /*
127
- tmp = tcg_temp_new_i32();
234
+ * In the real FPGA image there are always two cores, but the standard
128
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
235
+ * initial setting for the SCC SYSCON 0x000 register is 0x21, meaning
129
- store_reg(s, rt2, tmp);
236
+ * that the second core is held in reset and halted. Many images built for
130
+ do_ldrd_load(s, addr, a->rt, rt2);
237
+ * the board do not expect the second core to run at startup (especially
131
238
+ * since on the real FPGA image it is not possible to use LDREX/STREX
132
/* LDRD w/ base writeback is undefined if the registers overlap. */
239
+ * in RAM between the two cores, so a true SMP setup isn't supported).
133
- op_addr_ri_post(s, a, addr, -4);
240
+ *
134
+ op_addr_ri_post(s, a, addr, 0);
241
+ * As QEMU's equivalent of this, we support both -smp 1 and -smp 2,
135
return true;
242
+ * with the default being -smp 1. This seems a more intuitive UI for
136
}
243
+ * QEMU users than, for instance, having a machine property to allow
137
244
+ * the user to set the initial value of the SYSCON 0x000 register.
245
+ */
246
+ mc->default_cpus = 1;
247
+ mc->min_cpus = 1;
248
+ mc->max_cpus = 2;
249
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-r52");
250
mc->valid_cpu_types = valid_cpu_types;
251
mmc->raminfo = an536_raminfo;
252
--
138
--
253
2.34.1
139
2.43.0
diff view generated by jsdifflib
1
Architecturally, the AArch32 MSR/MRS to/from banked register
1
Our STRD implementation doesn't correctly implement the requirement:
2
instructions are UNPREDICTABLE for attempts to access a banked
2
* if the address is 8-aligned the access must be a 64-bit
3
register that the guest could access in a more direct way (e.g.
3
single-copy atomic access, not two 32-bit accesses
4
using this insn to access r8_fiq when already in FIQ mode). QEMU has
5
chosen to UNDEF on all of these.
6
4
7
However, for the case of accessing SPSR_hyp from hyp mode, it turns
5
Rewrite the handling of STRD to use a single tcg_gen_qemu_st_i64()
8
out that real hardware permits this, with the same effect as if the
6
of a value produced by concatenating the two 32 bit source registers.
9
guest had directly written to SPSR. Further, there is some
7
This allows us to get the atomicity right.
10
guest code out there that assumes it can do this, because it
11
happens to work on hardware: an example Cortex-R52 startup code
12
fragment uses this, and it got copied into various other places,
13
including Zephyr. Zephyr was fixed to not use this:
14
https://github.com/zephyrproject-rtos/zephyr/issues/47330
15
but other examples are still out there, like the selftest
16
binary for the MPS3-AN536.
17
8
18
For convenience of being able to run guest code, permit
9
As with the LDRD change, now that we don't update 'addr' in the
19
this UNPREDICTABLE access instead of UNDEFing it.
10
course of performing the store we need to adjust the offset
11
we pass to op_addr_ri_post() and op_addr_rr_post().
20
12
13
Cc: qemu-stable@nongnu.org
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20240206132931.38376-5-peter.maydell@linaro.org
16
Message-id: 20250227142746.1698904-3-peter.maydell@linaro.org
24
---
17
---
25
target/arm/tcg/op_helper.c | 43 ++++++++++++++++++++++++++------------
18
target/arm/tcg/translate.c | 59 +++++++++++++++++++++++++-------------
26
target/arm/tcg/translate.c | 19 +++++++++++------
19
1 file changed, 39 insertions(+), 20 deletions(-)
27
2 files changed, 43 insertions(+), 19 deletions(-)
28
20
29
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/tcg/op_helper.c
32
+++ b/target/arm/tcg/op_helper.c
33
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
34
*/
35
int curmode = env->uncached_cpsr & CPSR_M;
36
37
- if (regno == 17) {
38
- /* ELR_Hyp: a special case because access from tgtmode is OK */
39
- if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
40
- goto undef;
41
+ if (tgtmode == ARM_CPU_MODE_HYP) {
42
+ /*
43
+ * Handle Hyp target regs first because some are special cases
44
+ * which don't want the usual "not accessible from tgtmode" check.
45
+ */
46
+ switch (regno) {
47
+ case 16 ... 17: /* ELR_Hyp, SPSR_Hyp */
48
+ if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
49
+ goto undef;
50
+ }
51
+ break;
52
+ case 13:
53
+ if (curmode != ARM_CPU_MODE_MON) {
54
+ goto undef;
55
+ }
56
+ break;
57
+ default:
58
+ g_assert_not_reached();
59
}
60
return;
61
}
62
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
63
}
64
}
65
66
- if (tgtmode == ARM_CPU_MODE_HYP) {
67
- /* SPSR_Hyp, r13_hyp: accessible from Monitor mode only */
68
- if (curmode != ARM_CPU_MODE_MON) {
69
- goto undef;
70
- }
71
- }
72
-
73
return;
74
75
undef:
76
@@ -XXX,XX +XXX,XX @@ void HELPER(msr_banked)(CPUARMState *env, uint32_t value, uint32_t tgtmode,
77
78
switch (regno) {
79
case 16: /* SPSRs */
80
- env->banked_spsr[bank_number(tgtmode)] = value;
81
+ if (tgtmode == (env->uncached_cpsr & CPSR_M)) {
82
+ /* Only happens for SPSR_Hyp access in Hyp mode */
83
+ env->spsr = value;
84
+ } else {
85
+ env->banked_spsr[bank_number(tgtmode)] = value;
86
+ }
87
break;
88
case 17: /* ELR_Hyp */
89
env->elr_el[2] = value;
90
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mrs_banked)(CPUARMState *env, uint32_t tgtmode, uint32_t regno)
91
92
switch (regno) {
93
case 16: /* SPSRs */
94
- return env->banked_spsr[bank_number(tgtmode)];
95
+ if (tgtmode == (env->uncached_cpsr & CPSR_M)) {
96
+ /* Only happens for SPSR_Hyp access in Hyp mode */
97
+ return env->spsr;
98
+ } else {
99
+ return env->banked_spsr[bank_number(tgtmode)];
100
+ }
101
case 17: /* ELR_Hyp */
102
return env->elr_el[2];
103
case 13:
104
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
21
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
105
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
106
--- a/target/arm/tcg/translate.c
23
--- a/target/arm/tcg/translate.c
107
+++ b/target/arm/tcg/translate.c
24
+++ b/target/arm/tcg/translate.c
108
@@ -XXX,XX +XXX,XX @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
25
@@ -XXX,XX +XXX,XX @@ static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
109
break;
26
return true;
110
case ARM_CPU_MODE_HYP:
27
}
111
/*
28
112
- * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
29
+static void do_strd_store(DisasContext *s, TCGv_i32 addr, int rt, int rt2)
113
- * (and so we can forbid accesses from EL2 or below). elr_hyp
30
+{
114
- * can be accessed also from Hyp mode, so forbid accesses from
31
+ /*
115
- * EL0 or EL1.
32
+ * STRD is required to be an atomic 64-bit access if the
116
+ * r13_hyp can only be accessed from Monitor mode, and so we
33
+ * address is 8-aligned, two atomic 32-bit accesses if
117
+ * can forbid accesses from EL2 or below.
34
+ * it's only 4-aligned, and to give an alignment fault
118
+ * elr_hyp can be accessed also from Hyp mode, so forbid
35
+ * if it's not 4-aligned.
119
+ * accesses from EL0 or EL1.
36
+ * Rt is always the word from the lower address, and Rt2 the
120
+ * SPSR_hyp is supposed to be in the same category as r13_hyp
37
+ * data from the higher address, regardless of endianness.
121
+ * and UNPREDICTABLE if accessed from anything except Monitor
38
+ * So (like gen_store_exclusive) we avoid gen_aa32_ld_i64()
122
+ * mode. However there is some real-world code that will do
39
+ * so we don't get its SCTLR_B check, and instead do a 64-bit access
123
+ * it because at least some hardware happens to permit the
40
+ * using MO_BE if appropriate, using a value constructed
124
+ * access. (Notably a standard Cortex-R52 startup code fragment
41
+ * by putting the two halves together in the right order.
125
+ * does this.) So we permit SPSR_hyp from Hyp mode also, to allow
42
+ *
126
+ * this (incorrect) guest code to run.
43
+ * As with LDRD, the 64-bit atomicity is not required for
127
*/
44
+ * M-profile, or for A-profile before LPAE, and we provide
128
- if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
45
+ * the higher guarantee always for simplicity.
129
- (s->current_el < 3 && *regno != 17)) {
46
+ */
130
+ if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2
47
+ int mem_idx = get_mem_index(s);
131
+ || (s->current_el < 3 && *regno != 16 && *regno != 17)) {
48
+ MemOp opc = MO_64 | MO_ALIGN_4 | MO_ATOM_SUBALIGN | s->be_data;
132
goto undef;
49
+ TCGv taddr = gen_aa32_addr(s, addr, opc);
133
}
50
+ TCGv_i32 t1 = load_reg(s, rt);
134
break;
51
+ TCGv_i32 t2 = load_reg(s, rt2);
52
+ TCGv_i64 t64 = tcg_temp_new_i64();
53
+
54
+ if (s->be_data == MO_BE) {
55
+ tcg_gen_concat_i32_i64(t64, t2, t1);
56
+ } else {
57
+ tcg_gen_concat_i32_i64(t64, t1, t2);
58
+ }
59
+ tcg_gen_qemu_st_i64(t64, taddr, mem_idx, opc);
60
+}
61
+
62
static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
63
{
64
- int mem_idx = get_mem_index(s);
65
- TCGv_i32 addr, tmp;
66
+ TCGv_i32 addr;
67
68
if (!ENABLE_ARCH_5TE) {
69
return false;
70
@@ -XXX,XX +XXX,XX @@ static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
71
}
72
addr = op_addr_rr_pre(s, a);
73
74
- tmp = load_reg(s, a->rt);
75
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
76
+ do_strd_store(s, addr, a->rt, a->rt + 1);
77
78
- tcg_gen_addi_i32(addr, addr, 4);
79
-
80
- tmp = load_reg(s, a->rt + 1);
81
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
82
-
83
- op_addr_rr_post(s, a, addr, -4);
84
+ op_addr_rr_post(s, a, addr, 0);
85
return true;
86
}
87
88
@@ -XXX,XX +XXX,XX @@ static bool trans_LDRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
89
90
static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
91
{
92
- int mem_idx = get_mem_index(s);
93
- TCGv_i32 addr, tmp;
94
+ TCGv_i32 addr;
95
96
addr = op_addr_ri_pre(s, a);
97
98
- tmp = load_reg(s, a->rt);
99
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
100
+ do_strd_store(s, addr, a->rt, rt2);
101
102
- tcg_gen_addi_i32(addr, addr, 4);
103
-
104
- tmp = load_reg(s, rt2);
105
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
106
-
107
- op_addr_ri_post(s, a, addr, -4);
108
+ op_addr_ri_post(s, a, addr, 0);
109
return true;
110
}
111
135
--
112
--
136
2.34.1
113
2.43.0
diff view generated by jsdifflib
1
The MPS2 SCC device is broadly the same for all FPGA images, but has
1
All the callers of op_addr_rr_post() and op_addr_ri_post() now pass in
2
minor differences in the behaviour of the CFG registers depending on
2
zero for the address_offset, so we can remove that argument.
3
the image. In many cases we don't really care about the functionality
4
controlled by these registers and a reads-as-written or similar
5
behaviour is sufficient for the moment.
6
7
For the AN536 the required behaviour is:
8
9
* A_CFG0 has CPU reset and halt bits
10
- implement as reads-as-written for the moment
11
* A_CFG1 has flash or ATCM address 0 remap handling
12
- QEMU doesn't model this; implement as reads-as-written
13
* A_CFG2 has QSPI select (like AN524)
14
- implemented (no behaviour, as with AN524)
15
* A_CFG3 is MCC_MSB_ADDR "additional MCC addressing bits"
16
- QEMU doesn't care about these, so use the existing
17
RAZ behaviour for convenience
18
* A_CFG4 is board rev (like all other images)
19
- no change needed
20
* A_CFG5 is ACLK frq in hz (like AN524)
21
- implemented as reads-as-written, as for other boards
22
* A_CFG6 is core 0 vector table base address
23
- implemented as reads-as-written for the moment
24
* A_CFG7 is core 1 vector table base address
25
- implemented as reads-as-written for the moment
26
27
Make the changes necessary for this; leave TODO comments where
28
appropriate to indicate where we might want to come back and
29
implement things like CPU reset.
30
31
The other aspects of the device specific to this FPGA image (like the
32
values of the board ID and similar registers) will be set via the
33
device's qdev properties.
34
3
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
36
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
37
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
38
Message-id: 20240206132931.38376-8-peter.maydell@linaro.org
7
Message-id: 20250227142746.1698904-4-peter.maydell@linaro.org
39
---
8
---
40
include/hw/misc/mps2-scc.h | 1 +
9
target/arm/tcg/translate.c | 26 +++++++++++++-------------
41
hw/misc/mps2-scc.c | 101 +++++++++++++++++++++++++++++++++----
10
1 file changed, 13 insertions(+), 13 deletions(-)
42
2 files changed, 92 insertions(+), 10 deletions(-)
43
11
44
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
12
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
45
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
46
--- a/include/hw/misc/mps2-scc.h
14
--- a/target/arm/tcg/translate.c
47
+++ b/include/hw/misc/mps2-scc.h
15
+++ b/target/arm/tcg/translate.c
48
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
16
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 op_addr_rr_pre(DisasContext *s, arg_ldst_rr *a)
49
uint32_t cfg4;
17
}
50
uint32_t cfg5;
18
51
uint32_t cfg6;
19
static void op_addr_rr_post(DisasContext *s, arg_ldst_rr *a,
52
+ uint32_t cfg7;
20
- TCGv_i32 addr, int address_offset)
53
uint32_t cfgdata_rtn;
21
+ TCGv_i32 addr)
54
uint32_t cfgdata_out;
55
uint32_t cfgctrl;
56
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/misc/mps2-scc.c
59
+++ b/hw/misc/mps2-scc.c
60
@@ -XXX,XX +XXX,XX @@ REG32(CFG3, 0xc)
61
REG32(CFG4, 0x10)
62
REG32(CFG5, 0x14)
63
REG32(CFG6, 0x18)
64
+REG32(CFG7, 0x1c)
65
REG32(CFGDATA_RTN, 0xa0)
66
REG32(CFGDATA_OUT, 0xa4)
67
REG32(CFGCTRL, 0xa8)
68
@@ -XXX,XX +XXX,XX @@ static int scc_partno(MPS2SCC *s)
69
/* Is CFG_REG2 present? */
70
static bool have_cfg2(MPS2SCC *s)
71
{
22
{
72
- return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
23
if (!a->p) {
73
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547 ||
24
TCGv_i32 ofs = load_reg(s, a->rm);
74
+ scc_partno(s) == 0x536;
25
@@ -XXX,XX +XXX,XX @@ static void op_addr_rr_post(DisasContext *s, arg_ldst_rr *a,
26
} else if (!a->w) {
27
return;
28
}
29
- tcg_gen_addi_i32(addr, addr, address_offset);
30
store_reg(s, a->rn, addr);
75
}
31
}
76
32
77
/* Is CFG_REG3 present? */
33
@@ -XXX,XX +XXX,XX @@ static bool op_load_rr(DisasContext *s, arg_ldst_rr *a,
78
static bool have_cfg3(MPS2SCC *s)
34
* Perform base writeback before the loaded value to
35
* ensure correct behavior with overlapping index registers.
36
*/
37
- op_addr_rr_post(s, a, addr, 0);
38
+ op_addr_rr_post(s, a, addr);
39
store_reg_from_load(s, a->rt, tmp);
40
return true;
41
}
42
@@ -XXX,XX +XXX,XX @@ static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
43
gen_aa32_st_i32(s, tmp, addr, mem_idx, mop);
44
disas_set_da_iss(s, mop, issinfo);
45
46
- op_addr_rr_post(s, a, addr, 0);
47
+ op_addr_rr_post(s, a, addr);
48
return true;
49
}
50
51
@@ -XXX,XX +XXX,XX @@ static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
52
do_ldrd_load(s, addr, a->rt, a->rt + 1);
53
54
/* LDRD w/ base writeback is undefined if the registers overlap. */
55
- op_addr_rr_post(s, a, addr, 0);
56
+ op_addr_rr_post(s, a, addr);
57
return true;
58
}
59
60
@@ -XXX,XX +XXX,XX @@ static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
61
62
do_strd_store(s, addr, a->rt, a->rt + 1);
63
64
- op_addr_rr_post(s, a, addr, 0);
65
+ op_addr_rr_post(s, a, addr);
66
return true;
67
}
68
69
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 op_addr_ri_pre(DisasContext *s, arg_ldst_ri *a)
70
}
71
72
static void op_addr_ri_post(DisasContext *s, arg_ldst_ri *a,
73
- TCGv_i32 addr, int address_offset)
74
+ TCGv_i32 addr)
79
{
75
{
80
- return scc_partno(s) != 0x524 && scc_partno(s) != 0x547;
76
+ int address_offset = 0;
81
+ return scc_partno(s) != 0x524 && scc_partno(s) != 0x547 &&
77
if (!a->p) {
82
+ scc_partno(s) != 0x536;
78
if (a->u) {
79
- address_offset += a->imm;
80
+ address_offset = a->imm;
81
} else {
82
- address_offset -= a->imm;
83
+ address_offset = -a->imm;
84
}
85
} else if (!a->w) {
86
return;
87
@@ -XXX,XX +XXX,XX @@ static bool op_load_ri(DisasContext *s, arg_ldst_ri *a,
88
* Perform base writeback before the loaded value to
89
* ensure correct behavior with overlapping index registers.
90
*/
91
- op_addr_ri_post(s, a, addr, 0);
92
+ op_addr_ri_post(s, a, addr);
93
store_reg_from_load(s, a->rt, tmp);
94
return true;
83
}
95
}
84
96
@@ -XXX,XX +XXX,XX @@ static bool op_store_ri(DisasContext *s, arg_ldst_ri *a,
85
/* Is CFG_REG5 present? */
97
gen_aa32_st_i32(s, tmp, addr, mem_idx, mop);
86
static bool have_cfg5(MPS2SCC *s)
98
disas_set_da_iss(s, mop, issinfo);
87
{
99
88
- return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
100
- op_addr_ri_post(s, a, addr, 0);
89
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547 ||
101
+ op_addr_ri_post(s, a, addr);
90
+ scc_partno(s) == 0x536;
102
return true;
91
}
103
}
92
104
93
/* Is CFG_REG6 present? */
105
@@ -XXX,XX +XXX,XX @@ static bool op_ldrd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
94
static bool have_cfg6(MPS2SCC *s)
106
do_ldrd_load(s, addr, a->rt, rt2);
95
{
107
96
- return scc_partno(s) == 0x524;
108
/* LDRD w/ base writeback is undefined if the registers overlap. */
97
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x536;
109
- op_addr_ri_post(s, a, addr, 0);
98
+}
110
+ op_addr_ri_post(s, a, addr);
99
+
111
return true;
100
+/* Is CFG_REG7 present? */
101
+static bool have_cfg7(MPS2SCC *s)
102
+{
103
+ return scc_partno(s) == 0x536;
104
+}
105
+
106
+/* Does CFG_REG0 drive the 'remap' GPIO output? */
107
+static bool cfg0_is_remap(MPS2SCC *s)
108
+{
109
+ return scc_partno(s) != 0x536;
110
+}
111
+
112
+/* Is CFG_REG1 driving a set of LEDs? */
113
+static bool cfg1_is_leds(MPS2SCC *s)
114
+{
115
+ return scc_partno(s) != 0x536;
116
}
112
}
117
113
118
/* Handle a write via the SYS_CFG channel to the specified function/device.
114
@@ -XXX,XX +XXX,XX @@ static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
119
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
115
120
if (!have_cfg3(s)) {
116
do_strd_store(s, addr, a->rt, rt2);
121
goto bad_offset;
117
122
}
118
- op_addr_ri_post(s, a, addr, 0);
123
- /* These are user-settable DIP switches on the board. We don't
119
+ op_addr_ri_post(s, a, addr);
124
+ /*
120
return true;
125
+ * These are user-settable DIP switches on the board. We don't
126
* model that, so just return zeroes.
127
+ *
128
+ * TODO: for AN536 this is MCC_MSB_ADDR "additional MCC addressing
129
+ * bits". These change which part of the DDR4 the motherboard
130
+ * configuration controller can see in its memory map (see the
131
+ * appnote section 2.4). QEMU doesn't model the MCC at all, so these
132
+ * bits are not interesting to us; read-as-zero is as good as anything
133
+ * else.
134
*/
135
r = 0;
136
break;
137
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
138
}
139
r = s->cfg6;
140
break;
141
+ case A_CFG7:
142
+ if (!have_cfg7(s)) {
143
+ goto bad_offset;
144
+ }
145
+ r = s->cfg7;
146
+ break;
147
case A_CFGDATA_RTN:
148
r = s->cfgdata_rtn;
149
break;
150
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
151
* we always reflect bit 0 in the 'remap' GPIO output line,
152
* and let the board wire it up or not as it chooses.
153
* TODO on some boards bit 1 is CPU_WAIT.
154
+ *
155
+ * TODO: on the AN536 this register controls reset and halt
156
+ * for both CPUs. For the moment we don't implement this, so the
157
+ * register just reads as written.
158
*/
159
s->cfg0 = value;
160
- qemu_set_irq(s->remap, s->cfg0 & 1);
161
+ if (cfg0_is_remap(s)) {
162
+ qemu_set_irq(s->remap, s->cfg0 & 1);
163
+ }
164
break;
165
case A_CFG1:
166
s->cfg1 = value;
167
- for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
168
- led_set_state(s->led[i], extract32(value, i, 1));
169
+ /*
170
+ * On most boards this register drives LEDs.
171
+ *
172
+ * TODO: for AN536 this controls whether flash and ATCM are
173
+ * enabled or disabled on reset. QEMU doesn't model this, and
174
+ * always wires up RAM in the ATCM area and ROM in the flash area.
175
+ */
176
+ if (cfg1_is_leds(s)) {
177
+ for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
178
+ led_set_state(s->led[i], extract32(value, i, 1));
179
+ }
180
}
181
break;
182
case A_CFG2:
183
if (!have_cfg2(s)) {
184
goto bad_offset;
185
}
186
- /* AN524: QSPI Select signal */
187
+ /* AN524, AN536: QSPI Select signal */
188
s->cfg2 = value;
189
break;
190
case A_CFG5:
191
if (!have_cfg5(s)) {
192
goto bad_offset;
193
}
194
- /* AN524: ACLK frequency in Hz */
195
+ /* AN524, AN536: ACLK frequency in Hz */
196
s->cfg5 = value;
197
break;
198
case A_CFG6:
199
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
200
goto bad_offset;
201
}
202
/* AN524: Clock divider for BRAM */
203
+ /* AN536: Core 0 vector table base address */
204
+ s->cfg6 = value;
205
+ break;
206
+ case A_CFG7:
207
+ if (!have_cfg7(s)) {
208
+ goto bad_offset;
209
+ }
210
+ /* AN536: Core 1 vector table base address */
211
s->cfg6 = value;
212
break;
213
case A_CFGDATA_OUT:
214
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_finalize(Object *obj)
215
g_free(s->oscclk_reset);
216
}
121
}
217
122
218
+static bool cfg7_needed(void *opaque)
219
+{
220
+ MPS2SCC *s = opaque;
221
+
222
+ return have_cfg7(s);
223
+}
224
+
225
+static const VMStateDescription vmstate_cfg7 = {
226
+ .name = "mps2-scc/cfg7",
227
+ .version_id = 1,
228
+ .minimum_version_id = 1,
229
+ .needed = cfg7_needed,
230
+ .fields = (const VMStateField[]) {
231
+ VMSTATE_UINT32(cfg7, MPS2SCC),
232
+ VMSTATE_END_OF_LIST()
233
+ }
234
+};
235
+
236
static const VMStateDescription mps2_scc_vmstate = {
237
.name = "mps2-scc",
238
.version_id = 3,
239
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_scc_vmstate = {
240
VMSTATE_VARRAY_UINT32(oscclk, MPS2SCC, num_oscclk,
241
0, vmstate_info_uint32, uint32_t),
242
VMSTATE_END_OF_LIST()
243
+ },
244
+ .subsections = (const VMStateDescription * const []) {
245
+ &vmstate_cfg7,
246
+ NULL
247
}
248
};
249
250
--
123
--
251
2.34.1
124
2.43.0
252
125
253
126
diff view generated by jsdifflib
1
Add the remaining devices (or unimplemented-device stubs) for
1
In debug_helper.c we provide a few dummy versions of
2
this board: SPI controllers, SCC, FPGAIO, I2S, RTC, the
2
debug registers:
3
QSPI write-config block, and ethernet.
3
* DBGVCR (AArch32 only): enable bits for vector-catch
4
debug events
5
* MDCCINT_EL1: interrupt enable bits for the DCC
6
debug communications channel
7
* DBGVCR32_EL2: the AArch64 accessor for the state in
8
DBGVCR
4
9
10
We implemented these only to stop Linux crashing on startup,
11
but we chose to implement them as ARM_CP_NOP. This worked
12
for Linux where it only cares about trying to write to these
13
registers, but is very confusing behaviour for anything that
14
wants to read the registers (perhaps for context state switches),
15
because the destination register will be left with whatever
16
random value it happened to have before the read.
17
18
Model these registers instead as RAZ.
19
20
Fixes: 5e8b12ffbb8c68 ("target-arm: Implement minimal DBGVCR, OSDLR_EL1, MDCCSR_EL0")
21
Fixes: 5dbdc4342f479d ("target-arm: Implement dummy MDCCINT_EL1")
22
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2708
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20240206132931.38376-13-peter.maydell@linaro.org
25
Message-id: 20250228162424.1917269-1-peter.maydell@linaro.org
8
---
26
---
9
hw/arm/mps3r.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++
27
target/arm/debug_helper.c | 7 ++++---
10
1 file changed, 74 insertions(+)
28
1 file changed, 4 insertions(+), 3 deletions(-)
11
29
12
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
30
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
13
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/mps3r.c
32
--- a/target/arm/debug_helper.c
15
+++ b/hw/arm/mps3r.c
33
+++ b/target/arm/debug_helper.c
16
@@ -XXX,XX +XXX,XX @@
34
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
17
#include "hw/char/cmsdk-apb-uart.h"
35
{ .name = "DBGVCR",
18
#include "hw/i2c/arm_sbcon_i2c.h"
36
.cp = 14, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
19
#include "hw/intc/arm_gicv3.h"
37
.access = PL1_RW, .accessfn = access_tda,
20
+#include "hw/misc/mps2-scc.h"
38
- .type = ARM_CP_NOP },
21
+#include "hw/misc/mps2-fpgaio.h"
39
+ .type = ARM_CP_CONST, .resetvalue = 0 },
22
#include "hw/misc/unimp.h"
40
/*
23
+#include "hw/net/lan9118.h"
41
* Dummy MDCCINT_EL1, since we don't implement the Debug Communications
24
+#include "hw/rtc/pl031.h"
42
* Channel but Linux may try to access this register. The 32-bit
25
+#include "hw/ssi/pl022.h"
43
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
26
#include "hw/timer/cmsdk-apb-dualtimer.h"
44
{ .name = "MDCCINT_EL1", .state = ARM_CP_STATE_BOTH,
27
#include "hw/watchdog/cmsdk-apb-watchdog.h"
45
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
28
46
.access = PL1_RW, .accessfn = access_tdcc,
29
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
47
- .type = ARM_CP_NOP },
30
CMSDKAPBWatchdog watchdog;
48
+ .type = ARM_CP_CONST, .resetvalue = 0 },
31
CMSDKAPBDualTimer dualtimer;
49
/*
32
ArmSbconI2CState i2c[5];
50
* Dummy DBGCLAIM registers.
33
+ PL022State spi[3];
51
* "The architecture does not define any functionality for the CLAIM tag bits.",
34
+ MPS2SCC scc;
52
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_aa32_el1_reginfo[] = {
35
+ MPS2FPGAIO fpgaio;
53
{ .name = "DBGVCR32_EL2", .state = ARM_CP_STATE_AA64,
36
+ UnimplementedDeviceState i2s_audio;
54
.opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0,
37
+ PL031State rtc;
55
.access = PL2_RW, .accessfn = access_dbgvcr32,
38
Clock *clk;
56
- .type = ARM_CP_NOP | ARM_CP_EL3_NO_EL2_KEEP },
57
+ .type = ARM_CP_CONST | ARM_CP_EL3_NO_EL2_KEEP,
58
+ .resetvalue = 0 },
39
};
59
};
40
60
41
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an536_raminfo[] = {
61
static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
42
}
43
};
44
45
+static const int an536_oscclk[] = {
46
+ 24000000, /* 24MHz reference for RTC and timers */
47
+ 50000000, /* 50MHz ACLK */
48
+ 50000000, /* 50MHz MCLK */
49
+ 50000000, /* 50MHz GPUCLK */
50
+ 24576000, /* 24.576MHz AUDCLK */
51
+ 23750000, /* 23.75MHz HDLCDCLK */
52
+ 100000000, /* 100MHz DDR4_REF_CLK */
53
+};
54
+
55
static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
56
const RAMInfo *raminfo)
57
{
58
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
59
MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
60
MemoryRegion *sysmem = get_system_memory();
61
DeviceState *gicdev;
62
+ QList *oscclk;
63
64
mms->clk = clock_new(OBJECT(machine), "CLK");
65
clock_set_hz(mms->clk, CLK_FRQ);
66
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
67
}
68
}
69
70
+ for (int i = 0; i < ARRAY_SIZE(mms->spi); i++) {
71
+ g_autofree char *s = g_strdup_printf("spi%d", i);
72
+ hwaddr baseaddr = 0xe0104000 + i * 0x1000;
73
+
74
+ object_initialize_child(OBJECT(mms), s, &mms->spi[i], TYPE_PL022);
75
+ sysbus_realize(SYS_BUS_DEVICE(&mms->spi[i]), &error_fatal);
76
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->spi[i]), 0, baseaddr);
77
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->spi[i]), 0,
78
+ qdev_get_gpio_in(gicdev, 22 + i));
79
+ }
80
+
81
+ object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
82
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-cfg0", 0);
83
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-cfg4", 0x2);
84
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-aid", 0x00200008);
85
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-id", 0x41055360);
86
+ oscclk = qlist_new();
87
+ for (int i = 0; i < ARRAY_SIZE(an536_oscclk); i++) {
88
+ qlist_append_int(oscclk, an536_oscclk[i]);
89
+ }
90
+ qdev_prop_set_array(DEVICE(&mms->scc), "oscclk", oscclk);
91
+ sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
92
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->scc), 0, 0xe0200000);
93
+
94
+ create_unimplemented_device("i2s-audio", 0xe0201000, 0x1000);
95
+
96
+ object_initialize_child(OBJECT(mms), "fpgaio", &mms->fpgaio,
97
+ TYPE_MPS2_FPGAIO);
98
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "prescale-clk", an536_oscclk[1]);
99
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "num-leds", 10);
100
+ qdev_prop_set_bit(DEVICE(&mms->fpgaio), "has-switches", true);
101
+ qdev_prop_set_bit(DEVICE(&mms->fpgaio), "has-dbgctrl", false);
102
+ sysbus_realize(SYS_BUS_DEVICE(&mms->fpgaio), &error_fatal);
103
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->fpgaio), 0, 0xe0202000);
104
+
105
+ create_unimplemented_device("clcd", 0xe0209000, 0x1000);
106
+
107
+ object_initialize_child(OBJECT(mms), "rtc", &mms->rtc, TYPE_PL031);
108
+ sysbus_realize(SYS_BUS_DEVICE(&mms->rtc), &error_fatal);
109
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->rtc), 0, 0xe020a000);
110
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->rtc), 0,
111
+ qdev_get_gpio_in(gicdev, 4));
112
+
113
+ /*
114
+ * In hardware this is a LAN9220; the LAN9118 is software compatible
115
+ * except that it doesn't support the checksum-offload feature.
116
+ */
117
+ lan9118_init(0xe0300000,
118
+ qdev_get_gpio_in(gicdev, 18));
119
+
120
+ create_unimplemented_device("usb", 0xe0301000, 0x1000);
121
+ create_unimplemented_device("qspi-write-config", 0xe0600000, 0x1000);
122
+
123
mms->bootinfo.ram_size = machine->ram_size;
124
mms->bootinfo.board_id = -1;
125
mms->bootinfo.loader_start = mmc->loader_start;
126
--
62
--
127
2.34.1
63
2.43.0
128
129
diff view generated by jsdifflib
1
The MPS SCC device has a lot of different flavours for the various
1
Currently we call icount_start_warp_timer() from timerlist_rearm().
2
different MPS FPGA images, which look mostly similar but have
2
This produces incorrect behaviour, because timerlist_rearm() is
3
differences in how particular registers are handled. Currently we
3
called, for instance, when a timer callback modifies its timer. We
4
deal with this with a lot of open-coded checks on scc_partno(), but
4
cannot decide here to warp the timer forwards to the next timer
5
as we add more board types this is getting a bit hard to read.
5
deadline merely because all_cpu_threads_idle() is true, because the
6
timer callback we were called from (or some other callback later in
7
the list of callbacks being invoked) may be about to raise a CPU
8
interrupt and move a CPU from idle to ready.
6
9
7
Factor out the conditions into some functions which we can
10
The only valid place to choose to warp the timer forward is from the
8
give more descriptive names to.
11
main loop, when we know we have no outstanding IO or timer callbacks
12
that might be about to wake up a CPU.
9
13
14
For Arm guests, this bug was mostly latent until the refactoring
15
commit f6fc36deef6abc ("target/arm/helper: Implement
16
CNTHCTL_EL2.CNT[VP]MASK"), which exposed it because it refactored a
17
timer callback so that it happened to call timer_mod() first and
18
raise the interrupt second, when it had previously raised the
19
interrupt first and called timer_mod() afterwards.
20
21
This call seems to have originally derived from the
22
pre-record-and-replay icount code, which (as of e.g. commit
23
db1a49726c3c in 2010) in this location did a call to
24
qemu_notify_event(), necessary to get the icount code in the vCPU
25
round-robin thread to stop and recalculate the icount deadline when a
26
timer was reprogrammed from the IO thread. In current QEMU,
27
everything is done on the vCPU thread when we are in icount mode, so
28
there's no need to try to notify another thread here.
29
30
I suspect that the other reason why this call was doing icount timer
31
warping is that it pre-dates commit efab87cf79077a from 2015, which
32
added a call to icount_start_warp_timer() to main_loop_wait(). Once
33
the call in timerlist_rearm() has been removed, if the timer
34
callbacks don't cause any CPU to be woken up then we will end up
35
calling icount_start_warp_timer() from main_loop_wait() when the rr
36
main loop code calls rr_wait_io_event().
37
38
Remove the incorrect call from timerlist_rearm().
39
40
Cc: qemu-stable@nongnu.org
41
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2703
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
42
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
43
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20240206132931.38376-7-peter.maydell@linaro.org
44
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
45
Tested-by: Alex Bennée <alex.bennee@linaro.org>
46
Message-id: 20250210135804.3526943-1-peter.maydell@linaro.org
14
---
47
---
15
hw/misc/mps2-scc.c | 45 +++++++++++++++++++++++++++++++--------------
48
util/qemu-timer.c | 4 ----
16
1 file changed, 31 insertions(+), 14 deletions(-)
49
1 file changed, 4 deletions(-)
17
50
18
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
51
diff --git a/util/qemu-timer.c b/util/qemu-timer.c
19
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/misc/mps2-scc.c
53
--- a/util/qemu-timer.c
21
+++ b/hw/misc/mps2-scc.c
54
+++ b/util/qemu-timer.c
22
@@ -XXX,XX +XXX,XX @@ static int scc_partno(MPS2SCC *s)
55
@@ -XXX,XX +XXX,XX @@ static bool timer_mod_ns_locked(QEMUTimerList *timer_list,
23
return extract32(s->id, 4, 8);
56
57
static void timerlist_rearm(QEMUTimerList *timer_list)
58
{
59
- /* Interrupt execution to force deadline recalculation. */
60
- if (icount_enabled() && timer_list->clock->type == QEMU_CLOCK_VIRTUAL) {
61
- icount_start_warp_timer();
62
- }
63
timerlist_notify(timer_list);
24
}
64
}
25
65
26
+/* Is CFG_REG2 present? */
27
+static bool have_cfg2(MPS2SCC *s)
28
+{
29
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
30
+}
31
+
32
+/* Is CFG_REG3 present? */
33
+static bool have_cfg3(MPS2SCC *s)
34
+{
35
+ return scc_partno(s) != 0x524 && scc_partno(s) != 0x547;
36
+}
37
+
38
+/* Is CFG_REG5 present? */
39
+static bool have_cfg5(MPS2SCC *s)
40
+{
41
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
42
+}
43
+
44
+/* Is CFG_REG6 present? */
45
+static bool have_cfg6(MPS2SCC *s)
46
+{
47
+ return scc_partno(s) == 0x524;
48
+}
49
+
50
/* Handle a write via the SYS_CFG channel to the specified function/device.
51
* Return false on error (reported to guest via SYS_CFGCTRL ERROR bit).
52
*/
53
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
54
r = s->cfg1;
55
break;
56
case A_CFG2:
57
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
58
- /* CFG2 reserved on other boards */
59
+ if (!have_cfg2(s)) {
60
goto bad_offset;
61
}
62
r = s->cfg2;
63
break;
64
case A_CFG3:
65
- if (scc_partno(s) == 0x524 || scc_partno(s) == 0x547) {
66
- /* CFG3 reserved on AN524 */
67
+ if (!have_cfg3(s)) {
68
goto bad_offset;
69
}
70
/* These are user-settable DIP switches on the board. We don't
71
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
72
r = s->cfg4;
73
break;
74
case A_CFG5:
75
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
76
- /* CFG5 reserved on other boards */
77
+ if (!have_cfg5(s)) {
78
goto bad_offset;
79
}
80
r = s->cfg5;
81
break;
82
case A_CFG6:
83
- if (scc_partno(s) != 0x524) {
84
- /* CFG6 reserved on other boards */
85
+ if (!have_cfg6(s)) {
86
goto bad_offset;
87
}
88
r = s->cfg6;
89
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
90
}
91
break;
92
case A_CFG2:
93
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
94
- /* CFG2 reserved on other boards */
95
+ if (!have_cfg2(s)) {
96
goto bad_offset;
97
}
98
/* AN524: QSPI Select signal */
99
s->cfg2 = value;
100
break;
101
case A_CFG5:
102
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
103
- /* CFG5 reserved on other boards */
104
+ if (!have_cfg5(s)) {
105
goto bad_offset;
106
}
107
/* AN524: ACLK frequency in Hz */
108
s->cfg5 = value;
109
break;
110
case A_CFG6:
111
- if (scc_partno(s) != 0x524) {
112
- /* CFG6 reserved on other boards */
113
+ if (!have_cfg6(s)) {
114
goto bad_offset;
115
}
116
/* AN524: Clock divider for BRAM */
117
--
66
--
118
2.34.1
67
2.43.0
119
68
120
69
diff view generated by jsdifflib
1
Add the Cortex-R52 IMPDEF sysregs, by defining them here and
1
Expand the example in the comment documenting MO_ATOM_SUBALIGN,
2
also by enabling the AUXCR feature which defines the ACTLR
2
to be clearer about the atomicity guarantees it represents.
3
and HACTLR registers. As is our usual practice, we make these
4
simple reads-as-zero stubs for now.
5
3
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20240206132931.38376-4-peter.maydell@linaro.org
6
Message-id: 20250228103222.1838913-1-peter.maydell@linaro.org
9
---
7
---
10
target/arm/tcg/cpu32.c | 108 +++++++++++++++++++++++++++++++++++++++++
8
include/exec/memop.h | 8 ++++++--
11
1 file changed, 108 insertions(+)
9
1 file changed, 6 insertions(+), 2 deletions(-)
12
10
13
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
11
diff --git a/include/exec/memop.h b/include/exec/memop.h
14
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/tcg/cpu32.c
13
--- a/include/exec/memop.h
16
+++ b/target/arm/tcg/cpu32.c
14
+++ b/include/exec/memop.h
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
15
@@ -XXX,XX +XXX,XX @@ typedef enum MemOp {
18
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
16
* Depending on alignment, one or both will be single-copy atomic.
19
}
17
* This is the atomicity e.g. of Arm FEAT_LSE2 LDP.
20
18
* MO_ATOM_SUBALIGN: the operation is single-copy atomic by parts
21
+static const ARMCPRegInfo cortex_r52_cp_reginfo[] = {
19
- * by the alignment. E.g. if the address is 0 mod 4, then each
22
+ { .name = "CPUACTLR", .cp = 15, .opc1 = 0, .crm = 15,
20
- * 4-byte subobject is single-copy atomic.
23
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
21
+ * by the alignment. E.g. if an 8-byte value is accessed at an
24
+ { .name = "IMP_ATCMREGIONR",
22
+ * address which is 0 mod 8, then the whole 8-byte access is
25
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
23
+ * single-copy atomic; otherwise, if it is accessed at 0 mod 4
26
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
24
+ * then each 4-byte subobject is single-copy atomic; otherwise
27
+ { .name = "IMP_BTCMREGIONR",
25
+ * if it is accessed at 0 mod 2 then the four 2-byte subobjects
28
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1,
26
+ * are single-copy atomic.
29
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
27
* This is the atomicity e.g. of IBM Power.
30
+ { .name = "IMP_CTCMREGIONR",
28
* MO_ATOM_NONE: the operation has no atomicity requirements.
31
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 2,
29
*
32
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
33
+ { .name = "IMP_CSCTLR",
34
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 0,
35
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
36
+ { .name = "IMP_BPCTLR",
37
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 1,
38
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
39
+ { .name = "IMP_MEMPROTCLR",
40
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 2,
41
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
42
+ { .name = "IMP_SLAVEPCTLR",
43
+ .cp = 15, .opc1 = 0, .crn = 11, .crm = 0, .opc2 = 0,
44
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
45
+ { .name = "IMP_PERIPHREGIONR",
46
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 0,
47
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
48
+ { .name = "IMP_FLASHIFREGIONR",
49
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 1,
50
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
51
+ { .name = "IMP_BUILDOPTR",
52
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 0,
53
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
54
+ { .name = "IMP_PINOPTR",
55
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 7,
56
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
57
+ { .name = "IMP_QOSR",
58
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 1,
59
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
60
+ { .name = "IMP_BUSTIMEOUTR",
61
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 2,
62
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
63
+ { .name = "IMP_INTMONR",
64
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 4,
65
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
66
+ { .name = "IMP_ICERR0",
67
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 0, .opc2 = 0,
68
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
69
+ { .name = "IMP_ICERR1",
70
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 0, .opc2 = 1,
71
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
72
+ { .name = "IMP_DCERR0",
73
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 1, .opc2 = 0,
74
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
75
+ { .name = "IMP_DCERR1",
76
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 1, .opc2 = 1,
77
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
78
+ { .name = "IMP_TCMERR0",
79
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 0,
80
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
81
+ { .name = "IMP_TCMERR1",
82
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 1,
83
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
84
+ { .name = "IMP_TCMSYNDR0",
85
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 2,
86
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
87
+ { .name = "IMP_TCMSYNDR1",
88
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 3,
89
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
90
+ { .name = "IMP_FLASHERR0",
91
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 3, .opc2 = 0,
92
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
93
+ { .name = "IMP_FLASHERR1",
94
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 3, .opc2 = 1,
95
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
96
+ { .name = "IMP_CDBGDR0",
97
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 0, .opc2 = 0,
98
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
99
+ { .name = "IMP_CBDGBR1",
100
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 0, .opc2 = 1,
101
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
102
+ { .name = "IMP_TESTR0",
103
+ .cp = 15, .opc1 = 4, .crn = 15, .crm = 0, .opc2 = 0,
104
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
105
+ { .name = "IMP_TESTR1",
106
+ .cp = 15, .opc1 = 4, .crn = 15, .crm = 0, .opc2 = 1,
107
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
108
+ { .name = "IMP_CDBGDCI",
109
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 15, .opc2 = 0,
110
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
111
+ { .name = "IMP_CDBGDCT",
112
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 2, .opc2 = 0,
113
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
114
+ { .name = "IMP_CDBGICT",
115
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 2, .opc2 = 1,
116
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
117
+ { .name = "IMP_CDBGDCD",
118
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 4, .opc2 = 0,
119
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
120
+ { .name = "IMP_CDBGICD",
121
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 4, .opc2 = 1,
122
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
123
+};
124
+
125
+
126
static void cortex_r52_initfn(Object *obj)
127
{
128
ARMCPU *cpu = ARM_CPU(obj);
129
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
130
set_feature(&cpu->env, ARM_FEATURE_NEON);
131
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
132
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
133
+ set_feature(&cpu->env, ARM_FEATURE_AUXCR);
134
cpu->midr = 0x411fd133; /* r1p3 */
135
cpu->revidr = 0x00000000;
136
cpu->reset_fpsid = 0x41034023;
137
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
138
139
cpu->pmsav7_dregion = 16;
140
cpu->pmsav8r_hdregion = 16;
141
+
142
+ define_arm_cp_regs(cpu, cortex_r52_cp_reginfo);
143
}
144
145
static void cortex_r5f_initfn(Object *obj)
146
--
30
--
147
2.34.1
31
2.43.0
diff view generated by jsdifflib
1
From: Luc Michel <luc.michel@amd.com>
1
From: JianChunfu <jansef.jian@hj-micro.com>
2
2
3
An access fault is raised when the Access Flag is not set in the
3
Use a similar terminology smmu_hash_remove_by_sid_range() as the one
4
looked-up PTE and the AFFD field is not set in the corresponding context
4
being used for other hash table matching functions since
5
descriptor. This was already implemented for stage 2. Implement it for
5
smmuv3_invalidate_ste() name is not self explanatory, and introduce a
6
stage 1 as well.
6
helper that invokes the g_hash_table_foreach_remove.
7
7
8
Signed-off-by: Luc Michel <luc.michel@amd.com>
8
No functional change intended.
9
Reviewed-by: Mostafa Saleh <smostafa@google.com>
9
10
Signed-off-by: JianChunfu <jansef.jian@hj-micro.com>
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
Tested-by: Mostafa Saleh <smostafa@google.com>
12
Message-id: 20250228031438.3916-1-jansef.jian@hj-micro.com
12
Message-id: 20240213082211.3330400-1-luc.michel@amd.com
13
[PMM: tweaked comment text]
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
14
---
16
hw/arm/smmuv3-internal.h | 1 +
15
hw/arm/smmu-internal.h | 5 -----
17
include/hw/arm/smmu-common.h | 1 +
16
include/hw/arm/smmu-common.h | 6 ++++++
18
hw/arm/smmu-common.c | 11 +++++++++++
17
hw/arm/smmu-common.c | 21 +++++++++++++++++++++
19
hw/arm/smmuv3.c | 1 +
18
hw/arm/smmuv3.c | 19 ++-----------------
20
4 files changed, 14 insertions(+)
19
hw/arm/trace-events | 3 ++-
20
5 files changed, 31 insertions(+), 23 deletions(-)
21
21
22
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
22
diff --git a/hw/arm/smmu-internal.h b/hw/arm/smmu-internal.h
23
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/arm/smmuv3-internal.h
24
--- a/hw/arm/smmu-internal.h
25
+++ b/hw/arm/smmuv3-internal.h
25
+++ b/hw/arm/smmu-internal.h
26
@@ -XXX,XX +XXX,XX @@ static inline int pa_range(STE *ste)
26
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUIOTLBPageInvInfo {
27
#define CD_EPD(x, sel) extract32((x)->word[0], (16 * (sel)) + 14, 1)
27
uint64_t mask;
28
#define CD_ENDI(x) extract32((x)->word[0], 15, 1)
28
} SMMUIOTLBPageInvInfo;
29
#define CD_IPS(x) extract32((x)->word[1], 0 , 3)
29
30
+#define CD_AFFD(x) extract32((x)->word[1], 3 , 1)
30
-typedef struct SMMUSIDRange {
31
#define CD_TBI(x) extract32((x)->word[1], 6 , 2)
31
- uint32_t start;
32
#define CD_HD(x) extract32((x)->word[1], 10 , 1)
32
- uint32_t end;
33
#define CD_HA(x) extract32((x)->word[1], 11 , 1)
33
-} SMMUSIDRange;
34
-
35
#endif
34
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
36
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
35
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/arm/smmu-common.h
38
--- a/include/hw/arm/smmu-common.h
37
+++ b/include/hw/arm/smmu-common.h
39
+++ b/include/hw/arm/smmu-common.h
38
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUTransCfg {
40
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUIOTLBKey {
39
bool disabled; /* smmu is disabled */
41
uint8_t level;
40
bool bypassed; /* translation is bypassed */
42
} SMMUIOTLBKey;
41
bool aborted; /* translation is aborted */
43
42
+ bool affd; /* AF fault disable */
44
+typedef struct SMMUSIDRange {
43
uint32_t iotlb_hits; /* counts IOTLB hits */
45
+ uint32_t start;
44
uint32_t iotlb_misses; /* counts IOTLB misses*/
46
+ uint32_t end;
45
/* Used by stage-1 only. */
47
+} SMMUSIDRange;
48
+
49
struct SMMUState {
50
/* <private> */
51
SysBusDevice dev;
52
@@ -XXX,XX +XXX,XX @@ void smmu_iotlb_inv_iova(SMMUState *s, int asid, int vmid, dma_addr_t iova,
53
uint8_t tg, uint64_t num_pages, uint8_t ttl);
54
void smmu_iotlb_inv_ipa(SMMUState *s, int vmid, dma_addr_t ipa, uint8_t tg,
55
uint64_t num_pages, uint8_t ttl);
56
+void smmu_configs_inv_sid_range(SMMUState *s, SMMUSIDRange sid_range);
57
/* Unmap the range of all the notifiers registered to any IOMMU mr */
58
void smmu_inv_notifiers_all(SMMUState *s);
59
46
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
60
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
47
index XXXXXXX..XXXXXXX 100644
61
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/smmu-common.c
62
--- a/hw/arm/smmu-common.c
49
+++ b/hw/arm/smmu-common.c
63
+++ b/hw/arm/smmu-common.c
50
@@ -XXX,XX +XXX,XX @@ static int smmu_ptw_64_s1(SMMUTransCfg *cfg,
64
@@ -XXX,XX +XXX,XX @@ static gboolean smmu_hash_remove_by_vmid_ipa(gpointer key, gpointer value,
51
pte_addr, pte, iova, gpa,
65
((entry->iova & ~info->mask) == info->iova);
52
block_size >> 20);
66
}
53
}
67
68
+static gboolean
69
+smmu_hash_remove_by_sid_range(gpointer key, gpointer value, gpointer user_data)
70
+{
71
+ SMMUDevice *sdev = (SMMUDevice *)key;
72
+ uint32_t sid = smmu_get_sid(sdev);
73
+ SMMUSIDRange *sid_range = (SMMUSIDRange *)user_data;
54
+
74
+
55
+ /*
75
+ if (sid < sid_range->start || sid > sid_range->end) {
56
+ * QEMU does not currently implement HTTU, so if AFFD and PTE.AF
76
+ return false;
57
+ * are 0 we take an Access flag fault. (5.4. Context Descriptor)
77
+ }
58
+ * An Access flag fault takes priority over a Permission fault.
78
+ trace_smmu_config_cache_inv(sid);
59
+ */
79
+ return true;
60
+ if (!PTE_AF(pte) && !cfg->affd) {
80
+}
61
+ info->type = SMMU_PTW_ERR_ACCESS;
62
+ goto error;
63
+ }
64
+
81
+
65
ap = PTE_AP(pte);
82
+void smmu_configs_inv_sid_range(SMMUState *s, SMMUSIDRange sid_range)
66
if (is_permission_fault(ap, perm)) {
83
+{
67
info->type = SMMU_PTW_ERR_PERMISSION;
84
+ trace_smmu_configs_inv_sid_range(sid_range.start, sid_range.end);
85
+ g_hash_table_foreach_remove(s->configs, smmu_hash_remove_by_sid_range,
86
+ &sid_range);
87
+}
88
+
89
void smmu_iotlb_inv_iova(SMMUState *s, int asid, int vmid, dma_addr_t iova,
90
uint8_t tg, uint64_t num_pages, uint8_t ttl)
91
{
68
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
92
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
69
index XXXXXXX..XXXXXXX 100644
93
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/arm/smmuv3.c
94
--- a/hw/arm/smmuv3.c
71
+++ b/hw/arm/smmuv3.c
95
+++ b/hw/arm/smmuv3.c
72
@@ -XXX,XX +XXX,XX @@ static int decode_cd(SMMUTransCfg *cfg, CD *cd, SMMUEventInfo *event)
96
@@ -XXX,XX +XXX,XX @@ static void smmuv3_flush_config(SMMUDevice *sdev)
73
cfg->oas = MIN(oas2bits(SMMU_IDR5_OAS), cfg->oas);
97
SMMUv3State *s = sdev->smmu;
74
cfg->tbi = CD_TBI(cd);
98
SMMUState *bc = &s->smmu_state;
75
cfg->asid = CD_ASID(cd);
99
76
+ cfg->affd = CD_AFFD(cd);
100
- trace_smmuv3_config_cache_inv(smmu_get_sid(sdev));
77
101
+ trace_smmu_config_cache_inv(smmu_get_sid(sdev));
78
trace_smmuv3_decode_cd(cfg->oas);
102
g_hash_table_remove(bc->configs, sdev);
79
103
}
104
105
@@ -XXX,XX +XXX,XX @@ static void smmuv3_range_inval(SMMUState *s, Cmd *cmd, SMMUStage stage)
106
}
107
}
108
109
-static gboolean
110
-smmuv3_invalidate_ste(gpointer key, gpointer value, gpointer user_data)
111
-{
112
- SMMUDevice *sdev = (SMMUDevice *)key;
113
- uint32_t sid = smmu_get_sid(sdev);
114
- SMMUSIDRange *sid_range = (SMMUSIDRange *)user_data;
115
-
116
- if (sid < sid_range->start || sid > sid_range->end) {
117
- return false;
118
- }
119
- trace_smmuv3_config_cache_inv(sid);
120
- return true;
121
-}
122
-
123
static int smmuv3_cmdq_consume(SMMUv3State *s)
124
{
125
SMMUState *bs = ARM_SMMU(s);
126
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
127
sid_range.end = sid_range.start + mask;
128
129
trace_smmuv3_cmdq_cfgi_ste_range(sid_range.start, sid_range.end);
130
- g_hash_table_foreach_remove(bs->configs, smmuv3_invalidate_ste,
131
- &sid_range);
132
+ smmu_configs_inv_sid_range(bs, sid_range);
133
break;
134
}
135
case SMMU_CMD_CFGI_CD:
136
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
137
index XXXXXXX..XXXXXXX 100644
138
--- a/hw/arm/trace-events
139
+++ b/hw/arm/trace-events
140
@@ -XXX,XX +XXX,XX @@ smmu_iotlb_inv_asid_vmid(int asid, int vmid) "IOTLB invalidate asid=%d vmid=%d"
141
smmu_iotlb_inv_vmid(int vmid) "IOTLB invalidate vmid=%d"
142
smmu_iotlb_inv_vmid_s1(int vmid) "IOTLB invalidate vmid=%d"
143
smmu_iotlb_inv_iova(int asid, uint64_t addr) "IOTLB invalidate asid=%d addr=0x%"PRIx64
144
+smmu_configs_inv_sid_range(uint32_t start, uint32_t end) "Config cache INV SID range from 0x%x to 0x%x"
145
+smmu_config_cache_inv(uint32_t sid) "Config cache INV for sid=0x%x"
146
smmu_inv_notifiers_mr(const char *name) "iommu mr=%s"
147
smmu_iotlb_lookup_hit(int asid, int vmid, uint64_t addr, uint32_t hit, uint32_t miss, uint32_t p) "IOTLB cache HIT asid=%d vmid=%d addr=0x%"PRIx64" hit=%d miss=%d hit rate=%d"
148
smmu_iotlb_lookup_miss(int asid, int vmid, uint64_t addr, uint32_t hit, uint32_t miss, uint32_t p) "IOTLB cache MISS asid=%d vmid=%d addr=0x%"PRIx64" hit=%d miss=%d hit rate=%d"
149
@@ -XXX,XX +XXX,XX @@ smmuv3_cmdq_tlbi_nh(int vmid) "vmid=%d"
150
smmuv3_cmdq_tlbi_nsnh(void) ""
151
smmuv3_cmdq_tlbi_nh_asid(int asid) "asid=%d"
152
smmuv3_cmdq_tlbi_s12_vmid(int vmid) "vmid=%d"
153
-smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid=0x%x"
154
smmuv3_notify_flag_add(const char *iommu) "ADD SMMUNotifier node for iommu mr=%s"
155
smmuv3_notify_flag_del(const char *iommu) "DEL SMMUNotifier node for iommu mr=%s"
156
smmuv3_inv_notifiers_iova(const char *name, int asid, int vmid, uint64_t iova, uint8_t tg, uint64_t num_pages, int stage) "iommu mr=%s asid=%d vmid=%d iova=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64" stage=%d"
80
--
157
--
81
2.34.1
158
2.43.0
diff view generated by jsdifflib
1
We currently guard the CFG3 register read with
1
From: Keith Packard <keithp@keithp.com>
2
(scc_partno(s) == 0x524 && scc_partno(s) == 0x547)
3
which is clearly wrong as it is never true.
4
2
5
This register is present on all board types except AN524
3
The documentation says the vector is at 0xffffff80, instead of the
6
and AN527; correct the condition.
4
previous value of 0xffffffc0. That value must have been a bug because
5
the standard vector values (20, 21, 23, 25, 30) were all
6
past the end of the array.
7
7
8
Fixes: 6ac80818941829c0 ("hw/misc/mps2-scc: Implement changes for AN547")
8
Signed-off-by: Keith Packard <keithp@keithp.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20240206132931.38376-6-peter.maydell@linaro.org
13
---
11
---
14
hw/misc/mps2-scc.c | 2 +-
12
target/rx/helper.c | 2 +-
15
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
16
14
17
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
15
diff --git a/target/rx/helper.c b/target/rx/helper.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/misc/mps2-scc.c
17
--- a/target/rx/helper.c
20
+++ b/hw/misc/mps2-scc.c
18
+++ b/target/rx/helper.c
21
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
19
@@ -XXX,XX +XXX,XX @@ void rx_cpu_do_interrupt(CPUState *cs)
22
r = s->cfg2;
20
cpu_stl_data(env, env->isp, env->pc);
23
break;
21
24
case A_CFG3:
22
if (vec < 0x100) {
25
- if (scc_partno(s) == 0x524 && scc_partno(s) == 0x547) {
23
- env->pc = cpu_ldl_data(env, 0xffffffc0 + vec * 4);
26
+ if (scc_partno(s) == 0x524 || scc_partno(s) == 0x547) {
24
+ env->pc = cpu_ldl_data(env, 0xffffff80 + vec * 4);
27
/* CFG3 reserved on AN524 */
25
} else {
28
goto bad_offset;
26
env->pc = cpu_ldl_data(env, env->intb + (vec & 0xff) * 4);
29
}
27
}
30
--
28
--
31
2.34.1
29
2.43.0
32
33
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Keith Packard <keithp@keithp.com>
2
2
3
The field is encoded as [0-3], which is convenient for
3
Functions which modify TCG globals must not be marked TCG_CALL_NO_WG,
4
indexing our array of function pointers, but the true
4
as that tells the optimizer that TCG global values already loaded in
5
value is [1-4]. Adjust before calling do_mem_zpa.
5
machine registers are still valid, and so any changes which these
6
helpers make to the CPU state may be ignored.
6
7
7
Add an assert, and move the comment re passing ZT to
8
The target/rx code chooses to put (among other things) all the PSW
8
the helper back next to the relevant code.
9
bits and also ACC into globals, so the NO_WG flag on various
10
functions that touch the PSW or ACC is incorrect and must be removed.
11
This includes all the floating point helper functions, because
12
update_fpsw() will update PSW Z and S.
9
13
10
Cc: qemu-stable@nongnu.org
14
Signed-off-by: Keith Packard <keithp@keithp.com>
11
Fixes: 206adacfb8d ("target/arm: Add mte helpers for sve scalar + int loads")
15
[PMM: Clarified commit message]
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
14
Message-id: 20240207025210.8837-3-richard.henderson@linaro.org
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
---
18
target/arm/tcg/translate-sve.c | 16 ++++++++--------
19
target/rx/helper.h | 34 +++++++++++++++++-----------------
19
1 file changed, 8 insertions(+), 8 deletions(-)
20
1 file changed, 17 insertions(+), 17 deletions(-)
20
21
21
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
22
diff --git a/target/rx/helper.h b/target/rx/helper.h
22
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/tcg/translate-sve.c
24
--- a/target/rx/helper.h
24
+++ b/target/arm/tcg/translate-sve.c
25
+++ b/target/rx/helper.h
25
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
26
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(raise_privilege_violation, noreturn, env)
26
TCGv_ptr t_pg;
27
DEF_HELPER_1(wait, noreturn, env)
27
int desc = 0;
28
DEF_HELPER_2(rxint, noreturn, env, i32)
28
29
DEF_HELPER_1(rxbrk, noreturn, env)
29
- /*
30
-DEF_HELPER_FLAGS_3(fadd, TCG_CALL_NO_WG, f32, env, f32, f32)
30
- * For e.g. LD4, there are not enough arguments to pass all 4
31
-DEF_HELPER_FLAGS_3(fsub, TCG_CALL_NO_WG, f32, env, f32, f32)
31
- * registers as pointers, so encode the regno into the data field.
32
-DEF_HELPER_FLAGS_3(fmul, TCG_CALL_NO_WG, f32, env, f32, f32)
32
- * For consistency, do this even for LD1.
33
-DEF_HELPER_FLAGS_3(fdiv, TCG_CALL_NO_WG, f32, env, f32, f32)
33
- */
34
-DEF_HELPER_FLAGS_3(fcmp, TCG_CALL_NO_WG, void, env, f32, f32)
34
+ assert(mte_n >= 1 && mte_n <= 4);
35
-DEF_HELPER_FLAGS_2(ftoi, TCG_CALL_NO_WG, i32, env, f32)
35
if (s->mte_active[0]) {
36
-DEF_HELPER_FLAGS_2(round, TCG_CALL_NO_WG, i32, env, f32)
36
int msz = dtype_msz(dtype);
37
-DEF_HELPER_FLAGS_2(itof, TCG_CALL_NO_WG, f32, env, i32)
37
38
+DEF_HELPER_3(fadd, f32, env, f32, f32)
38
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
39
+DEF_HELPER_3(fsub, f32, env, f32, f32)
39
addr = clean_data_tbi(s, addr);
40
+DEF_HELPER_3(fmul, f32, env, f32, f32)
40
}
41
+DEF_HELPER_3(fdiv, f32, env, f32, f32)
41
42
+DEF_HELPER_3(fcmp, void, env, f32, f32)
42
+ /*
43
+DEF_HELPER_2(ftoi, i32, env, f32)
43
+ * For e.g. LD4, there are not enough arguments to pass all 4
44
+DEF_HELPER_2(round, i32, env, f32)
44
+ * registers as pointers, so encode the regno into the data field.
45
+DEF_HELPER_2(itof, f32, env, i32)
45
+ * For consistency, do this even for LD1.
46
DEF_HELPER_2(set_fpsw, void, env, i32)
46
+ */
47
-DEF_HELPER_FLAGS_2(racw, TCG_CALL_NO_WG, void, env, i32)
47
desc = simd_desc(vsz, vsz, zt | desc);
48
-DEF_HELPER_FLAGS_2(set_psw_rte, TCG_CALL_NO_WG, void, env, i32)
48
t_pg = tcg_temp_new_ptr();
49
-DEF_HELPER_FLAGS_2(set_psw, TCG_CALL_NO_WG, void, env, i32)
49
50
+DEF_HELPER_2(racw, void, env, i32)
50
@@ -XXX,XX +XXX,XX @@ static void do_ld_zpa(DisasContext *s, int zt, int pg,
51
+DEF_HELPER_2(set_psw_rte, void, env, i32)
51
* accessible via the instruction encoding.
52
+DEF_HELPER_2(set_psw, void, env, i32)
52
*/
53
DEF_HELPER_1(pack_psw, i32, env)
53
assert(fn != NULL);
54
-DEF_HELPER_FLAGS_3(div, TCG_CALL_NO_WG, i32, env, i32, i32)
54
- do_mem_zpa(s, zt, pg, addr, dtype, nreg, false, fn);
55
-DEF_HELPER_FLAGS_3(divu, TCG_CALL_NO_WG, i32, env, i32, i32)
55
+ do_mem_zpa(s, zt, pg, addr, dtype, nreg + 1, false, fn);
56
-DEF_HELPER_FLAGS_1(scmpu, TCG_CALL_NO_WG, void, env)
56
}
57
+DEF_HELPER_3(div, i32, env, i32, i32)
57
58
+DEF_HELPER_3(divu, i32, env, i32, i32)
58
static bool trans_LD_zprr(DisasContext *s, arg_rprr_load *a)
59
+DEF_HELPER_1(scmpu, void, env)
59
@@ -XXX,XX +XXX,XX @@ static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
60
DEF_HELPER_1(smovu, void, env)
60
if (nreg == 0) {
61
DEF_HELPER_1(smovf, void, env)
61
/* ST1 */
62
DEF_HELPER_1(smovb, void, env)
62
fn = fn_single[s->mte_active[0]][be][msz][esz];
63
DEF_HELPER_2(sstr, void, env, i32)
63
- nreg = 1;
64
-DEF_HELPER_FLAGS_2(swhile, TCG_CALL_NO_WG, void, env, i32)
64
} else {
65
-DEF_HELPER_FLAGS_2(suntil, TCG_CALL_NO_WG, void, env, i32)
65
/* ST2, ST3, ST4 -- msz == esz, enforced by encoding */
66
-DEF_HELPER_FLAGS_2(rmpa, TCG_CALL_NO_WG, void, env, i32)
66
assert(msz == esz);
67
+DEF_HELPER_2(swhile, void, env, i32)
67
fn = fn_multiple[s->mte_active[0]][be][nreg - 1][msz];
68
+DEF_HELPER_2(suntil, void, env, i32)
68
}
69
+DEF_HELPER_2(rmpa, void, env, i32)
69
assert(fn != NULL);
70
DEF_HELPER_1(satr, void, env)
70
- do_mem_zpa(s, zt, pg, addr, msz_dtype(s, msz), nreg, true, fn);
71
+ do_mem_zpa(s, zt, pg, addr, msz_dtype(s, msz), nreg + 1, true, fn);
72
}
73
74
static bool trans_ST_zprr(DisasContext *s, arg_rprr_store *a)
75
--
71
--
76
2.34.1
72
2.43.0
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Share code that creates mtedesc and embeds within simd_desc.
4
5
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
9
Message-id: 20240207025210.8837-5-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/tcg/translate-a64.h | 2 ++
13
target/arm/tcg/translate-sme.c | 15 +++--------
14
target/arm/tcg/translate-sve.c | 47 ++++++++++++++++++----------------
15
3 files changed, 31 insertions(+), 33 deletions(-)
16
17
diff --git a/target/arm/tcg/translate-a64.h b/target/arm/tcg/translate-a64.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/tcg/translate-a64.h
20
+++ b/target/arm/tcg/translate-a64.h
21
@@ -XXX,XX +XXX,XX @@ bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
22
bool sve_access_check(DisasContext *s);
23
bool sme_enabled_check(DisasContext *s);
24
bool sme_enabled_check_with_svcr(DisasContext *s, unsigned);
25
+uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
26
+ uint32_t msz, bool is_write, uint32_t data);
27
28
/* This function corresponds to CheckStreamingSVEEnabled. */
29
static inline bool sme_sm_enabled_check(DisasContext *s)
30
diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/tcg/translate-sme.c
33
+++ b/target/arm/tcg/translate-sme.c
34
@@ -XXX,XX +XXX,XX @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
35
36
TCGv_ptr t_za, t_pg;
37
TCGv_i64 addr;
38
- int svl, desc = 0;
39
+ uint32_t desc;
40
bool be = s->be_data == MO_BE;
41
bool mte = s->mte_active[0];
42
43
@@ -XXX,XX +XXX,XX @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
44
tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), a->esz);
45
tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
46
47
- if (mte) {
48
- desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
49
- desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
50
- desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
51
- desc = FIELD_DP32(desc, MTEDESC, WRITE, a->st);
52
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << a->esz) - 1);
53
- desc <<= SVE_MTEDESC_SHIFT;
54
- } else {
55
+ if (!mte) {
56
addr = clean_data_tbi(s, addr);
57
}
58
- svl = streaming_vec_reg_size(s);
59
- desc = simd_desc(svl, svl, desc);
60
+
61
+ desc = make_svemte_desc(s, streaming_vec_reg_size(s), 1, a->esz, a->st, 0);
62
63
fns[a->esz][be][a->v][mte][a->st](tcg_env, t_za, t_pg, addr,
64
tcg_constant_i32(desc));
65
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/tcg/translate-sve.c
68
+++ b/target/arm/tcg/translate-sve.c
69
@@ -XXX,XX +XXX,XX @@ static const uint8_t dtype_esz[16] = {
70
3, 2, 1, 3
71
};
72
73
-static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
74
- int dtype, uint32_t mte_n, bool is_write,
75
- gen_helper_gvec_mem *fn)
76
+uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
77
+ uint32_t msz, bool is_write, uint32_t data)
78
{
79
- unsigned vsz = vec_full_reg_size(s);
80
- TCGv_ptr t_pg;
81
uint32_t sizem1;
82
- int desc = 0;
83
+ uint32_t desc = 0;
84
85
- assert(mte_n >= 1 && mte_n <= 4);
86
- sizem1 = (mte_n << dtype_msz(dtype)) - 1;
87
+ /* Assert all of the data fits, with or without MTE enabled. */
88
+ assert(nregs >= 1 && nregs <= 4);
89
+ sizem1 = (nregs << msz) - 1;
90
assert(sizem1 <= R_MTEDESC_SIZEM1_MASK >> R_MTEDESC_SIZEM1_SHIFT);
91
+ assert(data < 1u << SVE_MTEDESC_SHIFT);
92
+
93
if (s->mte_active[0]) {
94
desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
95
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
96
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
97
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
98
desc = FIELD_DP32(desc, MTEDESC, SIZEM1, sizem1);
99
desc <<= SVE_MTEDESC_SHIFT;
100
- } else {
101
+ }
102
+ return simd_desc(vsz, vsz, desc | data);
103
+}
104
+
105
+static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
106
+ int dtype, uint32_t nregs, bool is_write,
107
+ gen_helper_gvec_mem *fn)
108
+{
109
+ TCGv_ptr t_pg;
110
+ uint32_t desc;
111
+
112
+ if (!s->mte_active[0]) {
113
addr = clean_data_tbi(s, addr);
114
}
115
116
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
117
* registers as pointers, so encode the regno into the data field.
118
* For consistency, do this even for LD1.
119
*/
120
- desc = simd_desc(vsz, vsz, zt | desc);
121
+ desc = make_svemte_desc(s, vec_full_reg_size(s), nregs,
122
+ dtype_msz(dtype), is_write, zt);
123
t_pg = tcg_temp_new_ptr();
124
125
tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg));
126
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpz(DisasContext *s, int zt, int pg, int zm,
127
int scale, TCGv_i64 scalar, int msz, bool is_write,
128
gen_helper_gvec_mem_scatter *fn)
129
{
130
- unsigned vsz = vec_full_reg_size(s);
131
TCGv_ptr t_zm = tcg_temp_new_ptr();
132
TCGv_ptr t_pg = tcg_temp_new_ptr();
133
TCGv_ptr t_zt = tcg_temp_new_ptr();
134
- int desc = 0;
135
-
136
- if (s->mte_active[0]) {
137
- desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
138
- desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
139
- desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
140
- desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
141
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << msz) - 1);
142
- desc <<= SVE_MTEDESC_SHIFT;
143
- }
144
- desc = simd_desc(vsz, vsz, desc | scale);
145
+ uint32_t desc;
146
147
tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg));
148
tcg_gen_addi_ptr(t_zm, tcg_env, vec_full_reg_offset(s, zm));
149
tcg_gen_addi_ptr(t_zt, tcg_env, vec_full_reg_offset(s, zt));
150
+
151
+ desc = make_svemte_desc(s, vec_full_reg_size(s), 1, msz, is_write, scale);
152
fn(tcg_env, t_zt, t_pg, t_zm, scalar, tcg_constant_i32(desc));
153
}
154
155
--
156
2.34.1
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
These functions "use the standard load helpers", but
4
fail to clean_data_tbi or populate mtedesc.
5
6
Cc: qemu-stable@nongnu.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
10
Message-id: 20240207025210.8837-6-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/tcg/translate-sve.c | 15 +++++++++++++--
14
1 file changed, 13 insertions(+), 2 deletions(-)
15
16
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/tcg/translate-sve.c
19
+++ b/target/arm/tcg/translate-sve.c
20
@@ -XXX,XX +XXX,XX @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
21
unsigned vsz = vec_full_reg_size(s);
22
TCGv_ptr t_pg;
23
int poff;
24
+ uint32_t desc;
25
26
/* Load the first quadword using the normal predicated load helpers. */
27
+ if (!s->mte_active[0]) {
28
+ addr = clean_data_tbi(s, addr);
29
+ }
30
+
31
poff = pred_full_reg_offset(s, pg);
32
if (vsz > 16) {
33
/*
34
@@ -XXX,XX +XXX,XX @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
35
36
gen_helper_gvec_mem *fn
37
= ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0];
38
- fn(tcg_env, t_pg, addr, tcg_constant_i32(simd_desc(16, 16, zt)));
39
+ desc = make_svemte_desc(s, 16, 1, dtype_msz(dtype), false, zt);
40
+ fn(tcg_env, t_pg, addr, tcg_constant_i32(desc));
41
42
/* Replicate that first quadword. */
43
if (vsz > 16) {
44
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
45
unsigned vsz_r32;
46
TCGv_ptr t_pg;
47
int poff, doff;
48
+ uint32_t desc;
49
50
if (vsz < 32) {
51
/*
52
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
53
}
54
55
/* Load the first octaword using the normal predicated load helpers. */
56
+ if (!s->mte_active[0]) {
57
+ addr = clean_data_tbi(s, addr);
58
+ }
59
60
poff = pred_full_reg_offset(s, pg);
61
if (vsz > 32) {
62
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
63
64
gen_helper_gvec_mem *fn
65
= ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0];
66
- fn(tcg_env, t_pg, addr, tcg_constant_i32(simd_desc(32, 32, zt)));
67
+ desc = make_svemte_desc(s, 32, 1, dtype_msz(dtype), false, zt);
68
+ fn(tcg_env, t_pg, addr, tcg_constant_i32(desc));
69
70
/*
71
* Replicate that first octaword.
72
--
73
2.34.1
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
The TBI and TCMA bits are located within mtedesc, not desc.
4
5
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
9
Message-id: 20240207025210.8837-7-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/tcg/sme_helper.c | 8 ++++----
13
target/arm/tcg/sve_helper.c | 12 ++++++------
14
2 files changed, 10 insertions(+), 10 deletions(-)
15
16
diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/tcg/sme_helper.c
19
+++ b/target/arm/tcg/sme_helper.c
20
@@ -XXX,XX +XXX,XX @@ void sme_ld1_mte(CPUARMState *env, void *za, uint64_t *vg,
21
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
22
23
/* Perform gross MTE suppression early. */
24
- if (!tbi_check(desc, bit55) ||
25
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
26
+ if (!tbi_check(mtedesc, bit55) ||
27
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
28
mtedesc = 0;
29
}
30
31
@@ -XXX,XX +XXX,XX @@ void sme_st1_mte(CPUARMState *env, void *za, uint64_t *vg, target_ulong addr,
32
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
33
34
/* Perform gross MTE suppression early. */
35
- if (!tbi_check(desc, bit55) ||
36
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
37
+ if (!tbi_check(mtedesc, bit55) ||
38
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
39
mtedesc = 0;
40
}
41
42
diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/tcg/sve_helper.c
45
+++ b/target/arm/tcg/sve_helper.c
46
@@ -XXX,XX +XXX,XX @@ void sve_ldN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
47
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
48
49
/* Perform gross MTE suppression early. */
50
- if (!tbi_check(desc, bit55) ||
51
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
52
+ if (!tbi_check(mtedesc, bit55) ||
53
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
54
mtedesc = 0;
55
}
56
57
@@ -XXX,XX +XXX,XX @@ void sve_ldnfff1_r_mte(CPUARMState *env, void *vg, target_ulong addr,
58
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
59
60
/* Perform gross MTE suppression early. */
61
- if (!tbi_check(desc, bit55) ||
62
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
63
+ if (!tbi_check(mtedesc, bit55) ||
64
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
65
mtedesc = 0;
66
}
67
68
@@ -XXX,XX +XXX,XX @@ void sve_stN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
69
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
70
71
/* Perform gross MTE suppression early. */
72
- if (!tbi_check(desc, bit55) ||
73
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
74
+ if (!tbi_check(mtedesc, bit55) ||
75
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
76
mtedesc = 0;
77
}
78
79
--
80
2.34.1
diff view generated by jsdifflib
Deleted patch
1
The raven_io_ops MemoryRegionOps is the only one in the source tree
2
which sets .valid.unaligned to indicate that it should support
3
unaligned accesses and which does not also set .impl.unaligned to
4
indicate that its read and write functions can do the unaligned
5
handling themselves. This is a problem, because at the moment the
6
core memory system does not implement the support for handling
7
unaligned accesses by doing a series of aligned accesses and
8
combining them (system/memory.c:access_with_adjusted_size() has a
9
TODO comment noting this).
10
1
11
Fortunately raven_io_read() and raven_io_write() will correctly deal
12
with the case of being passed an unaligned address, so we can fix the
13
missing unaligned access support by setting .impl.unaligned in the
14
MemoryRegionOps struct.
15
16
Fixes: 9a1839164c9c8f06 ("raven: Implement non-contiguous I/O region")
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Tested-by: Cédric Le Goater <clg@redhat.com>
19
Reviewed-by: Cédric Le Goater <clg@redhat.com>
20
Message-id: 20240112134640.1775041-1-peter.maydell@linaro.org
21
---
22
hw/pci-host/raven.c | 1 +
23
1 file changed, 1 insertion(+)
24
25
diff --git a/hw/pci-host/raven.c b/hw/pci-host/raven.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/pci-host/raven.c
28
+++ b/hw/pci-host/raven.c
29
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps raven_io_ops = {
30
.write = raven_io_write,
31
.endianness = DEVICE_LITTLE_ENDIAN,
32
.impl.max_access_size = 4,
33
+ .impl.unaligned = true,
34
.valid.unaligned = true,
35
};
36
37
--
38
2.34.1
39
40
diff view generated by jsdifflib
Deleted patch
1
Suppress the deprecation warning when we're running under qtest,
2
to avoid "make check" including warning messages in its output.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-id: 20240206154151.155620-1-peter.maydell@linaro.org
7
---
8
hw/block/tc58128.c | 4 +++-
9
1 file changed, 3 insertions(+), 1 deletion(-)
10
11
diff --git a/hw/block/tc58128.c b/hw/block/tc58128.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/block/tc58128.c
14
+++ b/hw/block/tc58128.c
15
@@ -XXX,XX +XXX,XX @@ static sh7750_io_device tc58128 = {
16
17
int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2)
18
{
19
- warn_report_once("The TC58128 flash device is deprecated");
20
+ if (!qtest_enabled()) {
21
+ warn_report_once("The TC58128 flash device is deprecated");
22
+ }
23
init_dev(&tc58128_devs[0], zone1);
24
init_dev(&tc58128_devs[1], zone2);
25
return sh7750_register_io_device(s, &tc58128);
26
--
27
2.34.1
28
29
diff view generated by jsdifflib
Deleted patch
1
We deliberately don't include qtests_npcm7xx in qtests_aarch64,
2
because we already get the coverage of those tests via qtests_arm,
3
and we don't want to use extra CI minutes testing them twice.
4
1
5
In commit 327b680877b79c4b we added it to qtests_aarch64; revert
6
that change.
7
8
Fixes: 327b680877b79c4b ("tests/qtest: Creating qtest for GMAC Module")
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20240206163043.315535-1-peter.maydell@linaro.org
12
---
13
tests/qtest/meson.build | 1 -
14
1 file changed, 1 deletion(-)
15
16
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
17
index XXXXXXX..XXXXXXX 100644
18
--- a/tests/qtest/meson.build
19
+++ b/tests/qtest/meson.build
20
@@ -XXX,XX +XXX,XX @@ qtests_aarch64 = \
21
(config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) + \
22
(config_all_accel.has_key('CONFIG_TCG') and \
23
config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \
24
- (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
25
['arm-cpu-features',
26
'numa-test',
27
'boot-serial-test',
28
--
29
2.34.1
30
31
diff view generated by jsdifflib
Deleted patch
1
Allow changes to the virt GTDT -- we are going to add the IRQ
2
entry for a new timer to it.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
6
Message-id: 20240122143537.233498-2-peter.maydell@linaro.org
7
---
8
tests/qtest/bios-tables-test-allowed-diff.h | 2 ++
9
1 file changed, 2 insertions(+)
10
11
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/tests/qtest/bios-tables-test-allowed-diff.h
14
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
15
@@ -1 +1,3 @@
16
/* List of comma-separated changed AML files to ignore */
17
+"tests/data/acpi/virt/FACP",
18
+"tests/data/acpi/virt/GTDT",
19
--
20
2.34.1
diff view generated by jsdifflib
Deleted patch
1
Update the virt golden reference files to say that the FACP is ACPI
2
v6.3, and the GTDT table is a revision 3 table with space for the
3
virtual EL2 timer.
4
1
5
Diffs from iasl:
6
7
@@ -XXX,XX +XXX,XX @@
8
/*
9
* Intel ACPI Component Architecture
10
* AML/ASL+ Disassembler version 20200925 (64-bit version)
11
* Copyright (c) 2000 - 2020 Intel Corporation
12
*
13
- * Disassembly of tests/data/acpi/virt/FACP, Mon Jan 22 13:48:40 2024
14
+ * Disassembly of /tmp/aml-W8RZH2, Mon Jan 22 13:48:40 2024
15
*
16
* ACPI Data Table [FACP]
17
*
18
* Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue
19
*/
20
21
[000h 0000 4] Signature : "FACP" [Fixed ACPI Description Table (FADT)]
22
[004h 0004 4] Table Length : 00000114
23
[008h 0008 1] Revision : 06
24
-[009h 0009 1] Checksum : 15
25
+[009h 0009 1] Checksum : 12
26
[00Ah 0010 6] Oem ID : "BOCHS "
27
[010h 0016 8] Oem Table ID : "BXPC "
28
[018h 0024 4] Oem Revision : 00000001
29
[01Ch 0028 4] Asl Compiler ID : "BXPC"
30
[020h 0032 4] Asl Compiler Revision : 00000001
31
32
[024h 0036 4] FACS Address : 00000000
33
[028h 0040 4] DSDT Address : 00000000
34
[02Ch 0044 1] Model : 00
35
[02Dh 0045 1] PM Profile : 00 [Unspecified]
36
[02Eh 0046 2] SCI Interrupt : 0000
37
[030h 0048 4] SMI Command Port : 00000000
38
[034h 0052 1] ACPI Enable Value : 00
39
[035h 0053 1] ACPI Disable Value : 00
40
[036h 0054 1] S4BIOS Command : 00
41
[037h 0055 1] P-State Control : 00
42
@@ -XXX,XX +XXX,XX @@
43
Use APIC Physical Destination Mode (V4) : 0
44
Hardware Reduced (V5) : 1
45
Low Power S0 Idle (V5) : 0
46
47
[074h 0116 12] Reset Register : [Generic Address Structure]
48
[074h 0116 1] Space ID : 00 [SystemMemory]
49
[075h 0117 1] Bit Width : 00
50
[076h 0118 1] Bit Offset : 00
51
[077h 0119 1] Encoded Access Width : 00 [Undefined/Legacy]
52
[078h 0120 8] Address : 0000000000000000
53
54
[080h 0128 1] Value to cause reset : 00
55
[081h 0129 2] ARM Flags (decoded below) : 0003
56
PSCI Compliant : 1
57
Must use HVC for PSCI : 1
58
59
-[083h 0131 1] FADT Minor Revision : 00
60
+[083h 0131 1] FADT Minor Revision : 03
61
[084h 0132 8] FACS Address : 0000000000000000
62
[08Ch 0140 8] DSDT Address : 0000000000000000
63
[094h 0148 12] PM1A Event Block : [Generic Address Structure]
64
[094h 0148 1] Space ID : 00 [SystemMemory]
65
[095h 0149 1] Bit Width : 00
66
[096h 0150 1] Bit Offset : 00
67
[097h 0151 1] Encoded Access Width : 00 [Undefined/Legacy]
68
[098h 0152 8] Address : 0000000000000000
69
70
[0A0h 0160 12] PM1B Event Block : [Generic Address Structure]
71
[0A0h 0160 1] Space ID : 00 [SystemMemory]
72
[0A1h 0161 1] Bit Width : 00
73
[0A2h 0162 1] Bit Offset : 00
74
[0A3h 0163 1] Encoded Access Width : 00 [Undefined/Legacy]
75
[0A4h 0164 8] Address : 0000000000000000
76
77
@@ -XXX,XX +XXX,XX @@
78
[0F5h 0245 1] Bit Width : 00
79
[0F6h 0246 1] Bit Offset : 00
80
[0F7h 0247 1] Encoded Access Width : 00 [Undefined/Legacy]
81
[0F8h 0248 8] Address : 0000000000000000
82
83
[100h 0256 12] Sleep Status Register : [Generic Address Structure]
84
[100h 0256 1] Space ID : 00 [SystemMemory]
85
[101h 0257 1] Bit Width : 00
86
[102h 0258 1] Bit Offset : 00
87
[103h 0259 1] Encoded Access Width : 00 [Undefined/Legacy]
88
[104h 0260 8] Address : 0000000000000000
89
90
[10Ch 0268 8] Hypervisor ID : 00000000554D4551
91
92
Raw Table Data: Length 276 (0x114)
93
94
- 0000: 46 41 43 50 14 01 00 00 06 15 42 4F 43 48 53 20 // FACP......BOCHS
95
+ 0000: 46 41 43 50 14 01 00 00 06 12 42 4F 43 48 53 20 // FACP......BOCHS
96
0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC
97
0020: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
98
0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
99
0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
100
0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
101
0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
102
0070: 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
103
- 0080: 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
104
+ 0080: 00 03 00 03 00 00 00 00 00 00 00 00 00 00 00 00 // ................
105
0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
106
00A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
107
00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
108
00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
109
00D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
110
00E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
111
00F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
112
0100: 00 00 00 00 00 00 00 00 00 00 00 00 51 45 4D 55 // ............QEMU
113
0110: 00 00 00 00 // ....
114
115
@@ -XXX,XX +XXX,XX @@
116
/*
117
* Intel ACPI Component Architecture
118
* AML/ASL+ Disassembler version 20200925 (64-bit version)
119
* Copyright (c) 2000 - 2020 Intel Corporation
120
*
121
- * Disassembly of tests/data/acpi/virt/GTDT, Mon Jan 22 13:48:40 2024
122
+ * Disassembly of /tmp/aml-XDSZH2, Mon Jan 22 13:48:40 2024
123
*
124
* ACPI Data Table [GTDT]
125
*
126
* Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue
127
*/
128
129
[000h 0000 4] Signature : "GTDT" [Generic Timer Description Table]
130
-[004h 0004 4] Table Length : 00000060
131
-[008h 0008 1] Revision : 02
132
-[009h 0009 1] Checksum : 9C
133
+[004h 0004 4] Table Length : 00000068
134
+[008h 0008 1] Revision : 03
135
+[009h 0009 1] Checksum : 93
136
[00Ah 0010 6] Oem ID : "BOCHS "
137
[010h 0016 8] Oem Table ID : "BXPC "
138
[018h 0024 4] Oem Revision : 00000001
139
[01Ch 0028 4] Asl Compiler ID : "BXPC"
140
[020h 0032 4] Asl Compiler Revision : 00000001
141
142
[024h 0036 8] Counter Block Address : FFFFFFFFFFFFFFFF
143
[02Ch 0044 4] Reserved : 00000000
144
145
[030h 0048 4] Secure EL1 Interrupt : 0000001D
146
[034h 0052 4] EL1 Flags (decoded below) : 00000000
147
Trigger Mode : 0
148
Polarity : 0
149
Always On : 0
150
151
[038h 0056 4] Non-Secure EL1 Interrupt : 0000001E
152
@@ -XXX,XX +XXX,XX @@
153
154
[040h 0064 4] Virtual Timer Interrupt : 0000001B
155
[044h 0068 4] VT Flags (decoded below) : 00000000
156
Trigger Mode : 0
157
Polarity : 0
158
Always On : 0
159
160
[048h 0072 4] Non-Secure EL2 Interrupt : 0000001A
161
[04Ch 0076 4] NEL2 Flags (decoded below) : 00000000
162
Trigger Mode : 0
163
Polarity : 0
164
Always On : 0
165
[050h 0080 8] Counter Read Block Address : FFFFFFFFFFFFFFFF
166
167
[058h 0088 4] Platform Timer Count : 00000000
168
[05Ch 0092 4] Platform Timer Offset : 00000000
169
+[060h 0096 4] Virtual EL2 Timer GSIV : 00000000
170
+[064h 0100 4] Virtual EL2 Timer Flags : 00000000
171
172
-Raw Table Data: Length 96 (0x60)
173
+Raw Table Data: Length 104 (0x68)
174
175
- 0000: 47 54 44 54 60 00 00 00 02 9C 42 4F 43 48 53 20 // GTDT`.....BOCHS
176
+ 0000: 47 54 44 54 68 00 00 00 03 93 42 4F 43 48 53 20 // GTDTh.....BOCHS
177
0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC
178
0020: 01 00 00 00 FF FF FF FF FF FF FF FF 00 00 00 00 // ................
179
0030: 1D 00 00 00 00 00 00 00 1E 00 00 00 04 00 00 00 // ................
180
0040: 1B 00 00 00 00 00 00 00 1A 00 00 00 00 00 00 00 // ................
181
0050: FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 00 // ................
182
+ 0060: 00 00 00 00 00 00 00 00 // ........
183
184
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
185
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
186
Message-id: 20240122143537.233498-4-peter.maydell@linaro.org
187
---
188
tests/qtest/bios-tables-test-allowed-diff.h | 2 --
189
tests/data/acpi/virt/FACP | Bin 276 -> 276 bytes
190
tests/data/acpi/virt/GTDT | Bin 96 -> 104 bytes
191
3 files changed, 2 deletions(-)
192
193
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
194
index XXXXXXX..XXXXXXX 100644
195
--- a/tests/qtest/bios-tables-test-allowed-diff.h
196
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
197
@@ -1,3 +1 @@
198
/* List of comma-separated changed AML files to ignore */
199
-"tests/data/acpi/virt/FACP",
200
-"tests/data/acpi/virt/GTDT",
201
diff --git a/tests/data/acpi/virt/FACP b/tests/data/acpi/virt/FACP
202
index XXXXXXX..XXXXXXX 100644
203
GIT binary patch
204
delta 25
205
gcmbQjG=+)F&CxkPgpq-PO=u!l<;2F$$vli407<0<)c^nh
206
207
delta 28
208
kcmbQjG=+)F&CxkPgpq-PO>`nx<-|!<6Akz$^DuG%0AAS!ssI20
209
210
diff --git a/tests/data/acpi/virt/GTDT b/tests/data/acpi/virt/GTDT
211
index XXXXXXX..XXXXXXX 100644
212
GIT binary patch
213
delta 25
214
bcmYeu;BpUf3CUn!U|^m+kt>V?$N&QXMtB4L
215
216
delta 16
217
Xcmc~u;BpUf2}xjJU|^avkt+-UB60)u
218
219
--
220
2.34.1
diff view generated by jsdifflib
Deleted patch
1
The patchset adding the GMAC ethernet to this SoC crossed in the
2
mail with the patchset cleaning up the NIC handling. When we
3
create the GMAC modules we must call qemu_configure_nic_device()
4
so that the user has the opportunity to use the -nic commandline
5
option to create a network backend and connect it to the GMACs.
6
1
7
Add the missing call.
8
9
Fixes: 21e5326a7c ("hw/arm: Add GMAC devices to NPCM7XX SoC")
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
12
Message-id: 20240206171231.396392-2-peter.maydell@linaro.org
13
---
14
hw/arm/npcm7xx.c | 1 +
15
1 file changed, 1 insertion(+)
16
17
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/npcm7xx.c
20
+++ b/hw/arm/npcm7xx.c
21
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
22
for (i = 0; i < ARRAY_SIZE(s->gmac); i++) {
23
SysBusDevice *sbd = SYS_BUS_DEVICE(&s->gmac[i]);
24
25
+ qemu_configure_nic_device(DEVICE(sbd), false, NULL);
26
/*
27
* The device exists regardless of whether it's connected to a QEMU
28
* netdev backend. So always instantiate it even if there is no
29
--
30
2.34.1
diff view generated by jsdifflib
Deleted patch
1
Currently QEMU will warn if there is a NIC on the board that
2
is not connected to a backend. By default the '-nic user' will
3
get used for all NICs, but if you manually connect a specific
4
NIC to a specific backend, then the other NICs on the board
5
have no backend and will be warned about:
6
1
7
qemu-system-arm: warning: nic npcm7xx-emc.1 has no peer
8
qemu-system-arm: warning: nic npcm-gmac.0 has no peer
9
qemu-system-arm: warning: nic npcm-gmac.1 has no peer
10
11
So suppress those warnings by manually connecting every NIC
12
on the board to some backend.
13
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
16
Reviewed-by: Thomas Huth <thuth@redhat.com>
17
Message-id: 20240206171231.396392-3-peter.maydell@linaro.org
18
---
19
tests/qtest/npcm7xx_emc-test.c | 5 ++++-
20
1 file changed, 4 insertions(+), 1 deletion(-)
21
22
diff --git a/tests/qtest/npcm7xx_emc-test.c b/tests/qtest/npcm7xx_emc-test.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/tests/qtest/npcm7xx_emc-test.c
25
+++ b/tests/qtest/npcm7xx_emc-test.c
26
@@ -XXX,XX +XXX,XX @@ static int *packet_test_init(int module_num, GString *cmd_line)
27
* KISS and use -nic. The driver accepts 'emc0' and 'emc1' as aliases
28
* in the 'model' field to specify the device to match.
29
*/
30
- g_string_append_printf(cmd_line, " -nic socket,fd=%d,model=emc%d ",
31
+ g_string_append_printf(cmd_line, " -nic socket,fd=%d,model=emc%d "
32
+ "-nic user,model=npcm7xx-emc "
33
+ "-nic user,model=npcm-gmac "
34
+ "-nic user,model=npcm-gmac",
35
test_sockets[1], module_num);
36
37
g_test_queue_destroy(packet_test_clear, test_sockets);
38
--
39
2.34.1
diff view generated by jsdifflib
Deleted patch
1
From: Nabih Estefan <nabihestefan@google.com>
2
1
3
Fix the nocm_gmac-test.c file to run on a nuvoton 7xx machine instead
4
of 8xx. Also fix comments referencing this and values expecting 8xx.
5
6
Change-Id: Iabd0fba14910c3f1e883c4a9521350f3db9ffab8
7
Signed-Off-By: Nabih Estefan <nabihestefan@google.com>
8
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
9
Message-id: 20240208194759.2858582-2-nabihestefan@google.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
[PMM: commit message tweaks]
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
tests/qtest/npcm_gmac-test.c | 84 +-----------------------------------
15
tests/qtest/meson.build | 3 +-
16
2 files changed, 4 insertions(+), 83 deletions(-)
17
18
diff --git a/tests/qtest/npcm_gmac-test.c b/tests/qtest/npcm_gmac-test.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/tests/qtest/npcm_gmac-test.c
21
+++ b/tests/qtest/npcm_gmac-test.c
22
@@ -XXX,XX +XXX,XX @@ typedef struct TestData {
23
const GMACModule *module;
24
} TestData;
25
26
-/* Values extracted from hw/arm/npcm8xx.c */
27
+/* Values extracted from hw/arm/npcm7xx.c */
28
static const GMACModule gmac_module_list[] = {
29
{
30
.irq = 14,
31
@@ -XXX,XX +XXX,XX @@ static const GMACModule gmac_module_list[] = {
32
.irq = 15,
33
.base_addr = 0xf0804000
34
},
35
- {
36
- .irq = 16,
37
- .base_addr = 0xf0806000
38
- },
39
- {
40
- .irq = 17,
41
- .base_addr = 0xf0808000
42
- }
43
};
44
45
/* Returns the index of the GMAC module. */
46
@@ -XXX,XX +XXX,XX @@ static uint32_t gmac_read(QTestState *qts, const GMACModule *mod,
47
return qtest_readl(qts, mod->base_addr + regno);
48
}
49
50
-static uint16_t pcs_read(QTestState *qts, const GMACModule *mod,
51
- NPCMRegister regno)
52
-{
53
- uint32_t write_value = (regno & 0x3ffe00) >> 9;
54
- qtest_writel(qts, PCS_BASE_ADDRESS + NPCM_PCS_IND_AC_BA, write_value);
55
- uint32_t read_offset = regno & 0x1ff;
56
- return qtest_readl(qts, PCS_BASE_ADDRESS + read_offset);
57
-}
58
-
59
/* Check that GMAC registers are reset to default value */
60
static void test_init(gconstpointer test_data)
61
{
62
const TestData *td = test_data;
63
const GMACModule *mod = td->module;
64
- QTestState *qts = qtest_init("-machine npcm845-evb");
65
+ QTestState *qts = qtest_init("-machine npcm750-evb");
66
67
#define CHECK_REG32(regno, value) \
68
do { \
69
g_assert_cmphex(gmac_read(qts, mod, (regno)), ==, (value)); \
70
} while (0)
71
72
-#define CHECK_REG_PCS(regno, value) \
73
- do { \
74
- g_assert_cmphex(pcs_read(qts, mod, (regno)), ==, (value)); \
75
- } while (0)
76
-
77
CHECK_REG32(NPCM_DMA_BUS_MODE, 0x00020100);
78
CHECK_REG32(NPCM_DMA_XMT_POLL_DEMAND, 0);
79
CHECK_REG32(NPCM_DMA_RCV_POLL_DEMAND, 0);
80
@@ -XXX,XX +XXX,XX @@ static void test_init(gconstpointer test_data)
81
CHECK_REG32(NPCM_GMAC_PTP_TAR, 0);
82
CHECK_REG32(NPCM_GMAC_PTP_TTSR, 0);
83
84
- /* TODO Add registers PCS */
85
- if (mod->base_addr == 0xf0802000) {
86
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID1, 0x699e);
87
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID2, 0);
88
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_STS, 0x8000);
89
-
90
- CHECK_REG_PCS(NPCM_PCS_SR_MII_CTRL, 0x1140);
91
- CHECK_REG_PCS(NPCM_PCS_SR_MII_STS, 0x0109);
92
- CHECK_REG_PCS(NPCM_PCS_SR_MII_DEV_ID1, 0x699e);
93
- CHECK_REG_PCS(NPCM_PCS_SR_MII_DEV_ID2, 0x0ced0);
94
- CHECK_REG_PCS(NPCM_PCS_SR_MII_AN_ADV, 0x0020);
95
- CHECK_REG_PCS(NPCM_PCS_SR_MII_LP_BABL, 0);
96
- CHECK_REG_PCS(NPCM_PCS_SR_MII_AN_EXPN, 0);
97
- CHECK_REG_PCS(NPCM_PCS_SR_MII_EXT_STS, 0xc000);
98
-
99
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_ABL, 0x0003);
100
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_LWR, 0x0038);
101
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_UPR, 0);
102
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_LWR, 0x0038);
103
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_UPR, 0);
104
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_LWR, 0x0058);
105
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_UPR, 0);
106
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_LWR, 0x0048);
107
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_UPR, 0);
108
-
109
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MMD_DIG_CTRL1, 0x2400);
110
- CHECK_REG_PCS(NPCM_PCS_VR_MII_AN_CTRL, 0);
111
- CHECK_REG_PCS(NPCM_PCS_VR_MII_AN_INTR_STS, 0x000a);
112
- CHECK_REG_PCS(NPCM_PCS_VR_MII_TC, 0);
113
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DBG_CTRL, 0);
114
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_MCTRL0, 0x899c);
115
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_TXTIMER, 0);
116
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_RXTIMER, 0);
117
- CHECK_REG_PCS(NPCM_PCS_VR_MII_LINK_TIMER_CTRL, 0);
118
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_MCTRL1, 0);
119
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_STS, 0x0010);
120
- CHECK_REG_PCS(NPCM_PCS_VR_MII_ICG_ERRCNT1, 0);
121
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MISC_STS, 0);
122
- CHECK_REG_PCS(NPCM_PCS_VR_MII_RX_LSTS, 0);
123
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_BSTCTRL0, 0x00a);
124
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_LVLCTRL0, 0x007f);
125
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_GENCTRL0, 0x0001);
126
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_GENCTRL1, 0);
127
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_STS, 0);
128
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_GENCTRL0, 0x0100);
129
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_GENCTRL1, 0x1100);
130
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_LOS_CTRL0, 0x000e);
131
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_CTRL0, 0x0100);
132
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_CTRL1, 0x0032);
133
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_STS, 0x0001);
134
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL2, 0);
135
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_LVL_CTRL, 0x0019);
136
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL0, 0);
137
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL1, 0);
138
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_CTRL2, 0);
139
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_ERRCNT_SEL, 0);
140
- }
141
-
142
qtest_quit(qts);
143
}
144
145
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
146
index XXXXXXX..XXXXXXX 100644
147
--- a/tests/qtest/meson.build
148
+++ b/tests/qtest/meson.build
149
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
150
'npcm7xx_sdhci-test',
151
'npcm7xx_smbus-test',
152
'npcm7xx_timer-test',
153
- 'npcm7xx_watchdog_timer-test'] + \
154
+ 'npcm7xx_watchdog_timer-test',
155
+ 'npcm_gmac-test'] + \
156
(slirp.found() ? ['npcm7xx_emc-test'] : [])
157
qtests_aspeed = \
158
['aspeed_hace-test',
159
--
160
2.34.1
diff view generated by jsdifflib
Deleted patch
1
The Cortex-R52 implements the Configuration Base Address Register
2
(CBAR), as a read-only register. Add ARM_FEATURE_CBAR_RO to this CPU
3
type, so that our implementation provides the register and the
4
associated qdev property.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20240206132931.38376-3-peter.maydell@linaro.org
9
---
10
target/arm/tcg/cpu32.c | 1 +
11
1 file changed, 1 insertion(+)
12
13
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/tcg/cpu32.c
16
+++ b/target/arm/tcg/cpu32.c
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
18
set_feature(&cpu->env, ARM_FEATURE_PMSA);
19
set_feature(&cpu->env, ARM_FEATURE_NEON);
20
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
21
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
22
cpu->midr = 0x411fd133; /* r1p3 */
23
cpu->revidr = 0x00000000;
24
cpu->reset_fpsid = 0x41034023;
25
--
26
2.34.1
diff view generated by jsdifflib
Deleted patch
1
Add documentation for the mps3-an536 board type.
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-id: 20240206132931.38376-14-peter.maydell@linaro.org
6
---
7
docs/system/arm/mps2.rst | 37 ++++++++++++++++++++++++++++++++++---
8
1 file changed, 34 insertions(+), 3 deletions(-)
9
10
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
11
index XXXXXXX..XXXXXXX 100644
12
--- a/docs/system/arm/mps2.rst
13
+++ b/docs/system/arm/mps2.rst
14
@@ -XXX,XX +XXX,XX @@
15
-Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an547``)
16
-=========================================================================================================================================================
17
+Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an536``, ``mps3-an547``)
18
+=========================================================================================================================================================================
19
20
-These board models all use Arm M-profile CPUs.
21
+These board models use Arm M-profile or R-profile CPUs.
22
23
The Arm MPS2, MPS2+ and MPS3 dev boards are FPGA based (the 2+ has a
24
bigger FPGA but is otherwise the same as the 2; the 3 has a bigger
25
@@ -XXX,XX +XXX,XX @@ FPGA image.
26
27
QEMU models the following FPGA images:
28
29
+FPGA images using M-profile CPUs:
30
+
31
``mps2-an385``
32
Cortex-M3 as documented in Arm Application Note AN385
33
``mps2-an386``
34
@@ -XXX,XX +XXX,XX @@ QEMU models the following FPGA images:
35
``mps3-an547``
36
Cortex-M55 on an MPS3, as documented in Arm Application Note AN547
37
38
+FPGA images using R-profile CPUs:
39
+
40
+``mps3-an536``
41
+ Dual Cortex-R52 on an MPS3, as documented in Arm Application Note AN536
42
+
43
Differences between QEMU and real hardware:
44
45
- AN385/AN386 remapping of low 16K of memory to either ZBT SSRAM1 or to
46
@@ -XXX,XX +XXX,XX @@ Differences between QEMU and real hardware:
47
flash, but only as simple ROM, so attempting to rewrite the flash
48
from the guest will fail
49
- QEMU does not model the USB controller in MPS3 boards
50
+- AN536 does not support runtime control of CPU reset and halt via
51
+ the SCC CFG_REG0 register.
52
+- AN536 does not support enabling or disabling the flash and ATCM
53
+ interfaces via the SCC CFG_REG1 register.
54
+- AN536 does not support setting of the initial vector table
55
+ base address via the SCC CFG_REG6 and CFG_REG7 register config,
56
+ and does not provide a mechanism for specifying these values at
57
+ startup, so all guest images must be built to start from TCM
58
+ (i.e. to expect the interrupt vector base at 0 from reset).
59
+- AN536 defaults to only creating a single CPU; this is the equivalent
60
+ of the way the real FPGA image usually runs with the second Cortex-R52
61
+ held in halt via the initial SCC CFG_REG0 register setting. You can
62
+ create the second CPU with ``-smp 2``; both CPUs will then start
63
+ execution immediately on startup.
64
+
65
+Note that for the AN536 the first UART is accessible only by
66
+CPU0, and the second UART is accessible only by CPU1. The
67
+first UART accessible shared between both CPUs is the third
68
+UART. Guest software might therefore be built to use either
69
+the first UART or the third UART; if you don't see any output
70
+from the UART you are looking at, try one of the others.
71
+(Even if the AN536 machine is started with a single CPU and so
72
+no "CPU1-only UART", the UART numbering remains the same,
73
+with the third UART being the first of the shared ones.)
74
75
Machine-specific options
76
""""""""""""""""""""""""
77
--
78
2.34.1
79
80
diff view generated by jsdifflib