1
Hi; here's a target-arm pullreq to go in before softfreeze.
1
Changes v1->v2 (fixing CI failures in v1, added a couple of
2
This is actually pretty much entirely bugfixes (since the
2
extra patches in an attempt to avoid having to do a last
3
SEL2 timers we implement here are a missing part of a feature
3
minute arm pullreq next week):
4
we claim to already implement).
4
* new patch to hopefully fix the build issue with the SVE/SME sysregs test
5
* dropped the IC IVAU test case patch
6
* new patch: fix over-length shift
7
* new patches: define neoverse-v1
5
8
6
thanks
9
thanks
7
-- PMM
10
-- PMM
8
11
9
The following changes since commit 98c7362b1efe651327385a25874a73e008c6549e:
12
The following changes since commit 2a6ae69154542caa91dd17c40fd3f5ffbec300de:
10
13
11
Merge tag 'accel-cpus-20250306' of https://github.com/philmd/qemu into staging (2025-03-07 07:39:49 +0800)
14
Merge tag 'pull-maintainer-ominbus-030723-1' of https://gitlab.com/stsquad/qemu into staging (2023-07-04 08:36:44 +0200)
12
15
13
are available in the Git repository at:
16
are available in the Git repository at:
14
17
15
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20250307
18
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230706
16
19
17
for you to fetch changes up to 0ce0739d46983e5e88fa9c149cb305689c9d8c6f:
20
for you to fetch changes up to c41077235168140cdd4a34fce9bd95c3d30efe9c:
18
21
19
target/rx: Remove TCG_CALL_NO_WG from helpers which write env (2025-03-07 15:03:20 +0000)
22
target/arm: Avoid over-length shift in arm_cpu_sve_finalize() error case (2023-07-06 13:36:51 +0100)
20
23
21
----------------------------------------------------------------
24
----------------------------------------------------------------
22
target-arm queue:
25
target-arm queue:
23
* hw/arm/smmu-common: Remove the repeated ttb field
26
* Add raw_writes ops for register whose write induce TLB maintenance
24
* hw/gpio: npcm7xx: fixup out-of-bounds access
27
* hw/arm/sbsa-ref: use XHCI to replace EHCI
25
* tests/functional/test_arm_sx1: Check whether the serial console is working
28
* Avoid splitting Zregs across lines in dump
26
* target/arm: Fix minor bugs in generic timer register handling
29
* Dump ZA[] when active
27
* target/arm: Implement SEL2 physical and virtual timers
30
* Fix SME full tile indexing
28
* target/arm: Correct STRD, LDRD atomicity and fault behaviour
31
* Handle IC IVAU to improve compatibility with JITs
29
* target/arm: Make dummy debug registers RAZ, not NOP
32
* xlnx-canfd-test: Fix code coverity issues
30
* util/qemu-timer.c: Don't warp timer from timerlist_rearm()
33
* gdbstub: Guard M-profile code with CONFIG_TCG
31
* include/exec/memop.h: Expand comment for MO_ATOM_SUBALIGN
34
* allwinner-sramc: Set class_size
32
* hw/arm/smmu: Introduce smmu_configs_inv_sid_range() helper
35
* target/xtensa: Assert that interrupt level is within bounds
33
* target/rx: Set exception vector base to 0xffffff80
36
* Avoid over-length shift in arm_cpu_sve_finalize() error case
34
* target/rx: Remove TCG_CALL_NO_WG from helpers which write env
37
* Define new 'neoverse-v1' CPU type
35
38
36
----------------------------------------------------------------
39
----------------------------------------------------------------
37
Alex Bennée (4):
40
Akihiko Odaki (1):
38
target/arm: Implement SEL2 physical and virtual timers
41
hw: arm: allwinner-sramc: Set class_size
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
42
42
43
JianChunfu (2):
43
Eric Auger (1):
44
hw/arm/smmu-common: Remove the repeated ttb field
44
target/arm: Add raw_writes ops for register whose write induce TLB maintenance
45
hw/arm/smmu: Introduce smmu_configs_inv_sid_range() helper
46
45
47
Keith Packard (2):
46
Fabiano Rosas (1):
48
target/rx: Set exception vector base to 0xffffff80
47
target/arm: gdbstub: Guard M-profile code with CONFIG_TCG
49
target/rx: Remove TCG_CALL_NO_WG from helpers which write env
50
48
51
Patrick Venture (1):
49
John Högberg (1):
52
hw/gpio: npcm7xx: fixup out-of-bounds access
50
target/arm: Handle IC IVAU to improve compatibility with JITs
53
51
54
Peter Maydell (11):
52
Peter Maydell (5):
55
target/arm: Apply correct timer offset when calculating deadlines
53
tests/tcg/aarch64/sysregs.c: Use S syntax for id_aa64zfr0_el1 and id_aa64smfr0_el1
56
target/arm: Don't apply CNTVOFF_EL2 for EL2_VIRT timer
54
target/xtensa: Assert that interrupt level is within bounds
57
target/arm: Make CNTPS_* UNDEF from Secure EL1 when Secure EL2 is enabled
55
target/arm: Suppress more TCG unimplemented features in ID registers
58
target/arm: Always apply CNTVOFF_EL2 for CNTV_TVAL_EL02 accesses
56
target/arm: Define neoverse-v1
59
target/arm: Refactor handling of timer offset for direct register accesses
57
target/arm: Avoid over-length shift in arm_cpu_sve_finalize() error case
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
66
58
67
Thomas Huth (1):
59
Richard Henderson (3):
68
tests/functional/test_arm_sx1: Check whether the serial console is working
60
target/arm: Avoid splitting Zregs across lines in dump
61
target/arm: Dump ZA[] when active
62
target/arm: Fix SME full tile indexing
69
63
70
MAINTAINERS | 1 +
64
Vikram Garhwal (1):
71
hw/arm/smmu-internal.h | 5 -
65
tests/qtest: xlnx-canfd-test: Fix code coverity issues
72
include/exec/memop.h | 8 +-
73
include/hw/arm/bsa.h | 2 +
74
include/hw/arm/smmu-common.h | 7 +-
75
target/arm/cpu.h | 2 +
76
target/arm/gtimer.h | 14 +-
77
target/arm/internals.h | 5 +-
78
target/rx/helper.h | 34 ++--
79
hw/arm/sbsa-ref.c | 2 +
80
hw/arm/smmu-common.c | 21 +++
81
hw/arm/smmuv3.c | 19 +--
82
hw/arm/virt.c | 2 +
83
hw/gpio/npcm7xx_gpio.c | 3 +-
84
target/arm/cpu.c | 4 +
85
target/arm/debug_helper.c | 7 +-
86
target/arm/helper.c | 324 ++++++++++++++++++++++++++++++++-------
87
target/arm/tcg/op_helper.c | 8 +-
88
target/arm/tcg/translate.c | 147 +++++++++++-------
89
target/rx/helper.c | 2 +-
90
util/qemu-timer.c | 4 -
91
hw/arm/trace-events | 3 +-
92
tests/functional/test_arm_sx1.py | 7 +-
93
23 files changed, 455 insertions(+), 176 deletions(-)
94
66
67
Yuquan Wang (1):
68
hw/arm/sbsa-ref: use XHCI to replace EHCI
69
70
docs/system/arm/sbsa.rst | 5 +-
71
docs/system/arm/virt.rst | 1 +
72
hw/arm/sbsa-ref.c | 24 ++++---
73
hw/arm/virt.c | 1 +
74
hw/misc/allwinner-sramc.c | 1 +
75
target/arm/cpu.c | 98 +++++++++++++++++++++--------
76
target/arm/cpu64.c | 4 +-
77
target/arm/gdbstub.c | 4 ++
78
target/arm/helper.c | 70 +++++++++++++++++----
79
target/arm/tcg/cpu64.c | 128 ++++++++++++++++++++++++++++++++++++++
80
target/arm/tcg/translate-sme.c | 24 +++++--
81
target/xtensa/exc_helper.c | 3 +
82
tests/qtest/xlnx-canfd-test.c | 33 ++++------
83
tests/tcg/aarch64/sme-outprod1.c | 83 ++++++++++++++++++++++++
84
tests/tcg/aarch64/sysregs.c | 11 ++--
85
hw/arm/Kconfig | 2 +-
86
tests/tcg/aarch64/Makefile.target | 16 ++---
87
17 files changed, 415 insertions(+), 93 deletions(-)
88
create mode 100644 tests/tcg/aarch64/sme-outprod1.c
89
diff view generated by jsdifflib
Deleted patch
1
From: JianChunfu <jansef.jian@hj-micro.com>
2
1
3
SMMUTransCfg->ttb is never used in QEMU, TT base address
4
can be accessed by SMMUTransCfg->tt[i]->ttb.
5
6
Signed-off-by: JianChunfu <jansef.jian@hj-micro.com>
7
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Message-id: 20250221031034.69822-1-jansef.jian@hj-micro.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/smmu-common.h | 1 -
12
1 file changed, 1 deletion(-)
13
14
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/smmu-common.h
17
+++ b/include/hw/arm/smmu-common.h
18
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUTransCfg {
19
/* Used by stage-1 only. */
20
bool aa64; /* arch64 or aarch32 translation table */
21
bool record_faults; /* record fault events */
22
- uint64_t ttb; /* TT base address */
23
uint8_t oas; /* output address width */
24
uint8_t tbi; /* Top Byte Ignore */
25
int asid;
26
--
27
2.43.0
diff view generated by jsdifflib
Deleted patch
1
From: Patrick Venture <venture@google.com>
2
1
3
The reg isn't validated to be a possible register before
4
it's dereferenced for one case. The mmio space registered
5
for the gpio device is 4KiB but there aren't that many
6
registers in the struct.
7
8
Cc: qemu-stable@nongnu.org
9
Fixes: 526dbbe0874 ("hw/gpio: Add GPIO model for Nuvoton NPCM7xx")
10
Signed-off-by: Patrick Venture <venture@google.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Message-id: 20250226024603.493148-1-venture@google.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/gpio/npcm7xx_gpio.c | 3 +--
16
1 file changed, 1 insertion(+), 2 deletions(-)
17
18
diff --git a/hw/gpio/npcm7xx_gpio.c b/hw/gpio/npcm7xx_gpio.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/gpio/npcm7xx_gpio.c
21
+++ b/hw/gpio/npcm7xx_gpio.c
22
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_gpio_regs_write(void *opaque, hwaddr addr, uint64_t v,
23
return;
24
}
25
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;
39
--
40
2.43.0
41
42
diff view generated by jsdifflib
Deleted patch
1
From: Thomas Huth <thuth@redhat.com>
2
1
3
The kernel that is used in the sx1 test prints the usual Linux log
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.
7
8
While we're at it, also add the test to the corresponding section
9
in the MAINTAINERS file.
10
11
Signed-off-by: Thomas Huth <thuth@redhat.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Message-id: 20250226104833.1176253-1-thuth@redhat.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
MAINTAINERS | 1 +
17
tests/functional/test_arm_sx1.py | 7 ++++---
18
2 files changed, 5 insertions(+), 3 deletions(-)
19
20
diff --git a/MAINTAINERS b/MAINTAINERS
21
index XXXXXXX..XXXXXXX 100644
22
--- a/MAINTAINERS
23
+++ b/MAINTAINERS
24
@@ -XXX,XX +XXX,XX @@ S: Maintained
25
F: hw/*/omap*
26
F: include/hw/arm/omap.h
27
F: docs/system/arm/sx1.rst
28
+F: tests/functional/test_arm_sx1.py
29
30
IPack
31
M: Alberto Garcia <berto@igalia.com>
32
diff --git a/tests/functional/test_arm_sx1.py b/tests/functional/test_arm_sx1.py
33
index XXXXXXX..XXXXXXX 100755
34
--- a/tests/functional/test_arm_sx1.py
35
+++ b/tests/functional/test_arm_sx1.py
36
@@ -XXX,XX +XXX,XX @@ def test_arm_sx1_initrd(self):
37
self.vm.add_args('-append', f'kunit.enable=0 rdinit=/sbin/init {self.CONSOLE_ARGS}')
38
self.vm.add_args('-no-reboot')
39
self.launch_kernel(zimage_path,
40
- initrd=initrd_path)
41
+ initrd=initrd_path,
42
+ wait_for='Boot successful')
43
self.vm.wait(timeout=120)
44
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__':
64
--
65
2.43.0
66
67
diff view generated by jsdifflib
1
When we added Secure EL2 support, we missed that this needs an update
1
From: Eric Auger <eric.auger@redhat.com>
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.
4
2
5
(Note for stable backporting: for backports to branches where
3
Some registers whose 'cooked' writefns induce TLB maintenance do
6
CP_ACCESS_UNDEFINED is not defined, the old name to use instead
4
not have raw_writefn ops defined. If only the writefn ops is set
7
is CP_ACCESS_TRAP_UNCATEGORIZED.)
5
(ie. no raw_writefn is provided), it is assumed the cooked also
6
work as the raw one. For those registers it is not obvious the
7
tlb_flush works on KVM mode so better/safer setting the raw write.
8
8
9
Cc: qemu-stable@nongnu.org
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
10
Suggested-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
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Message-id: 20250204125009.2281315-4-peter.maydell@linaro.org
13
---
13
---
14
target/arm/helper.c | 3 +++
14
target/arm/helper.c | 23 +++++++++++++----------
15
1 file changed, 3 insertions(+)
15
1 file changed, 13 insertions(+), 10 deletions(-)
16
16
17
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
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
19
--- a/target/arm/helper.c
20
+++ b/target/arm/helper.c
20
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gt_stimer_access(CPUARMState *env,
21
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
22
if (!arm_is_secure(env)) {
22
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0,
23
return CP_ACCESS_UNDEFINED;
23
.access = PL1_RW, .accessfn = access_tvm_trvm,
24
}
24
.fgt = FGT_TTBR0_EL1,
25
+ if (arm_is_el2_enabled(env)) {
25
- .writefn = vmsa_ttbr_write, .resetvalue = 0,
26
+ return CP_ACCESS_UNDEFINED;
26
+ .writefn = vmsa_ttbr_write, .resetvalue = 0, .raw_writefn = raw_write,
27
+ }
27
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
28
if (!(env->cp15.scr_el3 & SCR_ST)) {
28
offsetof(CPUARMState, cp15.ttbr0_ns) } },
29
return CP_ACCESS_TRAP_EL3;
29
{ .name = "TTBR1_EL1", .state = ARM_CP_STATE_BOTH,
30
}
30
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 1,
31
.access = PL1_RW, .accessfn = access_tvm_trvm,
32
.fgt = FGT_TTBR1_EL1,
33
- .writefn = vmsa_ttbr_write, .resetvalue = 0,
34
+ .writefn = vmsa_ttbr_write, .resetvalue = 0, .raw_writefn = raw_write,
35
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
36
offsetof(CPUARMState, cp15.ttbr1_ns) } },
37
{ .name = "TCR_EL1", .state = ARM_CP_STATE_AA64,
38
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
39
.type = ARM_CP_64BIT | ARM_CP_ALIAS,
40
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
41
offsetof(CPUARMState, cp15.ttbr0_ns) },
42
- .writefn = vmsa_ttbr_write, },
43
+ .writefn = vmsa_ttbr_write, .raw_writefn = raw_write },
44
{ .name = "TTBR1", .cp = 15, .crm = 2, .opc1 = 1,
45
.access = PL1_RW, .accessfn = access_tvm_trvm,
46
.type = ARM_CP_64BIT | ARM_CP_ALIAS,
47
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
48
offsetof(CPUARMState, cp15.ttbr1_ns) },
49
- .writefn = vmsa_ttbr_write, },
50
+ .writefn = vmsa_ttbr_write, .raw_writefn = raw_write },
51
};
52
53
static uint64_t aa64_fpcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
54
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
55
.type = ARM_CP_IO,
56
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
57
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
58
- .writefn = hcr_write },
59
+ .writefn = hcr_write, .raw_writefn = raw_write },
60
{ .name = "HCR", .state = ARM_CP_STATE_AA32,
61
.type = ARM_CP_ALIAS | ARM_CP_IO,
62
.cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
63
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
64
{ .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH,
65
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2,
66
.access = PL2_RW, .writefn = vmsa_tcr_el12_write,
67
+ .raw_writefn = raw_write,
68
.fieldoffset = offsetof(CPUARMState, cp15.tcr_el[2]) },
69
{ .name = "VTCR", .state = ARM_CP_STATE_AA32,
70
.cp = 15, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2,
71
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
72
.type = ARM_CP_64BIT | ARM_CP_ALIAS,
73
.access = PL2_RW, .accessfn = access_el3_aa32ns,
74
.fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2),
75
- .writefn = vttbr_write },
76
+ .writefn = vttbr_write, .raw_writefn = raw_write },
77
{ .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64,
78
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0,
79
- .access = PL2_RW, .writefn = vttbr_write,
80
+ .access = PL2_RW, .writefn = vttbr_write, .raw_writefn = raw_write,
81
.fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2) },
82
{ .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH,
83
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0,
84
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
85
.fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[2]) },
86
{ .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64,
87
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0,
88
- .access = PL2_RW, .resetvalue = 0, .writefn = vmsa_tcr_ttbr_el2_write,
89
+ .access = PL2_RW, .resetvalue = 0,
90
+ .writefn = vmsa_tcr_ttbr_el2_write, .raw_writefn = raw_write,
91
.fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) },
92
{ .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2,
93
.access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS,
94
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
95
{ .name = "SCR_EL3", .state = ARM_CP_STATE_AA64,
96
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0,
97
.access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3),
98
- .resetfn = scr_reset, .writefn = scr_write },
99
+ .resetfn = scr_reset, .writefn = scr_write, .raw_writefn = raw_write },
100
{ .name = "SCR", .type = ARM_CP_ALIAS | ARM_CP_NEWEL,
101
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 0,
102
.access = PL1_RW, .accessfn = access_trap_aa32s_el1,
103
.fieldoffset = offsetoflow32(CPUARMState, cp15.scr_el3),
104
- .writefn = scr_write },
105
+ .writefn = scr_write, .raw_writefn = raw_write },
106
{ .name = "SDER32_EL3", .state = ARM_CP_STATE_AA64,
107
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 1,
108
.access = PL3_RW, .resetvalue = 0,
109
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vhe_reginfo[] = {
110
{ .name = "TTBR1_EL2", .state = ARM_CP_STATE_AA64,
111
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 1,
112
.access = PL2_RW, .writefn = vmsa_tcr_ttbr_el2_write,
113
+ .raw_writefn = raw_write,
114
.fieldoffset = offsetof(CPUARMState, cp15.ttbr1_el[2]) },
115
#ifndef CONFIG_USER_ONLY
116
{ .name = "CNTHV_CVAL_EL2", .state = ARM_CP_STATE_AA64,
31
--
117
--
32
2.43.0
118
2.34.1
33
34
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Yuquan Wang <wangyuquan1236@phytium.com.cn>
2
2
3
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
3
The current sbsa-ref cannot use EHCI controller which is only
4
able to do 32-bit DMA, since sbsa-ref doesn't have RAM below 4GB.
5
Hence, this uses XHCI to provide a usb controller with 64-bit
6
DMA capablity instead of EHCI.
7
8
We bump the platform version to 0.3 with this change. Although the
9
hardware at the USB controller address changes, the firmware and
10
Linux can both cope with this -- on an older non-XHCI-aware
11
firmware/kernel setup the probe routine simply fails and the guest
12
proceeds without any USB. (This isn't a loss of functionality,
13
because the old USB controller never worked in the first place.) So
14
we can call this a backwards-compatible change and only bump the
15
minor version.
16
17
Signed-off-by: Yuquan Wang <wangyuquan1236@phytium.com.cn>
18
Message-id: 20230621103847.447508-2-wangyuquan1236@phytium.com.cn
19
[PMM: tweaked commit message; add line to docs about what
20
changes in platform version 0.3]
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
21
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Message-id: 20250204125009.2281315-10-peter.maydell@linaro.org
7
Cc: qemu-stable@nongnu.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
23
---
10
hw/arm/sbsa-ref.c | 2 ++
24
docs/system/arm/sbsa.rst | 5 ++++-
11
1 file changed, 2 insertions(+)
25
hw/arm/sbsa-ref.c | 23 +++++++++++++----------
26
hw/arm/Kconfig | 2 +-
27
3 files changed, 18 insertions(+), 12 deletions(-)
12
28
29
diff --git a/docs/system/arm/sbsa.rst b/docs/system/arm/sbsa.rst
30
index XXXXXXX..XXXXXXX 100644
31
--- a/docs/system/arm/sbsa.rst
32
+++ b/docs/system/arm/sbsa.rst
33
@@ -XXX,XX +XXX,XX @@ The ``sbsa-ref`` board supports:
34
- A configurable number of AArch64 CPUs
35
- GIC version 3
36
- System bus AHCI controller
37
- - System bus EHCI controller
38
+ - System bus XHCI controller
39
- CDROM and hard disc on AHCI bus
40
- E1000E ethernet card on PCIe bus
41
- Bochs display adapter on PCIe bus
42
@@ -XXX,XX +XXX,XX @@ Platform version changes:
43
44
0.2
45
GIC ITS information is present in devicetree.
46
+
47
+0.3
48
+ The USB controller is an XHCI device, not EHCI
13
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
49
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
14
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/sbsa-ref.c
51
--- a/hw/arm/sbsa-ref.c
16
+++ b/hw/arm/sbsa-ref.c
52
+++ b/hw/arm/sbsa-ref.c
17
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, MemoryRegion *mem)
53
@@ -XXX,XX +XXX,XX @@
18
[GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
54
#include "hw/pci-host/gpex.h"
19
[GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
55
#include "hw/qdev-properties.h"
20
[GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
56
#include "hw/usb.h"
21
+ [GTIMER_S_EL2_PHYS] = ARCH_TIMER_S_EL2_IRQ,
57
+#include "hw/usb/xhci.h"
22
+ [GTIMER_S_EL2_VIRT] = ARCH_TIMER_S_EL2_VIRT_IRQ,
58
#include "hw/char/pl011.h"
23
};
59
#include "hw/watchdog/sbsa_gwdt.h"
24
60
#include "net/net.h"
25
for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
61
@@ -XXX,XX +XXX,XX @@ enum {
62
SBSA_SECURE_UART_MM,
63
SBSA_SECURE_MEM,
64
SBSA_AHCI,
65
- SBSA_EHCI,
66
+ SBSA_XHCI,
67
};
68
69
struct SBSAMachineState {
70
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry sbsa_ref_memmap[] = {
71
[SBSA_SMMU] = { 0x60050000, 0x00020000 },
72
/* Space here reserved for more SMMUs */
73
[SBSA_AHCI] = { 0x60100000, 0x00010000 },
74
- [SBSA_EHCI] = { 0x60110000, 0x00010000 },
75
+ [SBSA_XHCI] = { 0x60110000, 0x00010000 },
76
/* Space here reserved for other devices */
77
[SBSA_PCIE_PIO] = { 0x7fff0000, 0x00010000 },
78
/* 32-bit address PCIE MMIO space */
79
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
80
[SBSA_SECURE_UART] = 8,
81
[SBSA_SECURE_UART_MM] = 9,
82
[SBSA_AHCI] = 10,
83
- [SBSA_EHCI] = 11,
84
+ [SBSA_XHCI] = 11,
85
[SBSA_SMMU] = 12, /* ... to 15 */
86
[SBSA_GWDT_WS0] = 16,
87
};
88
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SBSAMachineState *sms)
89
* fw compatibility.
90
*/
91
qemu_fdt_setprop_cell(fdt, "/", "machine-version-major", 0);
92
- qemu_fdt_setprop_cell(fdt, "/", "machine-version-minor", 2);
93
+ qemu_fdt_setprop_cell(fdt, "/", "machine-version-minor", 3);
94
95
if (ms->numa_state->have_numa_distance) {
96
int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
97
@@ -XXX,XX +XXX,XX @@ static void create_ahci(const SBSAMachineState *sms)
98
}
99
}
100
101
-static void create_ehci(const SBSAMachineState *sms)
102
+static void create_xhci(const SBSAMachineState *sms)
103
{
104
- hwaddr base = sbsa_ref_memmap[SBSA_EHCI].base;
105
- int irq = sbsa_ref_irqmap[SBSA_EHCI];
106
+ hwaddr base = sbsa_ref_memmap[SBSA_XHCI].base;
107
+ int irq = sbsa_ref_irqmap[SBSA_XHCI];
108
+ DeviceState *dev = qdev_new(TYPE_XHCI_SYSBUS);
109
110
- sysbus_create_simple("platform-ehci-usb", base,
111
- qdev_get_gpio_in(sms->gic, irq));
112
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
113
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
114
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(sms->gic, irq));
115
}
116
117
static void create_smmu(const SBSAMachineState *sms, PCIBus *bus)
118
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
119
120
create_ahci(sms);
121
122
- create_ehci(sms);
123
+ create_xhci(sms);
124
125
create_pcie(sms);
126
127
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
128
index XXXXXXX..XXXXXXX 100644
129
--- a/hw/arm/Kconfig
130
+++ b/hw/arm/Kconfig
131
@@ -XXX,XX +XXX,XX @@ config SBSA_REF
132
select PL011 # UART
133
select PL031 # RTC
134
select PL061 # GPIO
135
- select USB_EHCI_SYSBUS
136
+ select USB_XHCI_SYSBUS
137
select WDT_SBSA
138
select BOCHS_DISPLAY
139
26
--
140
--
27
2.43.0
141
2.34.1
28
29
diff view generated by jsdifflib
1
From: Keith Packard <keithp@keithp.com>
1
Some assemblers will complain about attempts to access
2
id_aa64zfr0_el1 and id_aa64smfr0_el1 by name if the test
3
binary isn't built for the right processor type:
2
4
3
Functions which modify TCG globals must not be marked TCG_CALL_NO_WG,
5
/tmp/ccASXpLo.s:782: Error: selected processor does not support system register name 'id_aa64zfr0_el1'
4
as that tells the optimizer that TCG global values already loaded in
6
/tmp/ccASXpLo.s:829: Error: selected processor does not support system register name 'id_aa64smfr0_el1'
5
machine registers are still valid, and so any changes which these
6
helpers make to the CPU state may be ignored.
7
7
8
The target/rx code chooses to put (among other things) all the PSW
8
However, these registers are in the ID space and are guaranteed to
9
bits and also ACC into globals, so the NO_WG flag on various
9
read-as-zero on older CPUs, so the access is both safe and sensible.
10
functions that touch the PSW or ACC is incorrect and must be removed.
10
Switch to using the S syntax, as we already do for ID_AA64ISAR2_EL1
11
This includes all the floating point helper functions, because
11
and ID_AA64MMFR2_EL1. This allows us to drop the HAS_ARMV9_SME check
12
update_fpsw() will update PSW Z and S.
12
and the makefile machinery to adjust the CFLAGS for this test, so we
13
don't rely on having a sufficiently new compiler to be able to check
14
these registers.
13
15
14
Signed-off-by: Keith Packard <keithp@keithp.com>
16
This means we're actually testing the SME ID register: no released
15
[PMM: Clarified commit message]
17
GCC yet recognizes -march=armv9-a+sme, so that was always skipped.
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
It also avoids a future problem if we try to switch the "do we have
19
SME support in the toolchain" check from "in the compiler" to "in the
20
assembler" (at which point we would otherwise run into the above
21
errors).
22
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
24
---
19
target/rx/helper.h | 34 +++++++++++++++++-----------------
25
tests/tcg/aarch64/sysregs.c | 11 +++++++----
20
1 file changed, 17 insertions(+), 17 deletions(-)
26
tests/tcg/aarch64/Makefile.target | 7 +------
27
2 files changed, 8 insertions(+), 10 deletions(-)
21
28
22
diff --git a/target/rx/helper.h b/target/rx/helper.h
29
diff --git a/tests/tcg/aarch64/sysregs.c b/tests/tcg/aarch64/sysregs.c
23
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
24
--- a/target/rx/helper.h
31
--- a/tests/tcg/aarch64/sysregs.c
25
+++ b/target/rx/helper.h
32
+++ b/tests/tcg/aarch64/sysregs.c
26
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(raise_privilege_violation, noreturn, env)
33
@@ -XXX,XX +XXX,XX @@
27
DEF_HELPER_1(wait, noreturn, env)
34
/*
28
DEF_HELPER_2(rxint, noreturn, env, i32)
35
* Older assemblers don't recognize newer system register names,
29
DEF_HELPER_1(rxbrk, noreturn, env)
36
* but we can still access them by the Sn_n_Cn_Cn_n syntax.
30
-DEF_HELPER_FLAGS_3(fadd, TCG_CALL_NO_WG, f32, env, f32, f32)
37
+ * This also means we don't need to specifically request that the
31
-DEF_HELPER_FLAGS_3(fsub, TCG_CALL_NO_WG, f32, env, f32, f32)
38
+ * assembler enables whatever architectural features the ID registers
32
-DEF_HELPER_FLAGS_3(fmul, TCG_CALL_NO_WG, f32, env, f32, f32)
39
+ * syntax might be gated behind.
33
-DEF_HELPER_FLAGS_3(fdiv, TCG_CALL_NO_WG, f32, env, f32, f32)
40
*/
34
-DEF_HELPER_FLAGS_3(fcmp, TCG_CALL_NO_WG, void, env, f32, f32)
41
#define SYS_ID_AA64ISAR2_EL1 S3_0_C0_C6_2
35
-DEF_HELPER_FLAGS_2(ftoi, TCG_CALL_NO_WG, i32, env, f32)
42
#define SYS_ID_AA64MMFR2_EL1 S3_0_C0_C7_2
36
-DEF_HELPER_FLAGS_2(round, TCG_CALL_NO_WG, i32, env, f32)
43
+#define SYS_ID_AA64ZFR0_EL1 S3_0_C0_C4_4
37
-DEF_HELPER_FLAGS_2(itof, TCG_CALL_NO_WG, f32, env, i32)
44
+#define SYS_ID_AA64SMFR0_EL1 S3_0_C0_C4_5
38
+DEF_HELPER_3(fadd, f32, env, f32, f32)
45
39
+DEF_HELPER_3(fsub, f32, env, f32, f32)
46
int failed_bit_count;
40
+DEF_HELPER_3(fmul, f32, env, f32, f32)
47
41
+DEF_HELPER_3(fdiv, f32, env, f32, f32)
48
@@ -XXX,XX +XXX,XX @@ int main(void)
42
+DEF_HELPER_3(fcmp, void, env, f32, f32)
49
/* all hidden, DebugVer fixed to 0x6 (ARMv8 debug architecture) */
43
+DEF_HELPER_2(ftoi, i32, env, f32)
50
get_cpu_reg_check_mask(id_aa64dfr0_el1, _m(0000,0000,0000,0006));
44
+DEF_HELPER_2(round, i32, env, f32)
51
get_cpu_reg_check_zero(id_aa64dfr1_el1);
45
+DEF_HELPER_2(itof, f32, env, i32)
52
- get_cpu_reg_check_mask(id_aa64zfr0_el1, _m(0ff0,ff0f,00ff,00ff));
46
DEF_HELPER_2(set_fpsw, void, env, i32)
53
-#ifdef HAS_ARMV9_SME
47
-DEF_HELPER_FLAGS_2(racw, TCG_CALL_NO_WG, void, env, i32)
54
- get_cpu_reg_check_mask(id_aa64smfr0_el1, _m(80f1,00fd,0000,0000));
48
-DEF_HELPER_FLAGS_2(set_psw_rte, TCG_CALL_NO_WG, void, env, i32)
55
-#endif
49
-DEF_HELPER_FLAGS_2(set_psw, TCG_CALL_NO_WG, void, env, i32)
56
+ get_cpu_reg_check_mask(SYS_ID_AA64ZFR0_EL1, _m(0ff0,ff0f,00ff,00ff));
50
+DEF_HELPER_2(racw, void, env, i32)
57
+ get_cpu_reg_check_mask(SYS_ID_AA64SMFR0_EL1, _m(80f1,00fd,0000,0000));
51
+DEF_HELPER_2(set_psw_rte, void, env, i32)
58
52
+DEF_HELPER_2(set_psw, void, env, i32)
59
get_cpu_reg_check_zero(id_aa64afr0_el1);
53
DEF_HELPER_1(pack_psw, i32, env)
60
get_cpu_reg_check_zero(id_aa64afr1_el1);
54
-DEF_HELPER_FLAGS_3(div, TCG_CALL_NO_WG, i32, env, i32, i32)
61
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
55
-DEF_HELPER_FLAGS_3(divu, TCG_CALL_NO_WG, i32, env, i32, i32)
62
index XXXXXXX..XXXXXXX 100644
56
-DEF_HELPER_FLAGS_1(scmpu, TCG_CALL_NO_WG, void, env)
63
--- a/tests/tcg/aarch64/Makefile.target
57
+DEF_HELPER_3(div, i32, env, i32, i32)
64
+++ b/tests/tcg/aarch64/Makefile.target
58
+DEF_HELPER_3(divu, i32, env, i32, i32)
65
@@ -XXX,XX +XXX,XX @@ AARCH64_TESTS += mte-1 mte-2 mte-3 mte-4 mte-5 mte-6 mte-7
59
+DEF_HELPER_1(scmpu, void, env)
66
mte-%: CFLAGS += -march=armv8.5-a+memtag
60
DEF_HELPER_1(smovu, void, env)
67
endif
61
DEF_HELPER_1(smovf, void, env)
68
62
DEF_HELPER_1(smovb, void, env)
69
-ifneq ($(CROSS_CC_HAS_SVE),)
63
DEF_HELPER_2(sstr, void, env, i32)
70
# System Registers Tests
64
-DEF_HELPER_FLAGS_2(swhile, TCG_CALL_NO_WG, void, env, i32)
71
AARCH64_TESTS += sysregs
65
-DEF_HELPER_FLAGS_2(suntil, TCG_CALL_NO_WG, void, env, i32)
72
-ifneq ($(CROSS_CC_HAS_ARMV9_SME),)
66
-DEF_HELPER_FLAGS_2(rmpa, TCG_CALL_NO_WG, void, env, i32)
73
-sysregs: CFLAGS+=-march=armv9-a+sme -DHAS_ARMV9_SME
67
+DEF_HELPER_2(swhile, void, env, i32)
74
-else
68
+DEF_HELPER_2(suntil, void, env, i32)
75
-sysregs: CFLAGS+=-march=armv8.1-a+sve
69
+DEF_HELPER_2(rmpa, void, env, i32)
76
-endif
70
DEF_HELPER_1(satr, void, env)
77
78
+ifneq ($(CROSS_CC_HAS_SVE),)
79
# SVE ioctl test
80
AARCH64_TESTS += sve-ioctls
81
sve-ioctls: CFLAGS+=-march=armv8.1-a+sve
71
--
82
--
72
2.43.0
83
2.34.1
diff view generated by jsdifflib
1
From: Keith Packard <keithp@keithp.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The documentation says the vector is at 0xffffff80, instead of the
3
Allow the line length to extend to 548 columns. While annoyingly wide,
4
previous value of 0xffffffc0. That value must have been a bug because
4
it's still less confusing than the continuations we print. Also, the
5
the standard vector values (20, 21, 23, 25, 30) were all
5
default VL used by Linux (and max for A64FX) uses only 140 columns.
6
past the end of the array.
7
6
8
Signed-off-by: Keith Packard <keithp@keithp.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230622151201.1578522-2-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
target/rx/helper.c | 2 +-
12
target/arm/cpu.c | 36 ++++++++++++++----------------------
13
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 14 insertions(+), 22 deletions(-)
14
14
15
diff --git a/target/rx/helper.c b/target/rx/helper.c
15
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/rx/helper.c
17
--- a/target/arm/cpu.c
18
+++ b/target/rx/helper.c
18
+++ b/target/arm/cpu.c
19
@@ -XXX,XX +XXX,XX @@ void rx_cpu_do_interrupt(CPUState *cs)
19
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
20
cpu_stl_data(env, env->isp, env->pc);
20
ARMCPU *cpu = ARM_CPU(cs);
21
21
CPUARMState *env = &cpu->env;
22
if (vec < 0x100) {
22
uint32_t psr = pstate_read(env);
23
- env->pc = cpu_ldl_data(env, 0xffffffc0 + vec * 4);
23
- int i;
24
+ env->pc = cpu_ldl_data(env, 0xffffff80 + vec * 4);
24
+ int i, j;
25
} else {
25
int el = arm_current_el(env);
26
env->pc = cpu_ldl_data(env, env->intb + (vec & 0xff) * 4);
26
const char *ns_status;
27
bool sve;
28
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
29
}
30
31
if (sve) {
32
- int j, zcr_len = sve_vqm1_for_el(env, el);
33
+ int zcr_len = sve_vqm1_for_el(env, el);
34
35
for (i = 0; i <= FFR_PRED_NUM; i++) {
36
bool eol;
37
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
38
}
39
}
40
41
- for (i = 0; i < 32; i++) {
42
- if (zcr_len == 0) {
43
+ if (zcr_len == 0) {
44
+ /*
45
+ * With vl=16, there are only 37 columns per register,
46
+ * so output two registers per line.
47
+ */
48
+ for (i = 0; i < 32; i++) {
49
qemu_fprintf(f, "Z%02d=%016" PRIx64 ":%016" PRIx64 "%s",
50
i, env->vfp.zregs[i].d[1],
51
env->vfp.zregs[i].d[0], i & 1 ? "\n" : " ");
52
- } else if (zcr_len == 1) {
53
- qemu_fprintf(f, "Z%02d=%016" PRIx64 ":%016" PRIx64
54
- ":%016" PRIx64 ":%016" PRIx64 "\n",
55
- i, env->vfp.zregs[i].d[3], env->vfp.zregs[i].d[2],
56
- env->vfp.zregs[i].d[1], env->vfp.zregs[i].d[0]);
57
- } else {
58
+ }
59
+ } else {
60
+ for (i = 0; i < 32; i++) {
61
+ qemu_fprintf(f, "Z%02d=", i);
62
for (j = zcr_len; j >= 0; j--) {
63
- bool odd = (zcr_len - j) % 2 != 0;
64
- if (j == zcr_len) {
65
- qemu_fprintf(f, "Z%02d[%x-%x]=", i, j, j - 1);
66
- } else if (!odd) {
67
- if (j > 0) {
68
- qemu_fprintf(f, " [%x-%x]=", j, j - 1);
69
- } else {
70
- qemu_fprintf(f, " [%x]=", j);
71
- }
72
- }
73
qemu_fprintf(f, "%016" PRIx64 ":%016" PRIx64 "%s",
74
env->vfp.zregs[i].d[j * 2 + 1],
75
- env->vfp.zregs[i].d[j * 2],
76
- odd || j == 0 ? "\n" : ":");
77
+ env->vfp.zregs[i].d[j * 2 + 0],
78
+ j ? ":" : "\n");
79
}
80
}
27
}
81
}
28
--
82
--
29
2.43.0
83
2.34.1
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
As we are about to add more physical and virtual timers let's make it
3
Always print each matrix row whole, one per line, so that we
4
clear what each timer does.
4
get the entire matrix in the proper shape.
5
5
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20230622151201.1578522-3-richard.henderson@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]
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
10
---
14
target/arm/gtimer.h | 10 +++++-----
11
target/arm/cpu.c | 18 ++++++++++++++++++
15
1 file changed, 5 insertions(+), 5 deletions(-)
12
1 file changed, 18 insertions(+)
16
13
17
diff --git a/target/arm/gtimer.h b/target/arm/gtimer.h
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/gtimer.h
16
--- a/target/arm/cpu.c
20
+++ b/target/arm/gtimer.h
17
+++ b/target/arm/cpu.c
21
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
22
#define TARGET_ARM_GTIMER_H
19
i, q[1], q[0], (i & 1 ? "\n" : " "));
23
20
}
24
enum {
21
}
25
- GTIMER_PHYS = 0,
22
+
26
- GTIMER_VIRT = 1,
23
+ if (cpu_isar_feature(aa64_sme, cpu) &&
27
- GTIMER_HYP = 2,
24
+ FIELD_EX64(env->svcr, SVCR, ZA) &&
28
- GTIMER_SEC = 3,
25
+ sme_exception_el(env, el) == 0) {
29
- GTIMER_HYPVIRT = 4,
26
+ int zcr_len = sve_vqm1_for_el_sm(env, el, true);
30
+ GTIMER_PHYS = 0, /* CNTP_* ; EL1 physical timer */
27
+ int svl = (zcr_len + 1) * 16;
31
+ GTIMER_VIRT = 1, /* CNTV_* ; EL1 virtual timer */
28
+ int svl_lg10 = svl < 100 ? 2 : 3;
32
+ GTIMER_HYP = 2, /* CNTHP_* ; EL2 physical timer */
29
+
33
+ GTIMER_SEC = 3, /* CNTPS_* ; EL3 physical timer */
30
+ for (i = 0; i < svl; i++) {
34
+ GTIMER_HYPVIRT = 4, /* CNTHV_* ; EL2 virtual timer ; only if FEAT_VHE */
31
+ qemu_fprintf(f, "ZA[%0*d]=", svl_lg10, i);
35
GTIMER_S_EL2_PHYS = 5, /* CNTHPS_* ; only if FEAT_SEL2 */
32
+ for (j = zcr_len; j >= 0; --j) {
36
GTIMER_S_EL2_VIRT = 6, /* CNTHVS_* ; only if FEAT_SEL2 */
33
+ qemu_fprintf(f, "%016" PRIx64 ":%016" PRIx64 "%c",
37
#define NUM_GTIMERS 7
34
+ env->zarray[i].d[2 * j + 1],
35
+ env->zarray[i].d[2 * j],
36
+ j ? ':' : '\n');
37
+ }
38
+ }
39
+ }
40
}
41
42
#else
38
--
43
--
39
2.43.0
44
2.34.1
40
41
diff view generated by jsdifflib
1
Currently we handle CNTV_TVAL_EL02 by calling gt_tval_read() for the
1
From: Richard Henderson <richard.henderson@linaro.org>
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.
6
2
7
We were getting this wrong, because we ended up in
3
For the outer product set of insns, which take an entire matrix
8
gt_virt_cnt_offset() and did the E2H check.
4
tile as output, the argument is not a combined tile+column.
5
Therefore using get_tile_rowcol was incorrect, as we extracted
6
the tile number from itself.
9
7
10
Factor out the tval read/write calculation from the selection of the
8
The test case relies only on assembler support for SME, since
11
offset, so that we can special case gt_virt_tval_read() and
9
no release of GCC recognizes -march=armv9-a+sme yet.
12
gt_virt_tval_write() to unconditionally pass CNTVOFF_EL2.
13
10
14
Cc: qemu-stable@nongnu.org
11
Cc: qemu-stable@nongnu.org
12
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1620
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20230622151201.1578522-5-richard.henderson@linaro.org
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
[PMM: dropped now-unneeded changes to sysregs CFLAGS]
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
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
18
---
18
---
19
target/arm/helper.c | 36 +++++++++++++++++++++++++++---------
19
target/arm/tcg/translate-sme.c | 24 ++++++---
20
1 file changed, 27 insertions(+), 9 deletions(-)
20
tests/tcg/aarch64/sme-outprod1.c | 83 +++++++++++++++++++++++++++++++
21
tests/tcg/aarch64/Makefile.target | 7 ++-
22
3 files changed, 107 insertions(+), 7 deletions(-)
23
create mode 100644 tests/tcg/aarch64/sme-outprod1.c
21
24
22
diff --git a/target/arm/helper.c b/target/arm/helper.c
25
diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c
23
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/helper.c
27
--- a/target/arm/tcg/translate-sme.c
25
+++ b/target/arm/helper.c
28
+++ b/target/arm/tcg/translate-sme.c
26
@@ -XXX,XX +XXX,XX @@ static void gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
29
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr get_tile_rowcol(DisasContext *s, int esz, int rs,
27
gt_recalc_timer(env_archcpu(env), timeridx);
30
return addr;
28
}
31
}
29
32
30
+static uint64_t do_tval_read(CPUARMState *env, int timeridx, uint64_t offset)
33
+/*
34
+ * Resolve tile.size[0] to a host pointer.
35
+ * Used by e.g. outer product insns where we require the entire tile.
36
+ */
37
+static TCGv_ptr get_tile(DisasContext *s, int esz, int tile)
31
+{
38
+{
32
+ return (uint32_t)(env->cp15.c14_timer[timeridx].cval -
39
+ TCGv_ptr addr = tcg_temp_new_ptr();
33
+ (gt_get_countervalue(env) - offset));
40
+ int offset;
41
+
42
+ offset = tile * sizeof(ARMVectorReg) + offsetof(CPUARMState, zarray);
43
+
44
+ tcg_gen_addi_ptr(addr, cpu_env, offset);
45
+ return addr;
34
+}
46
+}
35
+
47
+
36
static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
48
static bool trans_ZERO(DisasContext *s, arg_ZERO *a)
37
int timeridx)
38
{
49
{
39
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
50
if (!dc_isar_feature(aa64_sme, s)) {
40
break;
51
@@ -XXX,XX +XXX,XX @@ static bool do_adda(DisasContext *s, arg_adda *a, MemOp esz,
52
return true;
41
}
53
}
42
54
43
- return (uint32_t)(env->cp15.c14_timer[timeridx].cval -
55
- /* Sum XZR+zad to find ZAd. */
44
- (gt_get_countervalue(env) - offset));
56
- za = get_tile_rowcol(s, esz, 31, a->zad, false);
45
+ return do_tval_read(env, timeridx, offset);
57
+ za = get_tile(s, esz, a->zad);
58
zn = vec_full_reg_ptr(s, a->zn);
59
pn = pred_full_reg_ptr(s, a->pn);
60
pm = pred_full_reg_ptr(s, a->pm);
61
@@ -XXX,XX +XXX,XX @@ static bool do_outprod(DisasContext *s, arg_op *a, MemOp esz,
62
return true;
63
}
64
65
- /* Sum XZR+zad to find ZAd. */
66
- za = get_tile_rowcol(s, esz, 31, a->zad, false);
67
+ za = get_tile(s, esz, a->zad);
68
zn = vec_full_reg_ptr(s, a->zn);
69
zm = vec_full_reg_ptr(s, a->zm);
70
pn = pred_full_reg_ptr(s, a->pn);
71
@@ -XXX,XX +XXX,XX @@ static bool do_outprod_fpst(DisasContext *s, arg_op *a, MemOp esz,
72
return true;
73
}
74
75
- /* Sum XZR+zad to find ZAd. */
76
- za = get_tile_rowcol(s, esz, 31, a->zad, false);
77
+ za = get_tile(s, esz, a->zad);
78
zn = vec_full_reg_ptr(s, a->zn);
79
zm = vec_full_reg_ptr(s, a->zm);
80
pn = pred_full_reg_ptr(s, a->pn);
81
diff --git a/tests/tcg/aarch64/sme-outprod1.c b/tests/tcg/aarch64/sme-outprod1.c
82
new file mode 100644
83
index XXXXXXX..XXXXXXX
84
--- /dev/null
85
+++ b/tests/tcg/aarch64/sme-outprod1.c
86
@@ -XXX,XX +XXX,XX @@
87
+/*
88
+ * SME outer product, 1 x 1.
89
+ * SPDX-License-Identifier: GPL-2.0-or-later
90
+ */
91
+
92
+#include <stdio.h>
93
+
94
+extern void foo(float *dst);
95
+
96
+asm(
97
+"    .arch_extension sme\n"
98
+"    .type foo, @function\n"
99
+"foo:\n"
100
+"    stp x29, x30, [sp, -80]!\n"
101
+"    mov x29, sp\n"
102
+"    stp d8, d9, [sp, 16]\n"
103
+"    stp d10, d11, [sp, 32]\n"
104
+"    stp d12, d13, [sp, 48]\n"
105
+"    stp d14, d15, [sp, 64]\n"
106
+"    smstart\n"
107
+"    ptrue p0.s, vl4\n"
108
+"    fmov z0.s, #1.0\n"
109
+/*
110
+ * An outer product of a vector of 1.0 by itself should be a matrix of 1.0.
111
+ * Note that we are using tile 1 here (za1.s) rather than tile 0.
112
+ */
113
+"    zero {za}\n"
114
+"    fmopa za1.s, p0/m, p0/m, z0.s, z0.s\n"
115
+/*
116
+ * Read the first 4x4 sub-matrix of elements from tile 1:
117
+ * Note that za1h should be interchangable here.
118
+ */
119
+"    mov w12, #0\n"
120
+"    mova z0.s, p0/m, za1v.s[w12, #0]\n"
121
+"    mova z1.s, p0/m, za1v.s[w12, #1]\n"
122
+"    mova z2.s, p0/m, za1v.s[w12, #2]\n"
123
+"    mova z3.s, p0/m, za1v.s[w12, #3]\n"
124
+/*
125
+ * And store them to the input pointer (dst in the C code):
126
+ */
127
+"    st1w {z0.s}, p0, [x0]\n"
128
+"    add x0, x0, #16\n"
129
+"    st1w {z1.s}, p0, [x0]\n"
130
+"    add x0, x0, #16\n"
131
+"    st1w {z2.s}, p0, [x0]\n"
132
+"    add x0, x0, #16\n"
133
+"    st1w {z3.s}, p0, [x0]\n"
134
+"    smstop\n"
135
+"    ldp d8, d9, [sp, 16]\n"
136
+"    ldp d10, d11, [sp, 32]\n"
137
+"    ldp d12, d13, [sp, 48]\n"
138
+"    ldp d14, d15, [sp, 64]\n"
139
+"    ldp x29, x30, [sp], 80\n"
140
+"    ret\n"
141
+"    .size foo, . - foo"
142
+);
143
+
144
+int main()
145
+{
146
+ float dst[16];
147
+ int i, j;
148
+
149
+ foo(dst);
150
+
151
+ for (i = 0; i < 16; i++) {
152
+ if (dst[i] != 1.0f) {
153
+ break;
154
+ }
155
+ }
156
+
157
+ if (i == 16) {
158
+ return 0; /* success */
159
+ }
160
+
161
+ /* failure */
162
+ for (i = 0; i < 4; ++i) {
163
+ for (j = 0; j < 4; ++j) {
164
+ printf("%f ", (double)dst[i * 4 + j]);
165
+ }
166
+ printf("\n");
167
+ }
168
+ return 1;
46
+}
169
+}
170
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
171
index XXXXXXX..XXXXXXX 100644
172
--- a/tests/tcg/aarch64/Makefile.target
173
+++ b/tests/tcg/aarch64/Makefile.target
174
@@ -XXX,XX +XXX,XX @@ config-cc.mak: Makefile
175
     $(call cc-option,-march=armv8.5-a, CROSS_CC_HAS_ARMV8_5); \
176
     $(call cc-option,-mbranch-protection=standard, CROSS_CC_HAS_ARMV8_BTI); \
177
     $(call cc-option,-march=armv8.5-a+memtag, CROSS_CC_HAS_ARMV8_MTE); \
178
-     $(call cc-option,-march=armv9-a+sme, CROSS_CC_HAS_ARMV9_SME)) 3> config-cc.mak
179
+     $(call cc-option,-Wa$(COMMA)-march=armv9-a+sme, CROSS_AS_HAS_ARMV9_SME)) 3> config-cc.mak
180
-include config-cc.mak
181
182
ifneq ($(CROSS_CC_HAS_ARMV8_2),)
183
@@ -XXX,XX +XXX,XX @@ AARCH64_TESTS += mte-1 mte-2 mte-3 mte-4 mte-5 mte-6 mte-7
184
mte-%: CFLAGS += -march=armv8.5-a+memtag
185
endif
186
187
+# SME Tests
188
+ifneq ($(CROSS_AS_HAS_ARMV9_SME),)
189
+AARCH64_TESTS += sme-outprod1
190
+endif
47
+
191
+
48
+static void do_tval_write(CPUARMState *env, int timeridx, uint64_t value,
192
# System Registers Tests
49
+ uint64_t offset)
193
AARCH64_TESTS += sysregs
50
+{
194
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,
95
--
195
--
96
2.43.0
196
2.34.1
97
98
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: John Högberg <john.hogberg@ericsson.com>
2
2
3
When FEAT_SEL2 was implemented the SEL2 timers were missed. This
3
Unlike architectures with precise self-modifying code semantics
4
shows up when building the latest Hafnium with SPMC_AT_EL=2. The
4
(e.g. x86) ARM processors do not maintain coherency for instruction
5
actual implementation utilises the same logic as the rest of the
5
execution and memory, requiring an instruction synchronization
6
timers so all we need to do is:
6
barrier on every core that will execute the new code, and on many
7
models also the explicit use of cache management instructions.
7
8
8
- define the timers and their access functions
9
While this is required to make JITs work on actual hardware, QEMU
9
- conditionally add the correct system registers
10
has gotten away with not handling this since it does not emulate
10
- create a new accessfn as the rules are subtly different to the
11
caches, and unconditionally invalidates code whenever the softmmu
11
existing secure timer
12
or the user-mode page protection logic detects that code has been
13
modified.
12
14
13
Fixes: e9152ee91c (target/arm: add ARMv8.4-SEL2 system registers)
15
Unfortunately the latter does not work in the face of dual-mapped
14
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
16
code (a common W^X workaround), where one page is executable and
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
the other is writable: user-mode has no way to connect one with the
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
other as that is only known to the kernel and the emulated
17
Message-id: 20250204125009.2281315-7-peter.maydell@linaro.org
19
application.
18
Cc: qemu-stable@nongnu.org
20
19
Cc: Andrei Homescu <ahomescu@google.com>
21
This commit works around the issue by telling software that
20
Cc: Arve Hjønnevåg <arve@google.com>
22
instruction cache invalidation is required by clearing the
21
Cc: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
23
CPR_EL0.DIC flag (regardless of whether the emulated processor
22
[PMM: CP_ACCESS_TRAP_UNCATEGORIZED -> CP_ACCESS_UNDEFINED;
24
needs it), and then invalidating code in IC IVAU instructions.
23
offset logic now in gt_{indirect,direct}_access_timer_offset() ]
25
24
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
26
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1034
27
28
Co-authored-by: Richard Henderson <richard.henderson@linaro.org>
29
Signed-off-by: John Högberg <john.hogberg@ericsson.com>
30
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
31
Message-id: 168778890374.24232.3402138851538068785-1@git.sr.ht
32
[PMM: removed unnecessary AArch64 feature check; moved
33
"clear CTR_EL1.DIC" code up a bit so it's not in the middle
34
of the vfp/neon related tests]
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
---
36
---
27
include/hw/arm/bsa.h | 2 +
37
target/arm/cpu.c | 11 +++++++++++
28
target/arm/cpu.h | 2 +
38
target/arm/helper.c | 47 ++++++++++++++++++++++++++++++++++++++++++---
29
target/arm/gtimer.h | 4 +-
39
2 files changed, 55 insertions(+), 3 deletions(-)
30
target/arm/cpu.c | 4 ++
31
target/arm/helper.c | 163 +++++++++++++++++++++++++++++++++++++++++++
32
5 files changed, 174 insertions(+), 1 deletion(-)
33
40
34
diff --git a/include/hw/arm/bsa.h b/include/hw/arm/bsa.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/arm/bsa.h
37
+++ b/include/hw/arm/bsa.h
38
@@ -XXX,XX +XXX,XX @@
39
#define QEMU_ARM_BSA_H
40
41
/* These are architectural INTID values */
42
+#define ARCH_TIMER_S_EL2_VIRT_IRQ 19
43
+#define ARCH_TIMER_S_EL2_IRQ 20
44
#define VIRTUAL_PMU_IRQ 23
45
#define ARCH_GIC_MAINT_IRQ 25
46
#define ARCH_TIMER_NS_EL2_IRQ 26
47
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/cpu.h
50
+++ b/target/arm/cpu.h
51
@@ -XXX,XX +XXX,XX @@ void arm_gt_vtimer_cb(void *opaque);
52
void arm_gt_htimer_cb(void *opaque);
53
void arm_gt_stimer_cb(void *opaque);
54
void arm_gt_hvtimer_cb(void *opaque);
55
+void arm_gt_sel2timer_cb(void *opaque);
56
+void arm_gt_sel2vtimer_cb(void *opaque);
57
58
unsigned int gt_cntfrq_period_ns(ARMCPU *cpu);
59
void gt_rme_post_el_change(ARMCPU *cpu, void *opaque);
60
diff --git a/target/arm/gtimer.h b/target/arm/gtimer.h
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/gtimer.h
63
+++ b/target/arm/gtimer.h
64
@@ -XXX,XX +XXX,XX @@ enum {
65
GTIMER_HYP = 2,
66
GTIMER_SEC = 3,
67
GTIMER_HYPVIRT = 4,
68
-#define NUM_GTIMERS 5
69
+ GTIMER_S_EL2_PHYS = 5, /* CNTHPS_* ; only if FEAT_SEL2 */
70
+ GTIMER_S_EL2_VIRT = 6, /* CNTHVS_* ; only if FEAT_SEL2 */
71
+#define NUM_GTIMERS 7
72
};
73
74
#endif
75
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
41
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
76
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
77
--- a/target/arm/cpu.c
43
--- a/target/arm/cpu.c
78
+++ b/target/arm/cpu.c
44
+++ b/target/arm/cpu.c
79
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
45
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
80
arm_gt_stimer_cb, cpu);
46
return;
81
cpu->gt_timer[GTIMER_HYPVIRT] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
82
arm_gt_hvtimer_cb, cpu);
83
+ cpu->gt_timer[GTIMER_S_EL2_PHYS] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
84
+ arm_gt_sel2timer_cb, cpu);
85
+ cpu->gt_timer[GTIMER_S_EL2_VIRT] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
86
+ arm_gt_sel2vtimer_cb, cpu);
87
}
47
}
88
#endif
48
89
49
+#ifdef CONFIG_USER_ONLY
50
+ /*
51
+ * User mode relies on IC IVAU instructions to catch modification of
52
+ * dual-mapped code.
53
+ *
54
+ * Clear CTR_EL0.DIC to ensure that software that honors these flags uses
55
+ * IC IVAU even if the emulated processor does not normally require it.
56
+ */
57
+ cpu->ctr = FIELD_DP64(cpu->ctr, CTR_EL0, DIC, 0);
58
+#endif
59
+
60
if (arm_feature(env, ARM_FEATURE_AARCH64) &&
61
cpu->has_vfp != cpu->has_neon) {
62
/*
90
diff --git a/target/arm/helper.c b/target/arm/helper.c
63
diff --git a/target/arm/helper.c b/target/arm/helper.c
91
index XXXXXXX..XXXXXXX 100644
64
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/helper.c
65
--- a/target/arm/helper.c
93
+++ b/target/arm/helper.c
66
+++ b/target/arm/helper.c
94
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gt_stimer_access(CPUARMState *env,
67
@@ -XXX,XX +XXX,XX @@ static void mdcr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
95
}
68
}
96
}
69
}
97
70
98
+static CPAccessResult gt_sel2timer_access(CPUARMState *env,
71
+#ifdef CONFIG_USER_ONLY
99
+ const ARMCPRegInfo *ri,
72
+/*
100
+ bool isread)
73
+ * `IC IVAU` is handled to improve compatibility with JITs that dual-map their
74
+ * code to get around W^X restrictions, where one region is writable and the
75
+ * other is executable.
76
+ *
77
+ * Since the executable region is never written to we cannot detect code
78
+ * changes when running in user mode, and rely on the emulated JIT telling us
79
+ * that the code has changed by executing this instruction.
80
+ */
81
+static void ic_ivau_write(CPUARMState *env, const ARMCPRegInfo *ri,
82
+ uint64_t value)
101
+{
83
+{
84
+ uint64_t icache_line_mask, start_address, end_address;
85
+ const ARMCPU *cpu;
86
+
87
+ cpu = env_archcpu(env);
88
+
89
+ icache_line_mask = (4 << extract32(cpu->ctr, 0, 4)) - 1;
90
+ start_address = value & ~icache_line_mask;
91
+ end_address = value | icache_line_mask;
92
+
93
+ mmap_lock();
94
+
95
+ tb_invalidate_phys_range(start_address, end_address);
96
+
97
+ mmap_unlock();
98
+}
99
+#endif
100
+
101
static const ARMCPRegInfo v8_cp_reginfo[] = {
102
/*
103
* Minimal set of EL0-visible registers. This will need to be expanded
104
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
105
{ .name = "CURRENTEL", .state = ARM_CP_STATE_AA64,
106
.opc0 = 3, .opc1 = 0, .opc2 = 2, .crn = 4, .crm = 2,
107
.access = PL1_R, .type = ARM_CP_CURRENTEL },
108
- /* Cache ops: all NOPs since we don't emulate caches */
102
+ /*
109
+ /*
103
+ * The AArch64 register view of the secure EL2 timers are mostly
110
+ * Instruction cache ops. All of these except `IC IVAU` NOP because we
104
+ * accessible from EL3 and EL2 although can also be trapped to EL2
111
+ * don't emulate caches.
105
+ * from EL1 depending on nested virt config.
106
+ */
112
+ */
107
+ switch (arm_current_el(env)) {
113
{ .name = "IC_IALLUIS", .state = ARM_CP_STATE_AA64,
108
+ case 0: /* UNDEFINED */
114
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
109
+ return CP_ACCESS_UNDEFINED;
115
.access = PL1_W, .type = ARM_CP_NOP,
110
+ case 1:
116
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
111
+ if (!arm_is_secure(env)) {
117
.accessfn = access_tocu },
112
+ /* UNDEFINED */
118
{ .name = "IC_IVAU", .state = ARM_CP_STATE_AA64,
113
+ return CP_ACCESS_UNDEFINED;
119
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 5, .opc2 = 1,
114
+ } else if (arm_hcr_el2_eff(env) & HCR_NV) {
120
- .access = PL0_W, .type = ARM_CP_NOP,
115
+ /* Aarch64.SystemAccessTrap(EL2, 0x18) */
121
+ .access = PL0_W,
116
+ return CP_ACCESS_TRAP_EL2;
122
.fgt = FGT_ICIVAU,
117
+ }
123
- .accessfn = access_tocu },
118
+ /* UNDEFINED */
124
+ .accessfn = access_tocu,
119
+ return CP_ACCESS_UNDEFINED;
125
+#ifdef CONFIG_USER_ONLY
120
+ case 2:
126
+ .type = ARM_CP_NO_RAW,
121
+ if (!arm_is_secure(env)) {
127
+ .writefn = ic_ivau_write
122
+ /* UNDEFINED */
128
+#else
123
+ return CP_ACCESS_UNDEFINED;
129
+ .type = ARM_CP_NOP
124
+ }
130
+#endif
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)
138
{
139
ARMCPU *cpu = env_archcpu(env);
140
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_indirect_access_timer_offset(CPUARMState *env, int timeridx)
141
case GTIMER_HYP:
142
case GTIMER_SEC:
143
case GTIMER_HYPVIRT:
144
+ case GTIMER_S_EL2_PHYS:
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
+ },
131
+ },
256
+ { .name = "CNTHPS_CTL_EL2", .state = ARM_CP_STATE_AA64,
132
+ /* Cache ops: all NOPs since we don't emulate caches */
257
+ .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 5, .opc2 = 1,
133
{ .name = "DC_IVAC", .state = ARM_CP_STATE_AA64,
258
+ .type = ARM_CP_IO, .access = PL2_RW,
134
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1,
259
+ .accessfn = gt_sel2timer_access,
135
.access = PL1_W, .accessfn = aa64_cacheop_poc_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,
299
--
136
--
300
2.43.0
137
2.34.1
301
138
302
139
diff view generated by jsdifflib
1
From: JianChunfu <jansef.jian@hj-micro.com>
1
From: Vikram Garhwal <vikram.garhwal@amd.com>
2
2
3
Use a similar terminology smmu_hash_remove_by_sid_range() as the one
3
Following are done to fix the coverity issues:
4
being used for other hash table matching functions since
4
1. Change read_data to fix the CID 1512899: Out-of-bounds access (OVERRUN)
5
smmuv3_invalidate_ste() name is not self explanatory, and introduce a
5
2. Fix match_rx_tx_data to fix CID 1512900: Logically dead code (DEADCODE)
6
helper that invokes the g_hash_table_foreach_remove.
6
3. Replace rand() in generate_random_data() with g_rand_int()
7
7
8
No functional change intended.
8
Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
9
9
Message-id: 20230628202758.16398-1-vikram.garhwal@amd.com
10
Signed-off-by: JianChunfu <jansef.jian@hj-micro.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Eric Auger <eric.auger@redhat.com>
12
Message-id: 20250228031438.3916-1-jansef.jian@hj-micro.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
12
---
15
hw/arm/smmu-internal.h | 5 -----
13
tests/qtest/xlnx-canfd-test.c | 33 +++++++++++----------------------
16
include/hw/arm/smmu-common.h | 6 ++++++
14
1 file changed, 11 insertions(+), 22 deletions(-)
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(-)
21
15
22
diff --git a/hw/arm/smmu-internal.h b/hw/arm/smmu-internal.h
16
diff --git a/tests/qtest/xlnx-canfd-test.c b/tests/qtest/xlnx-canfd-test.c
23
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/arm/smmu-internal.h
18
--- a/tests/qtest/xlnx-canfd-test.c
25
+++ b/hw/arm/smmu-internal.h
19
+++ b/tests/qtest/xlnx-canfd-test.c
26
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUIOTLBPageInvInfo {
20
@@ -XXX,XX +XXX,XX @@ static void generate_random_data(uint32_t *buf_tx, bool is_canfd_frame)
27
uint64_t mask;
21
/* Generate random TX data for CANFD frame. */
28
} SMMUIOTLBPageInvInfo;
22
if (is_canfd_frame) {
29
23
for (int i = 0; i < CANFD_FRAME_SIZE - 2; i++) {
30
-typedef struct SMMUSIDRange {
24
- buf_tx[2 + i] = rand();
31
- uint32_t start;
25
+ buf_tx[2 + i] = g_random_int();
32
- uint32_t end;
26
}
33
-} SMMUSIDRange;
27
} else {
34
-
28
/* Generate random TX data for CAN frame. */
35
#endif
29
for (int i = 0; i < CAN_FRAME_SIZE - 2; i++) {
36
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
30
- buf_tx[2 + i] = rand();
37
index XXXXXXX..XXXXXXX 100644
31
+ buf_tx[2 + i] = g_random_int();
38
--- a/include/hw/arm/smmu-common.h
32
}
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);
66
}
67
68
+static gboolean
69
+smmu_hash_remove_by_sid_range(gpointer key, gpointer value, gpointer user_data)
70
+{
71
+ SMMUDevice *sdev = (SMMUDevice *)key;
72
+ uint32_t sid = smmu_get_sid(sdev);
73
+ SMMUSIDRange *sid_range = (SMMUSIDRange *)user_data;
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
}
33
}
107
}
34
}
108
35
109
-static gboolean
36
-static void read_data(QTestState *qts, uint64_t can_base_addr, uint32_t *buf_rx)
110
-smmuv3_invalidate_ste(gpointer key, gpointer value, gpointer user_data)
37
+static void read_data(QTestState *qts, uint64_t can_base_addr, uint32_t *buf_rx,
111
-{
38
+ uint32_t frame_size)
112
- SMMUDevice *sdev = (SMMUDevice *)key;
39
{
113
- uint32_t sid = smmu_get_sid(sdev);
40
uint32_t int_status;
114
- SMMUSIDRange *sid_range = (SMMUSIDRange *)user_data;
41
uint32_t fifo_status_reg_value;
42
/* At which RX FIFO the received data is stored. */
43
uint8_t store_ind = 0;
44
- bool is_canfd_frame = false;
45
46
/* Read the interrupt on CANFD rx. */
47
int_status = qtest_readl(qts, can_base_addr + R_ISR_OFFSET) & ISR_RXOK;
48
@@ -XXX,XX +XXX,XX @@ static void read_data(QTestState *qts, uint64_t can_base_addr, uint32_t *buf_rx)
49
buf_rx[0] = qtest_readl(qts, can_base_addr + R_RX0_ID_OFFSET);
50
buf_rx[1] = qtest_readl(qts, can_base_addr + R_RX0_DLC_OFFSET);
51
52
- is_canfd_frame = (buf_rx[1] >> DLC_FD_BIT_SHIFT) & 1;
115
-
53
-
116
- if (sid < sid_range->start || sid > sid_range->end) {
54
- if (is_canfd_frame) {
117
- return false;
55
- for (int i = 0; i < CANFD_FRAME_SIZE - 2; i++) {
118
- }
56
- buf_rx[i + 2] = qtest_readl(qts,
119
- trace_smmuv3_config_cache_inv(sid);
57
- can_base_addr + R_RX0_DATA1_OFFSET + 4 * i);
120
- return true;
58
- }
121
-}
59
- } else {
60
- buf_rx[2] = qtest_readl(qts, can_base_addr + R_RX0_DATA1_OFFSET);
61
- buf_rx[3] = qtest_readl(qts, can_base_addr + R_RX0_DATA2_OFFSET);
62
+ for (int i = 0; i < frame_size - 2; i++) {
63
+ buf_rx[i + 2] = qtest_readl(qts,
64
+ can_base_addr + R_RX0_DATA1_OFFSET + 4 * i);
65
}
66
67
/* Clear the RX interrupt. */
68
@@ -XXX,XX +XXX,XX @@ static void match_rx_tx_data(const uint32_t *buf_tx, const uint32_t *buf_rx,
69
g_assert_cmpint((buf_rx[size] & DLC_FD_BIT_MASK), ==,
70
(buf_tx[size] & DLC_FD_BIT_MASK));
71
} else {
72
- if (!is_canfd_frame && size == 4) {
73
- break;
74
- }
122
-
75
-
123
static int smmuv3_cmdq_consume(SMMUv3State *s)
76
g_assert_cmpint(buf_rx[size], ==, buf_tx[size]);
124
{
125
SMMUState *bs = ARM_SMMU(s);
126
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
127
sid_range.end = sid_range.start + mask;
128
129
trace_smmuv3_cmdq_cfgi_ste_range(sid_range.start, sid_range.end);
130
- g_hash_table_foreach_remove(bs->configs, smmuv3_invalidate_ste,
131
- &sid_range);
132
+ smmu_configs_inv_sid_range(bs, sid_range);
133
break;
134
}
77
}
135
case SMMU_CMD_CFGI_CD:
78
136
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
79
@@ -XXX,XX +XXX,XX @@ static void test_can_data_transfer(void)
137
index XXXXXXX..XXXXXXX 100644
80
write_data(qts, CANFD0_BASE_ADDR, buf_tx, false);
138
--- a/hw/arm/trace-events
81
139
+++ b/hw/arm/trace-events
82
send_data(qts, CANFD0_BASE_ADDR);
140
@@ -XXX,XX +XXX,XX @@ smmu_iotlb_inv_asid_vmid(int asid, int vmid) "IOTLB invalidate asid=%d vmid=%d"
83
- read_data(qts, CANFD1_BASE_ADDR, buf_rx);
141
smmu_iotlb_inv_vmid(int vmid) "IOTLB invalidate vmid=%d"
84
+ read_data(qts, CANFD1_BASE_ADDR, buf_rx, CAN_FRAME_SIZE);
142
smmu_iotlb_inv_vmid_s1(int vmid) "IOTLB invalidate vmid=%d"
85
match_rx_tx_data(buf_tx, buf_rx, false);
143
smmu_iotlb_inv_iova(int asid, uint64_t addr) "IOTLB invalidate asid=%d addr=0x%"PRIx64
86
144
+smmu_configs_inv_sid_range(uint32_t start, uint32_t end) "Config cache INV SID range from 0x%x to 0x%x"
87
qtest_quit(qts);
145
+smmu_config_cache_inv(uint32_t sid) "Config cache INV for sid=0x%x"
88
@@ -XXX,XX +XXX,XX @@ static void test_canfd_data_transfer(void)
146
smmu_inv_notifiers_mr(const char *name) "iommu mr=%s"
89
write_data(qts, CANFD0_BASE_ADDR, buf_tx, true);
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"
90
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"
91
send_data(qts, CANFD0_BASE_ADDR);
149
@@ -XXX,XX +XXX,XX @@ smmuv3_cmdq_tlbi_nh(int vmid) "vmid=%d"
92
- read_data(qts, CANFD1_BASE_ADDR, buf_rx);
150
smmuv3_cmdq_tlbi_nsnh(void) ""
93
+ read_data(qts, CANFD1_BASE_ADDR, buf_rx, CANFD_FRAME_SIZE);
151
smmuv3_cmdq_tlbi_nh_asid(int asid) "asid=%d"
94
match_rx_tx_data(buf_tx, buf_rx, true);
152
smmuv3_cmdq_tlbi_s12_vmid(int vmid) "vmid=%d"
95
153
-smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid=0x%x"
96
qtest_quit(qts);
154
smmuv3_notify_flag_add(const char *iommu) "ADD SMMUNotifier node for iommu mr=%s"
97
@@ -XXX,XX +XXX,XX @@ static void test_can_loopback(void)
155
smmuv3_notify_flag_del(const char *iommu) "DEL SMMUNotifier node for iommu mr=%s"
98
write_data(qts, CANFD0_BASE_ADDR, buf_tx, true);
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"
99
100
send_data(qts, CANFD0_BASE_ADDR);
101
- read_data(qts, CANFD0_BASE_ADDR, buf_rx);
102
+ read_data(qts, CANFD0_BASE_ADDR, buf_rx, CANFD_FRAME_SIZE);
103
match_rx_tx_data(buf_tx, buf_rx, true);
104
105
generate_random_data(buf_tx, true);
106
@@ -XXX,XX +XXX,XX @@ static void test_can_loopback(void)
107
write_data(qts, CANFD1_BASE_ADDR, buf_tx, true);
108
109
send_data(qts, CANFD1_BASE_ADDR);
110
- read_data(qts, CANFD1_BASE_ADDR, buf_rx);
111
+ read_data(qts, CANFD1_BASE_ADDR, buf_rx, CANFD_FRAME_SIZE);
112
match_rx_tx_data(buf_tx, buf_rx, true);
113
114
qtest_quit(qts);
157
--
115
--
158
2.43.0
116
2.34.1
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
3
This code is only relevant when TCG is present in the build. Building
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
with --disable-tcg --enable-xen on an x86 host we get:
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
6
Message-id: 20250204125009.2281315-9-peter.maydell@linaro.org
6
$ ../configure --target-list=x86_64-softmmu,aarch64-softmmu --disable-tcg --enable-xen
7
Cc: qemu-stable@nongnu.org
7
$ make -j$(nproc)
8
...
9
libqemu-aarch64-softmmu.fa.p/target_arm_gdbstub.c.o: in function `m_sysreg_ptr':
10
../target/arm/gdbstub.c:358: undefined reference to `arm_v7m_get_sp_ptr'
11
../target/arm/gdbstub.c:361: undefined reference to `arm_v7m_get_sp_ptr'
12
13
libqemu-aarch64-softmmu.fa.p/target_arm_gdbstub.c.o: in function `arm_gdb_get_m_systemreg':
14
../target/arm/gdbstub.c:405: undefined reference to `arm_v7m_mrs_control'
15
16
Signed-off-by: Fabiano Rosas <farosas@suse.de>
17
Message-id: 20230628164821.16771-1-farosas@suse.de
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
20
---
11
hw/arm/virt.c | 2 ++
21
target/arm/gdbstub.c | 4 ++++
12
1 file changed, 2 insertions(+)
22
1 file changed, 4 insertions(+)
13
23
14
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
24
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
15
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/virt.c
26
--- a/target/arm/gdbstub.c
17
+++ b/hw/arm/virt.c
27
+++ b/target/arm/gdbstub.c
18
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
28
@@ -XXX,XX +XXX,XX @@ static int arm_gen_dynamic_sysreg_xml(CPUState *cs, int base_reg)
19
[GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
29
return cpu->dyn_sysreg_xml.num;
20
[GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
30
}
21
[GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
31
22
+ [GTIMER_S_EL2_PHYS] = ARCH_TIMER_S_EL2_IRQ,
32
+#ifdef CONFIG_TCG
23
+ [GTIMER_S_EL2_VIRT] = ARCH_TIMER_S_EL2_VIRT_IRQ,
33
typedef enum {
24
};
34
M_SYSREG_MSP,
25
35
M_SYSREG_PSP,
26
for (unsigned irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
36
@@ -XXX,XX +XXX,XX @@ static int arm_gen_dynamic_m_secextreg_xml(CPUState *cs, int orig_base_reg)
37
return cpu->dyn_m_secextreg_xml.num;
38
}
39
#endif
40
+#endif /* CONFIG_TCG */
41
42
const char *arm_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname)
43
{
44
@@ -XXX,XX +XXX,XX @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
45
arm_gen_dynamic_sysreg_xml(cs, cs->gdb_num_regs),
46
"system-registers.xml", 0);
47
48
+#ifdef CONFIG_TCG
49
if (arm_feature(env, ARM_FEATURE_M) && tcg_enabled()) {
50
gdb_register_coprocessor(cs,
51
arm_gdb_get_m_systemreg, arm_gdb_set_m_systemreg,
52
@@ -XXX,XX +XXX,XX @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
53
}
54
#endif
55
}
56
+#endif /* CONFIG_TCG */
57
}
27
--
58
--
28
2.43.0
59
2.34.1
29
30
diff view generated by jsdifflib
1
Currently we call icount_start_warp_timer() from timerlist_rearm().
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
This produces incorrect behaviour, because timerlist_rearm() is
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.
9
2
10
The only valid place to choose to warp the timer forward is from the
3
AwSRAMCClass is larger than SysBusDeviceClass so the class size must be
11
main loop, when we know we have no outstanding IO or timer callbacks
4
advertised accordingly.
12
that might be about to wake up a CPU.
13
5
14
For Arm guests, this bug was mostly latent until the refactoring
6
Fixes: 05def917e1 ("hw: arm: allwinner-sramc: Add SRAM Controller support for R40")
15
commit f6fc36deef6abc ("target/arm/helper: Implement
7
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
16
CNTHCTL_EL2.CNT[VP]MASK"), which exposed it because it refactored a
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
17
timer callback so that it happened to call timer_mod() first and
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
raise the interrupt second, when it had previously raised the
10
Message-id: 20230628110905.38125-1-akihiko.odaki@daynix.com
19
interrupt first and called timer_mod() afterwards.
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/misc/allwinner-sramc.c | 1 +
14
1 file changed, 1 insertion(+)
20
15
21
This call seems to have originally derived from the
16
diff --git a/hw/misc/allwinner-sramc.c b/hw/misc/allwinner-sramc.c
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
42
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
43
Reviewed-by: Richard Henderson <richard.henderson@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
47
---
48
util/qemu-timer.c | 4 ----
49
1 file changed, 4 deletions(-)
50
51
diff --git a/util/qemu-timer.c b/util/qemu-timer.c
52
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
53
--- a/util/qemu-timer.c
18
--- a/hw/misc/allwinner-sramc.c
54
+++ b/util/qemu-timer.c
19
+++ b/hw/misc/allwinner-sramc.c
55
@@ -XXX,XX +XXX,XX @@ static bool timer_mod_ns_locked(QEMUTimerList *timer_list,
20
@@ -XXX,XX +XXX,XX @@ static const TypeInfo allwinner_sramc_info = {
56
21
.parent = TYPE_SYS_BUS_DEVICE,
57
static void timerlist_rearm(QEMUTimerList *timer_list)
22
.instance_init = allwinner_sramc_init,
58
{
23
.instance_size = sizeof(AwSRAMCState),
59
- /* Interrupt execution to force deadline recalculation. */
24
+ .class_size = sizeof(AwSRAMCClass),
60
- if (icount_enabled() && timer_list->clock->type == QEMU_CLOCK_VIRTUAL) {
25
.class_init = allwinner_sramc_class_init,
61
- icount_start_warp_timer();
26
};
62
- }
63
timerlist_notify(timer_list);
64
}
65
27
66
--
28
--
67
2.43.0
29
2.34.1
68
30
69
31
diff view generated by jsdifflib
1
Expand the example in the comment documenting MO_ATOM_SUBALIGN,
1
In handle_interrupt() we use level as an index into the interrupt_vector[]
2
to be clearer about the atomicity guarantees it represents.
2
array. This is safe because we have checked it against env->config->nlevel,
3
but Coverity can't see that (and it is only true because each CPU config
4
sets its XCHAL_NUM_INTLEVELS to something less than MAX_NLEVELS), so it
5
complains about a possible array overrun (CID 1507131)
6
7
Add an assert() which will make Coverity happy and catch the unlikely
8
case of a mis-set XCHAL_NUM_INTLEVELS in future.
3
9
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Acked-by: Max Filippov <jcmvbkbc@gmail.com>
6
Message-id: 20250228103222.1838913-1-peter.maydell@linaro.org
12
Message-id: 20230623154135.1930261-1-peter.maydell@linaro.org
7
---
13
---
8
include/exec/memop.h | 8 ++++++--
14
target/xtensa/exc_helper.c | 3 +++
9
1 file changed, 6 insertions(+), 2 deletions(-)
15
1 file changed, 3 insertions(+)
10
16
11
diff --git a/include/exec/memop.h b/include/exec/memop.h
17
diff --git a/target/xtensa/exc_helper.c b/target/xtensa/exc_helper.c
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/include/exec/memop.h
19
--- a/target/xtensa/exc_helper.c
14
+++ b/include/exec/memop.h
20
+++ b/target/xtensa/exc_helper.c
15
@@ -XXX,XX +XXX,XX @@ typedef enum MemOp {
21
@@ -XXX,XX +XXX,XX @@ static void handle_interrupt(CPUXtensaState *env)
16
* Depending on alignment, one or both will be single-copy atomic.
22
CPUState *cs = env_cpu(env);
17
* This is the atomicity e.g. of Arm FEAT_LSE2 LDP.
23
18
* MO_ATOM_SUBALIGN: the operation is single-copy atomic by parts
24
if (level > 1) {
19
- * by the alignment. E.g. if the address is 0 mod 4, then each
25
+ /* env->config->nlevel check should have ensured this */
20
- * 4-byte subobject is single-copy atomic.
26
+ assert(level < sizeof(env->config->interrupt_vector));
21
+ * by the alignment. E.g. if an 8-byte value is accessed at an
27
+
22
+ * address which is 0 mod 8, then the whole 8-byte access is
28
env->sregs[EPC1 + level - 1] = env->pc;
23
+ * single-copy atomic; otherwise, if it is accessed at 0 mod 4
29
env->sregs[EPS2 + level - 2] = env->sregs[PS];
24
+ * then each 4-byte subobject is single-copy atomic; otherwise
30
env->sregs[PS] =
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
--
31
2.43.0
32
2.34.1
diff view generated by jsdifflib
1
All the callers of op_addr_rr_post() and op_addr_ri_post() now pass in
1
We already squash the ID register field for FEAT_SPE (the Statistical
2
zero for the address_offset, so we can remove that argument.
2
Profiling Extension) because TCG does not implement it and if we
3
advertise it to the guest the guest will crash trying to look at
4
non-existent system registers. Do the same for some other features
5
which a real hardware Neoverse-V1 implements but which TCG doesn't:
6
* FEAT_TRF (Self-hosted Trace Extension)
7
* Trace Macrocell system register access
8
* Memory mapped trace
9
* FEAT_AMU (Activity Monitors Extension)
10
* FEAT_MPAM (Memory Partitioning and Monitoring Extension)
11
* FEAT_NV (Nested Virtualization)
12
13
Most of these, like FEAT_SPE, are "introspection/trace" type features
14
which QEMU is unlikely to ever implement. The odd-one-out here is
15
FEAT_NV -- we could implement that and at some point we probably
16
will.
3
17
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Message-id: 20230704130647.2842917-2-peter.maydell@linaro.org
20
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20250227142746.1698904-4-peter.maydell@linaro.org
8
---
22
---
9
target/arm/tcg/translate.c | 26 +++++++++++++-------------
23
target/arm/cpu.c | 33 +++++++++++++++++++++++++++++----
10
1 file changed, 13 insertions(+), 13 deletions(-)
24
1 file changed, 29 insertions(+), 4 deletions(-)
11
25
12
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
26
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
13
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/tcg/translate.c
28
--- a/target/arm/cpu.c
15
+++ b/target/arm/tcg/translate.c
29
+++ b/target/arm/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 op_addr_rr_pre(DisasContext *s, arg_ldst_rr *a)
30
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
17
}
31
18
32
if (tcg_enabled()) {
19
static void op_addr_rr_post(DisasContext *s, arg_ldst_rr *a,
33
/*
20
- TCGv_i32 addr, int address_offset)
34
- * Don't report the Statistical Profiling Extension in the ID
21
+ TCGv_i32 addr)
35
- * registers, because TCG doesn't implement it yet (not even a
22
{
36
- * minimal stub version) and guests will fall over when they
23
if (!a->p) {
37
- * try to access the non-existent system registers for it.
24
TCGv_i32 ofs = load_reg(s, a->rm);
38
+ * Don't report some architectural features in the ID registers
25
@@ -XXX,XX +XXX,XX @@ static void op_addr_rr_post(DisasContext *s, arg_ldst_rr *a,
39
+ * where TCG does not yet implement it (not even a minimal
26
} else if (!a->w) {
40
+ * stub version). This avoids guests falling over when they
27
return;
41
+ * try to access the non-existent system registers for them.
42
*/
43
+ /* FEAT_SPE (Statistical Profiling Extension) */
44
cpu->isar.id_aa64dfr0 =
45
FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, PMSVER, 0);
46
+ /* FEAT_TRF (Self-hosted Trace Extension) */
47
+ cpu->isar.id_aa64dfr0 =
48
+ FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, TRACEFILT, 0);
49
+ cpu->isar.id_dfr0 =
50
+ FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, TRACEFILT, 0);
51
+ /* Trace Macrocell system register access */
52
+ cpu->isar.id_aa64dfr0 =
53
+ FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, TRACEVER, 0);
54
+ cpu->isar.id_dfr0 =
55
+ FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPTRC, 0);
56
+ /* Memory mapped trace */
57
+ cpu->isar.id_dfr0 =
58
+ FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, MMAPTRC, 0);
59
+ /* FEAT_AMU (Activity Monitors Extension) */
60
+ cpu->isar.id_aa64pfr0 =
61
+ FIELD_DP64(cpu->isar.id_aa64pfr0, ID_AA64PFR0, AMU, 0);
62
+ cpu->isar.id_pfr0 =
63
+ FIELD_DP32(cpu->isar.id_pfr0, ID_PFR0, AMU, 0);
64
+ /* FEAT_MPAM (Memory Partitioning and Monitoring Extension) */
65
+ cpu->isar.id_aa64pfr0 =
66
+ FIELD_DP64(cpu->isar.id_aa64pfr0, ID_AA64PFR0, MPAM, 0);
67
+ /* FEAT_NV (Nested Virtualization) */
68
+ cpu->isar.id_aa64mmfr2 =
69
+ FIELD_DP64(cpu->isar.id_aa64mmfr2, ID_AA64MMFR2, NV, 0);
28
}
70
}
29
- tcg_gen_addi_i32(addr, addr, address_offset);
71
30
store_reg(s, a->rn, addr);
72
/* MPU can be configured out of a PMSA CPU either by setting has-mpu
31
}
32
33
@@ -XXX,XX +XXX,XX @@ static bool op_load_rr(DisasContext *s, arg_ldst_rr *a,
34
* Perform base writeback before the loaded value to
35
* ensure correct behavior with overlapping index registers.
36
*/
37
- op_addr_rr_post(s, a, addr, 0);
38
+ op_addr_rr_post(s, a, addr);
39
store_reg_from_load(s, a->rt, tmp);
40
return true;
41
}
42
@@ -XXX,XX +XXX,XX @@ static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
43
gen_aa32_st_i32(s, tmp, addr, mem_idx, mop);
44
disas_set_da_iss(s, mop, issinfo);
45
46
- op_addr_rr_post(s, a, addr, 0);
47
+ op_addr_rr_post(s, a, addr);
48
return true;
49
}
50
51
@@ -XXX,XX +XXX,XX @@ static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
52
do_ldrd_load(s, addr, a->rt, a->rt + 1);
53
54
/* LDRD w/ base writeback is undefined if the registers overlap. */
55
- op_addr_rr_post(s, a, addr, 0);
56
+ op_addr_rr_post(s, a, addr);
57
return true;
58
}
59
60
@@ -XXX,XX +XXX,XX @@ static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
61
62
do_strd_store(s, addr, a->rt, a->rt + 1);
63
64
- op_addr_rr_post(s, a, addr, 0);
65
+ op_addr_rr_post(s, a, addr);
66
return true;
67
}
68
69
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 op_addr_ri_pre(DisasContext *s, arg_ldst_ri *a)
70
}
71
72
static void op_addr_ri_post(DisasContext *s, arg_ldst_ri *a,
73
- TCGv_i32 addr, int address_offset)
74
+ TCGv_i32 addr)
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
}
122
123
--
73
--
124
2.43.0
74
2.34.1
125
75
126
76
diff view generated by jsdifflib
1
When reading or writing the timer registers, sometimes we need to
1
Now that we have implemented support for FEAT_LSE2, we can define
2
apply one of the timer offsets. Specifically, this happens for
2
a CPU model for the Neoverse-V1, and enable it for the virt and
3
direct reads of the counter registers CNTPCT_EL0 and CNTVCT_EL0 (and
3
sbsa-ref boards.
4
their self-synchronized variants CNTVCTSS_EL0 and CNTPCTSS_EL0). It
4
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>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Message-id: 20230704130647.2842917-3-peter.maydell@linaro.org
26
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
27
Message-id: 20250204125009.2281315-6-peter.maydell@linaro.org
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
28
---
9
---
29
target/arm/internals.h | 5 +-
10
docs/system/arm/virt.rst | 1 +
30
target/arm/helper.c | 103 +++++++++++++++++++------------------
11
hw/arm/sbsa-ref.c | 1 +
31
target/arm/tcg/op_helper.c | 8 ++-
12
hw/arm/virt.c | 1 +
32
3 files changed, 62 insertions(+), 54 deletions(-)
13
target/arm/tcg/cpu64.c | 128 +++++++++++++++++++++++++++++++++++++++
33
14
4 files changed, 131 insertions(+)
34
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
35
index XXXXXXX..XXXXXXX 100644
16
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
36
--- a/target/arm/internals.h
17
index XXXXXXX..XXXXXXX 100644
37
+++ b/target/arm/internals.h
18
--- a/docs/system/arm/virt.rst
38
@@ -XXX,XX +XXX,XX @@ int delete_hw_watchpoint(target_ulong addr, target_ulong len, int type);
19
+++ b/docs/system/arm/virt.rst
39
uint64_t gt_get_countervalue(CPUARMState *env);
20
@@ -XXX,XX +XXX,XX @@ Supported guest CPU types:
40
/*
21
- ``a64fx`` (64-bit)
41
* Return the currently applicable offset between the system counter
22
- ``host`` (with KVM only)
42
- * and CNTVCT_EL0 (this will be either 0 or the value of CNTVOFF_EL2).
23
- ``neoverse-n1`` (64-bit)
43
+ * and the counter for the specified timer, as used for direct register
24
+- ``neoverse-v1`` (64-bit)
44
+ * accesses.
25
- ``max`` (same as ``host`` for KVM; best possible emulation with TCG)
45
*/
26
46
-uint64_t gt_virt_cnt_offset(CPUARMState *env);
27
Note that the default is ``cortex-a15``, so for an AArch64 guest you must
47
+uint64_t gt_direct_access_timer_offset(CPUARMState *env, int timeridx);
28
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
48
29
index XXXXXXX..XXXXXXX 100644
49
/*
30
--- a/hw/arm/sbsa-ref.c
50
* Return mask of ARMMMUIdxBit values corresponding to an "invalidate
31
+++ b/hw/arm/sbsa-ref.c
51
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
@@ -XXX,XX +XXX,XX @@ static const char * const valid_cpus[] = {
52
index XXXXXXX..XXXXXXX 100644
33
ARM_CPU_TYPE_NAME("cortex-a57"),
53
--- a/target/arm/helper.c
34
ARM_CPU_TYPE_NAME("cortex-a72"),
54
+++ b/target/arm/helper.c
35
ARM_CPU_TYPE_NAME("neoverse-n1"),
55
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_phys_raw_cnt_offset(CPUARMState *env)
36
+ ARM_CPU_TYPE_NAME("neoverse-v1"),
56
return 0;
37
ARM_CPU_TYPE_NAME("max"),
38
};
39
40
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/arm/virt.c
43
+++ b/hw/arm/virt.c
44
@@ -XXX,XX +XXX,XX @@ static const char *valid_cpus[] = {
45
ARM_CPU_TYPE_NAME("cortex-a76"),
46
ARM_CPU_TYPE_NAME("a64fx"),
47
ARM_CPU_TYPE_NAME("neoverse-n1"),
48
+ ARM_CPU_TYPE_NAME("neoverse-v1"),
49
#endif
50
ARM_CPU_TYPE_NAME("cortex-a53"),
51
ARM_CPU_TYPE_NAME("cortex-a57"),
52
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/tcg/cpu64.c
55
+++ b/target/arm/tcg/cpu64.c
56
@@ -XXX,XX +XXX,XX @@ static void define_neoverse_n1_cp_reginfo(ARMCPU *cpu)
57
define_arm_cp_regs(cpu, neoverse_n1_cp_reginfo);
57
}
58
}
58
59
59
-static uint64_t gt_phys_cnt_offset(CPUARMState *env)
60
+static const ARMCPRegInfo neoverse_v1_cp_reginfo[] = {
60
-{
61
+ { .name = "CPUECTLR2_EL1", .state = ARM_CP_STATE_AA64,
61
- if (arm_current_el(env) >= 2) {
62
+ .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 5,
62
- return 0;
63
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
63
- }
64
+ { .name = "CPUPPMCR_EL3", .state = ARM_CP_STATE_AA64,
64
- return gt_phys_raw_cnt_offset(env);
65
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 2, .opc2 = 0,
65
-}
66
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
66
-
67
+ { .name = "CPUPPMCR2_EL3", .state = ARM_CP_STATE_AA64,
67
static uint64_t gt_indirect_access_timer_offset(CPUARMState *env, int timeridx)
68
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 2, .opc2 = 1,
68
{
69
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
69
/*
70
+ { .name = "CPUPPMCR3_EL3", .state = ARM_CP_STATE_AA64,
70
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_indirect_access_timer_offset(CPUARMState *env, int timeridx)
71
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 2, .opc2 = 6,
71
}
72
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
72
}
73
+};
73
74
+
74
+uint64_t gt_direct_access_timer_offset(CPUARMState *env, int timeridx)
75
+static void define_neoverse_v1_cp_reginfo(ARMCPU *cpu)
75
+{
76
+{
76
+ /*
77
+ /*
77
+ * Return the timer offset to use for direct accesses to the
78
+ * The Neoverse V1 has all of the Neoverse N1's IMPDEF
78
+ * counter registers CNTPCT and CNTVCT, and for direct accesses
79
+ * registers and a few more of its own.
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
+ */
80
+ */
87
+ uint64_t hcr;
81
+ define_arm_cp_regs(cpu, neoverse_n1_cp_reginfo);
88
+
82
+ define_arm_cp_regs(cpu, neoverse_v1_cp_reginfo);
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
+}
83
+}
119
+
84
+
120
static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
85
static void aarch64_neoverse_n1_initfn(Object *obj)
121
{
86
{
122
ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx];
87
ARMCPU *cpu = ARM_CPU(obj);
123
@@ -XXX,XX +XXX,XX @@ static void gt_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri,
88
@@ -XXX,XX +XXX,XX @@ static void aarch64_neoverse_n1_initfn(Object *obj)
124
89
define_neoverse_n1_cp_reginfo(cpu);
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
}
90
}
153
91
154
static uint64_t gt_virt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
92
+static void aarch64_neoverse_v1_initfn(Object *obj)
155
{
93
+{
156
- return gt_get_countervalue(env) - gt_virt_cnt_offset(env);
94
+ ARMCPU *cpu = ARM_CPU(obj);
157
+ uint64_t offset = gt_direct_access_timer_offset(env, GTIMER_VIRT);
95
+
158
+ return gt_get_countervalue(env) - offset;
96
+ cpu->dtb_compatible = "arm,neoverse-v1";
159
}
97
+ set_feature(&cpu->env, ARM_FEATURE_V8);
160
98
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
161
static void gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
99
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
162
@@ -XXX,XX +XXX,XX @@ static uint64_t do_tval_read(CPUARMState *env, int timeridx, uint64_t offset)
100
+ set_feature(&cpu->env, ARM_FEATURE_AARCH64);
163
static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
101
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
164
int timeridx)
102
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
165
{
103
+ set_feature(&cpu->env, ARM_FEATURE_EL3);
166
- uint64_t offset = 0;
104
+ set_feature(&cpu->env, ARM_FEATURE_PMU);
167
-
105
+
168
- switch (timeridx) {
106
+ /* Ordered by 3.2.4 AArch64 registers by functional group */
169
- case GTIMER_VIRT:
107
+ cpu->clidr = 0x82000023;
170
- offset = gt_virt_cnt_offset(env);
108
+ cpu->ctr = 0xb444c004; /* With DIC and IDC set */
171
- break;
109
+ cpu->dcz_blocksize = 4;
172
- case GTIMER_PHYS:
110
+ cpu->id_aa64afr0 = 0x00000000;
173
- offset = gt_phys_cnt_offset(env);
111
+ cpu->id_aa64afr1 = 0x00000000;
174
- break;
112
+ cpu->isar.id_aa64dfr0 = 0x000001f210305519ull;
175
- }
113
+ cpu->isar.id_aa64dfr1 = 0x00000000;
176
+ uint64_t offset = gt_direct_access_timer_offset(env, timeridx);
114
+ cpu->isar.id_aa64isar0 = 0x1011111110212120ull; /* with FEAT_RNG */
177
115
+ cpu->isar.id_aa64isar1 = 0x0111000001211032ull;
178
return do_tval_read(env, timeridx, offset);
116
+ cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull;
179
}
117
+ cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
180
@@ -XXX,XX +XXX,XX @@ static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
118
+ cpu->isar.id_aa64mmfr2 = 0x0220011102101011ull;
181
int timeridx,
119
+ cpu->isar.id_aa64pfr0 = 0x1101110120111112ull; /* GIC filled in later */
182
uint64_t value)
120
+ cpu->isar.id_aa64pfr1 = 0x0000000000000020ull;
183
{
121
+ cpu->id_afr0 = 0x00000000;
184
- uint64_t offset = 0;
122
+ cpu->isar.id_dfr0 = 0x15011099;
185
+ uint64_t offset = gt_direct_access_timer_offset(env, timeridx);
123
+ cpu->isar.id_isar0 = 0x02101110;
186
124
+ cpu->isar.id_isar1 = 0x13112111;
187
- switch (timeridx) {
125
+ cpu->isar.id_isar2 = 0x21232042;
188
- case GTIMER_VIRT:
126
+ cpu->isar.id_isar3 = 0x01112131;
189
- offset = gt_virt_cnt_offset(env);
127
+ cpu->isar.id_isar4 = 0x00010142;
190
- break;
128
+ cpu->isar.id_isar5 = 0x11011121;
191
- case GTIMER_PHYS:
129
+ cpu->isar.id_isar6 = 0x01100111;
192
- offset = gt_phys_cnt_offset(env);
130
+ cpu->isar.id_mmfr0 = 0x10201105;
193
- break;
131
+ cpu->isar.id_mmfr1 = 0x40000000;
194
- }
132
+ cpu->isar.id_mmfr2 = 0x01260000;
195
do_tval_write(env, timeridx, value, offset);
133
+ cpu->isar.id_mmfr3 = 0x02122211;
196
}
134
+ cpu->isar.id_mmfr4 = 0x01021110;
197
135
+ cpu->isar.id_pfr0 = 0x21110131;
198
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
136
+ cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */
199
index XXXXXXX..XXXXXXX 100644
137
+ cpu->isar.id_pfr2 = 0x00000011;
200
--- a/target/arm/tcg/op_helper.c
138
+ cpu->midr = 0x411FD402; /* r1p2 */
201
+++ b/target/arm/tcg/op_helper.c
139
+ cpu->revidr = 0;
202
@@ -XXX,XX +XXX,XX @@ void HELPER(wfit)(CPUARMState *env, uint64_t timeout)
140
+
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
+ /*
141
+ /*
208
+ * We want the value that we would get if we read CNTVCT_EL0 from
142
+ * The Neoverse-V1 r1p2 TRM lists 32-bit format CCSIDR_EL1 values,
209
+ * the current exception level, so the direct_access offset, not
143
+ * but also says it implements CCIDX, which means they should be
210
+ * the indirect_access one. Compare the pseudocode LocalTimeoutEvent(),
144
+ * 64-bit format. So we here use values which are based on the textual
211
+ * which calls VirtualCounterTimer().
145
+ * information in chapter 2 of the TRM (and on the fact that
146
+ * sets * associativity * linesize == cachesize).
147
+ *
148
+ * The 64-bit CCSIDR_EL1 format is:
149
+ * [55:32] number of sets - 1
150
+ * [23:3] associativity - 1
151
+ * [2:0] log2(linesize) - 4
152
+ * so 0 == 16 bytes, 1 == 32 bytes, 2 == 64 bytes, etc
153
+ *
154
+ * L1: 4-way set associative 64-byte line size, total size 64K,
155
+ * so sets is 256.
156
+ *
157
+ * L2: 8-way set associative, 64 byte line size, either 512K or 1MB.
158
+ * We pick 1MB, so this has 2048 sets.
159
+ *
160
+ * L3: No L3 (this matches the CLIDR_EL1 value).
212
+ */
161
+ */
213
+ uint64_t offset = gt_direct_access_timer_offset(env, GTIMER_VIRT);
162
+ cpu->ccsidr[0] = 0x000000ff0000001aull; /* 64KB L1 dcache */
214
uint64_t cntvct = cntval - offset;
163
+ cpu->ccsidr[1] = 0x000000ff0000001aull; /* 64KB L1 icache */
215
uint64_t nexttick;
164
+ cpu->ccsidr[2] = 0x000007ff0000003aull; /* 1MB L2 cache */
216
165
+
166
+ /* From 3.2.115 SCTLR_EL3 */
167
+ cpu->reset_sctlr = 0x30c50838;
168
+
169
+ /* From 3.4.8 ICC_CTLR_EL3 and 3.4.23 ICH_VTR_EL2 */
170
+ cpu->gic_num_lrs = 4;
171
+ cpu->gic_vpribits = 5;
172
+ cpu->gic_vprebits = 5;
173
+ cpu->gic_pribits = 5;
174
+
175
+ /* From 3.5.1 AdvSIMD AArch64 register summary */
176
+ cpu->isar.mvfr0 = 0x10110222;
177
+ cpu->isar.mvfr1 = 0x13211111;
178
+ cpu->isar.mvfr2 = 0x00000043;
179
+
180
+ /* From 3.7.5 ID_AA64ZFR0_EL1 */
181
+ cpu->isar.id_aa64zfr0 = 0x0000100000100000;
182
+ cpu->sve_vq.supported = (1 << 0) /* 128bit */
183
+ | (1 << 1); /* 256bit */
184
+
185
+ /* From 5.5.1 AArch64 PMU register summary */
186
+ cpu->isar.reset_pmcr_el0 = 0x41213000;
187
+
188
+ define_neoverse_v1_cp_reginfo(cpu);
189
+
190
+ aarch64_add_pauth_properties(obj);
191
+ aarch64_add_sve_properties(obj);
192
+}
193
+
194
/*
195
* -cpu max: a CPU with as many features enabled as our emulation supports.
196
* The version of '-cpu max' for qemu-system-arm is defined in cpu32.c;
197
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo aarch64_cpus[] = {
198
{ .name = "cortex-a76", .initfn = aarch64_a76_initfn },
199
{ .name = "a64fx", .initfn = aarch64_a64fx_initfn },
200
{ .name = "neoverse-n1", .initfn = aarch64_neoverse_n1_initfn },
201
+ { .name = "neoverse-v1", .initfn = aarch64_neoverse_v1_initfn },
202
};
203
204
static void aarch64_cpu_register_types(void)
217
--
205
--
218
2.43.0
206
2.34.1
219
207
220
208
diff view generated by jsdifflib
1
When we are calculating timer deadlines, the correct definition of
1
If you build QEMU with the clang sanitizer enabled, you can see it
2
whether or not to apply an offset to the physical count is described
2
fire when running the arm-cpu-features test:
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.
6
3
7
We got this right for the EL1 physical timer and for the EL1 virtual
4
$ QTEST_QEMU_BINARY=./build/arm-clang/qemu-system-aarch64 ./build/arm-clang/tests/qtest/arm-cpu-features
8
timer, but got all the rest wrong: they should be using a zero offset
5
[...]
9
always.
6
../../target/arm/cpu64.c:125:19: runtime error: shift exponent 64 is too large for 64-bit type 'unsigned long long'
7
[...]
10
8
11
Factor the offset calculation out into a function that has a comment
9
This happens because the user can specify some incorrect SVE
12
documenting exactly which offset it is calculating and which gets the
10
properties that result in our calculating a max_vq of 0. We catch
13
HYP, SEC, and HYPVIRT cases right.
11
this and error out, but before we do that we calculate
14
12
15
Cc: qemu-stable@nongnu.org
13
vq_mask = MAKE_64BIT_MASK(0, max_vq);$
14
15
and the MAKE_64BIT_MASK() call is only valid for lengths that are
16
greater than zero, so we hit the undefined behaviour.
17
18
Change the logic so that if max_vq is 0 we specifically set vq_mask
19
to 0 without going via MAKE_64BIT_MASK(). This lets us drop the
20
max_vq check from the error-exit logic, because if max_vq is 0 then
21
vq_map must now be 0.
22
23
The UB only happens in the case where the user passed us an incorrect
24
set of SVE properties, so it's not a big problem in practice.
25
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
27
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
18
Message-id: 20250204125009.2281315-2-peter.maydell@linaro.org
28
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Message-id: 20230704154332.3014896-1-peter.maydell@linaro.org
19
---
30
---
20
target/arm/helper.c | 29 +++++++++++++++++++++++++++--
31
target/arm/cpu64.c | 4 ++--
21
1 file changed, 27 insertions(+), 2 deletions(-)
32
1 file changed, 2 insertions(+), 2 deletions(-)
22
33
23
diff --git a/target/arm/helper.c b/target/arm/helper.c
34
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
24
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/helper.c
36
--- a/target/arm/cpu64.c
26
+++ b/target/arm/helper.c
37
+++ b/target/arm/cpu64.c
27
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_phys_cnt_offset(CPUARMState *env)
38
@@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
28
return gt_phys_raw_cnt_offset(env);
39
vq = ctz32(tmp) + 1;
29
}
40
30
41
max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
31
+static uint64_t gt_indirect_access_timer_offset(CPUARMState *env, int timeridx)
42
- vq_mask = MAKE_64BIT_MASK(0, max_vq);
32
+{
43
+ vq_mask = max_vq > 0 ? MAKE_64BIT_MASK(0, max_vq) : 0;
33
+ /*
44
vq_map = vq_supported & ~vq_init & vq_mask;
34
+ * Return the timer offset to use for indirect accesses to the timer.
45
35
+ * This is the Offset value as defined in D12.2.4.1 "Operation of the
46
- if (max_vq == 0 || vq_map == 0) {
36
+ * CompareValue views of the timers".
47
+ if (vq_map == 0) {
37
+ *
48
error_setg(errp, "cannot disable sve%d", vq * 128);
38
+ * The condition here is not always the same as the condition for
49
error_append_hint(errp, "Disabling sve%d results in all "
39
+ * whether to apply an offset register when doing a direct read of
50
"vector lengths being disabled.\n",
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;
70
--
51
--
71
2.43.0
52
2.34.1
72
53
73
54
diff view generated by jsdifflib
Deleted patch
1
The CNTVOFF_EL2 offset register should only be applied for accessses
2
to CNTVCT_EL0 and for the EL1 virtual timer (CNTV_*). We were
3
incorrectly applying it for the EL2 virtual timer (CNTHV_*).
4
1
5
Cc: qemu-stable@nongnu.org
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(-)
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
18
19
switch (timeridx) {
20
case GTIMER_VIRT:
21
- case GTIMER_HYPVIRT:
22
offset = gt_virt_cnt_offset(env);
23
break;
24
case GTIMER_PHYS:
25
@@ -XXX,XX +XXX,XX @@ static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
26
27
switch (timeridx) {
28
case GTIMER_VIRT:
29
- case GTIMER_HYPVIRT:
30
offset = gt_virt_cnt_offset(env);
31
break;
32
case GTIMER_PHYS:
33
--
34
2.43.0
35
36
diff view generated by jsdifflib
Deleted patch
1
Our LDRD implementation is wrong in two respects:
2
1
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
Deleted 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
4
1
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
Deleted 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
9
1
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