1
Small pile of bug fixes for rc1. I've included my patches to get
1
The following changes since commit bf4460a8d9a86f6cfe05d7a7f470c48e3a93d8b2:
2
our docs building with Sphinx 3, just for convenience...
3
2
4
-- PMM
3
Merge tag 'pull-tcg-20230123' of https://gitlab.com/rth7680/qemu into staging (2023-02-03 09:30:45 +0000)
5
6
The following changes since commit b149dea55cce97cb226683d06af61984a1c11e96:
7
8
Merge remote-tracking branch 'remotes/cschoenebeck/tags/pull-9p-20201102' into staging (2020-11-02 10:57:48 +0000)
9
4
10
are available in the Git repository at:
5
are available in the Git repository at:
11
6
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20201102
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230203
13
8
14
for you to fetch changes up to ffb4fbf90a2f63c9cb33e4bb9f854c79bf04ca4a:
9
for you to fetch changes up to bb18151d8bd9bedc497ee9d4e8d81b39a4e5bbf6:
15
10
16
tests/qtest/npcm7xx_rng-test: Disable randomness tests (2020-11-02 16:52:18 +0000)
11
target/arm: Enable FEAT_FGT on '-cpu max' (2023-02-03 12:59:24 +0000)
17
12
18
----------------------------------------------------------------
13
----------------------------------------------------------------
19
target-arm queue:
14
target-arm queue:
20
* target/arm: Fix Neon emulation bugs on big-endian hosts
15
* Fix physical address resolution for Stage2
21
* target/arm: fix handling of HCR.FB
16
* pl011: refactoring, implement reset method
22
* target/arm: fix LORID_EL1 access check
17
* Support GICv3 with hvf acceleration
23
* disas/capstone: Fix monitor disassembly of >32 bytes
18
* sbsa-ref: remove cortex-a76 from list of supported cpus
24
* hw/arm/smmuv3: Fix potential integer overflow (CID 1432363)
19
* Correct syndrome for ATS12NSO* traps at Secure EL1
25
* hw/arm/boot: fix SVE for EL3 direct kernel boot
20
* Fix priority of HSTR_EL2 traps vs UNDEFs
26
* hw/display/omap_lcdc: Fix potential NULL pointer dereference
21
* Implement FEAT_FGT for '-cpu max'
27
* hw/display/exynos4210_fimd: Fix potential NULL pointer dereference
28
* target/arm: Get correct MMU index for other-security-state
29
* configure: Test that gio libs from pkg-config work
30
* hw/intc/arm_gicv3_cpuif: Make GIC maintenance interrupts work
31
* docs: Fix building with Sphinx 3
32
* tests/qtest/npcm7xx_rng-test: Disable randomness tests
33
22
34
----------------------------------------------------------------
23
----------------------------------------------------------------
35
AlexChen (2):
24
Alexander Graf (3):
36
hw/display/omap_lcdc: Fix potential NULL pointer dereference
25
hvf: arm: Add support for GICv3
37
hw/display/exynos4210_fimd: Fix potential NULL pointer dereference
26
hw/arm/virt: Consolidate GIC finalize logic
27
hw/arm/virt: Make accels in GIC finalize logic explicit
38
28
39
Peter Maydell (9):
29
Evgeny Iakovlev (4):
40
target/arm: Fix float16 pairwise Neon ops on big-endian hosts
30
hw/char/pl011: refactor FIFO depth handling code
41
target/arm: Fix VUDOT/VSDOT (scalar) on big-endian hosts
31
hw/char/pl011: add post_load hook for backwards-compatibility
42
disas/capstone: Fix monitor disassembly of >32 bytes
32
hw/char/pl011: implement a reset method
43
target/arm: Get correct MMU index for other-security-state
33
hw/char/pl011: better handling of FIFO flags on LCR reset
44
configure: Test that gio libs from pkg-config work
45
hw/intc/arm_gicv3_cpuif: Make GIC maintenance interrupts work
46
scripts/kerneldoc: For Sphinx 3 use c:macro for macros with arguments
47
qemu-option-trace.rst.inc: Don't use option:: markup
48
tests/qtest/npcm7xx_rng-test: Disable randomness tests
49
34
50
Philippe Mathieu-Daudé (1):
35
Marcin Juszkiewicz (1):
51
hw/arm/smmuv3: Fix potential integer overflow (CID 1432363)
36
sbsa-ref: remove cortex-a76 from list of supported cpus
52
37
53
Richard Henderson (11):
38
Peter Maydell (23):
54
target/arm: Introduce neon_full_reg_offset
39
target/arm: Name AT_S1E1RP and AT_S1E1WP cpregs correctly
55
target/arm: Move neon_element_offset to translate.c
40
target/arm: Correct syndrome for ATS12NSO* at Secure EL1
56
target/arm: Use neon_element_offset in neon_load/store_reg
41
target/arm: Remove CP_ACCESS_TRAP_UNCATEGORIZED_{EL2, EL3}
57
target/arm: Use neon_element_offset in vfp_reg_offset
42
target/arm: Move do_coproc_insn() syndrome calculation earlier
58
target/arm: Add read/write_neon_element32
43
target/arm: All UNDEF-at-EL0 traps take priority over HSTR_EL2 traps
59
target/arm: Expand read/write_neon_element32 to all MemOp
44
target/arm: Make HSTR_EL2 traps take priority over UNDEF-at-EL1
60
target/arm: Rename neon_load_reg32 to vfp_load_reg32
45
target/arm: Disable HSTR_EL2 traps if EL2 is not enabled
61
target/arm: Add read/write_neon_element64
46
target/arm: Define the FEAT_FGT registers
62
target/arm: Rename neon_load_reg64 to vfp_load_reg64
47
target/arm: Implement FGT trapping infrastructure
63
target/arm: Simplify do_long_3d and do_2scalar_long
48
target/arm: Mark up sysregs for HFGRTR bits 0..11
64
target/arm: Improve do_prewiden_3d
49
target/arm: Mark up sysregs for HFGRTR bits 12..23
50
target/arm: Mark up sysregs for HFGRTR bits 24..35
51
target/arm: Mark up sysregs for HFGRTR bits 36..63
52
target/arm: Mark up sysregs for HDFGRTR bits 0..11
53
target/arm: Mark up sysregs for HDFGRTR bits 12..63
54
target/arm: Mark up sysregs for HFGITR bits 0..11
55
target/arm: Mark up sysregs for HFGITR bits 12..17
56
target/arm: Mark up sysregs for HFGITR bits 18..47
57
target/arm: Mark up sysregs for HFGITR bits 48..63
58
target/arm: Implement the HFGITR_EL2.ERET trap
59
target/arm: Implement the HFGITR_EL2.SVC_EL0 and SVC_EL1 traps
60
target/arm: Implement MDCR_EL2.TDCC and MDCR_EL3.TDCC traps
61
target/arm: Enable FEAT_FGT on '-cpu max'
65
62
66
Rémi Denis-Courmont (3):
63
Richard Henderson (2):
67
target/arm: fix handling of HCR.FB
64
hw/arm: Use TYPE_ARM_SMMUV3
68
target/arm: fix LORID_EL1 access check
65
target/arm: Fix physical address resolution for Stage2
69
hw/arm/boot: fix SVE for EL3 direct kernel boot
70
66
71
docs/qemu-option-trace.rst.inc | 6 +-
67
docs/system/arm/emulation.rst | 1 +
72
configure | 10 +-
68
include/hw/arm/virt.h | 15 +-
73
include/hw/intc/arm_gicv3_common.h | 1 -
69
include/hw/char/pl011.h | 5 +-
74
disas/capstone.c | 2 +-
70
target/arm/cpregs.h | 484 +++++++++++++++++++++++++++++++++++++++++-
75
hw/arm/boot.c | 3 +
71
target/arm/cpu.h | 18 ++
76
hw/arm/smmuv3.c | 3 +-
72
target/arm/internals.h | 20 ++
77
hw/display/exynos4210_fimd.c | 4 +-
73
target/arm/syndrome.h | 10 +
78
hw/display/omap_lcdc.c | 10 +-
74
target/arm/translate.h | 6 +
79
hw/intc/arm_gicv3_cpuif.c | 5 +-
75
hw/arm/sbsa-ref.c | 4 +-
80
target/arm/helper.c | 24 +-
76
hw/arm/virt.c | 203 +++++++++---------
81
target/arm/m_helper.c | 3 +-
77
hw/char/pl011.c | 93 ++++++--
82
target/arm/translate.c | 153 +++++++++---
78
hw/intc/arm_gicv3_cpuif.c | 18 +-
83
target/arm/vec_helper.c | 12 +-
79
target/arm/cpu64.c | 1 +
84
tests/qtest/npcm7xx_rng-test.c | 14 +-
80
target/arm/debug_helper.c | 46 +++-
85
scripts/kernel-doc | 18 +-
81
target/arm/helper.c | 245 ++++++++++++++++++++-
86
target/arm/translate-neon.c.inc | 472 ++++++++++++++++++++-----------------
82
target/arm/hvf/hvf.c | 151 +++++++++++++
87
target/arm/translate-vfp.c.inc | 341 +++++++++++----------------
83
target/arm/op_helper.c | 58 ++++-
88
17 files changed, 588 insertions(+), 493 deletions(-)
84
target/arm/ptw.c | 2 +-
89
85
target/arm/translate-a64.c | 22 +-
86
target/arm/translate.c | 125 +++++++----
87
target/arm/hvf/trace-events | 2 +
88
21 files changed, 1340 insertions(+), 189 deletions(-)
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
In both cases, we can sink the write-back and perform
3
Use the macro instead of two explicit string literals.
4
the accumulate into the normal destination temps.
5
4
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20201030022618.785675-11-richard.henderson@linaro.org
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Message-id: 20230124232059.4017615-1-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
target/arm/translate-neon.c.inc | 23 +++++++++--------------
11
hw/arm/sbsa-ref.c | 3 ++-
12
1 file changed, 9 insertions(+), 14 deletions(-)
12
hw/arm/virt.c | 2 +-
13
2 files changed, 3 insertions(+), 2 deletions(-)
13
14
14
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-neon.c.inc
17
--- a/hw/arm/sbsa-ref.c
17
+++ b/target/arm/translate-neon.c.inc
18
+++ b/hw/arm/sbsa-ref.c
18
@@ -XXX,XX +XXX,XX @@ static bool do_long_3d(DisasContext *s, arg_3diff *a,
19
@@ -XXX,XX +XXX,XX @@
19
if (accfn) {
20
#include "exec/hwaddr.h"
20
tmp = tcg_temp_new_i64();
21
#include "kvm_arm.h"
21
read_neon_element64(tmp, a->vd, 0, MO_64);
22
#include "hw/arm/boot.h"
22
- accfn(tmp, tmp, rd0);
23
+#include "hw/arm/smmuv3.h"
23
- write_neon_element64(tmp, a->vd, 0, MO_64);
24
#include "hw/block/flash.h"
24
+ accfn(rd0, tmp, rd0);
25
#include "hw/boards.h"
25
read_neon_element64(tmp, a->vd, 1, MO_64);
26
#include "hw/ide/internal.h"
26
- accfn(tmp, tmp, rd1);
27
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const SBSAMachineState *sms, PCIBus *bus)
27
- write_neon_element64(tmp, a->vd, 1, MO_64);
28
DeviceState *dev;
28
+ accfn(rd1, tmp, rd1);
29
int i;
29
tcg_temp_free_i64(tmp);
30
30
- } else {
31
- dev = qdev_new("arm-smmuv3");
31
- write_neon_element64(rd0, a->vd, 0, MO_64);
32
+ dev = qdev_new(TYPE_ARM_SMMUV3);
32
- write_neon_element64(rd1, a->vd, 1, MO_64);
33
34
object_property_set_link(OBJECT(dev), "primary-bus", OBJECT(bus),
35
&error_abort);
36
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/arm/virt.c
39
+++ b/hw/arm/virt.c
40
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const VirtMachineState *vms,
41
return;
33
}
42
}
34
43
35
+ write_neon_element64(rd0, a->vd, 0, MO_64);
44
- dev = qdev_new("arm-smmuv3");
36
+ write_neon_element64(rd1, a->vd, 1, MO_64);
45
+ dev = qdev_new(TYPE_ARM_SMMUV3);
37
tcg_temp_free_i64(rd0);
46
38
tcg_temp_free_i64(rd1);
47
object_property_set_link(OBJECT(dev), "primary-bus", OBJECT(bus),
39
48
&error_abort);
40
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_long(DisasContext *s, arg_2scalar *a,
41
if (accfn) {
42
TCGv_i64 t64 = tcg_temp_new_i64();
43
read_neon_element64(t64, a->vd, 0, MO_64);
44
- accfn(t64, t64, rn0_64);
45
- write_neon_element64(t64, a->vd, 0, MO_64);
46
+ accfn(rn0_64, t64, rn0_64);
47
read_neon_element64(t64, a->vd, 1, MO_64);
48
- accfn(t64, t64, rn1_64);
49
- write_neon_element64(t64, a->vd, 1, MO_64);
50
+ accfn(rn1_64, t64, rn1_64);
51
tcg_temp_free_i64(t64);
52
- } else {
53
- write_neon_element64(rn0_64, a->vd, 0, MO_64);
54
- write_neon_element64(rn1_64, a->vd, 1, MO_64);
55
}
56
+
57
+ write_neon_element64(rn0_64, a->vd, 0, MO_64);
58
+ write_neon_element64(rn1_64, a->vd, 1, MO_64);
59
tcg_temp_free_i64(rn0_64);
60
tcg_temp_free_i64(rn1_64);
61
return true;
62
--
49
--
63
2.20.1
50
2.34.1
64
51
65
52
diff view generated by jsdifflib
1
If we're using the capstone disassembler, disassembly of a run of
1
From: Richard Henderson <richard.henderson@linaro.org>
2
instructions more than 32 bytes long disassembles the wrong data for
3
instructions beyond the 32 byte mark:
4
2
5
(qemu) xp /16x 0x100
3
Conversion to probe_access_full missed applying the page offset.
6
0000000000000100: 0x00000005 0x54410001 0x00000001 0x00001000
7
0000000000000110: 0x00000000 0x00000004 0x54410002 0x3c000000
8
0000000000000120: 0x00000000 0x00000004 0x54410009 0x74736574
9
0000000000000130: 0x00000000 0x00000000 0x00000000 0x00000000
10
(qemu) xp /16i 0x100
11
0x00000100: 00000005 andeq r0, r0, r5
12
0x00000104: 54410001 strbpl r0, [r1], #-1
13
0x00000108: 00000001 andeq r0, r0, r1
14
0x0000010c: 00001000 andeq r1, r0, r0
15
0x00000110: 00000000 andeq r0, r0, r0
16
0x00000114: 00000004 andeq r0, r0, r4
17
0x00000118: 54410002 strbpl r0, [r1], #-2
18
0x0000011c: 3c000000 .byte 0x00, 0x00, 0x00, 0x3c
19
0x00000120: 54410001 strbpl r0, [r1], #-1
20
0x00000124: 00000001 andeq r0, r0, r1
21
0x00000128: 00001000 andeq r1, r0, r0
22
0x0000012c: 00000000 andeq r0, r0, r0
23
0x00000130: 00000004 andeq r0, r0, r4
24
0x00000134: 54410002 strbpl r0, [r1], #-2
25
0x00000138: 3c000000 .byte 0x00, 0x00, 0x00, 0x3c
26
0x0000013c: 00000000 andeq r0, r0, r0
27
28
Here the disassembly of 0x120..0x13f is using the data that is in
29
0x104..0x123.
30
31
This is caused by passing the wrong value to the read_memory_func().
32
The intention is that at this point in the loop the 'cap_buf' buffer
33
already contains 'csize' bytes of data for the instruction at guest
34
addr 'pc', and we want to read in an extra 'tsize' bytes. Those
35
extra bytes are therefore at 'pc + csize', not 'pc'. On the first
36
time through the loop 'csize' happens to be zero, so the initial read
37
of 32 bytes into cap_buf is correct and as long as the disassembly
38
never needs to read more data we return the correct information.
39
40
Use the correct guest address in the call to read_memory_func().
41
4
42
Cc: qemu-stable@nongnu.org
5
Cc: qemu-stable@nongnu.org
43
Fixes: https://bugs.launchpad.net/qemu/+bug/1900779
6
Reported-by: Sid Manning <sidneym@quicinc.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 20230126233134.103193-1-richard.henderson@linaro.org
10
Fixes: f3639a64f602 ("target/arm: Use softmmu tlbs for page table walking")
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
44
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
45
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
46
Message-id: 20201022132445.25039-1-peter.maydell@linaro.org
47
---
13
---
48
disas/capstone.c | 2 +-
14
target/arm/ptw.c | 2 +-
49
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 1 insertion(+), 1 deletion(-)
50
16
51
diff --git a/disas/capstone.c b/disas/capstone.c
17
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
52
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
53
--- a/disas/capstone.c
19
--- a/target/arm/ptw.c
54
+++ b/disas/capstone.c
20
+++ b/target/arm/ptw.c
55
@@ -XXX,XX +XXX,XX @@ bool cap_disas_monitor(disassemble_info *info, uint64_t pc, int count)
21
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
56
22
if (unlikely(flags & TLB_INVALID_MASK)) {
57
/* Make certain that we can make progress. */
23
goto fail;
58
assert(tsize != 0);
24
}
59
- info->read_memory_func(pc, cap_buf + csize, tsize, info);
25
- ptw->out_phys = full->phys_addr;
60
+ info->read_memory_func(pc + csize, cap_buf + csize, tsize, info);
26
+ ptw->out_phys = full->phys_addr | (addr & ~TARGET_PAGE_MASK);
61
csize += tsize;
27
ptw->out_rw = full->prot & PAGE_WRITE;
62
28
pte_attrs = full->pte_attrs;
63
if (cs_disasm_iter(handle, &cbuf, &csize, &pc, insn)) {
29
pte_secure = full->attrs.secure;
64
--
30
--
65
2.20.1
31
2.34.1
66
32
67
33
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
2
2
3
The only uses of this function are for loading VFP
3
PL011 can be in either of 2 modes depending guest config: FIFO and
4
double-precision values, and nothing to do with NEON.
4
single register. The last mode could be viewed as a 1-element-deep FIFO.
5
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Current code open-codes a bunch of depth-dependent logic. Refactor FIFO
7
Message-id: 20201030022618.785675-10-richard.henderson@linaro.org
7
depth handling code to isolate calculating current FIFO depth.
8
9
One functional (albeit guest-invisible) side-effect of this change is
10
that previously we would always increment s->read_pos in UARTDR read
11
handler even if FIFO was disabled, now we are limiting read_pos to not
12
exceed FIFO depth (read_pos itself is reset to 0 if user disables FIFO).
13
14
Signed-off-by: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
17
Message-id: 20230123162304.26254-2-eiakovlev@linux.microsoft.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
19
---
11
target/arm/translate.c | 8 ++--
20
include/hw/char/pl011.h | 5 ++++-
12
target/arm/translate-vfp.c.inc | 84 +++++++++++++++++-----------------
21
hw/char/pl011.c | 30 ++++++++++++++++++------------
13
2 files changed, 46 insertions(+), 46 deletions(-)
22
2 files changed, 22 insertions(+), 13 deletions(-)
14
23
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
24
diff --git a/include/hw/char/pl011.h b/include/hw/char/pl011.h
16
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.c
26
--- a/include/hw/char/pl011.h
18
+++ b/target/arm/translate.c
27
+++ b/include/hw/char/pl011.h
19
@@ -XXX,XX +XXX,XX @@ static long vfp_reg_offset(bool dp, unsigned reg)
28
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(PL011State, PL011)
29
/* This shares the same struct (and cast macro) as the base pl011 device */
30
#define TYPE_PL011_LUMINARY "pl011_luminary"
31
32
+/* Depth of UART FIFO in bytes, when FIFO mode is enabled (else depth == 1) */
33
+#define PL011_FIFO_DEPTH 16
34
+
35
struct PL011State {
36
SysBusDevice parent_obj;
37
38
@@ -XXX,XX +XXX,XX @@ struct PL011State {
39
uint32_t dmacr;
40
uint32_t int_enabled;
41
uint32_t int_level;
42
- uint32_t read_fifo[16];
43
+ uint32_t read_fifo[PL011_FIFO_DEPTH];
44
uint32_t ilpr;
45
uint32_t ibrd;
46
uint32_t fbrd;
47
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/char/pl011.c
50
+++ b/hw/char/pl011.c
51
@@ -XXX,XX +XXX,XX @@ static void pl011_update(PL011State *s)
20
}
52
}
21
}
53
}
22
54
23
-static inline void neon_load_reg64(TCGv_i64 var, int reg)
55
+static bool pl011_is_fifo_enabled(PL011State *s)
24
+static inline void vfp_load_reg64(TCGv_i64 var, int reg)
56
+{
57
+ return (s->lcr & 0x10) != 0;
58
+}
59
+
60
+static inline unsigned pl011_get_fifo_depth(PL011State *s)
61
+{
62
+ /* Note: FIFO depth is expected to be power-of-2 */
63
+ return pl011_is_fifo_enabled(s) ? PL011_FIFO_DEPTH : 1;
64
+}
65
+
66
static uint64_t pl011_read(void *opaque, hwaddr offset,
67
unsigned size)
25
{
68
{
26
- tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
69
@@ -XXX,XX +XXX,XX @@ static uint64_t pl011_read(void *opaque, hwaddr offset,
27
+ tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(true, reg));
70
c = s->read_fifo[s->read_pos];
71
if (s->read_count > 0) {
72
s->read_count--;
73
- if (++s->read_pos == 16)
74
- s->read_pos = 0;
75
+ s->read_pos = (s->read_pos + 1) & (pl011_get_fifo_depth(s) - 1);
76
}
77
if (s->read_count == 0) {
78
s->flags |= PL011_FLAG_RXFE;
79
@@ -XXX,XX +XXX,XX @@ static int pl011_can_receive(void *opaque)
80
PL011State *s = (PL011State *)opaque;
81
int r;
82
83
- if (s->lcr & 0x10) {
84
- r = s->read_count < 16;
85
- } else {
86
- r = s->read_count < 1;
87
- }
88
+ r = s->read_count < pl011_get_fifo_depth(s);
89
trace_pl011_can_receive(s->lcr, s->read_count, r);
90
return r;
28
}
91
}
29
92
@@ -XXX,XX +XXX,XX @@ static void pl011_put_fifo(void *opaque, uint32_t value)
30
-static inline void neon_store_reg64(TCGv_i64 var, int reg)
31
+static inline void vfp_store_reg64(TCGv_i64 var, int reg)
32
{
93
{
33
- tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
94
PL011State *s = (PL011State *)opaque;
34
+ tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(true, reg));
95
int slot;
35
}
96
+ unsigned pipe_depth;
36
97
37
static inline void vfp_load_reg32(TCGv_i32 var, int reg)
98
- slot = s->read_pos + s->read_count;
38
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
99
- if (slot >= 16)
39
index XXXXXXX..XXXXXXX 100644
100
- slot -= 16;
40
--- a/target/arm/translate-vfp.c.inc
101
+ pipe_depth = pl011_get_fifo_depth(s);
41
+++ b/target/arm/translate-vfp.c.inc
102
+ slot = (s->read_pos + s->read_count) & (pipe_depth - 1);
42
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
103
s->read_fifo[slot] = value;
43
tcg_gen_ext_i32_i64(nf, cpu_NF);
104
s->read_count++;
44
tcg_gen_ext_i32_i64(vf, cpu_VF);
105
s->flags &= ~PL011_FLAG_RXFE;
45
106
trace_pl011_put_fifo(value, s->read_count);
46
- neon_load_reg64(frn, rn);
107
- if (!(s->lcr & 0x10) || s->read_count == 16) {
47
- neon_load_reg64(frm, rm);
108
+ if (s->read_count == pipe_depth) {
48
+ vfp_load_reg64(frn, rn);
109
trace_pl011_put_fifo_full();
49
+ vfp_load_reg64(frm, rm);
110
s->flags |= PL011_FLAG_RXFF;
50
switch (a->cc) {
51
case 0: /* eq: Z */
52
tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
53
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
54
tcg_temp_free_i64(tmp);
55
break;
56
}
57
- neon_store_reg64(dest, rd);
58
+ vfp_store_reg64(dest, rd);
59
tcg_temp_free_i64(frn);
60
tcg_temp_free_i64(frm);
61
tcg_temp_free_i64(dest);
62
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
63
TCGv_i64 tcg_res;
64
tcg_op = tcg_temp_new_i64();
65
tcg_res = tcg_temp_new_i64();
66
- neon_load_reg64(tcg_op, rm);
67
+ vfp_load_reg64(tcg_op, rm);
68
gen_helper_rintd(tcg_res, tcg_op, fpst);
69
- neon_store_reg64(tcg_res, rd);
70
+ vfp_store_reg64(tcg_res, rd);
71
tcg_temp_free_i64(tcg_op);
72
tcg_temp_free_i64(tcg_res);
73
} else {
74
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
75
tcg_double = tcg_temp_new_i64();
76
tcg_res = tcg_temp_new_i64();
77
tcg_tmp = tcg_temp_new_i32();
78
- neon_load_reg64(tcg_double, rm);
79
+ vfp_load_reg64(tcg_double, rm);
80
if (is_signed) {
81
gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
82
} else {
83
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
84
tmp = tcg_temp_new_i64();
85
if (a->l) {
86
gen_aa32_ld64(s, tmp, addr, get_mem_index(s));
87
- neon_store_reg64(tmp, a->vd);
88
+ vfp_store_reg64(tmp, a->vd);
89
} else {
90
- neon_load_reg64(tmp, a->vd);
91
+ vfp_load_reg64(tmp, a->vd);
92
gen_aa32_st64(s, tmp, addr, get_mem_index(s));
93
}
111
}
94
tcg_temp_free_i64(tmp);
112
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pl011 = {
95
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a)
113
VMSTATE_UINT32(dmacr, PL011State),
96
if (a->l) {
114
VMSTATE_UINT32(int_enabled, PL011State),
97
/* load */
115
VMSTATE_UINT32(int_level, PL011State),
98
gen_aa32_ld64(s, tmp, addr, get_mem_index(s));
116
- VMSTATE_UINT32_ARRAY(read_fifo, PL011State, 16),
99
- neon_store_reg64(tmp, a->vd + i);
117
+ VMSTATE_UINT32_ARRAY(read_fifo, PL011State, PL011_FIFO_DEPTH),
100
+ vfp_store_reg64(tmp, a->vd + i);
118
VMSTATE_UINT32(ilpr, PL011State),
101
} else {
119
VMSTATE_UINT32(ibrd, PL011State),
102
/* store */
120
VMSTATE_UINT32(fbrd, PL011State),
103
- neon_load_reg64(tmp, a->vd + i);
104
+ vfp_load_reg64(tmp, a->vd + i);
105
gen_aa32_st64(s, tmp, addr, get_mem_index(s));
106
}
107
tcg_gen_addi_i32(addr, addr, offset);
108
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
109
fd = tcg_temp_new_i64();
110
fpst = fpstatus_ptr(FPST_FPCR);
111
112
- neon_load_reg64(f0, vn);
113
- neon_load_reg64(f1, vm);
114
+ vfp_load_reg64(f0, vn);
115
+ vfp_load_reg64(f1, vm);
116
117
for (;;) {
118
if (reads_vd) {
119
- neon_load_reg64(fd, vd);
120
+ vfp_load_reg64(fd, vd);
121
}
122
fn(fd, f0, f1, fpst);
123
- neon_store_reg64(fd, vd);
124
+ vfp_store_reg64(fd, vd);
125
126
if (veclen == 0) {
127
break;
128
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
129
veclen--;
130
vd = vfp_advance_dreg(vd, delta_d);
131
vn = vfp_advance_dreg(vn, delta_d);
132
- neon_load_reg64(f0, vn);
133
+ vfp_load_reg64(f0, vn);
134
if (delta_m) {
135
vm = vfp_advance_dreg(vm, delta_m);
136
- neon_load_reg64(f1, vm);
137
+ vfp_load_reg64(f1, vm);
138
}
139
}
140
141
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
142
f0 = tcg_temp_new_i64();
143
fd = tcg_temp_new_i64();
144
145
- neon_load_reg64(f0, vm);
146
+ vfp_load_reg64(f0, vm);
147
148
for (;;) {
149
fn(fd, f0);
150
- neon_store_reg64(fd, vd);
151
+ vfp_store_reg64(fd, vd);
152
153
if (veclen == 0) {
154
break;
155
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
156
/* single source one-many */
157
while (veclen--) {
158
vd = vfp_advance_dreg(vd, delta_d);
159
- neon_store_reg64(fd, vd);
160
+ vfp_store_reg64(fd, vd);
161
}
162
break;
163
}
164
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
165
veclen--;
166
vd = vfp_advance_dreg(vd, delta_d);
167
vd = vfp_advance_dreg(vm, delta_m);
168
- neon_load_reg64(f0, vm);
169
+ vfp_load_reg64(f0, vm);
170
}
171
172
tcg_temp_free_i64(f0);
173
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_dp(DisasContext *s, arg_VFMA_dp *a, bool neg_n, bool neg_d)
174
vm = tcg_temp_new_i64();
175
vd = tcg_temp_new_i64();
176
177
- neon_load_reg64(vn, a->vn);
178
- neon_load_reg64(vm, a->vm);
179
+ vfp_load_reg64(vn, a->vn);
180
+ vfp_load_reg64(vm, a->vm);
181
if (neg_n) {
182
/* VFNMS, VFMS */
183
gen_helper_vfp_negd(vn, vn);
184
}
185
- neon_load_reg64(vd, a->vd);
186
+ vfp_load_reg64(vd, a->vd);
187
if (neg_d) {
188
/* VFNMA, VFNMS */
189
gen_helper_vfp_negd(vd, vd);
190
}
191
fpst = fpstatus_ptr(FPST_FPCR);
192
gen_helper_vfp_muladdd(vd, vn, vm, vd, fpst);
193
- neon_store_reg64(vd, a->vd);
194
+ vfp_store_reg64(vd, a->vd);
195
196
tcg_temp_free_ptr(fpst);
197
tcg_temp_free_i64(vn);
198
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
199
fd = tcg_const_i64(vfp_expand_imm(MO_64, a->imm));
200
201
for (;;) {
202
- neon_store_reg64(fd, vd);
203
+ vfp_store_reg64(fd, vd);
204
205
if (veclen == 0) {
206
break;
207
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
208
vd = tcg_temp_new_i64();
209
vm = tcg_temp_new_i64();
210
211
- neon_load_reg64(vd, a->vd);
212
+ vfp_load_reg64(vd, a->vd);
213
if (a->z) {
214
tcg_gen_movi_i64(vm, 0);
215
} else {
216
- neon_load_reg64(vm, a->vm);
217
+ vfp_load_reg64(vm, a->vm);
218
}
219
220
if (a->e) {
221
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
222
tcg_gen_ld16u_i32(tmp, cpu_env, vfp_f16_offset(a->vm, a->t));
223
vd = tcg_temp_new_i64();
224
gen_helper_vfp_fcvt_f16_to_f64(vd, tmp, fpst, ahp_mode);
225
- neon_store_reg64(vd, a->vd);
226
+ vfp_store_reg64(vd, a->vd);
227
tcg_temp_free_i32(ahp_mode);
228
tcg_temp_free_ptr(fpst);
229
tcg_temp_free_i32(tmp);
230
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
231
tmp = tcg_temp_new_i32();
232
vm = tcg_temp_new_i64();
233
234
- neon_load_reg64(vm, a->vm);
235
+ vfp_load_reg64(vm, a->vm);
236
gen_helper_vfp_fcvt_f64_to_f16(tmp, vm, fpst, ahp_mode);
237
tcg_temp_free_i64(vm);
238
tcg_gen_st16_i32(tmp, cpu_env, vfp_f16_offset(a->vd, a->t));
239
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
240
}
241
242
tmp = tcg_temp_new_i64();
243
- neon_load_reg64(tmp, a->vm);
244
+ vfp_load_reg64(tmp, a->vm);
245
fpst = fpstatus_ptr(FPST_FPCR);
246
gen_helper_rintd(tmp, tmp, fpst);
247
- neon_store_reg64(tmp, a->vd);
248
+ vfp_store_reg64(tmp, a->vd);
249
tcg_temp_free_ptr(fpst);
250
tcg_temp_free_i64(tmp);
251
return true;
252
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
253
}
254
255
tmp = tcg_temp_new_i64();
256
- neon_load_reg64(tmp, a->vm);
257
+ vfp_load_reg64(tmp, a->vm);
258
fpst = fpstatus_ptr(FPST_FPCR);
259
tcg_rmode = tcg_const_i32(float_round_to_zero);
260
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
261
gen_helper_rintd(tmp, tmp, fpst);
262
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
263
- neon_store_reg64(tmp, a->vd);
264
+ vfp_store_reg64(tmp, a->vd);
265
tcg_temp_free_ptr(fpst);
266
tcg_temp_free_i64(tmp);
267
tcg_temp_free_i32(tcg_rmode);
268
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
269
}
270
271
tmp = tcg_temp_new_i64();
272
- neon_load_reg64(tmp, a->vm);
273
+ vfp_load_reg64(tmp, a->vm);
274
fpst = fpstatus_ptr(FPST_FPCR);
275
gen_helper_rintd_exact(tmp, tmp, fpst);
276
- neon_store_reg64(tmp, a->vd);
277
+ vfp_store_reg64(tmp, a->vd);
278
tcg_temp_free_ptr(fpst);
279
tcg_temp_free_i64(tmp);
280
return true;
281
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
282
vd = tcg_temp_new_i64();
283
vfp_load_reg32(vm, a->vm);
284
gen_helper_vfp_fcvtds(vd, vm, cpu_env);
285
- neon_store_reg64(vd, a->vd);
286
+ vfp_store_reg64(vd, a->vd);
287
tcg_temp_free_i32(vm);
288
tcg_temp_free_i64(vd);
289
return true;
290
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
291
292
vd = tcg_temp_new_i32();
293
vm = tcg_temp_new_i64();
294
- neon_load_reg64(vm, a->vm);
295
+ vfp_load_reg64(vm, a->vm);
296
gen_helper_vfp_fcvtsd(vd, vm, cpu_env);
297
vfp_store_reg32(vd, a->vd);
298
tcg_temp_free_i32(vd);
299
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
300
/* u32 -> f64 */
301
gen_helper_vfp_uitod(vd, vm, fpst);
302
}
303
- neon_store_reg64(vd, a->vd);
304
+ vfp_store_reg64(vd, a->vd);
305
tcg_temp_free_i32(vm);
306
tcg_temp_free_i64(vd);
307
tcg_temp_free_ptr(fpst);
308
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
309
310
vm = tcg_temp_new_i64();
311
vd = tcg_temp_new_i32();
312
- neon_load_reg64(vm, a->vm);
313
+ vfp_load_reg64(vm, a->vm);
314
gen_helper_vjcvt(vd, vm, cpu_env);
315
vfp_store_reg32(vd, a->vd);
316
tcg_temp_free_i64(vm);
317
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
318
frac_bits = (a->opc & 1) ? (32 - a->imm) : (16 - a->imm);
319
320
vd = tcg_temp_new_i64();
321
- neon_load_reg64(vd, a->vd);
322
+ vfp_load_reg64(vd, a->vd);
323
324
fpst = fpstatus_ptr(FPST_FPCR);
325
shift = tcg_const_i32(frac_bits);
326
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
327
g_assert_not_reached();
328
}
329
330
- neon_store_reg64(vd, a->vd);
331
+ vfp_store_reg64(vd, a->vd);
332
tcg_temp_free_i64(vd);
333
tcg_temp_free_i32(shift);
334
tcg_temp_free_ptr(fpst);
335
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
336
fpst = fpstatus_ptr(FPST_FPCR);
337
vm = tcg_temp_new_i64();
338
vd = tcg_temp_new_i32();
339
- neon_load_reg64(vm, a->vm);
340
+ vfp_load_reg64(vm, a->vm);
341
342
if (a->s) {
343
if (a->rz) {
344
--
121
--
345
2.20.1
122
2.34.1
346
123
347
124
diff view generated by jsdifflib
1
From: AlexChen <alex.chen@huawei.com>
1
From: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
2
2
3
In exynos4210_fimd_update(), the pointer s is dereferinced before
3
Previous change slightly modified the way we handle data writes when
4
being check if it is valid, which may lead to NULL pointer dereference.
4
FIFO is disabled. Previously we kept incrementing read_pos and were
5
So move the assignment to global_width after checking that the s is valid.
5
storing data at that position, although we only have a
6
single-register-deep FIFO now. Then we changed it to always store data
7
at pos 0.
6
8
7
Reported-by: Euler Robot <euler.robot@huawei.com>
9
If guest disables FIFO and the proceeds to read data, it will work out
8
Signed-off-by: Alex Chen <alex.chen@huawei.com>
10
fine, because we still read from current read_pos before setting it to
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
0.
10
Message-id: 5F9F8D88.9030102@huawei.com
12
13
However, to make code less fragile, introduce a post_load hook for
14
PL011State and move fixup read FIFO state when FIFO is disabled. Since
15
we are introducing a post_load hook, also do some sanity checking on
16
untrusted incoming input state.
17
18
Signed-off-by: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
19
Message-id: 20230123162304.26254-3-eiakovlev@linux.microsoft.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
21
---
13
hw/display/exynos4210_fimd.c | 4 +++-
22
hw/char/pl011.c | 25 +++++++++++++++++++++++++
14
1 file changed, 3 insertions(+), 1 deletion(-)
23
1 file changed, 25 insertions(+)
15
24
16
diff --git a/hw/display/exynos4210_fimd.c b/hw/display/exynos4210_fimd.c
25
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
17
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/display/exynos4210_fimd.c
27
--- a/hw/char/pl011.c
19
+++ b/hw/display/exynos4210_fimd.c
28
+++ b/hw/char/pl011.c
20
@@ -XXX,XX +XXX,XX @@ static void exynos4210_fimd_update(void *opaque)
29
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pl011_clock = {
21
bool blend = false;
22
uint8_t *host_fb_addr;
23
bool is_dirty = false;
24
- const int global_width = (s->vidtcon[2] & FIMD_VIDTCON2_SIZE_MASK) + 1;
25
+ int global_width;
26
27
if (!s || !s->console || !s->enabled ||
28
surface_bits_per_pixel(qemu_console_surface(s->console)) == 0) {
29
return;
30
}
30
}
31
};
32
33
+static int pl011_post_load(void *opaque, int version_id)
34
+{
35
+ PL011State* s = opaque;
31
+
36
+
32
+ global_width = (s->vidtcon[2] & FIMD_VIDTCON2_SIZE_MASK) + 1;
37
+ /* Sanity-check input state */
33
exynos4210_update_resolution(s);
38
+ if (s->read_pos >= ARRAY_SIZE(s->read_fifo) ||
34
surface = qemu_console_surface(s->console);
39
+ s->read_count > ARRAY_SIZE(s->read_fifo)) {
35
40
+ return -1;
41
+ }
42
+
43
+ if (!pl011_is_fifo_enabled(s) && s->read_count > 0 && s->read_pos > 0) {
44
+ /*
45
+ * Older versions of PL011 didn't ensure that the single
46
+ * character in the FIFO in FIFO-disabled mode is in
47
+ * element 0 of the array; convert to follow the current
48
+ * code's assumptions.
49
+ */
50
+ s->read_fifo[0] = s->read_fifo[s->read_pos];
51
+ s->read_pos = 0;
52
+ }
53
+
54
+ return 0;
55
+}
56
+
57
static const VMStateDescription vmstate_pl011 = {
58
.name = "pl011",
59
.version_id = 2,
60
.minimum_version_id = 2,
61
+ .post_load = pl011_post_load,
62
.fields = (VMStateField[]) {
63
VMSTATE_UINT32(readbuff, PL011State),
64
VMSTATE_UINT32(flags, PL011State),
36
--
65
--
37
2.20.1
66
2.34.1
38
39
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
2
2
3
Model these off the aa64 read/write_vec_element functions.
3
PL011 currently lacks a reset method. Implement it.
4
Use it within translate-neon.c.inc. The new functions do
5
not allocate or free temps, so this rearranges the calling
6
code a bit.
7
4
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
9
Message-id: 20201030022618.785675-6-richard.henderson@linaro.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20230123162304.26254-4-eiakovlev@linux.microsoft.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
target/arm/translate.c | 26 ++++
11
hw/char/pl011.c | 26 +++++++++++++++++++++-----
14
target/arm/translate-neon.c.inc | 256 ++++++++++++++++++++------------
12
1 file changed, 21 insertions(+), 5 deletions(-)
15
2 files changed, 183 insertions(+), 99 deletions(-)
16
13
17
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate.c
16
--- a/hw/char/pl011.c
20
+++ b/target/arm/translate.c
17
+++ b/hw/char/pl011.c
21
@@ -XXX,XX +XXX,XX @@ static inline void neon_store_reg32(TCGv_i32 var, int reg)
18
@@ -XXX,XX +XXX,XX @@ static void pl011_init(Object *obj)
22
tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
19
s->clk = qdev_init_clock_in(DEVICE(obj), "clk", pl011_clock_update, s,
20
ClockUpdate);
21
22
- s->read_trigger = 1;
23
- s->ifl = 0x12;
24
- s->cr = 0x300;
25
- s->flags = 0x90;
26
-
27
s->id = pl011_id_arm;
23
}
28
}
24
29
25
+static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp size)
30
@@ -XXX,XX +XXX,XX @@ static void pl011_realize(DeviceState *dev, Error **errp)
31
pl011_event, NULL, s, NULL, true);
32
}
33
34
+static void pl011_reset(DeviceState *dev)
26
+{
35
+{
27
+ long off = neon_element_offset(reg, ele, size);
36
+ PL011State *s = PL011(dev);
28
+
37
+
29
+ switch (size) {
38
+ s->lcr = 0;
30
+ case MO_32:
39
+ s->rsr = 0;
31
+ tcg_gen_ld_i32(dest, cpu_env, off);
40
+ s->dmacr = 0;
32
+ break;
41
+ s->int_enabled = 0;
33
+ default:
42
+ s->int_level = 0;
34
+ g_assert_not_reached();
43
+ s->ilpr = 0;
35
+ }
44
+ s->ibrd = 0;
45
+ s->fbrd = 0;
46
+ s->read_pos = 0;
47
+ s->read_count = 0;
48
+ s->read_trigger = 1;
49
+ s->ifl = 0x12;
50
+ s->cr = 0x300;
51
+ s->flags = 0x90;
36
+}
52
+}
37
+
53
+
38
+static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp size)
54
static void pl011_class_init(ObjectClass *oc, void *data)
39
+{
40
+ long off = neon_element_offset(reg, ele, size);
41
+
42
+ switch (size) {
43
+ case MO_32:
44
+ tcg_gen_st_i32(src, cpu_env, off);
45
+ break;
46
+ default:
47
+ g_assert_not_reached();
48
+ }
49
+}
50
+
51
static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
52
{
55
{
53
TCGv_ptr ret = tcg_temp_new_ptr();
56
DeviceClass *dc = DEVICE_CLASS(oc);
54
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
57
55
index XXXXXXX..XXXXXXX 100644
58
dc->realize = pl011_realize;
56
--- a/target/arm/translate-neon.c.inc
59
+ dc->reset = pl011_reset;
57
+++ b/target/arm/translate-neon.c.inc
60
dc->vmsd = &vmstate_pl011;
58
@@ -XXX,XX +XXX,XX @@ static bool do_3same_pair(DisasContext *s, arg_3same *a, NeonGenTwoOpFn *fn)
61
device_class_set_props(dc, pl011_properties);
59
* early. Since Q is 0 there are always just two passes, so instead
60
* of a complicated loop over each pass we just unroll.
61
*/
62
- tmp = neon_load_reg(a->vn, 0);
63
- tmp2 = neon_load_reg(a->vn, 1);
64
+ tmp = tcg_temp_new_i32();
65
+ tmp2 = tcg_temp_new_i32();
66
+ tmp3 = tcg_temp_new_i32();
67
+
68
+ read_neon_element32(tmp, a->vn, 0, MO_32);
69
+ read_neon_element32(tmp2, a->vn, 1, MO_32);
70
fn(tmp, tmp, tmp2);
71
- tcg_temp_free_i32(tmp2);
72
73
- tmp3 = neon_load_reg(a->vm, 0);
74
- tmp2 = neon_load_reg(a->vm, 1);
75
+ read_neon_element32(tmp3, a->vm, 0, MO_32);
76
+ read_neon_element32(tmp2, a->vm, 1, MO_32);
77
fn(tmp3, tmp3, tmp2);
78
- tcg_temp_free_i32(tmp2);
79
80
- neon_store_reg(a->vd, 0, tmp);
81
- neon_store_reg(a->vd, 1, tmp3);
82
+ write_neon_element32(tmp, a->vd, 0, MO_32);
83
+ write_neon_element32(tmp3, a->vd, 1, MO_32);
84
+
85
+ tcg_temp_free_i32(tmp);
86
+ tcg_temp_free_i32(tmp2);
87
+ tcg_temp_free_i32(tmp3);
88
return true;
89
}
90
91
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_env_32(DisasContext *s, arg_2reg_shift *a,
92
* 2-reg-and-shift operations, size < 3 case, where the
93
* helper needs to be passed cpu_env.
94
*/
95
- TCGv_i32 constimm;
96
+ TCGv_i32 constimm, tmp;
97
int pass;
98
99
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
100
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_env_32(DisasContext *s, arg_2reg_shift *a,
101
* by immediate using the variable shift operations.
102
*/
103
constimm = tcg_const_i32(dup_const(a->size, a->shift));
104
+ tmp = tcg_temp_new_i32();
105
106
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
107
- TCGv_i32 tmp = neon_load_reg(a->vm, pass);
108
+ read_neon_element32(tmp, a->vm, pass, MO_32);
109
fn(tmp, cpu_env, tmp, constimm);
110
- neon_store_reg(a->vd, pass, tmp);
111
+ write_neon_element32(tmp, a->vd, pass, MO_32);
112
}
113
+ tcg_temp_free_i32(tmp);
114
tcg_temp_free_i32(constimm);
115
return true;
116
}
117
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_64(DisasContext *s, arg_2reg_shift *a,
118
constimm = tcg_const_i64(-a->shift);
119
rm1 = tcg_temp_new_i64();
120
rm2 = tcg_temp_new_i64();
121
+ rd = tcg_temp_new_i32();
122
123
/* Load both inputs first to avoid potential overwrite if rm == rd */
124
neon_load_reg64(rm1, a->vm);
125
neon_load_reg64(rm2, a->vm + 1);
126
127
shiftfn(rm1, rm1, constimm);
128
- rd = tcg_temp_new_i32();
129
narrowfn(rd, cpu_env, rm1);
130
- neon_store_reg(a->vd, 0, rd);
131
+ write_neon_element32(rd, a->vd, 0, MO_32);
132
133
shiftfn(rm2, rm2, constimm);
134
- rd = tcg_temp_new_i32();
135
narrowfn(rd, cpu_env, rm2);
136
- neon_store_reg(a->vd, 1, rd);
137
+ write_neon_element32(rd, a->vd, 1, MO_32);
138
139
+ tcg_temp_free_i32(rd);
140
tcg_temp_free_i64(rm1);
141
tcg_temp_free_i64(rm2);
142
tcg_temp_free_i64(constimm);
143
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a,
144
constimm = tcg_const_i32(imm);
145
146
/* Load all inputs first to avoid potential overwrite */
147
- rm1 = neon_load_reg(a->vm, 0);
148
- rm2 = neon_load_reg(a->vm, 1);
149
- rm3 = neon_load_reg(a->vm + 1, 0);
150
- rm4 = neon_load_reg(a->vm + 1, 1);
151
+ rm1 = tcg_temp_new_i32();
152
+ rm2 = tcg_temp_new_i32();
153
+ rm3 = tcg_temp_new_i32();
154
+ rm4 = tcg_temp_new_i32();
155
+ read_neon_element32(rm1, a->vm, 0, MO_32);
156
+ read_neon_element32(rm2, a->vm, 1, MO_32);
157
+ read_neon_element32(rm3, a->vm, 2, MO_32);
158
+ read_neon_element32(rm4, a->vm, 3, MO_32);
159
rtmp = tcg_temp_new_i64();
160
161
shiftfn(rm1, rm1, constimm);
162
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a,
163
tcg_temp_free_i32(rm2);
164
165
narrowfn(rm1, cpu_env, rtmp);
166
- neon_store_reg(a->vd, 0, rm1);
167
+ write_neon_element32(rm1, a->vd, 0, MO_32);
168
+ tcg_temp_free_i32(rm1);
169
170
shiftfn(rm3, rm3, constimm);
171
shiftfn(rm4, rm4, constimm);
172
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a,
173
174
narrowfn(rm3, cpu_env, rtmp);
175
tcg_temp_free_i64(rtmp);
176
- neon_store_reg(a->vd, 1, rm3);
177
+ write_neon_element32(rm3, a->vd, 1, MO_32);
178
+ tcg_temp_free_i32(rm3);
179
return true;
180
}
181
182
@@ -XXX,XX +XXX,XX @@ static bool do_vshll_2sh(DisasContext *s, arg_2reg_shift *a,
183
widen_mask = dup_const(a->size + 1, widen_mask);
184
}
185
186
- rm0 = neon_load_reg(a->vm, 0);
187
- rm1 = neon_load_reg(a->vm, 1);
188
+ rm0 = tcg_temp_new_i32();
189
+ rm1 = tcg_temp_new_i32();
190
+ read_neon_element32(rm0, a->vm, 0, MO_32);
191
+ read_neon_element32(rm1, a->vm, 1, MO_32);
192
tmp = tcg_temp_new_i64();
193
194
widenfn(tmp, rm0);
195
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
196
if (src1_wide) {
197
neon_load_reg64(rn0_64, a->vn);
198
} else {
199
- TCGv_i32 tmp = neon_load_reg(a->vn, 0);
200
+ TCGv_i32 tmp = tcg_temp_new_i32();
201
+ read_neon_element32(tmp, a->vn, 0, MO_32);
202
widenfn(rn0_64, tmp);
203
tcg_temp_free_i32(tmp);
204
}
205
- rm = neon_load_reg(a->vm, 0);
206
+ rm = tcg_temp_new_i32();
207
+ read_neon_element32(rm, a->vm, 0, MO_32);
208
209
widenfn(rm_64, rm);
210
tcg_temp_free_i32(rm);
211
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
212
if (src1_wide) {
213
neon_load_reg64(rn1_64, a->vn + 1);
214
} else {
215
- TCGv_i32 tmp = neon_load_reg(a->vn, 1);
216
+ TCGv_i32 tmp = tcg_temp_new_i32();
217
+ read_neon_element32(tmp, a->vn, 1, MO_32);
218
widenfn(rn1_64, tmp);
219
tcg_temp_free_i32(tmp);
220
}
221
- rm = neon_load_reg(a->vm, 1);
222
+ rm = tcg_temp_new_i32();
223
+ read_neon_element32(rm, a->vm, 1, MO_32);
224
225
neon_store_reg64(rn0_64, a->vd);
226
227
@@ -XXX,XX +XXX,XX @@ static bool do_narrow_3d(DisasContext *s, arg_3diff *a,
228
229
narrowfn(rd1, rn_64);
230
231
- neon_store_reg(a->vd, 0, rd0);
232
- neon_store_reg(a->vd, 1, rd1);
233
+ write_neon_element32(rd0, a->vd, 0, MO_32);
234
+ write_neon_element32(rd1, a->vd, 1, MO_32);
235
236
+ tcg_temp_free_i32(rd0);
237
+ tcg_temp_free_i32(rd1);
238
tcg_temp_free_i64(rn_64);
239
tcg_temp_free_i64(rm_64);
240
241
@@ -XXX,XX +XXX,XX @@ static bool do_long_3d(DisasContext *s, arg_3diff *a,
242
rd0 = tcg_temp_new_i64();
243
rd1 = tcg_temp_new_i64();
244
245
- rn = neon_load_reg(a->vn, 0);
246
- rm = neon_load_reg(a->vm, 0);
247
+ rn = tcg_temp_new_i32();
248
+ rm = tcg_temp_new_i32();
249
+ read_neon_element32(rn, a->vn, 0, MO_32);
250
+ read_neon_element32(rm, a->vm, 0, MO_32);
251
opfn(rd0, rn, rm);
252
- tcg_temp_free_i32(rn);
253
- tcg_temp_free_i32(rm);
254
255
- rn = neon_load_reg(a->vn, 1);
256
- rm = neon_load_reg(a->vm, 1);
257
+ read_neon_element32(rn, a->vn, 1, MO_32);
258
+ read_neon_element32(rm, a->vm, 1, MO_32);
259
opfn(rd1, rn, rm);
260
tcg_temp_free_i32(rn);
261
tcg_temp_free_i32(rm);
262
@@ -XXX,XX +XXX,XX @@ static void gen_neon_dup_high16(TCGv_i32 var)
263
264
static inline TCGv_i32 neon_get_scalar(int size, int reg)
265
{
266
- TCGv_i32 tmp;
267
- if (size == 1) {
268
- tmp = neon_load_reg(reg & 7, reg >> 4);
269
+ TCGv_i32 tmp = tcg_temp_new_i32();
270
+ if (size == MO_16) {
271
+ read_neon_element32(tmp, reg & 7, reg >> 4, MO_32);
272
if (reg & 8) {
273
gen_neon_dup_high16(tmp);
274
} else {
275
gen_neon_dup_low16(tmp);
276
}
277
} else {
278
- tmp = neon_load_reg(reg & 15, reg >> 4);
279
+ read_neon_element32(tmp, reg & 15, reg >> 4, MO_32);
280
}
281
return tmp;
282
}
283
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar(DisasContext *s, arg_2scalar *a,
284
* perform an accumulation operation of that result into the
285
* destination.
286
*/
287
- TCGv_i32 scalar;
288
+ TCGv_i32 scalar, tmp;
289
int pass;
290
291
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
292
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar(DisasContext *s, arg_2scalar *a,
293
}
294
295
scalar = neon_get_scalar(a->size, a->vm);
296
+ tmp = tcg_temp_new_i32();
297
298
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
299
- TCGv_i32 tmp = neon_load_reg(a->vn, pass);
300
+ read_neon_element32(tmp, a->vn, pass, MO_32);
301
opfn(tmp, tmp, scalar);
302
if (accfn) {
303
- TCGv_i32 rd = neon_load_reg(a->vd, pass);
304
+ TCGv_i32 rd = tcg_temp_new_i32();
305
+ read_neon_element32(rd, a->vd, pass, MO_32);
306
accfn(tmp, rd, tmp);
307
tcg_temp_free_i32(rd);
308
}
309
- neon_store_reg(a->vd, pass, tmp);
310
+ write_neon_element32(tmp, a->vd, pass, MO_32);
311
}
312
+ tcg_temp_free_i32(tmp);
313
tcg_temp_free_i32(scalar);
314
return true;
315
}
316
@@ -XXX,XX +XXX,XX @@ static bool do_vqrdmlah_2sc(DisasContext *s, arg_2scalar *a,
317
* performs a kind of fused op-then-accumulate using a helper
318
* function that takes all of rd, rn and the scalar at once.
319
*/
320
- TCGv_i32 scalar;
321
+ TCGv_i32 scalar, rn, rd;
322
int pass;
323
324
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
325
@@ -XXX,XX +XXX,XX @@ static bool do_vqrdmlah_2sc(DisasContext *s, arg_2scalar *a,
326
}
327
328
scalar = neon_get_scalar(a->size, a->vm);
329
+ rn = tcg_temp_new_i32();
330
+ rd = tcg_temp_new_i32();
331
332
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
333
- TCGv_i32 rn = neon_load_reg(a->vn, pass);
334
- TCGv_i32 rd = neon_load_reg(a->vd, pass);
335
+ read_neon_element32(rn, a->vn, pass, MO_32);
336
+ read_neon_element32(rd, a->vd, pass, MO_32);
337
opfn(rd, cpu_env, rn, scalar, rd);
338
- tcg_temp_free_i32(rn);
339
- neon_store_reg(a->vd, pass, rd);
340
+ write_neon_element32(rd, a->vd, pass, MO_32);
341
}
342
+ tcg_temp_free_i32(rn);
343
+ tcg_temp_free_i32(rd);
344
tcg_temp_free_i32(scalar);
345
346
return true;
347
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_long(DisasContext *s, arg_2scalar *a,
348
scalar = neon_get_scalar(a->size, a->vm);
349
350
/* Load all inputs before writing any outputs, in case of overlap */
351
- rn = neon_load_reg(a->vn, 0);
352
+ rn = tcg_temp_new_i32();
353
+ read_neon_element32(rn, a->vn, 0, MO_32);
354
rn0_64 = tcg_temp_new_i64();
355
opfn(rn0_64, rn, scalar);
356
- tcg_temp_free_i32(rn);
357
358
- rn = neon_load_reg(a->vn, 1);
359
+ read_neon_element32(rn, a->vn, 1, MO_32);
360
rn1_64 = tcg_temp_new_i64();
361
opfn(rn1_64, rn, scalar);
362
tcg_temp_free_i32(rn);
363
@@ -XXX,XX +XXX,XX @@ static bool trans_VTBL(DisasContext *s, arg_VTBL *a)
364
return false;
365
}
366
n <<= 3;
367
+ tmp = tcg_temp_new_i32();
368
if (a->op) {
369
- tmp = neon_load_reg(a->vd, 0);
370
+ read_neon_element32(tmp, a->vd, 0, MO_32);
371
} else {
372
- tmp = tcg_temp_new_i32();
373
tcg_gen_movi_i32(tmp, 0);
374
}
375
- tmp2 = neon_load_reg(a->vm, 0);
376
+ tmp2 = tcg_temp_new_i32();
377
+ read_neon_element32(tmp2, a->vm, 0, MO_32);
378
ptr1 = vfp_reg_ptr(true, a->vn);
379
tmp4 = tcg_const_i32(n);
380
gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp4);
381
- tcg_temp_free_i32(tmp);
382
+
383
if (a->op) {
384
- tmp = neon_load_reg(a->vd, 1);
385
+ read_neon_element32(tmp, a->vd, 1, MO_32);
386
} else {
387
- tmp = tcg_temp_new_i32();
388
tcg_gen_movi_i32(tmp, 0);
389
}
390
- tmp3 = neon_load_reg(a->vm, 1);
391
+ tmp3 = tcg_temp_new_i32();
392
+ read_neon_element32(tmp3, a->vm, 1, MO_32);
393
gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp4);
394
+ tcg_temp_free_i32(tmp);
395
tcg_temp_free_i32(tmp4);
396
tcg_temp_free_ptr(ptr1);
397
- neon_store_reg(a->vd, 0, tmp2);
398
- neon_store_reg(a->vd, 1, tmp3);
399
- tcg_temp_free_i32(tmp);
400
+
401
+ write_neon_element32(tmp2, a->vd, 0, MO_32);
402
+ write_neon_element32(tmp3, a->vd, 1, MO_32);
403
+ tcg_temp_free_i32(tmp2);
404
+ tcg_temp_free_i32(tmp3);
405
return true;
406
}
407
408
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a)
409
static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
410
{
411
int pass, half;
412
+ TCGv_i32 tmp[2];
413
414
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
415
return false;
416
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
417
return true;
418
}
419
420
- for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
421
- TCGv_i32 tmp[2];
422
+ tmp[0] = tcg_temp_new_i32();
423
+ tmp[1] = tcg_temp_new_i32();
424
425
+ for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
426
for (half = 0; half < 2; half++) {
427
- tmp[half] = neon_load_reg(a->vm, pass * 2 + half);
428
+ read_neon_element32(tmp[half], a->vm, pass * 2 + half, MO_32);
429
switch (a->size) {
430
case 0:
431
tcg_gen_bswap32_i32(tmp[half], tmp[half]);
432
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
433
g_assert_not_reached();
434
}
435
}
436
- neon_store_reg(a->vd, pass * 2, tmp[1]);
437
- neon_store_reg(a->vd, pass * 2 + 1, tmp[0]);
438
+ write_neon_element32(tmp[1], a->vd, pass * 2, MO_32);
439
+ write_neon_element32(tmp[0], a->vd, pass * 2 + 1, MO_32);
440
}
441
+
442
+ tcg_temp_free_i32(tmp[0]);
443
+ tcg_temp_free_i32(tmp[1]);
444
return true;
445
}
446
447
@@ -XXX,XX +XXX,XX @@ static bool do_2misc_pairwise(DisasContext *s, arg_2misc *a,
448
rm0_64 = tcg_temp_new_i64();
449
rm1_64 = tcg_temp_new_i64();
450
rd_64 = tcg_temp_new_i64();
451
- tmp = neon_load_reg(a->vm, pass * 2);
452
+
453
+ tmp = tcg_temp_new_i32();
454
+ read_neon_element32(tmp, a->vm, pass * 2, MO_32);
455
widenfn(rm0_64, tmp);
456
- tcg_temp_free_i32(tmp);
457
- tmp = neon_load_reg(a->vm, pass * 2 + 1);
458
+ read_neon_element32(tmp, a->vm, pass * 2 + 1, MO_32);
459
widenfn(rm1_64, tmp);
460
tcg_temp_free_i32(tmp);
461
+
462
opfn(rd_64, rm0_64, rm1_64);
463
tcg_temp_free_i64(rm0_64);
464
tcg_temp_free_i64(rm1_64);
465
@@ -XXX,XX +XXX,XX @@ static bool do_vmovn(DisasContext *s, arg_2misc *a,
466
narrowfn(rd0, cpu_env, rm);
467
neon_load_reg64(rm, a->vm + 1);
468
narrowfn(rd1, cpu_env, rm);
469
- neon_store_reg(a->vd, 0, rd0);
470
- neon_store_reg(a->vd, 1, rd1);
471
+ write_neon_element32(rd0, a->vd, 0, MO_32);
472
+ write_neon_element32(rd1, a->vd, 1, MO_32);
473
+ tcg_temp_free_i32(rd0);
474
+ tcg_temp_free_i32(rd1);
475
tcg_temp_free_i64(rm);
476
return true;
477
}
478
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
479
}
480
481
rd = tcg_temp_new_i64();
482
+ rm0 = tcg_temp_new_i32();
483
+ rm1 = tcg_temp_new_i32();
484
485
- rm0 = neon_load_reg(a->vm, 0);
486
- rm1 = neon_load_reg(a->vm, 1);
487
+ read_neon_element32(rm0, a->vm, 0, MO_32);
488
+ read_neon_element32(rm1, a->vm, 1, MO_32);
489
490
widenfn(rd, rm0);
491
tcg_gen_shli_i64(rd, rd, 8 << a->size);
492
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F16_F32(DisasContext *s, arg_2misc *a)
493
494
fpst = fpstatus_ptr(FPST_STD);
495
ahp = get_ahp_flag();
496
- tmp = neon_load_reg(a->vm, 0);
497
+ tmp = tcg_temp_new_i32();
498
+ read_neon_element32(tmp, a->vm, 0, MO_32);
499
gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
500
- tmp2 = neon_load_reg(a->vm, 1);
501
+ tmp2 = tcg_temp_new_i32();
502
+ read_neon_element32(tmp2, a->vm, 1, MO_32);
503
gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
504
tcg_gen_shli_i32(tmp2, tmp2, 16);
505
tcg_gen_or_i32(tmp2, tmp2, tmp);
506
- tcg_temp_free_i32(tmp);
507
- tmp = neon_load_reg(a->vm, 2);
508
+ read_neon_element32(tmp, a->vm, 2, MO_32);
509
gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
510
- tmp3 = neon_load_reg(a->vm, 3);
511
- neon_store_reg(a->vd, 0, tmp2);
512
+ tmp3 = tcg_temp_new_i32();
513
+ read_neon_element32(tmp3, a->vm, 3, MO_32);
514
+ write_neon_element32(tmp2, a->vd, 0, MO_32);
515
+ tcg_temp_free_i32(tmp2);
516
gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
517
tcg_gen_shli_i32(tmp3, tmp3, 16);
518
tcg_gen_or_i32(tmp3, tmp3, tmp);
519
- neon_store_reg(a->vd, 1, tmp3);
520
+ write_neon_element32(tmp3, a->vd, 1, MO_32);
521
+ tcg_temp_free_i32(tmp3);
522
tcg_temp_free_i32(tmp);
523
tcg_temp_free_i32(ahp);
524
tcg_temp_free_ptr(fpst);
525
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a)
526
fpst = fpstatus_ptr(FPST_STD);
527
ahp = get_ahp_flag();
528
tmp3 = tcg_temp_new_i32();
529
- tmp = neon_load_reg(a->vm, 0);
530
- tmp2 = neon_load_reg(a->vm, 1);
531
+ tmp2 = tcg_temp_new_i32();
532
+ tmp = tcg_temp_new_i32();
533
+ read_neon_element32(tmp, a->vm, 0, MO_32);
534
+ read_neon_element32(tmp2, a->vm, 1, MO_32);
535
tcg_gen_ext16u_i32(tmp3, tmp);
536
gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
537
- neon_store_reg(a->vd, 0, tmp3);
538
+ write_neon_element32(tmp3, a->vd, 0, MO_32);
539
tcg_gen_shri_i32(tmp, tmp, 16);
540
gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
541
- neon_store_reg(a->vd, 1, tmp);
542
- tmp3 = tcg_temp_new_i32();
543
+ write_neon_element32(tmp, a->vd, 1, MO_32);
544
+ tcg_temp_free_i32(tmp);
545
tcg_gen_ext16u_i32(tmp3, tmp2);
546
gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
547
- neon_store_reg(a->vd, 2, tmp3);
548
+ write_neon_element32(tmp3, a->vd, 2, MO_32);
549
+ tcg_temp_free_i32(tmp3);
550
tcg_gen_shri_i32(tmp2, tmp2, 16);
551
gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
552
- neon_store_reg(a->vd, 3, tmp2);
553
+ write_neon_element32(tmp2, a->vd, 3, MO_32);
554
+ tcg_temp_free_i32(tmp2);
555
tcg_temp_free_i32(ahp);
556
tcg_temp_free_ptr(fpst);
557
558
@@ -XXX,XX +XXX,XX @@ DO_2M_CRYPTO(SHA256SU0, aa32_sha2, 2)
559
560
static bool do_2misc(DisasContext *s, arg_2misc *a, NeonGenOneOpFn *fn)
561
{
562
+ TCGv_i32 tmp;
563
int pass;
564
565
/* Handle a 2-reg-misc operation by iterating 32 bits at a time */
566
@@ -XXX,XX +XXX,XX @@ static bool do_2misc(DisasContext *s, arg_2misc *a, NeonGenOneOpFn *fn)
567
return true;
568
}
569
570
+ tmp = tcg_temp_new_i32();
571
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
572
- TCGv_i32 tmp = neon_load_reg(a->vm, pass);
573
+ read_neon_element32(tmp, a->vm, pass, MO_32);
574
fn(tmp, tmp);
575
- neon_store_reg(a->vd, pass, tmp);
576
+ write_neon_element32(tmp, a->vd, pass, MO_32);
577
}
578
+ tcg_temp_free_i32(tmp);
579
580
return true;
581
}
582
@@ -XXX,XX +XXX,XX @@ static bool trans_VTRN(DisasContext *s, arg_2misc *a)
583
return true;
584
}
585
586
- if (a->size == 2) {
587
+ tmp = tcg_temp_new_i32();
588
+ tmp2 = tcg_temp_new_i32();
589
+ if (a->size == MO_32) {
590
for (pass = 0; pass < (a->q ? 4 : 2); pass += 2) {
591
- tmp = neon_load_reg(a->vm, pass);
592
- tmp2 = neon_load_reg(a->vd, pass + 1);
593
- neon_store_reg(a->vm, pass, tmp2);
594
- neon_store_reg(a->vd, pass + 1, tmp);
595
+ read_neon_element32(tmp, a->vm, pass, MO_32);
596
+ read_neon_element32(tmp2, a->vd, pass + 1, MO_32);
597
+ write_neon_element32(tmp2, a->vm, pass, MO_32);
598
+ write_neon_element32(tmp, a->vd, pass + 1, MO_32);
599
}
600
} else {
601
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
602
- tmp = neon_load_reg(a->vm, pass);
603
- tmp2 = neon_load_reg(a->vd, pass);
604
- if (a->size == 0) {
605
+ read_neon_element32(tmp, a->vm, pass, MO_32);
606
+ read_neon_element32(tmp2, a->vd, pass, MO_32);
607
+ if (a->size == MO_8) {
608
gen_neon_trn_u8(tmp, tmp2);
609
} else {
610
gen_neon_trn_u16(tmp, tmp2);
611
}
612
- neon_store_reg(a->vm, pass, tmp2);
613
- neon_store_reg(a->vd, pass, tmp);
614
+ write_neon_element32(tmp2, a->vm, pass, MO_32);
615
+ write_neon_element32(tmp, a->vd, pass, MO_32);
616
}
617
}
618
+ tcg_temp_free_i32(tmp);
619
+ tcg_temp_free_i32(tmp2);
620
return true;
621
}
62
}
622
--
63
--
623
2.20.1
64
2.34.1
624
65
625
66
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
2
2
3
This function makes it clear that we're talking about the whole
3
Current FIFO handling code does not reset RXFE/RXFF flags when guest
4
register, and not the 32-bit piece at index 0. This fixes a bug
4
resets FIFO by writing to UARTLCR register, although internal FIFO state
5
when running on a big-endian host.
5
is reset to 0 read count. Actual guest-visible flag update will happen
6
only on next data read or write attempt. As a result of that any guest
7
that expects RXFE flag to be set (and RXFF to be cleared) after resetting
8
FIFO will never see that happen.
6
9
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
8
Message-id: 20201030022618.785675-2-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20230123162304.26254-5-eiakovlev@linux.microsoft.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
14
---
12
target/arm/translate.c | 8 ++++++
15
hw/char/pl011.c | 18 +++++++++++++-----
13
target/arm/translate-neon.c.inc | 44 ++++++++++++++++-----------------
16
1 file changed, 13 insertions(+), 5 deletions(-)
14
target/arm/translate-vfp.c.inc | 2 +-
15
3 files changed, 31 insertions(+), 23 deletions(-)
16
17
17
diff --git a/target/arm/translate.c b/target/arm/translate.c
18
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate.c
20
--- a/hw/char/pl011.c
20
+++ b/target/arm/translate.c
21
+++ b/hw/char/pl011.c
21
@@ -XXX,XX +XXX,XX @@ static inline void gen_hlt(DisasContext *s, int imm)
22
@@ -XXX,XX +XXX,XX @@ static inline unsigned pl011_get_fifo_depth(PL011State *s)
22
unallocated_encoding(s);
23
return pl011_is_fifo_enabled(s) ? PL011_FIFO_DEPTH : 1;
23
}
24
}
24
25
25
+/*
26
+static inline void pl011_reset_fifo(PL011State *s)
26
+ * Return the offset of a "full" NEON Dreg.
27
+ */
28
+static long neon_full_reg_offset(unsigned reg)
29
+{
27
+{
30
+ return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
28
+ s->read_count = 0;
29
+ s->read_pos = 0;
30
+
31
+ /* Reset FIFO flags */
32
+ s->flags &= ~(PL011_FLAG_RXFF | PL011_FLAG_TXFF);
33
+ s->flags |= PL011_FLAG_RXFE | PL011_FLAG_TXFE;
31
+}
34
+}
32
+
35
+
33
static inline long vfp_reg_offset(bool dp, unsigned reg)
36
static uint64_t pl011_read(void *opaque, hwaddr offset,
37
unsigned size)
34
{
38
{
35
if (dp) {
39
@@ -XXX,XX +XXX,XX @@ static void pl011_write(void *opaque, hwaddr offset,
36
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
40
case 11: /* UARTLCR_H */
37
index XXXXXXX..XXXXXXX 100644
41
/* Reset the FIFO state on FIFO enable or disable */
38
--- a/target/arm/translate-neon.c.inc
42
if ((s->lcr ^ value) & 0x10) {
39
+++ b/target/arm/translate-neon.c.inc
43
- s->read_count = 0;
40
@@ -XXX,XX +XXX,XX @@ neon_element_offset(int reg, int element, MemOp size)
44
- s->read_pos = 0;
41
ofs ^= 8 - element_size;
45
+ pl011_reset_fifo(s);
42
}
46
}
43
#endif
47
if ((s->lcr ^ value) & 0x1) {
44
- return neon_reg_offset(reg, 0) + ofs;
48
int break_enable = value & 0x1;
45
+ return neon_full_reg_offset(reg) + ofs;
49
@@ -XXX,XX +XXX,XX @@ static void pl011_reset(DeviceState *dev)
50
s->ilpr = 0;
51
s->ibrd = 0;
52
s->fbrd = 0;
53
- s->read_pos = 0;
54
- s->read_count = 0;
55
s->read_trigger = 1;
56
s->ifl = 0x12;
57
s->cr = 0x300;
58
- s->flags = 0x90;
59
+ s->flags = 0;
60
+ pl011_reset_fifo(s);
46
}
61
}
47
62
48
static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
63
static void pl011_class_init(ObjectClass *oc, void *data)
49
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
50
* We cannot write 16 bytes at once because the
51
* destination is unaligned.
52
*/
53
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
54
+ tcg_gen_gvec_dup_i32(size, neon_full_reg_offset(vd),
55
8, 8, tmp);
56
- tcg_gen_gvec_mov(0, neon_reg_offset(vd + 1, 0),
57
- neon_reg_offset(vd, 0), 8, 8);
58
+ tcg_gen_gvec_mov(0, neon_full_reg_offset(vd + 1),
59
+ neon_full_reg_offset(vd), 8, 8);
60
} else {
61
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
62
+ tcg_gen_gvec_dup_i32(size, neon_full_reg_offset(vd),
63
vec_size, vec_size, tmp);
64
}
65
tcg_gen_addi_i32(addr, addr, 1 << size);
66
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
67
static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
68
{
69
int vec_size = a->q ? 16 : 8;
70
- int rd_ofs = neon_reg_offset(a->vd, 0);
71
- int rn_ofs = neon_reg_offset(a->vn, 0);
72
- int rm_ofs = neon_reg_offset(a->vm, 0);
73
+ int rd_ofs = neon_full_reg_offset(a->vd);
74
+ int rn_ofs = neon_full_reg_offset(a->vn);
75
+ int rm_ofs = neon_full_reg_offset(a->vm);
76
77
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
78
return false;
79
@@ -XXX,XX +XXX,XX @@ static bool do_vector_2sh(DisasContext *s, arg_2reg_shift *a, GVecGen2iFn *fn)
80
{
81
/* Handle a 2-reg-shift insn which can be vectorized. */
82
int vec_size = a->q ? 16 : 8;
83
- int rd_ofs = neon_reg_offset(a->vd, 0);
84
- int rm_ofs = neon_reg_offset(a->vm, 0);
85
+ int rd_ofs = neon_full_reg_offset(a->vd);
86
+ int rm_ofs = neon_full_reg_offset(a->vm);
87
88
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
89
return false;
90
@@ -XXX,XX +XXX,XX @@ static bool do_fp_2sh(DisasContext *s, arg_2reg_shift *a,
91
{
92
/* FP operations in 2-reg-and-shift group */
93
int vec_size = a->q ? 16 : 8;
94
- int rd_ofs = neon_reg_offset(a->vd, 0);
95
- int rm_ofs = neon_reg_offset(a->vm, 0);
96
+ int rd_ofs = neon_full_reg_offset(a->vd);
97
+ int rm_ofs = neon_full_reg_offset(a->vm);
98
TCGv_ptr fpst;
99
100
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
101
@@ -XXX,XX +XXX,XX @@ static bool do_1reg_imm(DisasContext *s, arg_1reg_imm *a,
102
return true;
103
}
104
105
- reg_ofs = neon_reg_offset(a->vd, 0);
106
+ reg_ofs = neon_full_reg_offset(a->vd);
107
vec_size = a->q ? 16 : 8;
108
imm = asimd_imm_const(a->imm, a->cmode, a->op);
109
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VMULL_P_3d(DisasContext *s, arg_3diff *a)
111
return true;
112
}
113
114
- tcg_gen_gvec_3_ool(neon_reg_offset(a->vd, 0),
115
- neon_reg_offset(a->vn, 0),
116
- neon_reg_offset(a->vm, 0),
117
+ tcg_gen_gvec_3_ool(neon_full_reg_offset(a->vd),
118
+ neon_full_reg_offset(a->vn),
119
+ neon_full_reg_offset(a->vm),
120
16, 16, 0, fn_gvec);
121
return true;
122
}
123
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_fp_vec(DisasContext *s, arg_2scalar *a,
124
{
125
/* Two registers and a scalar, using gvec */
126
int vec_size = a->q ? 16 : 8;
127
- int rd_ofs = neon_reg_offset(a->vd, 0);
128
- int rn_ofs = neon_reg_offset(a->vn, 0);
129
+ int rd_ofs = neon_full_reg_offset(a->vd);
130
+ int rn_ofs = neon_full_reg_offset(a->vn);
131
int rm_ofs;
132
int idx;
133
TCGv_ptr fpstatus;
134
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_fp_vec(DisasContext *s, arg_2scalar *a,
135
/* a->vm is M:Vm, which encodes both register and index */
136
idx = extract32(a->vm, a->size + 2, 2);
137
a->vm = extract32(a->vm, 0, a->size + 2);
138
- rm_ofs = neon_reg_offset(a->vm, 0);
139
+ rm_ofs = neon_full_reg_offset(a->vm);
140
141
fpstatus = fpstatus_ptr(a->size == 1 ? FPST_STD_F16 : FPST_STD);
142
tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, fpstatus,
143
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a)
144
return true;
145
}
146
147
- tcg_gen_gvec_dup_mem(a->size, neon_reg_offset(a->vd, 0),
148
+ tcg_gen_gvec_dup_mem(a->size, neon_full_reg_offset(a->vd),
149
neon_element_offset(a->vm, a->index, a->size),
150
a->q ? 16 : 8, a->q ? 16 : 8);
151
return true;
152
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a)
153
static bool do_2misc_vec(DisasContext *s, arg_2misc *a, GVecGen2Fn *fn)
154
{
155
int vec_size = a->q ? 16 : 8;
156
- int rd_ofs = neon_reg_offset(a->vd, 0);
157
- int rm_ofs = neon_reg_offset(a->vm, 0);
158
+ int rd_ofs = neon_full_reg_offset(a->vd);
159
+ int rm_ofs = neon_full_reg_offset(a->vm);
160
161
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
162
return false;
163
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
164
index XXXXXXX..XXXXXXX 100644
165
--- a/target/arm/translate-vfp.c.inc
166
+++ b/target/arm/translate-vfp.c.inc
167
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
168
}
169
170
tmp = load_reg(s, a->rt);
171
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(a->vn, 0),
172
+ tcg_gen_gvec_dup_i32(size, neon_full_reg_offset(a->vn),
173
vec_size, vec_size, tmp);
174
tcg_temp_free_i32(tmp);
175
176
--
64
--
177
2.20.1
65
2.34.1
178
179
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
We can then use this to improve VMOV (scalar to gp) and
3
We currently only support GICv2 emulation. To also support GICv3, we will
4
VMOV (gp to scalar) so that we simply perform the memory
4
need to pass a few system registers into their respective handler functions.
5
operation that we wanted, rather than inserting or
5
6
extracting from a 32-bit quantity.
6
This patch adds support for HVF to call into the TCG callbacks for GICv3
7
7
system register handlers. This is safe because the GICv3 TCG code is generic
8
These were the last uses of neon_load/store_reg, so remove them.
8
as long as we limit ourselves to EL0 and EL1 - which are the only modes
9
9
supported by HVF.
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
11
Message-id: 20201030022618.785675-7-richard.henderson@linaro.org
11
To make sure nobody trips over that, we also annotate callbacks that don't
12
work in HVF mode, such as EL state change hooks.
13
14
With GICv3 support in place, we can run with more than 8 vCPUs.
15
16
Signed-off-by: Alexander Graf <agraf@csgraf.de>
17
Message-id: 20230128224459.70676-1-agraf@csgraf.de
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
20
---
15
target/arm/translate.c | 50 +++++++++++++-----------
21
hw/intc/arm_gicv3_cpuif.c | 16 +++-
16
target/arm/translate-vfp.c.inc | 71 +++++-----------------------------
22
target/arm/hvf/hvf.c | 151 ++++++++++++++++++++++++++++++++++++
17
2 files changed, 37 insertions(+), 84 deletions(-)
23
target/arm/hvf/trace-events | 2 +
18
24
3 files changed, 168 insertions(+), 1 deletion(-)
19
diff --git a/target/arm/translate.c b/target/arm/translate.c
25
26
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
20
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate.c
28
--- a/hw/intc/arm_gicv3_cpuif.c
22
+++ b/target/arm/translate.c
29
+++ b/hw/intc/arm_gicv3_cpuif.c
23
@@ -XXX,XX +XXX,XX @@ static long neon_full_reg_offset(unsigned reg)
30
@@ -XXX,XX +XXX,XX @@
24
* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
31
#include "hw/irq.h"
25
* where 0 is the least significant end of the register.
32
#include "cpu.h"
26
*/
33
#include "target/arm/cpregs.h"
27
-static long neon_element_offset(int reg, int element, MemOp size)
34
+#include "sysemu/tcg.h"
28
+static long neon_element_offset(int reg, int element, MemOp memop)
35
+#include "sysemu/qtest.h"
29
{
36
30
- int element_size = 1 << size;
37
/*
31
+ int element_size = 1 << (memop & MO_SIZE);
38
* Special case return value from hppvi_index(); must be larger than
32
int ofs = element * element_size;
39
@@ -XXX,XX +XXX,XX @@ void gicv3_init_cpuif(GICv3State *s)
33
#ifdef HOST_WORDS_BIGENDIAN
40
* which case we'd get the wrong value.
34
/*
41
* So instead we define the regs with no ri->opaque info, and
35
@@ -XXX,XX +XXX,XX @@ static long vfp_reg_offset(bool dp, unsigned reg)
42
* get back to the GICv3CPUState from the CPUARMState.
43
+ *
44
+ * These CP regs callbacks can be called from either TCG or HVF code.
45
*/
46
define_arm_cp_regs(cpu, gicv3_cpuif_reginfo);
47
48
@@ -XXX,XX +XXX,XX @@ void gicv3_init_cpuif(GICv3State *s)
49
define_arm_cp_regs(cpu, gicv3_cpuif_ich_apxr23_reginfo);
50
}
51
}
52
- arm_register_el_change_hook(cpu, gicv3_cpuif_el_change_hook, cs);
53
+ if (tcg_enabled() || qtest_enabled()) {
54
+ /*
55
+ * We can only trap EL changes with TCG. However the GIC interrupt
56
+ * state only changes on EL changes involving EL2 or EL3, so for
57
+ * the non-TCG case this is OK, as EL2 and EL3 can't exist.
58
+ */
59
+ arm_register_el_change_hook(cpu, gicv3_cpuif_el_change_hook, cs);
60
+ } else {
61
+ assert(!arm_feature(&cpu->env, ARM_FEATURE_EL2));
62
+ assert(!arm_feature(&cpu->env, ARM_FEATURE_EL3));
63
+ }
36
}
64
}
37
}
65
}
38
66
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
39
-static TCGv_i32 neon_load_reg(int reg, int pass)
67
index XXXXXXX..XXXXXXX 100644
40
-{
68
--- a/target/arm/hvf/hvf.c
41
- TCGv_i32 tmp = tcg_temp_new_i32();
69
+++ b/target/arm/hvf/hvf.c
42
- tcg_gen_ld_i32(tmp, cpu_env, neon_element_offset(reg, pass, MO_32));
70
@@ -XXX,XX +XXX,XX @@
43
- return tmp;
71
#define SYSREG_PMCCNTR_EL0 SYSREG(3, 3, 9, 13, 0)
44
-}
72
#define SYSREG_PMCCFILTR_EL0 SYSREG(3, 3, 14, 15, 7)
45
-
73
46
-static void neon_store_reg(int reg, int pass, TCGv_i32 var)
74
+#define SYSREG_ICC_AP0R0_EL1 SYSREG(3, 0, 12, 8, 4)
47
-{
75
+#define SYSREG_ICC_AP0R1_EL1 SYSREG(3, 0, 12, 8, 5)
48
- tcg_gen_st_i32(var, cpu_env, neon_element_offset(reg, pass, MO_32));
76
+#define SYSREG_ICC_AP0R2_EL1 SYSREG(3, 0, 12, 8, 6)
49
- tcg_temp_free_i32(var);
77
+#define SYSREG_ICC_AP0R3_EL1 SYSREG(3, 0, 12, 8, 7)
50
-}
78
+#define SYSREG_ICC_AP1R0_EL1 SYSREG(3, 0, 12, 9, 0)
51
-
79
+#define SYSREG_ICC_AP1R1_EL1 SYSREG(3, 0, 12, 9, 1)
52
static inline void neon_load_reg64(TCGv_i64 var, int reg)
80
+#define SYSREG_ICC_AP1R2_EL1 SYSREG(3, 0, 12, 9, 2)
81
+#define SYSREG_ICC_AP1R3_EL1 SYSREG(3, 0, 12, 9, 3)
82
+#define SYSREG_ICC_ASGI1R_EL1 SYSREG(3, 0, 12, 11, 6)
83
+#define SYSREG_ICC_BPR0_EL1 SYSREG(3, 0, 12, 8, 3)
84
+#define SYSREG_ICC_BPR1_EL1 SYSREG(3, 0, 12, 12, 3)
85
+#define SYSREG_ICC_CTLR_EL1 SYSREG(3, 0, 12, 12, 4)
86
+#define SYSREG_ICC_DIR_EL1 SYSREG(3, 0, 12, 11, 1)
87
+#define SYSREG_ICC_EOIR0_EL1 SYSREG(3, 0, 12, 8, 1)
88
+#define SYSREG_ICC_EOIR1_EL1 SYSREG(3, 0, 12, 12, 1)
89
+#define SYSREG_ICC_HPPIR0_EL1 SYSREG(3, 0, 12, 8, 2)
90
+#define SYSREG_ICC_HPPIR1_EL1 SYSREG(3, 0, 12, 12, 2)
91
+#define SYSREG_ICC_IAR0_EL1 SYSREG(3, 0, 12, 8, 0)
92
+#define SYSREG_ICC_IAR1_EL1 SYSREG(3, 0, 12, 12, 0)
93
+#define SYSREG_ICC_IGRPEN0_EL1 SYSREG(3, 0, 12, 12, 6)
94
+#define SYSREG_ICC_IGRPEN1_EL1 SYSREG(3, 0, 12, 12, 7)
95
+#define SYSREG_ICC_PMR_EL1 SYSREG(3, 0, 4, 6, 0)
96
+#define SYSREG_ICC_RPR_EL1 SYSREG(3, 0, 12, 11, 3)
97
+#define SYSREG_ICC_SGI0R_EL1 SYSREG(3, 0, 12, 11, 7)
98
+#define SYSREG_ICC_SGI1R_EL1 SYSREG(3, 0, 12, 11, 5)
99
+#define SYSREG_ICC_SRE_EL1 SYSREG(3, 0, 12, 12, 5)
100
+
101
#define WFX_IS_WFE (1 << 0)
102
103
#define TMR_CTL_ENABLE (1 << 0)
104
@@ -XXX,XX +XXX,XX @@ static bool is_id_sysreg(uint32_t reg)
105
SYSREG_CRM(reg) < 8;
106
}
107
108
+static uint32_t hvf_reg2cp_reg(uint32_t reg)
109
+{
110
+ return ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP,
111
+ (reg >> SYSREG_CRN_SHIFT) & SYSREG_CRN_MASK,
112
+ (reg >> SYSREG_CRM_SHIFT) & SYSREG_CRM_MASK,
113
+ (reg >> SYSREG_OP0_SHIFT) & SYSREG_OP0_MASK,
114
+ (reg >> SYSREG_OP1_SHIFT) & SYSREG_OP1_MASK,
115
+ (reg >> SYSREG_OP2_SHIFT) & SYSREG_OP2_MASK);
116
+}
117
+
118
+static bool hvf_sysreg_read_cp(CPUState *cpu, uint32_t reg, uint64_t *val)
119
+{
120
+ ARMCPU *arm_cpu = ARM_CPU(cpu);
121
+ CPUARMState *env = &arm_cpu->env;
122
+ const ARMCPRegInfo *ri;
123
+
124
+ ri = get_arm_cp_reginfo(arm_cpu->cp_regs, hvf_reg2cp_reg(reg));
125
+ if (ri) {
126
+ if (ri->accessfn) {
127
+ if (ri->accessfn(env, ri, true) != CP_ACCESS_OK) {
128
+ return false;
129
+ }
130
+ }
131
+ if (ri->type & ARM_CP_CONST) {
132
+ *val = ri->resetvalue;
133
+ } else if (ri->readfn) {
134
+ *val = ri->readfn(env, ri);
135
+ } else {
136
+ *val = CPREG_FIELD64(env, ri);
137
+ }
138
+ trace_hvf_vgic_read(ri->name, *val);
139
+ return true;
140
+ }
141
+
142
+ return false;
143
+}
144
+
145
static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint32_t rt)
53
{
146
{
54
tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
147
ARMCPU *arm_cpu = ARM_CPU(cpu);
55
@@ -XXX,XX +XXX,XX @@ static inline void neon_store_reg32(TCGv_i32 var, int reg)
148
@@ -XXX,XX +XXX,XX @@ static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint32_t rt)
56
tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
149
case SYSREG_OSDLR_EL1:
57
}
150
/* Dummy register */
58
151
break;
59
-static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp size)
152
+ case SYSREG_ICC_AP0R0_EL1:
60
+static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
153
+ case SYSREG_ICC_AP0R1_EL1:
61
{
154
+ case SYSREG_ICC_AP0R2_EL1:
62
- long off = neon_element_offset(reg, ele, size);
155
+ case SYSREG_ICC_AP0R3_EL1:
63
+ long off = neon_element_offset(reg, ele, memop);
156
+ case SYSREG_ICC_AP1R0_EL1:
64
157
+ case SYSREG_ICC_AP1R1_EL1:
65
- switch (size) {
158
+ case SYSREG_ICC_AP1R2_EL1:
66
- case MO_32:
159
+ case SYSREG_ICC_AP1R3_EL1:
67
+ switch (memop) {
160
+ case SYSREG_ICC_ASGI1R_EL1:
68
+ case MO_SB:
161
+ case SYSREG_ICC_BPR0_EL1:
69
+ tcg_gen_ld8s_i32(dest, cpu_env, off);
162
+ case SYSREG_ICC_BPR1_EL1:
163
+ case SYSREG_ICC_DIR_EL1:
164
+ case SYSREG_ICC_EOIR0_EL1:
165
+ case SYSREG_ICC_EOIR1_EL1:
166
+ case SYSREG_ICC_HPPIR0_EL1:
167
+ case SYSREG_ICC_HPPIR1_EL1:
168
+ case SYSREG_ICC_IAR0_EL1:
169
+ case SYSREG_ICC_IAR1_EL1:
170
+ case SYSREG_ICC_IGRPEN0_EL1:
171
+ case SYSREG_ICC_IGRPEN1_EL1:
172
+ case SYSREG_ICC_PMR_EL1:
173
+ case SYSREG_ICC_SGI0R_EL1:
174
+ case SYSREG_ICC_SGI1R_EL1:
175
+ case SYSREG_ICC_SRE_EL1:
176
+ case SYSREG_ICC_CTLR_EL1:
177
+ /* Call the TCG sysreg handler. This is only safe for GICv3 regs. */
178
+ if (!hvf_sysreg_read_cp(cpu, reg, &val)) {
179
+ hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
180
+ }
70
+ break;
181
+ break;
71
+ case MO_UB:
72
+ tcg_gen_ld8u_i32(dest, cpu_env, off);
73
+ break;
74
+ case MO_SW:
75
+ tcg_gen_ld16s_i32(dest, cpu_env, off);
76
+ break;
77
+ case MO_UW:
78
+ tcg_gen_ld16u_i32(dest, cpu_env, off);
79
+ break;
80
+ case MO_UL:
81
+ case MO_SL:
82
tcg_gen_ld_i32(dest, cpu_env, off);
83
break;
84
default:
182
default:
85
@@ -XXX,XX +XXX,XX @@ static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp size)
183
if (is_id_sysreg(reg)) {
184
/* ID system registers read as RES0 */
185
@@ -XXX,XX +XXX,XX @@ static void pmswinc_write(CPUARMState *env, uint64_t value)
86
}
186
}
87
}
187
}
88
188
89
-static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp size)
189
+static bool hvf_sysreg_write_cp(CPUState *cpu, uint32_t reg, uint64_t val)
90
+static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
190
+{
191
+ ARMCPU *arm_cpu = ARM_CPU(cpu);
192
+ CPUARMState *env = &arm_cpu->env;
193
+ const ARMCPRegInfo *ri;
194
+
195
+ ri = get_arm_cp_reginfo(arm_cpu->cp_regs, hvf_reg2cp_reg(reg));
196
+
197
+ if (ri) {
198
+ if (ri->accessfn) {
199
+ if (ri->accessfn(env, ri, false) != CP_ACCESS_OK) {
200
+ return false;
201
+ }
202
+ }
203
+ if (ri->writefn) {
204
+ ri->writefn(env, ri, val);
205
+ } else {
206
+ CPREG_FIELD64(env, ri) = val;
207
+ }
208
+
209
+ trace_hvf_vgic_write(ri->name, val);
210
+ return true;
211
+ }
212
+
213
+ return false;
214
+}
215
+
216
static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
91
{
217
{
92
- long off = neon_element_offset(reg, ele, size);
218
ARMCPU *arm_cpu = ARM_CPU(cpu);
93
+ long off = neon_element_offset(reg, ele, memop);
219
@@ -XXX,XX +XXX,XX @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
94
220
case SYSREG_OSDLR_EL1:
95
- switch (size) {
221
/* Dummy register */
96
+ switch (memop) {
222
break;
97
+ case MO_8:
223
+ case SYSREG_ICC_AP0R0_EL1:
98
+ tcg_gen_st8_i32(src, cpu_env, off);
224
+ case SYSREG_ICC_AP0R1_EL1:
225
+ case SYSREG_ICC_AP0R2_EL1:
226
+ case SYSREG_ICC_AP0R3_EL1:
227
+ case SYSREG_ICC_AP1R0_EL1:
228
+ case SYSREG_ICC_AP1R1_EL1:
229
+ case SYSREG_ICC_AP1R2_EL1:
230
+ case SYSREG_ICC_AP1R3_EL1:
231
+ case SYSREG_ICC_ASGI1R_EL1:
232
+ case SYSREG_ICC_BPR0_EL1:
233
+ case SYSREG_ICC_BPR1_EL1:
234
+ case SYSREG_ICC_CTLR_EL1:
235
+ case SYSREG_ICC_DIR_EL1:
236
+ case SYSREG_ICC_EOIR0_EL1:
237
+ case SYSREG_ICC_EOIR1_EL1:
238
+ case SYSREG_ICC_HPPIR0_EL1:
239
+ case SYSREG_ICC_HPPIR1_EL1:
240
+ case SYSREG_ICC_IAR0_EL1:
241
+ case SYSREG_ICC_IAR1_EL1:
242
+ case SYSREG_ICC_IGRPEN0_EL1:
243
+ case SYSREG_ICC_IGRPEN1_EL1:
244
+ case SYSREG_ICC_PMR_EL1:
245
+ case SYSREG_ICC_SGI0R_EL1:
246
+ case SYSREG_ICC_SGI1R_EL1:
247
+ case SYSREG_ICC_SRE_EL1:
248
+ /* Call the TCG sysreg handler. This is only safe for GICv3 regs. */
249
+ if (!hvf_sysreg_write_cp(cpu, reg, val)) {
250
+ hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
251
+ }
99
+ break;
252
+ break;
100
+ case MO_16:
253
default:
101
+ tcg_gen_st16_i32(src, cpu_env, off);
254
cpu_synchronize_state(cpu);
102
+ break;
255
trace_hvf_unhandled_sysreg_write(env->pc, reg,
103
case MO_32:
256
diff --git a/target/arm/hvf/trace-events b/target/arm/hvf/trace-events
104
tcg_gen_st_i32(src, cpu_env, off);
105
break;
106
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
107
index XXXXXXX..XXXXXXX 100644
257
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/translate-vfp.c.inc
258
--- a/target/arm/hvf/trace-events
109
+++ b/target/arm/translate-vfp.c.inc
259
+++ b/target/arm/hvf/trace-events
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
260
@@ -XXX,XX +XXX,XX @@ hvf_unknown_hvc(uint64_t x0) "unknown HVC! 0x%016"PRIx64
111
{
261
hvf_unknown_smc(uint64_t x0) "unknown SMC! 0x%016"PRIx64
112
/* VMOV scalar to general purpose register */
262
hvf_exit(uint64_t syndrome, uint32_t ec, uint64_t pc) "exit: 0x%"PRIx64" [ec=0x%x pc=0x%"PRIx64"]"
113
TCGv_i32 tmp;
263
hvf_psci_call(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, uint32_t cpuid) "PSCI Call x0=0x%016"PRIx64" x1=0x%016"PRIx64" x2=0x%016"PRIx64" x3=0x%016"PRIx64" cpu=0x%x"
114
- int pass;
264
+hvf_vgic_write(const char *name, uint64_t val) "vgic write to %s [val=0x%016"PRIx64"]"
115
- uint32_t offset;
265
+hvf_vgic_read(const char *name, uint64_t val) "vgic read from %s [val=0x%016"PRIx64"]"
116
117
- /* SIZE == 2 is a VFP instruction; otherwise NEON. */
118
- if (a->size == 2
119
+ /* SIZE == MO_32 is a VFP instruction; otherwise NEON. */
120
+ if (a->size == MO_32
121
? !dc_isar_feature(aa32_fpsp_v2, s)
122
: !arm_dc_feature(s, ARM_FEATURE_NEON)) {
123
return false;
124
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
125
return false;
126
}
127
128
- offset = a->index << a->size;
129
- pass = extract32(offset, 2, 1);
130
- offset = extract32(offset, 0, 2) * 8;
131
-
132
if (!vfp_access_check(s)) {
133
return true;
134
}
135
136
- tmp = neon_load_reg(a->vn, pass);
137
- switch (a->size) {
138
- case 0:
139
- if (offset) {
140
- tcg_gen_shri_i32(tmp, tmp, offset);
141
- }
142
- if (a->u) {
143
- gen_uxtb(tmp);
144
- } else {
145
- gen_sxtb(tmp);
146
- }
147
- break;
148
- case 1:
149
- if (a->u) {
150
- if (offset) {
151
- tcg_gen_shri_i32(tmp, tmp, 16);
152
- } else {
153
- gen_uxth(tmp);
154
- }
155
- } else {
156
- if (offset) {
157
- tcg_gen_sari_i32(tmp, tmp, 16);
158
- } else {
159
- gen_sxth(tmp);
160
- }
161
- }
162
- break;
163
- case 2:
164
- break;
165
- }
166
+ tmp = tcg_temp_new_i32();
167
+ read_neon_element32(tmp, a->vn, a->index, a->size | (a->u ? 0 : MO_SIGN));
168
store_reg(s, a->rt, tmp);
169
170
return true;
171
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
172
static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
173
{
174
/* VMOV general purpose register to scalar */
175
- TCGv_i32 tmp, tmp2;
176
- int pass;
177
- uint32_t offset;
178
+ TCGv_i32 tmp;
179
180
- /* SIZE == 2 is a VFP instruction; otherwise NEON. */
181
- if (a->size == 2
182
+ /* SIZE == MO_32 is a VFP instruction; otherwise NEON. */
183
+ if (a->size == MO_32
184
? !dc_isar_feature(aa32_fpsp_v2, s)
185
: !arm_dc_feature(s, ARM_FEATURE_NEON)) {
186
return false;
187
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
188
return false;
189
}
190
191
- offset = a->index << a->size;
192
- pass = extract32(offset, 2, 1);
193
- offset = extract32(offset, 0, 2) * 8;
194
-
195
if (!vfp_access_check(s)) {
196
return true;
197
}
198
199
tmp = load_reg(s, a->rt);
200
- switch (a->size) {
201
- case 0:
202
- tmp2 = neon_load_reg(a->vn, pass);
203
- tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
204
- tcg_temp_free_i32(tmp2);
205
- break;
206
- case 1:
207
- tmp2 = neon_load_reg(a->vn, pass);
208
- tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
209
- tcg_temp_free_i32(tmp2);
210
- break;
211
- case 2:
212
- break;
213
- }
214
- neon_store_reg(a->vn, pass, tmp);
215
+ write_neon_element32(tmp, a->vn, a->index, a->size);
216
+ tcg_temp_free_i32(tmp);
217
218
return true;
219
}
220
--
266
--
221
2.20.1
267
2.34.1
222
223
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
Replace all uses of neon_load/store_reg64 within translate-neon.c.inc.
3
Up to now, the finalize_gic_version() code open coded what is essentially
4
4
a support bitmap match between host/emulation environment and desired
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
target GIC type.
6
Message-id: 20201030022618.785675-9-richard.henderson@linaro.org
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
This open coding leads to undesirable side effects. For example, a VM with
8
KVM and -smp 10 will automatically choose GICv3 while the same command
9
line with TCG will stay on GICv2 and fail the launch.
10
11
This patch combines the TCG and KVM matching code paths by making
12
everything a 2 pass process. First, we determine which GIC versions the
13
current environment is able to support, then we go through a single
14
state machine to determine which target GIC mode that means for us.
15
16
After this patch, the only user noticable changes should be consolidated
17
error messages as well as TCG -M virt supporting -smp > 8 automatically.
18
19
Signed-off-by: Alexander Graf <agraf@csgraf.de>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
22
Reviewed-by: Zenghui Yu <yuzenghui@huawei.com>
23
Message-id: 20221223090107.98888-2-agraf@csgraf.de
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
25
---
10
target/arm/translate.c | 26 +++++++++
26
include/hw/arm/virt.h | 15 ++--
11
target/arm/translate-neon.c.inc | 94 ++++++++++++++++-----------------
27
hw/arm/virt.c | 198 ++++++++++++++++++++++--------------------
12
2 files changed, 73 insertions(+), 47 deletions(-)
28
2 files changed, 112 insertions(+), 101 deletions(-)
13
29
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
30
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
15
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
32
--- a/include/hw/arm/virt.h
17
+++ b/target/arm/translate.c
33
+++ b/include/hw/arm/virt.h
18
@@ -XXX,XX +XXX,XX @@ static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
34
@@ -XXX,XX +XXX,XX @@ typedef enum VirtMSIControllerType {
35
} VirtMSIControllerType;
36
37
typedef enum VirtGICType {
38
- VIRT_GIC_VERSION_MAX,
39
- VIRT_GIC_VERSION_HOST,
40
- VIRT_GIC_VERSION_2,
41
- VIRT_GIC_VERSION_3,
42
- VIRT_GIC_VERSION_4,
43
+ VIRT_GIC_VERSION_MAX = 0,
44
+ VIRT_GIC_VERSION_HOST = 1,
45
+ /* The concrete GIC values have to match the GIC version number */
46
+ VIRT_GIC_VERSION_2 = 2,
47
+ VIRT_GIC_VERSION_3 = 3,
48
+ VIRT_GIC_VERSION_4 = 4,
49
VIRT_GIC_VERSION_NOSEL,
50
} VirtGICType;
51
52
+#define VIRT_GIC_VERSION_2_MASK BIT(VIRT_GIC_VERSION_2)
53
+#define VIRT_GIC_VERSION_3_MASK BIT(VIRT_GIC_VERSION_3)
54
+#define VIRT_GIC_VERSION_4_MASK BIT(VIRT_GIC_VERSION_4)
55
+
56
struct VirtMachineClass {
57
MachineClass parent;
58
bool disallow_affinity_adjustment;
59
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/arm/virt.c
62
+++ b/hw/arm/virt.c
63
@@ -XXX,XX +XXX,XX @@ static void virt_set_memmap(VirtMachineState *vms, int pa_bits)
19
}
64
}
20
}
65
}
21
66
22
+static void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
67
+static VirtGICType finalize_gic_version_do(const char *accel_name,
68
+ VirtGICType gic_version,
69
+ int gics_supported,
70
+ unsigned int max_cpus)
23
+{
71
+{
24
+ long off = neon_element_offset(reg, ele, memop);
72
+ /* Convert host/max/nosel to GIC version number */
25
+
73
+ switch (gic_version) {
26
+ switch (memop) {
74
+ case VIRT_GIC_VERSION_HOST:
27
+ case MO_Q:
75
+ if (!kvm_enabled()) {
28
+ tcg_gen_ld_i64(dest, cpu_env, off);
76
+ error_report("gic-version=host requires KVM");
77
+ exit(1);
78
+ }
79
+
80
+ /* For KVM, gic-version=host means gic-version=max */
81
+ return finalize_gic_version_do(accel_name, VIRT_GIC_VERSION_MAX,
82
+ gics_supported, max_cpus);
83
+ case VIRT_GIC_VERSION_MAX:
84
+ if (gics_supported & VIRT_GIC_VERSION_4_MASK) {
85
+ gic_version = VIRT_GIC_VERSION_4;
86
+ } else if (gics_supported & VIRT_GIC_VERSION_3_MASK) {
87
+ gic_version = VIRT_GIC_VERSION_3;
88
+ } else {
89
+ gic_version = VIRT_GIC_VERSION_2;
90
+ }
91
+ break;
92
+ case VIRT_GIC_VERSION_NOSEL:
93
+ if ((gics_supported & VIRT_GIC_VERSION_2_MASK) &&
94
+ max_cpus <= GIC_NCPU) {
95
+ gic_version = VIRT_GIC_VERSION_2;
96
+ } else if (gics_supported & VIRT_GIC_VERSION_3_MASK) {
97
+ /*
98
+ * in case the host does not support v2 emulation or
99
+ * the end-user requested more than 8 VCPUs we now default
100
+ * to v3. In any case defaulting to v2 would be broken.
101
+ */
102
+ gic_version = VIRT_GIC_VERSION_3;
103
+ } else if (max_cpus > GIC_NCPU) {
104
+ error_report("%s only supports GICv2 emulation but more than 8 "
105
+ "vcpus are requested", accel_name);
106
+ exit(1);
107
+ }
108
+ break;
109
+ case VIRT_GIC_VERSION_2:
110
+ case VIRT_GIC_VERSION_3:
111
+ case VIRT_GIC_VERSION_4:
112
+ break;
113
+ }
114
+
115
+ /* Check chosen version is effectively supported */
116
+ switch (gic_version) {
117
+ case VIRT_GIC_VERSION_2:
118
+ if (!(gics_supported & VIRT_GIC_VERSION_2_MASK)) {
119
+ error_report("%s does not support GICv2 emulation", accel_name);
120
+ exit(1);
121
+ }
122
+ break;
123
+ case VIRT_GIC_VERSION_3:
124
+ if (!(gics_supported & VIRT_GIC_VERSION_3_MASK)) {
125
+ error_report("%s does not support GICv3 emulation", accel_name);
126
+ exit(1);
127
+ }
128
+ break;
129
+ case VIRT_GIC_VERSION_4:
130
+ if (!(gics_supported & VIRT_GIC_VERSION_4_MASK)) {
131
+ error_report("%s does not support GICv4 emulation, is virtualization=on?",
132
+ accel_name);
133
+ exit(1);
134
+ }
29
+ break;
135
+ break;
30
+ default:
136
+ default:
31
+ g_assert_not_reached();
137
+ error_report("logic error in finalize_gic_version");
138
+ exit(1);
139
+ break;
32
+ }
140
+ }
141
+
142
+ return gic_version;
33
+}
143
+}
34
+
144
+
35
static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
145
/*
146
* finalize_gic_version - Determines the final gic_version
147
* according to the gic-version property
148
@@ -XXX,XX +XXX,XX @@ static void virt_set_memmap(VirtMachineState *vms, int pa_bits)
149
*/
150
static void finalize_gic_version(VirtMachineState *vms)
36
{
151
{
37
long off = neon_element_offset(reg, ele, memop);
152
+ const char *accel_name = current_accel_name();
38
@@ -XXX,XX +XXX,XX @@ static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
153
unsigned int max_cpus = MACHINE(vms)->smp.max_cpus;
154
+ int gics_supported = 0;
155
156
- if (kvm_enabled()) {
157
- int probe_bitmap;
158
+ /* Determine which GIC versions the current environment supports */
159
+ if (kvm_enabled() && kvm_irqchip_in_kernel()) {
160
+ int probe_bitmap = kvm_arm_vgic_probe();
161
162
- if (!kvm_irqchip_in_kernel()) {
163
- switch (vms->gic_version) {
164
- case VIRT_GIC_VERSION_HOST:
165
- warn_report(
166
- "gic-version=host not relevant with kernel-irqchip=off "
167
- "as only userspace GICv2 is supported. Using v2 ...");
168
- return;
169
- case VIRT_GIC_VERSION_MAX:
170
- case VIRT_GIC_VERSION_NOSEL:
171
- vms->gic_version = VIRT_GIC_VERSION_2;
172
- return;
173
- case VIRT_GIC_VERSION_2:
174
- return;
175
- case VIRT_GIC_VERSION_3:
176
- error_report(
177
- "gic-version=3 is not supported with kernel-irqchip=off");
178
- exit(1);
179
- case VIRT_GIC_VERSION_4:
180
- error_report(
181
- "gic-version=4 is not supported with kernel-irqchip=off");
182
- exit(1);
183
- }
184
- }
185
-
186
- probe_bitmap = kvm_arm_vgic_probe();
187
if (!probe_bitmap) {
188
error_report("Unable to determine GIC version supported by host");
189
exit(1);
190
}
191
192
- switch (vms->gic_version) {
193
- case VIRT_GIC_VERSION_HOST:
194
- case VIRT_GIC_VERSION_MAX:
195
- if (probe_bitmap & KVM_ARM_VGIC_V3) {
196
- vms->gic_version = VIRT_GIC_VERSION_3;
197
- } else {
198
- vms->gic_version = VIRT_GIC_VERSION_2;
199
- }
200
- return;
201
- case VIRT_GIC_VERSION_NOSEL:
202
- if ((probe_bitmap & KVM_ARM_VGIC_V2) && max_cpus <= GIC_NCPU) {
203
- vms->gic_version = VIRT_GIC_VERSION_2;
204
- } else if (probe_bitmap & KVM_ARM_VGIC_V3) {
205
- /*
206
- * in case the host does not support v2 in-kernel emulation or
207
- * the end-user requested more than 8 VCPUs we now default
208
- * to v3. In any case defaulting to v2 would be broken.
209
- */
210
- vms->gic_version = VIRT_GIC_VERSION_3;
211
- } else if (max_cpus > GIC_NCPU) {
212
- error_report("host only supports in-kernel GICv2 emulation "
213
- "but more than 8 vcpus are requested");
214
- exit(1);
215
- }
216
- break;
217
- case VIRT_GIC_VERSION_2:
218
- case VIRT_GIC_VERSION_3:
219
- break;
220
- case VIRT_GIC_VERSION_4:
221
- error_report("gic-version=4 is not supported with KVM");
222
- exit(1);
223
+ if (probe_bitmap & KVM_ARM_VGIC_V2) {
224
+ gics_supported |= VIRT_GIC_VERSION_2_MASK;
225
}
226
-
227
- /* Check chosen version is effectively supported by the host */
228
- if (vms->gic_version == VIRT_GIC_VERSION_2 &&
229
- !(probe_bitmap & KVM_ARM_VGIC_V2)) {
230
- error_report("host does not support in-kernel GICv2 emulation");
231
- exit(1);
232
- } else if (vms->gic_version == VIRT_GIC_VERSION_3 &&
233
- !(probe_bitmap & KVM_ARM_VGIC_V3)) {
234
- error_report("host does not support in-kernel GICv3 emulation");
235
- exit(1);
236
+ if (probe_bitmap & KVM_ARM_VGIC_V3) {
237
+ gics_supported |= VIRT_GIC_VERSION_3_MASK;
238
}
239
- return;
240
- }
241
-
242
- /* TCG mode */
243
- switch (vms->gic_version) {
244
- case VIRT_GIC_VERSION_NOSEL:
245
- vms->gic_version = VIRT_GIC_VERSION_2;
246
- break;
247
- case VIRT_GIC_VERSION_MAX:
248
+ } else if (kvm_enabled() && !kvm_irqchip_in_kernel()) {
249
+ /* KVM w/o kernel irqchip can only deal with GICv2 */
250
+ gics_supported |= VIRT_GIC_VERSION_2_MASK;
251
+ accel_name = "KVM with kernel-irqchip=off";
252
+ } else {
253
+ gics_supported |= VIRT_GIC_VERSION_2_MASK;
254
if (module_object_class_by_name("arm-gicv3")) {
255
- /* CONFIG_ARM_GICV3_TCG was set */
256
+ gics_supported |= VIRT_GIC_VERSION_3_MASK;
257
if (vms->virt) {
258
/* GICv4 only makes sense if CPU has EL2 */
259
- vms->gic_version = VIRT_GIC_VERSION_4;
260
- } else {
261
- vms->gic_version = VIRT_GIC_VERSION_3;
262
+ gics_supported |= VIRT_GIC_VERSION_4_MASK;
263
}
264
- } else {
265
- vms->gic_version = VIRT_GIC_VERSION_2;
266
}
267
- break;
268
- case VIRT_GIC_VERSION_HOST:
269
- error_report("gic-version=host requires KVM");
270
- exit(1);
271
- case VIRT_GIC_VERSION_4:
272
- if (!vms->virt) {
273
- error_report("gic-version=4 requires virtualization enabled");
274
- exit(1);
275
- }
276
- break;
277
- case VIRT_GIC_VERSION_2:
278
- case VIRT_GIC_VERSION_3:
279
- break;
39
}
280
}
281
+
282
+ /*
283
+ * Then convert helpers like host/max to concrete GIC versions and ensure
284
+ * the desired version is supported
285
+ */
286
+ vms->gic_version = finalize_gic_version_do(accel_name, vms->gic_version,
287
+ gics_supported, max_cpus);
40
}
288
}
41
289
42
+static void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
290
/*
43
+{
44
+ long off = neon_element_offset(reg, ele, memop);
45
+
46
+ switch (memop) {
47
+ case MO_64:
48
+ tcg_gen_st_i64(src, cpu_env, off);
49
+ break;
50
+ default:
51
+ g_assert_not_reached();
52
+ }
53
+}
54
+
55
static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
56
{
57
TCGv_ptr ret = tcg_temp_new_ptr();
58
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/translate-neon.c.inc
61
+++ b/target/arm/translate-neon.c.inc
62
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_env_64(DisasContext *s, arg_2reg_shift *a,
63
for (pass = 0; pass < a->q + 1; pass++) {
64
TCGv_i64 tmp = tcg_temp_new_i64();
65
66
- neon_load_reg64(tmp, a->vm + pass);
67
+ read_neon_element64(tmp, a->vm, pass, MO_64);
68
fn(tmp, cpu_env, tmp, constimm);
69
- neon_store_reg64(tmp, a->vd + pass);
70
+ write_neon_element64(tmp, a->vd, pass, MO_64);
71
tcg_temp_free_i64(tmp);
72
}
73
tcg_temp_free_i64(constimm);
74
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_64(DisasContext *s, arg_2reg_shift *a,
75
rd = tcg_temp_new_i32();
76
77
/* Load both inputs first to avoid potential overwrite if rm == rd */
78
- neon_load_reg64(rm1, a->vm);
79
- neon_load_reg64(rm2, a->vm + 1);
80
+ read_neon_element64(rm1, a->vm, 0, MO_64);
81
+ read_neon_element64(rm2, a->vm, 1, MO_64);
82
83
shiftfn(rm1, rm1, constimm);
84
narrowfn(rd, cpu_env, rm1);
85
@@ -XXX,XX +XXX,XX @@ static bool do_vshll_2sh(DisasContext *s, arg_2reg_shift *a,
86
tcg_gen_shli_i64(tmp, tmp, a->shift);
87
tcg_gen_andi_i64(tmp, tmp, ~widen_mask);
88
}
89
- neon_store_reg64(tmp, a->vd);
90
+ write_neon_element64(tmp, a->vd, 0, MO_64);
91
92
widenfn(tmp, rm1);
93
tcg_temp_free_i32(rm1);
94
@@ -XXX,XX +XXX,XX @@ static bool do_vshll_2sh(DisasContext *s, arg_2reg_shift *a,
95
tcg_gen_shli_i64(tmp, tmp, a->shift);
96
tcg_gen_andi_i64(tmp, tmp, ~widen_mask);
97
}
98
- neon_store_reg64(tmp, a->vd + 1);
99
+ write_neon_element64(tmp, a->vd, 1, MO_64);
100
tcg_temp_free_i64(tmp);
101
return true;
102
}
103
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
104
rm_64 = tcg_temp_new_i64();
105
106
if (src1_wide) {
107
- neon_load_reg64(rn0_64, a->vn);
108
+ read_neon_element64(rn0_64, a->vn, 0, MO_64);
109
} else {
110
TCGv_i32 tmp = tcg_temp_new_i32();
111
read_neon_element32(tmp, a->vn, 0, MO_32);
112
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
113
* avoid incorrect results if a narrow input overlaps with the result.
114
*/
115
if (src1_wide) {
116
- neon_load_reg64(rn1_64, a->vn + 1);
117
+ read_neon_element64(rn1_64, a->vn, 1, MO_64);
118
} else {
119
TCGv_i32 tmp = tcg_temp_new_i32();
120
read_neon_element32(tmp, a->vn, 1, MO_32);
121
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
122
rm = tcg_temp_new_i32();
123
read_neon_element32(rm, a->vm, 1, MO_32);
124
125
- neon_store_reg64(rn0_64, a->vd);
126
+ write_neon_element64(rn0_64, a->vd, 0, MO_64);
127
128
widenfn(rm_64, rm);
129
tcg_temp_free_i32(rm);
130
opfn(rn1_64, rn1_64, rm_64);
131
- neon_store_reg64(rn1_64, a->vd + 1);
132
+ write_neon_element64(rn1_64, a->vd, 1, MO_64);
133
134
tcg_temp_free_i64(rn0_64);
135
tcg_temp_free_i64(rn1_64);
136
@@ -XXX,XX +XXX,XX @@ static bool do_narrow_3d(DisasContext *s, arg_3diff *a,
137
rd0 = tcg_temp_new_i32();
138
rd1 = tcg_temp_new_i32();
139
140
- neon_load_reg64(rn_64, a->vn);
141
- neon_load_reg64(rm_64, a->vm);
142
+ read_neon_element64(rn_64, a->vn, 0, MO_64);
143
+ read_neon_element64(rm_64, a->vm, 0, MO_64);
144
145
opfn(rn_64, rn_64, rm_64);
146
147
narrowfn(rd0, rn_64);
148
149
- neon_load_reg64(rn_64, a->vn + 1);
150
- neon_load_reg64(rm_64, a->vm + 1);
151
+ read_neon_element64(rn_64, a->vn, 1, MO_64);
152
+ read_neon_element64(rm_64, a->vm, 1, MO_64);
153
154
opfn(rn_64, rn_64, rm_64);
155
156
@@ -XXX,XX +XXX,XX @@ static bool do_long_3d(DisasContext *s, arg_3diff *a,
157
/* Don't store results until after all loads: they might overlap */
158
if (accfn) {
159
tmp = tcg_temp_new_i64();
160
- neon_load_reg64(tmp, a->vd);
161
+ read_neon_element64(tmp, a->vd, 0, MO_64);
162
accfn(tmp, tmp, rd0);
163
- neon_store_reg64(tmp, a->vd);
164
- neon_load_reg64(tmp, a->vd + 1);
165
+ write_neon_element64(tmp, a->vd, 0, MO_64);
166
+ read_neon_element64(tmp, a->vd, 1, MO_64);
167
accfn(tmp, tmp, rd1);
168
- neon_store_reg64(tmp, a->vd + 1);
169
+ write_neon_element64(tmp, a->vd, 1, MO_64);
170
tcg_temp_free_i64(tmp);
171
} else {
172
- neon_store_reg64(rd0, a->vd);
173
- neon_store_reg64(rd1, a->vd + 1);
174
+ write_neon_element64(rd0, a->vd, 0, MO_64);
175
+ write_neon_element64(rd1, a->vd, 1, MO_64);
176
}
177
178
tcg_temp_free_i64(rd0);
179
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_long(DisasContext *s, arg_2scalar *a,
180
181
if (accfn) {
182
TCGv_i64 t64 = tcg_temp_new_i64();
183
- neon_load_reg64(t64, a->vd);
184
+ read_neon_element64(t64, a->vd, 0, MO_64);
185
accfn(t64, t64, rn0_64);
186
- neon_store_reg64(t64, a->vd);
187
- neon_load_reg64(t64, a->vd + 1);
188
+ write_neon_element64(t64, a->vd, 0, MO_64);
189
+ read_neon_element64(t64, a->vd, 1, MO_64);
190
accfn(t64, t64, rn1_64);
191
- neon_store_reg64(t64, a->vd + 1);
192
+ write_neon_element64(t64, a->vd, 1, MO_64);
193
tcg_temp_free_i64(t64);
194
} else {
195
- neon_store_reg64(rn0_64, a->vd);
196
- neon_store_reg64(rn1_64, a->vd + 1);
197
+ write_neon_element64(rn0_64, a->vd, 0, MO_64);
198
+ write_neon_element64(rn1_64, a->vd, 1, MO_64);
199
}
200
tcg_temp_free_i64(rn0_64);
201
tcg_temp_free_i64(rn1_64);
202
@@ -XXX,XX +XXX,XX @@ static bool trans_VEXT(DisasContext *s, arg_VEXT *a)
203
right = tcg_temp_new_i64();
204
dest = tcg_temp_new_i64();
205
206
- neon_load_reg64(right, a->vn);
207
- neon_load_reg64(left, a->vm);
208
+ read_neon_element64(right, a->vn, 0, MO_64);
209
+ read_neon_element64(left, a->vm, 0, MO_64);
210
tcg_gen_extract2_i64(dest, right, left, a->imm * 8);
211
- neon_store_reg64(dest, a->vd);
212
+ write_neon_element64(dest, a->vd, 0, MO_64);
213
214
tcg_temp_free_i64(left);
215
tcg_temp_free_i64(right);
216
@@ -XXX,XX +XXX,XX @@ static bool trans_VEXT(DisasContext *s, arg_VEXT *a)
217
destright = tcg_temp_new_i64();
218
219
if (a->imm < 8) {
220
- neon_load_reg64(right, a->vn);
221
- neon_load_reg64(middle, a->vn + 1);
222
+ read_neon_element64(right, a->vn, 0, MO_64);
223
+ read_neon_element64(middle, a->vn, 1, MO_64);
224
tcg_gen_extract2_i64(destright, right, middle, a->imm * 8);
225
- neon_load_reg64(left, a->vm);
226
+ read_neon_element64(left, a->vm, 0, MO_64);
227
tcg_gen_extract2_i64(destleft, middle, left, a->imm * 8);
228
} else {
229
- neon_load_reg64(right, a->vn + 1);
230
- neon_load_reg64(middle, a->vm);
231
+ read_neon_element64(right, a->vn, 1, MO_64);
232
+ read_neon_element64(middle, a->vm, 0, MO_64);
233
tcg_gen_extract2_i64(destright, right, middle, (a->imm - 8) * 8);
234
- neon_load_reg64(left, a->vm + 1);
235
+ read_neon_element64(left, a->vm, 1, MO_64);
236
tcg_gen_extract2_i64(destleft, middle, left, (a->imm - 8) * 8);
237
}
238
239
- neon_store_reg64(destright, a->vd);
240
- neon_store_reg64(destleft, a->vd + 1);
241
+ write_neon_element64(destright, a->vd, 0, MO_64);
242
+ write_neon_element64(destleft, a->vd, 1, MO_64);
243
244
tcg_temp_free_i64(destright);
245
tcg_temp_free_i64(destleft);
246
@@ -XXX,XX +XXX,XX @@ static bool do_2misc_pairwise(DisasContext *s, arg_2misc *a,
247
248
if (accfn) {
249
TCGv_i64 tmp64 = tcg_temp_new_i64();
250
- neon_load_reg64(tmp64, a->vd + pass);
251
+ read_neon_element64(tmp64, a->vd, pass, MO_64);
252
accfn(rd_64, tmp64, rd_64);
253
tcg_temp_free_i64(tmp64);
254
}
255
- neon_store_reg64(rd_64, a->vd + pass);
256
+ write_neon_element64(rd_64, a->vd, pass, MO_64);
257
tcg_temp_free_i64(rd_64);
258
}
259
return true;
260
@@ -XXX,XX +XXX,XX @@ static bool do_vmovn(DisasContext *s, arg_2misc *a,
261
rd0 = tcg_temp_new_i32();
262
rd1 = tcg_temp_new_i32();
263
264
- neon_load_reg64(rm, a->vm);
265
+ read_neon_element64(rm, a->vm, 0, MO_64);
266
narrowfn(rd0, cpu_env, rm);
267
- neon_load_reg64(rm, a->vm + 1);
268
+ read_neon_element64(rm, a->vm, 1, MO_64);
269
narrowfn(rd1, cpu_env, rm);
270
write_neon_element32(rd0, a->vd, 0, MO_32);
271
write_neon_element32(rd1, a->vd, 1, MO_32);
272
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
273
274
widenfn(rd, rm0);
275
tcg_gen_shli_i64(rd, rd, 8 << a->size);
276
- neon_store_reg64(rd, a->vd);
277
+ write_neon_element64(rd, a->vd, 0, MO_64);
278
widenfn(rd, rm1);
279
tcg_gen_shli_i64(rd, rd, 8 << a->size);
280
- neon_store_reg64(rd, a->vd + 1);
281
+ write_neon_element64(rd, a->vd, 1, MO_64);
282
283
tcg_temp_free_i64(rd);
284
tcg_temp_free_i32(rm0);
285
@@ -XXX,XX +XXX,XX @@ static bool trans_VSWP(DisasContext *s, arg_2misc *a)
286
rm = tcg_temp_new_i64();
287
rd = tcg_temp_new_i64();
288
for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
289
- neon_load_reg64(rm, a->vm + pass);
290
- neon_load_reg64(rd, a->vd + pass);
291
- neon_store_reg64(rm, a->vd + pass);
292
- neon_store_reg64(rd, a->vm + pass);
293
+ read_neon_element64(rm, a->vm, pass, MO_64);
294
+ read_neon_element64(rd, a->vd, pass, MO_64);
295
+ write_neon_element64(rm, a->vd, pass, MO_64);
296
+ write_neon_element64(rd, a->vm, pass, MO_64);
297
}
298
tcg_temp_free_i64(rm);
299
tcg_temp_free_i64(rd);
300
--
291
--
301
2.20.1
292
2.34.1
302
303
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
Use the BIT_ULL() macro to ensure we use 64-bit arithmetic.
3
Let's explicitly list out all accelerators that we support when trying to
4
This fixes the following Coverity issue (OVERFLOW_BEFORE_WIDEN):
4
determine the supported set of GIC versions. KVM was already separate, so
5
the only missing one is HVF which simply reuses all of TCG's emulation
6
code and thus has the same compatibility matrix.
5
7
6
CID 1432363 (#1 of 1): Unintentional integer overflow:
8
Signed-off-by: Alexander Graf <agraf@csgraf.de>
7
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
overflow_before_widen:
10
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
9
Potentially overflowing expression 1 << scale with type int
11
Reviewed-by: Zenghui Yu <yuzenghui@huawei.com>
10
(32 bits, signed) is evaluated using 32-bit arithmetic, and
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
then used in a context that expects an expression of type
13
Message-id: 20221223090107.98888-3-agraf@csgraf.de
12
hwaddr (64 bits, unsigned).
14
[PMM: Added qtest to the list of accelerators]
13
14
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Acked-by: Eric Auger <eric.auger@redhat.com>
16
Message-id: 20201030144617.1535064-1-philmd@redhat.com
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
16
---
20
hw/arm/smmuv3.c | 3 ++-
17
hw/arm/virt.c | 7 ++++++-
21
1 file changed, 2 insertions(+), 1 deletion(-)
18
1 file changed, 6 insertions(+), 1 deletion(-)
22
19
23
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
20
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
24
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/smmuv3.c
22
--- a/hw/arm/virt.c
26
+++ b/hw/arm/smmuv3.c
23
+++ b/hw/arm/virt.c
27
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@
28
*/
25
#include "sysemu/numa.h"
29
26
#include "sysemu/runstate.h"
30
#include "qemu/osdep.h"
27
#include "sysemu/tpm.h"
31
+#include "qemu/bitops.h"
28
+#include "sysemu/tcg.h"
32
#include "hw/irq.h"
29
#include "sysemu/kvm.h"
33
#include "hw/sysbus.h"
30
#include "sysemu/hvf.h"
34
#include "migration/vmstate.h"
31
+#include "sysemu/qtest.h"
35
@@ -XXX,XX +XXX,XX @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
32
#include "hw/loader.h"
36
scale = CMD_SCALE(cmd);
33
#include "qapi/error.h"
37
num = CMD_NUM(cmd);
34
#include "qemu/bitops.h"
38
ttl = CMD_TTL(cmd);
35
@@ -XXX,XX +XXX,XX @@ static void finalize_gic_version(VirtMachineState *vms)
39
- num_pages = (num + 1) * (1 << (scale));
36
/* KVM w/o kernel irqchip can only deal with GICv2 */
40
+ num_pages = (num + 1) * BIT_ULL(scale);
37
gics_supported |= VIRT_GIC_VERSION_2_MASK;
38
accel_name = "KVM with kernel-irqchip=off";
39
- } else {
40
+ } else if (tcg_enabled() || hvf_enabled() || qtest_enabled()) {
41
gics_supported |= VIRT_GIC_VERSION_2_MASK;
42
if (module_object_class_by_name("arm-gicv3")) {
43
gics_supported |= VIRT_GIC_VERSION_3_MASK;
44
@@ -XXX,XX +XXX,XX @@ static void finalize_gic_version(VirtMachineState *vms)
45
gics_supported |= VIRT_GIC_VERSION_4_MASK;
46
}
47
}
48
+ } else {
49
+ error_report("Unsupported accelerator, can not determine GIC support");
50
+ exit(1);
41
}
51
}
42
52
43
if (type == SMMU_CMD_TLBI_NH_VA) {
53
/*
44
--
54
--
45
2.20.1
55
2.34.1
46
56
47
57
diff view generated by jsdifflib
1
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
2
2
3
When booting a CPU with EL3 using the -kernel flag, set up CPTR_EL3 so
3
Cortex-A76 supports 40bits of address space. sbsa-ref's memory
4
that SVE will not trap to EL3.
4
starts above this limit.
5
5
6
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
6
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20201030151541.11976-1-remi@remlab.net
9
Message-id: 20230126114416.2447685-1-marcin.juszkiewicz@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
hw/arm/boot.c | 3 +++
12
hw/arm/sbsa-ref.c | 1 -
12
1 file changed, 3 insertions(+)
13
1 file changed, 1 deletion(-)
13
14
14
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/boot.c
17
--- a/hw/arm/sbsa-ref.c
17
+++ b/hw/arm/boot.c
18
+++ b/hw/arm/sbsa-ref.c
18
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
19
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
19
if (cpu_isar_feature(aa64_mte, cpu)) {
20
static const char * const valid_cpus[] = {
20
env->cp15.scr_el3 |= SCR_ATA;
21
ARM_CPU_TYPE_NAME("cortex-a57"),
21
}
22
ARM_CPU_TYPE_NAME("cortex-a72"),
22
+ if (cpu_isar_feature(aa64_sve, cpu)) {
23
- ARM_CPU_TYPE_NAME("cortex-a76"),
23
+ env->cp15.cptr_el[3] |= CPTR_EZ;
24
ARM_CPU_TYPE_NAME("neoverse-n1"),
24
+ }
25
ARM_CPU_TYPE_NAME("max"),
25
/* AArch64 kernels never boot in secure mode */
26
};
26
assert(!info->secure_boot);
27
/* This hook is only supported for AArch32 currently:
28
--
27
--
29
2.20.1
28
2.34.1
30
29
31
30
diff view generated by jsdifflib
1
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
1
The encodings 0,0,C7,C9,0 and 0,0,C7,C9,1 are AT SP1E1RP and AT
2
S1E1WP, but our ARMCPRegInfo definitions for them incorrectly name
3
them AT S1E1R and AT S1E1W (which are entirely different
4
instructions). Fix the names.
2
5
3
HCR should be applied when NS is set, not when it is cleared.
6
(This has no guest-visible effect as the names are for debug purposes
7
only.)
4
8
5
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Tested-by: Fuad Tabba <tabba@google.com>
12
Message-id: 20230130182459.3309057-2-peter.maydell@linaro.org
13
Message-id: 20230127175507.2895013-2-peter.maydell@linaro.org
8
---
14
---
9
target/arm/helper.c | 5 ++---
15
target/arm/helper.c | 4 ++--
10
1 file changed, 2 insertions(+), 3 deletions(-)
16
1 file changed, 2 insertions(+), 2 deletions(-)
11
17
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
20
--- a/target/arm/helper.c
15
+++ b/target/arm/helper.c
21
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
22
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vhe_reginfo[] = {
17
23
18
/*
24
#ifndef CONFIG_USER_ONLY
19
* Non-IS variants of TLB operations are upgraded to
25
static const ARMCPRegInfo ats1e1_reginfo[] = {
20
- * IS versions if we are at NS EL1 and HCR_EL2.FB is set to
26
- { .name = "AT_S1E1R", .state = ARM_CP_STATE_AA64,
21
+ * IS versions if we are at EL1 and HCR_EL2.FB is effectively set to
27
+ { .name = "AT_S1E1RP", .state = ARM_CP_STATE_AA64,
22
* force broadcast of these operations.
28
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 0,
23
*/
29
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
24
static bool tlb_force_broadcast(CPUARMState *env)
30
.writefn = ats_write64 },
25
{
31
- { .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64,
26
- return (env->cp15.hcr_el2 & HCR_FB) &&
32
+ { .name = "AT_S1E1WP", .state = ARM_CP_STATE_AA64,
27
- arm_current_el(env) == 1 && arm_is_secure_below_el3(env);
33
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1,
28
+ return arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_FB);
34
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
29
}
35
.writefn = ats_write64 },
30
31
static void tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri,
32
--
36
--
33
2.20.1
37
2.34.1
34
35
diff view generated by jsdifflib
1
The helper functions for performing the udot/sdot operations against
1
The AArch32 ATS12NSO* address translation operations are supposed to
2
a scalar were not using an address-swizzling macro when converting
2
trap to either EL2 or EL3 if they're executed at Secure EL1 (which
3
the index of the scalar element into a pointer into the vm array.
3
can only happen if EL3 is AArch64). We implement this, but we got
4
This had no effect on little-endian hosts but meant we generated
4
the syndrome value wrong: like other traps to EL2 or EL3 on an
5
incorrect results on big-endian hosts.
5
AArch32 cpreg access, they should report the 0x3 syndrome, not the
6
0x0 'uncategorized' syndrome. This is clear in the access pseudocode
7
for these instructions.
6
8
7
For these insns, the index is indexing over group of 4 8-bit values,
9
Fix the syndrome value for these operations by correcting the
8
so 32 bits per indexed entity, and H4() is therefore what we want.
10
returned value from the ats_access() function.
9
(For Neon the only possible input indexes are 0 and 1.)
10
11
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Tested-by: Fuad Tabba <tabba@google.com>
14
Message-id: 20201028191712.4910-3-peter.maydell@linaro.org
15
Message-id: 20230130182459.3309057-3-peter.maydell@linaro.org
16
Message-id: 20230127175507.2895013-3-peter.maydell@linaro.org
15
---
17
---
16
target/arm/vec_helper.c | 4 ++--
18
target/arm/helper.c | 4 ++--
17
1 file changed, 2 insertions(+), 2 deletions(-)
19
1 file changed, 2 insertions(+), 2 deletions(-)
18
20
19
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/vec_helper.c
23
--- a/target/arm/helper.c
22
+++ b/target/arm/vec_helper.c
24
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_sdot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
25
@@ -XXX,XX +XXX,XX @@ static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri,
24
intptr_t index = simd_data(desc);
26
if (arm_current_el(env) == 1) {
25
uint32_t *d = vd;
27
if (arm_is_secure_below_el3(env)) {
26
int8_t *n = vn;
28
if (env->cp15.scr_el3 & SCR_EEL2) {
27
- int8_t *m_indexed = (int8_t *)vm + index * 4;
29
- return CP_ACCESS_TRAP_UNCATEGORIZED_EL2;
28
+ int8_t *m_indexed = (int8_t *)vm + H4(index) * 4;
30
+ return CP_ACCESS_TRAP_EL2;
29
31
}
30
/* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd.
32
- return CP_ACCESS_TRAP_UNCATEGORIZED_EL3;
31
* Otherwise opr_sz is a multiple of 16.
33
+ return CP_ACCESS_TRAP_EL3;
32
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_udot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
34
}
33
intptr_t index = simd_data(desc);
35
return CP_ACCESS_TRAP_UNCATEGORIZED;
34
uint32_t *d = vd;
36
}
35
uint8_t *n = vn;
36
- uint8_t *m_indexed = (uint8_t *)vm + index * 4;
37
+ uint8_t *m_indexed = (uint8_t *)vm + H4(index) * 4;
38
39
/* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd.
40
* Otherwise opr_sz is a multiple of 16.
41
--
37
--
42
2.20.1
38
2.34.1
43
44
diff view generated by jsdifflib
New patch
1
We added the CPAccessResult values CP_ACCESS_TRAP_UNCATEGORIZED_EL2
2
and CP_ACCESS_TRAP_UNCATEGORIZED_EL3 purely in order to use them in
3
the ats_access() function, but doing so was incorrect (a bug fixed in
4
a previous commit). There aren't any cases where we want an access
5
function to be able to request a trap to EL2 or EL3 with a zero
6
syndrome value, so remove these enum values.
1
7
8
As well as cleaning up dead code, the motivation here is that
9
we'd like to implement fine-grained-trap handling in
10
helper_access_check_cp_reg(). Although the fine-grained traps
11
to EL2 are always lower priority than trap-to-same-EL and
12
higher priority than trap-to-EL3, they are in the middle of
13
various other kinds of trap-to-EL2. Knowing that a trap-to-EL2
14
must always for us have the same syndrome (ie that an access
15
function will return CP_ACCESS_TRAP_EL2 and there is no other
16
kind of trap-to-EL2 enum value) means we don't have to try
17
to choose which of the two syndrome values to report if the
18
access would trap to EL2 both for the fine-grained-trap and
19
because the access function requires it.
20
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Tested-by: Fuad Tabba <tabba@google.com>
24
Message-id: 20230130182459.3309057-4-peter.maydell@linaro.org
25
Message-id: 20230127175507.2895013-4-peter.maydell@linaro.org
26
---
27
target/arm/cpregs.h | 4 ++--
28
target/arm/op_helper.c | 2 ++
29
2 files changed, 4 insertions(+), 2 deletions(-)
30
31
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/cpregs.h
34
+++ b/target/arm/cpregs.h
35
@@ -XXX,XX +XXX,XX @@ typedef enum CPAccessResult {
36
* Access fails and results in an exception syndrome 0x0 ("uncategorized").
37
* Note that this is not a catch-all case -- the set of cases which may
38
* result in this failure is specifically defined by the architecture.
39
+ * This trap is always to the usual target EL, never directly to a
40
+ * specified target EL.
41
*/
42
CP_ACCESS_TRAP_UNCATEGORIZED = (2 << 2),
43
- CP_ACCESS_TRAP_UNCATEGORIZED_EL2 = CP_ACCESS_TRAP_UNCATEGORIZED | 2,
44
- CP_ACCESS_TRAP_UNCATEGORIZED_EL3 = CP_ACCESS_TRAP_UNCATEGORIZED | 3,
45
} CPAccessResult;
46
47
typedef struct ARMCPRegInfo ARMCPRegInfo;
48
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/op_helper.c
51
+++ b/target/arm/op_helper.c
52
@@ -XXX,XX +XXX,XX @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key,
53
case CP_ACCESS_TRAP:
54
break;
55
case CP_ACCESS_TRAP_UNCATEGORIZED:
56
+ /* Only CP_ACCESS_TRAP traps are direct to a specified EL */
57
+ assert((res & CP_ACCESS_EL_MASK) == 0);
58
if (cpu_isar_feature(aa64_ids, cpu) && isread &&
59
arm_cpreg_in_idspace(ri)) {
60
/*
61
--
62
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Rearrange the code in do_coproc_insn() so that we calculate the
2
syndrome value for a potential trap early; we're about to add a
3
second check that wants this value earlier than where it is currently
4
determined.
2
5
3
This seems a bit more readable than using offsetof CPU_DoubleU.
6
(Specifically, a trap to EL2 because of HSTR_EL2 should take
7
priority over an UNDEF to EL1, even when the UNDEF is because
8
the register does not exist at all or because its ri->access
9
bits non-configurably fail the access. So the check we put in
10
for HSTR_EL2 trapping at EL1 (which needs the syndrome) is
11
going to have to be done before the check "is the ARMCPRegInfo
12
pointer NULL".)
4
13
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
This commit is just code motion; the change to HSTR_EL2
6
Message-id: 20201030022618.785675-5-richard.henderson@linaro.org
15
handling that will use the 'syndrome' variable is in a
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
subsequent commit.
17
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Tested-by: Fuad Tabba <tabba@google.com>
21
Message-id: 20230130182459.3309057-5-peter.maydell@linaro.org
22
Message-id: 20230127175507.2895013-5-peter.maydell@linaro.org
9
---
23
---
10
target/arm/translate.c | 13 ++++---------
24
target/arm/translate.c | 83 +++++++++++++++++++++---------------------
11
1 file changed, 4 insertions(+), 9 deletions(-)
25
1 file changed, 41 insertions(+), 42 deletions(-)
12
26
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
27
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
29
--- a/target/arm/translate.c
16
+++ b/target/arm/translate.c
30
+++ b/target/arm/translate.c
17
@@ -XXX,XX +XXX,XX @@ static long neon_element_offset(int reg, int element, MemOp size)
31
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
18
return neon_full_reg_offset(reg) + ofs;
32
const ARMCPRegInfo *ri = get_arm_cp_reginfo(s->cp_regs, key);
19
}
33
TCGv_ptr tcg_ri = NULL;
20
34
bool need_exit_tb;
21
-static inline long vfp_reg_offset(bool dp, unsigned reg)
35
+ uint32_t syndrome;
22
+/* Return the offset of a VFP Dreg (dp = true) or VFP Sreg (dp = false). */
36
+
23
+static long vfp_reg_offset(bool dp, unsigned reg)
37
+ /*
24
{
38
+ * Note that since we are an implementation which takes an
25
if (dp) {
39
+ * exception on a trapped conditional instruction only if the
26
- return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
40
+ * instruction passes its condition code check, we can take
27
+ return neon_element_offset(reg, 0, MO_64);
41
+ * advantage of the clause in the ARM ARM that allows us to set
28
} else {
42
+ * the COND field in the instruction to 0xE in all cases.
29
- long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
43
+ * We could fish the actual condition out of the insn (ARM)
30
- if (reg & 1) {
44
+ * or the condexec bits (Thumb) but it isn't necessary.
31
- ofs += offsetof(CPU_DoubleU, l.upper);
45
+ */
32
- } else {
46
+ switch (cpnum) {
33
- ofs += offsetof(CPU_DoubleU, l.lower);
47
+ case 14:
48
+ if (is64) {
49
+ syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
50
+ isread, false);
51
+ } else {
52
+ syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
53
+ rt, isread, false);
54
+ }
55
+ break;
56
+ case 15:
57
+ if (is64) {
58
+ syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
59
+ isread, false);
60
+ } else {
61
+ syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
62
+ rt, isread, false);
63
+ }
64
+ break;
65
+ default:
66
+ /*
67
+ * ARMv8 defines that only coprocessors 14 and 15 exist,
68
+ * so this can only happen if this is an ARMv7 or earlier CPU,
69
+ * in which case the syndrome information won't actually be
70
+ * guest visible.
71
+ */
72
+ assert(!arm_dc_feature(s, ARM_FEATURE_V8));
73
+ syndrome = syn_uncategorized();
74
+ break;
75
+ }
76
77
if (!ri) {
78
/*
79
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
80
* Note that on XScale all cp0..c13 registers do an access check
81
* call in order to handle c15_cpar.
82
*/
83
- uint32_t syndrome;
84
-
85
- /*
86
- * Note that since we are an implementation which takes an
87
- * exception on a trapped conditional instruction only if the
88
- * instruction passes its condition code check, we can take
89
- * advantage of the clause in the ARM ARM that allows us to set
90
- * the COND field in the instruction to 0xE in all cases.
91
- * We could fish the actual condition out of the insn (ARM)
92
- * or the condexec bits (Thumb) but it isn't necessary.
93
- */
94
- switch (cpnum) {
95
- case 14:
96
- if (is64) {
97
- syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
98
- isread, false);
99
- } else {
100
- syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
101
- rt, isread, false);
102
- }
103
- break;
104
- case 15:
105
- if (is64) {
106
- syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
107
- isread, false);
108
- } else {
109
- syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
110
- rt, isread, false);
111
- }
112
- break;
113
- default:
114
- /*
115
- * ARMv8 defines that only coprocessors 14 and 15 exist,
116
- * so this can only happen if this is an ARMv7 or earlier CPU,
117
- * in which case the syndrome information won't actually be
118
- * guest visible.
119
- */
120
- assert(!arm_dc_feature(s, ARM_FEATURE_V8));
121
- syndrome = syn_uncategorized();
122
- break;
34
- }
123
- }
35
- return ofs;
124
-
36
+ return neon_element_offset(reg >> 1, reg & 1, MO_32);
125
gen_set_condexec(s);
37
}
126
gen_update_pc(s, 0);
38
}
127
tcg_ri = tcg_temp_new_ptr();
39
40
--
128
--
41
2.20.1
129
2.34.1
42
43
diff view generated by jsdifflib
1
From: AlexChen <alex.chen@huawei.com>
1
The HSTR_EL2 register has a collection of trap bits which allow
2
trapping to EL2 for AArch32 EL0 or EL1 accesses to coprocessor
3
registers. The specification of these bits is that when the bit is
4
set we should trap
5
* EL1 accesses
6
* EL0 accesses, if the access is not UNDEFINED when the
7
trap bit is 0
2
8
3
In omap_lcd_interrupts(), the pointer omap_lcd is dereferinced before
9
In other words, all UNDEF traps from EL0 to EL1 take precedence over
4
being check if it is valid, which may lead to NULL pointer dereference.
10
the HSTR_EL2 trap to EL2. (Since this is all AArch32, the only kind
5
So move the assignment to surface after checking that the omap_lcd is valid
11
of trap-to-EL1 is the UNDEF.)
6
and move surface_bits_per_pixel(surface) to after the surface assignment.
7
12
8
Reported-by: Euler Robot <euler.robot@huawei.com>
13
Our implementation doesn't quite get this right -- we check for traps
9
Signed-off-by: AlexChen <alex.chen@huawei.com>
14
in the order:
10
Message-id: 5F9CDB8A.9000001@huawei.com
15
* no such register
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
* ARMCPRegInfo::access bits
17
* HSTR_EL2 trap bits
18
* ARMCPRegInfo::accessfn
19
20
So UNDEFs that happen because of the access bits or because the
21
register doesn't exist at all correctly take priority over the
22
HSTR_EL2 trap, but where a register can UNDEF at EL0 because of the
23
accessfn we are incorrectly always taking the HSTR_EL2 trap. There
24
aren't many of these, but one example is the PMCR; if you look at the
25
access pseudocode for this register you can see that UNDEFs taken
26
because of the value of PMUSERENR.EN are checked before the HSTR_EL2
27
bit.
28
29
Rearrange helper_access_check_cp_reg() so that we always call the
30
accessfn, and use its return value if it indicates that the access
31
traps to EL0 rather than continuing to do the HSTR_EL2 check.
32
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
35
Tested-by: Fuad Tabba <tabba@google.com>
36
Message-id: 20230130182459.3309057-6-peter.maydell@linaro.org
37
Message-id: 20230127175507.2895013-6-peter.maydell@linaro.org
13
---
38
---
14
hw/display/omap_lcdc.c | 10 +++++++---
39
target/arm/op_helper.c | 21 ++++++++++++++++-----
15
1 file changed, 7 insertions(+), 3 deletions(-)
40
1 file changed, 16 insertions(+), 5 deletions(-)
16
41
17
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
42
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
18
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/display/omap_lcdc.c
44
--- a/target/arm/op_helper.c
20
+++ b/hw/display/omap_lcdc.c
45
+++ b/target/arm/op_helper.c
21
@@ -XXX,XX +XXX,XX @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
46
@@ -XXX,XX +XXX,XX @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key,
22
static void omap_update_display(void *opaque)
47
goto fail;
23
{
48
}
24
struct omap_lcd_panel_s *omap_lcd = (struct omap_lcd_panel_s *) opaque;
49
25
- DisplaySurface *surface = qemu_console_surface(omap_lcd->con);
50
+ if (ri->accessfn) {
26
+ DisplaySurface *surface;
51
+ res = ri->accessfn(env, ri, isread);
27
draw_line_func draw_line;
28
int size, height, first, last;
29
int width, linesize, step, bpp, frame_offset;
30
hwaddr frame_base;
31
32
- if (!omap_lcd || omap_lcd->plm == 1 || !omap_lcd->enable ||
33
- !surface_bits_per_pixel(surface)) {
34
+ if (!omap_lcd || omap_lcd->plm == 1 || !omap_lcd->enable) {
35
+ return;
36
+ }
52
+ }
37
+
53
+
38
+ surface = qemu_console_surface(omap_lcd->con);
54
/*
39
+ if (!surface_bits_per_pixel(surface)) {
55
- * Check for an EL2 trap due to HSTR_EL2. We expect EL0 accesses
40
return;
56
- * to sysregs non accessible at EL0 to have UNDEF-ed already.
57
+ * If the access function indicates a trap from EL0 to EL1 then
58
+ * that always takes priority over the HSTR_EL2 trap. (If it indicates
59
+ * a trap to EL3, then the HSTR_EL2 trap takes priority; if it indicates
60
+ * a trap to EL2, then the syndrome is the same either way so we don't
61
+ * care whether technically the architecture says that HSTR_EL2 trap or
62
+ * the other trap takes priority. So we take the "check HSTR_EL2" path
63
+ * for all of those cases.)
64
*/
65
+ if (res != CP_ACCESS_OK && ((res & CP_ACCESS_EL_MASK) == 0) &&
66
+ arm_current_el(env) == 0) {
67
+ goto fail;
68
+ }
69
+
70
if (!is_a64(env) && arm_current_el(env) < 2 && ri->cp == 15 &&
71
(arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
72
uint32_t mask = 1 << ri->crn;
73
@@ -XXX,XX +XXX,XX @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key,
74
}
41
}
75
}
42
76
77
- if (ri->accessfn) {
78
- res = ri->accessfn(env, ri, isread);
79
- }
80
if (likely(res == CP_ACCESS_OK)) {
81
return ri;
82
}
43
--
83
--
44
2.20.1
84
2.34.1
45
46
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The semantics of HSTR_EL2 require that it traps cpreg accesses
2
to EL2 for:
3
* EL1 accesses
4
* EL0 accesses, if the access is not UNDEFINED when the
5
trap bit is 0
2
6
3
We can use proper widening loads to extend 32-bit inputs,
7
(You can see this in the I_ZFGJP priority ordering, where HSTR_EL2
4
and skip the "widenfn" step.
8
traps from EL1 to EL2 are priority 12, UNDEFs are priority 13, and
9
HSTR_EL2 traps from EL0 are priority 15.)
5
10
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
However, we don't get this right for EL1 accesses which UNDEF because
7
Message-id: 20201030022618.785675-12-richard.henderson@linaro.org
12
the register doesn't exist at all or because its ri->access bits
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
non-configurably forbid the access. At EL1, check for the HSTR_EL2
14
trap early, before either of these UNDEF reasons.
15
16
We have to retain the HSTR_EL2 check in access_check_cp_reg(),
17
because at EL0 any kind of UNDEF-to-EL1 (including "no such
18
register", "bad ri->access" and "ri->accessfn returns 'trap to EL1'")
19
takes precedence over the trap to EL2. But we only need to do that
20
check for EL0 now.
21
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Tested-by: Fuad Tabba <tabba@google.com>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Message-id: 20230130182459.3309057-7-peter.maydell@linaro.org
26
Message-id: 20230127175507.2895013-7-peter.maydell@linaro.org
10
---
27
---
11
target/arm/translate.c | 6 +++
28
target/arm/op_helper.c | 6 +++++-
12
target/arm/translate-neon.c.inc | 66 ++++++++++++++++++---------------
29
target/arm/translate.c | 28 +++++++++++++++++++++++++++-
13
2 files changed, 43 insertions(+), 29 deletions(-)
30
2 files changed, 32 insertions(+), 2 deletions(-)
14
31
32
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/op_helper.c
35
+++ b/target/arm/op_helper.c
36
@@ -XXX,XX +XXX,XX @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key,
37
goto fail;
38
}
39
40
- if (!is_a64(env) && arm_current_el(env) < 2 && ri->cp == 15 &&
41
+ /*
42
+ * HSTR_EL2 traps from EL1 are checked earlier, in generated code;
43
+ * we only need to check here for traps from EL0.
44
+ */
45
+ if (!is_a64(env) && arm_current_el(env) == 0 && ri->cp == 15 &&
46
(arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
47
uint32_t mask = 1 << ri->crn;
48
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
49
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.c
51
--- a/target/arm/translate.c
18
+++ b/target/arm/translate.c
52
+++ b/target/arm/translate.c
19
@@ -XXX,XX +XXX,XX @@ static void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
53
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
20
long off = neon_element_offset(reg, ele, memop);
21
22
switch (memop) {
23
+ case MO_SL:
24
+ tcg_gen_ld32s_i64(dest, cpu_env, off);
25
+ break;
26
+ case MO_UL:
27
+ tcg_gen_ld32u_i64(dest, cpu_env, off);
28
+ break;
29
case MO_Q:
30
tcg_gen_ld_i64(dest, cpu_env, off);
31
break;
54
break;
32
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate-neon.c.inc
35
+++ b/target/arm/translate-neon.c.inc
36
@@ -XXX,XX +XXX,XX @@ static bool trans_Vimm_1r(DisasContext *s, arg_1reg_imm *a)
37
static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
38
NeonGenWidenFn *widenfn,
39
NeonGenTwo64OpFn *opfn,
40
- bool src1_wide)
41
+ int src1_mop, int src2_mop)
42
{
43
/* 3-regs different lengths, prewidening case (VADDL/VSUBL/VAADW/VSUBW) */
44
TCGv_i64 rn0_64, rn1_64, rm_64;
45
- TCGv_i32 rm;
46
47
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
48
return false;
49
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
50
return false;
51
}
55
}
52
56
53
- if (!widenfn || !opfn) {
57
+ if (s->hstr_active && cpnum == 15 && s->current_el == 1) {
54
+ if (!opfn) {
58
+ /*
55
/* size == 3 case, which is an entirely different insn group */
59
+ * At EL1, check for a HSTR_EL2 trap, which must take precedence
56
return false;
60
+ * over the UNDEF for "no such register" or the UNDEF for "access
61
+ * permissions forbid this EL1 access". HSTR_EL2 traps from EL0
62
+ * only happen if the cpreg doesn't UNDEF at EL0, so we do those in
63
+ * access_check_cp_reg(), after the checks for whether the access
64
+ * configurably trapped to EL1.
65
+ */
66
+ uint32_t maskbit = is64 ? crm : crn;
67
+
68
+ if (maskbit != 4 && maskbit != 14) {
69
+ /* T4 and T14 are RES0 so never cause traps */
70
+ TCGv_i32 t;
71
+ DisasLabel over = gen_disas_label(s);
72
+
73
+ t = load_cpu_offset(offsetoflow32(CPUARMState, cp15.hstr_el2));
74
+ tcg_gen_andi_i32(t, t, 1u << maskbit);
75
+ tcg_gen_brcondi_i32(TCG_COND_EQ, t, 0, over.label);
76
+ tcg_temp_free_i32(t);
77
+
78
+ gen_exception_insn(s, 0, EXCP_UDEF, syndrome);
79
+ set_disas_label(s, over);
80
+ }
81
+ }
82
+
83
if (!ri) {
84
/*
85
* Unknown register; this might be a guest error or a QEMU
86
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
87
return;
57
}
88
}
58
89
59
- if ((a->vd & 1) || (src1_wide && (a->vn & 1))) {
90
- if (s->hstr_active || ri->accessfn ||
60
+ if ((a->vd & 1) || (src1_mop == MO_Q && (a->vn & 1))) {
91
+ if ((s->hstr_active && s->current_el == 0) || ri->accessfn ||
61
return false;
92
(arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
62
}
93
/*
63
94
* Emit code to perform further access permissions checks at
64
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
65
rn1_64 = tcg_temp_new_i64();
66
rm_64 = tcg_temp_new_i64();
67
68
- if (src1_wide) {
69
- read_neon_element64(rn0_64, a->vn, 0, MO_64);
70
+ if (src1_mop >= 0) {
71
+ read_neon_element64(rn0_64, a->vn, 0, src1_mop);
72
} else {
73
TCGv_i32 tmp = tcg_temp_new_i32();
74
read_neon_element32(tmp, a->vn, 0, MO_32);
75
widenfn(rn0_64, tmp);
76
tcg_temp_free_i32(tmp);
77
}
78
- rm = tcg_temp_new_i32();
79
- read_neon_element32(rm, a->vm, 0, MO_32);
80
+ if (src2_mop >= 0) {
81
+ read_neon_element64(rm_64, a->vm, 0, src2_mop);
82
+ } else {
83
+ TCGv_i32 tmp = tcg_temp_new_i32();
84
+ read_neon_element32(tmp, a->vm, 0, MO_32);
85
+ widenfn(rm_64, tmp);
86
+ tcg_temp_free_i32(tmp);
87
+ }
88
89
- widenfn(rm_64, rm);
90
- tcg_temp_free_i32(rm);
91
opfn(rn0_64, rn0_64, rm_64);
92
93
/*
94
* Load second pass inputs before storing the first pass result, to
95
* avoid incorrect results if a narrow input overlaps with the result.
96
*/
97
- if (src1_wide) {
98
- read_neon_element64(rn1_64, a->vn, 1, MO_64);
99
+ if (src1_mop >= 0) {
100
+ read_neon_element64(rn1_64, a->vn, 1, src1_mop);
101
} else {
102
TCGv_i32 tmp = tcg_temp_new_i32();
103
read_neon_element32(tmp, a->vn, 1, MO_32);
104
widenfn(rn1_64, tmp);
105
tcg_temp_free_i32(tmp);
106
}
107
- rm = tcg_temp_new_i32();
108
- read_neon_element32(rm, a->vm, 1, MO_32);
109
+ if (src2_mop >= 0) {
110
+ read_neon_element64(rm_64, a->vm, 1, src2_mop);
111
+ } else {
112
+ TCGv_i32 tmp = tcg_temp_new_i32();
113
+ read_neon_element32(tmp, a->vm, 1, MO_32);
114
+ widenfn(rm_64, tmp);
115
+ tcg_temp_free_i32(tmp);
116
+ }
117
118
write_neon_element64(rn0_64, a->vd, 0, MO_64);
119
120
- widenfn(rm_64, rm);
121
- tcg_temp_free_i32(rm);
122
opfn(rn1_64, rn1_64, rm_64);
123
write_neon_element64(rn1_64, a->vd, 1, MO_64);
124
125
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
126
return true;
127
}
128
129
-#define DO_PREWIDEN(INSN, S, EXT, OP, SRC1WIDE) \
130
+#define DO_PREWIDEN(INSN, S, OP, SRC1WIDE, SIGN) \
131
static bool trans_##INSN##_3d(DisasContext *s, arg_3diff *a) \
132
{ \
133
static NeonGenWidenFn * const widenfn[] = { \
134
gen_helper_neon_widen_##S##8, \
135
gen_helper_neon_widen_##S##16, \
136
- tcg_gen_##EXT##_i32_i64, \
137
- NULL, \
138
+ NULL, NULL, \
139
}; \
140
static NeonGenTwo64OpFn * const addfn[] = { \
141
gen_helper_neon_##OP##l_u16, \
142
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
143
tcg_gen_##OP##_i64, \
144
NULL, \
145
}; \
146
- return do_prewiden_3d(s, a, widenfn[a->size], \
147
- addfn[a->size], SRC1WIDE); \
148
+ int narrow_mop = a->size == MO_32 ? MO_32 | SIGN : -1; \
149
+ return do_prewiden_3d(s, a, widenfn[a->size], addfn[a->size], \
150
+ SRC1WIDE ? MO_Q : narrow_mop, \
151
+ narrow_mop); \
152
}
153
154
-DO_PREWIDEN(VADDL_S, s, ext, add, false)
155
-DO_PREWIDEN(VADDL_U, u, extu, add, false)
156
-DO_PREWIDEN(VSUBL_S, s, ext, sub, false)
157
-DO_PREWIDEN(VSUBL_U, u, extu, sub, false)
158
-DO_PREWIDEN(VADDW_S, s, ext, add, true)
159
-DO_PREWIDEN(VADDW_U, u, extu, add, true)
160
-DO_PREWIDEN(VSUBW_S, s, ext, sub, true)
161
-DO_PREWIDEN(VSUBW_U, u, extu, sub, true)
162
+DO_PREWIDEN(VADDL_S, s, add, false, MO_SIGN)
163
+DO_PREWIDEN(VADDL_U, u, add, false, 0)
164
+DO_PREWIDEN(VSUBL_S, s, sub, false, MO_SIGN)
165
+DO_PREWIDEN(VSUBL_U, u, sub, false, 0)
166
+DO_PREWIDEN(VADDW_S, s, add, true, MO_SIGN)
167
+DO_PREWIDEN(VADDW_U, u, add, true, 0)
168
+DO_PREWIDEN(VSUBW_S, s, sub, true, MO_SIGN)
169
+DO_PREWIDEN(VSUBW_U, u, sub, true, 0)
170
171
static bool do_narrow_3d(DisasContext *s, arg_3diff *a,
172
NeonGenTwo64OpFn *opfn, NeonGenNarrowFn *narrowfn)
173
--
95
--
174
2.20.1
96
2.34.1
175
176
diff view generated by jsdifflib
1
In the neon_padd/pmax/pmin helpers for float16, a cut-and-paste error
1
The HSTR_EL2 register is not supposed to have an effect unless EL2 is
2
meant we were using the H4() address swizzler macro rather than the
2
enabled in the current security state. We weren't checking for this,
3
H2() which is required for 2-byte data. This had no effect on
3
which meant that if the guest set up the HSTR_EL2 register we would
4
little-endian hosts but meant we put the result data into the
4
incorrectly trap even for accesses from Secure EL0 and EL1.
5
destination Dreg in the wrong order on big-endian hosts.
5
6
Add the missing checks. (Other places where we look at HSTR_EL2
7
for the not-in-v8A bits TTEE and TJDBX are already checking that
8
we are in NS EL0 or EL1, so there we alredy know EL2 is enabled.)
6
9
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Tested-by: Fuad Tabba <tabba@google.com>
10
Message-id: 20201028191712.4910-2-peter.maydell@linaro.org
13
Message-id: 20230130182459.3309057-8-peter.maydell@linaro.org
14
Message-id: 20230127175507.2895013-8-peter.maydell@linaro.org
11
---
15
---
12
target/arm/vec_helper.c | 8 ++++----
16
target/arm/helper.c | 2 +-
13
1 file changed, 4 insertions(+), 4 deletions(-)
17
target/arm/op_helper.c | 1 +
18
2 files changed, 2 insertions(+), 1 deletion(-)
14
19
15
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/vec_helper.c
22
--- a/target/arm/helper.c
18
+++ b/target/arm/vec_helper.c
23
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ DO_ABA(gvec_uaba_d, uint64_t)
24
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el,
20
r2 = float16_##OP(m[H2(0)], m[H2(1)], fpst); \
25
DP_TBFLAG_A32(flags, VFPEN, 1);
21
r3 = float16_##OP(m[H2(2)], m[H2(3)], fpst); \
22
\
23
- d[H4(0)] = r0; \
24
- d[H4(1)] = r1; \
25
- d[H4(2)] = r2; \
26
- d[H4(3)] = r3; \
27
+ d[H2(0)] = r0; \
28
+ d[H2(1)] = r1; \
29
+ d[H2(2)] = r2; \
30
+ d[H2(3)] = r3; \
31
}
26
}
32
27
33
DO_NEON_PAIRWISE(neon_padd, add)
28
- if (el < 2 && env->cp15.hstr_el2 &&
29
+ if (el < 2 && env->cp15.hstr_el2 && arm_is_el2_enabled(env) &&
30
(arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
31
DP_TBFLAG_A32(flags, HSTR_ACTIVE, 1);
32
}
33
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/op_helper.c
36
+++ b/target/arm/op_helper.c
37
@@ -XXX,XX +XXX,XX @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key,
38
* we only need to check here for traps from EL0.
39
*/
40
if (!is_a64(env) && arm_current_el(env) == 0 && ri->cp == 15 &&
41
+ arm_is_el2_enabled(env) &&
42
(arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
43
uint32_t mask = 1 << ri->crn;
44
34
--
45
--
35
2.20.1
46
2.34.1
36
37
diff view generated by jsdifflib
New patch
1
1
Define the system registers which are provided by the
2
FEAT_FGT fine-grained trap architectural feature:
3
HFGRTR_EL2, HFGWTR_EL2, HDFGRTR_EL2, HDFGWTR_EL2, HFGITR_EL2
4
5
All these registers are a set of bit fields, where each bit is set
6
for a trap and clear to not trap on a particular system register
7
access. The R and W register pairs are for system registers,
8
allowing trapping to be done separately for reads and writes; the I
9
register is for system instructions where trapping is on instruction
10
execution.
11
12
The data storage in the CPU state struct is arranged as a set of
13
arrays rather than separate fields so that when we're looking up the
14
bits for a system register access we can just index into the array
15
rather than having to use a switch to select a named struct member.
16
The later FEAT_FGT2 will add extra elements to these arrays.
17
18
The field definitions for the new registers are in cpregs.h because
19
in practice the code that needs them is code that also needs
20
the cpregs information; cpu.h is included in a lot more files.
21
We're also going to add some FGT-specific definitions to cpregs.h
22
in the next commit.
23
24
We do not implement HAFGRTR_EL2, because we don't implement
25
FEAT_AMUv1.
26
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Tested-by: Fuad Tabba <tabba@google.com>
30
Message-id: 20230130182459.3309057-9-peter.maydell@linaro.org
31
Message-id: 20230127175507.2895013-9-peter.maydell@linaro.org
32
---
33
target/arm/cpregs.h | 285 ++++++++++++++++++++++++++++++++++++++++++++
34
target/arm/cpu.h | 15 +++
35
target/arm/helper.c | 40 +++++++
36
3 files changed, 340 insertions(+)
37
38
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/cpregs.h
41
+++ b/target/arm/cpregs.h
42
@@ -XXX,XX +XXX,XX @@ typedef enum CPAccessResult {
43
CP_ACCESS_TRAP_UNCATEGORIZED = (2 << 2),
44
} CPAccessResult;
45
46
+/* Indexes into fgt_read[] */
47
+#define FGTREG_HFGRTR 0
48
+#define FGTREG_HDFGRTR 1
49
+/* Indexes into fgt_write[] */
50
+#define FGTREG_HFGWTR 0
51
+#define FGTREG_HDFGWTR 1
52
+/* Indexes into fgt_exec[] */
53
+#define FGTREG_HFGITR 0
54
+
55
+FIELD(HFGRTR_EL2, AFSR0_EL1, 0, 1)
56
+FIELD(HFGRTR_EL2, AFSR1_EL1, 1, 1)
57
+FIELD(HFGRTR_EL2, AIDR_EL1, 2, 1)
58
+FIELD(HFGRTR_EL2, AMAIR_EL1, 3, 1)
59
+FIELD(HFGRTR_EL2, APDAKEY, 4, 1)
60
+FIELD(HFGRTR_EL2, APDBKEY, 5, 1)
61
+FIELD(HFGRTR_EL2, APGAKEY, 6, 1)
62
+FIELD(HFGRTR_EL2, APIAKEY, 7, 1)
63
+FIELD(HFGRTR_EL2, APIBKEY, 8, 1)
64
+FIELD(HFGRTR_EL2, CCSIDR_EL1, 9, 1)
65
+FIELD(HFGRTR_EL2, CLIDR_EL1, 10, 1)
66
+FIELD(HFGRTR_EL2, CONTEXTIDR_EL1, 11, 1)
67
+FIELD(HFGRTR_EL2, CPACR_EL1, 12, 1)
68
+FIELD(HFGRTR_EL2, CSSELR_EL1, 13, 1)
69
+FIELD(HFGRTR_EL2, CTR_EL0, 14, 1)
70
+FIELD(HFGRTR_EL2, DCZID_EL0, 15, 1)
71
+FIELD(HFGRTR_EL2, ESR_EL1, 16, 1)
72
+FIELD(HFGRTR_EL2, FAR_EL1, 17, 1)
73
+FIELD(HFGRTR_EL2, ISR_EL1, 18, 1)
74
+FIELD(HFGRTR_EL2, LORC_EL1, 19, 1)
75
+FIELD(HFGRTR_EL2, LOREA_EL1, 20, 1)
76
+FIELD(HFGRTR_EL2, LORID_EL1, 21, 1)
77
+FIELD(HFGRTR_EL2, LORN_EL1, 22, 1)
78
+FIELD(HFGRTR_EL2, LORSA_EL1, 23, 1)
79
+FIELD(HFGRTR_EL2, MAIR_EL1, 24, 1)
80
+FIELD(HFGRTR_EL2, MIDR_EL1, 25, 1)
81
+FIELD(HFGRTR_EL2, MPIDR_EL1, 26, 1)
82
+FIELD(HFGRTR_EL2, PAR_EL1, 27, 1)
83
+FIELD(HFGRTR_EL2, REVIDR_EL1, 28, 1)
84
+FIELD(HFGRTR_EL2, SCTLR_EL1, 29, 1)
85
+FIELD(HFGRTR_EL2, SCXTNUM_EL1, 30, 1)
86
+FIELD(HFGRTR_EL2, SCXTNUM_EL0, 31, 1)
87
+FIELD(HFGRTR_EL2, TCR_EL1, 32, 1)
88
+FIELD(HFGRTR_EL2, TPIDR_EL1, 33, 1)
89
+FIELD(HFGRTR_EL2, TPIDRRO_EL0, 34, 1)
90
+FIELD(HFGRTR_EL2, TPIDR_EL0, 35, 1)
91
+FIELD(HFGRTR_EL2, TTBR0_EL1, 36, 1)
92
+FIELD(HFGRTR_EL2, TTBR1_EL1, 37, 1)
93
+FIELD(HFGRTR_EL2, VBAR_EL1, 38, 1)
94
+FIELD(HFGRTR_EL2, ICC_IGRPENN_EL1, 39, 1)
95
+FIELD(HFGRTR_EL2, ERRIDR_EL1, 40, 1)
96
+FIELD(HFGRTR_EL2, ERRSELR_EL1, 41, 1)
97
+FIELD(HFGRTR_EL2, ERXFR_EL1, 42, 1)
98
+FIELD(HFGRTR_EL2, ERXCTLR_EL1, 43, 1)
99
+FIELD(HFGRTR_EL2, ERXSTATUS_EL1, 44, 1)
100
+FIELD(HFGRTR_EL2, ERXMISCN_EL1, 45, 1)
101
+FIELD(HFGRTR_EL2, ERXPFGF_EL1, 46, 1)
102
+FIELD(HFGRTR_EL2, ERXPFGCTL_EL1, 47, 1)
103
+FIELD(HFGRTR_EL2, ERXPFGCDN_EL1, 48, 1)
104
+FIELD(HFGRTR_EL2, ERXADDR_EL1, 49, 1)
105
+FIELD(HFGRTR_EL2, NACCDATA_EL1, 50, 1)
106
+/* 51-53: RES0 */
107
+FIELD(HFGRTR_EL2, NSMPRI_EL1, 54, 1)
108
+FIELD(HFGRTR_EL2, NTPIDR2_EL0, 55, 1)
109
+/* 56-63: RES0 */
110
+
111
+/* These match HFGRTR but bits for RO registers are RES0 */
112
+FIELD(HFGWTR_EL2, AFSR0_EL1, 0, 1)
113
+FIELD(HFGWTR_EL2, AFSR1_EL1, 1, 1)
114
+FIELD(HFGWTR_EL2, AMAIR_EL1, 3, 1)
115
+FIELD(HFGWTR_EL2, APDAKEY, 4, 1)
116
+FIELD(HFGWTR_EL2, APDBKEY, 5, 1)
117
+FIELD(HFGWTR_EL2, APGAKEY, 6, 1)
118
+FIELD(HFGWTR_EL2, APIAKEY, 7, 1)
119
+FIELD(HFGWTR_EL2, APIBKEY, 8, 1)
120
+FIELD(HFGWTR_EL2, CONTEXTIDR_EL1, 11, 1)
121
+FIELD(HFGWTR_EL2, CPACR_EL1, 12, 1)
122
+FIELD(HFGWTR_EL2, CSSELR_EL1, 13, 1)
123
+FIELD(HFGWTR_EL2, ESR_EL1, 16, 1)
124
+FIELD(HFGWTR_EL2, FAR_EL1, 17, 1)
125
+FIELD(HFGWTR_EL2, LORC_EL1, 19, 1)
126
+FIELD(HFGWTR_EL2, LOREA_EL1, 20, 1)
127
+FIELD(HFGWTR_EL2, LORN_EL1, 22, 1)
128
+FIELD(HFGWTR_EL2, LORSA_EL1, 23, 1)
129
+FIELD(HFGWTR_EL2, MAIR_EL1, 24, 1)
130
+FIELD(HFGWTR_EL2, PAR_EL1, 27, 1)
131
+FIELD(HFGWTR_EL2, SCTLR_EL1, 29, 1)
132
+FIELD(HFGWTR_EL2, SCXTNUM_EL1, 30, 1)
133
+FIELD(HFGWTR_EL2, SCXTNUM_EL0, 31, 1)
134
+FIELD(HFGWTR_EL2, TCR_EL1, 32, 1)
135
+FIELD(HFGWTR_EL2, TPIDR_EL1, 33, 1)
136
+FIELD(HFGWTR_EL2, TPIDRRO_EL0, 34, 1)
137
+FIELD(HFGWTR_EL2, TPIDR_EL0, 35, 1)
138
+FIELD(HFGWTR_EL2, TTBR0_EL1, 36, 1)
139
+FIELD(HFGWTR_EL2, TTBR1_EL1, 37, 1)
140
+FIELD(HFGWTR_EL2, VBAR_EL1, 38, 1)
141
+FIELD(HFGWTR_EL2, ICC_IGRPENN_EL1, 39, 1)
142
+FIELD(HFGWTR_EL2, ERRSELR_EL1, 41, 1)
143
+FIELD(HFGWTR_EL2, ERXCTLR_EL1, 43, 1)
144
+FIELD(HFGWTR_EL2, ERXSTATUS_EL1, 44, 1)
145
+FIELD(HFGWTR_EL2, ERXMISCN_EL1, 45, 1)
146
+FIELD(HFGWTR_EL2, ERXPFGCTL_EL1, 47, 1)
147
+FIELD(HFGWTR_EL2, ERXPFGCDN_EL1, 48, 1)
148
+FIELD(HFGWTR_EL2, ERXADDR_EL1, 49, 1)
149
+FIELD(HFGWTR_EL2, NACCDATA_EL1, 50, 1)
150
+FIELD(HFGWTR_EL2, NSMPRI_EL1, 54, 1)
151
+FIELD(HFGWTR_EL2, NTPIDR2_EL0, 55, 1)
152
+
153
+FIELD(HFGITR_EL2, ICIALLUIS, 0, 1)
154
+FIELD(HFGITR_EL2, ICIALLU, 1, 1)
155
+FIELD(HFGITR_EL2, ICIVAU, 2, 1)
156
+FIELD(HFGITR_EL2, DCIVAC, 3, 1)
157
+FIELD(HFGITR_EL2, DCISW, 4, 1)
158
+FIELD(HFGITR_EL2, DCCSW, 5, 1)
159
+FIELD(HFGITR_EL2, DCCISW, 6, 1)
160
+FIELD(HFGITR_EL2, DCCVAU, 7, 1)
161
+FIELD(HFGITR_EL2, DCCVAP, 8, 1)
162
+FIELD(HFGITR_EL2, DCCVADP, 9, 1)
163
+FIELD(HFGITR_EL2, DCCIVAC, 10, 1)
164
+FIELD(HFGITR_EL2, DCZVA, 11, 1)
165
+FIELD(HFGITR_EL2, ATS1E1R, 12, 1)
166
+FIELD(HFGITR_EL2, ATS1E1W, 13, 1)
167
+FIELD(HFGITR_EL2, ATS1E0R, 14, 1)
168
+FIELD(HFGITR_EL2, ATS1E0W, 15, 1)
169
+FIELD(HFGITR_EL2, ATS1E1RP, 16, 1)
170
+FIELD(HFGITR_EL2, ATS1E1WP, 17, 1)
171
+FIELD(HFGITR_EL2, TLBIVMALLE1OS, 18, 1)
172
+FIELD(HFGITR_EL2, TLBIVAE1OS, 19, 1)
173
+FIELD(HFGITR_EL2, TLBIASIDE1OS, 20, 1)
174
+FIELD(HFGITR_EL2, TLBIVAAE1OS, 21, 1)
175
+FIELD(HFGITR_EL2, TLBIVALE1OS, 22, 1)
176
+FIELD(HFGITR_EL2, TLBIVAALE1OS, 23, 1)
177
+FIELD(HFGITR_EL2, TLBIRVAE1OS, 24, 1)
178
+FIELD(HFGITR_EL2, TLBIRVAAE1OS, 25, 1)
179
+FIELD(HFGITR_EL2, TLBIRVALE1OS, 26, 1)
180
+FIELD(HFGITR_EL2, TLBIRVAALE1OS, 27, 1)
181
+FIELD(HFGITR_EL2, TLBIVMALLE1IS, 28, 1)
182
+FIELD(HFGITR_EL2, TLBIVAE1IS, 29, 1)
183
+FIELD(HFGITR_EL2, TLBIASIDE1IS, 30, 1)
184
+FIELD(HFGITR_EL2, TLBIVAAE1IS, 31, 1)
185
+FIELD(HFGITR_EL2, TLBIVALE1IS, 32, 1)
186
+FIELD(HFGITR_EL2, TLBIVAALE1IS, 33, 1)
187
+FIELD(HFGITR_EL2, TLBIRVAE1IS, 34, 1)
188
+FIELD(HFGITR_EL2, TLBIRVAAE1IS, 35, 1)
189
+FIELD(HFGITR_EL2, TLBIRVALE1IS, 36, 1)
190
+FIELD(HFGITR_EL2, TLBIRVAALE1IS, 37, 1)
191
+FIELD(HFGITR_EL2, TLBIRVAE1, 38, 1)
192
+FIELD(HFGITR_EL2, TLBIRVAAE1, 39, 1)
193
+FIELD(HFGITR_EL2, TLBIRVALE1, 40, 1)
194
+FIELD(HFGITR_EL2, TLBIRVAALE1, 41, 1)
195
+FIELD(HFGITR_EL2, TLBIVMALLE1, 42, 1)
196
+FIELD(HFGITR_EL2, TLBIVAE1, 43, 1)
197
+FIELD(HFGITR_EL2, TLBIASIDE1, 44, 1)
198
+FIELD(HFGITR_EL2, TLBIVAAE1, 45, 1)
199
+FIELD(HFGITR_EL2, TLBIVALE1, 46, 1)
200
+FIELD(HFGITR_EL2, TLBIVAALE1, 47, 1)
201
+FIELD(HFGITR_EL2, CFPRCTX, 48, 1)
202
+FIELD(HFGITR_EL2, DVPRCTX, 49, 1)
203
+FIELD(HFGITR_EL2, CPPRCTX, 50, 1)
204
+FIELD(HFGITR_EL2, ERET, 51, 1)
205
+FIELD(HFGITR_EL2, SVC_EL0, 52, 1)
206
+FIELD(HFGITR_EL2, SVC_EL1, 53, 1)
207
+FIELD(HFGITR_EL2, DCCVAC, 54, 1)
208
+FIELD(HFGITR_EL2, NBRBINJ, 55, 1)
209
+FIELD(HFGITR_EL2, NBRBIALL, 56, 1)
210
+
211
+FIELD(HDFGRTR_EL2, DBGBCRN_EL1, 0, 1)
212
+FIELD(HDFGRTR_EL2, DBGBVRN_EL1, 1, 1)
213
+FIELD(HDFGRTR_EL2, DBGWCRN_EL1, 2, 1)
214
+FIELD(HDFGRTR_EL2, DBGWVRN_EL1, 3, 1)
215
+FIELD(HDFGRTR_EL2, MDSCR_EL1, 4, 1)
216
+FIELD(HDFGRTR_EL2, DBGCLAIM, 5, 1)
217
+FIELD(HDFGRTR_EL2, DBGAUTHSTATUS_EL1, 6, 1)
218
+FIELD(HDFGRTR_EL2, DBGPRCR_EL1, 7, 1)
219
+/* 8: RES0: OSLAR_EL1 is WO */
220
+FIELD(HDFGRTR_EL2, OSLSR_EL1, 9, 1)
221
+FIELD(HDFGRTR_EL2, OSECCR_EL1, 10, 1)
222
+FIELD(HDFGRTR_EL2, OSDLR_EL1, 11, 1)
223
+FIELD(HDFGRTR_EL2, PMEVCNTRN_EL0, 12, 1)
224
+FIELD(HDFGRTR_EL2, PMEVTYPERN_EL0, 13, 1)
225
+FIELD(HDFGRTR_EL2, PMCCFILTR_EL0, 14, 1)
226
+FIELD(HDFGRTR_EL2, PMCCNTR_EL0, 15, 1)
227
+FIELD(HDFGRTR_EL2, PMCNTEN, 16, 1)
228
+FIELD(HDFGRTR_EL2, PMINTEN, 17, 1)
229
+FIELD(HDFGRTR_EL2, PMOVS, 18, 1)
230
+FIELD(HDFGRTR_EL2, PMSELR_EL0, 19, 1)
231
+/* 20: RES0: PMSWINC_EL0 is WO */
232
+/* 21: RES0: PMCR_EL0 is WO */
233
+FIELD(HDFGRTR_EL2, PMMIR_EL1, 22, 1)
234
+FIELD(HDFGRTR_EL2, PMBLIMITR_EL1, 23, 1)
235
+FIELD(HDFGRTR_EL2, PMBPTR_EL1, 24, 1)
236
+FIELD(HDFGRTR_EL2, PMBSR_EL1, 25, 1)
237
+FIELD(HDFGRTR_EL2, PMSCR_EL1, 26, 1)
238
+FIELD(HDFGRTR_EL2, PMSEVFR_EL1, 27, 1)
239
+FIELD(HDFGRTR_EL2, PMSFCR_EL1, 28, 1)
240
+FIELD(HDFGRTR_EL2, PMSICR_EL1, 29, 1)
241
+FIELD(HDFGRTR_EL2, PMSIDR_EL1, 30, 1)
242
+FIELD(HDFGRTR_EL2, PMSIRR_EL1, 31, 1)
243
+FIELD(HDFGRTR_EL2, PMSLATFR_EL1, 32, 1)
244
+FIELD(HDFGRTR_EL2, TRC, 33, 1)
245
+FIELD(HDFGRTR_EL2, TRCAUTHSTATUS, 34, 1)
246
+FIELD(HDFGRTR_EL2, TRCAUXCTLR, 35, 1)
247
+FIELD(HDFGRTR_EL2, TRCCLAIM, 36, 1)
248
+FIELD(HDFGRTR_EL2, TRCCNTVRn, 37, 1)
249
+/* 38, 39: RES0 */
250
+FIELD(HDFGRTR_EL2, TRCID, 40, 1)
251
+FIELD(HDFGRTR_EL2, TRCIMSPECN, 41, 1)
252
+/* 42: RES0: TRCOSLAR is WO */
253
+FIELD(HDFGRTR_EL2, TRCOSLSR, 43, 1)
254
+FIELD(HDFGRTR_EL2, TRCPRGCTLR, 44, 1)
255
+FIELD(HDFGRTR_EL2, TRCSEQSTR, 45, 1)
256
+FIELD(HDFGRTR_EL2, TRCSSCSRN, 46, 1)
257
+FIELD(HDFGRTR_EL2, TRCSTATR, 47, 1)
258
+FIELD(HDFGRTR_EL2, TRCVICTLR, 48, 1)
259
+/* 49: RES0: TRFCR_EL1 is WO */
260
+FIELD(HDFGRTR_EL2, TRBBASER_EL1, 50, 1)
261
+FIELD(HDFGRTR_EL2, TRBIDR_EL1, 51, 1)
262
+FIELD(HDFGRTR_EL2, TRBLIMITR_EL1, 52, 1)
263
+FIELD(HDFGRTR_EL2, TRBMAR_EL1, 53, 1)
264
+FIELD(HDFGRTR_EL2, TRBPTR_EL1, 54, 1)
265
+FIELD(HDFGRTR_EL2, TRBSR_EL1, 55, 1)
266
+FIELD(HDFGRTR_EL2, TRBTRG_EL1, 56, 1)
267
+FIELD(HDFGRTR_EL2, PMUSERENR_EL0, 57, 1)
268
+FIELD(HDFGRTR_EL2, PMCEIDN_EL0, 58, 1)
269
+FIELD(HDFGRTR_EL2, NBRBIDR, 59, 1)
270
+FIELD(HDFGRTR_EL2, NBRBCTL, 60, 1)
271
+FIELD(HDFGRTR_EL2, NBRBDATA, 61, 1)
272
+FIELD(HDFGRTR_EL2, NPMSNEVFR_EL1, 62, 1)
273
+FIELD(HDFGRTR_EL2, PMBIDR_EL1, 63, 1)
274
+
275
+/*
276
+ * These match HDFGRTR_EL2, but bits for RO registers are RES0.
277
+ * A few bits are for WO registers, where the HDFGRTR_EL2 bit is RES0.
278
+ */
279
+FIELD(HDFGWTR_EL2, DBGBCRN_EL1, 0, 1)
280
+FIELD(HDFGWTR_EL2, DBGBVRN_EL1, 1, 1)
281
+FIELD(HDFGWTR_EL2, DBGWCRN_EL1, 2, 1)
282
+FIELD(HDFGWTR_EL2, DBGWVRN_EL1, 3, 1)
283
+FIELD(HDFGWTR_EL2, MDSCR_EL1, 4, 1)
284
+FIELD(HDFGWTR_EL2, DBGCLAIM, 5, 1)
285
+FIELD(HDFGWTR_EL2, DBGPRCR_EL1, 7, 1)
286
+FIELD(HDFGWTR_EL2, OSLAR_EL1, 8, 1)
287
+FIELD(HDFGWTR_EL2, OSLSR_EL1, 9, 1)
288
+FIELD(HDFGWTR_EL2, OSECCR_EL1, 10, 1)
289
+FIELD(HDFGWTR_EL2, OSDLR_EL1, 11, 1)
290
+FIELD(HDFGWTR_EL2, PMEVCNTRN_EL0, 12, 1)
291
+FIELD(HDFGWTR_EL2, PMEVTYPERN_EL0, 13, 1)
292
+FIELD(HDFGWTR_EL2, PMCCFILTR_EL0, 14, 1)
293
+FIELD(HDFGWTR_EL2, PMCCNTR_EL0, 15, 1)
294
+FIELD(HDFGWTR_EL2, PMCNTEN, 16, 1)
295
+FIELD(HDFGWTR_EL2, PMINTEN, 17, 1)
296
+FIELD(HDFGWTR_EL2, PMOVS, 18, 1)
297
+FIELD(HDFGWTR_EL2, PMSELR_EL0, 19, 1)
298
+FIELD(HDFGWTR_EL2, PMSWINC_EL0, 20, 1)
299
+FIELD(HDFGWTR_EL2, PMCR_EL0, 21, 1)
300
+FIELD(HDFGWTR_EL2, PMBLIMITR_EL1, 23, 1)
301
+FIELD(HDFGWTR_EL2, PMBPTR_EL1, 24, 1)
302
+FIELD(HDFGWTR_EL2, PMBSR_EL1, 25, 1)
303
+FIELD(HDFGWTR_EL2, PMSCR_EL1, 26, 1)
304
+FIELD(HDFGWTR_EL2, PMSEVFR_EL1, 27, 1)
305
+FIELD(HDFGWTR_EL2, PMSFCR_EL1, 28, 1)
306
+FIELD(HDFGWTR_EL2, PMSICR_EL1, 29, 1)
307
+FIELD(HDFGWTR_EL2, PMSIRR_EL1, 31, 1)
308
+FIELD(HDFGWTR_EL2, PMSLATFR_EL1, 32, 1)
309
+FIELD(HDFGWTR_EL2, TRC, 33, 1)
310
+FIELD(HDFGWTR_EL2, TRCAUXCTLR, 35, 1)
311
+FIELD(HDFGWTR_EL2, TRCCLAIM, 36, 1)
312
+FIELD(HDFGWTR_EL2, TRCCNTVRn, 37, 1)
313
+FIELD(HDFGWTR_EL2, TRCIMSPECN, 41, 1)
314
+FIELD(HDFGWTR_EL2, TRCOSLAR, 42, 1)
315
+FIELD(HDFGWTR_EL2, TRCPRGCTLR, 44, 1)
316
+FIELD(HDFGWTR_EL2, TRCSEQSTR, 45, 1)
317
+FIELD(HDFGWTR_EL2, TRCSSCSRN, 46, 1)
318
+FIELD(HDFGWTR_EL2, TRCVICTLR, 48, 1)
319
+FIELD(HDFGWTR_EL2, TRFCR_EL1, 49, 1)
320
+FIELD(HDFGWTR_EL2, TRBBASER_EL1, 50, 1)
321
+FIELD(HDFGWTR_EL2, TRBLIMITR_EL1, 52, 1)
322
+FIELD(HDFGWTR_EL2, TRBMAR_EL1, 53, 1)
323
+FIELD(HDFGWTR_EL2, TRBPTR_EL1, 54, 1)
324
+FIELD(HDFGWTR_EL2, TRBSR_EL1, 55, 1)
325
+FIELD(HDFGWTR_EL2, TRBTRG_EL1, 56, 1)
326
+FIELD(HDFGWTR_EL2, PMUSERENR_EL0, 57, 1)
327
+FIELD(HDFGWTR_EL2, NBRBCTL, 60, 1)
328
+FIELD(HDFGWTR_EL2, NBRBDATA, 61, 1)
329
+FIELD(HDFGWTR_EL2, NPMSNEVFR_EL1, 62, 1)
330
+
331
typedef struct ARMCPRegInfo ARMCPRegInfo;
332
333
/*
334
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
335
index XXXXXXX..XXXXXXX 100644
336
--- a/target/arm/cpu.h
337
+++ b/target/arm/cpu.h
338
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
339
uint64_t disr_el1;
340
uint64_t vdisr_el2;
341
uint64_t vsesr_el2;
342
+
343
+ /*
344
+ * Fine-Grained Trap registers. We store these as arrays so the
345
+ * access checking code doesn't have to manually select
346
+ * HFGRTR_EL2 vs HFDFGRTR_EL2 etc when looking up the bit to test.
347
+ * FEAT_FGT2 will add more elements to these arrays.
348
+ */
349
+ uint64_t fgt_read[2]; /* HFGRTR, HDFGRTR */
350
+ uint64_t fgt_write[2]; /* HFGWTR, HDFGWTR */
351
+ uint64_t fgt_exec[1]; /* HFGITR */
352
} cp15;
353
354
struct {
355
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_tgran64_2(const ARMISARegisters *id)
356
return t >= 2 || (t == 0 && isar_feature_aa64_tgran64(id));
357
}
358
359
+static inline bool isar_feature_aa64_fgt(const ARMISARegisters *id)
360
+{
361
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, FGT) != 0;
362
+}
363
+
364
static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
365
{
366
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
367
diff --git a/target/arm/helper.c b/target/arm/helper.c
368
index XXXXXXX..XXXXXXX 100644
369
--- a/target/arm/helper.c
370
+++ b/target/arm/helper.c
371
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
372
if (cpu_isar_feature(aa64_hcx, cpu)) {
373
valid_mask |= SCR_HXEN;
374
}
375
+ if (cpu_isar_feature(aa64_fgt, cpu)) {
376
+ valid_mask |= SCR_FGTEN;
377
+ }
378
} else {
379
valid_mask &= ~(SCR_RW | SCR_ST);
380
if (cpu_isar_feature(aa32_ras, cpu)) {
381
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo scxtnum_reginfo[] = {
382
.access = PL3_RW,
383
.fieldoffset = offsetof(CPUARMState, scxtnum_el[3]) },
384
};
385
+
386
+static CPAccessResult access_fgt(CPUARMState *env, const ARMCPRegInfo *ri,
387
+ bool isread)
388
+{
389
+ if (arm_current_el(env) == 2 &&
390
+ arm_feature(env, ARM_FEATURE_EL3) && !(env->cp15.scr_el3 & SCR_FGTEN)) {
391
+ return CP_ACCESS_TRAP_EL3;
392
+ }
393
+ return CP_ACCESS_OK;
394
+}
395
+
396
+static const ARMCPRegInfo fgt_reginfo[] = {
397
+ { .name = "HFGRTR_EL2", .state = ARM_CP_STATE_AA64,
398
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4,
399
+ .access = PL2_RW, .accessfn = access_fgt,
400
+ .fieldoffset = offsetof(CPUARMState, cp15.fgt_read[FGTREG_HFGRTR]) },
401
+ { .name = "HFGWTR_EL2", .state = ARM_CP_STATE_AA64,
402
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 5,
403
+ .access = PL2_RW, .accessfn = access_fgt,
404
+ .fieldoffset = offsetof(CPUARMState, cp15.fgt_write[FGTREG_HFGWTR]) },
405
+ { .name = "HDFGRTR_EL2", .state = ARM_CP_STATE_AA64,
406
+ .opc0 = 3, .opc1 = 4, .crn = 3, .crm = 1, .opc2 = 4,
407
+ .access = PL2_RW, .accessfn = access_fgt,
408
+ .fieldoffset = offsetof(CPUARMState, cp15.fgt_read[FGTREG_HDFGRTR]) },
409
+ { .name = "HDFGWTR_EL2", .state = ARM_CP_STATE_AA64,
410
+ .opc0 = 3, .opc1 = 4, .crn = 3, .crm = 1, .opc2 = 5,
411
+ .access = PL2_RW, .accessfn = access_fgt,
412
+ .fieldoffset = offsetof(CPUARMState, cp15.fgt_write[FGTREG_HDFGWTR]) },
413
+ { .name = "HFGITR_EL2", .state = ARM_CP_STATE_AA64,
414
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 6,
415
+ .access = PL2_RW, .accessfn = access_fgt,
416
+ .fieldoffset = offsetof(CPUARMState, cp15.fgt_exec[FGTREG_HFGITR]) },
417
+};
418
#endif /* TARGET_AARCH64 */
419
420
static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
421
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
422
if (cpu_isar_feature(aa64_scxtnum, cpu)) {
423
define_arm_cp_regs(cpu, scxtnum_reginfo);
424
}
425
+
426
+ if (cpu_isar_feature(aa64_fgt, cpu)) {
427
+ define_arm_cp_regs(cpu, fgt_reginfo);
428
+ }
429
#endif
430
431
if (cpu_isar_feature(any_predinv, cpu)) {
432
--
433
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the machinery for fine-grained traps on normal sysregs.
2
2
Any sysreg with a fine-grained trap will set the new field to
3
These are the only users of neon_reg_offset, so remove that.
3
indicate which FGT register bit it should trap on.
4
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
FGT traps only happen when an AArch64 EL2 enables them for
6
Message-id: 20201030022618.785675-4-richard.henderson@linaro.org
6
an AArch64 EL1. They therefore are only relevant for AArch32
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
cpregs when the cpreg can be accessed from EL0. The logic
8
in access_check_cp_reg() will check this, so it is safe to
9
add a .fgt marking to an ARM_CP_STATE_BOTH ARMCPRegInfo.
10
11
The DO_BIT and DO_REV_BIT macros define enum constants FGT_##bitname
12
which can be used to specify the FGT bit, eg
13
.fgt = FGT_AFSR0_EL1
14
(We assume that there is no bit name duplication across the FGT
15
registers, for brevity's sake.)
16
17
Subsequent commits will add the .fgt fields to the relevant register
18
definitions and define the FGT_nnn values for them.
19
20
Note that some of the FGT traps are for instructions that we don't
21
handle via the cpregs mechanisms (mostly these are instruction traps).
22
Those we will have to handle separately.
23
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Tested-by: Fuad Tabba <tabba@google.com>
27
Message-id: 20230130182459.3309057-10-peter.maydell@linaro.org
28
Message-id: 20230127175507.2895013-10-peter.maydell@linaro.org
9
---
29
---
10
target/arm/translate.c | 14 ++------------
30
target/arm/cpregs.h | 72 ++++++++++++++++++++++++++++++++++++++
11
1 file changed, 2 insertions(+), 12 deletions(-)
31
target/arm/cpu.h | 1 +
12
32
target/arm/internals.h | 20 +++++++++++
33
target/arm/translate.h | 2 ++
34
target/arm/helper.c | 9 +++++
35
target/arm/op_helper.c | 30 ++++++++++++++++
36
target/arm/translate-a64.c | 3 +-
37
target/arm/translate.c | 2 ++
38
8 files changed, 138 insertions(+), 1 deletion(-)
39
40
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/cpregs.h
43
+++ b/target/arm/cpregs.h
44
@@ -XXX,XX +XXX,XX @@ FIELD(HDFGWTR_EL2, NBRBCTL, 60, 1)
45
FIELD(HDFGWTR_EL2, NBRBDATA, 61, 1)
46
FIELD(HDFGWTR_EL2, NPMSNEVFR_EL1, 62, 1)
47
48
+/* Which fine-grained trap bit register to check, if any */
49
+FIELD(FGT, TYPE, 10, 3)
50
+FIELD(FGT, REV, 9, 1) /* Is bit sense reversed? */
51
+FIELD(FGT, IDX, 6, 3) /* Index within a uint64_t[] array */
52
+FIELD(FGT, BITPOS, 0, 6) /* Bit position within the uint64_t */
53
+
54
+/*
55
+ * Macros to define FGT_##bitname enum constants to use in ARMCPRegInfo::fgt
56
+ * fields. We assume for brevity's sake that there are no duplicated
57
+ * bit names across the various FGT registers.
58
+ */
59
+#define DO_BIT(REG, BITNAME) \
60
+ FGT_##BITNAME = FGT_##REG | R_##REG##_EL2_##BITNAME##_SHIFT
61
+
62
+/* Some bits have reversed sense, so 0 means trap and 1 means not */
63
+#define DO_REV_BIT(REG, BITNAME) \
64
+ FGT_##BITNAME = FGT_##REG | FGT_REV | R_##REG##_EL2_##BITNAME##_SHIFT
65
+
66
+typedef enum FGTBit {
67
+ /*
68
+ * These bits tell us which register arrays to use:
69
+ * if FGT_R is set then reads are checked against fgt_read[];
70
+ * if FGT_W is set then writes are checked against fgt_write[];
71
+ * if FGT_EXEC is set then all accesses are checked against fgt_exec[].
72
+ *
73
+ * For almost all bits in the R/W register pairs, the bit exists in
74
+ * both registers for a RW register, in HFGRTR/HDFGRTR for a RO register
75
+ * with the corresponding HFGWTR/HDFGTWTR bit being RES0, and vice-versa
76
+ * for a WO register. There are unfortunately a couple of exceptions
77
+ * (PMCR_EL0, TRFCR_EL1) where the register being trapped is RW but
78
+ * the FGT system only allows trapping of writes, not reads.
79
+ *
80
+ * Note that we arrange these bits so that a 0 FGTBit means "no trap".
81
+ */
82
+ FGT_R = 1 << R_FGT_TYPE_SHIFT,
83
+ FGT_W = 2 << R_FGT_TYPE_SHIFT,
84
+ FGT_EXEC = 4 << R_FGT_TYPE_SHIFT,
85
+ FGT_RW = FGT_R | FGT_W,
86
+ /* Bit to identify whether trap bit is reversed sense */
87
+ FGT_REV = R_FGT_REV_MASK,
88
+
89
+ /*
90
+ * If a bit exists in HFGRTR/HDFGRTR then either the register being
91
+ * trapped is RO or the bit also exists in HFGWTR/HDFGWTR, so we either
92
+ * want to trap for both reads and writes or else it's harmless to mark
93
+ * it as trap-on-writes.
94
+ * If a bit exists only in HFGWTR/HDFGWTR then either the register being
95
+ * trapped is WO, or else it is one of the two oddball special cases
96
+ * which are RW but have only a write trap. We mark these as only
97
+ * FGT_W so we get the right behaviour for those special cases.
98
+ * (If a bit was added in future that provided only a read trap for an
99
+ * RW register we'd need to do something special to get the FGT_R bit
100
+ * only. But this seems unlikely to happen.)
101
+ *
102
+ * So for the DO_BIT/DO_REV_BIT macros: use FGT_HFGRTR/FGT_HDFGRTR if
103
+ * the bit exists in that register. Otherwise use FGT_HFGWTR/FGT_HDFGWTR.
104
+ */
105
+ FGT_HFGRTR = FGT_RW | (FGTREG_HFGRTR << R_FGT_IDX_SHIFT),
106
+ FGT_HFGWTR = FGT_W | (FGTREG_HFGWTR << R_FGT_IDX_SHIFT),
107
+ FGT_HDFGRTR = FGT_RW | (FGTREG_HDFGRTR << R_FGT_IDX_SHIFT),
108
+ FGT_HDFGWTR = FGT_W | (FGTREG_HDFGWTR << R_FGT_IDX_SHIFT),
109
+ FGT_HFGITR = FGT_EXEC | (FGTREG_HFGITR << R_FGT_IDX_SHIFT),
110
+} FGTBit;
111
+
112
+#undef DO_BIT
113
+#undef DO_REV_BIT
114
+
115
typedef struct ARMCPRegInfo ARMCPRegInfo;
116
117
/*
118
@@ -XXX,XX +XXX,XX @@ struct ARMCPRegInfo {
119
CPAccessRights access;
120
/* Security state: ARM_CP_SECSTATE_* bits/values */
121
CPSecureState secure;
122
+ /*
123
+ * Which fine-grained trap register bit to check, if any. This
124
+ * value encodes both the trap register and bit within it.
125
+ */
126
+ FGTBit fgt;
127
/*
128
* The opaque pointer passed to define_arm_cp_regs_with_opaque() when
129
* this register was defined: can be used to hand data through to the
130
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
131
index XXXXXXX..XXXXXXX 100644
132
--- a/target/arm/cpu.h
133
+++ b/target/arm/cpu.h
134
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, FPEXC_EL, 8, 2)
135
/* Memory operations require alignment: SCTLR_ELx.A or CCR.UNALIGN_TRP */
136
FIELD(TBFLAG_ANY, ALIGN_MEM, 10, 1)
137
FIELD(TBFLAG_ANY, PSTATE__IL, 11, 1)
138
+FIELD(TBFLAG_ANY, FGT_ACTIVE, 12, 1)
139
140
/*
141
* Bit usage when in AArch32 state, both A- and M-profile.
142
diff --git a/target/arm/internals.h b/target/arm/internals.h
143
index XXXXXXX..XXXXXXX 100644
144
--- a/target/arm/internals.h
145
+++ b/target/arm/internals.h
146
@@ -XXX,XX +XXX,XX @@ static inline uint64_t arm_mdcr_el2_eff(CPUARMState *env)
147
((1 << (1 - 1)) | (1 << (2 - 1)) | \
148
(1 << (4 - 1)) | (1 << (8 - 1)) | (1 << (16 - 1)))
149
150
+/*
151
+ * Return true if it is possible to take a fine-grained-trap to EL2.
152
+ */
153
+static inline bool arm_fgt_active(CPUARMState *env, int el)
154
+{
155
+ /*
156
+ * The Arm ARM only requires the "{E2H,TGE} != {1,1}" test for traps
157
+ * that can affect EL0, but it is harmless to do the test also for
158
+ * traps on registers that are only accessible at EL1 because if the test
159
+ * returns true then we can't be executing at EL1 anyway.
160
+ * FGT traps only happen when EL2 is enabled and EL1 is AArch64;
161
+ * traps from AArch32 only happen for the EL0 is AArch32 case.
162
+ */
163
+ return cpu_isar_feature(aa64_fgt, env_archcpu(env)) &&
164
+ el < 2 && arm_is_el2_enabled(env) &&
165
+ arm_el_is_aa64(env, 1) &&
166
+ (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE) &&
167
+ (!arm_feature(env, ARM_FEATURE_EL3) || (env->cp15.scr_el3 & SCR_FGTEN));
168
+}
169
+
170
#endif
171
diff --git a/target/arm/translate.h b/target/arm/translate.h
172
index XXXXXXX..XXXXXXX 100644
173
--- a/target/arm/translate.h
174
+++ b/target/arm/translate.h
175
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
176
bool is_nonstreaming;
177
/* True if MVE insns are definitely not predicated by VPR or LTPSIZE */
178
bool mve_no_pred;
179
+ /* True if fine-grained traps are active */
180
+ bool fgt_active;
181
/*
182
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
183
* < 0, set by the current instruction.
184
diff --git a/target/arm/helper.c b/target/arm/helper.c
185
index XXXXXXX..XXXXXXX 100644
186
--- a/target/arm/helper.c
187
+++ b/target/arm/helper.c
188
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_common(CPUARMState *env, int fp_el,
189
if (arm_singlestep_active(env)) {
190
DP_TBFLAG_ANY(flags, SS_ACTIVE, 1);
191
}
192
+
193
return flags;
194
}
195
196
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el,
197
DP_TBFLAG_A32(flags, HSTR_ACTIVE, 1);
198
}
199
200
+ if (arm_fgt_active(env, el)) {
201
+ DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1);
202
+ }
203
+
204
if (env->uncached_cpsr & CPSR_IL) {
205
DP_TBFLAG_ANY(flags, PSTATE__IL, 1);
206
}
207
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
208
DP_TBFLAG_ANY(flags, PSTATE__IL, 1);
209
}
210
211
+ if (arm_fgt_active(env, el)) {
212
+ DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1);
213
+ }
214
+
215
if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
216
/*
217
* Set MTE_ACTIVE if any access may be Checked, and leave clear
218
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
219
index XXXXXXX..XXXXXXX 100644
220
--- a/target/arm/op_helper.c
221
+++ b/target/arm/op_helper.c
222
@@ -XXX,XX +XXX,XX @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key,
223
}
224
}
225
226
+ /*
227
+ * Fine-grained traps also are lower priority than undef-to-EL1,
228
+ * higher priority than trap-to-EL3, and we don't care about priority
229
+ * order with other EL2 traps because the syndrome value is the same.
230
+ */
231
+ if (arm_fgt_active(env, arm_current_el(env))) {
232
+ uint64_t trapword = 0;
233
+ unsigned int idx = FIELD_EX32(ri->fgt, FGT, IDX);
234
+ unsigned int bitpos = FIELD_EX32(ri->fgt, FGT, BITPOS);
235
+ bool rev = FIELD_EX32(ri->fgt, FGT, REV);
236
+ bool trapbit;
237
+
238
+ if (ri->fgt & FGT_EXEC) {
239
+ assert(idx < ARRAY_SIZE(env->cp15.fgt_exec));
240
+ trapword = env->cp15.fgt_exec[idx];
241
+ } else if (isread && (ri->fgt & FGT_R)) {
242
+ assert(idx < ARRAY_SIZE(env->cp15.fgt_read));
243
+ trapword = env->cp15.fgt_read[idx];
244
+ } else if (!isread && (ri->fgt & FGT_W)) {
245
+ assert(idx < ARRAY_SIZE(env->cp15.fgt_write));
246
+ trapword = env->cp15.fgt_write[idx];
247
+ }
248
+
249
+ trapbit = extract64(trapword, bitpos, 1);
250
+ if (trapbit != rev) {
251
+ res = CP_ACCESS_TRAP_EL2;
252
+ goto fail;
253
+ }
254
+ }
255
+
256
if (likely(res == CP_ACCESS_OK)) {
257
return ri;
258
}
259
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
260
index XXXXXXX..XXXXXXX 100644
261
--- a/target/arm/translate-a64.c
262
+++ b/target/arm/translate-a64.c
263
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
264
return;
265
}
266
267
- if (ri->accessfn) {
268
+ if (ri->accessfn || (ri->fgt && s->fgt_active)) {
269
/* Emit code to perform further access permissions checks at
270
* runtime; this may result in an exception.
271
*/
272
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
273
dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
274
dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
275
dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
276
+ dc->fgt_active = EX_TBFLAG_ANY(tb_flags, FGT_ACTIVE);
277
dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
278
dc->sme_excp_el = EX_TBFLAG_A64(tb_flags, SMEEXC_EL);
279
dc->vl = (EX_TBFLAG_A64(tb_flags, VL) + 1) * 16;
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
280
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
index XXXXXXX..XXXXXXX 100644
281
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
282
--- a/target/arm/translate.c
16
+++ b/target/arm/translate.c
283
+++ b/target/arm/translate.c
17
@@ -XXX,XX +XXX,XX @@ static inline long vfp_reg_offset(bool dp, unsigned reg)
284
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
18
}
285
}
19
}
286
20
287
if ((s->hstr_active && s->current_el == 0) || ri->accessfn ||
21
-/* Return the offset of a 32-bit piece of a NEON register.
288
+ (ri->fgt && s->fgt_active) ||
22
- zero is the least significant end of the register. */
289
(arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
23
-static inline long
290
/*
24
-neon_reg_offset (int reg, int n)
291
* Emit code to perform further access permissions checks at
25
-{
292
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
26
- int sreg;
293
dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
27
- sreg = reg * 2 + n;
294
dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
28
- return vfp_reg_offset(0, sreg);
295
dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
29
-}
296
+ dc->fgt_active = EX_TBFLAG_ANY(tb_flags, FGT_ACTIVE);
30
-
297
31
static TCGv_i32 neon_load_reg(int reg, int pass)
298
if (arm_feature(env, ARM_FEATURE_M)) {
32
{
299
dc->vfp_enabled = 1;
33
TCGv_i32 tmp = tcg_temp_new_i32();
34
- tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
35
+ tcg_gen_ld_i32(tmp, cpu_env, neon_element_offset(reg, pass, MO_32));
36
return tmp;
37
}
38
39
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
40
{
41
- tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
42
+ tcg_gen_st_i32(var, cpu_env, neon_element_offset(reg, pass, MO_32));
43
tcg_temp_free_i32(var);
44
}
45
46
--
300
--
47
2.20.1
301
2.34.1
48
49
diff view generated by jsdifflib
New patch
1
Mark up the sysreg definitions for the registers trapped
2
by HFGRTR/HFGWTR bits 0..11.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Fuad Tabba <tabba@google.com>
7
Message-id: 20230130182459.3309057-11-peter.maydell@linaro.org
8
Message-id: 20230127175507.2895013-11-peter.maydell@linaro.org
9
---
10
target/arm/cpregs.h | 14 ++++++++++++++
11
target/arm/helper.c | 17 +++++++++++++++++
12
2 files changed, 31 insertions(+)
13
14
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpregs.h
17
+++ b/target/arm/cpregs.h
18
@@ -XXX,XX +XXX,XX @@ typedef enum FGTBit {
19
FGT_HDFGRTR = FGT_RW | (FGTREG_HDFGRTR << R_FGT_IDX_SHIFT),
20
FGT_HDFGWTR = FGT_W | (FGTREG_HDFGWTR << R_FGT_IDX_SHIFT),
21
FGT_HFGITR = FGT_EXEC | (FGTREG_HFGITR << R_FGT_IDX_SHIFT),
22
+
23
+ /* Trap bits in HFGRTR_EL2 / HFGWTR_EL2, starting from bit 0. */
24
+ DO_BIT(HFGRTR, AFSR0_EL1),
25
+ DO_BIT(HFGRTR, AFSR1_EL1),
26
+ DO_BIT(HFGRTR, AIDR_EL1),
27
+ DO_BIT(HFGRTR, AMAIR_EL1),
28
+ DO_BIT(HFGRTR, APDAKEY),
29
+ DO_BIT(HFGRTR, APDBKEY),
30
+ DO_BIT(HFGRTR, APGAKEY),
31
+ DO_BIT(HFGRTR, APIAKEY),
32
+ DO_BIT(HFGRTR, APIBKEY),
33
+ DO_BIT(HFGRTR, CCSIDR_EL1),
34
+ DO_BIT(HFGRTR, CLIDR_EL1),
35
+ DO_BIT(HFGRTR, CONTEXTIDR_EL1),
36
} FGTBit;
37
38
#undef DO_BIT
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/helper.c
42
+++ b/target/arm/helper.c
43
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cp_reginfo[] = {
44
{ .name = "CONTEXTIDR_EL1", .state = ARM_CP_STATE_BOTH,
45
.opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
46
.access = PL1_RW, .accessfn = access_tvm_trvm,
47
+ .fgt = FGT_CONTEXTIDR_EL1,
48
.secure = ARM_CP_SECSTATE_NS,
49
.fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[1]),
50
.resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
51
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
52
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
53
.access = PL1_R,
54
.accessfn = access_tid4,
55
+ .fgt = FGT_CCSIDR_EL1,
56
.readfn = ccsidr_read, .type = ARM_CP_NO_RAW },
57
{ .name = "CSSELR", .state = ARM_CP_STATE_BOTH,
58
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
59
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
60
.opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 7,
61
.access = PL1_R, .type = ARM_CP_CONST,
62
.accessfn = access_aa64_tid1,
63
+ .fgt = FGT_AIDR_EL1,
64
.resetvalue = 0 },
65
/*
66
* Auxiliary fault status registers: these also are IMPDEF, and we
67
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
68
{ .name = "AFSR0_EL1", .state = ARM_CP_STATE_BOTH,
69
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 0,
70
.access = PL1_RW, .accessfn = access_tvm_trvm,
71
+ .fgt = FGT_AFSR0_EL1,
72
.type = ARM_CP_CONST, .resetvalue = 0 },
73
{ .name = "AFSR1_EL1", .state = ARM_CP_STATE_BOTH,
74
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 1,
75
.access = PL1_RW, .accessfn = access_tvm_trvm,
76
+ .fgt = FGT_AFSR1_EL1,
77
.type = ARM_CP_CONST, .resetvalue = 0 },
78
/*
79
* MAIR can just read-as-written because we don't implement caches
80
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
81
{ .name = "AMAIR0", .state = ARM_CP_STATE_BOTH,
82
.opc0 = 3, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 0,
83
.access = PL1_RW, .accessfn = access_tvm_trvm,
84
+ .fgt = FGT_AMAIR_EL1,
85
.type = ARM_CP_CONST, .resetvalue = 0 },
86
/* AMAIR1 is mapped to AMAIR_EL1[63:32] */
87
{ .name = "AMAIR1", .cp = 15, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 1,
88
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pauth_reginfo[] = {
89
{ .name = "APDAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
90
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 0,
91
.access = PL1_RW, .accessfn = access_pauth,
92
+ .fgt = FGT_APDAKEY,
93
.fieldoffset = offsetof(CPUARMState, keys.apda.lo) },
94
{ .name = "APDAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
95
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 1,
96
.access = PL1_RW, .accessfn = access_pauth,
97
+ .fgt = FGT_APDAKEY,
98
.fieldoffset = offsetof(CPUARMState, keys.apda.hi) },
99
{ .name = "APDBKEYLO_EL1", .state = ARM_CP_STATE_AA64,
100
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 2,
101
.access = PL1_RW, .accessfn = access_pauth,
102
+ .fgt = FGT_APDBKEY,
103
.fieldoffset = offsetof(CPUARMState, keys.apdb.lo) },
104
{ .name = "APDBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
105
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 3,
106
.access = PL1_RW, .accessfn = access_pauth,
107
+ .fgt = FGT_APDBKEY,
108
.fieldoffset = offsetof(CPUARMState, keys.apdb.hi) },
109
{ .name = "APGAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
110
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 3, .opc2 = 0,
111
.access = PL1_RW, .accessfn = access_pauth,
112
+ .fgt = FGT_APGAKEY,
113
.fieldoffset = offsetof(CPUARMState, keys.apga.lo) },
114
{ .name = "APGAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
115
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 3, .opc2 = 1,
116
.access = PL1_RW, .accessfn = access_pauth,
117
+ .fgt = FGT_APGAKEY,
118
.fieldoffset = offsetof(CPUARMState, keys.apga.hi) },
119
{ .name = "APIAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
120
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 0,
121
.access = PL1_RW, .accessfn = access_pauth,
122
+ .fgt = FGT_APIAKEY,
123
.fieldoffset = offsetof(CPUARMState, keys.apia.lo) },
124
{ .name = "APIAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
125
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 1,
126
.access = PL1_RW, .accessfn = access_pauth,
127
+ .fgt = FGT_APIAKEY,
128
.fieldoffset = offsetof(CPUARMState, keys.apia.hi) },
129
{ .name = "APIBKEYLO_EL1", .state = ARM_CP_STATE_AA64,
130
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 2,
131
.access = PL1_RW, .accessfn = access_pauth,
132
+ .fgt = FGT_APIBKEY,
133
.fieldoffset = offsetof(CPUARMState, keys.apib.lo) },
134
{ .name = "APIBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
135
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 3,
136
.access = PL1_RW, .accessfn = access_pauth,
137
+ .fgt = FGT_APIBKEY,
138
.fieldoffset = offsetof(CPUARMState, keys.apib.hi) },
139
};
140
141
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
142
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
143
.access = PL1_R, .type = ARM_CP_CONST,
144
.accessfn = access_tid4,
145
+ .fgt = FGT_CLIDR_EL1,
146
.resetvalue = cpu->clidr
147
};
148
define_one_arm_cp_reg(cpu, &clidr);
149
--
150
2.34.1
diff view generated by jsdifflib
1
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
1
Mark up the sysreg definitions for the registers trapped
2
by HFGRTR/HFGWTR bits 12..23.
2
3
3
Secure mode is not exempted from checking SCR_EL3.TLOR, and in the
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
future HCR_EL2.TLOR when S-EL2 is enabled.
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Fuad Tabba <tabba@google.com>
7
Message-id: 20230130182459.3309057-12-peter.maydell@linaro.org
8
Message-id: 20230127175507.2895013-12-peter.maydell@linaro.org
9
---
10
target/arm/cpregs.h | 12 ++++++++++++
11
target/arm/helper.c | 12 ++++++++++++
12
2 files changed, 24 insertions(+)
5
13
6
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
14
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
index XXXXXXX..XXXXXXX 100644
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
--- a/target/arm/cpregs.h
9
---
17
+++ b/target/arm/cpregs.h
10
target/arm/helper.c | 19 +++++--------------
18
@@ -XXX,XX +XXX,XX @@ typedef enum FGTBit {
11
1 file changed, 5 insertions(+), 14 deletions(-)
19
DO_BIT(HFGRTR, CCSIDR_EL1),
12
20
DO_BIT(HFGRTR, CLIDR_EL1),
21
DO_BIT(HFGRTR, CONTEXTIDR_EL1),
22
+ DO_BIT(HFGRTR, CPACR_EL1),
23
+ DO_BIT(HFGRTR, CSSELR_EL1),
24
+ DO_BIT(HFGRTR, CTR_EL0),
25
+ DO_BIT(HFGRTR, DCZID_EL0),
26
+ DO_BIT(HFGRTR, ESR_EL1),
27
+ DO_BIT(HFGRTR, FAR_EL1),
28
+ DO_BIT(HFGRTR, ISR_EL1),
29
+ DO_BIT(HFGRTR, LORC_EL1),
30
+ DO_BIT(HFGRTR, LOREA_EL1),
31
+ DO_BIT(HFGRTR, LORID_EL1),
32
+ DO_BIT(HFGRTR, LORN_EL1),
33
+ DO_BIT(HFGRTR, LORSA_EL1),
34
} FGTBit;
35
36
#undef DO_BIT
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
39
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
40
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
41
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
18
#endif
42
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0, },
19
43
{ .name = "CPACR", .state = ARM_CP_STATE_BOTH, .opc0 = 3,
20
/* Shared logic between LORID and the rest of the LOR* registers.
44
.crn = 1, .crm = 0, .opc1 = 0, .opc2 = 2, .accessfn = cpacr_access,
21
- * Secure state has already been delt with.
45
+ .fgt = FGT_CPACR_EL1,
22
+ * Secure state exclusion has already been dealt with.
46
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.cpacr_el1),
23
*/
47
.resetfn = cpacr_reset, .writefn = cpacr_write, .readfn = cpacr_read },
24
-static CPAccessResult access_lor_ns(CPUARMState *env)
48
};
25
+static CPAccessResult access_lor_ns(CPUARMState *env,
49
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
26
+ const ARMCPRegInfo *ri, bool isread)
50
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
27
{
51
.access = PL1_RW,
28
int el = arm_current_el(env);
52
.accessfn = access_tid4,
29
53
+ .fgt = FGT_CSSELR_EL1,
30
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_lor_ns(CPUARMState *env)
54
.writefn = csselr_write, .resetvalue = 0,
31
return CP_ACCESS_OK;
55
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.csselr_s),
32
}
56
offsetof(CPUARMState, cp15.csselr_ns) } },
33
57
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
34
-static CPAccessResult access_lorid(CPUARMState *env, const ARMCPRegInfo *ri,
58
.resetfn = arm_cp_reset_ignore },
35
- bool isread)
59
{ .name = "ISR_EL1", .state = ARM_CP_STATE_BOTH,
36
-{
60
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 1, .opc2 = 0,
37
- if (arm_is_secure_below_el3(env)) {
61
+ .fgt = FGT_ISR_EL1,
38
- /* Access ok in secure mode. */
62
.type = ARM_CP_NO_RAW, .access = PL1_R, .readfn = isr_read },
39
- return CP_ACCESS_OK;
63
/* 32 bit ITLB invalidates */
40
- }
64
{ .name = "ITLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 0,
41
- return access_lor_ns(env);
65
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_pmsa_cp_reginfo[] = {
42
-}
66
{ .name = "FAR_EL1", .state = ARM_CP_STATE_AA64,
43
-
67
.opc0 = 3, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
44
static CPAccessResult access_lor_other(CPUARMState *env,
68
.access = PL1_RW, .accessfn = access_tvm_trvm,
45
const ARMCPRegInfo *ri, bool isread)
69
+ .fgt = FGT_FAR_EL1,
46
{
70
.fieldoffset = offsetof(CPUARMState, cp15.far_el[1]),
47
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_lor_other(CPUARMState *env,
71
.resetvalue = 0, },
48
/* Access denied in secure mode. */
72
};
49
return CP_ACCESS_TRAP;
73
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
50
}
74
{ .name = "ESR_EL1", .state = ARM_CP_STATE_AA64,
51
- return access_lor_ns(env);
75
.opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0,
52
+ return access_lor_ns(env, ri, isread);
76
.access = PL1_RW, .accessfn = access_tvm_trvm,
53
}
77
+ .fgt = FGT_ESR_EL1,
54
78
.fieldoffset = offsetof(CPUARMState, cp15.esr_el[1]), .resetvalue = 0, },
55
/*
79
{ .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
80
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0,
81
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
82
{ .name = "DCZID_EL0", .state = ARM_CP_STATE_AA64,
83
.opc0 = 3, .opc1 = 3, .opc2 = 7, .crn = 0, .crm = 0,
84
.access = PL0_R, .type = ARM_CP_NO_RAW,
85
+ .fgt = FGT_DCZID_EL0,
86
.readfn = aa64_dczid_read },
87
{ .name = "DC_ZVA", .state = ARM_CP_STATE_AA64,
88
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 4, .opc2 = 1,
56
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lor_reginfo[] = {
89
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lor_reginfo[] = {
90
{ .name = "LORSA_EL1", .state = ARM_CP_STATE_AA64,
91
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 0,
92
.access = PL1_RW, .accessfn = access_lor_other,
93
+ .fgt = FGT_LORSA_EL1,
94
.type = ARM_CP_CONST, .resetvalue = 0 },
95
{ .name = "LOREA_EL1", .state = ARM_CP_STATE_AA64,
96
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 1,
97
.access = PL1_RW, .accessfn = access_lor_other,
98
+ .fgt = FGT_LOREA_EL1,
99
.type = ARM_CP_CONST, .resetvalue = 0 },
100
{ .name = "LORN_EL1", .state = ARM_CP_STATE_AA64,
101
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 2,
102
.access = PL1_RW, .accessfn = access_lor_other,
103
+ .fgt = FGT_LORN_EL1,
104
.type = ARM_CP_CONST, .resetvalue = 0 },
105
{ .name = "LORC_EL1", .state = ARM_CP_STATE_AA64,
106
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 3,
107
.access = PL1_RW, .accessfn = access_lor_other,
108
+ .fgt = FGT_LORC_EL1,
57
.type = ARM_CP_CONST, .resetvalue = 0 },
109
.type = ARM_CP_CONST, .resetvalue = 0 },
58
{ .name = "LORID_EL1", .state = ARM_CP_STATE_AA64,
110
{ .name = "LORID_EL1", .state = ARM_CP_STATE_AA64,
59
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7,
111
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7,
60
- .access = PL1_R, .accessfn = access_lorid,
112
.access = PL1_R, .accessfn = access_lor_ns,
61
+ .access = PL1_R, .accessfn = access_lor_ns,
113
+ .fgt = FGT_LORID_EL1,
62
.type = ARM_CP_CONST, .resetvalue = 0 },
114
.type = ARM_CP_CONST, .resetvalue = 0 },
63
REGINFO_SENTINEL
64
};
115
};
116
117
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
118
{ .name = "CTR_EL0", .state = ARM_CP_STATE_AA64,
119
.opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 0, .crm = 0,
120
.access = PL0_R, .accessfn = ctr_el0_access,
121
+ .fgt = FGT_CTR_EL0,
122
.type = ARM_CP_CONST, .resetvalue = cpu->ctr },
123
/* TCMTR and TLBTR exist in v8 but have no 64-bit versions */
124
{ .name = "TCMTR",
65
--
125
--
66
2.20.1
126
2.34.1
67
68
diff view generated by jsdifflib
New patch
1
Mark up the sysreg definitions for the registers trapped
2
by HFGRTR/HFGWTR bits 24..35.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Fuad Tabba <tabba@google.com>
7
Message-id: 20230130182459.3309057-13-peter.maydell@linaro.org
8
Message-id: 20230127175507.2895013-13-peter.maydell@linaro.org
9
---
10
target/arm/cpregs.h | 12 ++++++++++++
11
target/arm/helper.c | 14 ++++++++++++++
12
2 files changed, 26 insertions(+)
13
14
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpregs.h
17
+++ b/target/arm/cpregs.h
18
@@ -XXX,XX +XXX,XX @@ typedef enum FGTBit {
19
DO_BIT(HFGRTR, LORID_EL1),
20
DO_BIT(HFGRTR, LORN_EL1),
21
DO_BIT(HFGRTR, LORSA_EL1),
22
+ DO_BIT(HFGRTR, MAIR_EL1),
23
+ DO_BIT(HFGRTR, MIDR_EL1),
24
+ DO_BIT(HFGRTR, MPIDR_EL1),
25
+ DO_BIT(HFGRTR, PAR_EL1),
26
+ DO_BIT(HFGRTR, REVIDR_EL1),
27
+ DO_BIT(HFGRTR, SCTLR_EL1),
28
+ DO_BIT(HFGRTR, SCXTNUM_EL1),
29
+ DO_BIT(HFGRTR, SCXTNUM_EL0),
30
+ DO_BIT(HFGRTR, TCR_EL1),
31
+ DO_BIT(HFGRTR, TPIDR_EL1),
32
+ DO_BIT(HFGRTR, TPIDRRO_EL0),
33
+ DO_BIT(HFGRTR, TPIDR_EL0),
34
} FGTBit;
35
36
#undef DO_BIT
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/helper.c
40
+++ b/target/arm/helper.c
41
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
42
{ .name = "MAIR_EL1", .state = ARM_CP_STATE_AA64,
43
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0,
44
.access = PL1_RW, .accessfn = access_tvm_trvm,
45
+ .fgt = FGT_MAIR_EL1,
46
.fieldoffset = offsetof(CPUARMState, cp15.mair_el[1]),
47
.resetvalue = 0 },
48
{ .name = "MAIR_EL3", .state = ARM_CP_STATE_AA64,
49
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
50
{ .name = "TPIDR_EL0", .state = ARM_CP_STATE_AA64,
51
.opc0 = 3, .opc1 = 3, .opc2 = 2, .crn = 13, .crm = 0,
52
.access = PL0_RW,
53
+ .fgt = FGT_TPIDR_EL0,
54
.fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[0]), .resetvalue = 0 },
55
{ .name = "TPIDRURW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 2,
56
.access = PL0_RW,
57
+ .fgt = FGT_TPIDR_EL0,
58
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrurw_s),
59
offsetoflow32(CPUARMState, cp15.tpidrurw_ns) },
60
.resetfn = arm_cp_reset_ignore },
61
{ .name = "TPIDRRO_EL0", .state = ARM_CP_STATE_AA64,
62
.opc0 = 3, .opc1 = 3, .opc2 = 3, .crn = 13, .crm = 0,
63
.access = PL0_R | PL1_W,
64
+ .fgt = FGT_TPIDRRO_EL0,
65
.fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el[0]),
66
.resetvalue = 0},
67
{ .name = "TPIDRURO", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 3,
68
.access = PL0_R | PL1_W,
69
+ .fgt = FGT_TPIDRRO_EL0,
70
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidruro_s),
71
offsetoflow32(CPUARMState, cp15.tpidruro_ns) },
72
.resetfn = arm_cp_reset_ignore },
73
{ .name = "TPIDR_EL1", .state = ARM_CP_STATE_AA64,
74
.opc0 = 3, .opc1 = 0, .opc2 = 4, .crn = 13, .crm = 0,
75
.access = PL1_RW,
76
+ .fgt = FGT_TPIDR_EL1,
77
.fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[1]), .resetvalue = 0 },
78
{ .name = "TPIDRPRW", .opc1 = 0, .cp = 15, .crn = 13, .crm = 0, .opc2 = 4,
79
.access = PL1_RW,
80
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
81
{ .name = "TCR_EL1", .state = ARM_CP_STATE_AA64,
82
.opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
83
.access = PL1_RW, .accessfn = access_tvm_trvm,
84
+ .fgt = FGT_TCR_EL1,
85
.writefn = vmsa_tcr_el12_write,
86
.raw_writefn = raw_write,
87
.resetvalue = 0,
88
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
89
.type = ARM_CP_ALIAS,
90
.opc0 = 3, .opc1 = 0, .crn = 7, .crm = 4, .opc2 = 0,
91
.access = PL1_RW, .resetvalue = 0,
92
+ .fgt = FGT_PAR_EL1,
93
.fieldoffset = offsetof(CPUARMState, cp15.par_el[1]),
94
.writefn = par_write },
95
#endif
96
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo scxtnum_reginfo[] = {
97
{ .name = "SCXTNUM_EL0", .state = ARM_CP_STATE_AA64,
98
.opc0 = 3, .opc1 = 3, .crn = 13, .crm = 0, .opc2 = 7,
99
.access = PL0_RW, .accessfn = access_scxtnum,
100
+ .fgt = FGT_SCXTNUM_EL0,
101
.fieldoffset = offsetof(CPUARMState, scxtnum_el[0]) },
102
{ .name = "SCXTNUM_EL1", .state = ARM_CP_STATE_AA64,
103
.opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 7,
104
.access = PL1_RW, .accessfn = access_scxtnum,
105
+ .fgt = FGT_SCXTNUM_EL1,
106
.fieldoffset = offsetof(CPUARMState, scxtnum_el[1]) },
107
{ .name = "SCXTNUM_EL2", .state = ARM_CP_STATE_AA64,
108
.opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 7,
109
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
110
{ .name = "MIDR_EL1", .state = ARM_CP_STATE_BOTH,
111
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 0,
112
.access = PL1_R, .type = ARM_CP_NO_RAW, .resetvalue = cpu->midr,
113
+ .fgt = FGT_MIDR_EL1,
114
.fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid),
115
.readfn = midr_read },
116
/* crn = 0 op1 = 0 crm = 0 op2 = 7 : AArch32 aliases of MIDR */
117
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
118
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 6,
119
.access = PL1_R,
120
.accessfn = access_aa64_tid1,
121
+ .fgt = FGT_REVIDR_EL1,
122
.type = ARM_CP_CONST, .resetvalue = cpu->revidr },
123
};
124
ARMCPRegInfo id_v8_midr_alias_cp_reginfo = {
125
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
126
ARMCPRegInfo mpidr_cp_reginfo[] = {
127
{ .name = "MPIDR_EL1", .state = ARM_CP_STATE_BOTH,
128
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 5,
129
+ .fgt = FGT_MPIDR_EL1,
130
.access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_RAW },
131
};
132
#ifdef CONFIG_USER_ONLY
133
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
134
.name = "SCTLR", .state = ARM_CP_STATE_BOTH,
135
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0,
136
.access = PL1_RW, .accessfn = access_tvm_trvm,
137
+ .fgt = FGT_SCTLR_EL1,
138
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.sctlr_s),
139
offsetof(CPUARMState, cp15.sctlr_ns) },
140
.writefn = sctlr_write, .resetvalue = cpu->reset_sctlr,
141
--
142
2.34.1
diff view generated by jsdifflib
1
In gicv3_init_cpuif() we copy the ARMCPU gicv3_maintenance_interrupt
1
Mark up the sysreg definitions for the registers trapped
2
into the GICv3CPUState struct's maintenance_irq field. This will
2
by HFGRTR/HFGWTR bits 36..63.
3
only work if the board happens to have already wired up the CPU
4
maintenance IRQ before the GIC was realized. Unfortunately this is
5
not the case for the 'virt' board, and so the value that gets copied
6
is NULL (since a qemu_irq is really a pointer to an IRQState struct
7
under the hood). The effect is that the CPU interface code never
8
actually raises the maintenance interrupt line.
9
3
10
Instead, since the GICv3CPUState has a pointer to the CPUState, make
4
Of these, some correspond to RAS registers which we implement as
11
the dereference at the point where we want to raise the interrupt, to
5
always-UNDEF: these don't need any extra handling for FGT because the
12
avoid an implicit requirement on board code to wire things up in a
6
UNDEF-to-EL1 always takes priority over any theoretical
13
particular order.
7
FGT-trap-to-EL2.
14
8
15
Reported-by: Jose Martins <josemartins90@gmail.com>
9
Bit 50 (NACCDATA_EL1) is for the ACCDATA_EL1 register which is part
10
of the FEAT_LS64_ACCDATA feature which we don't yet implement.
11
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Message-id: 20201009153904.28529-1-peter.maydell@linaro.org
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Luc Michel <luc@lmichel.fr>
14
Tested-by: Fuad Tabba <tabba@google.com>
15
Message-id: 20230130182459.3309057-14-peter.maydell@linaro.org
16
Message-id: 20230127175507.2895013-14-peter.maydell@linaro.org
19
---
17
---
20
include/hw/intc/arm_gicv3_common.h | 1 -
18
target/arm/cpregs.h | 7 +++++++
21
hw/intc/arm_gicv3_cpuif.c | 5 ++---
19
hw/intc/arm_gicv3_cpuif.c | 2 ++
22
2 files changed, 2 insertions(+), 4 deletions(-)
20
target/arm/helper.c | 10 ++++++++++
21
3 files changed, 19 insertions(+)
23
22
24
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
23
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
25
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/intc/arm_gicv3_common.h
25
--- a/target/arm/cpregs.h
27
+++ b/include/hw/intc/arm_gicv3_common.h
26
+++ b/target/arm/cpregs.h
28
@@ -XXX,XX +XXX,XX @@ struct GICv3CPUState {
27
@@ -XXX,XX +XXX,XX @@ typedef enum FGTBit {
29
qemu_irq parent_fiq;
28
DO_BIT(HFGRTR, TPIDR_EL1),
30
qemu_irq parent_virq;
29
DO_BIT(HFGRTR, TPIDRRO_EL0),
31
qemu_irq parent_vfiq;
30
DO_BIT(HFGRTR, TPIDR_EL0),
32
- qemu_irq maintenance_irq;
31
+ DO_BIT(HFGRTR, TTBR0_EL1),
33
32
+ DO_BIT(HFGRTR, TTBR1_EL1),
34
/* Redistributor */
33
+ DO_BIT(HFGRTR, VBAR_EL1),
35
uint32_t level; /* Current IRQ level */
34
+ DO_BIT(HFGRTR, ICC_IGRPENN_EL1),
35
+ DO_BIT(HFGRTR, ERRIDR_EL1),
36
+ DO_REV_BIT(HFGRTR, NSMPRI_EL1),
37
+ DO_REV_BIT(HFGRTR, NTPIDR2_EL0),
38
} FGTBit;
39
40
#undef DO_BIT
36
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
41
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
37
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/intc/arm_gicv3_cpuif.c
43
--- a/hw/intc/arm_gicv3_cpuif.c
39
+++ b/hw/intc/arm_gicv3_cpuif.c
44
+++ b/hw/intc/arm_gicv3_cpuif.c
40
@@ -XXX,XX +XXX,XX @@ static void gicv3_cpuif_virt_update(GICv3CPUState *cs)
45
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
41
int irqlevel = 0;
46
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 6,
42
int fiqlevel = 0;
47
.type = ARM_CP_IO | ARM_CP_NO_RAW,
43
int maintlevel = 0;
48
.access = PL1_RW, .accessfn = gicv3_fiq_access,
44
+ ARMCPU *cpu = ARM_CPU(cs->cpu);
49
+ .fgt = FGT_ICC_IGRPENN_EL1,
45
50
.readfn = icc_igrpen_read,
46
idx = hppvi_index(cs);
51
.writefn = icc_igrpen_write,
47
trace_gicv3_cpuif_virt_update(gicv3_redist_affid(cs), idx);
52
},
48
@@ -XXX,XX +XXX,XX @@ static void gicv3_cpuif_virt_update(GICv3CPUState *cs)
53
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
49
54
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 7,
50
qemu_set_irq(cs->parent_vfiq, fiqlevel);
55
.type = ARM_CP_IO | ARM_CP_NO_RAW,
51
qemu_set_irq(cs->parent_virq, irqlevel);
56
.access = PL1_RW, .accessfn = gicv3_irq_access,
52
- qemu_set_irq(cs->maintenance_irq, maintlevel);
57
+ .fgt = FGT_ICC_IGRPENN_EL1,
53
+ qemu_set_irq(cpu->gicv3_maintenance_interrupt, maintlevel);
58
.readfn = icc_igrpen_read,
54
}
59
.writefn = icc_igrpen_write,
55
60
},
56
static uint64_t icv_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
61
diff --git a/target/arm/helper.c b/target/arm/helper.c
57
@@ -XXX,XX +XXX,XX @@ void gicv3_init_cpuif(GICv3State *s)
62
index XXXXXXX..XXXXXXX 100644
58
&& cpu->gic_num_lrs) {
63
--- a/target/arm/helper.c
59
int j;
64
+++ b/target/arm/helper.c
60
65
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
61
- cs->maintenance_irq = cpu->gicv3_maintenance_interrupt;
66
{ .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
62
-
67
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0,
63
cs->num_list_regs = cpu->gic_num_lrs;
68
.access = PL1_RW, .accessfn = access_tvm_trvm,
64
cs->vpribits = cpu->gic_vpribits;
69
+ .fgt = FGT_TTBR0_EL1,
65
cs->vprebits = cpu->gic_vprebits;
70
.writefn = vmsa_ttbr_write, .resetvalue = 0,
71
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
72
offsetof(CPUARMState, cp15.ttbr0_ns) } },
73
{ .name = "TTBR1_EL1", .state = ARM_CP_STATE_BOTH,
74
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 1,
75
.access = PL1_RW, .accessfn = access_tvm_trvm,
76
+ .fgt = FGT_TTBR1_EL1,
77
.writefn = vmsa_ttbr_write, .resetvalue = 0,
78
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
79
offsetof(CPUARMState, cp15.ttbr1_ns) } },
80
@@ -XXX,XX +XXX,XX @@ static void disr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t val)
81
* ERRSELR_EL1
82
* may generate UNDEFINED, which is the effect we get by not
83
* listing them at all.
84
+ *
85
+ * These registers have fine-grained trap bits, but UNDEF-to-EL1
86
+ * is higher priority than FGT-to-EL2 so we do not need to list them
87
+ * in order to check for an FGT.
88
*/
89
static const ARMCPRegInfo minimal_ras_reginfo[] = {
90
{ .name = "DISR_EL1", .state = ARM_CP_STATE_BOTH,
91
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo minimal_ras_reginfo[] = {
92
{ .name = "ERRIDR_EL1", .state = ARM_CP_STATE_BOTH,
93
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 3, .opc2 = 0,
94
.access = PL1_R, .accessfn = access_terr,
95
+ .fgt = FGT_ERRIDR_EL1,
96
.type = ARM_CP_CONST, .resetvalue = 0 },
97
{ .name = "VDISR_EL2", .state = ARM_CP_STATE_BOTH,
98
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 1, .opc2 = 1,
99
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo sme_reginfo[] = {
100
{ .name = "TPIDR2_EL0", .state = ARM_CP_STATE_AA64,
101
.opc0 = 3, .opc1 = 3, .crn = 13, .crm = 0, .opc2 = 5,
102
.access = PL0_RW, .accessfn = access_tpidr2,
103
+ .fgt = FGT_NTPIDR2_EL0,
104
.fieldoffset = offsetof(CPUARMState, cp15.tpidr2_el0) },
105
{ .name = "SVCR", .state = ARM_CP_STATE_AA64,
106
.opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 2,
107
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo sme_reginfo[] = {
108
{ .name = "SMPRI_EL1", .state = ARM_CP_STATE_AA64,
109
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 4,
110
.access = PL1_RW, .accessfn = access_esm,
111
+ .fgt = FGT_NSMPRI_EL1,
112
.type = ARM_CP_CONST, .resetvalue = 0 },
113
{ .name = "SMPRIMAP_EL2", .state = ARM_CP_STATE_AA64,
114
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 5,
115
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
116
{ .name = "VBAR", .state = ARM_CP_STATE_BOTH,
117
.opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
118
.access = PL1_RW, .writefn = vbar_write,
119
+ .fgt = FGT_VBAR_EL1,
120
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s),
121
offsetof(CPUARMState, cp15.vbar_ns) },
122
.resetvalue = 0 },
66
--
123
--
67
2.20.1
124
2.34.1
68
69
diff view generated by jsdifflib
New patch
1
Mark up the sysreg definitons for the registers trapped
2
by HDFGRTR/HDFGWTR bits 0..11. These cover various debug
3
related registers.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Fuad Tabba <tabba@google.com>
8
Message-id: 20230130182459.3309057-15-peter.maydell@linaro.org
9
Message-id: 20230127175507.2895013-15-peter.maydell@linaro.org
10
---
11
target/arm/cpregs.h | 12 ++++++++++++
12
target/arm/debug_helper.c | 11 +++++++++++
13
2 files changed, 23 insertions(+)
14
15
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpregs.h
18
+++ b/target/arm/cpregs.h
19
@@ -XXX,XX +XXX,XX @@ typedef enum FGTBit {
20
DO_BIT(HFGRTR, ERRIDR_EL1),
21
DO_REV_BIT(HFGRTR, NSMPRI_EL1),
22
DO_REV_BIT(HFGRTR, NTPIDR2_EL0),
23
+
24
+ /* Trap bits in HDFGRTR_EL2 / HDFGWTR_EL2, starting from bit 0. */
25
+ DO_BIT(HDFGRTR, DBGBCRN_EL1),
26
+ DO_BIT(HDFGRTR, DBGBVRN_EL1),
27
+ DO_BIT(HDFGRTR, DBGWCRN_EL1),
28
+ DO_BIT(HDFGRTR, DBGWVRN_EL1),
29
+ DO_BIT(HDFGRTR, MDSCR_EL1),
30
+ DO_BIT(HDFGRTR, DBGCLAIM),
31
+ DO_BIT(HDFGWTR, OSLAR_EL1),
32
+ DO_BIT(HDFGRTR, OSLSR_EL1),
33
+ DO_BIT(HDFGRTR, OSECCR_EL1),
34
+ DO_BIT(HDFGRTR, OSDLR_EL1),
35
} FGTBit;
36
37
#undef DO_BIT
38
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/debug_helper.c
41
+++ b/target/arm/debug_helper.c
42
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
43
{ .name = "MDSCR_EL1", .state = ARM_CP_STATE_BOTH,
44
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
45
.access = PL1_RW, .accessfn = access_tda,
46
+ .fgt = FGT_MDSCR_EL1,
47
.fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1),
48
.resetvalue = 0 },
49
/*
50
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
51
{ .name = "OSECCR_EL1", .state = ARM_CP_STATE_BOTH, .cp = 14,
52
.opc0 = 2, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2,
53
.access = PL1_RW, .accessfn = access_tda,
54
+ .fgt = FGT_OSECCR_EL1,
55
.type = ARM_CP_CONST, .resetvalue = 0 },
56
/*
57
* DBGDSCRint[15,12,5:2] map to MDSCR_EL1[15,12,5:2]. Map all bits as
58
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
59
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 4,
60
.access = PL1_W, .type = ARM_CP_NO_RAW,
61
.accessfn = access_tdosa,
62
+ .fgt = FGT_OSLAR_EL1,
63
.writefn = oslar_write },
64
{ .name = "OSLSR_EL1", .state = ARM_CP_STATE_BOTH,
65
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 4,
66
.access = PL1_R, .resetvalue = 10,
67
.accessfn = access_tdosa,
68
+ .fgt = FGT_OSLSR_EL1,
69
.fieldoffset = offsetof(CPUARMState, cp15.oslsr_el1) },
70
/* Dummy OSDLR_EL1: 32-bit Linux will read this */
71
{ .name = "OSDLR_EL1", .state = ARM_CP_STATE_BOTH,
72
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 4,
73
.access = PL1_RW, .accessfn = access_tdosa,
74
+ .fgt = FGT_OSDLR_EL1,
75
.writefn = osdlr_write,
76
.fieldoffset = offsetof(CPUARMState, cp15.osdlr_el1) },
77
/*
78
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
79
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 6,
80
.type = ARM_CP_ALIAS,
81
.access = PL1_RW, .accessfn = access_tda,
82
+ .fgt = FGT_DBGCLAIM,
83
.writefn = dbgclaimset_write, .readfn = dbgclaimset_read },
84
{ .name = "DBGCLAIMCLR_EL1", .state = ARM_CP_STATE_BOTH,
85
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 6,
86
.access = PL1_RW, .accessfn = access_tda,
87
+ .fgt = FGT_DBGCLAIM,
88
.writefn = dbgclaimclr_write, .raw_writefn = raw_write,
89
.fieldoffset = offsetof(CPUARMState, cp15.dbgclaim) },
90
};
91
@@ -XXX,XX +XXX,XX @@ void define_debug_regs(ARMCPU *cpu)
92
{ .name = dbgbvr_el1_name, .state = ARM_CP_STATE_BOTH,
93
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,
94
.access = PL1_RW, .accessfn = access_tda,
95
+ .fgt = FGT_DBGBVRN_EL1,
96
.fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]),
97
.writefn = dbgbvr_write, .raw_writefn = raw_write
98
},
99
{ .name = dbgbcr_el1_name, .state = ARM_CP_STATE_BOTH,
100
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5,
101
.access = PL1_RW, .accessfn = access_tda,
102
+ .fgt = FGT_DBGBCRN_EL1,
103
.fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]),
104
.writefn = dbgbcr_write, .raw_writefn = raw_write
105
},
106
@@ -XXX,XX +XXX,XX @@ void define_debug_regs(ARMCPU *cpu)
107
{ .name = dbgwvr_el1_name, .state = ARM_CP_STATE_BOTH,
108
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,
109
.access = PL1_RW, .accessfn = access_tda,
110
+ .fgt = FGT_DBGWVRN_EL1,
111
.fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]),
112
.writefn = dbgwvr_write, .raw_writefn = raw_write
113
},
114
{ .name = dbgwcr_el1_name, .state = ARM_CP_STATE_BOTH,
115
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7,
116
.access = PL1_RW, .accessfn = access_tda,
117
+ .fgt = FGT_DBGWCRN_EL1,
118
.fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]),
119
.writefn = dbgwcr_write, .raw_writefn = raw_write
120
},
121
--
122
2.34.1
diff view generated by jsdifflib
1
The randomness tests in the NPCM7xx RNG test fail intermittently
1
Mark up the sysreg definitions for the registers trapped
2
but fairly frequently. On my machine running the test in a loop:
2
by HDFGRTR/HDFGWTR bits 12..x.
3
while QTEST_QEMU_BINARY=./qemu-system-aarch64 ./tests/qtest/npcm7xx_rng-test; do true; done
3
4
4
Bits 12..22 and bit 58 are for PMU registers.
5
will fail in less than a minute with an error like:
5
6
ERROR:../../tests/qtest/npcm7xx_rng-test.c:256:test_first_byte_runs:
6
The remaining bits in HDFGRTR/HDFGWTR are for traps on
7
assertion failed (calc_runs_p(buf.l, sizeof(buf) * BITS_PER_BYTE) > 0.01): (0.00286205989 > 0.01)
7
registers that are part of features we don't implement:
8
8
9
(Failures have been observed on all 4 of the randomness tests,
9
Bits 23..32 and 63 : FEAT_SPE
10
not just first_byte_runs.)
10
Bits 33..48 : FEAT_ETE
11
11
Bits 50..56 : FEAT_TRBE
12
It's not clear why these tests are failing like this, but intermittent
12
Bits 59..61 : FEAT_BRBE
13
failures make CI and merge testing awkward, so disable running them
13
Bit 62 : FEAT_SPEv1p2.
14
unless a developer specifically sets QEMU_TEST_FLAKY_RNG_TESTS when
15
running the test suite, until we work out the cause.
16
14
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20201102152454.8287-1-peter.maydell@linaro.org
17
Tested-by: Fuad Tabba <tabba@google.com>
20
Reviewed-by: Havard Skinnemoen <hskinnemoen@google.com>
18
Message-id: 20230130182459.3309057-16-peter.maydell@linaro.org
19
Message-id: 20230127175507.2895013-16-peter.maydell@linaro.org
21
---
20
---
22
tests/qtest/npcm7xx_rng-test.c | 14 ++++++++++----
21
target/arm/cpregs.h | 12 ++++++++++++
23
1 file changed, 10 insertions(+), 4 deletions(-)
22
target/arm/helper.c | 37 +++++++++++++++++++++++++++++++++++++
24
23
2 files changed, 49 insertions(+)
25
diff --git a/tests/qtest/npcm7xx_rng-test.c b/tests/qtest/npcm7xx_rng-test.c
24
25
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
26
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
27
--- a/tests/qtest/npcm7xx_rng-test.c
27
--- a/target/arm/cpregs.h
28
+++ b/tests/qtest/npcm7xx_rng-test.c
28
+++ b/target/arm/cpregs.h
29
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
29
@@ -XXX,XX +XXX,XX @@ typedef enum FGTBit {
30
30
DO_BIT(HDFGRTR, OSLSR_EL1),
31
qtest_add_func("npcm7xx_rng/enable_disable", test_enable_disable);
31
DO_BIT(HDFGRTR, OSECCR_EL1),
32
qtest_add_func("npcm7xx_rng/rosel", test_rosel);
32
DO_BIT(HDFGRTR, OSDLR_EL1),
33
- qtest_add_func("npcm7xx_rng/continuous/monobit", test_continuous_monobit);
33
+ DO_BIT(HDFGRTR, PMEVCNTRN_EL0),
34
- qtest_add_func("npcm7xx_rng/continuous/runs", test_continuous_runs);
34
+ DO_BIT(HDFGRTR, PMEVTYPERN_EL0),
35
- qtest_add_func("npcm7xx_rng/first_byte/monobit", test_first_byte_monobit);
35
+ DO_BIT(HDFGRTR, PMCCFILTR_EL0),
36
- qtest_add_func("npcm7xx_rng/first_byte/runs", test_first_byte_runs);
36
+ DO_BIT(HDFGRTR, PMCCNTR_EL0),
37
+ /*
37
+ DO_BIT(HDFGRTR, PMCNTEN),
38
+ * These tests fail intermittently; only run them on explicit
38
+ DO_BIT(HDFGRTR, PMINTEN),
39
+ * request until we figure out why.
39
+ DO_BIT(HDFGRTR, PMOVS),
40
+ */
40
+ DO_BIT(HDFGRTR, PMSELR_EL0),
41
+ if (getenv("QEMU_TEST_FLAKY_RNG_TESTS")) {
41
+ DO_BIT(HDFGWTR, PMSWINC_EL0),
42
+ qtest_add_func("npcm7xx_rng/continuous/monobit", test_continuous_monobit);
42
+ DO_BIT(HDFGWTR, PMCR_EL0),
43
+ qtest_add_func("npcm7xx_rng/continuous/runs", test_continuous_runs);
43
+ DO_BIT(HDFGRTR, PMMIR_EL1),
44
+ qtest_add_func("npcm7xx_rng/first_byte/monobit", test_first_byte_monobit);
44
+ DO_BIT(HDFGRTR, PMCEIDN_EL0),
45
+ qtest_add_func("npcm7xx_rng/first_byte/runs", test_first_byte_runs);
45
} FGTBit;
46
+ }
46
47
47
#undef DO_BIT
48
qtest_start("-machine npcm750-evb");
48
diff --git a/target/arm/helper.c b/target/arm/helper.c
49
ret = g_test_run();
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/helper.c
51
+++ b/target/arm/helper.c
52
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
53
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcnten),
54
.writefn = pmcntenset_write,
55
.accessfn = pmreg_access,
56
+ .fgt = FGT_PMCNTEN,
57
.raw_writefn = raw_write },
58
{ .name = "PMCNTENSET_EL0", .state = ARM_CP_STATE_AA64, .type = ARM_CP_IO,
59
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 1,
60
.access = PL0_RW, .accessfn = pmreg_access,
61
+ .fgt = FGT_PMCNTEN,
62
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten), .resetvalue = 0,
63
.writefn = pmcntenset_write, .raw_writefn = raw_write },
64
{ .name = "PMCNTENCLR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 2,
65
.access = PL0_RW,
66
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcnten),
67
.accessfn = pmreg_access,
68
+ .fgt = FGT_PMCNTEN,
69
.writefn = pmcntenclr_write,
70
.type = ARM_CP_ALIAS | ARM_CP_IO },
71
{ .name = "PMCNTENCLR_EL0", .state = ARM_CP_STATE_AA64,
72
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 2,
73
.access = PL0_RW, .accessfn = pmreg_access,
74
+ .fgt = FGT_PMCNTEN,
75
.type = ARM_CP_ALIAS | ARM_CP_IO,
76
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
77
.writefn = pmcntenclr_write },
78
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
79
.access = PL0_RW, .type = ARM_CP_IO,
80
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr),
81
.accessfn = pmreg_access,
82
+ .fgt = FGT_PMOVS,
83
.writefn = pmovsr_write,
84
.raw_writefn = raw_write },
85
{ .name = "PMOVSCLR_EL0", .state = ARM_CP_STATE_AA64,
86
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 3,
87
.access = PL0_RW, .accessfn = pmreg_access,
88
+ .fgt = FGT_PMOVS,
89
.type = ARM_CP_ALIAS | ARM_CP_IO,
90
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
91
.writefn = pmovsr_write,
92
.raw_writefn = raw_write },
93
{ .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4,
94
.access = PL0_W, .accessfn = pmreg_access_swinc,
95
+ .fgt = FGT_PMSWINC_EL0,
96
.type = ARM_CP_NO_RAW | ARM_CP_IO,
97
.writefn = pmswinc_write },
98
{ .name = "PMSWINC_EL0", .state = ARM_CP_STATE_AA64,
99
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 4,
100
.access = PL0_W, .accessfn = pmreg_access_swinc,
101
+ .fgt = FGT_PMSWINC_EL0,
102
.type = ARM_CP_NO_RAW | ARM_CP_IO,
103
.writefn = pmswinc_write },
104
{ .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5,
105
.access = PL0_RW, .type = ARM_CP_ALIAS,
106
+ .fgt = FGT_PMSELR_EL0,
107
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmselr),
108
.accessfn = pmreg_access_selr, .writefn = pmselr_write,
109
.raw_writefn = raw_write},
110
{ .name = "PMSELR_EL0", .state = ARM_CP_STATE_AA64,
111
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 5,
112
.access = PL0_RW, .accessfn = pmreg_access_selr,
113
+ .fgt = FGT_PMSELR_EL0,
114
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmselr),
115
.writefn = pmselr_write, .raw_writefn = raw_write, },
116
{ .name = "PMCCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 0,
117
.access = PL0_RW, .resetvalue = 0, .type = ARM_CP_ALIAS | ARM_CP_IO,
118
+ .fgt = FGT_PMCCNTR_EL0,
119
.readfn = pmccntr_read, .writefn = pmccntr_write32,
120
.accessfn = pmreg_access_ccntr },
121
{ .name = "PMCCNTR_EL0", .state = ARM_CP_STATE_AA64,
122
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 0,
123
.access = PL0_RW, .accessfn = pmreg_access_ccntr,
124
+ .fgt = FGT_PMCCNTR_EL0,
125
.type = ARM_CP_IO,
126
.fieldoffset = offsetof(CPUARMState, cp15.c15_ccnt),
127
.readfn = pmccntr_read, .writefn = pmccntr_write,
128
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
129
{ .name = "PMCCFILTR", .cp = 15, .opc1 = 0, .crn = 14, .crm = 15, .opc2 = 7,
130
.writefn = pmccfiltr_write_a32, .readfn = pmccfiltr_read_a32,
131
.access = PL0_RW, .accessfn = pmreg_access,
132
+ .fgt = FGT_PMCCFILTR_EL0,
133
.type = ARM_CP_ALIAS | ARM_CP_IO,
134
.resetvalue = 0, },
135
{ .name = "PMCCFILTR_EL0", .state = ARM_CP_STATE_AA64,
136
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 15, .opc2 = 7,
137
.writefn = pmccfiltr_write, .raw_writefn = raw_write,
138
.access = PL0_RW, .accessfn = pmreg_access,
139
+ .fgt = FGT_PMCCFILTR_EL0,
140
.type = ARM_CP_IO,
141
.fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0),
142
.resetvalue = 0, },
143
{ .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1,
144
.access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
145
.accessfn = pmreg_access,
146
+ .fgt = FGT_PMEVTYPERN_EL0,
147
.writefn = pmxevtyper_write, .readfn = pmxevtyper_read },
148
{ .name = "PMXEVTYPER_EL0", .state = ARM_CP_STATE_AA64,
149
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 1,
150
.access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
151
.accessfn = pmreg_access,
152
+ .fgt = FGT_PMEVTYPERN_EL0,
153
.writefn = pmxevtyper_write, .readfn = pmxevtyper_read },
154
{ .name = "PMXEVCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 2,
155
.access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
156
.accessfn = pmreg_access_xevcntr,
157
+ .fgt = FGT_PMEVCNTRN_EL0,
158
.writefn = pmxevcntr_write, .readfn = pmxevcntr_read },
159
{ .name = "PMXEVCNTR_EL0", .state = ARM_CP_STATE_AA64,
160
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 2,
161
.access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
162
.accessfn = pmreg_access_xevcntr,
163
+ .fgt = FGT_PMEVCNTRN_EL0,
164
.writefn = pmxevcntr_write, .readfn = pmxevcntr_read },
165
{ .name = "PMUSERENR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 0,
166
.access = PL0_R | PL1_RW, .accessfn = access_tpm,
167
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
168
.writefn = pmuserenr_write, .raw_writefn = raw_write },
169
{ .name = "PMINTENSET", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 1,
170
.access = PL1_RW, .accessfn = access_tpm,
171
+ .fgt = FGT_PMINTEN,
172
.type = ARM_CP_ALIAS | ARM_CP_IO,
173
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pminten),
174
.resetvalue = 0,
175
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
176
{ .name = "PMINTENSET_EL1", .state = ARM_CP_STATE_AA64,
177
.opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 1,
178
.access = PL1_RW, .accessfn = access_tpm,
179
+ .fgt = FGT_PMINTEN,
180
.type = ARM_CP_IO,
181
.fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
182
.writefn = pmintenset_write, .raw_writefn = raw_write,
183
.resetvalue = 0x0 },
184
{ .name = "PMINTENCLR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 2,
185
.access = PL1_RW, .accessfn = access_tpm,
186
+ .fgt = FGT_PMINTEN,
187
.type = ARM_CP_ALIAS | ARM_CP_IO | ARM_CP_NO_RAW,
188
.fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
189
.writefn = pmintenclr_write, },
190
{ .name = "PMINTENCLR_EL1", .state = ARM_CP_STATE_AA64,
191
.opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 2,
192
.access = PL1_RW, .accessfn = access_tpm,
193
+ .fgt = FGT_PMINTEN,
194
.type = ARM_CP_ALIAS | ARM_CP_IO | ARM_CP_NO_RAW,
195
.fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
196
.writefn = pmintenclr_write },
197
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmovsset_cp_reginfo[] = {
198
/* PMOVSSET is not implemented in v7 before v7ve */
199
{ .name = "PMOVSSET", .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 3,
200
.access = PL0_RW, .accessfn = pmreg_access,
201
+ .fgt = FGT_PMOVS,
202
.type = ARM_CP_ALIAS | ARM_CP_IO,
203
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr),
204
.writefn = pmovsset_write,
205
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmovsset_cp_reginfo[] = {
206
{ .name = "PMOVSSET_EL0", .state = ARM_CP_STATE_AA64,
207
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 14, .opc2 = 3,
208
.access = PL0_RW, .accessfn = pmreg_access,
209
+ .fgt = FGT_PMOVS,
210
.type = ARM_CP_ALIAS | ARM_CP_IO,
211
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
212
.writefn = pmovsset_write,
213
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
214
ARMCPRegInfo pmcr = {
215
.name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
216
.access = PL0_RW,
217
+ .fgt = FGT_PMCR_EL0,
218
.type = ARM_CP_IO | ARM_CP_ALIAS,
219
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),
220
.accessfn = pmreg_access, .writefn = pmcr_write,
221
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
222
.name = "PMCR_EL0", .state = ARM_CP_STATE_AA64,
223
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 0,
224
.access = PL0_RW, .accessfn = pmreg_access,
225
+ .fgt = FGT_PMCR_EL0,
226
.type = ARM_CP_IO,
227
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
228
.resetvalue = cpu->isar.reset_pmcr_el0,
229
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
230
{ .name = pmevcntr_name, .cp = 15, .crn = 14,
231
.crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
232
.access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
233
+ .fgt = FGT_PMEVCNTRN_EL0,
234
.readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
235
.accessfn = pmreg_access_xevcntr },
236
{ .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
237
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 8 | (3 & (i >> 3)),
238
.opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access_xevcntr,
239
.type = ARM_CP_IO,
240
+ .fgt = FGT_PMEVCNTRN_EL0,
241
.readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
242
.raw_readfn = pmevcntr_rawread,
243
.raw_writefn = pmevcntr_rawwrite },
244
{ .name = pmevtyper_name, .cp = 15, .crn = 14,
245
.crm = 12 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
246
.access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
247
+ .fgt = FGT_PMEVTYPERN_EL0,
248
.readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
249
.accessfn = pmreg_access },
250
{ .name = pmevtyper_el0_name, .state = ARM_CP_STATE_AA64,
251
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 12 | (3 & (i >> 3)),
252
.opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
253
+ .fgt = FGT_PMEVTYPERN_EL0,
254
.type = ARM_CP_IO,
255
.readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
256
.raw_writefn = pmevtyper_rawwrite },
257
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
258
{ .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
259
.cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
260
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
261
+ .fgt = FGT_PMCEIDN_EL0,
262
.resetvalue = extract64(cpu->pmceid0, 32, 32) },
263
{ .name = "PMCEID3", .state = ARM_CP_STATE_AA32,
264
.cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5,
265
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
266
+ .fgt = FGT_PMCEIDN_EL0,
267
.resetvalue = extract64(cpu->pmceid1, 32, 32) },
268
};
269
define_arm_cp_regs(cpu, v81_pmu_regs);
270
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
271
.name = "PMMIR_EL1", .state = ARM_CP_STATE_BOTH,
272
.opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 6,
273
.access = PL1_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
274
+ .fgt = FGT_PMMIR_EL1,
275
.resetvalue = 0
276
};
277
define_one_arm_cp_reg(cpu, &v84_pmmir);
278
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
279
{ .name = "PMCEID0", .state = ARM_CP_STATE_AA32,
280
.cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 6,
281
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
282
+ .fgt = FGT_PMCEIDN_EL0,
283
.resetvalue = extract64(cpu->pmceid0, 0, 32) },
284
{ .name = "PMCEID0_EL0", .state = ARM_CP_STATE_AA64,
285
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 6,
286
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
287
+ .fgt = FGT_PMCEIDN_EL0,
288
.resetvalue = cpu->pmceid0 },
289
{ .name = "PMCEID1", .state = ARM_CP_STATE_AA32,
290
.cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 7,
291
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
292
+ .fgt = FGT_PMCEIDN_EL0,
293
.resetvalue = extract64(cpu->pmceid1, 0, 32) },
294
{ .name = "PMCEID1_EL0", .state = ARM_CP_STATE_AA64,
295
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 7,
296
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
297
+ .fgt = FGT_PMCEIDN_EL0,
298
.resetvalue = cpu->pmceid1 },
299
};
300
#ifdef CONFIG_USER_ONLY
50
--
301
--
51
2.20.1
302
2.34.1
52
53
diff view generated by jsdifflib
1
Sphinx 3.2 is pickier than earlier versions about the option:: markup,
1
Mark up the sysreg definitions for the system instructions
2
and complains about our usage in qemu-option-trace.rst:
2
trapped by HFGITR bits 0..11. These bits cover various
3
3
cache maintenance operations.
4
../../docs/qemu-option-trace.rst.inc:4:Malformed option description
5
'[enable=]PATTERN', should look like "opt", "-opt args", "--opt args",
6
"/opt args" or "+opt args"
7
8
In this file, we're really trying to document the different parts of
9
the top-level --trace option, which qemu-nbd.rst and qemu-img.rst
10
have already introduced with an option:: markup. So it's not right
11
to use option:: here anyway. Switch to a different markup
12
(definition lists) which gives about the same formatted output.
13
14
(Unlike option::, this markup doesn't produce index entries; but
15
at the moment we don't do anything much with indexes anyway, and
16
in any case I think it doesn't make much sense to have individual
17
index entries for the sub-parts of the --trace option.)
18
4
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Tested-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Tested-by: Fuad Tabba <tabba@google.com>
22
Message-id: 20201030174700.7204-3-peter.maydell@linaro.org
8
Message-id: 20230130182459.3309057-17-peter.maydell@linaro.org
9
Message-id: 20230127175507.2895013-17-peter.maydell@linaro.org
23
---
10
---
24
docs/qemu-option-trace.rst.inc | 6 +++---
11
target/arm/cpregs.h | 14 ++++++++++++++
25
1 file changed, 3 insertions(+), 3 deletions(-)
12
target/arm/helper.c | 28 ++++++++++++++++++++++++++++
13
2 files changed, 42 insertions(+)
26
14
27
diff --git a/docs/qemu-option-trace.rst.inc b/docs/qemu-option-trace.rst.inc
15
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
28
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
29
--- a/docs/qemu-option-trace.rst.inc
17
--- a/target/arm/cpregs.h
30
+++ b/docs/qemu-option-trace.rst.inc
18
+++ b/target/arm/cpregs.h
31
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ typedef enum FGTBit {
32
20
DO_BIT(HDFGWTR, PMCR_EL0),
33
Specify tracing options.
21
DO_BIT(HDFGRTR, PMMIR_EL1),
34
22
DO_BIT(HDFGRTR, PMCEIDN_EL0),
35
-.. option:: [enable=]PATTERN
23
+
36
+``[enable=]PATTERN``
24
+ /* Trap bits in HFGITR_EL2, starting from bit 0 */
37
25
+ DO_BIT(HFGITR, ICIALLUIS),
38
Immediately enable events matching *PATTERN*
26
+ DO_BIT(HFGITR, ICIALLU),
39
(either event name or a globbing pattern). This option is only
27
+ DO_BIT(HFGITR, ICIVAU),
40
@@ -XXX,XX +XXX,XX @@ Specify tracing options.
28
+ DO_BIT(HFGITR, DCIVAC),
41
29
+ DO_BIT(HFGITR, DCISW),
42
Use :option:`-trace help` to print a list of names of trace points.
30
+ DO_BIT(HFGITR, DCCSW),
43
31
+ DO_BIT(HFGITR, DCCISW),
44
-.. option:: events=FILE
32
+ DO_BIT(HFGITR, DCCVAU),
45
+``events=FILE``
33
+ DO_BIT(HFGITR, DCCVAP),
46
34
+ DO_BIT(HFGITR, DCCVADP),
47
Immediately enable events listed in *FILE*.
35
+ DO_BIT(HFGITR, DCCIVAC),
48
The file must contain one event name (as listed in the ``trace-events-all``
36
+ DO_BIT(HFGITR, DCZVA),
49
@@ -XXX,XX +XXX,XX @@ Specify tracing options.
37
} FGTBit;
50
available if QEMU has been compiled with the ``simple``, ``log`` or
38
51
``ftrace`` tracing backend.
39
#undef DO_BIT
52
40
diff --git a/target/arm/helper.c b/target/arm/helper.c
53
-.. option:: file=FILE
41
index XXXXXXX..XXXXXXX 100644
54
+``file=FILE``
42
--- a/target/arm/helper.c
55
43
+++ b/target/arm/helper.c
56
Log output traces to *FILE*.
44
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
57
This option is only available if QEMU has been compiled with
45
#ifndef CONFIG_USER_ONLY
46
/* Avoid overhead of an access check that always passes in user-mode */
47
.accessfn = aa64_zva_access,
48
+ .fgt = FGT_DCZVA,
49
#endif
50
},
51
{ .name = "CURRENTEL", .state = ARM_CP_STATE_AA64,
52
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
53
{ .name = "IC_IALLUIS", .state = ARM_CP_STATE_AA64,
54
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
55
.access = PL1_W, .type = ARM_CP_NOP,
56
+ .fgt = FGT_ICIALLUIS,
57
.accessfn = access_ticab },
58
{ .name = "IC_IALLU", .state = ARM_CP_STATE_AA64,
59
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 0,
60
.access = PL1_W, .type = ARM_CP_NOP,
61
+ .fgt = FGT_ICIALLU,
62
.accessfn = access_tocu },
63
{ .name = "IC_IVAU", .state = ARM_CP_STATE_AA64,
64
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 5, .opc2 = 1,
65
.access = PL0_W, .type = ARM_CP_NOP,
66
+ .fgt = FGT_ICIVAU,
67
.accessfn = access_tocu },
68
{ .name = "DC_IVAC", .state = ARM_CP_STATE_AA64,
69
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1,
70
.access = PL1_W, .accessfn = aa64_cacheop_poc_access,
71
+ .fgt = FGT_DCIVAC,
72
.type = ARM_CP_NOP },
73
{ .name = "DC_ISW", .state = ARM_CP_STATE_AA64,
74
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2,
75
+ .fgt = FGT_DCISW,
76
.access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
77
{ .name = "DC_CVAC", .state = ARM_CP_STATE_AA64,
78
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 1,
79
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
80
.accessfn = aa64_cacheop_poc_access },
81
{ .name = "DC_CSW", .state = ARM_CP_STATE_AA64,
82
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2,
83
+ .fgt = FGT_DCCSW,
84
.access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
85
{ .name = "DC_CVAU", .state = ARM_CP_STATE_AA64,
86
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 11, .opc2 = 1,
87
.access = PL0_W, .type = ARM_CP_NOP,
88
+ .fgt = FGT_DCCVAU,
89
.accessfn = access_tocu },
90
{ .name = "DC_CIVAC", .state = ARM_CP_STATE_AA64,
91
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 1,
92
.access = PL0_W, .type = ARM_CP_NOP,
93
+ .fgt = FGT_DCCIVAC,
94
.accessfn = aa64_cacheop_poc_access },
95
{ .name = "DC_CISW", .state = ARM_CP_STATE_AA64,
96
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
97
+ .fgt = FGT_DCCISW,
98
.access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
99
/* TLBI operations */
100
{ .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64,
101
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo dcpop_reg[] = {
102
{ .name = "DC_CVAP", .state = ARM_CP_STATE_AA64,
103
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 1,
104
.access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
105
+ .fgt = FGT_DCCVAP,
106
.accessfn = aa64_cacheop_poc_access, .writefn = dccvap_writefn },
107
};
108
109
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo dcpodp_reg[] = {
110
{ .name = "DC_CVADP", .state = ARM_CP_STATE_AA64,
111
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 1,
112
.access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
113
+ .fgt = FGT_DCCVADP,
114
.accessfn = aa64_cacheop_poc_access, .writefn = dccvap_writefn },
115
};
116
#endif /*CONFIG_USER_ONLY*/
117
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_reginfo[] = {
118
{ .name = "DC_IGVAC", .state = ARM_CP_STATE_AA64,
119
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 3,
120
.type = ARM_CP_NOP, .access = PL1_W,
121
+ .fgt = FGT_DCIVAC,
122
.accessfn = aa64_cacheop_poc_access },
123
{ .name = "DC_IGSW", .state = ARM_CP_STATE_AA64,
124
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 4,
125
+ .fgt = FGT_DCISW,
126
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
127
{ .name = "DC_IGDVAC", .state = ARM_CP_STATE_AA64,
128
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 5,
129
.type = ARM_CP_NOP, .access = PL1_W,
130
+ .fgt = FGT_DCIVAC,
131
.accessfn = aa64_cacheop_poc_access },
132
{ .name = "DC_IGDSW", .state = ARM_CP_STATE_AA64,
133
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 6,
134
+ .fgt = FGT_DCISW,
135
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
136
{ .name = "DC_CGSW", .state = ARM_CP_STATE_AA64,
137
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 4,
138
+ .fgt = FGT_DCCSW,
139
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
140
{ .name = "DC_CGDSW", .state = ARM_CP_STATE_AA64,
141
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 6,
142
+ .fgt = FGT_DCCSW,
143
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
144
{ .name = "DC_CIGSW", .state = ARM_CP_STATE_AA64,
145
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 4,
146
+ .fgt = FGT_DCCISW,
147
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
148
{ .name = "DC_CIGDSW", .state = ARM_CP_STATE_AA64,
149
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 6,
150
+ .fgt = FGT_DCCISW,
151
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
152
};
153
154
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_el0_cacheop_reginfo[] = {
155
{ .name = "DC_CGVAP", .state = ARM_CP_STATE_AA64,
156
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 3,
157
.type = ARM_CP_NOP, .access = PL0_W,
158
+ .fgt = FGT_DCCVAP,
159
.accessfn = aa64_cacheop_poc_access },
160
{ .name = "DC_CGDVAP", .state = ARM_CP_STATE_AA64,
161
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 5,
162
.type = ARM_CP_NOP, .access = PL0_W,
163
+ .fgt = FGT_DCCVAP,
164
.accessfn = aa64_cacheop_poc_access },
165
{ .name = "DC_CGVADP", .state = ARM_CP_STATE_AA64,
166
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 3,
167
.type = ARM_CP_NOP, .access = PL0_W,
168
+ .fgt = FGT_DCCVADP,
169
.accessfn = aa64_cacheop_poc_access },
170
{ .name = "DC_CGDVADP", .state = ARM_CP_STATE_AA64,
171
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 5,
172
.type = ARM_CP_NOP, .access = PL0_W,
173
+ .fgt = FGT_DCCVADP,
174
.accessfn = aa64_cacheop_poc_access },
175
{ .name = "DC_CIGVAC", .state = ARM_CP_STATE_AA64,
176
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 3,
177
.type = ARM_CP_NOP, .access = PL0_W,
178
+ .fgt = FGT_DCCIVAC,
179
.accessfn = aa64_cacheop_poc_access },
180
{ .name = "DC_CIGDVAC", .state = ARM_CP_STATE_AA64,
181
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 5,
182
.type = ARM_CP_NOP, .access = PL0_W,
183
+ .fgt = FGT_DCCIVAC,
184
.accessfn = aa64_cacheop_poc_access },
185
{ .name = "DC_GVA", .state = ARM_CP_STATE_AA64,
186
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 4, .opc2 = 3,
187
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_el0_cacheop_reginfo[] = {
188
#ifndef CONFIG_USER_ONLY
189
/* Avoid overhead of an access check that always passes in user-mode */
190
.accessfn = aa64_zva_access,
191
+ .fgt = FGT_DCZVA,
192
#endif
193
},
194
{ .name = "DC_GZVA", .state = ARM_CP_STATE_AA64,
195
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_el0_cacheop_reginfo[] = {
196
#ifndef CONFIG_USER_ONLY
197
/* Avoid overhead of an access check that always passes in user-mode */
198
.accessfn = aa64_zva_access,
199
+ .fgt = FGT_DCZVA,
200
#endif
201
},
202
};
58
--
203
--
59
2.20.1
204
2.34.1
60
61
diff view generated by jsdifflib
New patch
1
Mark up the sysreg definitions for the system instructions
2
trapped by HFGITR bits 12..17. These bits cover AT address
3
translation instructions.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Fuad Tabba <tabba@google.com>
8
Message-id: 20230130182459.3309057-18-peter.maydell@linaro.org
9
Message-id: 20230127175507.2895013-18-peter.maydell@linaro.org
10
---
11
target/arm/cpregs.h | 6 ++++++
12
target/arm/helper.c | 6 ++++++
13
2 files changed, 12 insertions(+)
14
15
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpregs.h
18
+++ b/target/arm/cpregs.h
19
@@ -XXX,XX +XXX,XX @@ typedef enum FGTBit {
20
DO_BIT(HFGITR, DCCVADP),
21
DO_BIT(HFGITR, DCCIVAC),
22
DO_BIT(HFGITR, DCZVA),
23
+ DO_BIT(HFGITR, ATS1E1R),
24
+ DO_BIT(HFGITR, ATS1E1W),
25
+ DO_BIT(HFGITR, ATS1E0R),
26
+ DO_BIT(HFGITR, ATS1E0W),
27
+ DO_BIT(HFGITR, ATS1E1RP),
28
+ DO_BIT(HFGITR, ATS1E1WP),
29
} FGTBit;
30
31
#undef DO_BIT
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/helper.c
35
+++ b/target/arm/helper.c
36
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
37
{ .name = "AT_S1E1R", .state = ARM_CP_STATE_AA64,
38
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 0,
39
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
40
+ .fgt = FGT_ATS1E1R,
41
.writefn = ats_write64 },
42
{ .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64,
43
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 1,
44
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
45
+ .fgt = FGT_ATS1E1W,
46
.writefn = ats_write64 },
47
{ .name = "AT_S1E0R", .state = ARM_CP_STATE_AA64,
48
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 2,
49
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
50
+ .fgt = FGT_ATS1E0R,
51
.writefn = ats_write64 },
52
{ .name = "AT_S1E0W", .state = ARM_CP_STATE_AA64,
53
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 3,
54
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
55
+ .fgt = FGT_ATS1E0W,
56
.writefn = ats_write64 },
57
{ .name = "AT_S12E1R", .state = ARM_CP_STATE_AA64,
58
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 4,
59
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo ats1e1_reginfo[] = {
60
{ .name = "AT_S1E1RP", .state = ARM_CP_STATE_AA64,
61
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 0,
62
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
63
+ .fgt = FGT_ATS1E1RP,
64
.writefn = ats_write64 },
65
{ .name = "AT_S1E1WP", .state = ARM_CP_STATE_AA64,
66
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1,
67
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
68
+ .fgt = FGT_ATS1E1WP,
69
.writefn = ats_write64 },
70
};
71
72
--
73
2.34.1
diff view generated by jsdifflib
1
On some hosts (eg Ubuntu Bionic) pkg-config returns a set of
1
Mark up the sysreg definitions for the system instructions
2
libraries for gio-2.0 which don't actually work when compiling
2
trapped by HFGITR bits 18..47. These bits cover TLBI
3
statically. (Specifically, the returned library string includes
3
TLB maintenance instructions.
4
-lmount, but not -lblkid which -lmount depends upon, so linking
5
fails due to missing symbols.)
6
4
7
Check that the libraries work, and don't enable gio if they don't,
5
(If we implemented FEAT_XS we would need to trap some of the
8
in the same way we do for gnutls.
6
instructions added by that feature using these bits; but we don't
7
yet, so will need to add the .fgt markup when we do.)
9
8
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Tested-by: Fuad Tabba <tabba@google.com>
13
Message-id: 20200928160402.7961-1-peter.maydell@linaro.org
12
Message-id: 20230130182459.3309057-19-peter.maydell@linaro.org
13
Message-id: 20230127175507.2895013-19-peter.maydell@linaro.org
14
---
14
---
15
configure | 10 +++++++++-
15
target/arm/cpregs.h | 30 ++++++++++++++++++++++++++++++
16
1 file changed, 9 insertions(+), 1 deletion(-)
16
target/arm/helper.c | 30 ++++++++++++++++++++++++++++++
17
2 files changed, 60 insertions(+)
17
18
18
diff --git a/configure b/configure
19
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
19
index XXXXXXX..XXXXXXX 100755
20
index XXXXXXX..XXXXXXX 100644
20
--- a/configure
21
--- a/target/arm/cpregs.h
21
+++ b/configure
22
+++ b/target/arm/cpregs.h
22
@@ -XXX,XX +XXX,XX @@ if test "$static" = yes && test "$mingw32" = yes; then
23
@@ -XXX,XX +XXX,XX @@ typedef enum FGTBit {
23
fi
24
DO_BIT(HFGITR, ATS1E0W),
24
25
DO_BIT(HFGITR, ATS1E1RP),
25
if $pkg_config --atleast-version=$glib_req_ver gio-2.0; then
26
DO_BIT(HFGITR, ATS1E1WP),
26
- gio=yes
27
+ DO_BIT(HFGITR, TLBIVMALLE1OS),
27
gio_cflags=$($pkg_config --cflags gio-2.0)
28
+ DO_BIT(HFGITR, TLBIVAE1OS),
28
gio_libs=$($pkg_config --libs gio-2.0)
29
+ DO_BIT(HFGITR, TLBIASIDE1OS),
29
gdbus_codegen=$($pkg_config --variable=gdbus_codegen gio-2.0)
30
+ DO_BIT(HFGITR, TLBIVAAE1OS),
30
if [ ! -x "$gdbus_codegen" ]; then
31
+ DO_BIT(HFGITR, TLBIVALE1OS),
31
gdbus_codegen=
32
+ DO_BIT(HFGITR, TLBIVAALE1OS),
32
fi
33
+ DO_BIT(HFGITR, TLBIRVAE1OS),
33
+ # Check that the libraries actually work -- Ubuntu 18.04 ships
34
+ DO_BIT(HFGITR, TLBIRVAAE1OS),
34
+ # with pkg-config --static --libs data for gio-2.0 that is missing
35
+ DO_BIT(HFGITR, TLBIRVALE1OS),
35
+ # -lblkid and will give a link error.
36
+ DO_BIT(HFGITR, TLBIRVAALE1OS),
36
+ write_c_skeleton
37
+ DO_BIT(HFGITR, TLBIVMALLE1IS),
37
+ if compile_prog "" "gio_libs" ; then
38
+ DO_BIT(HFGITR, TLBIVAE1IS),
38
+ gio=yes
39
+ DO_BIT(HFGITR, TLBIASIDE1IS),
39
+ else
40
+ DO_BIT(HFGITR, TLBIVAAE1IS),
40
+ gio=no
41
+ DO_BIT(HFGITR, TLBIVALE1IS),
41
+ fi
42
+ DO_BIT(HFGITR, TLBIVAALE1IS),
42
else
43
+ DO_BIT(HFGITR, TLBIRVAE1IS),
43
gio=no
44
+ DO_BIT(HFGITR, TLBIRVAAE1IS),
44
fi
45
+ DO_BIT(HFGITR, TLBIRVALE1IS),
46
+ DO_BIT(HFGITR, TLBIRVAALE1IS),
47
+ DO_BIT(HFGITR, TLBIRVAE1),
48
+ DO_BIT(HFGITR, TLBIRVAAE1),
49
+ DO_BIT(HFGITR, TLBIRVALE1),
50
+ DO_BIT(HFGITR, TLBIRVAALE1),
51
+ DO_BIT(HFGITR, TLBIVMALLE1),
52
+ DO_BIT(HFGITR, TLBIVAE1),
53
+ DO_BIT(HFGITR, TLBIASIDE1),
54
+ DO_BIT(HFGITR, TLBIVAAE1),
55
+ DO_BIT(HFGITR, TLBIVALE1),
56
+ DO_BIT(HFGITR, TLBIVAALE1),
57
} FGTBit;
58
59
#undef DO_BIT
60
diff --git a/target/arm/helper.c b/target/arm/helper.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/helper.c
63
+++ b/target/arm/helper.c
64
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
65
{ .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64,
66
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0,
67
.access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
68
+ .fgt = FGT_TLBIVMALLE1IS,
69
.writefn = tlbi_aa64_vmalle1is_write },
70
{ .name = "TLBI_VAE1IS", .state = ARM_CP_STATE_AA64,
71
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1,
72
.access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
73
+ .fgt = FGT_TLBIVAE1IS,
74
.writefn = tlbi_aa64_vae1is_write },
75
{ .name = "TLBI_ASIDE1IS", .state = ARM_CP_STATE_AA64,
76
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2,
77
.access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
78
+ .fgt = FGT_TLBIASIDE1IS,
79
.writefn = tlbi_aa64_vmalle1is_write },
80
{ .name = "TLBI_VAAE1IS", .state = ARM_CP_STATE_AA64,
81
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3,
82
.access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
83
+ .fgt = FGT_TLBIVAAE1IS,
84
.writefn = tlbi_aa64_vae1is_write },
85
{ .name = "TLBI_VALE1IS", .state = ARM_CP_STATE_AA64,
86
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5,
87
.access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
88
+ .fgt = FGT_TLBIVALE1IS,
89
.writefn = tlbi_aa64_vae1is_write },
90
{ .name = "TLBI_VAALE1IS", .state = ARM_CP_STATE_AA64,
91
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7,
92
.access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
93
+ .fgt = FGT_TLBIVAALE1IS,
94
.writefn = tlbi_aa64_vae1is_write },
95
{ .name = "TLBI_VMALLE1", .state = ARM_CP_STATE_AA64,
96
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0,
97
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
98
+ .fgt = FGT_TLBIVMALLE1,
99
.writefn = tlbi_aa64_vmalle1_write },
100
{ .name = "TLBI_VAE1", .state = ARM_CP_STATE_AA64,
101
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1,
102
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
103
+ .fgt = FGT_TLBIVAE1,
104
.writefn = tlbi_aa64_vae1_write },
105
{ .name = "TLBI_ASIDE1", .state = ARM_CP_STATE_AA64,
106
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2,
107
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
108
+ .fgt = FGT_TLBIASIDE1,
109
.writefn = tlbi_aa64_vmalle1_write },
110
{ .name = "TLBI_VAAE1", .state = ARM_CP_STATE_AA64,
111
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3,
112
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
113
+ .fgt = FGT_TLBIVAAE1,
114
.writefn = tlbi_aa64_vae1_write },
115
{ .name = "TLBI_VALE1", .state = ARM_CP_STATE_AA64,
116
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5,
117
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
118
+ .fgt = FGT_TLBIVALE1,
119
.writefn = tlbi_aa64_vae1_write },
120
{ .name = "TLBI_VAALE1", .state = ARM_CP_STATE_AA64,
121
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7,
122
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
123
+ .fgt = FGT_TLBIVAALE1,
124
.writefn = tlbi_aa64_vae1_write },
125
{ .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64,
126
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
127
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbirange_reginfo[] = {
128
{ .name = "TLBI_RVAE1IS", .state = ARM_CP_STATE_AA64,
129
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 1,
130
.access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
131
+ .fgt = FGT_TLBIRVAE1IS,
132
.writefn = tlbi_aa64_rvae1is_write },
133
{ .name = "TLBI_RVAAE1IS", .state = ARM_CP_STATE_AA64,
134
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 3,
135
.access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
136
+ .fgt = FGT_TLBIRVAAE1IS,
137
.writefn = tlbi_aa64_rvae1is_write },
138
{ .name = "TLBI_RVALE1IS", .state = ARM_CP_STATE_AA64,
139
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 5,
140
.access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
141
+ .fgt = FGT_TLBIRVALE1IS,
142
.writefn = tlbi_aa64_rvae1is_write },
143
{ .name = "TLBI_RVAALE1IS", .state = ARM_CP_STATE_AA64,
144
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 7,
145
.access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
146
+ .fgt = FGT_TLBIRVAALE1IS,
147
.writefn = tlbi_aa64_rvae1is_write },
148
{ .name = "TLBI_RVAE1OS", .state = ARM_CP_STATE_AA64,
149
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 1,
150
.access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
151
+ .fgt = FGT_TLBIRVAE1OS,
152
.writefn = tlbi_aa64_rvae1is_write },
153
{ .name = "TLBI_RVAAE1OS", .state = ARM_CP_STATE_AA64,
154
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 3,
155
.access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
156
+ .fgt = FGT_TLBIRVAAE1OS,
157
.writefn = tlbi_aa64_rvae1is_write },
158
{ .name = "TLBI_RVALE1OS", .state = ARM_CP_STATE_AA64,
159
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 5,
160
.access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
161
+ .fgt = FGT_TLBIRVALE1OS,
162
.writefn = tlbi_aa64_rvae1is_write },
163
{ .name = "TLBI_RVAALE1OS", .state = ARM_CP_STATE_AA64,
164
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 7,
165
.access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
166
+ .fgt = FGT_TLBIRVAALE1OS,
167
.writefn = tlbi_aa64_rvae1is_write },
168
{ .name = "TLBI_RVAE1", .state = ARM_CP_STATE_AA64,
169
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 1,
170
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
171
+ .fgt = FGT_TLBIRVAE1,
172
.writefn = tlbi_aa64_rvae1_write },
173
{ .name = "TLBI_RVAAE1", .state = ARM_CP_STATE_AA64,
174
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 3,
175
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
176
+ .fgt = FGT_TLBIRVAAE1,
177
.writefn = tlbi_aa64_rvae1_write },
178
{ .name = "TLBI_RVALE1", .state = ARM_CP_STATE_AA64,
179
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 5,
180
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
181
+ .fgt = FGT_TLBIRVALE1,
182
.writefn = tlbi_aa64_rvae1_write },
183
{ .name = "TLBI_RVAALE1", .state = ARM_CP_STATE_AA64,
184
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 7,
185
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
186
+ .fgt = FGT_TLBIRVAALE1,
187
.writefn = tlbi_aa64_rvae1_write },
188
{ .name = "TLBI_RIPAS2E1IS", .state = ARM_CP_STATE_AA64,
189
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 2,
190
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbios_reginfo[] = {
191
{ .name = "TLBI_VMALLE1OS", .state = ARM_CP_STATE_AA64,
192
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 0,
193
.access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
194
+ .fgt = FGT_TLBIVMALLE1OS,
195
.writefn = tlbi_aa64_vmalle1is_write },
196
{ .name = "TLBI_VAE1OS", .state = ARM_CP_STATE_AA64,
197
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 1,
198
+ .fgt = FGT_TLBIVAE1OS,
199
.access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
200
.writefn = tlbi_aa64_vae1is_write },
201
{ .name = "TLBI_ASIDE1OS", .state = ARM_CP_STATE_AA64,
202
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 2,
203
.access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
204
+ .fgt = FGT_TLBIASIDE1OS,
205
.writefn = tlbi_aa64_vmalle1is_write },
206
{ .name = "TLBI_VAAE1OS", .state = ARM_CP_STATE_AA64,
207
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 3,
208
.access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
209
+ .fgt = FGT_TLBIVAAE1OS,
210
.writefn = tlbi_aa64_vae1is_write },
211
{ .name = "TLBI_VALE1OS", .state = ARM_CP_STATE_AA64,
212
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 5,
213
.access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
214
+ .fgt = FGT_TLBIVALE1OS,
215
.writefn = tlbi_aa64_vae1is_write },
216
{ .name = "TLBI_VAALE1OS", .state = ARM_CP_STATE_AA64,
217
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 7,
218
.access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
219
+ .fgt = FGT_TLBIVAALE1OS,
220
.writefn = tlbi_aa64_vae1is_write },
221
{ .name = "TLBI_ALLE2OS", .state = ARM_CP_STATE_AA64,
222
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 0,
45
--
223
--
46
2.20.1
224
2.34.1
47
48
diff view generated by jsdifflib
New patch
1
Mark up the sysreg definitions for the system instructions
2
trapped by HFGITR bits 48..63.
1
3
4
Some of these bits are for trapping instructions which are
5
not in the system instruction encoding (i.e. which are
6
not handled by the ARMCPRegInfo mechanism):
7
* ERET, ERETAA, ERETAB
8
* SVC
9
10
We will have to handle those separately and manually.
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Tested-by: Fuad Tabba <tabba@google.com>
15
Message-id: 20230130182459.3309057-20-peter.maydell@linaro.org
16
Message-id: 20230127175507.2895013-20-peter.maydell@linaro.org
17
---
18
target/arm/cpregs.h | 4 ++++
19
target/arm/helper.c | 9 +++++++++
20
2 files changed, 13 insertions(+)
21
22
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpregs.h
25
+++ b/target/arm/cpregs.h
26
@@ -XXX,XX +XXX,XX @@ typedef enum FGTBit {
27
DO_BIT(HFGITR, TLBIVAAE1),
28
DO_BIT(HFGITR, TLBIVALE1),
29
DO_BIT(HFGITR, TLBIVAALE1),
30
+ DO_BIT(HFGITR, CFPRCTX),
31
+ DO_BIT(HFGITR, DVPRCTX),
32
+ DO_BIT(HFGITR, CPPRCTX),
33
+ DO_BIT(HFGITR, DCCVAC),
34
} FGTBit;
35
36
#undef DO_BIT
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/helper.c
40
+++ b/target/arm/helper.c
41
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
42
{ .name = "DC_CVAC", .state = ARM_CP_STATE_AA64,
43
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 1,
44
.access = PL0_W, .type = ARM_CP_NOP,
45
+ .fgt = FGT_DCCVAC,
46
.accessfn = aa64_cacheop_poc_access },
47
{ .name = "DC_CSW", .state = ARM_CP_STATE_AA64,
48
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2,
49
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_el0_cacheop_reginfo[] = {
50
{ .name = "DC_CGVAC", .state = ARM_CP_STATE_AA64,
51
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 3,
52
.type = ARM_CP_NOP, .access = PL0_W,
53
+ .fgt = FGT_DCCVAC,
54
.accessfn = aa64_cacheop_poc_access },
55
{ .name = "DC_CGDVAC", .state = ARM_CP_STATE_AA64,
56
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 5,
57
.type = ARM_CP_NOP, .access = PL0_W,
58
+ .fgt = FGT_DCCVAC,
59
.accessfn = aa64_cacheop_poc_access },
60
{ .name = "DC_CGVAP", .state = ARM_CP_STATE_AA64,
61
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 3,
62
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
63
static const ARMCPRegInfo predinv_reginfo[] = {
64
{ .name = "CFP_RCTX", .state = ARM_CP_STATE_AA64,
65
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 4,
66
+ .fgt = FGT_CFPRCTX,
67
.type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
68
{ .name = "DVP_RCTX", .state = ARM_CP_STATE_AA64,
69
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 5,
70
+ .fgt = FGT_DVPRCTX,
71
.type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
72
{ .name = "CPP_RCTX", .state = ARM_CP_STATE_AA64,
73
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 7,
74
+ .fgt = FGT_CPPRCTX,
75
.type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
76
/*
77
* Note the AArch32 opcodes have a different OPC1.
78
*/
79
{ .name = "CFPRCTX", .state = ARM_CP_STATE_AA32,
80
.cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 4,
81
+ .fgt = FGT_CFPRCTX,
82
.type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
83
{ .name = "DVPRCTX", .state = ARM_CP_STATE_AA32,
84
.cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 5,
85
+ .fgt = FGT_DVPRCTX,
86
.type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
87
{ .name = "CPPRCTX", .state = ARM_CP_STATE_AA32,
88
.cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 7,
89
+ .fgt = FGT_CPPRCTX,
90
.type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
91
};
92
93
--
94
2.34.1
diff view generated by jsdifflib
1
The kerneldoc script currently emits Sphinx markup for a macro with
1
Implement the HFGITR_EL2.ERET fine-grained trap. This traps
2
arguments that uses the c:function directive. This is correct for
2
execution from AArch64 EL1 of ERET, ERETAA and ERETAB. The trap is
3
Sphinx versions earlier than Sphinx 3, where c:macro doesn't allow
3
reported with a syndrome value of 0x1a.
4
documentation of macros with arguments and c:function is not picky
5
about the syntax of what it is passed. However, in Sphinx 3 the
6
c:macro directive was enhanced to support macros with arguments,
7
and c:function was made more picky about what syntax it accepted.
8
4
9
When kerneldoc is told that it needs to produce output for Sphinx
5
The trap must take precedence over a possible pointer-authentication
10
3 or later, make it emit c:function only for functions and c:macro
6
trap for ERETAA and ERETAB.
11
for macros with arguments. We assume that anything with a return
12
type is a function and anything without is a macro.
13
14
This fixes the Sphinx error:
15
16
/home/petmay01/linaro/qemu-from-laptop/qemu/docs/../include/qom/object.h:155:Error in declarator
17
If declarator-id with parameters (e.g., 'void f(int arg)'):
18
Invalid C declaration: Expected identifier in nested name. [error at 25]
19
DECLARE_INSTANCE_CHECKER ( InstanceType, OBJ_NAME, TYPENAME)
20
-------------------------^
21
If parenthesis in noptr-declarator (e.g., 'void (*f(int arg))(double)'):
22
Error in declarator or parameters
23
Invalid C declaration: Expecting "(" in parameters. [error at 39]
24
DECLARE_INSTANCE_CHECKER ( InstanceType, OBJ_NAME, TYPENAME)
25
---------------------------------------^
26
7
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Tested-by: Stefan Hajnoczi <stefanha@redhat.com>
10
Tested-by: Fuad Tabba <tabba@google.com>
30
Message-id: 20201030174700.7204-2-peter.maydell@linaro.org
11
Message-id: 20230130182459.3309057-21-peter.maydell@linaro.org
12
Message-id: 20230127175507.2895013-21-peter.maydell@linaro.org
31
---
13
---
32
scripts/kernel-doc | 18 +++++++++++++++++-
14
target/arm/cpu.h | 1 +
33
1 file changed, 17 insertions(+), 1 deletion(-)
15
target/arm/syndrome.h | 10 ++++++++++
16
target/arm/translate.h | 2 ++
17
target/arm/helper.c | 3 +++
18
target/arm/translate-a64.c | 10 ++++++++++
19
5 files changed, 26 insertions(+)
34
20
35
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
36
index XXXXXXX..XXXXXXX 100755
22
index XXXXXXX..XXXXXXX 100644
37
--- a/scripts/kernel-doc
23
--- a/target/arm/cpu.h
38
+++ b/scripts/kernel-doc
24
+++ b/target/arm/cpu.h
39
@@ -XXX,XX +XXX,XX @@ sub output_function_rst(%) {
25
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, PSTATE_ZA, 23, 1)
40
    output_highlight_rst($args{'purpose'});
26
FIELD(TBFLAG_A64, SVL, 24, 4)
41
    $start = "\n\n**Syntax**\n\n ``";
27
/* Indicates that SME Streaming mode is active, and SMCR_ELx.FA64 is not. */
42
} else {
28
FIELD(TBFLAG_A64, SME_TRAP_NONSTREAMING, 28, 1)
43
-    print ".. c:function:: ";
29
+FIELD(TBFLAG_A64, FGT_ERET, 29, 1)
44
+ if ((split(/\./, $sphinx_version))[0] >= 3) {
30
45
+ # Sphinx 3 and later distinguish macros and functions and
31
/*
46
+ # complain if you use c:function with something that's not
32
* Helpers for using the above.
47
+ # syntactically valid as a function declaration.
33
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
48
+ # We assume that anything with a return type is a function
34
index XXXXXXX..XXXXXXX 100644
49
+ # and anything without is a macro.
35
--- a/target/arm/syndrome.h
50
+ if ($args{'functiontype'} ne "") {
36
+++ b/target/arm/syndrome.h
51
+ print ".. c:function:: ";
37
@@ -XXX,XX +XXX,XX @@ enum arm_exception_class {
52
+ } else {
38
EC_AA64_SMC = 0x17,
53
+ print ".. c:macro:: ";
39
EC_SYSTEMREGISTERTRAP = 0x18,
54
+ }
40
EC_SVEACCESSTRAP = 0x19,
55
+ } else {
41
+ EC_ERETTRAP = 0x1a,
56
+ # Older Sphinx don't support documenting macros that take
42
EC_SMETRAP = 0x1d,
57
+ # arguments with c:macro, and don't complain about the use
43
EC_INSNABORT = 0x20,
58
+ # of c:function for this.
44
EC_INSNABORT_SAME_EL = 0x21,
59
+ print ".. c:function:: ";
45
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_sve_access_trap(void)
46
return EC_SVEACCESSTRAP << ARM_EL_EC_SHIFT;
47
}
48
49
+/*
50
+ * eret_op is bits [1:0] of the ERET instruction, so:
51
+ * 0 for ERET, 2 for ERETAA, 3 for ERETAB.
52
+ */
53
+static inline uint32_t syn_erettrap(int eret_op)
54
+{
55
+ return (EC_ERETTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL | eret_op;
56
+}
57
+
58
static inline uint32_t syn_smetrap(SMEExceptionType etype, bool is_16bit)
59
{
60
return (EC_SMETRAP << ARM_EL_EC_SHIFT)
61
diff --git a/target/arm/translate.h b/target/arm/translate.h
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/translate.h
64
+++ b/target/arm/translate.h
65
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
66
bool mve_no_pred;
67
/* True if fine-grained traps are active */
68
bool fgt_active;
69
+ /* True if fine-grained trap on ERET is enabled */
70
+ bool fgt_eret;
71
/*
72
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
73
* < 0, set by the current instruction.
74
diff --git a/target/arm/helper.c b/target/arm/helper.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/arm/helper.c
77
+++ b/target/arm/helper.c
78
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
79
80
if (arm_fgt_active(env, el)) {
81
DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1);
82
+ if (FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, ERET)) {
83
+ DP_TBFLAG_A64(flags, FGT_ERET, 1);
60
+ }
84
+ }
61
}
85
}
62
if ($args{'functiontype'} ne "") {
86
63
    $start .= $args{'functiontype'} . " " . $args{'function'} . " (";
87
if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
88
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/translate-a64.c
91
+++ b/target/arm/translate-a64.c
92
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
93
if (op4 != 0) {
94
goto do_unallocated;
95
}
96
+ if (s->fgt_eret) {
97
+ gen_exception_insn_el(s, 0, EXCP_UDEF, syn_erettrap(op3), 2);
98
+ return;
99
+ }
100
dst = tcg_temp_new_i64();
101
tcg_gen_ld_i64(dst, cpu_env,
102
offsetof(CPUARMState, elr_el[s->current_el]));
103
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
104
if (rn != 0x1f || op4 != 0x1f) {
105
goto do_unallocated;
106
}
107
+ /* The FGT trap takes precedence over an auth trap. */
108
+ if (s->fgt_eret) {
109
+ gen_exception_insn_el(s, 0, EXCP_UDEF, syn_erettrap(op3), 2);
110
+ return;
111
+ }
112
dst = tcg_temp_new_i64();
113
tcg_gen_ld_i64(dst, cpu_env,
114
offsetof(CPUARMState, elr_el[s->current_el]));
115
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
116
dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
117
dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
118
dc->fgt_active = EX_TBFLAG_ANY(tb_flags, FGT_ACTIVE);
119
+ dc->fgt_eret = EX_TBFLAG_A64(tb_flags, FGT_ERET);
120
dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
121
dc->sme_excp_el = EX_TBFLAG_A64(tb_flags, SMEEXC_EL);
122
dc->vl = (EX_TBFLAG_A64(tb_flags, VL) + 1) * 16;
64
--
123
--
65
2.20.1
124
2.34.1
66
67
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the HFGITR_EL2.SVC_EL0 and SVC_EL1 fine-grained traps.
2
These trap execution of the SVC instruction from AArch32 and AArch64.
3
(As usual, AArch32 can only trap from EL0, as fine grained traps are
4
disabled with an AArch32 EL1.)
2
5
3
The only uses of this function are for loading VFP
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
single-precision values, and nothing to do with NEON.
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Fuad Tabba <tabba@google.com>
9
Message-id: 20230130182459.3309057-22-peter.maydell@linaro.org
10
Message-id: 20230127175507.2895013-22-peter.maydell@linaro.org
11
---
12
target/arm/cpu.h | 1 +
13
target/arm/translate.h | 2 ++
14
target/arm/helper.c | 20 ++++++++++++++++++++
15
target/arm/translate-a64.c | 9 ++++++++-
16
target/arm/translate.c | 12 +++++++++---
17
5 files changed, 40 insertions(+), 4 deletions(-)
5
18
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
7
Message-id: 20201030022618.785675-8-richard.henderson@linaro.org
20
index XXXXXXX..XXXXXXX 100644
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
21
--- a/target/arm/cpu.h
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
+++ b/target/arm/cpu.h
10
---
23
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, FPEXC_EL, 8, 2)
11
target/arm/translate.c | 4 +-
24
FIELD(TBFLAG_ANY, ALIGN_MEM, 10, 1)
12
target/arm/translate-vfp.c.inc | 184 ++++++++++++++++-----------------
25
FIELD(TBFLAG_ANY, PSTATE__IL, 11, 1)
13
2 files changed, 94 insertions(+), 94 deletions(-)
26
FIELD(TBFLAG_ANY, FGT_ACTIVE, 12, 1)
14
27
+FIELD(TBFLAG_ANY, FGT_SVC, 13, 1)
28
29
/*
30
* Bit usage when in AArch32 state, both A- and M-profile.
31
diff --git a/target/arm/translate.h b/target/arm/translate.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/translate.h
34
+++ b/target/arm/translate.h
35
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
36
bool fgt_active;
37
/* True if fine-grained trap on ERET is enabled */
38
bool fgt_eret;
39
+ /* True if fine-grained trap on SVC is enabled */
40
+ bool fgt_svc;
41
/*
42
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
43
* < 0, set by the current instruction.
44
diff --git a/target/arm/helper.c b/target/arm/helper.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/helper.c
47
+++ b/target/arm/helper.c
48
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_mmu_idx(CPUARMState *env)
49
return arm_mmu_idx_el(env, arm_current_el(env));
50
}
51
52
+static inline bool fgt_svc(CPUARMState *env, int el)
53
+{
54
+ /*
55
+ * Assuming fine-grained-traps are active, return true if we
56
+ * should be trapping on SVC instructions. Only AArch64 can
57
+ * trap on an SVC at EL1, but we don't need to special-case this
58
+ * because if this is AArch32 EL1 then arm_fgt_active() is false.
59
+ * We also know el is 0 or 1.
60
+ */
61
+ return el == 0 ?
62
+ FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, SVC_EL0) :
63
+ FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, SVC_EL1);
64
+}
65
+
66
static CPUARMTBFlags rebuild_hflags_common(CPUARMState *env, int fp_el,
67
ARMMMUIdx mmu_idx,
68
CPUARMTBFlags flags)
69
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el,
70
71
if (arm_fgt_active(env, el)) {
72
DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1);
73
+ if (fgt_svc(env, el)) {
74
+ DP_TBFLAG_ANY(flags, FGT_SVC, 1);
75
+ }
76
}
77
78
if (env->uncached_cpsr & CPSR_IL) {
79
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
80
if (FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, ERET)) {
81
DP_TBFLAG_A64(flags, FGT_ERET, 1);
82
}
83
+ if (fgt_svc(env, el)) {
84
+ DP_TBFLAG_ANY(flags, FGT_SVC, 1);
85
+ }
86
}
87
88
if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
89
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/target/arm/translate-a64.c
92
+++ b/target/arm/translate-a64.c
93
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
94
int opc = extract32(insn, 21, 3);
95
int op2_ll = extract32(insn, 0, 5);
96
int imm16 = extract32(insn, 5, 16);
97
+ uint32_t syndrome;
98
99
switch (opc) {
100
case 0:
101
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
102
*/
103
switch (op2_ll) {
104
case 1: /* SVC */
105
+ syndrome = syn_aa64_svc(imm16);
106
+ if (s->fgt_svc) {
107
+ gen_exception_insn_el(s, 0, EXCP_UDEF, syndrome, 2);
108
+ break;
109
+ }
110
gen_ss_advance(s);
111
- gen_exception_insn(s, 4, EXCP_SWI, syn_aa64_svc(imm16));
112
+ gen_exception_insn(s, 4, EXCP_SWI, syndrome);
113
break;
114
case 2: /* HVC */
115
if (s->current_el == 0) {
116
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
117
dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
118
dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
119
dc->fgt_active = EX_TBFLAG_ANY(tb_flags, FGT_ACTIVE);
120
+ dc->fgt_svc = EX_TBFLAG_ANY(tb_flags, FGT_SVC);
121
dc->fgt_eret = EX_TBFLAG_A64(tb_flags, FGT_ERET);
122
dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
123
dc->sme_excp_el = EX_TBFLAG_A64(tb_flags, SMEEXC_EL);
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
124
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
index XXXXXXX..XXXXXXX 100644
125
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.c
126
--- a/target/arm/translate.c
18
+++ b/target/arm/translate.c
127
+++ b/target/arm/translate.c
19
@@ -XXX,XX +XXX,XX @@ static inline void neon_store_reg64(TCGv_i64 var, int reg)
128
@@ -XXX,XX +XXX,XX @@ static bool trans_SVC(DisasContext *s, arg_SVC *a)
20
tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
129
(a->imm == semihost_imm)) {
21
}
130
gen_exception_internal_insn(s, EXCP_SEMIHOST);
22
131
} else {
23
-static inline void neon_load_reg32(TCGv_i32 var, int reg)
132
- gen_update_pc(s, curr_insn_len(s));
24
+static inline void vfp_load_reg32(TCGv_i32 var, int reg)
133
- s->svc_imm = a->imm;
25
{
134
- s->base.is_jmp = DISAS_SWI;
26
tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
135
+ if (s->fgt_svc) {
27
}
136
+ uint32_t syndrome = syn_aa32_svc(a->imm, s->thumb);
28
137
+ gen_exception_insn_el(s, 0, EXCP_UDEF, syndrome, 2);
29
-static inline void neon_store_reg32(TCGv_i32 var, int reg)
138
+ } else {
30
+static inline void vfp_store_reg32(TCGv_i32 var, int reg)
139
+ gen_update_pc(s, curr_insn_len(s));
31
{
140
+ s->svc_imm = a->imm;
32
tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
141
+ s->base.is_jmp = DISAS_SWI;
33
}
142
+ }
34
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-vfp.c.inc
37
+++ b/target/arm/translate-vfp.c.inc
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
39
frn = tcg_temp_new_i32();
40
frm = tcg_temp_new_i32();
41
dest = tcg_temp_new_i32();
42
- neon_load_reg32(frn, rn);
43
- neon_load_reg32(frm, rm);
44
+ vfp_load_reg32(frn, rn);
45
+ vfp_load_reg32(frm, rm);
46
switch (a->cc) {
47
case 0: /* eq: Z */
48
tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
49
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
50
if (sz == 1) {
51
tcg_gen_andi_i32(dest, dest, 0xffff);
52
}
53
- neon_store_reg32(dest, rd);
54
+ vfp_store_reg32(dest, rd);
55
tcg_temp_free_i32(frn);
56
tcg_temp_free_i32(frm);
57
tcg_temp_free_i32(dest);
58
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
59
TCGv_i32 tcg_res;
60
tcg_op = tcg_temp_new_i32();
61
tcg_res = tcg_temp_new_i32();
62
- neon_load_reg32(tcg_op, rm);
63
+ vfp_load_reg32(tcg_op, rm);
64
if (sz == 1) {
65
gen_helper_rinth(tcg_res, tcg_op, fpst);
66
} else {
67
gen_helper_rints(tcg_res, tcg_op, fpst);
68
}
69
- neon_store_reg32(tcg_res, rd);
70
+ vfp_store_reg32(tcg_res, rd);
71
tcg_temp_free_i32(tcg_op);
72
tcg_temp_free_i32(tcg_res);
73
}
143
}
74
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
75
gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
76
}
77
tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
78
- neon_store_reg32(tcg_tmp, rd);
79
+ vfp_store_reg32(tcg_tmp, rd);
80
tcg_temp_free_i32(tcg_tmp);
81
tcg_temp_free_i64(tcg_res);
82
tcg_temp_free_i64(tcg_double);
83
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
84
TCGv_i32 tcg_single, tcg_res;
85
tcg_single = tcg_temp_new_i32();
86
tcg_res = tcg_temp_new_i32();
87
- neon_load_reg32(tcg_single, rm);
88
+ vfp_load_reg32(tcg_single, rm);
89
if (sz == 1) {
90
if (is_signed) {
91
gen_helper_vfp_toslh(tcg_res, tcg_single, tcg_shift, fpst);
92
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
93
gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
94
}
95
}
96
- neon_store_reg32(tcg_res, rd);
97
+ vfp_store_reg32(tcg_res, rd);
98
tcg_temp_free_i32(tcg_res);
99
tcg_temp_free_i32(tcg_single);
100
}
101
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_half(DisasContext *s, arg_VMOV_single *a)
102
if (a->l) {
103
/* VFP to general purpose register */
104
tmp = tcg_temp_new_i32();
105
- neon_load_reg32(tmp, a->vn);
106
+ vfp_load_reg32(tmp, a->vn);
107
tcg_gen_andi_i32(tmp, tmp, 0xffff);
108
store_reg(s, a->rt, tmp);
109
} else {
110
/* general purpose register to VFP */
111
tmp = load_reg(s, a->rt);
112
tcg_gen_andi_i32(tmp, tmp, 0xffff);
113
- neon_store_reg32(tmp, a->vn);
114
+ vfp_store_reg32(tmp, a->vn);
115
tcg_temp_free_i32(tmp);
116
}
117
118
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_single(DisasContext *s, arg_VMOV_single *a)
119
if (a->l) {
120
/* VFP to general purpose register */
121
tmp = tcg_temp_new_i32();
122
- neon_load_reg32(tmp, a->vn);
123
+ vfp_load_reg32(tmp, a->vn);
124
if (a->rt == 15) {
125
/* Set the 4 flag bits in the CPSR. */
126
gen_set_nzcv(tmp);
127
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_single(DisasContext *s, arg_VMOV_single *a)
128
} else {
129
/* general purpose register to VFP */
130
tmp = load_reg(s, a->rt);
131
- neon_store_reg32(tmp, a->vn);
132
+ vfp_store_reg32(tmp, a->vn);
133
tcg_temp_free_i32(tmp);
134
}
135
136
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_sp(DisasContext *s, arg_VMOV_64_sp *a)
137
if (a->op) {
138
/* fpreg to gpreg */
139
tmp = tcg_temp_new_i32();
140
- neon_load_reg32(tmp, a->vm);
141
+ vfp_load_reg32(tmp, a->vm);
142
store_reg(s, a->rt, tmp);
143
tmp = tcg_temp_new_i32();
144
- neon_load_reg32(tmp, a->vm + 1);
145
+ vfp_load_reg32(tmp, a->vm + 1);
146
store_reg(s, a->rt2, tmp);
147
} else {
148
/* gpreg to fpreg */
149
tmp = load_reg(s, a->rt);
150
- neon_store_reg32(tmp, a->vm);
151
+ vfp_store_reg32(tmp, a->vm);
152
tcg_temp_free_i32(tmp);
153
tmp = load_reg(s, a->rt2);
154
- neon_store_reg32(tmp, a->vm + 1);
155
+ vfp_store_reg32(tmp, a->vm + 1);
156
tcg_temp_free_i32(tmp);
157
}
158
159
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a)
160
if (a->op) {
161
/* fpreg to gpreg */
162
tmp = tcg_temp_new_i32();
163
- neon_load_reg32(tmp, a->vm * 2);
164
+ vfp_load_reg32(tmp, a->vm * 2);
165
store_reg(s, a->rt, tmp);
166
tmp = tcg_temp_new_i32();
167
- neon_load_reg32(tmp, a->vm * 2 + 1);
168
+ vfp_load_reg32(tmp, a->vm * 2 + 1);
169
store_reg(s, a->rt2, tmp);
170
} else {
171
/* gpreg to fpreg */
172
tmp = load_reg(s, a->rt);
173
- neon_store_reg32(tmp, a->vm * 2);
174
+ vfp_store_reg32(tmp, a->vm * 2);
175
tcg_temp_free_i32(tmp);
176
tmp = load_reg(s, a->rt2);
177
- neon_store_reg32(tmp, a->vm * 2 + 1);
178
+ vfp_store_reg32(tmp, a->vm * 2 + 1);
179
tcg_temp_free_i32(tmp);
180
}
181
182
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_hp(DisasContext *s, arg_VLDR_VSTR_sp *a)
183
tmp = tcg_temp_new_i32();
184
if (a->l) {
185
gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
186
- neon_store_reg32(tmp, a->vd);
187
+ vfp_store_reg32(tmp, a->vd);
188
} else {
189
- neon_load_reg32(tmp, a->vd);
190
+ vfp_load_reg32(tmp, a->vd);
191
gen_aa32_st16(s, tmp, addr, get_mem_index(s));
192
}
193
tcg_temp_free_i32(tmp);
194
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
195
tmp = tcg_temp_new_i32();
196
if (a->l) {
197
gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
198
- neon_store_reg32(tmp, a->vd);
199
+ vfp_store_reg32(tmp, a->vd);
200
} else {
201
- neon_load_reg32(tmp, a->vd);
202
+ vfp_load_reg32(tmp, a->vd);
203
gen_aa32_st32(s, tmp, addr, get_mem_index(s));
204
}
205
tcg_temp_free_i32(tmp);
206
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_sp(DisasContext *s, arg_VLDM_VSTM_sp *a)
207
if (a->l) {
208
/* load */
209
gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
210
- neon_store_reg32(tmp, a->vd + i);
211
+ vfp_store_reg32(tmp, a->vd + i);
212
} else {
213
/* store */
214
- neon_load_reg32(tmp, a->vd + i);
215
+ vfp_load_reg32(tmp, a->vd + i);
216
gen_aa32_st32(s, tmp, addr, get_mem_index(s));
217
}
218
tcg_gen_addi_i32(addr, addr, offset);
219
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_sp(DisasContext *s, VFPGen3OpSPFn *fn,
220
fd = tcg_temp_new_i32();
221
fpst = fpstatus_ptr(FPST_FPCR);
222
223
- neon_load_reg32(f0, vn);
224
- neon_load_reg32(f1, vm);
225
+ vfp_load_reg32(f0, vn);
226
+ vfp_load_reg32(f1, vm);
227
228
for (;;) {
229
if (reads_vd) {
230
- neon_load_reg32(fd, vd);
231
+ vfp_load_reg32(fd, vd);
232
}
233
fn(fd, f0, f1, fpst);
234
- neon_store_reg32(fd, vd);
235
+ vfp_store_reg32(fd, vd);
236
237
if (veclen == 0) {
238
break;
239
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_sp(DisasContext *s, VFPGen3OpSPFn *fn,
240
veclen--;
241
vd = vfp_advance_sreg(vd, delta_d);
242
vn = vfp_advance_sreg(vn, delta_d);
243
- neon_load_reg32(f0, vn);
244
+ vfp_load_reg32(f0, vn);
245
if (delta_m) {
246
vm = vfp_advance_sreg(vm, delta_m);
247
- neon_load_reg32(f1, vm);
248
+ vfp_load_reg32(f1, vm);
249
}
250
}
251
252
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_hp(DisasContext *s, VFPGen3OpSPFn *fn,
253
fd = tcg_temp_new_i32();
254
fpst = fpstatus_ptr(FPST_FPCR_F16);
255
256
- neon_load_reg32(f0, vn);
257
- neon_load_reg32(f1, vm);
258
+ vfp_load_reg32(f0, vn);
259
+ vfp_load_reg32(f1, vm);
260
261
if (reads_vd) {
262
- neon_load_reg32(fd, vd);
263
+ vfp_load_reg32(fd, vd);
264
}
265
fn(fd, f0, f1, fpst);
266
- neon_store_reg32(fd, vd);
267
+ vfp_store_reg32(fd, vd);
268
269
tcg_temp_free_i32(f0);
270
tcg_temp_free_i32(f1);
271
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
272
f0 = tcg_temp_new_i32();
273
fd = tcg_temp_new_i32();
274
275
- neon_load_reg32(f0, vm);
276
+ vfp_load_reg32(f0, vm);
277
278
for (;;) {
279
fn(fd, f0);
280
- neon_store_reg32(fd, vd);
281
+ vfp_store_reg32(fd, vd);
282
283
if (veclen == 0) {
284
break;
285
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
286
/* single source one-many */
287
while (veclen--) {
288
vd = vfp_advance_sreg(vd, delta_d);
289
- neon_store_reg32(fd, vd);
290
+ vfp_store_reg32(fd, vd);
291
}
292
break;
293
}
294
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
295
veclen--;
296
vd = vfp_advance_sreg(vd, delta_d);
297
vm = vfp_advance_sreg(vm, delta_m);
298
- neon_load_reg32(f0, vm);
299
+ vfp_load_reg32(f0, vm);
300
}
301
302
tcg_temp_free_i32(f0);
303
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_hp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
304
}
305
306
f0 = tcg_temp_new_i32();
307
- neon_load_reg32(f0, vm);
308
+ vfp_load_reg32(f0, vm);
309
fn(f0, f0);
310
- neon_store_reg32(f0, vd);
311
+ vfp_store_reg32(f0, vd);
312
tcg_temp_free_i32(f0);
313
314
return true;
315
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_hp(DisasContext *s, arg_VFMA_sp *a, bool neg_n, bool neg_d)
316
vm = tcg_temp_new_i32();
317
vd = tcg_temp_new_i32();
318
319
- neon_load_reg32(vn, a->vn);
320
- neon_load_reg32(vm, a->vm);
321
+ vfp_load_reg32(vn, a->vn);
322
+ vfp_load_reg32(vm, a->vm);
323
if (neg_n) {
324
/* VFNMS, VFMS */
325
gen_helper_vfp_negh(vn, vn);
326
}
327
- neon_load_reg32(vd, a->vd);
328
+ vfp_load_reg32(vd, a->vd);
329
if (neg_d) {
330
/* VFNMA, VFNMS */
331
gen_helper_vfp_negh(vd, vd);
332
}
333
fpst = fpstatus_ptr(FPST_FPCR_F16);
334
gen_helper_vfp_muladdh(vd, vn, vm, vd, fpst);
335
- neon_store_reg32(vd, a->vd);
336
+ vfp_store_reg32(vd, a->vd);
337
338
tcg_temp_free_ptr(fpst);
339
tcg_temp_free_i32(vn);
340
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_sp(DisasContext *s, arg_VFMA_sp *a, bool neg_n, bool neg_d)
341
vm = tcg_temp_new_i32();
342
vd = tcg_temp_new_i32();
343
344
- neon_load_reg32(vn, a->vn);
345
- neon_load_reg32(vm, a->vm);
346
+ vfp_load_reg32(vn, a->vn);
347
+ vfp_load_reg32(vm, a->vm);
348
if (neg_n) {
349
/* VFNMS, VFMS */
350
gen_helper_vfp_negs(vn, vn);
351
}
352
- neon_load_reg32(vd, a->vd);
353
+ vfp_load_reg32(vd, a->vd);
354
if (neg_d) {
355
/* VFNMA, VFNMS */
356
gen_helper_vfp_negs(vd, vd);
357
}
358
fpst = fpstatus_ptr(FPST_FPCR);
359
gen_helper_vfp_muladds(vd, vn, vm, vd, fpst);
360
- neon_store_reg32(vd, a->vd);
361
+ vfp_store_reg32(vd, a->vd);
362
363
tcg_temp_free_ptr(fpst);
364
tcg_temp_free_i32(vn);
365
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_hp(DisasContext *s, arg_VMOV_imm_sp *a)
366
}
367
368
fd = tcg_const_i32(vfp_expand_imm(MO_16, a->imm));
369
- neon_store_reg32(fd, a->vd);
370
+ vfp_store_reg32(fd, a->vd);
371
tcg_temp_free_i32(fd);
372
return true;
144
return true;
373
}
145
}
374
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
146
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
375
fd = tcg_const_i32(vfp_expand_imm(MO_32, a->imm));
147
dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
376
148
dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
377
for (;;) {
149
dc->fgt_active = EX_TBFLAG_ANY(tb_flags, FGT_ACTIVE);
378
- neon_store_reg32(fd, vd);
150
+ dc->fgt_svc = EX_TBFLAG_ANY(tb_flags, FGT_SVC);
379
+ vfp_store_reg32(fd, vd);
151
380
152
if (arm_feature(env, ARM_FEATURE_M)) {
381
if (veclen == 0) {
153
dc->vfp_enabled = 1;
382
break;
383
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_hp(DisasContext *s, arg_VCMP_sp *a)
384
vd = tcg_temp_new_i32();
385
vm = tcg_temp_new_i32();
386
387
- neon_load_reg32(vd, a->vd);
388
+ vfp_load_reg32(vd, a->vd);
389
if (a->z) {
390
tcg_gen_movi_i32(vm, 0);
391
} else {
392
- neon_load_reg32(vm, a->vm);
393
+ vfp_load_reg32(vm, a->vm);
394
}
395
396
if (a->e) {
397
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_sp(DisasContext *s, arg_VCMP_sp *a)
398
vd = tcg_temp_new_i32();
399
vm = tcg_temp_new_i32();
400
401
- neon_load_reg32(vd, a->vd);
402
+ vfp_load_reg32(vd, a->vd);
403
if (a->z) {
404
tcg_gen_movi_i32(vm, 0);
405
} else {
406
- neon_load_reg32(vm, a->vm);
407
+ vfp_load_reg32(vm, a->vm);
408
}
409
410
if (a->e) {
411
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f32_f16(DisasContext *s, arg_VCVT_f32_f16 *a)
412
/* The T bit tells us if we want the low or high 16 bits of Vm */
413
tcg_gen_ld16u_i32(tmp, cpu_env, vfp_f16_offset(a->vm, a->t));
414
gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp_mode);
415
- neon_store_reg32(tmp, a->vd);
416
+ vfp_store_reg32(tmp, a->vd);
417
tcg_temp_free_i32(ahp_mode);
418
tcg_temp_free_ptr(fpst);
419
tcg_temp_free_i32(tmp);
420
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f32(DisasContext *s, arg_VCVT_f16_f32 *a)
421
ahp_mode = get_ahp_flag();
422
tmp = tcg_temp_new_i32();
423
424
- neon_load_reg32(tmp, a->vm);
425
+ vfp_load_reg32(tmp, a->vm);
426
gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp_mode);
427
tcg_gen_st16_i32(tmp, cpu_env, vfp_f16_offset(a->vd, a->t));
428
tcg_temp_free_i32(ahp_mode);
429
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_hp(DisasContext *s, arg_VRINTR_sp *a)
430
}
431
432
tmp = tcg_temp_new_i32();
433
- neon_load_reg32(tmp, a->vm);
434
+ vfp_load_reg32(tmp, a->vm);
435
fpst = fpstatus_ptr(FPST_FPCR_F16);
436
gen_helper_rinth(tmp, tmp, fpst);
437
- neon_store_reg32(tmp, a->vd);
438
+ vfp_store_reg32(tmp, a->vd);
439
tcg_temp_free_ptr(fpst);
440
tcg_temp_free_i32(tmp);
441
return true;
442
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_sp(DisasContext *s, arg_VRINTR_sp *a)
443
}
444
445
tmp = tcg_temp_new_i32();
446
- neon_load_reg32(tmp, a->vm);
447
+ vfp_load_reg32(tmp, a->vm);
448
fpst = fpstatus_ptr(FPST_FPCR);
449
gen_helper_rints(tmp, tmp, fpst);
450
- neon_store_reg32(tmp, a->vd);
451
+ vfp_store_reg32(tmp, a->vd);
452
tcg_temp_free_ptr(fpst);
453
tcg_temp_free_i32(tmp);
454
return true;
455
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_hp(DisasContext *s, arg_VRINTZ_sp *a)
456
}
457
458
tmp = tcg_temp_new_i32();
459
- neon_load_reg32(tmp, a->vm);
460
+ vfp_load_reg32(tmp, a->vm);
461
fpst = fpstatus_ptr(FPST_FPCR_F16);
462
tcg_rmode = tcg_const_i32(float_round_to_zero);
463
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
464
gen_helper_rinth(tmp, tmp, fpst);
465
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
466
- neon_store_reg32(tmp, a->vd);
467
+ vfp_store_reg32(tmp, a->vd);
468
tcg_temp_free_ptr(fpst);
469
tcg_temp_free_i32(tcg_rmode);
470
tcg_temp_free_i32(tmp);
471
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_sp(DisasContext *s, arg_VRINTZ_sp *a)
472
}
473
474
tmp = tcg_temp_new_i32();
475
- neon_load_reg32(tmp, a->vm);
476
+ vfp_load_reg32(tmp, a->vm);
477
fpst = fpstatus_ptr(FPST_FPCR);
478
tcg_rmode = tcg_const_i32(float_round_to_zero);
479
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
480
gen_helper_rints(tmp, tmp, fpst);
481
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
482
- neon_store_reg32(tmp, a->vd);
483
+ vfp_store_reg32(tmp, a->vd);
484
tcg_temp_free_ptr(fpst);
485
tcg_temp_free_i32(tcg_rmode);
486
tcg_temp_free_i32(tmp);
487
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_hp(DisasContext *s, arg_VRINTX_sp *a)
488
}
489
490
tmp = tcg_temp_new_i32();
491
- neon_load_reg32(tmp, a->vm);
492
+ vfp_load_reg32(tmp, a->vm);
493
fpst = fpstatus_ptr(FPST_FPCR_F16);
494
gen_helper_rinth_exact(tmp, tmp, fpst);
495
- neon_store_reg32(tmp, a->vd);
496
+ vfp_store_reg32(tmp, a->vd);
497
tcg_temp_free_ptr(fpst);
498
tcg_temp_free_i32(tmp);
499
return true;
500
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_sp(DisasContext *s, arg_VRINTX_sp *a)
501
}
502
503
tmp = tcg_temp_new_i32();
504
- neon_load_reg32(tmp, a->vm);
505
+ vfp_load_reg32(tmp, a->vm);
506
fpst = fpstatus_ptr(FPST_FPCR);
507
gen_helper_rints_exact(tmp, tmp, fpst);
508
- neon_store_reg32(tmp, a->vd);
509
+ vfp_store_reg32(tmp, a->vd);
510
tcg_temp_free_ptr(fpst);
511
tcg_temp_free_i32(tmp);
512
return true;
513
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
514
515
vm = tcg_temp_new_i32();
516
vd = tcg_temp_new_i64();
517
- neon_load_reg32(vm, a->vm);
518
+ vfp_load_reg32(vm, a->vm);
519
gen_helper_vfp_fcvtds(vd, vm, cpu_env);
520
neon_store_reg64(vd, a->vd);
521
tcg_temp_free_i32(vm);
522
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
523
vm = tcg_temp_new_i64();
524
neon_load_reg64(vm, a->vm);
525
gen_helper_vfp_fcvtsd(vd, vm, cpu_env);
526
- neon_store_reg32(vd, a->vd);
527
+ vfp_store_reg32(vd, a->vd);
528
tcg_temp_free_i32(vd);
529
tcg_temp_free_i64(vm);
530
return true;
531
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_hp(DisasContext *s, arg_VCVT_int_sp *a)
532
}
533
534
vm = tcg_temp_new_i32();
535
- neon_load_reg32(vm, a->vm);
536
+ vfp_load_reg32(vm, a->vm);
537
fpst = fpstatus_ptr(FPST_FPCR_F16);
538
if (a->s) {
539
/* i32 -> f16 */
540
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_hp(DisasContext *s, arg_VCVT_int_sp *a)
541
/* u32 -> f16 */
542
gen_helper_vfp_uitoh(vm, vm, fpst);
543
}
544
- neon_store_reg32(vm, a->vd);
545
+ vfp_store_reg32(vm, a->vd);
546
tcg_temp_free_i32(vm);
547
tcg_temp_free_ptr(fpst);
548
return true;
549
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_sp(DisasContext *s, arg_VCVT_int_sp *a)
550
}
551
552
vm = tcg_temp_new_i32();
553
- neon_load_reg32(vm, a->vm);
554
+ vfp_load_reg32(vm, a->vm);
555
fpst = fpstatus_ptr(FPST_FPCR);
556
if (a->s) {
557
/* i32 -> f32 */
558
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_sp(DisasContext *s, arg_VCVT_int_sp *a)
559
/* u32 -> f32 */
560
gen_helper_vfp_uitos(vm, vm, fpst);
561
}
562
- neon_store_reg32(vm, a->vd);
563
+ vfp_store_reg32(vm, a->vd);
564
tcg_temp_free_i32(vm);
565
tcg_temp_free_ptr(fpst);
566
return true;
567
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
568
569
vm = tcg_temp_new_i32();
570
vd = tcg_temp_new_i64();
571
- neon_load_reg32(vm, a->vm);
572
+ vfp_load_reg32(vm, a->vm);
573
fpst = fpstatus_ptr(FPST_FPCR);
574
if (a->s) {
575
/* i32 -> f64 */
576
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
577
vd = tcg_temp_new_i32();
578
neon_load_reg64(vm, a->vm);
579
gen_helper_vjcvt(vd, vm, cpu_env);
580
- neon_store_reg32(vd, a->vd);
581
+ vfp_store_reg32(vd, a->vd);
582
tcg_temp_free_i64(vm);
583
tcg_temp_free_i32(vd);
584
return true;
585
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_hp(DisasContext *s, arg_VCVT_fix_sp *a)
586
frac_bits = (a->opc & 1) ? (32 - a->imm) : (16 - a->imm);
587
588
vd = tcg_temp_new_i32();
589
- neon_load_reg32(vd, a->vd);
590
+ vfp_load_reg32(vd, a->vd);
591
592
fpst = fpstatus_ptr(FPST_FPCR_F16);
593
shift = tcg_const_i32(frac_bits);
594
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_hp(DisasContext *s, arg_VCVT_fix_sp *a)
595
g_assert_not_reached();
596
}
597
598
- neon_store_reg32(vd, a->vd);
599
+ vfp_store_reg32(vd, a->vd);
600
tcg_temp_free_i32(vd);
601
tcg_temp_free_i32(shift);
602
tcg_temp_free_ptr(fpst);
603
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
604
frac_bits = (a->opc & 1) ? (32 - a->imm) : (16 - a->imm);
605
606
vd = tcg_temp_new_i32();
607
- neon_load_reg32(vd, a->vd);
608
+ vfp_load_reg32(vd, a->vd);
609
610
fpst = fpstatus_ptr(FPST_FPCR);
611
shift = tcg_const_i32(frac_bits);
612
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
613
g_assert_not_reached();
614
}
615
616
- neon_store_reg32(vd, a->vd);
617
+ vfp_store_reg32(vd, a->vd);
618
tcg_temp_free_i32(vd);
619
tcg_temp_free_i32(shift);
620
tcg_temp_free_ptr(fpst);
621
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_hp_int(DisasContext *s, arg_VCVT_sp_int *a)
622
623
fpst = fpstatus_ptr(FPST_FPCR_F16);
624
vm = tcg_temp_new_i32();
625
- neon_load_reg32(vm, a->vm);
626
+ vfp_load_reg32(vm, a->vm);
627
628
if (a->s) {
629
if (a->rz) {
630
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_hp_int(DisasContext *s, arg_VCVT_sp_int *a)
631
gen_helper_vfp_touih(vm, vm, fpst);
632
}
633
}
634
- neon_store_reg32(vm, a->vd);
635
+ vfp_store_reg32(vm, a->vd);
636
tcg_temp_free_i32(vm);
637
tcg_temp_free_ptr(fpst);
638
return true;
639
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp_int(DisasContext *s, arg_VCVT_sp_int *a)
640
641
fpst = fpstatus_ptr(FPST_FPCR);
642
vm = tcg_temp_new_i32();
643
- neon_load_reg32(vm, a->vm);
644
+ vfp_load_reg32(vm, a->vm);
645
646
if (a->s) {
647
if (a->rz) {
648
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp_int(DisasContext *s, arg_VCVT_sp_int *a)
649
gen_helper_vfp_touis(vm, vm, fpst);
650
}
651
}
652
- neon_store_reg32(vm, a->vd);
653
+ vfp_store_reg32(vm, a->vd);
654
tcg_temp_free_i32(vm);
655
tcg_temp_free_ptr(fpst);
656
return true;
657
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
658
gen_helper_vfp_touid(vd, vm, fpst);
659
}
660
}
661
- neon_store_reg32(vd, a->vd);
662
+ vfp_store_reg32(vd, a->vd);
663
tcg_temp_free_i32(vd);
664
tcg_temp_free_i64(vm);
665
tcg_temp_free_ptr(fpst);
666
@@ -XXX,XX +XXX,XX @@ static bool trans_VINS(DisasContext *s, arg_VINS *a)
667
/* Insert low half of Vm into high half of Vd */
668
rm = tcg_temp_new_i32();
669
rd = tcg_temp_new_i32();
670
- neon_load_reg32(rm, a->vm);
671
- neon_load_reg32(rd, a->vd);
672
+ vfp_load_reg32(rm, a->vm);
673
+ vfp_load_reg32(rd, a->vd);
674
tcg_gen_deposit_i32(rd, rd, rm, 16, 16);
675
- neon_store_reg32(rd, a->vd);
676
+ vfp_store_reg32(rd, a->vd);
677
tcg_temp_free_i32(rm);
678
tcg_temp_free_i32(rd);
679
return true;
680
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOVX(DisasContext *s, arg_VINS *a)
681
682
/* Set Vd to high half of Vm */
683
rm = tcg_temp_new_i32();
684
- neon_load_reg32(rm, a->vm);
685
+ vfp_load_reg32(rm, a->vm);
686
tcg_gen_shri_i32(rm, rm, 16);
687
- neon_store_reg32(rm, a->vd);
688
+ vfp_store_reg32(rm, a->vd);
689
tcg_temp_free_i32(rm);
690
return true;
691
}
692
--
154
--
693
2.20.1
155
2.34.1
694
695
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
FEAT_FGT also implements an extra trap bit in the MDCR_EL2 and
2
MDCR_EL3 registers: bit TDCC enables trapping of use of the Debug
3
Comms Channel registers OSDTRRX_EL1, OSDTRTX_EL1, MDCCSR_EL0,
4
MDCCINT_EL0, DBGDTR_EL0, DBGDTRRX_EL0 and DBGDTRTX_EL0 (and their
5
AArch32 equivalents). This trapping is independent of whether
6
fine-grained traps are enabled or not.
2
7
3
This will shortly have users outside of translate-neon.c.inc.
8
Implement these extra traps. (We don't implement DBGDTR_EL0,
9
DBGDTRRX_EL0 and DBGDTRTX_EL0.)
4
10
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20201030022618.785675-3-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Tested-by: Fuad Tabba <tabba@google.com>
14
Message-id: 20230130182459.3309057-23-peter.maydell@linaro.org
15
Message-id: 20230127175507.2895013-23-peter.maydell@linaro.org
9
---
16
---
10
target/arm/translate.c | 20 ++++++++++++++++++++
17
target/arm/debug_helper.c | 35 +++++++++++++++++++++++++++++++----
11
target/arm/translate-neon.c.inc | 19 -------------------
18
1 file changed, 31 insertions(+), 4 deletions(-)
12
2 files changed, 20 insertions(+), 19 deletions(-)
13
19
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
20
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
22
--- a/target/arm/debug_helper.c
17
+++ b/target/arm/translate.c
23
+++ b/target/arm/debug_helper.c
18
@@ -XXX,XX +XXX,XX @@ static long neon_full_reg_offset(unsigned reg)
24
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tda(CPUARMState *env, const ARMCPRegInfo *ri,
19
return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
25
return CP_ACCESS_OK;
20
}
26
}
21
27
22
+/*
28
+/*
23
+ * Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
29
+ * Check for traps to Debug Comms Channel registers. If FEAT_FGT
24
+ * where 0 is the least significant end of the register.
30
+ * is implemented then these are controlled by MDCR_EL2.TDCC for
31
+ * EL2 and MDCR_EL3.TDCC for EL3. They are also controlled by
32
+ * the general debug access trap bits MDCR_EL2.TDA and MDCR_EL3.TDA.
25
+ */
33
+ */
26
+static long neon_element_offset(int reg, int element, MemOp size)
34
+static CPAccessResult access_tdcc(CPUARMState *env, const ARMCPRegInfo *ri,
35
+ bool isread)
27
+{
36
+{
28
+ int element_size = 1 << size;
37
+ int el = arm_current_el(env);
29
+ int ofs = element * element_size;
38
+ uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
30
+#ifdef HOST_WORDS_BIGENDIAN
39
+ bool mdcr_el2_tda = (mdcr_el2 & MDCR_TDA) || (mdcr_el2 & MDCR_TDE) ||
31
+ /*
40
+ (arm_hcr_el2_eff(env) & HCR_TGE);
32
+ * Calculate the offset assuming fully little-endian,
41
+ bool mdcr_el2_tdcc = cpu_isar_feature(aa64_fgt, env_archcpu(env)) &&
33
+ * then XOR to account for the order of the 8-byte units.
42
+ (mdcr_el2 & MDCR_TDCC);
34
+ */
43
+ bool mdcr_el3_tdcc = cpu_isar_feature(aa64_fgt, env_archcpu(env)) &&
35
+ if (element_size < 8) {
44
+ (env->cp15.mdcr_el3 & MDCR_TDCC);
36
+ ofs ^= 8 - element_size;
45
+
46
+ if (el < 2 && (mdcr_el2_tda || mdcr_el2_tdcc)) {
47
+ return CP_ACCESS_TRAP_EL2;
37
+ }
48
+ }
38
+#endif
49
+ if (el < 3 && ((env->cp15.mdcr_el3 & MDCR_TDA) || mdcr_el3_tdcc)) {
39
+ return neon_full_reg_offset(reg) + ofs;
50
+ return CP_ACCESS_TRAP_EL3;
51
+ }
52
+ return CP_ACCESS_OK;
40
+}
53
+}
41
+
54
+
42
static inline long vfp_reg_offset(bool dp, unsigned reg)
55
static void oslar_write(CPUARMState *env, const ARMCPRegInfo *ri,
56
uint64_t value)
43
{
57
{
44
if (dp) {
58
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
45
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
59
*/
46
index XXXXXXX..XXXXXXX 100644
60
{ .name = "MDCCSR_EL0", .state = ARM_CP_STATE_AA64,
47
--- a/target/arm/translate-neon.c.inc
61
.opc0 = 2, .opc1 = 3, .crn = 0, .crm = 1, .opc2 = 0,
48
+++ b/target/arm/translate-neon.c.inc
62
- .access = PL0_R, .accessfn = access_tda,
49
@@ -XXX,XX +XXX,XX @@ static inline int neon_3same_fp_size(DisasContext *s, int x)
63
+ .access = PL0_R, .accessfn = access_tdcc,
50
#include "decode-neon-ls.c.inc"
64
.type = ARM_CP_CONST, .resetvalue = 0 },
51
#include "decode-neon-shared.c.inc"
65
/*
52
66
* OSDTRRX_EL1/OSDTRTX_EL1 are used for save and restore of DBGDTRRX_EL0.
53
-/* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
67
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
54
- * where 0 is the least significant end of the register.
68
*/
55
- */
69
{ .name = "OSDTRRX_EL1", .state = ARM_CP_STATE_BOTH, .cp = 14,
56
-static inline long
70
.opc0 = 2, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 2,
57
-neon_element_offset(int reg, int element, MemOp size)
71
- .access = PL1_RW, .accessfn = access_tda,
58
-{
72
+ .access = PL1_RW, .accessfn = access_tdcc,
59
- int element_size = 1 << size;
73
.type = ARM_CP_CONST, .resetvalue = 0 },
60
- int ofs = element * element_size;
74
{ .name = "OSDTRTX_EL1", .state = ARM_CP_STATE_BOTH, .cp = 14,
61
-#ifdef HOST_WORDS_BIGENDIAN
75
.opc0 = 2, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2,
62
- /* Calculate the offset assuming fully little-endian,
76
- .access = PL1_RW, .accessfn = access_tda,
63
- * then XOR to account for the order of the 8-byte units.
77
+ .access = PL1_RW, .accessfn = access_tdcc,
64
- */
78
.type = ARM_CP_CONST, .resetvalue = 0 },
65
- if (element_size < 8) {
79
/*
66
- ofs ^= 8 - element_size;
80
* OSECCR_EL1 provides a mechanism for an operating system
67
- }
81
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
68
-#endif
82
*/
69
- return neon_full_reg_offset(reg) + ofs;
83
{ .name = "MDCCINT_EL1", .state = ARM_CP_STATE_BOTH,
70
-}
84
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
71
-
85
- .access = PL1_RW, .accessfn = access_tda,
72
static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
86
+ .access = PL1_RW, .accessfn = access_tdcc,
73
{
87
.type = ARM_CP_NOP },
74
long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
88
/*
89
* Dummy DBGCLAIM registers.
75
--
90
--
76
2.20.1
91
2.34.1
77
78
diff view generated by jsdifflib
1
In arm_v7m_mmu_idx_for_secstate() we get the 'priv' level to pass to
1
Update the ID registers for TCG's '-cpu max' to report the
2
armv7m_mmu_idx_for_secstate_and_priv() by calling arm_current_el().
2
presence of FEAT_FGT Fine-Grained Traps support.
3
This is incorrect when the security state being queried is not the
4
current one, because arm_current_el() uses the current security state
5
to determine which of the banked CONTROL.nPRIV bits to look at.
6
The effect was that if (for instance) Secure state was in privileged
7
mode but Non-Secure was not then we would return the wrong MMU index.
8
9
The only places where we are using this function in a way that could
10
trigger this bug are for the stack loads during a v8M function-return
11
and for the instruction fetch of a v8M SG insn.
12
13
Fix the bug by expanding out the M-profile version of the
14
arm_current_el() logic inline so it can use the passed in secstate
15
rather than env->v7m.secure.
16
3
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20201022164408.13214-1-peter.maydell@linaro.org
6
Tested-by: Fuad Tabba <tabba@google.com>
7
Message-id: 20230130182459.3309057-24-peter.maydell@linaro.org
8
Message-id: 20230127175507.2895013-24-peter.maydell@linaro.org
20
---
9
---
21
target/arm/m_helper.c | 3 ++-
10
docs/system/arm/emulation.rst | 1 +
22
1 file changed, 2 insertions(+), 1 deletion(-)
11
target/arm/cpu64.c | 1 +
12
2 files changed, 2 insertions(+)
23
13
24
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
14
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/m_helper.c
16
--- a/docs/system/arm/emulation.rst
27
+++ b/target/arm/m_helper.c
17
+++ b/docs/system/arm/emulation.rst
28
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
18
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
29
/* Return the MMU index for a v7M CPU in the specified security state */
19
- FEAT_ETS (Enhanced Translation Synchronization)
30
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
20
- FEAT_EVT (Enhanced Virtualization Traps)
31
{
21
- FEAT_FCMA (Floating-point complex number instructions)
32
- bool priv = arm_current_el(env) != 0;
22
+- FEAT_FGT (Fine-Grained Traps)
33
+ bool priv = arm_v7m_is_handler_mode(env) ||
23
- FEAT_FHM (Floating-point half-precision multiplication instructions)
34
+ !(env->v7m.control[secstate] & 1);
24
- FEAT_FP16 (Half-precision floating-point data processing)
35
25
- FEAT_FRINTTS (Floating-point to integer instructions)
36
return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
26
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
37
}
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/cpu64.c
29
+++ b/target/arm/cpu64.c
30
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
31
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 2); /* 16k stage2 supported */
32
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN64_2, 2); /* 64k stage2 supported */
33
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 2); /* 4k stage2 supported */
34
+ t = FIELD_DP64(t, ID_AA64MMFR0, FGT, 1); /* FEAT_FGT */
35
cpu->isar.id_aa64mmfr0 = t;
36
37
t = cpu->isar.id_aa64mmfr1;
38
--
38
--
39
2.20.1
39
2.34.1
40
41
diff view generated by jsdifflib