1
Patches for rc1: nothing major, just some minor bugfixes and
1
Hi; here's a target-arm pullreq to go in before softfreeze.
2
code cleanups.
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).
3
5
6
thanks
4
-- PMM
7
-- PMM
5
8
6
The following changes since commit f7e1914adad8885a5d4c70239ab90d901ed97e9f:
9
The following changes since commit 98c7362b1efe651327385a25874a73e008c6549e:
7
10
8
Merge remote-tracking branch 'remotes/alistair/tags/pull-riscv-to-apply-20201109' into staging (2020-11-10 09:24:56 +0000)
11
Merge tag 'accel-cpus-20250306' of https://github.com/philmd/qemu into staging (2025-03-07 07:39:49 +0800)
9
12
10
are available in the Git repository at:
13
are available in the Git repository at:
11
14
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20201110
15
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20250307
13
16
14
for you to fetch changes up to b6c56c8a9a4064ea783f352f43c5df6231a110fa:
17
for you to fetch changes up to 0ce0739d46983e5e88fa9c149cb305689c9d8c6f:
15
18
16
target/arm/translate-neon.c: Handle VTBL UNDEF case before VFP access check (2020-11-10 11:03:48 +0000)
19
target/rx: Remove TCG_CALL_NO_WG from helpers which write env (2025-03-07 15:03:20 +0000)
17
20
18
----------------------------------------------------------------
21
----------------------------------------------------------------
19
target-arm queue:
22
target-arm queue:
20
* hw/arm/Kconfig: ARM_V7M depends on PTIMER
23
* hw/arm/smmu-common: Remove the repeated ttb field
21
* Minor coding style fixes
24
* hw/gpio: npcm7xx: fixup out-of-bounds access
22
* docs: add some notes on the sbsa-ref machine
25
* tests/functional/test_arm_sx1: Check whether the serial console is working
23
* hw/arm/virt: Remove dependency on Cortex-A15 MPCore peripherals
26
* target/arm: Fix minor bugs in generic timer register handling
24
* target/arm: Fix neon VTBL/VTBX for len > 1
27
* target/arm: Implement SEL2 physical and virtual timers
25
* hw/arm/armsse: Correct expansion MPC interrupt lines
28
* target/arm: Correct STRD, LDRD atomicity and fault behaviour
26
* hw/misc/stm32f2xx_syscfg: Remove extraneous IRQ
29
* target/arm: Make dummy debug registers RAZ, not NOP
27
* hw/arm/nseries: Remove invalid/unnecessary n8x0_uart_setup()
30
* util/qemu-timer.c: Don't warp timer from timerlist_rearm()
28
* hw/arm/musicpal: Don't connect two qemu_irqs directly to the same input
31
* include/exec/memop.h: Expand comment for MO_ATOM_SUBALIGN
29
* hw/arm/musicpal: Only use qdev_get_gpio_in() when necessary
32
* hw/arm/smmu: Introduce smmu_configs_inv_sid_range() helper
30
* hw/arm/nseries: Check return value from load_image_targphys()
33
* target/rx: Set exception vector base to 0xffffff80
31
* tests/qtest/npcm7xx_rng-test: count runs properly
34
* target/rx: Remove TCG_CALL_NO_WG from helpers which write env
32
* target/arm/translate-neon.c: Handle VTBL UNDEF case before VFP access check
33
35
34
----------------------------------------------------------------
36
----------------------------------------------------------------
35
Alex Bennée (1):
37
Alex Bennée (4):
36
docs: add some notes on the sbsa-ref machine
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
37
42
38
AlexChen (1):
43
JianChunfu (2):
39
ssi: Fix bad printf format specifiers
44
hw/arm/smmu-common: Remove the repeated ttb field
45
hw/arm/smmu: Introduce smmu_configs_inv_sid_range() helper
40
46
41
Andrew Jones (1):
47
Keith Packard (2):
42
hw/arm/Kconfig: ARM_V7M depends on PTIMER
48
target/rx: Set exception vector base to 0xffffff80
49
target/rx: Remove TCG_CALL_NO_WG from helpers which write env
43
50
44
Havard Skinnemoen (1):
51
Patrick Venture (1):
45
tests/qtest/npcm7xx_rng-test: count runs properly
52
hw/gpio: npcm7xx: fixup out-of-bounds access
46
53
47
Peter Maydell (2):
54
Peter Maydell (11):
48
hw/arm/nseries: Check return value from load_image_targphys()
55
target/arm: Apply correct timer offset when calculating deadlines
49
target/arm/translate-neon.c: Handle VTBL UNDEF case before VFP access check
56
target/arm: Don't apply CNTVOFF_EL2 for EL2_VIRT timer
57
target/arm: Make CNTPS_* UNDEF from Secure EL1 when Secure EL2 is enabled
58
target/arm: Always apply CNTVOFF_EL2 for CNTV_TVAL_EL02 accesses
59
target/arm: Refactor handling of timer offset for direct register accesses
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
50
66
51
Philippe Mathieu-Daudé (6):
67
Thomas Huth (1):
52
hw/arm/virt: Remove dependency on Cortex-A15 MPCore peripherals
68
tests/functional/test_arm_sx1: Check whether the serial console is working
53
hw/arm/armsse: Correct expansion MPC interrupt lines
54
hw/misc/stm32f2xx_syscfg: Remove extraneous IRQ
55
hw/arm/nseries: Remove invalid/unnecessary n8x0_uart_setup()
56
hw/arm/musicpal: Don't connect two qemu_irqs directly to the same input
57
hw/arm/musicpal: Only use qdev_get_gpio_in() when necessary
58
69
59
Richard Henderson (1):
70
MAINTAINERS | 1 +
60
target/arm: Fix neon VTBL/VTBX for len > 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(-)
61
94
62
Xinhao Zhang (3):
63
target/arm: add spaces around operator
64
target/arm: Don't use '#' flag of printf format
65
target/arm: add space before the open parenthesis '('
66
67
docs/system/arm/sbsa.rst | 32 ++++++++++++++++++++++
68
docs/system/target-arm.rst | 1 +
69
include/hw/misc/stm32f2xx_syscfg.h | 2 --
70
target/arm/helper.h | 2 +-
71
hw/arm/armsse.c | 3 +-
72
hw/arm/musicpal.c | 40 +++++++++++++++++----------
73
hw/arm/nseries.c | 26 ++++++++----------
74
hw/arm/stm32f205_soc.c | 1 -
75
hw/misc/stm32f2xx_syscfg.c | 2 --
76
hw/ssi/imx_spi.c | 2 +-
77
hw/ssi/xilinx_spi.c | 2 +-
78
target/arm/arch_dump.c | 8 +++---
79
target/arm/arm-semi.c | 8 +++---
80
target/arm/helper.c | 2 +-
81
target/arm/op_helper.c | 23 +++++++++-------
82
target/arm/translate-a64.c | 4 +--
83
target/arm/translate.c | 2 +-
84
tests/qtest/npcm7xx_rng-test.c | 2 +-
85
hw/arm/Kconfig | 3 +-
86
target/arm/translate-neon.c.inc | 56 ++++++++++++++------------------------
87
20 files changed, 123 insertions(+), 98 deletions(-)
88
create mode 100644 docs/system/arm/sbsa.rst
89
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: JianChunfu <jansef.jian@hj-micro.com>
2
2
3
When using a Cortex-A15, the Virt machine does not use any
3
SMMUTransCfg->ttb is never used in QEMU, TT base address
4
MPCore peripherals. Remove the dependency.
4
can be accessed by SMMUTransCfg->tt[i]->ttb.
5
5
6
Fixes: 7951c7b7c05 ("hw/arm: Express dependencies of the virt machine with Kconfig")
6
Signed-off-by: JianChunfu <jansef.jian@hj-micro.com>
7
Reported-by: Miroslav Rezanina <mrezanin@redhat.com>
7
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20250221031034.69822-1-jansef.jian@hj-micro.com
9
Message-id: 20201107114852.271922-1-philmd@redhat.com
10
Reviewed-by: Peter Maydell <peter.maydell@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/Kconfig | 1 -
11
include/hw/arm/smmu-common.h | 1 -
14
1 file changed, 1 deletion(-)
12
1 file changed, 1 deletion(-)
15
13
16
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
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/Kconfig
16
--- a/include/hw/arm/smmu-common.h
19
+++ b/hw/arm/Kconfig
17
+++ b/include/hw/arm/smmu-common.h
20
@@ -XXX,XX +XXX,XX @@ config ARM_VIRT
18
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUTransCfg {
21
imply VFIO_PLATFORM
19
/* Used by stage-1 only. */
22
imply VFIO_XGMAC
20
bool aa64; /* arch64 or aarch32 translation table */
23
imply TPM_TIS_SYSBUS
21
bool record_faults; /* record fault events */
24
- select A15MPCORE
22
- uint64_t ttb; /* TT base address */
25
select ACPI
23
uint8_t oas; /* output address width */
26
select ARM_SMMUV3
24
uint8_t tbi; /* Top Byte Ignore */
27
select GPIO_KEY
25
int asid;
28
--
26
--
29
2.20.1
27
2.43.0
30
31
diff view generated by jsdifflib
1
From: Havard Skinnemoen <hskinnemoen@google.com>
1
From: Patrick Venture <venture@google.com>
2
2
3
The number of runs is equal to the number of 0-1 and 1-0 transitions,
3
The reg isn't validated to be a possible register before
4
plus one. Currently, it's counting the number of times these transitions
4
it's dereferenced for one case. The mmio space registered
5
do _not_ happen, plus one.
5
for the gpio device is 4KiB but there aren't that many
6
registers in the struct.
6
7
7
Source:
8
Cc: qemu-stable@nongnu.org
8
https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-22r1a.pdf
9
Fixes: 526dbbe0874 ("hw/gpio: Add GPIO model for Nuvoton NPCM7xx")
9
section 2.3.4 point (3).
10
Signed-off-by: Patrick Venture <venture@google.com>
10
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Signed-off-by: Havard Skinnemoen <hskinnemoen@google.com>
12
Message-id: 20250226024603.493148-1-venture@google.com
12
Message-id: 20201103011457.2959989-2-hskinnemoen@google.com
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
14
---
16
tests/qtest/npcm7xx_rng-test.c | 2 +-
15
hw/gpio/npcm7xx_gpio.c | 3 +--
17
1 file changed, 1 insertion(+), 1 deletion(-)
16
1 file changed, 1 insertion(+), 2 deletions(-)
18
17
19
diff --git a/tests/qtest/npcm7xx_rng-test.c b/tests/qtest/npcm7xx_rng-test.c
18
diff --git a/hw/gpio/npcm7xx_gpio.c b/hw/gpio/npcm7xx_gpio.c
20
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
21
--- a/tests/qtest/npcm7xx_rng-test.c
20
--- a/hw/gpio/npcm7xx_gpio.c
22
+++ b/tests/qtest/npcm7xx_rng-test.c
21
+++ b/hw/gpio/npcm7xx_gpio.c
23
@@ -XXX,XX +XXX,XX @@ static double calc_runs_p(const unsigned long *buf, unsigned int nr_bits)
22
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_gpio_regs_write(void *opaque, hwaddr addr, uint64_t v,
24
pi = (double)nr_ones / nr_bits;
23
return;
25
26
for (k = 0; k < nr_bits - 1; k++) {
27
- vn_obs += !(test_bit(k, buf) ^ test_bit(k + 1, buf));
28
+ vn_obs += (test_bit(k, buf) ^ test_bit(k + 1, buf));
29
}
24
}
30
vn_obs += 1;
25
31
26
- diff = s->regs[reg] ^ value;
27
-
28
switch (reg) {
29
case NPCM7XX_GPIO_TLOCK1:
30
case NPCM7XX_GPIO_TLOCK2:
31
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_gpio_regs_write(void *opaque, hwaddr addr, uint64_t v,
32
case NPCM7XX_GPIO_PU:
33
case NPCM7XX_GPIO_PD:
34
case NPCM7XX_GPIO_IEM:
35
+ diff = s->regs[reg] ^ value;
36
s->regs[reg] = value;
37
npcm7xx_gpio_update_pins(s, diff);
38
break;
32
--
39
--
33
2.20.1
40
2.43.0
34
41
35
42
diff view generated by jsdifflib
1
From: AlexChen <alex.chen@huawei.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
We should use printf format specifier "%u" instead of "%d" for
3
The kernel that is used in the sx1 test prints the usual Linux log
4
argument of type "unsigned int".
4
onto the serial console, but this test currently ignores it. To
5
make sure that the serial device is working properly, let's check
6
for some strings in the output here.
5
7
6
Reported-by: Euler Robot <euler.robot@huawei.com>
8
While we're at it, also add the test to the corresponding section
7
Signed-off-by: Alex Chen <alex.chen@huawei.com>
9
in the MAINTAINERS file.
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
9
Message-id: 5FA280F5.8060902@huawei.com
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
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
15
---
12
hw/ssi/imx_spi.c | 2 +-
16
MAINTAINERS | 1 +
13
hw/ssi/xilinx_spi.c | 2 +-
17
tests/functional/test_arm_sx1.py | 7 ++++---
14
2 files changed, 2 insertions(+), 2 deletions(-)
18
2 files changed, 5 insertions(+), 3 deletions(-)
15
19
16
diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
20
diff --git a/MAINTAINERS b/MAINTAINERS
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/ssi/imx_spi.c
22
--- a/MAINTAINERS
19
+++ b/hw/ssi/imx_spi.c
23
+++ b/MAINTAINERS
20
@@ -XXX,XX +XXX,XX @@ static const char *imx_spi_reg_name(uint32_t reg)
24
@@ -XXX,XX +XXX,XX @@ S: Maintained
21
case ECSPI_MSGDATA:
25
F: hw/*/omap*
22
return "ECSPI_MSGDATA";
26
F: include/hw/arm/omap.h
23
default:
27
F: docs/system/arm/sx1.rst
24
- sprintf(unknown, "%d ?", reg);
28
+F: tests/functional/test_arm_sx1.py
25
+ sprintf(unknown, "%u ?", reg);
29
26
return unknown;
30
IPack
27
}
31
M: Alberto Garcia <berto@igalia.com>
28
}
32
diff --git a/tests/functional/test_arm_sx1.py b/tests/functional/test_arm_sx1.py
29
diff --git a/hw/ssi/xilinx_spi.c b/hw/ssi/xilinx_spi.c
33
index XXXXXXX..XXXXXXX 100755
30
index XXXXXXX..XXXXXXX 100644
34
--- a/tests/functional/test_arm_sx1.py
31
--- a/hw/ssi/xilinx_spi.c
35
+++ b/tests/functional/test_arm_sx1.py
32
+++ b/hw/ssi/xilinx_spi.c
36
@@ -XXX,XX +XXX,XX @@ def test_arm_sx1_initrd(self):
33
@@ -XXX,XX +XXX,XX @@ static void xlx_spi_update_irq(XilinxSPI *s)
37
self.vm.add_args('-append', f'kunit.enable=0 rdinit=/sbin/init {self.CONSOLE_ARGS}')
34
irq chain unless things really changed. */
38
self.vm.add_args('-no-reboot')
35
if (pending != s->irqline) {
39
self.launch_kernel(zimage_path,
36
s->irqline = pending;
40
- initrd=initrd_path)
37
- DB_PRINT("irq_change of state %d ISR:%x IER:%X\n",
41
+ initrd=initrd_path,
38
+ DB_PRINT("irq_change of state %u ISR:%x IER:%X\n",
42
+ wait_for='Boot successful')
39
pending, s->regs[R_IPISR], s->regs[R_IPIER]);
43
self.vm.wait(timeout=120)
40
qemu_set_irq(s->irq, pending);
44
41
}
45
def test_arm_sx1_sd(self):
46
@@ -XXX,XX +XXX,XX @@ def test_arm_sx1_sd(self):
47
self.vm.add_args('-no-reboot')
48
self.vm.add_args('-snapshot')
49
self.vm.add_args('-drive', f'format=raw,if=sd,file={sd_fs_path}')
50
- self.launch_kernel(zimage_path)
51
+ self.launch_kernel(zimage_path, wait_for='Boot successful')
52
self.vm.wait(timeout=120)
53
54
def test_arm_sx1_flash(self):
55
@@ -XXX,XX +XXX,XX @@ def test_arm_sx1_flash(self):
56
self.vm.add_args('-no-reboot')
57
self.vm.add_args('-snapshot')
58
self.vm.add_args('-drive', f'format=raw,if=pflash,file={flash_path}')
59
- self.launch_kernel(zimage_path)
60
+ self.launch_kernel(zimage_path, wait_for='Boot successful')
61
self.vm.wait(timeout=120)
62
63
if __name__ == '__main__':
42
--
64
--
43
2.20.1
65
2.43.0
44
66
45
67
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
When we are calculating timer deadlines, the correct definition of
2
whether or not to apply an offset to the physical count is described
3
in the Arm ARM DDI4087 rev L.a section D12.2.4.1. This is different
4
from when the offset should be applied for a direct read of the
5
counter sysreg.
2
6
3
commit 32bd322a0134 ("hw/timer/armv7m_systick: Rewrite to use ptimers")
7
We got this right for the EL1 physical timer and for the EL1 virtual
4
changed armv7m_systick to build on ptimers. Make sure we have ptimers
8
timer, but got all the rest wrong: they should be using a zero offset
5
in the build when building armv7m_systick.
9
always.
6
10
7
Signed-off-by: Andrew Jones <drjones@redhat.com>
11
Factor the offset calculation out into a function that has a comment
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
documenting exactly which offset it is calculating and which gets the
9
Message-id: 20201104103343.30392-1-drjones@redhat.com
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>
17
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
18
Message-id: 20250204125009.2281315-2-peter.maydell@linaro.org
11
---
19
---
12
hw/arm/Kconfig | 1 +
20
target/arm/helper.c | 29 +++++++++++++++++++++++++++--
13
1 file changed, 1 insertion(+)
21
1 file changed, 27 insertions(+), 2 deletions(-)
14
22
15
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
23
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/Kconfig
25
--- a/target/arm/helper.c
18
+++ b/hw/arm/Kconfig
26
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ config ZYNQ
27
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_phys_cnt_offset(CPUARMState *env)
20
28
return gt_phys_raw_cnt_offset(env);
21
config ARM_V7M
29
}
22
bool
30
23
+ select PTIMER
31
+static uint64_t gt_indirect_access_timer_offset(CPUARMState *env, int timeridx)
24
32
+{
25
config ALLWINNER_A10
33
+ /*
26
bool
34
+ * Return the timer offset to use for indirect accesses to the timer.
35
+ * This is the Offset value as defined in D12.2.4.1 "Operation of the
36
+ * CompareValue views of the timers".
37
+ *
38
+ * The condition here is not always the same as the condition for
39
+ * whether to apply an offset register when doing a direct read of
40
+ * the counter sysreg; those conditions are described in the
41
+ * access pseudocode for each counter register.
42
+ */
43
+ switch (timeridx) {
44
+ case GTIMER_PHYS:
45
+ return gt_phys_raw_cnt_offset(env);
46
+ case GTIMER_VIRT:
47
+ return env->cp15.cntvoff_el2;
48
+ case GTIMER_HYP:
49
+ case GTIMER_SEC:
50
+ case GTIMER_HYPVIRT:
51
+ return 0;
52
+ default:
53
+ g_assert_not_reached();
54
+ }
55
+}
56
+
57
static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
58
{
59
ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx];
60
@@ -XXX,XX +XXX,XX @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
61
* Timer enabled: calculate and set current ISTATUS, irq, and
62
* reset timer to when ISTATUS next has to change
63
*/
64
- uint64_t offset = timeridx == GTIMER_VIRT ?
65
- cpu->env.cp15.cntvoff_el2 : gt_phys_raw_cnt_offset(&cpu->env);
66
+ uint64_t offset = gt_indirect_access_timer_offset(&cpu->env, timeridx);
67
uint64_t count = gt_get_countervalue(&cpu->env);
68
/* Note that this must be unsigned 64 bit arithmetic: */
69
int istatus = count - offset >= gt->cval;
27
--
70
--
28
2.20.1
71
2.43.0
29
72
30
73
diff view generated by jsdifflib
1
The nseries machines have a codepath that allows them to load a
1
The CNTVOFF_EL2 offset register should only be applied for accessses
2
secondary bootloader. This code wasn't checking that the
2
to CNTVCT_EL0 and for the EL1 virtual timer (CNTV_*). We were
3
load_image_targphys() succeeded. Check the return value and report
3
incorrectly applying it for the EL2 virtual timer (CNTHV_*).
4
the error to the user.
5
4
6
While we're in the vicinity, fix the comment style of the
5
Cc: qemu-stable@nongnu.org
7
comment documenting what this image load is doing.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20250204125009.2281315-3-peter.maydell@linaro.org
9
---
10
target/arm/helper.c | 2 --
11
1 file changed, 2 deletions(-)
8
12
9
Fixes: Coverity CID 1192904
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Message-id: 20201103114918.11807-1-peter.maydell@linaro.org
13
---
14
hw/arm/nseries.c | 15 +++++++++++----
15
1 file changed, 11 insertions(+), 4 deletions(-)
16
17
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/nseries.c
15
--- a/target/arm/helper.c
20
+++ b/hw/arm/nseries.c
16
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@ static void n8x0_init(MachineState *machine,
17
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
22
/* No, wait, better start at the ROM. */
18
23
s->mpu->cpu->env.regs[15] = OMAP2_Q2_BASE + 0x400000;
19
switch (timeridx) {
24
20
case GTIMER_VIRT:
25
- /* This is intended for loading the `secondary.bin' program from
21
- case GTIMER_HYPVIRT:
26
+ /*
22
offset = gt_virt_cnt_offset(env);
27
+ * This is intended for loading the `secondary.bin' program from
23
break;
28
* Nokia images (the NOLO bootloader). The entry point seems
24
case GTIMER_PHYS:
29
* to be at OMAP2_Q2_BASE + 0x400000.
25
@@ -XXX,XX +XXX,XX @@ static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
30
*
26
31
@@ -XXX,XX +XXX,XX @@ static void n8x0_init(MachineState *machine,
27
switch (timeridx) {
32
* for them the entry point needs to be set to OMAP2_SRAM_BASE.
28
case GTIMER_VIRT:
33
*
29
- case GTIMER_HYPVIRT:
34
* The code above is for loading the `zImage' file from Nokia
30
offset = gt_virt_cnt_offset(env);
35
- * images. */
31
break;
36
- load_image_targphys(option_rom[0].name, OMAP2_Q2_BASE + 0x400000,
32
case GTIMER_PHYS:
37
- machine->ram_size - 0x400000);
38
+ * images.
39
+ */
40
+ if (load_image_targphys(option_rom[0].name,
41
+ OMAP2_Q2_BASE + 0x400000,
42
+ machine->ram_size - 0x400000) < 0) {
43
+ error_report("Failed to load secondary bootloader %s",
44
+ option_rom[0].name);
45
+ exit(EXIT_FAILURE);
46
+ }
47
48
n800_setup_nolo_tags(nolo_tags);
49
cpu_physical_memory_write(OMAP2_SRAM_BASE, nolo_tags, 0x10000);
50
--
33
--
51
2.20.1
34
2.43.0
52
35
53
36
diff view generated by jsdifflib
1
From: Xinhao Zhang <zhangxinhao1@huawei.com>
1
When we added Secure EL2 support, we missed that this needs an update
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.
2
4
3
Fix code style. Operator needs spaces both sides.
5
(Note for stable backporting: for backports to branches where
6
CP_ACCESS_UNDEFINED is not defined, the old name to use instead
7
is CP_ACCESS_TRAP_UNCATEGORIZED.)
4
8
5
Signed-off-by: Xinhao Zhang <zhangxinhao1@huawei.com>
9
Cc: qemu-stable@nongnu.org
6
Signed-off-by: Kai Deng <dengkai1@huawei.com>
7
Message-id: 20201103114529.638233-1-zhangxinhao1@huawei.com
8
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>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Message-id: 20250204125009.2281315-4-peter.maydell@linaro.org
10
---
13
---
11
target/arm/arch_dump.c | 8 ++++----
14
target/arm/helper.c | 3 +++
12
target/arm/arm-semi.c | 8 ++++----
15
1 file changed, 3 insertions(+)
13
target/arm/helper.c | 2 +-
14
3 files changed, 9 insertions(+), 9 deletions(-)
15
16
16
diff --git a/target/arm/arch_dump.c b/target/arm/arch_dump.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/arch_dump.c
19
+++ b/target/arm/arch_dump.c
20
@@ -XXX,XX +XXX,XX @@ static int aarch64_write_elf64_prfpreg(WriteCoreDumpFunction f,
21
22
for (i = 0; i < 32; ++i) {
23
uint64_t *q = aa64_vfp_qreg(env, i);
24
- note.vfp.vregs[2*i + 0] = cpu_to_dump64(s, q[0]);
25
- note.vfp.vregs[2*i + 1] = cpu_to_dump64(s, q[1]);
26
+ note.vfp.vregs[2 * i + 0] = cpu_to_dump64(s, q[0]);
27
+ note.vfp.vregs[2 * i + 1] = cpu_to_dump64(s, q[1]);
28
}
29
30
if (s->dump_info.d_endian == ELFDATA2MSB) {
31
@@ -XXX,XX +XXX,XX @@ static int aarch64_write_elf64_prfpreg(WriteCoreDumpFunction f,
32
*/
33
for (i = 0; i < 32; ++i) {
34
uint64_t tmp = note.vfp.vregs[2*i];
35
- note.vfp.vregs[2*i] = note.vfp.vregs[2*i+1];
36
- note.vfp.vregs[2*i+1] = tmp;
37
+ note.vfp.vregs[2 * i] = note.vfp.vregs[2 * i + 1];
38
+ note.vfp.vregs[2 * i + 1] = tmp;
39
}
40
}
41
42
diff --git a/target/arm/arm-semi.c b/target/arm/arm-semi.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/arm-semi.c
45
+++ b/target/arm/arm-semi.c
46
@@ -XXX,XX +XXX,XX @@ target_ulong do_arm_semihosting(CPUARMState *env)
47
if (use_gdb_syscalls()) {
48
arm_semi_open_guestfd = guestfd;
49
ret = arm_gdb_syscall(cpu, arm_semi_open_cb, "open,%s,%x,1a4", arg0,
50
- (int)arg2+1, gdb_open_modeflags[arg1]);
51
+ (int)arg2 + 1, gdb_open_modeflags[arg1]);
52
} else {
53
ret = set_swi_errno(env, open(s, open_modeflags[arg1], 0644));
54
if (ret == (uint32_t)-1) {
55
@@ -XXX,XX +XXX,XX @@ target_ulong do_arm_semihosting(CPUARMState *env)
56
GET_ARG(1);
57
if (use_gdb_syscalls()) {
58
ret = arm_gdb_syscall(cpu, arm_semi_cb, "unlink,%s",
59
- arg0, (int)arg1+1);
60
+ arg0, (int)arg1 + 1);
61
} else {
62
s = lock_user_string(arg0);
63
if (!s) {
64
@@ -XXX,XX +XXX,XX @@ target_ulong do_arm_semihosting(CPUARMState *env)
65
GET_ARG(3);
66
if (use_gdb_syscalls()) {
67
return arm_gdb_syscall(cpu, arm_semi_cb, "rename,%s,%s",
68
- arg0, (int)arg1+1, arg2, (int)arg3+1);
69
+ arg0, (int)arg1 + 1, arg2, (int)arg3 + 1);
70
} else {
71
char *s2;
72
s = lock_user_string(arg0);
73
@@ -XXX,XX +XXX,XX @@ target_ulong do_arm_semihosting(CPUARMState *env)
74
GET_ARG(1);
75
if (use_gdb_syscalls()) {
76
return arm_gdb_syscall(cpu, arm_semi_cb, "system,%s",
77
- arg0, (int)arg1+1);
78
+ arg0, (int)arg1 + 1);
79
} else {
80
s = lock_user_string(arg0);
81
if (!s) {
82
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
83
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
84
--- a/target/arm/helper.c
19
--- a/target/arm/helper.c
85
+++ b/target/arm/helper.c
20
+++ b/target/arm/helper.c
86
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(usad8)(uint32_t a, uint32_t b)
21
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gt_stimer_access(CPUARMState *env,
87
uint32_t sum;
22
if (!arm_is_secure(env)) {
88
sum = do_usad(a, b);
23
return CP_ACCESS_UNDEFINED;
89
sum += do_usad(a >> 8, b >> 8);
24
}
90
- sum += do_usad(a >> 16, b >>16);
25
+ if (arm_is_el2_enabled(env)) {
91
+ sum += do_usad(a >> 16, b >> 16);
26
+ return CP_ACCESS_UNDEFINED;
92
sum += do_usad(a >> 24, b >> 24);
27
+ }
93
return sum;
28
if (!(env->cp15.scr_el3 & SCR_ST)) {
94
}
29
return CP_ACCESS_TRAP_EL3;
30
}
95
--
31
--
96
2.20.1
32
2.43.0
97
33
98
34
diff view generated by jsdifflib
1
From: Xinhao Zhang <zhangxinhao1@huawei.com>
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
Fix code style. Don't use '#' flag of printf format ('%#') in
7
We were getting this wrong, because we ended up in
4
format strings, use '0x' prefix instead
8
gt_virt_cnt_offset() and did the E2H check.
5
9
6
Signed-off-by: Xinhao Zhang <zhangxinhao1@huawei.com>
10
Factor out the tval read/write calculation from the selection of the
7
Signed-off-by: Kai Deng <dengkai1@huawei.com>
11
offset, so that we can special case gt_virt_tval_read() and
8
Message-id: 20201103114529.638233-2-zhangxinhao1@huawei.com
12
gt_virt_tval_write() to unconditionally pass CNTVOFF_EL2.
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
14
Cc: qemu-stable@nongnu.org
10
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
11
---
18
---
12
target/arm/translate-a64.c | 4 ++--
19
target/arm/helper.c | 36 +++++++++++++++++++++++++++---------
13
1 file changed, 2 insertions(+), 2 deletions(-)
20
1 file changed, 27 insertions(+), 9 deletions(-)
14
21
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
22
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
24
--- a/target/arm/helper.c
18
+++ b/target/arm/translate-a64.c
25
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
26
@@ -XXX,XX +XXX,XX @@ static void gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
20
gen_helper_advsimd_acgt_f16(tcg_res, tcg_op1, tcg_op2, fpst);
27
gt_recalc_timer(env_archcpu(env), timeridx);
21
break;
28
}
22
default:
29
23
- fprintf(stderr, "%s: insn %#04x, fpop %#2x @ %#" PRIx64 "\n",
30
+static uint64_t do_tval_read(CPUARMState *env, int timeridx, uint64_t offset)
24
+ fprintf(stderr, "%s: insn 0x%04x, fpop 0x%2x @ 0x%" PRIx64 "\n",
31
+{
25
__func__, insn, fpopcode, s->pc_curr);
32
+ return (uint32_t)(env->cp15.c14_timer[timeridx].cval -
26
g_assert_not_reached();
33
+ (gt_get_countervalue(env) - offset));
27
}
34
+}
28
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
35
+
29
case 0x7f: /* FSQRT (vector) */
36
static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
37
int timeridx)
38
{
39
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
30
break;
40
break;
31
default:
32
- fprintf(stderr, "%s: insn %#04x fpop %#2x\n", __func__, insn, fpop);
33
+ fprintf(stderr, "%s: insn 0x%04x fpop 0x%2x\n", __func__, insn, fpop);
34
g_assert_not_reached();
35
}
41
}
36
42
43
- return (uint32_t)(env->cp15.c14_timer[timeridx].cval -
44
- (gt_get_countervalue(env) - offset));
45
+ return do_tval_read(env, timeridx, offset);
46
+}
47
+
48
+static void do_tval_write(CPUARMState *env, int timeridx, uint64_t value,
49
+ uint64_t offset)
50
+{
51
+ trace_arm_gt_tval_write(timeridx, value);
52
+ env->cp15.c14_timer[timeridx].cval = gt_get_countervalue(env) - offset +
53
+ sextract64(value, 0, 32);
54
+ gt_recalc_timer(env_archcpu(env), timeridx);
55
}
56
57
static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
58
@@ -XXX,XX +XXX,XX @@ static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
59
offset = gt_phys_cnt_offset(env);
60
break;
61
}
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);
68
}
69
70
static void gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
71
@@ -XXX,XX +XXX,XX @@ static void gt_virt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
72
73
static uint64_t gt_virt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri)
74
{
75
- return gt_tval_read(env, ri, GTIMER_VIRT);
76
+ /*
77
+ * This is CNTV_TVAL_EL02; unlike the underlying CNTV_TVAL_EL0
78
+ * we always apply CNTVOFF_EL2. Special case that here rather
79
+ * than going into the generic gt_tval_read() and then having
80
+ * to re-detect that it's this register.
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);
84
}
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,
37
--
95
--
38
2.20.1
96
2.43.0
39
97
40
98
diff view generated by jsdifflib
New patch
1
1
When reading or writing the timer registers, sometimes we need to
2
apply one of the timer offsets. Specifically, this happens for
3
direct reads of the counter registers CNTPCT_EL0 and CNTVCT_EL0 (and
4
their self-synchronized variants CNTVCTSS_EL0 and CNTPCTSS_EL0). It
5
also applies for direct reads and writes of the CNT*_TVAL_EL*
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.)
23
24
Cc: qemu-stable@nongnu.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
28
---
29
target/arm/internals.h | 5 +-
30
target/arm/helper.c | 103 +++++++++++++++++++------------------
31
target/arm/tcg/op_helper.c | 8 ++-
32
3 files changed, 62 insertions(+), 54 deletions(-)
33
34
diff --git a/target/arm/internals.h b/target/arm/internals.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/internals.h
37
+++ b/target/arm/internals.h
38
@@ -XXX,XX +XXX,XX @@ int delete_hw_watchpoint(target_ulong addr, target_ulong len, int type);
39
uint64_t gt_get_countervalue(CPUARMState *env);
40
/*
41
* Return the currently applicable offset between the system counter
42
- * and CNTVCT_EL0 (this will be either 0 or the value of CNTVOFF_EL2).
43
+ * and the counter for the specified timer, as used for direct register
44
+ * accesses.
45
*/
46
-uint64_t gt_virt_cnt_offset(CPUARMState *env);
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
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/helper.c
54
+++ b/target/arm/helper.c
55
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_phys_raw_cnt_offset(CPUARMState *env)
56
return 0;
57
}
58
59
-static uint64_t gt_phys_cnt_offset(CPUARMState *env)
60
-{
61
- if (arm_current_el(env) >= 2) {
62
- return 0;
63
- }
64
- return gt_phys_raw_cnt_offset(env);
65
-}
66
-
67
static uint64_t gt_indirect_access_timer_offset(CPUARMState *env, int timeridx)
68
{
69
/*
70
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_indirect_access_timer_offset(CPUARMState *env, int timeridx)
71
}
72
}
73
74
+uint64_t gt_direct_access_timer_offset(CPUARMState *env, int timeridx)
75
+{
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
217
--
218
2.43.0
219
220
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
The system configuration controller (SYSCFG) doesn't have
3
When FEAT_SEL2 was implemented the SEL2 timers were missed. This
4
any output IRQ (and the INTC input #71 belongs to the UART6).
4
shows up when building the latest Hafnium with SPMC_AT_EL=2. The
5
Remove the invalid code.
5
actual implementation utilises the same logic as the rest of the
6
6
timers so all we need to do is:
7
Fixes: db635521a02 ("stm32f205: Add the stm32f205 SoC")
7
8
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
- define the timers and their access functions
9
Message-id: 20201107193403.436146-3-f4bug@amsat.org
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>
16
Reviewed-by: Peter Maydell <peter.maydell@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() ]
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
24
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
26
---
13
include/hw/misc/stm32f2xx_syscfg.h | 2 --
27
include/hw/arm/bsa.h | 2 +
14
hw/arm/stm32f205_soc.c | 1 -
28
target/arm/cpu.h | 2 +
15
hw/misc/stm32f2xx_syscfg.c | 2 --
29
target/arm/gtimer.h | 4 +-
16
3 files changed, 5 deletions(-)
30
target/arm/cpu.c | 4 ++
17
31
target/arm/helper.c | 163 +++++++++++++++++++++++++++++++++++++++++++
18
diff --git a/include/hw/misc/stm32f2xx_syscfg.h b/include/hw/misc/stm32f2xx_syscfg.h
32
5 files changed, 174 insertions(+), 1 deletion(-)
19
index XXXXXXX..XXXXXXX 100644
33
20
--- a/include/hw/misc/stm32f2xx_syscfg.h
34
diff --git a/include/hw/arm/bsa.h b/include/hw/arm/bsa.h
21
+++ b/include/hw/misc/stm32f2xx_syscfg.h
35
index XXXXXXX..XXXXXXX 100644
22
@@ -XXX,XX +XXX,XX @@ struct STM32F2XXSyscfgState {
36
--- a/include/hw/arm/bsa.h
23
uint32_t syscfg_exticr3;
37
+++ b/include/hw/arm/bsa.h
24
uint32_t syscfg_exticr4;
38
@@ -XXX,XX +XXX,XX @@
25
uint32_t syscfg_cmpcr;
39
#define QEMU_ARM_BSA_H
26
-
40
27
- qemu_irq irq;
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
28
};
72
};
29
73
30
#endif /* HW_STM32F2XX_SYSCFG_H */
74
#endif
31
diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
75
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
32
index XXXXXXX..XXXXXXX 100644
76
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/arm/stm32f205_soc.c
77
--- a/target/arm/cpu.c
34
+++ b/hw/arm/stm32f205_soc.c
78
+++ b/target/arm/cpu.c
35
@@ -XXX,XX +XXX,XX @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
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);
36
}
87
}
37
busdev = SYS_BUS_DEVICE(dev);
88
#endif
38
sysbus_mmio_map(busdev, 0, 0x40013800);
89
39
- sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, 71));
90
diff --git a/target/arm/helper.c b/target/arm/helper.c
40
91
index XXXXXXX..XXXXXXX 100644
41
/* Attach UART (uses USART registers) and USART controllers */
92
--- a/target/arm/helper.c
42
for (i = 0; i < STM_NUM_USARTS; i++) {
93
+++ b/target/arm/helper.c
43
diff --git a/hw/misc/stm32f2xx_syscfg.c b/hw/misc/stm32f2xx_syscfg.c
94
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gt_stimer_access(CPUARMState *env,
44
index XXXXXXX..XXXXXXX 100644
95
}
45
--- a/hw/misc/stm32f2xx_syscfg.c
96
}
46
+++ b/hw/misc/stm32f2xx_syscfg.c
97
47
@@ -XXX,XX +XXX,XX @@ static void stm32f2xx_syscfg_init(Object *obj)
98
+static CPAccessResult gt_sel2timer_access(CPUARMState *env,
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)
48
{
138
{
49
STM32F2XXSyscfgState *s = STM32F2XX_SYSCFG(obj);
139
ARMCPU *cpu = env_archcpu(env);
50
140
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_indirect_access_timer_offset(CPUARMState *env, int timeridx)
51
- sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
141
case GTIMER_HYP:
52
-
142
case GTIMER_SEC:
53
memory_region_init_io(&s->mmio, obj, &stm32f2xx_syscfg_ops, s,
143
case GTIMER_HYPVIRT:
54
TYPE_STM32F2XX_SYSCFG, 0x400);
144
+ case GTIMER_S_EL2_PHYS:
55
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
145
+ case GTIMER_S_EL2_VIRT:
146
return 0;
147
default:
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);
160
}
161
162
+static void gt_sec_pel2_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri)
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)
219
{
220
gt_timer_reset(env, ri, GTIMER_HYPVIRT);
221
@@ -XXX,XX +XXX,XX @@ void arm_gt_stimer_cb(void *opaque)
222
gt_recalc_timer(cpu, GTIMER_SEC);
223
}
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,
56
--
299
--
57
2.20.1
300
2.43.0
58
301
59
302
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
We don't need to fill the full pic[] array if we only use
3
As we are about to add more physical and virtual timers let's make it
4
few of the interrupt lines. Directly call qdev_get_gpio_in()
4
clear what each timer does.
5
when necessary.
6
5
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20201107193403.436146-6-f4bug@amsat.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20250204125009.2281315-8-peter.maydell@linaro.org
10
[PMM: Add timer register name prefix to each comment]
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
hw/arm/musicpal.c | 25 +++++++++++++------------
14
target/arm/gtimer.h | 10 +++++-----
13
1 file changed, 13 insertions(+), 12 deletions(-)
15
1 file changed, 5 insertions(+), 5 deletions(-)
14
16
15
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
17
diff --git a/target/arm/gtimer.h b/target/arm/gtimer.h
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/musicpal.c
19
--- a/target/arm/gtimer.h
18
+++ b/hw/arm/musicpal.c
20
+++ b/target/arm/gtimer.h
19
@@ -XXX,XX +XXX,XX @@ static struct arm_boot_info musicpal_binfo = {
21
@@ -XXX,XX +XXX,XX @@
20
static void musicpal_init(MachineState *machine)
22
#define TARGET_ARM_GTIMER_H
21
{
23
22
ARMCPU *cpu;
24
enum {
23
- qemu_irq pic[32];
25
- GTIMER_PHYS = 0,
24
DeviceState *dev;
26
- GTIMER_VIRT = 1,
25
+ DeviceState *pic;
27
- GTIMER_HYP = 2,
26
DeviceState *uart_orgate;
28
- GTIMER_SEC = 3,
27
DeviceState *i2c_dev;
29
- GTIMER_HYPVIRT = 4,
28
DeviceState *lcd_dev;
30
+ GTIMER_PHYS = 0, /* CNTP_* ; EL1 physical timer */
29
@@ -XXX,XX +XXX,XX @@ static void musicpal_init(MachineState *machine)
31
+ GTIMER_VIRT = 1, /* CNTV_* ; EL1 virtual timer */
30
&error_fatal);
32
+ GTIMER_HYP = 2, /* CNTHP_* ; EL2 physical timer */
31
memory_region_add_subregion(address_space_mem, MP_SRAM_BASE, sram);
33
+ GTIMER_SEC = 3, /* CNTPS_* ; EL3 physical timer */
32
34
+ GTIMER_HYPVIRT = 4, /* CNTHV_* ; EL2 virtual timer ; only if FEAT_VHE */
33
- dev = sysbus_create_simple(TYPE_MV88W8618_PIC, MP_PIC_BASE,
35
GTIMER_S_EL2_PHYS = 5, /* CNTHPS_* ; only if FEAT_SEL2 */
34
+ pic = sysbus_create_simple(TYPE_MV88W8618_PIC, MP_PIC_BASE,
36
GTIMER_S_EL2_VIRT = 6, /* CNTHVS_* ; only if FEAT_SEL2 */
35
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
37
#define NUM_GTIMERS 7
36
- for (i = 0; i < 32; i++) {
37
- pic[i] = qdev_get_gpio_in(dev, i);
38
- }
39
- sysbus_create_varargs(TYPE_MV88W8618_PIT, MP_PIT_BASE, pic[MP_TIMER1_IRQ],
40
- pic[MP_TIMER2_IRQ], pic[MP_TIMER3_IRQ],
41
- pic[MP_TIMER4_IRQ], NULL);
42
+ sysbus_create_varargs(TYPE_MV88W8618_PIT, MP_PIT_BASE,
43
+ qdev_get_gpio_in(pic, MP_TIMER1_IRQ),
44
+ qdev_get_gpio_in(pic, MP_TIMER2_IRQ),
45
+ qdev_get_gpio_in(pic, MP_TIMER3_IRQ),
46
+ qdev_get_gpio_in(pic, MP_TIMER4_IRQ), NULL);
47
48
/* Logically OR both UART IRQs together */
49
uart_orgate = DEVICE(object_new(TYPE_OR_IRQ));
50
object_property_set_int(OBJECT(uart_orgate), "num-lines", 2, &error_fatal);
51
qdev_realize_and_unref(uart_orgate, NULL, &error_fatal);
52
- qdev_connect_gpio_out(DEVICE(uart_orgate), 0, pic[MP_UART_SHARED_IRQ]);
53
+ qdev_connect_gpio_out(DEVICE(uart_orgate), 0,
54
+ qdev_get_gpio_in(pic, MP_UART_SHARED_IRQ));
55
56
serial_mm_init(address_space_mem, MP_UART1_BASE, 2,
57
qdev_get_gpio_in(uart_orgate, 0),
58
@@ -XXX,XX +XXX,XX @@ static void musicpal_init(MachineState *machine)
59
OBJECT(get_system_memory()), &error_fatal);
60
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
61
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, MP_ETH_BASE);
62
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[MP_ETH_IRQ]);
63
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
64
+ qdev_get_gpio_in(pic, MP_ETH_IRQ));
65
66
sysbus_create_simple("mv88w8618_wlan", MP_WLAN_BASE, NULL);
67
68
sysbus_create_simple(TYPE_MUSICPAL_MISC, MP_MISC_BASE, NULL);
69
70
dev = sysbus_create_simple(TYPE_MUSICPAL_GPIO, MP_GPIO_BASE,
71
- pic[MP_GPIO_IRQ]);
72
+ qdev_get_gpio_in(pic, MP_GPIO_IRQ));
73
i2c_dev = sysbus_create_simple("gpio_i2c", -1, NULL);
74
i2c = (I2CBus *)qdev_get_child_bus(i2c_dev, "i2c");
75
76
@@ -XXX,XX +XXX,XX @@ static void musicpal_init(MachineState *machine)
77
NULL);
78
sysbus_realize_and_unref(s, &error_fatal);
79
sysbus_mmio_map(s, 0, MP_AUDIO_BASE);
80
- sysbus_connect_irq(s, 0, pic[MP_AUDIO_IRQ]);
81
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(pic, MP_AUDIO_IRQ));
82
83
musicpal_binfo.ram_size = MP_RAM_DEFAULT_SIZE;
84
arm_load_kernel(cpu, machine, &musicpal_binfo);
85
--
38
--
86
2.20.1
39
2.43.0
87
40
88
41
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
The MusicPal board code connects both of the IRQ outputs of the UART
3
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
4
to the same INTC qemu_irq. Connecting two qemu_irqs outputs directly
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
to the same input is not valid as it produces subtly wrong behaviour
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
(for instance if both the IRQ lines are high, and then one goes
6
Message-id: 20250204125009.2281315-9-peter.maydell@linaro.org
7
low, the INTC input will see this as a high-to-low transition
7
Cc: qemu-stable@nongnu.org
8
even though the second IRQ line should still be holding it high).
9
10
This kind of wiring needs an explicitly created OR gate; add one.
11
12
Inspired-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20201107193403.436146-5-f4bug@amsat.org
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
10
---
18
hw/arm/musicpal.c | 17 +++++++++++++----
11
hw/arm/virt.c | 2 ++
19
hw/arm/Kconfig | 1 +
12
1 file changed, 2 insertions(+)
20
2 files changed, 14 insertions(+), 4 deletions(-)
21
13
22
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
14
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
23
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/arm/musicpal.c
16
--- a/hw/arm/virt.c
25
+++ b/hw/arm/musicpal.c
17
+++ b/hw/arm/virt.c
26
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
27
#include "ui/console.h"
19
[GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
28
#include "hw/i2c/i2c.h"
20
[GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
29
#include "hw/irq.h"
21
[GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
30
+#include "hw/or-irq.h"
22
+ [GTIMER_S_EL2_PHYS] = ARCH_TIMER_S_EL2_IRQ,
31
#include "hw/audio/wm8750.h"
23
+ [GTIMER_S_EL2_VIRT] = ARCH_TIMER_S_EL2_VIRT_IRQ,
32
#include "sysemu/block-backend.h"
24
};
33
#include "sysemu/runstate.h"
25
34
@@ -XXX,XX +XXX,XX @@
26
for (unsigned irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
35
#define MP_TIMER4_IRQ 7
36
#define MP_EHCI_IRQ 8
37
#define MP_ETH_IRQ 9
38
-#define MP_UART1_IRQ 11
39
-#define MP_UART2_IRQ 11
40
+#define MP_UART_SHARED_IRQ 11
41
#define MP_GPIO_IRQ 12
42
#define MP_RTC_IRQ 28
43
#define MP_AUDIO_IRQ 30
44
@@ -XXX,XX +XXX,XX @@ static void musicpal_init(MachineState *machine)
45
ARMCPU *cpu;
46
qemu_irq pic[32];
47
DeviceState *dev;
48
+ DeviceState *uart_orgate;
49
DeviceState *i2c_dev;
50
DeviceState *lcd_dev;
51
DeviceState *key_dev;
52
@@ -XXX,XX +XXX,XX @@ static void musicpal_init(MachineState *machine)
53
pic[MP_TIMER2_IRQ], pic[MP_TIMER3_IRQ],
54
pic[MP_TIMER4_IRQ], NULL);
55
56
- serial_mm_init(address_space_mem, MP_UART1_BASE, 2, pic[MP_UART1_IRQ],
57
+ /* Logically OR both UART IRQs together */
58
+ uart_orgate = DEVICE(object_new(TYPE_OR_IRQ));
59
+ object_property_set_int(OBJECT(uart_orgate), "num-lines", 2, &error_fatal);
60
+ qdev_realize_and_unref(uart_orgate, NULL, &error_fatal);
61
+ qdev_connect_gpio_out(DEVICE(uart_orgate), 0, pic[MP_UART_SHARED_IRQ]);
62
+
63
+ serial_mm_init(address_space_mem, MP_UART1_BASE, 2,
64
+ qdev_get_gpio_in(uart_orgate, 0),
65
1825000, serial_hd(0), DEVICE_NATIVE_ENDIAN);
66
- serial_mm_init(address_space_mem, MP_UART2_BASE, 2, pic[MP_UART2_IRQ],
67
+ serial_mm_init(address_space_mem, MP_UART2_BASE, 2,
68
+ qdev_get_gpio_in(uart_orgate, 1),
69
1825000, serial_hd(1), DEVICE_NATIVE_ENDIAN);
70
71
/* Register flash */
72
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
73
index XXXXXXX..XXXXXXX 100644
74
--- a/hw/arm/Kconfig
75
+++ b/hw/arm/Kconfig
76
@@ -XXX,XX +XXX,XX @@ config MUSCA
77
78
config MUSICPAL
79
bool
80
+ select OR_IRQ
81
select BITBANG_I2C
82
select MARVELL_88W8618
83
select PTIMER
84
--
27
--
85
2.20.1
28
2.43.0
86
29
87
30
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
We should at least document what this machine is about.
4
5
Reviewed-by: Graeme Gregory <graeme@nuviainc.com>
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
3
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20201104165254.24822-1-alex.bennee@linaro.org
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Cc: Leif Lindholm <leif@nuviainc.com>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Cc: Shashi Mallela <shashi.mallela@linaro.org>
6
Message-id: 20250204125009.2281315-10-peter.maydell@linaro.org
10
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Cc: qemu-stable@nongnu.org
11
[PMM: fixed filename mismatch]
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
9
---
14
docs/system/arm/sbsa.rst | 32 ++++++++++++++++++++++++++++++++
10
hw/arm/sbsa-ref.c | 2 ++
15
docs/system/target-arm.rst | 1 +
11
1 file changed, 2 insertions(+)
16
2 files changed, 33 insertions(+)
17
create mode 100644 docs/system/arm/sbsa.rst
18
12
19
diff --git a/docs/system/arm/sbsa.rst b/docs/system/arm/sbsa.rst
13
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
20
new file mode 100644
21
index XXXXXXX..XXXXXXX
22
--- /dev/null
23
+++ b/docs/system/arm/sbsa.rst
24
@@ -XXX,XX +XXX,XX @@
25
+Arm Server Base System Architecture Reference board (``sbsa-ref``)
26
+==================================================================
27
+
28
+While the `virt` board is a generic board platform that doesn't match
29
+any real hardware the `sbsa-ref` board intends to look like real
30
+hardware. The `Server Base System Architecture
31
+<https://developer.arm.com/documentation/den0029/latest>` defines a
32
+minimum base line of hardware support and importantly how the firmware
33
+reports that to any operating system. It is a static system that
34
+reports a very minimal DT to the firmware for non-discoverable
35
+information about components affected by the qemu command line (i.e.
36
+cpus and memory). As a result it must have a firmware specifically
37
+built to expect a certain hardware layout (as you would in a real
38
+machine).
39
+
40
+It is intended to be a machine for developing firmware and testing
41
+standards compliance with operating systems.
42
+
43
+Supported devices
44
+"""""""""""""""""
45
+
46
+The sbsa-ref board supports:
47
+
48
+ - A configurable number of AArch64 CPUs
49
+ - GIC version 3
50
+ - System bus AHCI controller
51
+ - System bus EHCI controller
52
+ - CDROM and hard disc on AHCI bus
53
+ - E1000E ethernet card on PCIe bus
54
+ - VGA display adaptor on PCIe bus
55
+ - A generic SBSA watchdog device
56
+
57
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
58
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
59
--- a/docs/system/target-arm.rst
15
--- a/hw/arm/sbsa-ref.c
60
+++ b/docs/system/target-arm.rst
16
+++ b/hw/arm/sbsa-ref.c
61
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
17
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, MemoryRegion *mem)
62
arm/mps2
18
[GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
63
arm/musca
19
[GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
64
arm/realview
20
[GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
65
+ arm/sbsa
21
+ [GTIMER_S_EL2_PHYS] = ARCH_TIMER_S_EL2_IRQ,
66
arm/versatile
22
+ [GTIMER_S_EL2_VIRT] = ARCH_TIMER_S_EL2_VIRT_IRQ,
67
arm/vexpress
23
};
68
arm/aspeed
24
25
for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
69
--
26
--
70
2.20.1
27
2.43.0
71
28
72
29
diff view generated by jsdifflib
New patch
1
Our LDRD implementation is wrong in two respects:
1
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>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Message-id: 20250227142746.1698904-2-peter.maydell@linaro.org
30
---
31
target/arm/tcg/translate.c | 70 +++++++++++++++++++++++++-------------
32
1 file changed, 46 insertions(+), 24 deletions(-)
33
34
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/tcg/translate.c
37
+++ b/target/arm/tcg/translate.c
38
@@ -XXX,XX +XXX,XX @@ static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
39
return true;
40
}
41
42
+static void do_ldrd_load(DisasContext *s, TCGv_i32 addr, int rt, int rt2)
43
+{
44
+ /*
45
+ * LDRD is required to be an atomic 64-bit access if the
46
+ * address is 8-aligned, two atomic 32-bit accesses if
47
+ * it's only 4-aligned, and to give an alignment fault
48
+ * if it's not 4-aligned. This is MO_ALIGN_4 | MO_ATOM_SUBALIGN.
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.
64
+ */
65
+ int mem_idx = get_mem_index(s);
66
+ MemOp opc = MO_64 | MO_ALIGN_4 | MO_ATOM_SUBALIGN | s->be_data;
67
+ TCGv taddr = gen_aa32_addr(s, addr, opc);
68
+ TCGv_i64 t64 = tcg_temp_new_i64();
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);
77
+ }
78
+ store_reg(s, rt, tmp);
79
+ store_reg(s, rt2, tmp2);
80
+}
81
+
82
static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
83
{
84
- int mem_idx = get_mem_index(s);
85
- TCGv_i32 addr, tmp;
86
+ TCGv_i32 addr;
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)
91
}
92
addr = op_addr_rr_pre(s, a);
93
94
- tmp = tcg_temp_new_i32();
95
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
96
- store_reg(s, a->rt, tmp);
97
-
98
- tcg_gen_addi_i32(addr, addr, 4);
99
-
100
- tmp = tcg_temp_new_i32();
101
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
102
- store_reg(s, a->rt + 1, tmp);
103
+ do_ldrd_load(s, addr, a->rt, a->rt + 1);
104
105
/* LDRD w/ base writeback is undefined if the registers overlap. */
106
- op_addr_rr_post(s, a, addr, -4);
107
+ op_addr_rr_post(s, a, addr, 0);
108
return true;
109
}
110
111
@@ -XXX,XX +XXX,XX @@ static bool op_store_ri(DisasContext *s, arg_ldst_ri *a,
112
113
static bool op_ldrd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
114
{
115
- int mem_idx = get_mem_index(s);
116
- TCGv_i32 addr, tmp;
117
+ TCGv_i32 addr;
118
119
addr = op_addr_ri_pre(s, a);
120
121
- tmp = tcg_temp_new_i32();
122
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
123
- store_reg(s, a->rt, tmp);
124
-
125
- tcg_gen_addi_i32(addr, addr, 4);
126
-
127
- tmp = tcg_temp_new_i32();
128
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
129
- store_reg(s, rt2, tmp);
130
+ do_ldrd_load(s, addr, a->rt, rt2);
131
132
/* LDRD w/ base writeback is undefined if the registers overlap. */
133
- op_addr_ri_post(s, a, addr, -4);
134
+ op_addr_ri_post(s, a, addr, 0);
135
return true;
136
}
137
138
--
139
2.43.0
diff view generated by jsdifflib
New patch
1
Our STRD implementation doesn't correctly implement the requirement:
2
* if the address is 8-aligned the access must be a 64-bit
3
single-copy atomic access, not two 32-bit accesses
1
4
5
Rewrite the handling of STRD to use a single tcg_gen_qemu_st_i64()
6
of a value produced by concatenating the two 32 bit source registers.
7
This allows us to get the atomicity right.
8
9
As with the LDRD change, now that we don't update 'addr' in the
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().
12
13
Cc: qemu-stable@nongnu.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20250227142746.1698904-3-peter.maydell@linaro.org
17
---
18
target/arm/tcg/translate.c | 59 +++++++++++++++++++++++++-------------
19
1 file changed, 39 insertions(+), 20 deletions(-)
20
21
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/tcg/translate.c
24
+++ b/target/arm/tcg/translate.c
25
@@ -XXX,XX +XXX,XX @@ static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
26
return true;
27
}
28
29
+static void do_strd_store(DisasContext *s, TCGv_i32 addr, int rt, int rt2)
30
+{
31
+ /*
32
+ * STRD is required to be an atomic 64-bit access if the
33
+ * address is 8-aligned, two atomic 32-bit accesses if
34
+ * it's only 4-aligned, and to give an alignment fault
35
+ * if it's not 4-aligned.
36
+ * Rt is always the word from the lower address, and Rt2 the
37
+ * data from the higher address, regardless of endianness.
38
+ * So (like gen_store_exclusive) we avoid gen_aa32_ld_i64()
39
+ * so we don't get its SCTLR_B check, and instead do a 64-bit access
40
+ * using MO_BE if appropriate, using a value constructed
41
+ * by putting the two halves together in the right order.
42
+ *
43
+ * As with LDRD, the 64-bit atomicity is not required for
44
+ * M-profile, or for A-profile before LPAE, and we provide
45
+ * the higher guarantee always for simplicity.
46
+ */
47
+ int mem_idx = get_mem_index(s);
48
+ MemOp opc = MO_64 | MO_ALIGN_4 | MO_ATOM_SUBALIGN | s->be_data;
49
+ TCGv taddr = gen_aa32_addr(s, addr, opc);
50
+ TCGv_i32 t1 = load_reg(s, rt);
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
112
--
113
2.43.0
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
All the callers of op_addr_rr_post() and op_addr_ri_post() now pass in
2
zero for the address_offset, so we can remove that argument.
2
3
3
The helper function did not get updated when we reorganized
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
the vector register file for SVE. Since then, the neon dregs
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
are non-sequential and cannot be simply indexed.
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20250227142746.1698904-4-peter.maydell@linaro.org
8
---
9
target/arm/tcg/translate.c | 26 +++++++++++++-------------
10
1 file changed, 13 insertions(+), 13 deletions(-)
6
11
7
At the same time, make the helper function operate on 64-bit
12
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
8
quantities so that we do not have to call it twice.
9
10
Fixes: c39c2b9043e
11
Reported-by: Ard Biesheuvel <ardb@kernel.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
[PMM: use aa32_vfp_dreg() rather than opencoding]
14
Message-id: 20201105171126.88014-1-richard.henderson@linaro.org
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
target/arm/helper.h | 2 +-
19
target/arm/op_helper.c | 23 +++++++++--------
20
target/arm/translate-neon.c.inc | 44 +++++++++++----------------------
21
3 files changed, 29 insertions(+), 40 deletions(-)
22
23
diff --git a/target/arm/helper.h b/target/arm/helper.h
24
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/helper.h
14
--- a/target/arm/tcg/translate.c
26
+++ b/target/arm/helper.h
15
+++ b/target/arm/tcg/translate.c
27
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(rsqrte_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
16
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 op_addr_rr_pre(DisasContext *s, arg_ldst_rr *a)
28
DEF_HELPER_FLAGS_2(rsqrte_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
29
DEF_HELPER_FLAGS_1(recpe_u32, TCG_CALL_NO_RWG, i32, i32)
30
DEF_HELPER_FLAGS_1(rsqrte_u32, TCG_CALL_NO_RWG, i32, i32)
31
-DEF_HELPER_FLAGS_4(neon_tbl, TCG_CALL_NO_RWG, i32, i32, i32, ptr, i32)
32
+DEF_HELPER_FLAGS_4(neon_tbl, TCG_CALL_NO_RWG, i64, env, i32, i64, i64)
33
34
DEF_HELPER_3(shl_cc, i32, env, i32, i32)
35
DEF_HELPER_3(shr_cc, i32, env, i32, i32)
36
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/op_helper.c
39
+++ b/target/arm/op_helper.c
40
@@ -XXX,XX +XXX,XX @@ void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome,
41
cpu_loop_exit_restore(cs, ra);
42
}
17
}
43
18
44
-uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def, void *vn,
19
static void op_addr_rr_post(DisasContext *s, arg_ldst_rr *a,
45
- uint32_t maxindex)
20
- TCGv_i32 addr, int address_offset)
46
+uint64_t HELPER(neon_tbl)(CPUARMState *env, uint32_t desc,
21
+ TCGv_i32 addr)
47
+ uint64_t ireg, uint64_t def)
48
{
22
{
49
- uint32_t val, shift;
23
if (!a->p) {
50
- uint64_t *table = vn;
24
TCGv_i32 ofs = load_reg(s, a->rm);
51
+ uint64_t tmp, val = 0;
25
@@ -XXX,XX +XXX,XX @@ static void op_addr_rr_post(DisasContext *s, arg_ldst_rr *a,
52
+ uint32_t maxindex = ((desc & 3) + 1) * 8;
26
} else if (!a->w) {
53
+ uint32_t base_reg = desc >> 2;
27
return;
54
+ uint32_t shift, index, reg;
55
56
- val = 0;
57
- for (shift = 0; shift < 32; shift += 8) {
58
- uint32_t index = (ireg >> shift) & 0xff;
59
+ for (shift = 0; shift < 64; shift += 8) {
60
+ index = (ireg >> shift) & 0xff;
61
if (index < maxindex) {
62
- uint32_t tmp = (table[index >> 3] >> ((index & 7) << 3)) & 0xff;
63
- val |= tmp << shift;
64
+ reg = base_reg + (index >> 3);
65
+ tmp = *aa32_vfp_dreg(env, reg);
66
+ tmp = ((tmp >> ((index & 7) << 3)) & 0xff) << shift;
67
} else {
68
- val |= def & (0xff << shift);
69
+ tmp = def & (0xffull << shift);
70
}
71
+ val |= tmp;
72
}
28
}
73
return val;
29
- tcg_gen_addi_i32(addr, addr, address_offset);
30
store_reg(s, a->rn, addr);
74
}
31
}
75
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
32
76
index XXXXXXX..XXXXXXX 100644
33
@@ -XXX,XX +XXX,XX @@ static bool op_load_rr(DisasContext *s, arg_ldst_rr *a,
77
--- a/target/arm/translate-neon.c.inc
34
* Perform base writeback before the loaded value to
78
+++ b/target/arm/translate-neon.c.inc
35
* ensure correct behavior with overlapping index registers.
79
@@ -XXX,XX +XXX,XX @@ static bool trans_VEXT(DisasContext *s, arg_VEXT *a)
36
*/
80
37
- op_addr_rr_post(s, a, addr, 0);
81
static bool trans_VTBL(DisasContext *s, arg_VTBL *a)
38
+ op_addr_rr_post(s, a, addr);
82
{
39
store_reg_from_load(s, a->rt, tmp);
83
- int n;
84
- TCGv_i32 tmp, tmp2, tmp3, tmp4;
85
- TCGv_ptr ptr1;
86
+ TCGv_i64 val, def;
87
+ TCGv_i32 desc;
88
89
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
90
return false;
91
@@ -XXX,XX +XXX,XX @@ static bool trans_VTBL(DisasContext *s, arg_VTBL *a)
92
return true;
93
}
94
95
- n = a->len + 1;
96
- if ((a->vn + n) > 32) {
97
+ if ((a->vn + a->len + 1) > 32) {
98
/*
99
* This is UNPREDICTABLE; we choose to UNDEF to avoid the
100
* helper function running off the end of the register file.
101
*/
102
return false;
103
}
104
- n <<= 3;
105
- tmp = tcg_temp_new_i32();
106
- if (a->op) {
107
- read_neon_element32(tmp, a->vd, 0, MO_32);
108
- } else {
109
- tcg_gen_movi_i32(tmp, 0);
110
- }
111
- tmp2 = tcg_temp_new_i32();
112
- read_neon_element32(tmp2, a->vm, 0, MO_32);
113
- ptr1 = vfp_reg_ptr(true, a->vn);
114
- tmp4 = tcg_const_i32(n);
115
- gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp4);
116
117
+ desc = tcg_const_i32((a->vn << 2) | a->len);
118
+ def = tcg_temp_new_i64();
119
if (a->op) {
120
- read_neon_element32(tmp, a->vd, 1, MO_32);
121
+ read_neon_element64(def, a->vd, 0, MO_64);
122
} else {
123
- tcg_gen_movi_i32(tmp, 0);
124
+ tcg_gen_movi_i64(def, 0);
125
}
126
- tmp3 = tcg_temp_new_i32();
127
- read_neon_element32(tmp3, a->vm, 1, MO_32);
128
- gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp4);
129
- tcg_temp_free_i32(tmp);
130
- tcg_temp_free_i32(tmp4);
131
- tcg_temp_free_ptr(ptr1);
132
+ val = tcg_temp_new_i64();
133
+ read_neon_element64(val, a->vm, 0, MO_64);
134
135
- write_neon_element32(tmp2, a->vd, 0, MO_32);
136
- write_neon_element32(tmp3, a->vd, 1, MO_32);
137
- tcg_temp_free_i32(tmp2);
138
- tcg_temp_free_i32(tmp3);
139
+ gen_helper_neon_tbl(val, cpu_env, desc, val, def);
140
+ write_neon_element64(val, a->vd, 0, MO_64);
141
+
142
+ tcg_temp_free_i64(def);
143
+ tcg_temp_free_i64(val);
144
+ tcg_temp_free_i32(desc);
145
return true;
40
return true;
146
}
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)
75
{
76
+ int address_offset = 0;
77
if (!a->p) {
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;
95
}
96
@@ -XXX,XX +XXX,XX @@ static bool op_store_ri(DisasContext *s, arg_ldst_ri *a,
97
gen_aa32_st_i32(s, tmp, addr, mem_idx, mop);
98
disas_set_da_iss(s, mop, issinfo);
99
100
- op_addr_ri_post(s, a, addr, 0);
101
+ op_addr_ri_post(s, a, addr);
102
return true;
103
}
104
105
@@ -XXX,XX +XXX,XX @@ static bool op_ldrd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
106
do_ldrd_load(s, addr, a->rt, rt2);
107
108
/* LDRD w/ base writeback is undefined if the registers overlap. */
109
- op_addr_ri_post(s, a, addr, 0);
110
+ op_addr_ri_post(s, a, addr);
111
return true;
112
}
113
114
@@ -XXX,XX +XXX,XX @@ static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
115
116
do_strd_store(s, addr, a->rt, rt2);
117
118
- op_addr_ri_post(s, a, addr, 0);
119
+ op_addr_ri_post(s, a, addr);
120
return true;
121
}
147
122
148
--
123
--
149
2.20.1
124
2.43.0
150
125
151
126
diff view generated by jsdifflib
New patch
1
In debug_helper.c we provide a few dummy versions of
2
debug registers:
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
1
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
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Message-id: 20250228162424.1917269-1-peter.maydell@linaro.org
26
---
27
target/arm/debug_helper.c | 7 ++++---
28
1 file changed, 4 insertions(+), 3 deletions(-)
29
30
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/debug_helper.c
33
+++ b/target/arm/debug_helper.c
34
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
35
{ .name = "DBGVCR",
36
.cp = 14, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
37
.access = PL1_RW, .accessfn = access_tda,
38
- .type = ARM_CP_NOP },
39
+ .type = ARM_CP_CONST, .resetvalue = 0 },
40
/*
41
* Dummy MDCCINT_EL1, since we don't implement the Debug Communications
42
* Channel but Linux may try to access this register. The 32-bit
43
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
44
{ .name = "MDCCINT_EL1", .state = ARM_CP_STATE_BOTH,
45
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
46
.access = PL1_RW, .accessfn = access_tdcc,
47
- .type = ARM_CP_NOP },
48
+ .type = ARM_CP_CONST, .resetvalue = 0 },
49
/*
50
* Dummy DBGCLAIM registers.
51
* "The architecture does not define any functionality for the CLAIM tag bits.",
52
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_aa32_el1_reginfo[] = {
53
{ .name = "DBGVCR32_EL2", .state = ARM_CP_STATE_AA64,
54
.opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0,
55
.access = PL2_RW, .accessfn = access_dbgvcr32,
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 },
59
};
60
61
static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
62
--
63
2.43.0
diff view generated by jsdifflib
1
Checks for UNDEF cases should go before the "is VFP enabled?" access
1
Currently we call icount_start_warp_timer() from timerlist_rearm().
2
check, except in special cases. Move a stray UNDEF check in the VTBL
2
This produces incorrect behaviour, because timerlist_rearm() is
3
trans function up above the access check.
3
called, for instance, when a timer callback modifies its timer. We
4
cannot decide here to warp the timer forwards to the next timer
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.
4
9
10
The only valid place to choose to warp the timer forward is from the
11
main loop, when we know we have no outstanding IO or timer callbacks
12
that might be about to wake up a CPU.
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
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
42
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
43
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20201109145324.2859-1-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
8
---
47
---
9
target/arm/translate-neon.c.inc | 8 ++++----
48
util/qemu-timer.c | 4 ----
10
1 file changed, 4 insertions(+), 4 deletions(-)
49
1 file changed, 4 deletions(-)
11
50
12
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
51
diff --git a/util/qemu-timer.c b/util/qemu-timer.c
13
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-neon.c.inc
53
--- a/util/qemu-timer.c
15
+++ b/target/arm/translate-neon.c.inc
54
+++ b/util/qemu-timer.c
16
@@ -XXX,XX +XXX,XX @@ static bool trans_VTBL(DisasContext *s, arg_VTBL *a)
55
@@ -XXX,XX +XXX,XX @@ static bool timer_mod_ns_locked(QEMUTimerList *timer_list,
17
return false;
56
18
}
57
static void timerlist_rearm(QEMUTimerList *timer_list)
19
58
{
20
- if (!vfp_access_check(s)) {
59
- /* Interrupt execution to force deadline recalculation. */
21
- return true;
60
- if (icount_enabled() && timer_list->clock->type == QEMU_CLOCK_VIRTUAL) {
61
- icount_start_warp_timer();
22
- }
62
- }
23
-
63
timerlist_notify(timer_list);
24
if ((a->vn + a->len + 1) > 32) {
64
}
25
/*
65
26
* This is UNPREDICTABLE; we choose to UNDEF to avoid the
27
@@ -XXX,XX +XXX,XX @@ static bool trans_VTBL(DisasContext *s, arg_VTBL *a)
28
return false;
29
}
30
31
+ if (!vfp_access_check(s)) {
32
+ return true;
33
+ }
34
+
35
desc = tcg_const_i32((a->vn << 2) | a->len);
36
def = tcg_temp_new_i64();
37
if (a->op) {
38
--
66
--
39
2.20.1
67
2.43.0
40
68
41
69
diff view generated by jsdifflib
New patch
1
Expand the example in the comment documenting MO_ATOM_SUBALIGN,
2
to be clearer about the atomicity guarantees it represents.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20250228103222.1838913-1-peter.maydell@linaro.org
7
---
8
include/exec/memop.h | 8 ++++++--
9
1 file changed, 6 insertions(+), 2 deletions(-)
10
11
diff --git a/include/exec/memop.h b/include/exec/memop.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/include/exec/memop.h
14
+++ b/include/exec/memop.h
15
@@ -XXX,XX +XXX,XX @@ typedef enum MemOp {
16
* Depending on alignment, one or both will be single-copy atomic.
17
* This is the atomicity e.g. of Arm FEAT_LSE2 LDP.
18
* MO_ATOM_SUBALIGN: the operation is single-copy atomic by parts
19
- * by the alignment. E.g. if the address is 0 mod 4, then each
20
- * 4-byte subobject is single-copy atomic.
21
+ * by the alignment. E.g. if an 8-byte value is accessed at an
22
+ * address which is 0 mod 8, then the whole 8-byte access is
23
+ * single-copy atomic; otherwise, if it is accessed at 0 mod 4
24
+ * then each 4-byte subobject is single-copy atomic; otherwise
25
+ * if it is accessed at 0 mod 2 then the four 2-byte subobjects
26
+ * are single-copy atomic.
27
* This is the atomicity e.g. of IBM Power.
28
* MO_ATOM_NONE: the operation has no atomicity requirements.
29
*
30
--
31
2.43.0
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: JianChunfu <jansef.jian@hj-micro.com>
2
2
3
omap2420_mpu_init() introduced in commit 827df9f3c5f ("Add basic
3
Use a similar terminology smmu_hash_remove_by_sid_range() as the one
4
OMAP2 chip support") takes care of creating the 3 UARTs.
4
being used for other hash table matching functions since
5
smmuv3_invalidate_ste() name is not self explanatory, and introduce a
6
helper that invokes the g_hash_table_foreach_remove.
5
7
6
Then commit 58a26b477e9 ("Emulate a serial bluetooth HCI with H4+
8
No functional change intended.
7
extensions and attach to n8x0's UART") added n8x0_uart_setup()
8
which create the UART and connects it to an IRQ output,
9
overwritting the existing peripheral and its IRQ connection.
10
This is incorrect.
11
9
12
Fortunately we don't need to fix this, because commit 6da68df7f9b
10
Signed-off-by: JianChunfu <jansef.jian@hj-micro.com>
13
("hw/arm/nseries: Replace the bluetooth chardev with a "null"
11
Reviewed-by: Eric Auger <eric.auger@redhat.com>
14
chardev") removed the use of this peripheral. We can simply
12
Message-id: 20250228031438.3916-1-jansef.jian@hj-micro.com
15
remove the code.
16
17
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Message-id: 20201107193403.436146-4-f4bug@amsat.org
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
14
---
22
hw/arm/nseries.c | 11 -----------
15
hw/arm/smmu-internal.h | 5 -----
23
1 file changed, 11 deletions(-)
16
include/hw/arm/smmu-common.h | 6 ++++++
17
hw/arm/smmu-common.c | 21 +++++++++++++++++++++
18
hw/arm/smmuv3.c | 19 ++-----------------
19
hw/arm/trace-events | 3 ++-
20
5 files changed, 31 insertions(+), 23 deletions(-)
24
21
25
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
22
diff --git a/hw/arm/smmu-internal.h b/hw/arm/smmu-internal.h
26
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/nseries.c
24
--- a/hw/arm/smmu-internal.h
28
+++ b/hw/arm/nseries.c
25
+++ b/hw/arm/smmu-internal.h
29
@@ -XXX,XX +XXX,XX @@ static void n8x0_cbus_setup(struct n800_s *s)
26
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUIOTLBPageInvInfo {
30
cbus_attach(cbus, s->tahvo = tahvo_init(tahvo_irq, 1));
27
uint64_t mask;
28
} SMMUIOTLBPageInvInfo;
29
30
-typedef struct SMMUSIDRange {
31
- uint32_t start;
32
- uint32_t end;
33
-} SMMUSIDRange;
34
-
35
#endif
36
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/include/hw/arm/smmu-common.h
39
+++ b/include/hw/arm/smmu-common.h
40
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUIOTLBKey {
41
uint8_t level;
42
} SMMUIOTLBKey;
43
44
+typedef struct SMMUSIDRange {
45
+ uint32_t start;
46
+ uint32_t end;
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
60
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/arm/smmu-common.c
63
+++ b/hw/arm/smmu-common.c
64
@@ -XXX,XX +XXX,XX @@ static gboolean smmu_hash_remove_by_vmid_ipa(gpointer key, gpointer value,
65
((entry->iova & ~info->mask) == info->iova);
31
}
66
}
32
67
33
-static void n8x0_uart_setup(struct n800_s *s)
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;
74
+
75
+ if (sid < sid_range->start || sid > sid_range->end) {
76
+ return false;
77
+ }
78
+ trace_smmu_config_cache_inv(sid);
79
+ return true;
80
+}
81
+
82
+void smmu_configs_inv_sid_range(SMMUState *s, SMMUSIDRange sid_range)
83
+{
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
{
92
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/hw/arm/smmuv3.c
95
+++ b/hw/arm/smmuv3.c
96
@@ -XXX,XX +XXX,XX @@ static void smmuv3_flush_config(SMMUDevice *sdev)
97
SMMUv3State *s = sdev->smmu;
98
SMMUState *bc = &s->smmu_state;
99
100
- trace_smmuv3_config_cache_inv(smmu_get_sid(sdev));
101
+ trace_smmu_config_cache_inv(smmu_get_sid(sdev));
102
g_hash_table_remove(bc->configs, sdev);
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)
34
-{
111
-{
35
- Chardev *radio = qemu_chr_new("bt-dummy-uart", "null", NULL);
112
- SMMUDevice *sdev = (SMMUDevice *)key;
36
- /*
113
- uint32_t sid = smmu_get_sid(sdev);
37
- * Note: We used to connect N8X0_BT_RESET_GPIO and N8X0_BT_WKUP_GPIO
114
- SMMUSIDRange *sid_range = (SMMUSIDRange *)user_data;
38
- * here, but this code has been removed with the bluetooth backend.
115
-
39
- */
116
- if (sid < sid_range->start || sid > sid_range->end) {
40
- omap_uart_attach(s->mpu->uart[BT_UART], radio);
117
- return false;
118
- }
119
- trace_smmuv3_config_cache_inv(sid);
120
- return true;
41
-}
121
-}
42
-
122
-
43
static void n8x0_usb_setup(struct n800_s *s)
123
static int smmuv3_cmdq_consume(SMMUv3State *s)
44
{
124
{
45
SysBusDevice *dev;
125
SMMUState *bs = ARM_SMMU(s);
46
@@ -XXX,XX +XXX,XX @@ static void n8x0_init(MachineState *machine,
126
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
47
n8x0_spi_setup(s);
127
sid_range.end = sid_range.start + mask;
48
n8x0_dss_setup(s);
128
49
n8x0_cbus_setup(s);
129
trace_smmuv3_cmdq_cfgi_ste_range(sid_range.start, sid_range.end);
50
- n8x0_uart_setup(s);
130
- g_hash_table_foreach_remove(bs->configs, smmuv3_invalidate_ste,
51
if (machine_usb(machine)) {
131
- &sid_range);
52
n8x0_usb_setup(s);
132
+ smmu_configs_inv_sid_range(bs, sid_range);
53
}
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"
54
--
157
--
55
2.20.1
158
2.43.0
56
57
diff view generated by jsdifflib
1
From: Xinhao Zhang <zhangxinhao1@huawei.com>
1
From: Keith Packard <keithp@keithp.com>
2
2
3
Fix code style. Space required before the open parenthesis '('.
3
The documentation says the vector is at 0xffffff80, instead of the
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.
4
7
5
Signed-off-by: Xinhao Zhang <zhangxinhao1@huawei.com>
8
Signed-off-by: Keith Packard <keithp@keithp.com>
6
Signed-off-by: Kai Deng <dengkai1@huawei.com>
7
Message-id: 20201103114529.638233-3-zhangxinhao1@huawei.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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
---
11
---
11
target/arm/translate.c | 2 +-
12
target/rx/helper.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
diff --git a/target/rx/helper.c b/target/rx/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
17
--- a/target/rx/helper.c
17
+++ b/target/arm/translate.c
18
+++ b/target/rx/helper.c
18
@@ -XXX,XX +XXX,XX @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
19
@@ -XXX,XX +XXX,XX @@ void rx_cpu_do_interrupt(CPUState *cs)
19
- Hardware watchpoints.
20
cpu_stl_data(env, env->isp, env->pc);
20
Hardware breakpoints have already been handled and skip this code.
21
21
*/
22
if (vec < 0x100) {
22
- switch(dc->base.is_jmp) {
23
- env->pc = cpu_ldl_data(env, 0xffffffc0 + vec * 4);
23
+ switch (dc->base.is_jmp) {
24
+ env->pc = cpu_ldl_data(env, 0xffffff80 + vec * 4);
24
case DISAS_NEXT:
25
} else {
25
case DISAS_TOO_MANY:
26
env->pc = cpu_ldl_data(env, env->intb + (vec & 0xff) * 4);
26
gen_goto_tb(dc, 1, dc->base.pc_next);
27
}
27
--
28
--
28
2.20.1
29
2.43.0
29
30
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Keith Packard <keithp@keithp.com>
2
2
3
We can use one MPC per SRAM bank, but we currently only wire the
3
Functions which modify TCG globals must not be marked TCG_CALL_NO_WG,
4
IRQ from the first expansion MPC to the IRQ splitter. Fix that.
4
as that tells the optimizer that TCG global values already loaded in
5
machine registers are still valid, and so any changes which these
6
helpers make to the CPU state may be ignored.
5
7
6
Fixes: bb75e16d5e6 ("hw/arm/iotkit: Wire up MPC interrupt lines")
8
The target/rx code chooses to put (among other things) all the PSW
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
bits and also ACC into globals, so the NO_WG flag on various
8
Message-id: 20201107193403.436146-2-f4bug@amsat.org
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.
13
14
Signed-off-by: Keith Packard <keithp@keithp.com>
15
[PMM: Clarified commit message]
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
18
---
12
hw/arm/armsse.c | 3 ++-
19
target/rx/helper.h | 34 +++++++++++++++++-----------------
13
1 file changed, 2 insertions(+), 1 deletion(-)
20
1 file changed, 17 insertions(+), 17 deletions(-)
14
21
15
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
22
diff --git a/target/rx/helper.h b/target/rx/helper.h
16
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/armsse.c
24
--- a/target/rx/helper.h
18
+++ b/hw/arm/armsse.c
25
+++ b/target/rx/helper.h
19
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
26
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(raise_privilege_violation, noreturn, env)
20
qdev_get_gpio_in(dev_splitter, 0));
27
DEF_HELPER_1(wait, noreturn, env)
21
qdev_connect_gpio_out(dev_splitter, 0,
28
DEF_HELPER_2(rxint, noreturn, env, i32)
22
qdev_get_gpio_in_named(dev_secctl,
29
DEF_HELPER_1(rxbrk, noreturn, env)
23
- "mpc_status", 0));
30
-DEF_HELPER_FLAGS_3(fadd, TCG_CALL_NO_WG, f32, env, f32, f32)
24
+ "mpc_status",
31
-DEF_HELPER_FLAGS_3(fsub, TCG_CALL_NO_WG, f32, env, f32, f32)
25
+ i - IOTS_NUM_EXP_MPC));
32
-DEF_HELPER_FLAGS_3(fmul, TCG_CALL_NO_WG, f32, env, f32, f32)
26
}
33
-DEF_HELPER_FLAGS_3(fdiv, TCG_CALL_NO_WG, f32, env, f32, f32)
27
34
-DEF_HELPER_FLAGS_3(fcmp, TCG_CALL_NO_WG, void, env, f32, f32)
28
qdev_connect_gpio_out(dev_splitter, 1,
35
-DEF_HELPER_FLAGS_2(ftoi, TCG_CALL_NO_WG, i32, env, f32)
36
-DEF_HELPER_FLAGS_2(round, TCG_CALL_NO_WG, i32, env, f32)
37
-DEF_HELPER_FLAGS_2(itof, TCG_CALL_NO_WG, f32, env, i32)
38
+DEF_HELPER_3(fadd, f32, env, f32, f32)
39
+DEF_HELPER_3(fsub, f32, env, f32, f32)
40
+DEF_HELPER_3(fmul, f32, env, f32, f32)
41
+DEF_HELPER_3(fdiv, f32, env, f32, f32)
42
+DEF_HELPER_3(fcmp, void, env, f32, f32)
43
+DEF_HELPER_2(ftoi, i32, env, f32)
44
+DEF_HELPER_2(round, i32, env, f32)
45
+DEF_HELPER_2(itof, f32, env, i32)
46
DEF_HELPER_2(set_fpsw, void, env, i32)
47
-DEF_HELPER_FLAGS_2(racw, TCG_CALL_NO_WG, void, env, i32)
48
-DEF_HELPER_FLAGS_2(set_psw_rte, TCG_CALL_NO_WG, void, env, i32)
49
-DEF_HELPER_FLAGS_2(set_psw, TCG_CALL_NO_WG, void, env, i32)
50
+DEF_HELPER_2(racw, void, env, i32)
51
+DEF_HELPER_2(set_psw_rte, void, env, i32)
52
+DEF_HELPER_2(set_psw, void, env, i32)
53
DEF_HELPER_1(pack_psw, i32, env)
54
-DEF_HELPER_FLAGS_3(div, TCG_CALL_NO_WG, i32, env, i32, i32)
55
-DEF_HELPER_FLAGS_3(divu, TCG_CALL_NO_WG, i32, env, i32, i32)
56
-DEF_HELPER_FLAGS_1(scmpu, TCG_CALL_NO_WG, void, env)
57
+DEF_HELPER_3(div, i32, env, i32, i32)
58
+DEF_HELPER_3(divu, i32, env, i32, i32)
59
+DEF_HELPER_1(scmpu, void, env)
60
DEF_HELPER_1(smovu, void, env)
61
DEF_HELPER_1(smovf, void, env)
62
DEF_HELPER_1(smovb, void, env)
63
DEF_HELPER_2(sstr, void, env, i32)
64
-DEF_HELPER_FLAGS_2(swhile, TCG_CALL_NO_WG, void, env, i32)
65
-DEF_HELPER_FLAGS_2(suntil, TCG_CALL_NO_WG, void, env, i32)
66
-DEF_HELPER_FLAGS_2(rmpa, TCG_CALL_NO_WG, void, env, i32)
67
+DEF_HELPER_2(swhile, void, env, i32)
68
+DEF_HELPER_2(suntil, void, env, i32)
69
+DEF_HELPER_2(rmpa, void, env, i32)
70
DEF_HELPER_1(satr, void, env)
29
--
71
--
30
2.20.1
72
2.43.0
31
32
diff view generated by jsdifflib