1
target-arm queue, mostly SME preliminaries.
1
Hi; here's a target-arm pullreq to go in before softfreeze.
2
This is actually pretty much entirely bugfixes (since the
3
SEL2 timers we implement here are a missing part of a feature
4
we claim to already implement).
2
5
3
In the unlikely event we don't land the rest of SME before freeze
6
thanks
4
for 7.1 we can revert the docs/property changes included here.
5
6
-- PMM
7
-- PMM
7
8
8
The following changes since commit 097ccbbbaf2681df1e65542e5b7d2b2d0c66e2bc:
9
The following changes since commit 98c7362b1efe651327385a25874a73e008c6549e:
9
10
10
Merge tag 'qemu-sparc-20220626' of https://github.com/mcayland/qemu into staging (2022-06-27 05:21:05 +0530)
11
Merge tag 'accel-cpus-20250306' of https://github.com/philmd/qemu into staging (2025-03-07 07:39:49 +0800)
11
12
12
are available in the Git repository at:
13
are available in the Git repository at:
13
14
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220627
15
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20250307
15
16
16
for you to fetch changes up to 59e1b8a22ea9f947d038ccac784de1020f266e14:
17
for you to fetch changes up to 0ce0739d46983e5e88fa9c149cb305689c9d8c6f:
17
18
18
target/arm: Check V7VE as well as LPAE in arm_pamax (2022-06-27 11:18:17 +0100)
19
target/rx: Remove TCG_CALL_NO_WG from helpers which write env (2025-03-07 15:03:20 +0000)
19
20
20
----------------------------------------------------------------
21
----------------------------------------------------------------
21
target-arm queue:
22
target-arm queue:
22
* sphinx: change default language to 'en'
23
* hw/arm/smmu-common: Remove the repeated ttb field
23
* Diagnose attempts to emulate EL3 in hvf as well as kvm
24
* hw/gpio: npcm7xx: fixup out-of-bounds access
24
* More SME groundwork patches
25
* tests/functional/test_arm_sx1: Check whether the serial console is working
25
* virt: Fix calculation of physical address space size
26
* target/arm: Fix minor bugs in generic timer register handling
26
for v7VE CPUs (eg cortex-a15)
27
* target/arm: Implement SEL2 physical and virtual timers
28
* target/arm: Correct STRD, LDRD atomicity and fault behaviour
29
* target/arm: Make dummy debug registers RAZ, not NOP
30
* util/qemu-timer.c: Don't warp timer from timerlist_rearm()
31
* include/exec/memop.h: Expand comment for MO_ATOM_SUBALIGN
32
* hw/arm/smmu: Introduce smmu_configs_inv_sid_range() helper
33
* target/rx: Set exception vector base to 0xffffff80
34
* target/rx: Remove TCG_CALL_NO_WG from helpers which write env
27
35
28
----------------------------------------------------------------
36
----------------------------------------------------------------
29
Alexander Graf (2):
37
Alex Bennée (4):
30
accel: Introduce current_accel_name()
38
target/arm: Implement SEL2 physical and virtual timers
31
target/arm: Catch invalid kvm state also for hvf
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
32
42
33
Martin Liška (1):
43
JianChunfu (2):
34
sphinx: change default language to 'en'
44
hw/arm/smmu-common: Remove the repeated ttb field
45
hw/arm/smmu: Introduce smmu_configs_inv_sid_range() helper
35
46
36
Richard Henderson (22):
47
Keith Packard (2):
37
target/arm: Implement TPIDR2_EL0
48
target/rx: Set exception vector base to 0xffffff80
38
target/arm: Add SMEEXC_EL to TB flags
49
target/rx: Remove TCG_CALL_NO_WG from helpers which write env
39
target/arm: Add syn_smetrap
40
target/arm: Add ARM_CP_SME
41
target/arm: Add SVCR
42
target/arm: Add SMCR_ELx
43
target/arm: Add SMIDR_EL1, SMPRI_EL1, SMPRIMAP_EL2
44
target/arm: Add PSTATE.{SM,ZA} to TB flags
45
target/arm: Add the SME ZA storage to CPUARMState
46
target/arm: Implement SMSTART, SMSTOP
47
target/arm: Move error for sve%d property to arm_cpu_sve_finalize
48
target/arm: Create ARMVQMap
49
target/arm: Generalize cpu_arm_{get,set}_vq
50
target/arm: Generalize cpu_arm_{get, set}_default_vec_len
51
target/arm: Move arm_cpu_*_finalize to internals.h
52
target/arm: Unexport aarch64_add_*_properties
53
target/arm: Add cpu properties for SME
54
target/arm: Introduce sve_vqm1_for_el_sm
55
target/arm: Add SVL to TB flags
56
target/arm: Move pred_{full, gvec}_reg_{offset, size} to translate-a64.h
57
target/arm: Extend arm_pamax to more than aarch64
58
target/arm: Check V7VE as well as LPAE in arm_pamax
59
50
60
docs/conf.py | 2 +-
51
Patrick Venture (1):
61
docs/system/arm/cpu-features.rst | 56 ++++++++++
52
hw/gpio: npcm7xx: fixup out-of-bounds access
62
include/qemu/accel.h | 1 +
63
target/arm/cpregs.h | 5 +
64
target/arm/cpu.h | 103 ++++++++++++++-----
65
target/arm/helper-sme.h | 21 ++++
66
target/arm/helper.h | 1 +
67
target/arm/internals.h | 4 +
68
target/arm/syndrome.h | 14 +++
69
target/arm/translate-a64.h | 38 +++++++
70
target/arm/translate.h | 6 ++
71
accel/accel-common.c | 8 ++
72
hw/arm/virt.c | 10 +-
73
softmmu/vl.c | 3 +-
74
target/arm/cpu.c | 32 ++++--
75
target/arm/cpu64.c | 205 ++++++++++++++++++++++++++++---------
76
target/arm/helper.c | 213 +++++++++++++++++++++++++++++++++++++--
77
target/arm/kvm64.c | 2 +-
78
target/arm/machine.c | 34 +++++++
79
target/arm/ptw.c | 26 +++--
80
target/arm/sme_helper.c | 61 +++++++++++
81
target/arm/translate-a64.c | 46 +++++++++
82
target/arm/translate-sve.c | 36 -------
83
target/arm/meson.build | 1 +
84
24 files changed, 782 insertions(+), 146 deletions(-)
85
create mode 100644 target/arm/helper-sme.h
86
create mode 100644 target/arm/sme_helper.c
87
53
54
Peter Maydell (11):
55
target/arm: Apply correct timer offset when calculating deadlines
56
target/arm: Don't apply CNTVOFF_EL2 for EL2_VIRT timer
57
target/arm: Make CNTPS_* UNDEF from Secure EL1 when Secure EL2 is enabled
58
target/arm: Always apply CNTVOFF_EL2 for CNTV_TVAL_EL02 accesses
59
target/arm: Refactor handling of timer offset for direct register accesses
60
target/arm: Correct LDRD atomicity and fault behaviour
61
target/arm: Correct STRD atomicity
62
target/arm: Drop unused address_offset from op_addr_{rr, ri}_post()
63
target/arm: Make dummy debug registers RAZ, not NOP
64
util/qemu-timer.c: Don't warp timer from timerlist_rearm()
65
include/exec/memop.h: Expand comment for MO_ATOM_SUBALIGN
66
67
Thomas Huth (1):
68
tests/functional/test_arm_sx1: Check whether the serial console is working
69
70
MAINTAINERS | 1 +
71
hw/arm/smmu-internal.h | 5 -
72
include/exec/memop.h | 8 +-
73
include/hw/arm/bsa.h | 2 +
74
include/hw/arm/smmu-common.h | 7 +-
75
target/arm/cpu.h | 2 +
76
target/arm/gtimer.h | 14 +-
77
target/arm/internals.h | 5 +-
78
target/rx/helper.h | 34 ++--
79
hw/arm/sbsa-ref.c | 2 +
80
hw/arm/smmu-common.c | 21 +++
81
hw/arm/smmuv3.c | 19 +--
82
hw/arm/virt.c | 2 +
83
hw/gpio/npcm7xx_gpio.c | 3 +-
84
target/arm/cpu.c | 4 +
85
target/arm/debug_helper.c | 7 +-
86
target/arm/helper.c | 324 ++++++++++++++++++++++++++++++++-------
87
target/arm/tcg/op_helper.c | 8 +-
88
target/arm/tcg/translate.c | 147 +++++++++++-------
89
target/rx/helper.c | 2 +-
90
util/qemu-timer.c | 4 -
91
hw/arm/trace-events | 3 +-
92
tests/functional/test_arm_sx1.py | 7 +-
93
23 files changed, 455 insertions(+), 176 deletions(-)
94
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: JianChunfu <jansef.jian@hj-micro.com>
2
2
3
We will need these functions in translate-sme.c.
3
SMMUTransCfg->ttb is never used in QEMU, TT base address
4
can be accessed by SMMUTransCfg->tt[i]->ttb.
4
5
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: JianChunfu <jansef.jian@hj-micro.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Eric Auger <eric.auger@redhat.com>
7
Message-id: 20220620175235.60881-21-richard.henderson@linaro.org
8
Message-id: 20250221031034.69822-1-jansef.jian@hj-micro.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/translate-a64.h | 38 ++++++++++++++++++++++++++++++++++++++
11
include/hw/arm/smmu-common.h | 1 -
11
target/arm/translate-sve.c | 36 ------------------------------------
12
1 file changed, 1 deletion(-)
12
2 files changed, 38 insertions(+), 36 deletions(-)
13
13
14
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
14
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.h
16
--- a/include/hw/arm/smmu-common.h
17
+++ b/target/arm/translate-a64.h
17
+++ b/include/hw/arm/smmu-common.h
18
@@ -XXX,XX +XXX,XX @@ static inline int vec_full_reg_size(DisasContext *s)
18
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUTransCfg {
19
return s->vl;
19
/* Used by stage-1 only. */
20
}
20
bool aa64; /* arch64 or aarch32 translation table */
21
21
bool record_faults; /* record fault events */
22
+/*
22
- uint64_t ttb; /* TT base address */
23
+ * Return the offset info CPUARMState of the predicate vector register Pn.
23
uint8_t oas; /* output address width */
24
+ * Note for this purpose, FFR is P16.
24
uint8_t tbi; /* Top Byte Ignore */
25
+ */
25
int asid;
26
+static inline int pred_full_reg_offset(DisasContext *s, int regno)
27
+{
28
+ return offsetof(CPUARMState, vfp.pregs[regno]);
29
+}
30
+
31
+/* Return the byte size of the whole predicate register, VL / 64. */
32
+static inline int pred_full_reg_size(DisasContext *s)
33
+{
34
+ return s->vl >> 3;
35
+}
36
+
37
+/*
38
+ * Round up the size of a register to a size allowed by
39
+ * the tcg vector infrastructure. Any operation which uses this
40
+ * size may assume that the bits above pred_full_reg_size are zero,
41
+ * and must leave them the same way.
42
+ *
43
+ * Note that this is not needed for the vector registers as they
44
+ * are always properly sized for tcg vectors.
45
+ */
46
+static inline int size_for_gvec(int size)
47
+{
48
+ if (size <= 8) {
49
+ return 8;
50
+ } else {
51
+ return QEMU_ALIGN_UP(size, 16);
52
+ }
53
+}
54
+
55
+static inline int pred_gvec_reg_size(DisasContext *s)
56
+{
57
+ return size_for_gvec(pred_full_reg_size(s));
58
+}
59
+
60
bool disas_sve(DisasContext *, uint32_t);
61
62
void gen_gvec_rax1(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
63
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/translate-sve.c
66
+++ b/target/arm/translate-sve.c
67
@@ -XXX,XX +XXX,XX @@ static inline int msz_dtype(DisasContext *s, int msz)
68
* Implement all of the translator functions referenced by the decoder.
69
*/
70
71
-/* Return the offset info CPUARMState of the predicate vector register Pn.
72
- * Note for this purpose, FFR is P16.
73
- */
74
-static inline int pred_full_reg_offset(DisasContext *s, int regno)
75
-{
76
- return offsetof(CPUARMState, vfp.pregs[regno]);
77
-}
78
-
79
-/* Return the byte size of the whole predicate register, VL / 64. */
80
-static inline int pred_full_reg_size(DisasContext *s)
81
-{
82
- return s->vl >> 3;
83
-}
84
-
85
-/* Round up the size of a register to a size allowed by
86
- * the tcg vector infrastructure. Any operation which uses this
87
- * size may assume that the bits above pred_full_reg_size are zero,
88
- * and must leave them the same way.
89
- *
90
- * Note that this is not needed for the vector registers as they
91
- * are always properly sized for tcg vectors.
92
- */
93
-static int size_for_gvec(int size)
94
-{
95
- if (size <= 8) {
96
- return 8;
97
- } else {
98
- return QEMU_ALIGN_UP(size, 16);
99
- }
100
-}
101
-
102
-static int pred_gvec_reg_size(DisasContext *s)
103
-{
104
- return size_for_gvec(pred_full_reg_size(s));
105
-}
106
-
107
/* Invoke an out-of-line helper on 2 Zregs. */
108
static bool gen_gvec_ool_zz(DisasContext *s, gen_helper_gvec_2 *fn,
109
int rd, int rn, int data)
110
--
26
--
111
2.25.1
27
2.43.0
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Patrick Venture <venture@google.com>
2
2
3
Rename from cpu_arm_{get,set}_sve_default_vec_len,
3
The reg isn't validated to be a possible register before
4
and take the pointer to default_vq from opaque.
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.
5
7
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Cc: qemu-stable@nongnu.org
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Fixes: 526dbbe0874 ("hw/gpio: Add GPIO model for Nuvoton NPCM7xx")
8
Message-id: 20220620175235.60881-15-richard.henderson@linaro.org
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
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
14
---
11
target/arm/cpu64.c | 27 ++++++++++++++-------------
15
hw/gpio/npcm7xx_gpio.c | 3 +--
12
1 file changed, 14 insertions(+), 13 deletions(-)
16
1 file changed, 1 insertion(+), 2 deletions(-)
13
17
14
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
18
diff --git a/hw/gpio/npcm7xx_gpio.c b/hw/gpio/npcm7xx_gpio.c
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu64.c
20
--- a/hw/gpio/npcm7xx_gpio.c
17
+++ b/target/arm/cpu64.c
21
+++ b/hw/gpio/npcm7xx_gpio.c
18
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve(Object *obj, bool value, Error **errp)
22
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_gpio_regs_write(void *opaque, hwaddr addr, uint64_t v,
19
20
#ifdef CONFIG_USER_ONLY
21
/* Mirror linux /proc/sys/abi/sve_default_vector_length. */
22
-static void cpu_arm_set_sve_default_vec_len(Object *obj, Visitor *v,
23
- const char *name, void *opaque,
24
- Error **errp)
25
+static void cpu_arm_set_default_vec_len(Object *obj, Visitor *v,
26
+ const char *name, void *opaque,
27
+ Error **errp)
28
{
29
- ARMCPU *cpu = ARM_CPU(obj);
30
+ uint32_t *ptr_default_vq = opaque;
31
int32_t default_len, default_vq, remainder;
32
33
if (!visit_type_int32(v, name, &default_len, errp)) {
34
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve_default_vec_len(Object *obj, Visitor *v,
35
36
/* Undocumented, but the kernel allows -1 to indicate "maximum". */
37
if (default_len == -1) {
38
- cpu->sve_default_vq = ARM_MAX_VQ;
39
+ *ptr_default_vq = ARM_MAX_VQ;
40
return;
23
return;
41
}
24
}
42
25
43
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve_default_vec_len(Object *obj, Visitor *v,
26
- diff = s->regs[reg] ^ value;
44
return;
27
-
45
}
28
switch (reg) {
46
29
case NPCM7XX_GPIO_TLOCK1:
47
- cpu->sve_default_vq = default_vq;
30
case NPCM7XX_GPIO_TLOCK2:
48
+ *ptr_default_vq = default_vq;
31
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_gpio_regs_write(void *opaque, hwaddr addr, uint64_t v,
49
}
32
case NPCM7XX_GPIO_PU:
50
33
case NPCM7XX_GPIO_PD:
51
-static void cpu_arm_get_sve_default_vec_len(Object *obj, Visitor *v,
34
case NPCM7XX_GPIO_IEM:
52
- const char *name, void *opaque,
35
+ diff = s->regs[reg] ^ value;
53
- Error **errp)
36
s->regs[reg] = value;
54
+static void cpu_arm_get_default_vec_len(Object *obj, Visitor *v,
37
npcm7xx_gpio_update_pins(s, diff);
55
+ const char *name, void *opaque,
38
break;
56
+ Error **errp)
57
{
58
- ARMCPU *cpu = ARM_CPU(obj);
59
- int32_t value = cpu->sve_default_vq * 16;
60
+ uint32_t *ptr_default_vq = opaque;
61
+ int32_t value = *ptr_default_vq * 16;
62
63
visit_type_int32(v, name, &value, errp);
64
}
65
@@ -XXX,XX +XXX,XX @@ void aarch64_add_sve_properties(Object *obj)
66
#ifdef CONFIG_USER_ONLY
67
/* Mirror linux /proc/sys/abi/sve_default_vector_length. */
68
object_property_add(obj, "sve-default-vector-length", "int32",
69
- cpu_arm_get_sve_default_vec_len,
70
- cpu_arm_set_sve_default_vec_len, NULL, NULL);
71
+ cpu_arm_get_default_vec_len,
72
+ cpu_arm_set_default_vec_len, NULL,
73
+ &cpu->sve_default_vq);
74
#endif
75
}
76
77
--
39
--
78
2.25.1
40
2.43.0
41
42
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
We need SVL separate from VL for RDSVL et al, as well as
3
The kernel that is used in the sx1 test prints the usual Linux log
4
ZA storage loads and stores, which do not require PSTATE.SM.
4
onto the serial console, but this test currently ignores it. To
5
make sure that the serial device is working properly, let's check
6
for some strings in the output here.
5
7
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
While we're at it, also add the test to the corresponding section
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
in the MAINTAINERS file.
8
Message-id: 20220620175235.60881-20-richard.henderson@linaro.org
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
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
15
---
11
target/arm/cpu.h | 12 ++++++++++++
16
MAINTAINERS | 1 +
12
target/arm/translate.h | 1 +
17
tests/functional/test_arm_sx1.py | 7 ++++---
13
target/arm/helper.c | 8 +++++++-
18
2 files changed, 5 insertions(+), 3 deletions(-)
14
target/arm/translate-a64.c | 1 +
15
4 files changed, 21 insertions(+), 1 deletion(-)
16
19
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
diff --git a/MAINTAINERS b/MAINTAINERS
18
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
22
--- a/MAINTAINERS
20
+++ b/target/arm/cpu.h
23
+++ b/MAINTAINERS
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, MTE0_ACTIVE, 19, 1)
24
@@ -XXX,XX +XXX,XX @@ S: Maintained
22
FIELD(TBFLAG_A64, SMEEXC_EL, 20, 2)
25
F: hw/*/omap*
23
FIELD(TBFLAG_A64, PSTATE_SM, 22, 1)
26
F: include/hw/arm/omap.h
24
FIELD(TBFLAG_A64, PSTATE_ZA, 23, 1)
27
F: docs/system/arm/sx1.rst
25
+FIELD(TBFLAG_A64, SVL, 24, 4)
28
+F: tests/functional/test_arm_sx1.py
26
29
27
/*
30
IPack
28
* Helpers for using the above.
31
M: Alberto Garcia <berto@igalia.com>
29
@@ -XXX,XX +XXX,XX @@ static inline int sve_vq(CPUARMState *env)
32
diff --git a/tests/functional/test_arm_sx1.py b/tests/functional/test_arm_sx1.py
30
return EX_TBFLAG_A64(env->hflags, VL) + 1;
33
index XXXXXXX..XXXXXXX 100755
31
}
34
--- a/tests/functional/test_arm_sx1.py
32
35
+++ b/tests/functional/test_arm_sx1.py
33
+/**
36
@@ -XXX,XX +XXX,XX @@ def test_arm_sx1_initrd(self):
34
+ * sme_vq
37
self.vm.add_args('-append', f'kunit.enable=0 rdinit=/sbin/init {self.CONSOLE_ARGS}')
35
+ * @env: the cpu context
38
self.vm.add_args('-no-reboot')
36
+ *
39
self.launch_kernel(zimage_path,
37
+ * Return the SVL cached within env->hflags, in units of quadwords.
40
- initrd=initrd_path)
38
+ */
41
+ initrd=initrd_path,
39
+static inline int sme_vq(CPUARMState *env)
42
+ wait_for='Boot successful')
40
+{
43
self.vm.wait(timeout=120)
41
+ return EX_TBFLAG_A64(env->hflags, SVL) + 1;
44
42
+}
45
def test_arm_sx1_sd(self):
43
+
46
@@ -XXX,XX +XXX,XX @@ def test_arm_sx1_sd(self):
44
static inline bool bswap_code(bool sctlr_b)
47
self.vm.add_args('-no-reboot')
45
{
48
self.vm.add_args('-snapshot')
46
#ifdef CONFIG_USER_ONLY
49
self.vm.add_args('-drive', f'format=raw,if=sd,file={sd_fs_path}')
47
diff --git a/target/arm/translate.h b/target/arm/translate.h
50
- self.launch_kernel(zimage_path)
48
index XXXXXXX..XXXXXXX 100644
51
+ self.launch_kernel(zimage_path, wait_for='Boot successful')
49
--- a/target/arm/translate.h
52
self.vm.wait(timeout=120)
50
+++ b/target/arm/translate.h
53
51
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
54
def test_arm_sx1_flash(self):
52
int sve_excp_el; /* SVE exception EL or 0 if enabled */
55
@@ -XXX,XX +XXX,XX @@ def test_arm_sx1_flash(self):
53
int sme_excp_el; /* SME exception EL or 0 if enabled */
56
self.vm.add_args('-no-reboot')
54
int vl; /* current vector length in bytes */
57
self.vm.add_args('-snapshot')
55
+ int svl; /* current streaming vector length in bytes */
58
self.vm.add_args('-drive', f'format=raw,if=pflash,file={flash_path}')
56
bool vfp_enabled; /* FP enabled via FPSCR.EN */
59
- self.launch_kernel(zimage_path)
57
int vec_len;
60
+ self.launch_kernel(zimage_path, wait_for='Boot successful')
58
int vec_stride;
61
self.vm.wait(timeout=120)
59
diff --git a/target/arm/helper.c b/target/arm/helper.c
62
60
index XXXXXXX..XXXXXXX 100644
63
if __name__ == '__main__':
61
--- a/target/arm/helper.c
62
+++ b/target/arm/helper.c
63
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
64
DP_TBFLAG_A64(flags, SVEEXC_EL, sve_el);
65
}
66
if (cpu_isar_feature(aa64_sme, env_archcpu(env))) {
67
- DP_TBFLAG_A64(flags, SMEEXC_EL, sme_exception_el(env, el));
68
+ int sme_el = sme_exception_el(env, el);
69
+
70
+ DP_TBFLAG_A64(flags, SMEEXC_EL, sme_el);
71
+ if (sme_el == 0) {
72
+ /* Similarly, do not compute SVL if SME is disabled. */
73
+ DP_TBFLAG_A64(flags, SVL, sve_vqm1_for_el_sm(env, el, true));
74
+ }
75
if (FIELD_EX64(env->svcr, SVCR, SM)) {
76
DP_TBFLAG_A64(flags, PSTATE_SM, 1);
77
}
78
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/target/arm/translate-a64.c
81
+++ b/target/arm/translate-a64.c
82
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
83
dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
84
dc->sme_excp_el = EX_TBFLAG_A64(tb_flags, SMEEXC_EL);
85
dc->vl = (EX_TBFLAG_A64(tb_flags, VL) + 1) * 16;
86
+ dc->svl = (EX_TBFLAG_A64(tb_flags, SVL) + 1) * 16;
87
dc->pauth_active = EX_TBFLAG_A64(tb_flags, PAUTH_ACTIVE);
88
dc->bt = EX_TBFLAG_A64(tb_flags, BT);
89
dc->btype = EX_TBFLAG_A64(tb_flags, BTYPE);
90
--
64
--
91
2.25.1
65
2.43.0
66
67
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
When we are calculating timer deadlines, the correct definition of
2
whether or not to apply an offset to the physical count is described
3
in the Arm ARM DDI4087 rev L.a section D12.2.4.1. This is different
4
from when the offset should be applied for a direct read of the
5
counter sysreg.
2
6
3
These cpregs control the streaming vector length and whether the
7
We got this right for the EL1 physical timer and for the EL1 virtual
4
full a64 instruction set is allowed while in streaming mode.
8
timer, but got all the rest wrong: they should be using a zero offset
9
always.
5
10
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Factor the offset calculation out into a function that has a comment
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
documenting exactly which offset it is calculating and which gets the
8
Message-id: 20220620175235.60881-7-richard.henderson@linaro.org
13
HYP, SEC, and HYPVIRT cases right.
14
15
Cc: qemu-stable@nongnu.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
18
Message-id: 20250204125009.2281315-2-peter.maydell@linaro.org
10
---
19
---
11
target/arm/cpu.h | 8 ++++++--
20
target/arm/helper.c | 29 +++++++++++++++++++++++++++--
12
target/arm/helper.c | 41 +++++++++++++++++++++++++++++++++++++++++
21
1 file changed, 27 insertions(+), 2 deletions(-)
13
2 files changed, 47 insertions(+), 2 deletions(-)
14
22
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
20
float_status standard_fp_status;
21
float_status standard_fp_status_f16;
22
23
- /* ZCR_EL[1-3] */
24
- uint64_t zcr_el[4];
25
+ uint64_t zcr_el[4]; /* ZCR_EL[1-3] */
26
+ uint64_t smcr_el[4]; /* SMCR_EL[1-3] */
27
} vfp;
28
uint64_t exclusive_addr;
29
uint64_t exclusive_val;
30
@@ -XXX,XX +XXX,XX @@ FIELD(CPTR_EL3, TCPAC, 31, 1)
31
FIELD(SVCR, SM, 0, 1)
32
FIELD(SVCR, ZA, 1, 1)
33
34
+/* Fields for SMCR_ELx. */
35
+FIELD(SMCR, LEN, 0, 4)
36
+FIELD(SMCR, FA64, 31, 1)
37
+
38
/* Write a new value to v7m.exception, thus transitioning into or out
39
* of Handler mode; this may result in a change of active stack pointer.
40
*/
41
diff --git a/target/arm/helper.c b/target/arm/helper.c
23
diff --git a/target/arm/helper.c b/target/arm/helper.c
42
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/helper.c
25
--- a/target/arm/helper.c
44
+++ b/target/arm/helper.c
26
+++ b/target/arm/helper.c
45
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
27
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_phys_cnt_offset(CPUARMState *env)
46
*/
28
return gt_phys_raw_cnt_offset(env);
47
{ K(3, 0, 1, 2, 0), K(3, 4, 1, 2, 0), K(3, 5, 1, 2, 0),
48
"ZCR_EL1", "ZCR_EL2", "ZCR_EL12", isar_feature_aa64_sve },
49
+ { K(3, 0, 1, 2, 6), K(3, 4, 1, 2, 6), K(3, 5, 1, 2, 6),
50
+ "SMCR_EL1", "SMCR_EL2", "SMCR_EL12", isar_feature_aa64_sme },
51
52
{ K(3, 0, 5, 6, 0), K(3, 4, 5, 6, 0), K(3, 5, 5, 6, 0),
53
"TFSR_EL1", "TFSR_EL2", "TFSR_EL12", isar_feature_aa64_mte },
54
@@ -XXX,XX +XXX,XX @@ static void svcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
55
env->svcr = value;
56
}
29
}
57
30
58
+static void smcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
31
+static uint64_t gt_indirect_access_timer_offset(CPUARMState *env, int timeridx)
59
+ uint64_t value)
60
+{
32
+{
61
+ int cur_el = arm_current_el(env);
62
+ int old_len = sve_vqm1_for_el(env, cur_el);
63
+ int new_len;
64
+
65
+ QEMU_BUILD_BUG_ON(ARM_MAX_VQ > R_SMCR_LEN_MASK + 1);
66
+ value &= R_SMCR_LEN_MASK | R_SMCR_FA64_MASK;
67
+ raw_write(env, ri, value);
68
+
69
+ /*
33
+ /*
70
+ * Note that it is CONSTRAINED UNPREDICTABLE what happens to ZA storage
34
+ * Return the timer offset to use for indirect accesses to the timer.
71
+ * when SVL is widened (old values kept, or zeros). Choose to keep the
35
+ * This is the Offset value as defined in D12.2.4.1 "Operation of the
72
+ * current values for simplicity. But for QEMU internals, we must still
36
+ * CompareValue views of the timers".
73
+ * apply the narrower SVL to the Zregs and Pregs -- see the comment
37
+ *
74
+ * above aarch64_sve_narrow_vq.
38
+ * The condition here is not always the same as the condition for
39
+ * whether to apply an offset register when doing a direct read of
40
+ * the counter sysreg; those conditions are described in the
41
+ * access pseudocode for each counter register.
75
+ */
42
+ */
76
+ new_len = sve_vqm1_for_el(env, cur_el);
43
+ switch (timeridx) {
77
+ if (new_len < old_len) {
44
+ case GTIMER_PHYS:
78
+ aarch64_sve_narrow_vq(env, new_len + 1);
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();
79
+ }
54
+ }
80
+}
55
+}
81
+
56
+
82
static const ARMCPRegInfo sme_reginfo[] = {
57
static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
83
{ .name = "TPIDR2_EL0", .state = ARM_CP_STATE_AA64,
58
{
84
.opc0 = 3, .opc1 = 3, .crn = 13, .crm = 0, .opc2 = 5,
59
ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx];
85
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo sme_reginfo[] = {
60
@@ -XXX,XX +XXX,XX @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
86
.access = PL0_RW, .type = ARM_CP_SME,
61
* Timer enabled: calculate and set current ISTATUS, irq, and
87
.fieldoffset = offsetof(CPUARMState, svcr),
62
* reset timer to when ISTATUS next has to change
88
.writefn = svcr_write, .raw_writefn = raw_write },
63
*/
89
+ { .name = "SMCR_EL1", .state = ARM_CP_STATE_AA64,
64
- uint64_t offset = timeridx == GTIMER_VIRT ?
90
+ .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 6,
65
- cpu->env.cp15.cntvoff_el2 : gt_phys_raw_cnt_offset(&cpu->env);
91
+ .access = PL1_RW, .type = ARM_CP_SME,
66
+ uint64_t offset = gt_indirect_access_timer_offset(&cpu->env, timeridx);
92
+ .fieldoffset = offsetof(CPUARMState, vfp.smcr_el[1]),
67
uint64_t count = gt_get_countervalue(&cpu->env);
93
+ .writefn = smcr_write, .raw_writefn = raw_write },
68
/* Note that this must be unsigned 64 bit arithmetic: */
94
+ { .name = "SMCR_EL2", .state = ARM_CP_STATE_AA64,
69
int istatus = count - offset >= gt->cval;
95
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 6,
96
+ .access = PL2_RW, .type = ARM_CP_SME,
97
+ .fieldoffset = offsetof(CPUARMState, vfp.smcr_el[2]),
98
+ .writefn = smcr_write, .raw_writefn = raw_write },
99
+ { .name = "SMCR_EL3", .state = ARM_CP_STATE_AA64,
100
+ .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 6,
101
+ .access = PL3_RW, .type = ARM_CP_SME,
102
+ .fieldoffset = offsetof(CPUARMState, vfp.smcr_el[3]),
103
+ .writefn = smcr_write, .raw_writefn = raw_write },
104
};
105
#endif /* TARGET_AARCH64 */
106
107
--
70
--
108
2.25.1
71
2.43.0
72
73
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
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_*).
2
4
3
When Streaming SVE mode is enabled, the size is taken from
5
Cc: qemu-stable@nongnu.org
4
SMCR_ELx instead of ZCR_ELx. The format is shared, but the
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
set of vector lengths is not. Further, Streaming SVE does
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
not require any particular length to be supported.
8
Message-id: 20250204125009.2281315-3-peter.maydell@linaro.org
9
---
10
target/arm/helper.c | 2 --
11
1 file changed, 2 deletions(-)
7
12
8
Adjust sve_vqm1_for_el to pass the current value of PSTATE.SM
9
to the new function.
10
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20220620175235.60881-19-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
target/arm/cpu.h | 9 +++++++--
17
target/arm/helper.c | 32 +++++++++++++++++++++++++-------
18
2 files changed, 32 insertions(+), 9 deletions(-)
19
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
23
+++ b/target/arm/cpu.h
24
@@ -XXX,XX +XXX,XX @@ int sve_exception_el(CPUARMState *env, int cur_el);
25
int sme_exception_el(CPUARMState *env, int cur_el);
26
27
/**
28
- * sve_vqm1_for_el:
29
+ * sve_vqm1_for_el_sm:
30
* @env: CPUARMState
31
* @el: exception level
32
+ * @sm: streaming mode
33
*
34
- * Compute the current SVE vector length for @el, in units of
35
+ * Compute the current vector length for @el & @sm, in units of
36
* Quadwords Minus 1 -- the same scale used for ZCR_ELx.LEN.
37
+ * If @sm, compute for SVL, otherwise NVL.
38
*/
39
+uint32_t sve_vqm1_for_el_sm(CPUARMState *env, int el, bool sm);
40
+
41
+/* Likewise, but using @sm = PSTATE.SM. */
42
uint32_t sve_vqm1_for_el(CPUARMState *env, int el);
43
44
static inline bool is_a64(CPUARMState *env)
45
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
46
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/helper.c
15
--- a/target/arm/helper.c
48
+++ b/target/arm/helper.c
16
+++ b/target/arm/helper.c
49
@@ -XXX,XX +XXX,XX @@ int sme_exception_el(CPUARMState *env, int el)
17
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
50
/*
18
51
* Given that SVE is enabled, return the vector length for EL.
19
switch (timeridx) {
52
*/
20
case GTIMER_VIRT:
53
-uint32_t sve_vqm1_for_el(CPUARMState *env, int el)
21
- case GTIMER_HYPVIRT:
54
+uint32_t sve_vqm1_for_el_sm(CPUARMState *env, int el, bool sm)
22
offset = gt_virt_cnt_offset(env);
55
{
23
break;
56
ARMCPU *cpu = env_archcpu(env);
24
case GTIMER_PHYS:
57
- uint32_t len = cpu->sve_max_vq - 1;
25
@@ -XXX,XX +XXX,XX @@ static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
58
+ uint64_t *cr = env->vfp.zcr_el;
26
59
+ uint32_t map = cpu->sve_vq.map;
27
switch (timeridx) {
60
+ uint32_t len = ARM_MAX_VQ - 1;
28
case GTIMER_VIRT:
61
+
29
- case GTIMER_HYPVIRT:
62
+ if (sm) {
30
offset = gt_virt_cnt_offset(env);
63
+ cr = env->vfp.smcr_el;
31
break;
64
+ map = cpu->sme_vq.map;
32
case GTIMER_PHYS:
65
+ }
66
67
if (el <= 1 && !el_is_in_host(env, el)) {
68
- len = MIN(len, 0xf & (uint32_t)env->vfp.zcr_el[1]);
69
+ len = MIN(len, 0xf & (uint32_t)cr[1]);
70
}
71
if (el <= 2 && arm_feature(env, ARM_FEATURE_EL2)) {
72
- len = MIN(len, 0xf & (uint32_t)env->vfp.zcr_el[2]);
73
+ len = MIN(len, 0xf & (uint32_t)cr[2]);
74
}
75
if (arm_feature(env, ARM_FEATURE_EL3)) {
76
- len = MIN(len, 0xf & (uint32_t)env->vfp.zcr_el[3]);
77
+ len = MIN(len, 0xf & (uint32_t)cr[3]);
78
}
79
80
- len = 31 - clz32(cpu->sve_vq.map & MAKE_64BIT_MASK(0, len + 1));
81
- return len;
82
+ map &= MAKE_64BIT_MASK(0, len + 1);
83
+ if (map != 0) {
84
+ return 31 - clz32(map);
85
+ }
86
+
87
+ /* Bit 0 is always set for Normal SVE -- not so for Streaming SVE. */
88
+ assert(sm);
89
+ return ctz32(cpu->sme_vq.map);
90
+}
91
+
92
+uint32_t sve_vqm1_for_el(CPUARMState *env, int el)
93
+{
94
+ return sve_vqm1_for_el_sm(env, el, FIELD_EX64(env->svcr, SVCR, SM));
95
}
96
97
static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
98
--
33
--
99
2.25.1
34
2.43.0
35
36
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
When we added Secure EL2 support, we missed that this needs an update
2
to the access code for the EL3 physical timer registers. These are
3
supposed to UNDEF from Secure EL1 when Secure EL2 is enabled.
2
4
3
These are required to determine if various insns
5
(Note for stable backporting: for backports to branches where
4
are allowed to issue.
6
CP_ACCESS_UNDEFINED is not defined, the old name to use instead
7
is CP_ACCESS_TRAP_UNCATEGORIZED.)
5
8
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Cc: qemu-stable@nongnu.org
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220620175235.60881-9-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Message-id: 20250204125009.2281315-4-peter.maydell@linaro.org
10
---
13
---
11
target/arm/cpu.h | 2 ++
14
target/arm/helper.c | 3 +++
12
target/arm/translate.h | 4 ++++
15
1 file changed, 3 insertions(+)
13
target/arm/helper.c | 4 ++++
14
target/arm/translate-a64.c | 2 ++
15
4 files changed, 12 insertions(+)
16
16
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, TCMA, 16, 2)
22
FIELD(TBFLAG_A64, MTE_ACTIVE, 18, 1)
23
FIELD(TBFLAG_A64, MTE0_ACTIVE, 19, 1)
24
FIELD(TBFLAG_A64, SMEEXC_EL, 20, 2)
25
+FIELD(TBFLAG_A64, PSTATE_SM, 22, 1)
26
+FIELD(TBFLAG_A64, PSTATE_ZA, 23, 1)
27
28
/*
29
* Helpers for using the above.
30
diff --git a/target/arm/translate.h b/target/arm/translate.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/translate.h
33
+++ b/target/arm/translate.h
34
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
35
bool align_mem;
36
/* True if PSTATE.IL is set */
37
bool pstate_il;
38
+ /* True if PSTATE.SM is set. */
39
+ bool pstate_sm;
40
+ /* True if PSTATE.ZA is set. */
41
+ bool pstate_za;
42
/* True if MVE insns are definitely not predicated by VPR or LTPSIZE */
43
bool mve_no_pred;
44
/*
45
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
46
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/helper.c
19
--- a/target/arm/helper.c
48
+++ b/target/arm/helper.c
20
+++ b/target/arm/helper.c
49
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
21
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gt_stimer_access(CPUARMState *env,
50
}
22
if (!arm_is_secure(env)) {
51
if (cpu_isar_feature(aa64_sme, env_archcpu(env))) {
23
return CP_ACCESS_UNDEFINED;
52
DP_TBFLAG_A64(flags, SMEEXC_EL, sme_exception_el(env, el));
24
}
53
+ if (FIELD_EX64(env->svcr, SVCR, SM)) {
25
+ if (arm_is_el2_enabled(env)) {
54
+ DP_TBFLAG_A64(flags, PSTATE_SM, 1);
26
+ return CP_ACCESS_UNDEFINED;
55
+ }
27
+ }
56
+ DP_TBFLAG_A64(flags, PSTATE_ZA, FIELD_EX64(env->svcr, SVCR, ZA));
28
if (!(env->cp15.scr_el3 & SCR_ST)) {
57
}
29
return CP_ACCESS_TRAP_EL3;
58
30
}
59
sctlr = regime_sctlr(env, stage1);
60
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/translate-a64.c
63
+++ b/target/arm/translate-a64.c
64
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
65
dc->ata = EX_TBFLAG_A64(tb_flags, ATA);
66
dc->mte_active[0] = EX_TBFLAG_A64(tb_flags, MTE_ACTIVE);
67
dc->mte_active[1] = EX_TBFLAG_A64(tb_flags, MTE0_ACTIVE);
68
+ dc->pstate_sm = EX_TBFLAG_A64(tb_flags, PSTATE_SM);
69
+ dc->pstate_za = EX_TBFLAG_A64(tb_flags, PSTATE_ZA);
70
dc->vec_len = 0;
71
dc->vec_stride = 0;
72
dc->cp_regs = arm_cpu->cp_regs;
73
--
31
--
74
2.25.1
32
2.43.0
33
34
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Currently we handle CNTV_TVAL_EL02 by calling gt_tval_read() for the
2
EL1 virt timer. This is almost correct, but the underlying
3
CNTV_TVAL_EL0 register behaves slightly differently. CNTV_TVAL_EL02
4
always applies the CNTVOFF_EL2 offset; CNTV_TVAL_EL0 doesn't do so if
5
we're at EL2 and HCR_EL2.E2H is 1.
2
6
3
These two instructions are aliases of MSR (immediate).
7
We were getting this wrong, because we ended up in
4
Use the two helpers to properly implement svcr_write.
8
gt_virt_cnt_offset() and did the E2H check.
5
9
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Factor out the tval read/write calculation from the selection of the
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
offset, so that we can special case gt_virt_tval_read() and
8
Message-id: 20220620175235.60881-11-richard.henderson@linaro.org
12
gt_virt_tval_write() to unconditionally pass CNTVOFF_EL2.
13
14
Cc: qemu-stable@nongnu.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
17
Message-id: 20250204125009.2281315-5-peter.maydell@linaro.org
10
---
18
---
11
target/arm/cpu.h | 1 +
19
target/arm/helper.c | 36 +++++++++++++++++++++++++++---------
12
target/arm/helper-sme.h | 21 +++++++++++++
20
1 file changed, 27 insertions(+), 9 deletions(-)
13
target/arm/helper.h | 1 +
14
target/arm/helper.c | 6 ++--
15
target/arm/sme_helper.c | 61 ++++++++++++++++++++++++++++++++++++++
16
target/arm/translate-a64.c | 24 +++++++++++++++
17
target/arm/meson.build | 1 +
18
7 files changed, 112 insertions(+), 3 deletions(-)
19
create mode 100644 target/arm/helper-sme.h
20
create mode 100644 target/arm/sme_helper.c
21
21
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
25
+++ b/target/arm/cpu.h
26
@@ -XXX,XX +XXX,XX @@ void aarch64_sve_change_el(CPUARMState *env, int old_el,
27
int new_el, bool el0_a64);
28
void aarch64_add_sve_properties(Object *obj);
29
void aarch64_add_pauth_properties(Object *obj);
30
+void arm_reset_sve_state(CPUARMState *env);
31
32
/*
33
* SVE registers are encoded in KVM's memory in an endianness-invariant format.
34
diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
35
new file mode 100644
36
index XXXXXXX..XXXXXXX
37
--- /dev/null
38
+++ b/target/arm/helper-sme.h
39
@@ -XXX,XX +XXX,XX @@
40
+/*
41
+ * AArch64 SME specific helper definitions
42
+ *
43
+ * Copyright (c) 2022 Linaro, Ltd
44
+ *
45
+ * This library is free software; you can redistribute it and/or
46
+ * modify it under the terms of the GNU Lesser General Public
47
+ * License as published by the Free Software Foundation; either
48
+ * version 2.1 of the License, or (at your option) any later version.
49
+ *
50
+ * This library is distributed in the hope that it will be useful,
51
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
52
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
53
+ * Lesser General Public License for more details.
54
+ *
55
+ * You should have received a copy of the GNU Lesser General Public
56
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
57
+ */
58
+
59
+DEF_HELPER_FLAGS_2(set_pstate_sm, TCG_CALL_NO_RWG, void, env, i32)
60
+DEF_HELPER_FLAGS_2(set_pstate_za, TCG_CALL_NO_RWG, void, env, i32)
61
diff --git a/target/arm/helper.h b/target/arm/helper.h
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/helper.h
64
+++ b/target/arm/helper.h
65
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(gvec_bfmlal_idx, TCG_CALL_NO_RWG,
66
#ifdef TARGET_AARCH64
67
#include "helper-a64.h"
68
#include "helper-sve.h"
69
+#include "helper-sme.h"
70
#endif
71
72
#include "helper-mve.h"
73
diff --git a/target/arm/helper.c b/target/arm/helper.c
22
diff --git a/target/arm/helper.c b/target/arm/helper.c
74
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
75
--- a/target/arm/helper.c
24
--- a/target/arm/helper.c
76
+++ b/target/arm/helper.c
25
+++ b/target/arm/helper.c
77
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_esm(CPUARMState *env, const ARMCPRegInfo *ri,
26
@@ -XXX,XX +XXX,XX @@ static void gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
78
static void svcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
27
gt_recalc_timer(env_archcpu(env), timeridx);
79
uint64_t value)
80
{
81
- value &= R_SVCR_SM_MASK | R_SVCR_ZA_MASK;
82
- /* TODO: Side effects. */
83
- env->svcr = value;
84
+ helper_set_pstate_sm(env, FIELD_EX64(value, SVCR, SM));
85
+ helper_set_pstate_za(env, FIELD_EX64(value, SVCR, ZA));
86
+ arm_rebuild_hflags(env);
87
}
28
}
88
29
89
static void smcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
30
+static uint64_t do_tval_read(CPUARMState *env, int timeridx, uint64_t offset)
90
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
91
new file mode 100644
92
index XXXXXXX..XXXXXXX
93
--- /dev/null
94
+++ b/target/arm/sme_helper.c
95
@@ -XXX,XX +XXX,XX @@
96
+/*
97
+ * ARM SME Operations
98
+ *
99
+ * Copyright (c) 2022 Linaro, Ltd.
100
+ *
101
+ * This library is free software; you can redistribute it and/or
102
+ * modify it under the terms of the GNU Lesser General Public
103
+ * License as published by the Free Software Foundation; either
104
+ * version 2.1 of the License, or (at your option) any later version.
105
+ *
106
+ * This library is distributed in the hope that it will be useful,
107
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
108
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
109
+ * Lesser General Public License for more details.
110
+ *
111
+ * You should have received a copy of the GNU Lesser General Public
112
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
113
+ */
114
+
115
+#include "qemu/osdep.h"
116
+#include "cpu.h"
117
+#include "internals.h"
118
+#include "exec/helper-proto.h"
119
+
120
+/* ResetSVEState */
121
+void arm_reset_sve_state(CPUARMState *env)
122
+{
31
+{
123
+ memset(env->vfp.zregs, 0, sizeof(env->vfp.zregs));
32
+ return (uint32_t)(env->cp15.c14_timer[timeridx].cval -
124
+ /* Recall that FFR is stored as pregs[16]. */
33
+ (gt_get_countervalue(env) - offset));
125
+ memset(env->vfp.pregs, 0, sizeof(env->vfp.pregs));
126
+ vfp_set_fpcr(env, 0x0800009f);
127
+}
34
+}
128
+
35
+
129
+void helper_set_pstate_sm(CPUARMState *env, uint32_t i)
36
static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
130
+{
37
int timeridx)
131
+ if (i == FIELD_EX64(env->svcr, SVCR, SM)) {
38
{
132
+ return;
39
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
133
+ }
40
break;
134
+ env->svcr ^= R_SVCR_SM_MASK;
41
}
135
+ arm_reset_sve_state(env);
42
43
- return (uint32_t)(env->cp15.c14_timer[timeridx].cval -
44
- (gt_get_countervalue(env) - offset));
45
+ return do_tval_read(env, timeridx, offset);
136
+}
46
+}
137
+
47
+
138
+void helper_set_pstate_za(CPUARMState *env, uint32_t i)
48
+static void do_tval_write(CPUARMState *env, int timeridx, uint64_t value,
49
+ uint64_t offset)
139
+{
50
+{
140
+ if (i == FIELD_EX64(env->svcr, SVCR, ZA)) {
51
+ trace_arm_gt_tval_write(timeridx, value);
141
+ return;
52
+ env->cp15.c14_timer[timeridx].cval = gt_get_countervalue(env) - offset +
142
+ }
53
+ sextract64(value, 0, 32);
143
+ env->svcr ^= R_SVCR_ZA_MASK;
54
+ gt_recalc_timer(env_archcpu(env), timeridx);
144
+
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);
145
+ /*
76
+ /*
146
+ * ResetSMEState.
77
+ * This is CNTV_TVAL_EL02; unlike the underlying CNTV_TVAL_EL0
147
+ *
78
+ * we always apply CNTVOFF_EL2. Special case that here rather
148
+ * SetPSTATE_ZA zeros on enable and disable. We can zero this only
79
+ * than going into the generic gt_tval_read() and then having
149
+ * on enable: while disabled, the storage is inaccessible and the
80
+ * to re-detect that it's this register.
150
+ * value does not matter. We're not saving the storage in vmstate
81
+ * Note that the accessfn/perms mean we know we're at EL2 or EL3 here.
151
+ * when disabled either.
152
+ */
82
+ */
153
+ if (i) {
83
+ return do_tval_read(env, GTIMER_VIRT, env->cp15.cntvoff_el2);
154
+ memset(env->zarray, 0, sizeof(env->zarray));
84
}
155
+ }
85
156
+}
86
static void gt_virt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
157
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
87
uint64_t value)
158
index XXXXXXX..XXXXXXX 100644
88
{
159
--- a/target/arm/translate-a64.c
89
- gt_tval_write(env, ri, GTIMER_VIRT, value);
160
+++ b/target/arm/translate-a64.c
90
+ /* Similarly for writes to CNTV_TVAL_EL02 */
161
@@ -XXX,XX +XXX,XX @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
91
+ do_tval_write(env, GTIMER_VIRT, value, env->cp15.cntvoff_el2);
162
}
92
}
163
break;
93
164
94
static void gt_virt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
165
+ case 0x1b: /* SVCR* */
166
+ if (!dc_isar_feature(aa64_sme, s) || crm < 2 || crm > 7) {
167
+ goto do_unallocated;
168
+ }
169
+ if (sme_access_check(s)) {
170
+ bool i = crm & 1;
171
+ bool changed = false;
172
+
173
+ if ((crm & 2) && i != s->pstate_sm) {
174
+ gen_helper_set_pstate_sm(cpu_env, tcg_constant_i32(i));
175
+ changed = true;
176
+ }
177
+ if ((crm & 4) && i != s->pstate_za) {
178
+ gen_helper_set_pstate_za(cpu_env, tcg_constant_i32(i));
179
+ changed = true;
180
+ }
181
+ if (changed) {
182
+ gen_rebuild_hflags(s);
183
+ } else {
184
+ s->base.is_jmp = DISAS_NEXT;
185
+ }
186
+ }
187
+ break;
188
+
189
default:
190
do_unallocated:
191
unallocated_encoding(s);
192
diff --git a/target/arm/meson.build b/target/arm/meson.build
193
index XXXXXXX..XXXXXXX 100644
194
--- a/target/arm/meson.build
195
+++ b/target/arm/meson.build
196
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
197
'mte_helper.c',
198
'pauth_helper.c',
199
'sve_helper.c',
200
+ 'sme_helper.c',
201
'translate-a64.c',
202
'translate-sve.c',
203
))
204
--
95
--
205
2.25.1
96
2.43.0
97
98
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
When reading or writing the timer registers, sometimes we need to
2
2
apply one of the timer offsets. Specifically, this happens for
3
This is CheckSMEAccess, which is the basis for a set of
3
direct reads of the counter registers CNTPCT_EL0 and CNTVCT_EL0 (and
4
related tests for various SME cpregs and instructions.
4
their self-synchronized variants CNTVCTSS_EL0 and CNTPCTSS_EL0). It
5
5
also applies for direct reads and writes of the CNT*_TVAL_EL*
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
registers that provide the 32-bit downcounting view of each timer.
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
8
Message-id: 20220620175235.60881-3-richard.henderson@linaro.org
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
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
27
Message-id: 20250204125009.2281315-6-peter.maydell@linaro.org
10
---
28
---
11
target/arm/cpu.h | 2 ++
29
target/arm/internals.h | 5 +-
12
target/arm/translate.h | 1 +
30
target/arm/helper.c | 103 +++++++++++++++++++------------------
13
target/arm/helper.c | 52 ++++++++++++++++++++++++++++++++++++++
31
target/arm/tcg/op_helper.c | 8 ++-
14
target/arm/translate-a64.c | 1 +
32
3 files changed, 62 insertions(+), 54 deletions(-)
15
4 files changed, 56 insertions(+)
33
16
34
diff --git a/target/arm/internals.h b/target/arm/internals.h
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
36
--- a/target/arm/internals.h
20
+++ b/target/arm/cpu.h
37
+++ b/target/arm/internals.h
21
@@ -XXX,XX +XXX,XX @@ void aarch64_sync_64_to_32(CPUARMState *env);
38
@@ -XXX,XX +XXX,XX @@ int delete_hw_watchpoint(target_ulong addr, target_ulong len, int type);
22
39
uint64_t gt_get_countervalue(CPUARMState *env);
23
int fp_exception_el(CPUARMState *env, int cur_el);
24
int sve_exception_el(CPUARMState *env, int cur_el);
25
+int sme_exception_el(CPUARMState *env, int cur_el);
26
27
/**
28
* sve_vqm1_for_el:
29
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, ATA, 15, 1)
30
FIELD(TBFLAG_A64, TCMA, 16, 2)
31
FIELD(TBFLAG_A64, MTE_ACTIVE, 18, 1)
32
FIELD(TBFLAG_A64, MTE0_ACTIVE, 19, 1)
33
+FIELD(TBFLAG_A64, SMEEXC_EL, 20, 2)
34
35
/*
40
/*
36
* Helpers for using the above.
41
* Return the currently applicable offset between the system counter
37
diff --git a/target/arm/translate.h b/target/arm/translate.h
42
- * and CNTVCT_EL0 (this will be either 0 or the value of CNTVOFF_EL2).
38
index XXXXXXX..XXXXXXX 100644
43
+ * and the counter for the specified timer, as used for direct register
39
--- a/target/arm/translate.h
44
+ * accesses.
40
+++ b/target/arm/translate.h
45
*/
41
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
46
-uint64_t gt_virt_cnt_offset(CPUARMState *env);
42
bool ns; /* Use non-secure CPREG bank on access */
47
+uint64_t gt_direct_access_timer_offset(CPUARMState *env, int timeridx);
43
int fp_excp_el; /* FP exception EL or 0 if enabled */
48
44
int sve_excp_el; /* SVE exception EL or 0 if enabled */
49
/*
45
+ int sme_excp_el; /* SME exception EL or 0 if enabled */
50
* Return mask of ARMMMUIdxBit values corresponding to an "invalidate
46
int vl; /* current vector length in bytes */
47
bool vfp_enabled; /* FP enabled via FPSCR.EN */
48
int vec_len;
49
diff --git a/target/arm/helper.c b/target/arm/helper.c
51
diff --git a/target/arm/helper.c b/target/arm/helper.c
50
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/helper.c
53
--- a/target/arm/helper.c
52
+++ b/target/arm/helper.c
54
+++ b/target/arm/helper.c
53
@@ -XXX,XX +XXX,XX @@ int sve_exception_el(CPUARMState *env, int el)
55
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_phys_raw_cnt_offset(CPUARMState *env)
54
return 0;
56
return 0;
55
}
57
}
56
58
57
+/*
59
-static uint64_t gt_phys_cnt_offset(CPUARMState *env)
58
+ * Return the exception level to which exceptions should be taken for SME.
60
-{
59
+ * C.f. the ARM pseudocode function CheckSMEAccess.
61
- if (arm_current_el(env) >= 2) {
60
+ */
62
- return 0;
61
+int sme_exception_el(CPUARMState *env, int el)
63
- }
64
- return gt_phys_raw_cnt_offset(env);
65
-}
66
-
67
static uint64_t gt_indirect_access_timer_offset(CPUARMState *env, int timeridx)
68
{
69
/*
70
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_indirect_access_timer_offset(CPUARMState *env, int timeridx)
71
}
72
}
73
74
+uint64_t gt_direct_access_timer_offset(CPUARMState *env, int timeridx)
62
+{
75
+{
63
+#ifndef CONFIG_USER_ONLY
76
+ /*
64
+ if (el <= 1 && !el_is_in_host(env, el)) {
77
+ * Return the timer offset to use for direct accesses to the
65
+ switch (FIELD_EX64(env->cp15.cpacr_el1, CPACR_EL1, SMEN)) {
78
+ * counter registers CNTPCT and CNTVCT, and for direct accesses
66
+ case 1:
79
+ * to the CNT*_TVAL registers.
67
+ if (el != 0) {
80
+ *
68
+ break;
81
+ * This isn't exactly the same as the indirect-access offset,
82
+ * because here we also care about what EL the register access
83
+ * is being made from.
84
+ *
85
+ * This corresponds to the access pseudocode for the registers.
86
+ */
87
+ uint64_t hcr;
88
+
89
+ switch (timeridx) {
90
+ case GTIMER_PHYS:
91
+ if (arm_current_el(env) >= 2) {
92
+ return 0;
93
+ }
94
+ return gt_phys_raw_cnt_offset(env);
95
+ case GTIMER_VIRT:
96
+ switch (arm_current_el(env)) {
97
+ case 2:
98
+ hcr = arm_hcr_el2_eff(env);
99
+ if (hcr & HCR_E2H) {
100
+ return 0;
69
+ }
101
+ }
70
+ /* fall through */
102
+ break;
71
+ case 0:
103
+ case 0:
72
+ case 2:
104
+ hcr = arm_hcr_el2_eff(env);
73
+ return 1;
105
+ if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
106
+ return 0;
107
+ }
108
+ break;
74
+ }
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();
75
+ }
117
+ }
76
+
77
+ if (el <= 2 && arm_is_el2_enabled(env)) {
78
+ /* CPTR_EL2 changes format with HCR_EL2.E2H (regardless of TGE). */
79
+ if (env->cp15.hcr_el2 & HCR_E2H) {
80
+ switch (FIELD_EX64(env->cp15.cptr_el[2], CPTR_EL2, SMEN)) {
81
+ case 1:
82
+ if (el != 0 || !(env->cp15.hcr_el2 & HCR_TGE)) {
83
+ break;
84
+ }
85
+ /* fall through */
86
+ case 0:
87
+ case 2:
88
+ return 2;
89
+ }
90
+ } else {
91
+ if (FIELD_EX64(env->cp15.cptr_el[2], CPTR_EL2, TSM)) {
92
+ return 2;
93
+ }
94
+ }
95
+ }
96
+
97
+ /* CPTR_EL3. Since ESM is negative we must check for EL3. */
98
+ if (arm_feature(env, ARM_FEATURE_EL3)
99
+ && !FIELD_EX64(env->cp15.cptr_el[3], CPTR_EL3, ESM)) {
100
+ return 3;
101
+ }
102
+#endif
103
+ return 0;
104
+}
118
+}
105
+
119
+
106
/*
120
static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
107
* Given that SVE is enabled, return the vector length for EL.
121
{
108
*/
122
ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx];
109
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
123
@@ -XXX,XX +XXX,XX @@ static void gt_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri,
110
}
124
111
DP_TBFLAG_A64(flags, SVEEXC_EL, sve_el);
125
static uint64_t gt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
112
}
126
{
113
+ if (cpu_isar_feature(aa64_sme, env_archcpu(env))) {
127
- return gt_get_countervalue(env) - gt_phys_cnt_offset(env);
114
+ DP_TBFLAG_A64(flags, SMEEXC_EL, sme_exception_el(env, el));
128
-}
115
+ }
129
-
116
130
-uint64_t gt_virt_cnt_offset(CPUARMState *env)
117
sctlr = regime_sctlr(env, stage1);
131
-{
118
132
- uint64_t hcr;
119
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
133
-
134
- switch (arm_current_el(env)) {
135
- case 2:
136
- hcr = arm_hcr_el2_eff(env);
137
- if (hcr & HCR_E2H) {
138
- return 0;
139
- }
140
- break;
141
- case 0:
142
- hcr = arm_hcr_el2_eff(env);
143
- if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
144
- return 0;
145
- }
146
- break;
147
- }
148
-
149
- return env->cp15.cntvoff_el2;
150
+ uint64_t offset = gt_direct_access_timer_offset(env, GTIMER_PHYS);
151
+ return gt_get_countervalue(env) - offset;
152
}
153
154
static uint64_t gt_virt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
155
{
156
- return gt_get_countervalue(env) - gt_virt_cnt_offset(env);
157
+ uint64_t offset = gt_direct_access_timer_offset(env, GTIMER_VIRT);
158
+ return gt_get_countervalue(env) - offset;
159
}
160
161
static void gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
162
@@ -XXX,XX +XXX,XX @@ static uint64_t do_tval_read(CPUARMState *env, int timeridx, uint64_t offset)
163
static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
164
int timeridx)
165
{
166
- uint64_t offset = 0;
167
-
168
- switch (timeridx) {
169
- case GTIMER_VIRT:
170
- offset = gt_virt_cnt_offset(env);
171
- break;
172
- case GTIMER_PHYS:
173
- offset = gt_phys_cnt_offset(env);
174
- break;
175
- }
176
+ uint64_t offset = gt_direct_access_timer_offset(env, timeridx);
177
178
return do_tval_read(env, timeridx, offset);
179
}
180
@@ -XXX,XX +XXX,XX @@ static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
181
int timeridx,
182
uint64_t value)
183
{
184
- uint64_t offset = 0;
185
+ uint64_t offset = gt_direct_access_timer_offset(env, timeridx);
186
187
- switch (timeridx) {
188
- case GTIMER_VIRT:
189
- offset = gt_virt_cnt_offset(env);
190
- break;
191
- case GTIMER_PHYS:
192
- offset = gt_phys_cnt_offset(env);
193
- break;
194
- }
195
do_tval_write(env, timeridx, value, offset);
196
}
197
198
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
120
index XXXXXXX..XXXXXXX 100644
199
index XXXXXXX..XXXXXXX 100644
121
--- a/target/arm/translate-a64.c
200
--- a/target/arm/tcg/op_helper.c
122
+++ b/target/arm/translate-a64.c
201
+++ b/target/arm/tcg/op_helper.c
123
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
202
@@ -XXX,XX +XXX,XX @@ void HELPER(wfit)(CPUARMState *env, uint64_t timeout)
124
dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
203
int target_el = check_wfx_trap(env, false, &excp);
125
dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
204
/* The WFIT should time out when CNTVCT_EL0 >= the specified value. */
126
dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
205
uint64_t cntval = gt_get_countervalue(env);
127
+ dc->sme_excp_el = EX_TBFLAG_A64(tb_flags, SMEEXC_EL);
206
- uint64_t offset = gt_virt_cnt_offset(env);
128
dc->vl = (EX_TBFLAG_A64(tb_flags, VL) + 1) * 16;
207
+ /*
129
dc->pauth_active = EX_TBFLAG_A64(tb_flags, PAUTH_ACTIVE);
208
+ * We want the value that we would get if we read CNTVCT_EL0 from
130
dc->bt = EX_TBFLAG_A64(tb_flags, BT);
209
+ * the current exception level, so the direct_access offset, not
210
+ * the indirect_access one. Compare the pseudocode LocalTimeoutEvent(),
211
+ * which calls VirtualCounterTimer().
212
+ */
213
+ uint64_t offset = gt_direct_access_timer_offset(env, GTIMER_VIRT);
214
uint64_t cntvct = cntval - offset;
215
uint64_t nexttick;
216
131
--
217
--
132
2.25.1
218
2.43.0
219
220
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
Mirror the properties for SVE. The main difference is
3
When FEAT_SEL2 was implemented the SEL2 timers were missed. This
4
that any arbitrary set of powers of 2 may be supported,
4
shows up when building the latest Hafnium with SPMC_AT_EL=2. The
5
and not the stricter constraints that apply to SVE.
5
actual implementation utilises the same logic as the rest of the
6
6
timers so all we need to do is:
7
Include a property to control FEAT_SME_FA64, as failing
7
8
to restrict the runtime to the proper subset of insns
8
- define the timers and their access functions
9
could be a major point for bugs.
9
- conditionally add the correct system registers
10
10
- create a new accessfn as the rules are subtly different to the
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
existing secure timer
12
13
Fixes: e9152ee91c (target/arm: add ARMv8.4-SEL2 system registers)
14
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20220620175235.60881-18-richard.henderson@linaro.org
17
Message-id: 20250204125009.2281315-7-peter.maydell@linaro.org
18
Cc: qemu-stable@nongnu.org
19
Cc: Andrei Homescu <ahomescu@google.com>
20
Cc: Arve Hjønnevåg <arve@google.com>
21
Cc: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
22
[PMM: CP_ACCESS_TRAP_UNCATEGORIZED -> CP_ACCESS_UNDEFINED;
23
offset logic now in gt_{indirect,direct}_access_timer_offset() ]
24
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
26
---
16
docs/system/arm/cpu-features.rst | 56 +++++++++++++++
27
include/hw/arm/bsa.h | 2 +
17
target/arm/cpu.h | 2 +
28
target/arm/cpu.h | 2 +
18
target/arm/internals.h | 1 +
29
target/arm/gtimer.h | 4 +-
19
target/arm/cpu.c | 14 +++-
30
target/arm/cpu.c | 4 ++
20
target/arm/cpu64.c | 114 +++++++++++++++++++++++++++++--
31
target/arm/helper.c | 163 +++++++++++++++++++++++++++++++++++++++++++
21
5 files changed, 180 insertions(+), 7 deletions(-)
32
5 files changed, 174 insertions(+), 1 deletion(-)
22
33
23
diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
34
diff --git a/include/hw/arm/bsa.h b/include/hw/arm/bsa.h
24
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
25
--- a/docs/system/arm/cpu-features.rst
36
--- a/include/hw/arm/bsa.h
26
+++ b/docs/system/arm/cpu-features.rst
37
+++ b/include/hw/arm/bsa.h
27
@@ -XXX,XX +XXX,XX @@ verbose command lines. However, the recommended way to select vector
38
@@ -XXX,XX +XXX,XX @@
28
lengths is to explicitly enable each desired length. Therefore only
39
#define QEMU_ARM_BSA_H
29
example's (1), (4), and (6) exhibit recommended uses of the properties.
40
30
41
/* These are architectural INTID values */
31
+SME CPU Property Examples
42
+#define ARCH_TIMER_S_EL2_VIRT_IRQ 19
32
+-------------------------
43
+#define ARCH_TIMER_S_EL2_IRQ 20
33
+
44
#define VIRTUAL_PMU_IRQ 23
34
+ 1) Disable SME::
45
#define ARCH_GIC_MAINT_IRQ 25
35
+
46
#define ARCH_TIMER_NS_EL2_IRQ 26
36
+ $ qemu-system-aarch64 -M virt -cpu max,sme=off
37
+
38
+ 2) Implicitly enable all vector lengths for the ``max`` CPU type::
39
+
40
+ $ qemu-system-aarch64 -M virt -cpu max
41
+
42
+ 3) Only enable the 256-bit vector length::
43
+
44
+ $ qemu-system-aarch64 -M virt -cpu max,sme256=on
45
+
46
+ 3) Enable the 256-bit and 1024-bit vector lengths::
47
+
48
+ $ qemu-system-aarch64 -M virt -cpu max,sme256=on,sme1024=on
49
+
50
+ 4) Disable the 512-bit vector length. This results in all the other
51
+ lengths supported by ``max`` defaulting to enabled
52
+ (128, 256, 1024 and 2048)::
53
+
54
+ $ qemu-system-aarch64 -M virt -cpu max,sve512=off
55
+
56
SVE User-mode Default Vector Length Property
57
--------------------------------------------
58
59
@@ -XXX,XX +XXX,XX @@ length supported by QEMU is 256.
60
61
If this property is set to ``-1`` then the default vector length
62
is set to the maximum possible length.
63
+
64
+SME CPU Properties
65
+==================
66
+
67
+The SME CPU properties are much like the SVE properties: ``sme`` is
68
+used to enable or disable the entire SME feature, and ``sme<N>`` is
69
+used to enable or disable specific vector lengths. Finally,
70
+``sme_fa64`` is used to enable or disable ``FEAT_SME_FA64``, which
71
+allows execution of the "full a64" instruction set while Streaming
72
+SVE mode is enabled.
73
+
74
+SME is not supported by KVM at this time.
75
+
76
+At least one vector length must be enabled when ``sme`` is enabled,
77
+and all vector lengths must be powers of 2. The maximum vector
78
+length supported by qemu is 2048 bits. Otherwise, there are no
79
+additional constraints on the set of vector lengths supported by SME.
80
+
81
+SME User-mode Default Vector Length Property
82
+--------------------------------------------
83
+
84
+For qemu-aarch64, the cpu propery ``sme-default-vector-length=N`` is
85
+defined to mirror the Linux kernel parameter file
86
+``/proc/sys/abi/sme_default_vector_length``. The default length, ``N``,
87
+is in units of bytes and must be between 16 and 8192.
88
+If not specified, the default vector length is 32.
89
+
90
+As with ``sve-default-vector-length``, if the default length is larger
91
+than the maximum vector length enabled, the actual vector length will
92
+be reduced. If this property is set to ``-1`` then the default vector
93
+length is set to the maximum possible length.
94
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
47
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
95
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
96
--- a/target/arm/cpu.h
49
--- a/target/arm/cpu.h
97
+++ b/target/arm/cpu.h
50
+++ b/target/arm/cpu.h
98
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
51
@@ -XXX,XX +XXX,XX @@ void arm_gt_vtimer_cb(void *opaque);
99
#ifdef CONFIG_USER_ONLY
52
void arm_gt_htimer_cb(void *opaque);
100
/* Used to set the default vector length at process start. */
53
void arm_gt_stimer_cb(void *opaque);
101
uint32_t sve_default_vq;
54
void arm_gt_hvtimer_cb(void *opaque);
102
+ uint32_t sme_default_vq;
55
+void arm_gt_sel2timer_cb(void *opaque);
103
#endif
56
+void arm_gt_sel2vtimer_cb(void *opaque);
104
57
105
ARMVQMap sve_vq;
58
unsigned int gt_cntfrq_period_ns(ARMCPU *cpu);
106
+ ARMVQMap sme_vq;
59
void gt_rme_post_el_change(ARMCPU *cpu, void *opaque);
107
60
diff --git a/target/arm/gtimer.h b/target/arm/gtimer.h
108
/* Generic timer counter frequency, in Hz */
61
index XXXXXXX..XXXXXXX 100644
109
uint64_t gt_cntfrq_hz;
62
--- a/target/arm/gtimer.h
110
diff --git a/target/arm/internals.h b/target/arm/internals.h
63
+++ b/target/arm/gtimer.h
111
index XXXXXXX..XXXXXXX 100644
64
@@ -XXX,XX +XXX,XX @@ enum {
112
--- a/target/arm/internals.h
65
GTIMER_HYP = 2,
113
+++ b/target/arm/internals.h
66
GTIMER_SEC = 3,
114
@@ -XXX,XX +XXX,XX @@ int arm_gdb_set_svereg(CPUARMState *env, uint8_t *buf, int reg);
67
GTIMER_HYPVIRT = 4,
115
int aarch64_fpu_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg);
68
-#define NUM_GTIMERS 5
116
int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg);
69
+ GTIMER_S_EL2_PHYS = 5, /* CNTHPS_* ; only if FEAT_SEL2 */
117
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp);
70
+ GTIMER_S_EL2_VIRT = 6, /* CNTHVS_* ; only if FEAT_SEL2 */
118
+void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp);
71
+#define NUM_GTIMERS 7
119
void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp);
72
};
120
void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp);
73
121
#endif
74
#endif
122
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
75
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
123
index XXXXXXX..XXXXXXX 100644
76
index XXXXXXX..XXXXXXX 100644
124
--- a/target/arm/cpu.c
77
--- a/target/arm/cpu.c
125
+++ b/target/arm/cpu.c
78
+++ b/target/arm/cpu.c
126
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_initfn(Object *obj)
79
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
127
#ifdef CONFIG_USER_ONLY
80
arm_gt_stimer_cb, cpu);
128
# ifdef TARGET_AARCH64
81
cpu->gt_timer[GTIMER_HYPVIRT] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
129
/*
82
arm_gt_hvtimer_cb, cpu);
130
- * The linux kernel defaults to 512-bit vectors, when sve is supported.
83
+ cpu->gt_timer[GTIMER_S_EL2_PHYS] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
131
- * See documentation for /proc/sys/abi/sve_default_vector_length, and
84
+ arm_gt_sel2timer_cb, cpu);
132
- * our corresponding sve-default-vector-length cpu property.
85
+ cpu->gt_timer[GTIMER_S_EL2_VIRT] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
133
+ * The linux kernel defaults to 512-bit for SVE, and 256-bit for SME.
86
+ arm_gt_sel2vtimer_cb, cpu);
134
+ * These values were chosen to fit within the default signal frame.
87
}
135
+ * See documentation for /proc/sys/abi/{sve,sme}_default_vector_length,
88
#endif
136
+ * and our corresponding cpu property.
89
137
*/
90
diff --git a/target/arm/helper.c b/target/arm/helper.c
138
cpu->sve_default_vq = 4;
91
index XXXXXXX..XXXXXXX 100644
139
+ cpu->sme_default_vq = 2;
92
--- a/target/arm/helper.c
140
# endif
93
+++ b/target/arm/helper.c
141
#else
94
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gt_stimer_access(CPUARMState *env,
142
/* Our inbound IRQ and FIQ lines */
95
}
143
@@ -XXX,XX +XXX,XX @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
96
}
144
return;
97
145
}
98
+static CPAccessResult gt_sel2timer_access(CPUARMState *env,
146
99
+ const ARMCPRegInfo *ri,
147
+ arm_cpu_sme_finalize(cpu, &local_err);
100
+ bool isread)
148
+ if (local_err != NULL) {
101
+{
149
+ error_propagate(errp, local_err);
102
+ /*
150
+ return;
103
+ * The AArch64 register view of the secure EL2 timers are mostly
104
+ * accessible from EL3 and EL2 although can also be trapped to EL2
105
+ * from EL1 depending on nested virt config.
106
+ */
107
+ switch (arm_current_el(env)) {
108
+ case 0: /* UNDEFINED */
109
+ return CP_ACCESS_UNDEFINED;
110
+ case 1:
111
+ if (!arm_is_secure(env)) {
112
+ /* UNDEFINED */
113
+ return CP_ACCESS_UNDEFINED;
114
+ } else if (arm_hcr_el2_eff(env) & HCR_NV) {
115
+ /* Aarch64.SystemAccessTrap(EL2, 0x18) */
116
+ return CP_ACCESS_TRAP_EL2;
151
+ }
117
+ }
152
+
118
+ /* UNDEFINED */
153
arm_cpu_pauth_finalize(cpu, &local_err);
119
+ return CP_ACCESS_UNDEFINED;
154
if (local_err != NULL) {
120
+ case 2:
155
error_propagate(errp, local_err);
121
+ if (!arm_is_secure(env)) {
156
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
122
+ /* UNDEFINED */
157
index XXXXXXX..XXXXXXX 100644
123
+ return CP_ACCESS_UNDEFINED;
158
--- a/target/arm/cpu64.c
124
+ }
159
+++ b/target/arm/cpu64.c
125
+ return CP_ACCESS_OK;
160
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_get_vq(Object *obj, Visitor *v, const char *name,
126
+ case 3:
161
ARMCPU *cpu = ARM_CPU(obj);
127
+ if (env->cp15.scr_el3 & SCR_EEL2) {
162
ARMVQMap *vq_map = opaque;
128
+ return CP_ACCESS_OK;
163
uint32_t vq = atoi(&name[3]) / 128;
129
+ } else {
164
+ bool sve = vq_map == &cpu->sve_vq;
130
+ return CP_ACCESS_UNDEFINED;
165
bool value;
131
+ }
166
132
+ default:
167
- /* All vector lengths are disabled when SVE is off. */
133
+ g_assert_not_reached();
168
- if (!cpu_isar_feature(aa64_sve, cpu)) {
134
+ }
169
+ /* All vector lengths are disabled when feature is off. */
135
+}
170
+ if (sve
136
+
171
+ ? !cpu_isar_feature(aa64_sve, cpu)
137
uint64_t gt_get_countervalue(CPUARMState *env)
172
+ : !cpu_isar_feature(aa64_sme, cpu)) {
138
{
173
value = false;
139
ARMCPU *cpu = env_archcpu(env);
174
} else {
140
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_indirect_access_timer_offset(CPUARMState *env, int timeridx)
175
value = extract32(vq_map->map, vq - 1, 1);
141
case GTIMER_HYP:
176
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve(Object *obj, bool value, Error **errp)
142
case GTIMER_SEC:
177
cpu->isar.id_aa64pfr0 = t;
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);
178
}
160
}
179
161
180
+void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp)
162
+static void gt_sec_pel2_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri)
181
+{
163
+{
182
+ uint32_t vq_map = cpu->sme_vq.map;
164
+ gt_timer_reset(env, ri, GTIMER_S_EL2_PHYS);
183
+ uint32_t vq_init = cpu->sme_vq.init;
165
+}
184
+ uint32_t vq_supported = cpu->sme_vq.supported;
166
+
185
+ uint32_t vq;
167
+static void gt_sec_pel2_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
186
+
168
+ uint64_t value)
187
+ if (vq_map == 0) {
169
+{
188
+ if (!cpu_isar_feature(aa64_sme, cpu)) {
170
+ gt_cval_write(env, ri, GTIMER_S_EL2_PHYS, value);
189
+ cpu->isar.id_aa64smfr0 = 0;
171
+}
190
+ return;
172
+
191
+ }
173
+static uint64_t gt_sec_pel2_tval_read(CPUARMState *env, const ARMCPRegInfo *ri)
192
+
174
+{
193
+ /* TODO: KVM will require limitations via SMCR_EL2. */
175
+ return gt_tval_read(env, ri, GTIMER_S_EL2_PHYS);
194
+ vq_map = vq_supported & ~vq_init;
176
+}
195
+
177
+
196
+ if (vq_map == 0) {
178
+static void gt_sec_pel2_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
197
+ vq = ctz32(vq_supported) + 1;
179
+ uint64_t value)
198
+ error_setg(errp, "cannot disable sme%d", vq * 128);
180
+{
199
+ error_append_hint(errp, "All SME vector lengths are disabled.\n");
181
+ gt_tval_write(env, ri, GTIMER_S_EL2_PHYS, value);
200
+ error_append_hint(errp, "With SME enabled, at least one "
182
+}
201
+ "vector length must be enabled.\n");
183
+
202
+ return;
184
+static void gt_sec_pel2_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
203
+ }
185
+ uint64_t value)
204
+ } else {
186
+{
205
+ if (!cpu_isar_feature(aa64_sme, cpu)) {
187
+ gt_ctl_write(env, ri, GTIMER_S_EL2_PHYS, value);
206
+ vq = 32 - clz32(vq_map);
188
+}
207
+ error_setg(errp, "cannot enable sme%d", vq * 128);
189
+
208
+ error_append_hint(errp, "SME must be enabled to enable "
190
+static void gt_sec_vel2_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri)
209
+ "vector lengths.\n");
191
+{
210
+ error_append_hint(errp, "Add sme=on to the CPU property list.\n");
192
+ gt_timer_reset(env, ri, GTIMER_S_EL2_VIRT);
211
+ return;
193
+}
212
+ }
194
+
213
+ /* TODO: KVM will require limitations via SMCR_EL2. */
195
+static void gt_sec_vel2_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
214
+ }
196
+ uint64_t value)
215
+
197
+{
216
+ cpu->sme_vq.map = vq_map;
198
+ gt_cval_write(env, ri, GTIMER_S_EL2_VIRT, value);
217
+}
199
+}
218
+
200
+
219
+static bool cpu_arm_get_sme(Object *obj, Error **errp)
201
+static uint64_t gt_sec_vel2_tval_read(CPUARMState *env, const ARMCPRegInfo *ri)
220
+{
202
+{
221
+ ARMCPU *cpu = ARM_CPU(obj);
203
+ return gt_tval_read(env, ri, GTIMER_S_EL2_VIRT);
222
+ return cpu_isar_feature(aa64_sme, cpu);
204
+}
223
+}
205
+
224
+
206
+static void gt_sec_vel2_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
225
+static void cpu_arm_set_sme(Object *obj, bool value, Error **errp)
207
+ uint64_t value)
226
+{
208
+{
227
+ ARMCPU *cpu = ARM_CPU(obj);
209
+ gt_tval_write(env, ri, GTIMER_S_EL2_VIRT, value);
228
+ uint64_t t;
210
+}
229
+
211
+
230
+ t = cpu->isar.id_aa64pfr1;
212
+static void gt_sec_vel2_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
231
+ t = FIELD_DP64(t, ID_AA64PFR1, SME, value);
213
+ uint64_t value)
232
+ cpu->isar.id_aa64pfr1 = t;
214
+{
233
+}
215
+ gt_ctl_write(env, ri, GTIMER_S_EL2_VIRT, value);
234
+
216
+}
235
+static bool cpu_arm_get_sme_fa64(Object *obj, Error **errp)
217
+
236
+{
218
static void gt_hv_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri)
237
+ ARMCPU *cpu = ARM_CPU(obj);
219
{
238
+ return cpu_isar_feature(aa64_sme, cpu) &&
220
gt_timer_reset(env, ri, GTIMER_HYPVIRT);
239
+ cpu_isar_feature(aa64_sme_fa64, cpu);
221
@@ -XXX,XX +XXX,XX @@ void arm_gt_stimer_cb(void *opaque)
240
+}
222
gt_recalc_timer(cpu, GTIMER_SEC);
241
+
242
+static void cpu_arm_set_sme_fa64(Object *obj, bool value, Error **errp)
243
+{
244
+ ARMCPU *cpu = ARM_CPU(obj);
245
+ uint64_t t;
246
+
247
+ t = cpu->isar.id_aa64smfr0;
248
+ t = FIELD_DP64(t, ID_AA64SMFR0, FA64, value);
249
+ cpu->isar.id_aa64smfr0 = t;
250
+}
251
+
252
#ifdef CONFIG_USER_ONLY
253
-/* Mirror linux /proc/sys/abi/sve_default_vector_length. */
254
+/* Mirror linux /proc/sys/abi/{sve,sme}_default_vector_length. */
255
static void cpu_arm_set_default_vec_len(Object *obj, Visitor *v,
256
const char *name, void *opaque,
257
Error **errp)
258
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_default_vec_len(Object *obj, Visitor *v,
259
* and is the maximum architectural width of ZCR_ELx.LEN.
260
*/
261
if (remainder || default_vq < 1 || default_vq > 512) {
262
- error_setg(errp, "cannot set sve-default-vector-length");
263
+ ARMCPU *cpu = ARM_CPU(obj);
264
+ const char *which =
265
+ (ptr_default_vq == &cpu->sve_default_vq ? "sve" : "sme");
266
+
267
+ error_setg(errp, "cannot set %s-default-vector-length", which);
268
if (remainder) {
269
error_append_hint(errp, "Vector length not a multiple of 16\n");
270
} else if (default_vq < 1) {
271
@@ -XXX,XX +XXX,XX @@ static void aarch64_add_sve_properties(Object *obj)
272
#endif
273
}
223
}
274
224
275
+static void aarch64_add_sme_properties(Object *obj)
225
+void arm_gt_sel2timer_cb(void *opaque)
276
+{
226
+{
277
+ ARMCPU *cpu = ARM_CPU(obj);
227
+ ARMCPU *cpu = opaque;
278
+ uint32_t vq;
228
+
279
+
229
+ gt_recalc_timer(cpu, GTIMER_S_EL2_PHYS);
280
+ object_property_add_bool(obj, "sme", cpu_arm_get_sme, cpu_arm_set_sme);
230
+}
281
+ object_property_add_bool(obj, "sme_fa64", cpu_arm_get_sme_fa64,
231
+
282
+ cpu_arm_set_sme_fa64);
232
+void arm_gt_sel2vtimer_cb(void *opaque)
283
+
233
+{
284
+ for (vq = 1; vq <= ARM_MAX_VQ; vq <<= 1) {
234
+ ARMCPU *cpu = opaque;
285
+ char name[8];
235
+
286
+ sprintf(name, "sme%d", vq * 128);
236
+ gt_recalc_timer(cpu, GTIMER_S_EL2_VIRT);
287
+ object_property_add(obj, name, "bool", cpu_arm_get_vq,
237
+}
288
+ cpu_arm_set_vq, NULL, &cpu->sme_vq);
238
+
289
+ }
239
void arm_gt_hvtimer_cb(void *opaque)
290
+
240
{
291
+#ifdef CONFIG_USER_ONLY
241
ARMCPU *cpu = opaque;
292
+ /* Mirror linux /proc/sys/abi/sme_default_vector_length. */
242
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_sec_cp_reginfo[] = {
293
+ object_property_add(obj, "sme-default-vector-length", "int32",
243
.access = PL2_RW, .accessfn = sel2_access,
294
+ cpu_arm_get_default_vec_len,
244
.nv2_redirect_offset = 0x48,
295
+ cpu_arm_set_default_vec_len, NULL,
245
.fieldoffset = offsetof(CPUARMState, cp15.vstcr_el2) },
296
+ &cpu->sme_default_vq);
246
+#ifndef CONFIG_USER_ONLY
247
+ /* Secure EL2 Physical Timer */
248
+ { .name = "CNTHPS_TVAL_EL2", .state = ARM_CP_STATE_AA64,
249
+ .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 5, .opc2 = 0,
250
+ .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL2_RW,
251
+ .accessfn = gt_sel2timer_access,
252
+ .readfn = gt_sec_pel2_tval_read,
253
+ .writefn = gt_sec_pel2_tval_write,
254
+ .resetfn = gt_sec_pel2_timer_reset,
255
+ },
256
+ { .name = "CNTHPS_CTL_EL2", .state = ARM_CP_STATE_AA64,
257
+ .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 5, .opc2 = 1,
258
+ .type = ARM_CP_IO, .access = PL2_RW,
259
+ .accessfn = gt_sel2timer_access,
260
+ .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_S_EL2_PHYS].ctl),
261
+ .resetvalue = 0,
262
+ .writefn = gt_sec_pel2_ctl_write, .raw_writefn = raw_write,
263
+ },
264
+ { .name = "CNTHPS_CVAL_EL2", .state = ARM_CP_STATE_AA64,
265
+ .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 5, .opc2 = 2,
266
+ .type = ARM_CP_IO, .access = PL2_RW,
267
+ .accessfn = gt_sel2timer_access,
268
+ .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_S_EL2_PHYS].cval),
269
+ .writefn = gt_sec_pel2_cval_write, .raw_writefn = raw_write,
270
+ },
271
+ /* Secure EL2 Virtual Timer */
272
+ { .name = "CNTHVS_TVAL_EL2", .state = ARM_CP_STATE_AA64,
273
+ .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 4, .opc2 = 0,
274
+ .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL2_RW,
275
+ .accessfn = gt_sel2timer_access,
276
+ .readfn = gt_sec_vel2_tval_read,
277
+ .writefn = gt_sec_vel2_tval_write,
278
+ .resetfn = gt_sec_vel2_timer_reset,
279
+ },
280
+ { .name = "CNTHVS_CTL_EL2", .state = ARM_CP_STATE_AA64,
281
+ .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 4, .opc2 = 1,
282
+ .type = ARM_CP_IO, .access = PL2_RW,
283
+ .accessfn = gt_sel2timer_access,
284
+ .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_S_EL2_VIRT].ctl),
285
+ .resetvalue = 0,
286
+ .writefn = gt_sec_vel2_ctl_write, .raw_writefn = raw_write,
287
+ },
288
+ { .name = "CNTHVS_CVAL_EL2", .state = ARM_CP_STATE_AA64,
289
+ .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 4, .opc2 = 2,
290
+ .type = ARM_CP_IO, .access = PL2_RW,
291
+ .accessfn = gt_sel2timer_access,
292
+ .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_S_EL2_VIRT].cval),
293
+ .writefn = gt_sec_vel2_cval_write, .raw_writefn = raw_write,
294
+ },
297
+#endif
295
+#endif
298
+}
296
};
299
+
297
300
void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
298
static CPAccessResult nsacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
301
{
302
int arch_val = 0, impdef_val = 0;
303
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
304
#endif
305
306
cpu->sve_vq.supported = MAKE_64BIT_MASK(0, ARM_MAX_VQ);
307
+ cpu->sme_vq.supported = SVE_VQ_POW2_MAP;
308
309
aarch64_add_pauth_properties(obj);
310
aarch64_add_sve_properties(obj);
311
+ aarch64_add_sme_properties(obj);
312
object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
313
cpu_max_set_sve_max_vq, NULL, NULL);
314
qdev_property_add_static(DEVICE(obj), &arm_cpu_lpa2_property);
315
--
299
--
316
2.25.1
300
2.43.0
301
302
diff view generated by jsdifflib
1
From: Martin Liška <mliska@suse.cz>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
Fixes the following Sphinx warning (treated as error) starting
3
As we are about to add more physical and virtual timers let's make it
4
with 5.0 release:
4
clear what each timer does.
5
5
6
Warning, treated as error:
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Invalid configuration value found: 'language = None'. Update your configuration to a valid langauge code. Falling back to 'en' (English).
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Martin Liska <mliska@suse.cz>
9
Message-id: 20250204125009.2281315-8-peter.maydell@linaro.org
10
Message-id: e91e51ee-48ac-437e-6467-98b56ee40042@suse.cz
10
[PMM: Add timer register name prefix to each comment]
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
13
---
14
docs/conf.py | 2 +-
14
target/arm/gtimer.h | 10 +++++-----
15
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 5 insertions(+), 5 deletions(-)
16
16
17
diff --git a/docs/conf.py b/docs/conf.py
17
diff --git a/target/arm/gtimer.h b/target/arm/gtimer.h
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/docs/conf.py
19
--- a/target/arm/gtimer.h
20
+++ b/docs/conf.py
20
+++ b/target/arm/gtimer.h
21
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
22
#
22
#define TARGET_ARM_GTIMER_H
23
# This is also used if you do content translation via gettext catalogs.
23
24
# Usually you set "language" from the command line for these cases.
24
enum {
25
-language = None
25
- GTIMER_PHYS = 0,
26
+language = 'en'
26
- GTIMER_VIRT = 1,
27
27
- GTIMER_HYP = 2,
28
# List of patterns, relative to source directory, that match files and
28
- GTIMER_SEC = 3,
29
# directories to ignore when looking for source files.
29
- GTIMER_HYPVIRT = 4,
30
+ GTIMER_PHYS = 0, /* CNTP_* ; EL1 physical timer */
31
+ GTIMER_VIRT = 1, /* CNTV_* ; EL1 virtual timer */
32
+ GTIMER_HYP = 2, /* CNTHP_* ; EL2 physical timer */
33
+ GTIMER_SEC = 3, /* CNTPS_* ; EL3 physical timer */
34
+ GTIMER_HYPVIRT = 4, /* CNTHV_* ; EL2 virtual timer ; only if FEAT_VHE */
35
GTIMER_S_EL2_PHYS = 5, /* CNTHPS_* ; only if FEAT_SEL2 */
36
GTIMER_S_EL2_VIRT = 6, /* CNTHVS_* ; only if FEAT_SEL2 */
37
#define NUM_GTIMERS 7
30
--
38
--
31
2.25.1
39
2.43.0
32
40
33
41
diff view generated by jsdifflib
Deleted patch
1
From: Alexander Graf <agraf@csgraf.de>
2
1
3
We need to fetch the name of the current accelerator in flexible error
4
messages more going forward. Let's create a helper that gives it to us
5
without casting in the target code.
6
7
Signed-off-by: Alexander Graf <agraf@csgraf.de>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220620192242.70573-1-agraf@csgraf.de
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/qemu/accel.h | 1 +
13
accel/accel-common.c | 8 ++++++++
14
softmmu/vl.c | 3 +--
15
3 files changed, 10 insertions(+), 2 deletions(-)
16
17
diff --git a/include/qemu/accel.h b/include/qemu/accel.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/qemu/accel.h
20
+++ b/include/qemu/accel.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct AccelClass {
22
23
AccelClass *accel_find(const char *opt_name);
24
AccelState *current_accel(void);
25
+const char *current_accel_name(void);
26
27
void accel_init_interfaces(AccelClass *ac);
28
29
diff --git a/accel/accel-common.c b/accel/accel-common.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/accel/accel-common.c
32
+++ b/accel/accel-common.c
33
@@ -XXX,XX +XXX,XX @@ AccelClass *accel_find(const char *opt_name)
34
return ac;
35
}
36
37
+/* Return the name of the current accelerator */
38
+const char *current_accel_name(void)
39
+{
40
+ AccelClass *ac = ACCEL_GET_CLASS(current_accel());
41
+
42
+ return ac->name;
43
+}
44
+
45
static void accel_init_cpu_int_aux(ObjectClass *klass, void *opaque)
46
{
47
CPUClass *cc = CPU_CLASS(klass);
48
diff --git a/softmmu/vl.c b/softmmu/vl.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/softmmu/vl.c
51
+++ b/softmmu/vl.c
52
@@ -XXX,XX +XXX,XX @@ static void configure_accelerators(const char *progname)
53
}
54
55
if (init_failed && !qtest_chrdev) {
56
- AccelClass *ac = ACCEL_GET_CLASS(current_accel());
57
- error_report("falling back to %s", ac->name);
58
+ error_report("falling back to %s", current_accel_name());
59
}
60
61
if (icount_enabled() && !tcg_enabled()) {
62
--
63
2.25.1
diff view generated by jsdifflib
Deleted patch
1
From: Alexander Graf <agraf@csgraf.de>
2
1
3
Some features such as running in EL3 or running M profile code are
4
incompatible with virtualization as QEMU implements it today. To prevent
5
users from picking invalid configurations on other virt solutions like
6
Hvf, let's run the same checks there too.
7
8
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1073
9
Signed-off-by: Alexander Graf <agraf@csgraf.de>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220620192242.70573-2-agraf@csgraf.de
12
[PMM: Allow qtest accelerator too; tweak comment]
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
target/arm/cpu.c | 16 ++++++++++++----
16
1 file changed, 12 insertions(+), 4 deletions(-)
17
18
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.c
21
+++ b/target/arm/cpu.c
22
@@ -XXX,XX +XXX,XX @@
23
#include "hw/boards.h"
24
#endif
25
#include "sysemu/tcg.h"
26
+#include "sysemu/qtest.h"
27
#include "sysemu/hw_accel.h"
28
#include "kvm_arm.h"
29
#include "disas/capstone.h"
30
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
31
}
32
}
33
34
- if (kvm_enabled()) {
35
+ if (!tcg_enabled() && !qtest_enabled()) {
36
/*
37
+ * We assume that no accelerator except TCG (and the "not really an
38
+ * accelerator" qtest) can handle these features, because Arm hardware
39
+ * virtualization can't virtualize them.
40
+ *
41
* Catch all the cases which might cause us to create more than one
42
* address space for the CPU (otherwise we will assert() later in
43
* cpu_address_space_init()).
44
*/
45
if (arm_feature(env, ARM_FEATURE_M)) {
46
error_setg(errp,
47
- "Cannot enable KVM when using an M-profile guest CPU");
48
+ "Cannot enable %s when using an M-profile guest CPU",
49
+ current_accel_name());
50
return;
51
}
52
if (cpu->has_el3) {
53
error_setg(errp,
54
- "Cannot enable KVM when guest CPU has EL3 enabled");
55
+ "Cannot enable %s when guest CPU has EL3 enabled",
56
+ current_accel_name());
57
return;
58
}
59
if (cpu->tag_memory) {
60
error_setg(errp,
61
- "Cannot enable KVM when guest CPUs has MTE enabled");
62
+ "Cannot enable %s when guest CPUs has MTE enabled",
63
+ current_accel_name());
64
return;
65
}
66
}
67
--
68
2.25.1
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
This register is part of SME, but isn't closely related to the
4
rest of the extension.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220620175235.60881-2-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/cpu.h | 1 +
12
target/arm/helper.c | 32 ++++++++++++++++++++++++++++++++
13
2 files changed, 33 insertions(+)
14
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
20
};
21
uint64_t tpidr_el[4];
22
};
23
+ uint64_t tpidr2_el0;
24
/* The secure banks of these registers don't map anywhere */
25
uint64_t tpidrurw_s;
26
uint64_t tpidrprw_s;
27
diff --git a/target/arm/helper.c b/target/arm/helper.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/helper.c
30
+++ b/target/arm/helper.c
31
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo zcr_reginfo[] = {
32
.writefn = zcr_write, .raw_writefn = raw_write },
33
};
34
35
+#ifdef TARGET_AARCH64
36
+static CPAccessResult access_tpidr2(CPUARMState *env, const ARMCPRegInfo *ri,
37
+ bool isread)
38
+{
39
+ int el = arm_current_el(env);
40
+
41
+ if (el == 0) {
42
+ uint64_t sctlr = arm_sctlr(env, el);
43
+ if (!(sctlr & SCTLR_EnTP2)) {
44
+ return CP_ACCESS_TRAP;
45
+ }
46
+ }
47
+ /* TODO: FEAT_FGT */
48
+ if (el < 3
49
+ && arm_feature(env, ARM_FEATURE_EL3)
50
+ && !(env->cp15.scr_el3 & SCR_ENTP2)) {
51
+ return CP_ACCESS_TRAP_EL3;
52
+ }
53
+ return CP_ACCESS_OK;
54
+}
55
+
56
+static const ARMCPRegInfo sme_reginfo[] = {
57
+ { .name = "TPIDR2_EL0", .state = ARM_CP_STATE_AA64,
58
+ .opc0 = 3, .opc1 = 3, .crn = 13, .crm = 0, .opc2 = 5,
59
+ .access = PL0_RW, .accessfn = access_tpidr2,
60
+ .fieldoffset = offsetof(CPUARMState, cp15.tpidr2_el0) },
61
+};
62
+#endif /* TARGET_AARCH64 */
63
+
64
void hw_watchpoint_update(ARMCPU *cpu, int n)
65
{
66
CPUARMState *env = &cpu->env;
67
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
68
}
69
70
#ifdef TARGET_AARCH64
71
+ if (cpu_isar_feature(aa64_sme, cpu)) {
72
+ define_arm_cp_regs(cpu, sme_reginfo);
73
+ }
74
if (cpu_isar_feature(aa64_pauth, cpu)) {
75
define_arm_cp_regs(cpu, pauth_reginfo);
76
}
77
--
78
2.25.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
Move the code from hw/arm/virt.c that is supposed
3
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
4
to handle v7 into the one function.
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20250204125009.2281315-9-peter.maydell@linaro.org
7
Reported-by: He Zhe <zhe.he@windriver.com>
7
Cc: qemu-stable@nongnu.org
8
Message-id: 20220619001541.131672-2-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
hw/arm/virt.c | 10 +---------
11
hw/arm/virt.c | 2 ++
13
target/arm/ptw.c | 24 ++++++++++++++++--------
12
1 file changed, 2 insertions(+)
14
2 files changed, 17 insertions(+), 17 deletions(-)
15
13
16
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
14
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/virt.c
16
--- a/hw/arm/virt.c
19
+++ b/hw/arm/virt.c
17
+++ b/hw/arm/virt.c
20
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
18
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
21
cpuobj = object_new(possible_cpus->cpus[0].type);
19
[GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
22
armcpu = ARM_CPU(cpuobj);
20
[GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
23
21
[GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
24
- if (object_property_get_bool(cpuobj, "aarch64", NULL)) {
22
+ [GTIMER_S_EL2_PHYS] = ARCH_TIMER_S_EL2_IRQ,
25
- pa_bits = arm_pamax(armcpu);
23
+ [GTIMER_S_EL2_VIRT] = ARCH_TIMER_S_EL2_VIRT_IRQ,
26
- } else if (arm_feature(&armcpu->env, ARM_FEATURE_LPAE)) {
24
};
27
- /* v7 with LPAE */
25
28
- pa_bits = 40;
26
for (unsigned irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
29
- } else {
30
- /* Anything else */
31
- pa_bits = 32;
32
- }
33
+ pa_bits = arm_pamax(armcpu);
34
35
object_unref(cpuobj);
36
37
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/ptw.c
40
+++ b/target/arm/ptw.c
41
@@ -XXX,XX +XXX,XX @@ static const uint8_t pamax_map[] = {
42
/* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */
43
unsigned int arm_pamax(ARMCPU *cpu)
44
{
45
- unsigned int parange =
46
- FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
47
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
48
+ unsigned int parange =
49
+ FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
50
51
- /*
52
- * id_aa64mmfr0 is a read-only register so values outside of the
53
- * supported mappings can be considered an implementation error.
54
- */
55
- assert(parange < ARRAY_SIZE(pamax_map));
56
- return pamax_map[parange];
57
+ /*
58
+ * id_aa64mmfr0 is a read-only register so values outside of the
59
+ * supported mappings can be considered an implementation error.
60
+ */
61
+ assert(parange < ARRAY_SIZE(pamax_map));
62
+ return pamax_map[parange];
63
+ }
64
+ if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) {
65
+ /* v7 with LPAE */
66
+ return 40;
67
+ }
68
+ /* Anything else */
69
+ return 32;
70
}
71
72
/*
73
--
27
--
74
2.25.1
28
2.43.0
29
30
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
This cpreg is used to access two new bits of PSTATE
3
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
4
that are not visible via any other mechanism.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20220620175235.60881-6-richard.henderson@linaro.org
6
Message-id: 20250204125009.2281315-10-peter.maydell@linaro.org
7
Cc: qemu-stable@nongnu.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
target/arm/cpu.h | 6 ++++++
10
hw/arm/sbsa-ref.c | 2 ++
12
target/arm/helper.c | 13 +++++++++++++
11
1 file changed, 2 insertions(+)
13
2 files changed, 19 insertions(+)
14
12
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
15
--- a/hw/arm/sbsa-ref.c
18
+++ b/target/arm/cpu.h
16
+++ b/hw/arm/sbsa-ref.c
19
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
17
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, MemoryRegion *mem)
20
* nRW (also known as M[4]) is kept, inverted, in env->aarch64
18
[GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
21
* DAIF (exception masks) are kept in env->daif
19
[GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
22
* BTYPE is kept in env->btype
20
[GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
23
+ * SM and ZA are kept in env->svcr
21
+ [GTIMER_S_EL2_PHYS] = ARCH_TIMER_S_EL2_IRQ,
24
* all other bits are stored in their correct places in env->pstate
22
+ [GTIMER_S_EL2_VIRT] = ARCH_TIMER_S_EL2_VIRT_IRQ,
25
*/
23
};
26
uint32_t pstate;
24
27
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
25
for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
28
uint32_t condexec_bits; /* IT bits. cpsr[15:10,26:25]. */
29
uint32_t btype; /* BTI branch type. spsr[11:10]. */
30
uint64_t daif; /* exception masks, in the bits they are in PSTATE */
31
+ uint64_t svcr; /* PSTATE.{SM,ZA} in the bits they are in SVCR */
32
33
uint64_t elr_el[4]; /* AArch64 exception link regs */
34
uint64_t sp_el[4]; /* AArch64 banked stack pointers */
35
@@ -XXX,XX +XXX,XX @@ FIELD(CPTR_EL3, TCPAC, 31, 1)
36
#define PSTATE_MODE_EL1t 4
37
#define PSTATE_MODE_EL0t 0
38
39
+/* PSTATE bits that are accessed via SVCR and not stored in SPSR_ELx. */
40
+FIELD(SVCR, SM, 0, 1)
41
+FIELD(SVCR, ZA, 1, 1)
42
+
43
/* Write a new value to v7m.exception, thus transitioning into or out
44
* of Handler mode; this may result in a change of active stack pointer.
45
*/
46
diff --git a/target/arm/helper.c b/target/arm/helper.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/helper.c
49
+++ b/target/arm/helper.c
50
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tpidr2(CPUARMState *env, const ARMCPRegInfo *ri,
51
return CP_ACCESS_OK;
52
}
53
54
+static void svcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
55
+ uint64_t value)
56
+{
57
+ value &= R_SVCR_SM_MASK | R_SVCR_ZA_MASK;
58
+ /* TODO: Side effects. */
59
+ env->svcr = value;
60
+}
61
+
62
static const ARMCPRegInfo sme_reginfo[] = {
63
{ .name = "TPIDR2_EL0", .state = ARM_CP_STATE_AA64,
64
.opc0 = 3, .opc1 = 3, .crn = 13, .crm = 0, .opc2 = 5,
65
.access = PL0_RW, .accessfn = access_tpidr2,
66
.fieldoffset = offsetof(CPUARMState, cp15.tpidr2_el0) },
67
+ { .name = "SVCR", .state = ARM_CP_STATE_AA64,
68
+ .opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 2,
69
+ .access = PL0_RW, .type = ARM_CP_SME,
70
+ .fieldoffset = offsetof(CPUARMState, svcr),
71
+ .writefn = svcr_write, .raw_writefn = raw_write },
72
};
73
#endif /* TARGET_AARCH64 */
74
75
--
26
--
76
2.25.1
27
2.43.0
28
29
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Our LDRD implementation is wrong in two respects:
2
2
3
Implement the streaming mode identification register, and the
3
* if the address is 4-aligned and the load crosses a page boundary
4
two streaming priority registers. For QEMU, they are all RES0.
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
5
9
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Rewrite the handling of the loads in LDRD to use a single
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
tcg_gen_qemu_ld_i64() and split the result into the destination
8
Message-id: 20220620175235.60881-8-richard.henderson@linaro.org
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>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
10
---
30
---
11
target/arm/helper.c | 33 +++++++++++++++++++++++++++++++++
31
target/arm/tcg/translate.c | 70 +++++++++++++++++++++++++-------------
12
1 file changed, 33 insertions(+)
32
1 file changed, 46 insertions(+), 24 deletions(-)
13
33
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
34
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
15
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
36
--- a/target/arm/tcg/translate.c
17
+++ b/target/arm/helper.c
37
+++ b/target/arm/tcg/translate.c
18
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tpidr2(CPUARMState *env, const ARMCPRegInfo *ri,
38
@@ -XXX,XX +XXX,XX @@ static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
19
return CP_ACCESS_OK;
39
return true;
20
}
40
}
21
41
22
+static CPAccessResult access_esm(CPUARMState *env, const ARMCPRegInfo *ri,
42
+static void do_ldrd_load(DisasContext *s, TCGv_i32 addr, int rt, int rt2)
23
+ bool isread)
24
+{
43
+{
25
+ /* TODO: FEAT_FGT for SMPRI_EL1 but not SMPRIMAP_EL2 */
44
+ /*
26
+ if (arm_current_el(env) < 3
45
+ * LDRD is required to be an atomic 64-bit access if the
27
+ && arm_feature(env, ARM_FEATURE_EL3)
46
+ * address is 8-aligned, two atomic 32-bit accesses if
28
+ && !FIELD_EX64(env->cp15.cptr_el[3], CPTR_EL3, ESM)) {
47
+ * it's only 4-aligned, and to give an alignment fault
29
+ return CP_ACCESS_TRAP_EL3;
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);
30
+ }
77
+ }
31
+ return CP_ACCESS_OK;
78
+ store_reg(s, rt, tmp);
79
+ store_reg(s, rt2, tmp2);
32
+}
80
+}
33
+
81
+
34
static void svcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
82
static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
35
uint64_t value)
36
{
83
{
37
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo sme_reginfo[] = {
84
- int mem_idx = get_mem_index(s);
38
.access = PL3_RW, .type = ARM_CP_SME,
85
- TCGv_i32 addr, tmp;
39
.fieldoffset = offsetof(CPUARMState, vfp.smcr_el[3]),
86
+ TCGv_i32 addr;
40
.writefn = smcr_write, .raw_writefn = raw_write },
87
41
+ { .name = "SMIDR_EL1", .state = ARM_CP_STATE_AA64,
88
if (!ENABLE_ARCH_5TE) {
42
+ .opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 6,
89
return false;
43
+ .access = PL1_R, .accessfn = access_aa64_tid1,
90
@@ -XXX,XX +XXX,XX @@ static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
44
+ /*
91
}
45
+ * IMPLEMENTOR = 0 (software)
92
addr = op_addr_rr_pre(s, a);
46
+ * REVISION = 0 (implementation defined)
93
47
+ * SMPS = 0 (no streaming execution priority in QEMU)
94
- tmp = tcg_temp_new_i32();
48
+ * AFFINITY = 0 (streaming sve mode not shared with other PEs)
95
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
49
+ */
96
- store_reg(s, a->rt, tmp);
50
+ .type = ARM_CP_CONST, .resetvalue = 0, },
97
-
51
+ /*
98
- tcg_gen_addi_i32(addr, addr, 4);
52
+ * Because SMIDR_EL1.SMPS is 0, SMPRI_EL1 and SMPRIMAP_EL2 are RES 0.
99
-
53
+ */
100
- tmp = tcg_temp_new_i32();
54
+ { .name = "SMPRI_EL1", .state = ARM_CP_STATE_AA64,
101
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
55
+ .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 4,
102
- store_reg(s, a->rt + 1, tmp);
56
+ .access = PL1_RW, .accessfn = access_esm,
103
+ do_ldrd_load(s, addr, a->rt, a->rt + 1);
57
+ .type = ARM_CP_CONST, .resetvalue = 0 },
104
58
+ { .name = "SMPRIMAP_EL2", .state = ARM_CP_STATE_AA64,
105
/* LDRD w/ base writeback is undefined if the registers overlap. */
59
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 5,
106
- op_addr_rr_post(s, a, addr, -4);
60
+ .access = PL2_RW, .accessfn = access_esm,
107
+ op_addr_rr_post(s, a, addr, 0);
61
+ .type = ARM_CP_CONST, .resetvalue = 0 },
108
return true;
62
};
109
}
63
#endif /* TARGET_AARCH64 */
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
}
64
137
65
--
138
--
66
2.25.1
139
2.43.0
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
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
2
4
3
Rename from cpu_arm_{get,set}_sve_vq, and take the
5
Rewrite the handling of STRD to use a single tcg_gen_qemu_st_i64()
4
ARMVQMap as the opaque parameter.
6
of a value produced by concatenating the two 32 bit source registers.
7
This allows us to get the atomicity right.
5
8
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
As with the LDRD change, now that we don't update 'addr' in the
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
course of performing the store we need to adjust the offset
8
Message-id: 20220620175235.60881-14-richard.henderson@linaro.org
11
we pass to op_addr_ri_post() and op_addr_rr_post().
12
13
Cc: qemu-stable@nongnu.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.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
10
---
17
---
11
target/arm/cpu64.c | 29 +++++++++++++++--------------
18
target/arm/tcg/translate.c | 59 +++++++++++++++++++++++++-------------
12
1 file changed, 15 insertions(+), 14 deletions(-)
19
1 file changed, 39 insertions(+), 20 deletions(-)
13
20
14
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
21
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
15
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu64.c
23
--- a/target/arm/tcg/translate.c
17
+++ b/target/arm/cpu64.c
24
+++ b/target/arm/tcg/translate.c
18
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
25
@@ -XXX,XX +XXX,XX @@ static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
26
return true;
19
}
27
}
20
28
21
/*
29
+static void do_strd_store(DisasContext *s, TCGv_i32 addr, int rt, int rt2)
22
- * Note that cpu_arm_get/set_sve_vq cannot use the simpler
30
+{
23
- * object_property_add_bool interface because they make use
31
+ /*
24
- * of the contents of "name" to determine which bit on which
32
+ * STRD is required to be an atomic 64-bit access if the
25
- * to operate.
33
+ * address is 8-aligned, two atomic 32-bit accesses if
26
+ * Note that cpu_arm_{get,set}_vq cannot use the simpler
34
+ * it's only 4-aligned, and to give an alignment fault
27
+ * object_property_add_bool interface because they make use of the
35
+ * if it's not 4-aligned.
28
+ * contents of "name" to determine which bit on which to operate.
36
+ * Rt is always the word from the lower address, and Rt2 the
29
*/
37
+ * data from the higher address, regardless of endianness.
30
-static void cpu_arm_get_sve_vq(Object *obj, Visitor *v, const char *name,
38
+ * So (like gen_store_exclusive) we avoid gen_aa32_ld_i64()
31
- void *opaque, Error **errp)
39
+ * so we don't get its SCTLR_B check, and instead do a 64-bit access
32
+static void cpu_arm_get_vq(Object *obj, Visitor *v, const char *name,
40
+ * using MO_BE if appropriate, using a value constructed
33
+ void *opaque, Error **errp)
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)
34
{
63
{
35
ARMCPU *cpu = ARM_CPU(obj);
64
- int mem_idx = get_mem_index(s);
36
+ ARMVQMap *vq_map = opaque;
65
- TCGv_i32 addr, tmp;
37
uint32_t vq = atoi(&name[3]) / 128;
66
+ TCGv_i32 addr;
38
bool value;
67
39
68
if (!ENABLE_ARCH_5TE) {
40
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_get_sve_vq(Object *obj, Visitor *v, const char *name,
69
return false;
41
if (!cpu_isar_feature(aa64_sve, cpu)) {
70
@@ -XXX,XX +XXX,XX @@ static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
42
value = false;
43
} else {
44
- value = extract32(cpu->sve_vq.map, vq - 1, 1);
45
+ value = extract32(vq_map->map, vq - 1, 1);
46
}
71
}
47
visit_type_bool(v, name, &value, errp);
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;
48
}
86
}
49
87
50
-static void cpu_arm_set_sve_vq(Object *obj, Visitor *v, const char *name,
88
@@ -XXX,XX +XXX,XX @@ static bool trans_LDRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
51
- void *opaque, Error **errp)
89
52
+static void cpu_arm_set_vq(Object *obj, Visitor *v, const char *name,
90
static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
53
+ void *opaque, Error **errp)
54
{
91
{
55
- ARMCPU *cpu = ARM_CPU(obj);
92
- int mem_idx = get_mem_index(s);
56
+ ARMVQMap *vq_map = opaque;
93
- TCGv_i32 addr, tmp;
57
uint32_t vq = atoi(&name[3]) / 128;
94
+ TCGv_i32 addr;
58
bool value;
95
59
96
addr = op_addr_ri_pre(s, a);
60
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve_vq(Object *obj, Visitor *v, const char *name,
97
61
return;
98
- tmp = load_reg(s, a->rt);
62
}
99
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
63
100
+ do_strd_store(s, addr, a->rt, rt2);
64
- cpu->sve_vq.map = deposit32(cpu->sve_vq.map, vq - 1, 1, value);
101
65
- cpu->sve_vq.init |= 1 << (vq - 1);
102
- tcg_gen_addi_i32(addr, addr, 4);
66
+ vq_map->map = deposit32(vq_map->map, vq - 1, 1, value);
103
-
67
+ vq_map->init |= 1 << (vq - 1);
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;
68
}
110
}
69
111
70
static bool cpu_arm_get_sve(Object *obj, Error **errp)
71
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_get_sve_default_vec_len(Object *obj, Visitor *v,
72
73
void aarch64_add_sve_properties(Object *obj)
74
{
75
+ ARMCPU *cpu = ARM_CPU(obj);
76
uint32_t vq;
77
78
object_property_add_bool(obj, "sve", cpu_arm_get_sve, cpu_arm_set_sve);
79
@@ -XXX,XX +XXX,XX @@ void aarch64_add_sve_properties(Object *obj)
80
for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
81
char name[8];
82
sprintf(name, "sve%d", vq * 128);
83
- object_property_add(obj, name, "bool", cpu_arm_get_sve_vq,
84
- cpu_arm_set_sve_vq, NULL, NULL);
85
+ object_property_add(obj, name, "bool", cpu_arm_get_vq,
86
+ cpu_arm_set_vq, NULL, &cpu->sve_vq);
87
}
88
89
#ifdef CONFIG_USER_ONLY
90
--
112
--
91
2.25.1
113
2.43.0
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
All the callers of op_addr_rr_post() and op_addr_ri_post() now pass in
2
zero for the address_offset, so we can remove that argument.
2
3
3
Pull the three sve_vq_* values into a structure.
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
This will be reused for SME.
5
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
---
9
target/arm/tcg/translate.c | 26 +++++++++++++-------------
10
1 file changed, 13 insertions(+), 13 deletions(-)
5
11
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220620175235.60881-13-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/cpu.h | 29 ++++++++++++++---------------
12
target/arm/cpu64.c | 22 +++++++++++-----------
13
target/arm/helper.c | 2 +-
14
target/arm/kvm64.c | 2 +-
15
4 files changed, 27 insertions(+), 28 deletions(-)
16
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
14
--- a/target/arm/tcg/translate.c
20
+++ b/target/arm/cpu.h
15
+++ b/target/arm/tcg/translate.c
21
@@ -XXX,XX +XXX,XX @@ typedef enum ARMPSCIState {
16
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 op_addr_rr_pre(DisasContext *s, arg_ldst_rr *a)
22
23
typedef struct ARMISARegisters ARMISARegisters;
24
25
+/*
26
+ * In map, each set bit is a supported vector length of (bit-number + 1) * 16
27
+ * bytes, i.e. each bit number + 1 is the vector length in quadwords.
28
+ *
29
+ * While processing properties during initialization, corresponding init bits
30
+ * are set for bits in sve_vq_map that have been set by properties.
31
+ *
32
+ * Bits set in supported represent valid vector lengths for the CPU type.
33
+ */
34
+typedef struct {
35
+ uint32_t map, init, supported;
36
+} ARMVQMap;
37
+
38
/**
39
* ARMCPU:
40
* @env: #CPUARMState
41
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
42
uint32_t sve_default_vq;
43
#endif
44
45
- /*
46
- * In sve_vq_map each set bit is a supported vector length of
47
- * (bit-number + 1) * 16 bytes, i.e. each bit number + 1 is the vector
48
- * length in quadwords.
49
- *
50
- * While processing properties during initialization, corresponding
51
- * sve_vq_init bits are set for bits in sve_vq_map that have been
52
- * set by properties.
53
- *
54
- * Bits set in sve_vq_supported represent valid vector lengths for
55
- * the CPU type.
56
- */
57
- uint32_t sve_vq_map;
58
- uint32_t sve_vq_init;
59
- uint32_t sve_vq_supported;
60
+ ARMVQMap sve_vq;
61
62
/* Generic timer counter frequency, in Hz */
63
uint64_t gt_cntfrq_hz;
64
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/cpu64.c
67
+++ b/target/arm/cpu64.c
68
@@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
69
* any of the above. Finally, if SVE is not disabled, then at least one
70
* vector length must be enabled.
71
*/
72
- uint32_t vq_map = cpu->sve_vq_map;
73
- uint32_t vq_init = cpu->sve_vq_init;
74
+ uint32_t vq_map = cpu->sve_vq.map;
75
+ uint32_t vq_init = cpu->sve_vq.init;
76
uint32_t vq_supported;
77
uint32_t vq_mask = 0;
78
uint32_t tmp, vq, max_vq = 0;
79
@@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
80
*/
81
if (kvm_enabled()) {
82
if (kvm_arm_sve_supported()) {
83
- cpu->sve_vq_supported = kvm_arm_sve_get_vls(CPU(cpu));
84
- vq_supported = cpu->sve_vq_supported;
85
+ cpu->sve_vq.supported = kvm_arm_sve_get_vls(CPU(cpu));
86
+ vq_supported = cpu->sve_vq.supported;
87
} else {
88
assert(!cpu_isar_feature(aa64_sve, cpu));
89
vq_supported = 0;
90
}
91
} else {
92
- vq_supported = cpu->sve_vq_supported;
93
+ vq_supported = cpu->sve_vq.supported;
94
}
95
96
/*
97
@@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
98
99
/* From now on sve_max_vq is the actual maximum supported length. */
100
cpu->sve_max_vq = max_vq;
101
- cpu->sve_vq_map = vq_map;
102
+ cpu->sve_vq.map = vq_map;
103
}
17
}
104
18
105
static void cpu_max_get_sve_max_vq(Object *obj, Visitor *v, const char *name,
19
static void op_addr_rr_post(DisasContext *s, arg_ldst_rr *a,
106
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_get_sve_vq(Object *obj, Visitor *v, const char *name,
20
- TCGv_i32 addr, int address_offset)
107
if (!cpu_isar_feature(aa64_sve, cpu)) {
21
+ TCGv_i32 addr)
108
value = false;
22
{
109
} else {
23
if (!a->p) {
110
- value = extract32(cpu->sve_vq_map, vq - 1, 1);
24
TCGv_i32 ofs = load_reg(s, a->rm);
111
+ value = extract32(cpu->sve_vq.map, vq - 1, 1);
25
@@ -XXX,XX +XXX,XX @@ static void op_addr_rr_post(DisasContext *s, arg_ldst_rr *a,
112
}
26
} else if (!a->w) {
113
visit_type_bool(v, name, &value, errp);
114
}
115
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve_vq(Object *obj, Visitor *v, const char *name,
116
return;
27
return;
117
}
28
}
118
29
- tcg_gen_addi_i32(addr, addr, address_offset);
119
- cpu->sve_vq_map = deposit32(cpu->sve_vq_map, vq - 1, 1, value);
30
store_reg(s, a->rn, addr);
120
- cpu->sve_vq_init |= 1 << (vq - 1);
121
+ cpu->sve_vq.map = deposit32(cpu->sve_vq.map, vq - 1, 1, value);
122
+ cpu->sve_vq.init |= 1 << (vq - 1);
123
}
31
}
124
32
125
static bool cpu_arm_get_sve(Object *obj, Error **errp)
33
@@ -XXX,XX +XXX,XX @@ static bool op_load_rr(DisasContext *s, arg_ldst_rr *a,
126
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
34
* Perform base writeback before the loaded value to
127
cpu->dcz_blocksize = 7; /* 512 bytes */
35
* ensure correct behavior with overlapping index registers.
128
#endif
36
*/
129
37
- op_addr_rr_post(s, a, addr, 0);
130
- cpu->sve_vq_supported = MAKE_64BIT_MASK(0, ARM_MAX_VQ);
38
+ op_addr_rr_post(s, a, addr);
131
+ cpu->sve_vq.supported = MAKE_64BIT_MASK(0, ARM_MAX_VQ);
39
store_reg_from_load(s, a->rt, tmp);
132
40
return true;
133
aarch64_add_pauth_properties(obj);
134
aarch64_add_sve_properties(obj);
135
@@ -XXX,XX +XXX,XX @@ static void aarch64_a64fx_initfn(Object *obj)
136
137
/* The A64FX supports only 128, 256 and 512 bit vector lengths */
138
aarch64_add_sve_properties(obj);
139
- cpu->sve_vq_supported = (1 << 0) /* 128bit */
140
+ cpu->sve_vq.supported = (1 << 0) /* 128bit */
141
| (1 << 1) /* 256bit */
142
| (1 << 3); /* 512bit */
143
144
diff --git a/target/arm/helper.c b/target/arm/helper.c
145
index XXXXXXX..XXXXXXX 100644
146
--- a/target/arm/helper.c
147
+++ b/target/arm/helper.c
148
@@ -XXX,XX +XXX,XX @@ uint32_t sve_vqm1_for_el(CPUARMState *env, int el)
149
len = MIN(len, 0xf & (uint32_t)env->vfp.zcr_el[3]);
150
}
151
152
- len = 31 - clz32(cpu->sve_vq_map & MAKE_64BIT_MASK(0, len + 1));
153
+ len = 31 - clz32(cpu->sve_vq.map & MAKE_64BIT_MASK(0, len + 1));
154
return len;
155
}
41
}
156
42
@@ -XXX,XX +XXX,XX @@ static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
157
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
43
gen_aa32_st_i32(s, tmp, addr, mem_idx, mop);
158
index XXXXXXX..XXXXXXX 100644
44
disas_set_da_iss(s, mop, issinfo);
159
--- a/target/arm/kvm64.c
45
160
+++ b/target/arm/kvm64.c
46
- op_addr_rr_post(s, a, addr, 0);
161
@@ -XXX,XX +XXX,XX @@ uint32_t kvm_arm_sve_get_vls(CPUState *cs)
47
+ op_addr_rr_post(s, a, addr);
162
static int kvm_arm_sve_set_vls(CPUState *cs)
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)
163
{
75
{
164
ARMCPU *cpu = ARM_CPU(cs);
76
+ int address_offset = 0;
165
- uint64_t vls[KVM_ARM64_SVE_VLS_WORDS] = { cpu->sve_vq_map };
77
if (!a->p) {
166
+ uint64_t vls[KVM_ARM64_SVE_VLS_WORDS] = { cpu->sve_vq.map };
78
if (a->u) {
167
struct kvm_one_reg reg = {
79
- address_offset += a->imm;
168
.id = KVM_REG_ARM64_SVE_VLS,
80
+ address_offset = a->imm;
169
.addr = (uint64_t)&vls[0],
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
170
--
123
--
171
2.25.1
124
2.43.0
125
126
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
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
2
9
3
This will be used for raising various traps for SME.
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.
4
17
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Model these registers instead as RAZ.
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
19
7
Message-id: 20220620175235.60881-4-richard.henderson@linaro.org
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
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
9
---
26
---
10
target/arm/syndrome.h | 14 ++++++++++++++
27
target/arm/debug_helper.c | 7 ++++---
11
1 file changed, 14 insertions(+)
28
1 file changed, 4 insertions(+), 3 deletions(-)
12
29
13
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
30
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
14
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/syndrome.h
32
--- a/target/arm/debug_helper.c
16
+++ b/target/arm/syndrome.h
33
+++ b/target/arm/debug_helper.c
17
@@ -XXX,XX +XXX,XX @@ enum arm_exception_class {
34
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
18
EC_AA64_SMC = 0x17,
35
{ .name = "DBGVCR",
19
EC_SYSTEMREGISTERTRAP = 0x18,
36
.cp = 14, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
20
EC_SVEACCESSTRAP = 0x19,
37
.access = PL1_RW, .accessfn = access_tda,
21
+ EC_SMETRAP = 0x1d,
38
- .type = ARM_CP_NOP },
22
EC_INSNABORT = 0x20,
39
+ .type = ARM_CP_CONST, .resetvalue = 0 },
23
EC_INSNABORT_SAME_EL = 0x21,
40
/*
24
EC_PCALIGNMENT = 0x22,
41
* Dummy MDCCINT_EL1, since we don't implement the Debug Communications
25
@@ -XXX,XX +XXX,XX @@ enum arm_exception_class {
42
* Channel but Linux may try to access this register. The 32-bit
26
EC_AA64_BKPT = 0x3c,
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 },
27
};
59
};
28
60
29
+typedef enum {
61
static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
30
+ SME_ET_AccessTrap,
31
+ SME_ET_Streaming,
32
+ SME_ET_NotStreaming,
33
+ SME_ET_InactiveZA,
34
+} SMEExceptionType;
35
+
36
#define ARM_EL_EC_SHIFT 26
37
#define ARM_EL_IL_SHIFT 25
38
#define ARM_EL_ISV_SHIFT 24
39
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_sve_access_trap(void)
40
return EC_SVEACCESSTRAP << ARM_EL_EC_SHIFT;
41
}
42
43
+static inline uint32_t syn_smetrap(SMEExceptionType etype, bool is_16bit)
44
+{
45
+ return (EC_SMETRAP << ARM_EL_EC_SHIFT)
46
+ | (is_16bit ? 0 : ARM_EL_IL) | etype;
47
+}
48
+
49
static inline uint32_t syn_pactrap(void)
50
{
51
return EC_PACTRAP << ARM_EL_EC_SHIFT;
52
--
62
--
53
2.25.1
63
2.43.0
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Currently we call icount_start_warp_timer() from timerlist_rearm().
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.
2
9
3
These functions are not used outside cpu64.c,
10
The only valid place to choose to warp the timer forward is from the
4
so make them static.
11
main loop, when we know we have no outstanding IO or timer callbacks
12
that might be about to wake up a CPU.
5
13
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
For Arm guests, this bug was mostly latent until the refactoring
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
commit f6fc36deef6abc ("target/arm/helper: Implement
8
Message-id: 20220620175235.60881-17-richard.henderson@linaro.org
16
CNTHCTL_EL2.CNT[VP]MASK"), which exposed it because it refactored a
17
timer callback so that it happened to call timer_mod() first and
18
raise the interrupt second, when it had previously raised the
19
interrupt first and called timer_mod() afterwards.
20
21
This call seems to have originally derived from the
22
pre-record-and-replay icount code, which (as of e.g. commit
23
db1a49726c3c in 2010) in this location did a call to
24
qemu_notify_event(), necessary to get the icount code in the vCPU
25
round-robin thread to stop and recalculate the icount deadline when a
26
timer was reprogrammed from the IO thread. In current QEMU,
27
everything is done on the vCPU thread when we are in icount mode, so
28
there's no need to try to notify another thread here.
29
30
I suspect that the other reason why this call was doing icount timer
31
warping is that it pre-dates commit efab87cf79077a from 2015, which
32
added a call to icount_start_warp_timer() to main_loop_wait(). Once
33
the call in timerlist_rearm() has been removed, if the timer
34
callbacks don't cause any CPU to be woken up then we will end up
35
calling icount_start_warp_timer() from main_loop_wait() when the rr
36
main loop code calls rr_wait_io_event().
37
38
Remove the incorrect call from timerlist_rearm().
39
40
Cc: qemu-stable@nongnu.org
41
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2703
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
10
---
47
---
11
target/arm/cpu.h | 3 ---
48
util/qemu-timer.c | 4 ----
12
target/arm/cpu64.c | 4 ++--
49
1 file changed, 4 deletions(-)
13
2 files changed, 2 insertions(+), 5 deletions(-)
14
50
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
51
diff --git a/util/qemu-timer.c b/util/qemu-timer.c
16
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
53
--- a/util/qemu-timer.c
18
+++ b/target/arm/cpu.h
54
+++ b/util/qemu-timer.c
19
@@ -XXX,XX +XXX,XX @@ int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
55
@@ -XXX,XX +XXX,XX @@ static bool timer_mod_ns_locked(QEMUTimerList *timer_list,
20
void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq);
56
21
void aarch64_sve_change_el(CPUARMState *env, int old_el,
57
static void timerlist_rearm(QEMUTimerList *timer_list)
22
int new_el, bool el0_a64);
58
{
23
-void aarch64_add_sve_properties(Object *obj);
59
- /* Interrupt execution to force deadline recalculation. */
24
-void aarch64_add_pauth_properties(Object *obj);
60
- if (icount_enabled() && timer_list->clock->type == QEMU_CLOCK_VIRTUAL) {
25
void arm_reset_sve_state(CPUARMState *env);
61
- icount_start_warp_timer();
26
62
- }
27
/*
63
timerlist_notify(timer_list);
28
@@ -XXX,XX +XXX,XX @@ static inline void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq) { }
29
static inline void aarch64_sve_change_el(CPUARMState *env, int o,
30
int n, bool a)
31
{ }
32
-static inline void aarch64_add_sve_properties(Object *obj) { }
33
#endif
34
35
void aarch64_sync_32_to_64(CPUARMState *env);
36
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/cpu64.c
39
+++ b/target/arm/cpu64.c
40
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_get_default_vec_len(Object *obj, Visitor *v,
41
}
64
}
42
#endif
43
44
-void aarch64_add_sve_properties(Object *obj)
45
+static void aarch64_add_sve_properties(Object *obj)
46
{
47
ARMCPU *cpu = ARM_CPU(obj);
48
uint32_t vq;
49
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_pauth_property =
50
static Property arm_cpu_pauth_impdef_property =
51
DEFINE_PROP_BOOL("pauth-impdef", ARMCPU, prop_pauth_impdef, false);
52
53
-void aarch64_add_pauth_properties(Object *obj)
54
+static void aarch64_add_pauth_properties(Object *obj)
55
{
56
ARMCPU *cpu = ARM_CPU(obj);
57
65
58
--
66
--
59
2.25.1
67
2.43.0
68
69
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Expand the example in the comment documenting MO_ATOM_SUBALIGN,
2
to be clearer about the atomicity guarantees it represents.
2
3
3
Drop the aa32-only inline fallbacks,
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
and just use a couple of ifdefs.
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20250228103222.1838913-1-peter.maydell@linaro.org
7
---
8
include/exec/memop.h | 8 ++++++--
9
1 file changed, 6 insertions(+), 2 deletions(-)
5
10
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
diff --git a/include/exec/memop.h b/include/exec/memop.h
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220620175235.60881-16-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/cpu.h | 6 ------
12
target/arm/internals.h | 3 +++
13
target/arm/cpu.c | 2 ++
14
3 files changed, 5 insertions(+), 6 deletions(-)
15
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
13
--- a/include/exec/memop.h
19
+++ b/target/arm/cpu.h
14
+++ b/include/exec/memop.h
20
@@ -XXX,XX +XXX,XX @@ typedef struct {
15
@@ -XXX,XX +XXX,XX @@ typedef enum MemOp {
21
16
* Depending on alignment, one or both will be single-copy atomic.
22
#ifdef TARGET_AARCH64
17
* This is the atomicity e.g. of Arm FEAT_LSE2 LDP.
23
# define ARM_MAX_VQ 16
18
* MO_ATOM_SUBALIGN: the operation is single-copy atomic by parts
24
-void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp);
19
- * by the alignment. E.g. if the address is 0 mod 4, then each
25
-void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp);
20
- * 4-byte subobject is single-copy atomic.
26
-void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp);
21
+ * by the alignment. E.g. if an 8-byte value is accessed at an
27
#else
22
+ * address which is 0 mod 8, then the whole 8-byte access is
28
# define ARM_MAX_VQ 1
23
+ * single-copy atomic; otherwise, if it is accessed at 0 mod 4
29
-static inline void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) { }
24
+ * then each 4-byte subobject is single-copy atomic; otherwise
30
-static inline void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp) { }
25
+ * if it is accessed at 0 mod 2 then the four 2-byte subobjects
31
-static inline void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp) { }
26
+ * are single-copy atomic.
32
#endif
27
* This is the atomicity e.g. of IBM Power.
33
28
* MO_ATOM_NONE: the operation has no atomicity requirements.
34
typedef struct ARMVectorReg {
29
*
35
diff --git a/target/arm/internals.h b/target/arm/internals.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/internals.h
38
+++ b/target/arm/internals.h
39
@@ -XXX,XX +XXX,XX @@ int arm_gdb_get_svereg(CPUARMState *env, GByteArray *buf, int reg);
40
int arm_gdb_set_svereg(CPUARMState *env, uint8_t *buf, int reg);
41
int aarch64_fpu_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg);
42
int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg);
43
+void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp);
44
+void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp);
45
+void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp);
46
#endif
47
48
#ifdef CONFIG_USER_ONLY
49
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/cpu.c
52
+++ b/target/arm/cpu.c
53
@@ -XXX,XX +XXX,XX @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
54
{
55
Error *local_err = NULL;
56
57
+#ifdef TARGET_AARCH64
58
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
59
arm_cpu_sve_finalize(cpu, &local_err);
60
if (local_err != NULL) {
61
@@ -XXX,XX +XXX,XX @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
62
return;
63
}
64
}
65
+#endif
66
67
if (kvm_enabled()) {
68
kvm_arm_steal_time_finalize(cpu, &local_err);
69
--
30
--
70
2.25.1
31
2.43.0
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: JianChunfu <jansef.jian@hj-micro.com>
2
2
3
This will be used for controlling access to SME cpregs.
3
Use a similar terminology smmu_hash_remove_by_sid_range() as the one
4
being used for other hash table matching functions since
5
smmuv3_invalidate_ste() name is not self explanatory, and introduce a
6
helper that invokes the g_hash_table_foreach_remove.
4
7
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
No functional change intended.
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
7
Message-id: 20220620175235.60881-5-richard.henderson@linaro.org
10
Signed-off-by: JianChunfu <jansef.jian@hj-micro.com>
11
Reviewed-by: Eric Auger <eric.auger@redhat.com>
12
Message-id: 20250228031438.3916-1-jansef.jian@hj-micro.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
14
---
10
target/arm/cpregs.h | 5 +++++
15
hw/arm/smmu-internal.h | 5 -----
11
target/arm/translate-a64.c | 18 ++++++++++++++++++
16
include/hw/arm/smmu-common.h | 6 ++++++
12
2 files changed, 23 insertions(+)
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(-)
13
21
14
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
22
diff --git a/hw/arm/smmu-internal.h b/hw/arm/smmu-internal.h
15
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpregs.h
24
--- a/hw/arm/smmu-internal.h
17
+++ b/target/arm/cpregs.h
25
+++ b/hw/arm/smmu-internal.h
18
@@ -XXX,XX +XXX,XX @@ enum {
26
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUIOTLBPageInvInfo {
19
ARM_CP_EL3_NO_EL2_UNDEF = 1 << 16,
27
uint64_t mask;
20
ARM_CP_EL3_NO_EL2_KEEP = 1 << 17,
28
} SMMUIOTLBPageInvInfo;
21
ARM_CP_EL3_NO_EL2_C_NZ = 1 << 18,
29
22
+ /*
30
-typedef struct SMMUSIDRange {
23
+ * Flag: Access check for this sysreg is constrained by the
31
- uint32_t start;
24
+ * ARM pseudocode function CheckSMEAccess().
32
- uint32_t end;
25
+ */
33
-} SMMUSIDRange;
26
+ ARM_CP_SME = 1 << 19,
34
-
27
};
35
#endif
28
36
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
29
/*
30
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
31
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/translate-a64.c
38
--- a/include/hw/arm/smmu-common.h
33
+++ b/target/arm/translate-a64.c
39
+++ b/include/hw/arm/smmu-common.h
34
@@ -XXX,XX +XXX,XX @@ bool sve_access_check(DisasContext *s)
40
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUIOTLBKey {
35
return fp_access_check(s);
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);
36
}
66
}
37
67
38
+/*
68
+static gboolean
39
+ * Check that SME access is enabled, raise an exception if not.
69
+smmu_hash_remove_by_sid_range(gpointer key, gpointer value, gpointer user_data)
40
+ * Note that this function corresponds to CheckSMEAccess and is
41
+ * only used directly for cpregs.
42
+ */
43
+static bool sme_access_check(DisasContext *s)
44
+{
70
+{
45
+ if (s->sme_excp_el) {
71
+ SMMUDevice *sdev = (SMMUDevice *)key;
46
+ gen_exception_insn_el(s, s->pc_curr, EXCP_UDEF,
72
+ uint32_t sid = smmu_get_sid(sdev);
47
+ syn_smetrap(SME_ET_AccessTrap, false),
73
+ SMMUSIDRange *sid_range = (SMMUSIDRange *)user_data;
48
+ s->sme_excp_el);
74
+
75
+ if (sid < sid_range->start || sid > sid_range->end) {
49
+ return false;
76
+ return false;
50
+ }
77
+ }
78
+ trace_smmu_config_cache_inv(sid);
51
+ return true;
79
+ return true;
52
+}
80
+}
53
+
81
+
54
/*
82
+void smmu_configs_inv_sid_range(SMMUState *s, SMMUSIDRange sid_range)
55
* This utility function is for doing register extension with an
83
+{
56
* optional shift. You will likely want to pass a temporary for the
84
+ trace_smmu_configs_inv_sid_range(sid_range.start, sid_range.end);
57
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
85
+ g_hash_table_foreach_remove(s->configs, smmu_hash_remove_by_sid_range,
58
return;
86
+ &sid_range);
59
} else if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
87
+}
60
return;
88
+
61
+ } else if ((ri->type & ARM_CP_SME) && !sme_access_check(s)) {
89
void smmu_iotlb_inv_iova(SMMUState *s, int asid, int vmid, dma_addr_t iova,
62
+ return;
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)
63
}
106
}
64
107
}
65
if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
108
109
-static gboolean
110
-smmuv3_invalidate_ste(gpointer key, gpointer value, gpointer user_data)
111
-{
112
- SMMUDevice *sdev = (SMMUDevice *)key;
113
- uint32_t sid = smmu_get_sid(sdev);
114
- SMMUSIDRange *sid_range = (SMMUSIDRange *)user_data;
115
-
116
- if (sid < sid_range->start || sid > sid_range->end) {
117
- return false;
118
- }
119
- trace_smmuv3_config_cache_inv(sid);
120
- return true;
121
-}
122
-
123
static int smmuv3_cmdq_consume(SMMUv3State *s)
124
{
125
SMMUState *bs = ARM_SMMU(s);
126
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
127
sid_range.end = sid_range.start + mask;
128
129
trace_smmuv3_cmdq_cfgi_ste_range(sid_range.start, sid_range.end);
130
- g_hash_table_foreach_remove(bs->configs, smmuv3_invalidate_ste,
131
- &sid_range);
132
+ smmu_configs_inv_sid_range(bs, sid_range);
133
break;
134
}
135
case SMMU_CMD_CFGI_CD:
136
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
137
index XXXXXXX..XXXXXXX 100644
138
--- a/hw/arm/trace-events
139
+++ b/hw/arm/trace-events
140
@@ -XXX,XX +XXX,XX @@ smmu_iotlb_inv_asid_vmid(int asid, int vmid) "IOTLB invalidate asid=%d vmid=%d"
141
smmu_iotlb_inv_vmid(int vmid) "IOTLB invalidate vmid=%d"
142
smmu_iotlb_inv_vmid_s1(int vmid) "IOTLB invalidate vmid=%d"
143
smmu_iotlb_inv_iova(int asid, uint64_t addr) "IOTLB invalidate asid=%d addr=0x%"PRIx64
144
+smmu_configs_inv_sid_range(uint32_t start, uint32_t end) "Config cache INV SID range from 0x%x to 0x%x"
145
+smmu_config_cache_inv(uint32_t sid) "Config cache INV for sid=0x%x"
146
smmu_inv_notifiers_mr(const char *name) "iommu mr=%s"
147
smmu_iotlb_lookup_hit(int asid, int vmid, uint64_t addr, uint32_t hit, uint32_t miss, uint32_t p) "IOTLB cache HIT asid=%d vmid=%d addr=0x%"PRIx64" hit=%d miss=%d hit rate=%d"
148
smmu_iotlb_lookup_miss(int asid, int vmid, uint64_t addr, uint32_t hit, uint32_t miss, uint32_t p) "IOTLB cache MISS asid=%d vmid=%d addr=0x%"PRIx64" hit=%d miss=%d hit rate=%d"
149
@@ -XXX,XX +XXX,XX @@ smmuv3_cmdq_tlbi_nh(int vmid) "vmid=%d"
150
smmuv3_cmdq_tlbi_nsnh(void) ""
151
smmuv3_cmdq_tlbi_nh_asid(int asid) "asid=%d"
152
smmuv3_cmdq_tlbi_s12_vmid(int vmid) "vmid=%d"
153
-smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid=0x%x"
154
smmuv3_notify_flag_add(const char *iommu) "ADD SMMUNotifier node for iommu mr=%s"
155
smmuv3_notify_flag_del(const char *iommu) "DEL SMMUNotifier node for iommu mr=%s"
156
smmuv3_inv_notifiers_iova(const char *name, int asid, int vmid, uint64_t iova, uint8_t tg, uint64_t num_pages, int stage) "iommu mr=%s asid=%d vmid=%d iova=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64" stage=%d"
66
--
157
--
67
2.25.1
158
2.43.0
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Place this late in the resettable section of the structure,
4
to keep the most common element offsets from being > 64k.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220620175235.60881-10-richard.henderson@linaro.org
9
[PMM: expanded comment on zarray[] format]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 22 ++++++++++++++++++++++
13
target/arm/machine.c | 34 ++++++++++++++++++++++++++++++++++
14
2 files changed, 56 insertions(+)
15
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
21
} keys;
22
23
uint64_t scxtnum_el[4];
24
+
25
+ /*
26
+ * SME ZA storage -- 256 x 256 byte array, with bytes in host word order,
27
+ * as we do with vfp.zregs[]. This corresponds to the architectural ZA
28
+ * array, where ZA[N] is in the least-significant bytes of env->zarray[N].
29
+ * When SVL is less than the architectural maximum, the accessible
30
+ * storage is restricted, such that if the SVL is X bytes the guest can
31
+ * see only the bottom X elements of zarray[], and only the least
32
+ * significant X bytes of each element of the array. (In other words,
33
+ * the observable part is always square.)
34
+ *
35
+ * The ZA storage can also be considered as a set of square tiles of
36
+ * elements of different sizes. The mapping from tiles to the ZA array
37
+ * is architecturally defined, such that for tiles of elements of esz
38
+ * bytes, the Nth row (or "horizontal slice") of tile T is in
39
+ * ZA[T + N * esz]. Note that this means that each tile is not contiguous
40
+ * in the ZA storage, because its rows are striped through the ZA array.
41
+ *
42
+ * Because this is so large, keep this toward the end of the reset area,
43
+ * to keep the offsets into the rest of the structure smaller.
44
+ */
45
+ ARMVectorReg zarray[ARM_MAX_VQ * 16];
46
#endif
47
48
#if defined(CONFIG_USER_ONLY)
49
diff --git a/target/arm/machine.c b/target/arm/machine.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/machine.c
52
+++ b/target/arm/machine.c
53
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_sve = {
54
VMSTATE_END_OF_LIST()
55
}
56
};
57
+
58
+static const VMStateDescription vmstate_vreg = {
59
+ .name = "vreg",
60
+ .version_id = 1,
61
+ .minimum_version_id = 1,
62
+ .fields = (VMStateField[]) {
63
+ VMSTATE_UINT64_ARRAY(d, ARMVectorReg, ARM_MAX_VQ * 2),
64
+ VMSTATE_END_OF_LIST()
65
+ }
66
+};
67
+
68
+static bool za_needed(void *opaque)
69
+{
70
+ ARMCPU *cpu = opaque;
71
+
72
+ /*
73
+ * When ZA storage is disabled, its contents are discarded.
74
+ * It will be zeroed when ZA storage is re-enabled.
75
+ */
76
+ return FIELD_EX64(cpu->env.svcr, SVCR, ZA);
77
+}
78
+
79
+static const VMStateDescription vmstate_za = {
80
+ .name = "cpu/sme",
81
+ .version_id = 1,
82
+ .minimum_version_id = 1,
83
+ .needed = za_needed,
84
+ .fields = (VMStateField[]) {
85
+ VMSTATE_STRUCT_ARRAY(env.zarray, ARMCPU, ARM_MAX_VQ * 16, 0,
86
+ vmstate_vreg, ARMVectorReg),
87
+ VMSTATE_END_OF_LIST()
88
+ }
89
+};
90
#endif /* AARCH64 */
91
92
static bool serror_needed(void *opaque)
93
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_arm_cpu = {
94
&vmstate_m_security,
95
#ifdef TARGET_AARCH64
96
&vmstate_sve,
97
+ &vmstate_za,
98
#endif
99
&vmstate_serror,
100
&vmstate_irq_line_state,
101
--
102
2.25.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Keith Packard <keithp@keithp.com>
2
2
3
Keep all of the error messages together. This does mean that
3
The documentation says the vector is at 0xffffff80, instead of the
4
when setting many sve length properties we'll only generate
4
previous value of 0xffffffc0. That value must have been a bug because
5
one error, but we only really need one.
5
the standard vector values (20, 21, 23, 25, 30) were all
6
past the end of the array.
6
7
8
Signed-off-by: Keith Packard <keithp@keithp.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220620175235.60881-12-richard.henderson@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/arm/cpu64.c | 15 +++++++--------
12
target/rx/helper.c | 2 +-
13
1 file changed, 7 insertions(+), 8 deletions(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
14
15
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
15
diff --git a/target/rx/helper.c b/target/rx/helper.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu64.c
17
--- a/target/rx/helper.c
18
+++ b/target/arm/cpu64.c
18
+++ b/target/rx/helper.c
19
@@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
19
@@ -XXX,XX +XXX,XX @@ void rx_cpu_do_interrupt(CPUState *cs)
20
"using only sve<N> properties.\n");
20
cpu_stl_data(env, env->isp, env->pc);
21
} else {
21
22
error_setg(errp, "cannot enable sve%d", vq * 128);
22
if (vec < 0x100) {
23
- error_append_hint(errp, "This CPU does not support "
23
- env->pc = cpu_ldl_data(env, 0xffffffc0 + vec * 4);
24
- "the vector length %d-bits.\n", vq * 128);
24
+ env->pc = cpu_ldl_data(env, 0xffffff80 + vec * 4);
25
+ if (vq_supported) {
26
+ error_append_hint(errp, "This CPU does not support "
27
+ "the vector length %d-bits.\n", vq * 128);
28
+ } else {
29
+ error_append_hint(errp, "SVE not supported by KVM "
30
+ "on this host\n");
31
+ }
32
}
33
return;
34
} else {
25
} else {
35
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve_vq(Object *obj, Visitor *v, const char *name,
26
env->pc = cpu_ldl_data(env, env->intb + (vec & 0xff) * 4);
36
return;
27
}
37
}
38
39
- if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
40
- error_setg(errp, "cannot enable %s", name);
41
- error_append_hint(errp, "SVE not supported by KVM on this host\n");
42
- return;
43
- }
44
-
45
cpu->sve_vq_map = deposit32(cpu->sve_vq_map, vq - 1, 1, value);
46
cpu->sve_vq_init |= 1 << (vq - 1);
47
}
48
--
28
--
49
2.25.1
29
2.43.0
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Keith Packard <keithp@keithp.com>
2
2
3
In machvirt_init we create a cpu but do not fully initialize it.
3
Functions which modify TCG globals must not be marked TCG_CALL_NO_WG,
4
Thus the propagation of V7VE to LPAE has not been done, and we
4
as that tells the optimizer that TCG global values already loaded in
5
compute the wrong value for some v7 cpus, e.g. cortex-a15.
5
machine registers are still valid, and so any changes which these
6
helpers make to the CPU state may be ignored.
6
7
7
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1078
8
The target/rx code chooses to put (among other things) all the PSW
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
bits and also ACC into globals, so the NO_WG flag on various
9
Reported-by: He Zhe <zhe.he@windriver.com>
10
functions that touch the PSW or ACC is incorrect and must be removed.
10
Message-id: 20220619001541.131672-3-richard.henderson@linaro.org
11
This includes all the floating point helper functions, because
12
update_fpsw() will update PSW Z and S.
13
14
Signed-off-by: Keith Packard <keithp@keithp.com>
15
[PMM: Clarified commit message]
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
18
---
14
target/arm/ptw.c | 8 +++++++-
19
target/rx/helper.h | 34 +++++++++++++++++-----------------
15
1 file changed, 7 insertions(+), 1 deletion(-)
20
1 file changed, 17 insertions(+), 17 deletions(-)
16
21
17
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
22
diff --git a/target/rx/helper.h b/target/rx/helper.h
18
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/ptw.c
24
--- a/target/rx/helper.h
20
+++ b/target/arm/ptw.c
25
+++ b/target/rx/helper.h
21
@@ -XXX,XX +XXX,XX @@ unsigned int arm_pamax(ARMCPU *cpu)
26
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(raise_privilege_violation, noreturn, env)
22
assert(parange < ARRAY_SIZE(pamax_map));
27
DEF_HELPER_1(wait, noreturn, env)
23
return pamax_map[parange];
28
DEF_HELPER_2(rxint, noreturn, env, i32)
24
}
29
DEF_HELPER_1(rxbrk, noreturn, env)
25
- if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) {
30
-DEF_HELPER_FLAGS_3(fadd, TCG_CALL_NO_WG, f32, env, f32, f32)
26
+
31
-DEF_HELPER_FLAGS_3(fsub, TCG_CALL_NO_WG, f32, env, f32, f32)
27
+ /*
32
-DEF_HELPER_FLAGS_3(fmul, TCG_CALL_NO_WG, f32, env, f32, f32)
28
+ * In machvirt_init, we call arm_pamax on a cpu that is not fully
33
-DEF_HELPER_FLAGS_3(fdiv, TCG_CALL_NO_WG, f32, env, f32, f32)
29
+ * initialized, so we can't rely on the propagation done in realize.
34
-DEF_HELPER_FLAGS_3(fcmp, TCG_CALL_NO_WG, void, env, f32, f32)
30
+ */
35
-DEF_HELPER_FLAGS_2(ftoi, TCG_CALL_NO_WG, i32, env, f32)
31
+ if (arm_feature(&cpu->env, ARM_FEATURE_LPAE) ||
36
-DEF_HELPER_FLAGS_2(round, TCG_CALL_NO_WG, i32, env, f32)
32
+ arm_feature(&cpu->env, ARM_FEATURE_V7VE)) {
37
-DEF_HELPER_FLAGS_2(itof, TCG_CALL_NO_WG, f32, env, i32)
33
/* v7 with LPAE */
38
+DEF_HELPER_3(fadd, f32, env, f32, f32)
34
return 40;
39
+DEF_HELPER_3(fsub, f32, env, f32, f32)
35
}
40
+DEF_HELPER_3(fmul, f32, env, f32, f32)
41
+DEF_HELPER_3(fdiv, f32, env, f32, f32)
42
+DEF_HELPER_3(fcmp, void, env, f32, f32)
43
+DEF_HELPER_2(ftoi, i32, env, f32)
44
+DEF_HELPER_2(round, i32, env, f32)
45
+DEF_HELPER_2(itof, f32, env, i32)
46
DEF_HELPER_2(set_fpsw, void, env, i32)
47
-DEF_HELPER_FLAGS_2(racw, TCG_CALL_NO_WG, void, env, i32)
48
-DEF_HELPER_FLAGS_2(set_psw_rte, TCG_CALL_NO_WG, void, env, i32)
49
-DEF_HELPER_FLAGS_2(set_psw, TCG_CALL_NO_WG, void, env, i32)
50
+DEF_HELPER_2(racw, void, env, i32)
51
+DEF_HELPER_2(set_psw_rte, void, env, i32)
52
+DEF_HELPER_2(set_psw, void, env, i32)
53
DEF_HELPER_1(pack_psw, i32, env)
54
-DEF_HELPER_FLAGS_3(div, TCG_CALL_NO_WG, i32, env, i32, i32)
55
-DEF_HELPER_FLAGS_3(divu, TCG_CALL_NO_WG, i32, env, i32, i32)
56
-DEF_HELPER_FLAGS_1(scmpu, TCG_CALL_NO_WG, void, env)
57
+DEF_HELPER_3(div, i32, env, i32, i32)
58
+DEF_HELPER_3(divu, i32, env, i32, i32)
59
+DEF_HELPER_1(scmpu, void, env)
60
DEF_HELPER_1(smovu, void, env)
61
DEF_HELPER_1(smovf, void, env)
62
DEF_HELPER_1(smovb, void, env)
63
DEF_HELPER_2(sstr, void, env, i32)
64
-DEF_HELPER_FLAGS_2(swhile, TCG_CALL_NO_WG, void, env, i32)
65
-DEF_HELPER_FLAGS_2(suntil, TCG_CALL_NO_WG, void, env, i32)
66
-DEF_HELPER_FLAGS_2(rmpa, TCG_CALL_NO_WG, void, env, i32)
67
+DEF_HELPER_2(swhile, void, env, i32)
68
+DEF_HELPER_2(suntil, void, env, i32)
69
+DEF_HELPER_2(rmpa, void, env, i32)
70
DEF_HELPER_1(satr, void, env)
36
--
71
--
37
2.25.1
72
2.43.0
diff view generated by jsdifflib