1
Arm stuff, mostly patches from RTH.
1
target-arm queue: the big stuff here is the final part of
2
rth's patches for Cortex-A76 and Neoverse-N1 support;
3
also present are Gavin's NUMA series and a few other things.
2
4
3
thanks
5
thanks
4
-- PMM
6
-- PMM
5
7
6
The following changes since commit 01a9a51ffaf4699827ea6425cb2b834a356e159d:
8
The following changes since commit 554623226f800acf48a2ed568900c1c968ec9a8b:
7
9
8
Merge remote-tracking branch 'remotes/kraxel/tags/ui-20190205-pull-request' into staging (2019-02-05 14:01:29 +0000)
10
Merge tag 'qemu-sparc-20220508' of https://github.com/mcayland/qemu into staging (2022-05-08 17:03:26 -0500)
9
11
10
are available in the Git repository at:
12
are available in the Git repository at:
11
13
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190205
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220509
13
15
14
for you to fetch changes up to a15945d98d3a3390c3da344d1b47218e91e49d8b:
16
for you to fetch changes up to ae9141d4a3265553503bf07d3574b40f84615a34:
15
17
16
target/arm: Make FPSCR/FPCR trapped-exception bits RAZ/WI (2019-02-05 16:52:42 +0000)
18
hw/acpi/aml-build: Use existing CPU topology to build PPTT table (2022-05-09 11:47:55 +0100)
17
19
18
----------------------------------------------------------------
20
----------------------------------------------------------------
19
target-arm queue:
21
target-arm queue:
20
* Implement Armv8.5-BTI extension for system emulation mode
22
* MAINTAINERS/.mailmap: update email for Leif Lindholm
21
* Implement the PR_PAC_RESET_KEYS prctl() for linux-user mode's Armv8.3-PAuth support
23
* hw/arm: add version information to sbsa-ref machine DT
22
* Support TBI (top-byte-ignore) properly for linux-user mode
24
* Enable new features for -cpu max:
23
* gdbstub: allow killing QEMU via vKill command
25
FEAT_Debugv8p2, FEAT_Debugv8p4, FEAT_RAS (minimal version only),
24
* hw/arm/boot: Support DTB autoload for firmware-only boots
26
FEAT_IESB, FEAT_CSV2, FEAT_CSV2_2, FEAT_CSV3, FEAT_DGH
25
* target/arm: Make FPSCR/FPCR trapped-exception bits RAZ/WI
27
* Emulate Cortex-A76
28
* Emulate Neoverse-N1
29
* Fix the virt board default NUMA topology
26
30
27
----------------------------------------------------------------
31
----------------------------------------------------------------
28
Max Filippov (1):
32
Gavin Shan (6):
29
gdbstub: allow killing QEMU via vKill command
33
qapi/machine.json: Add cluster-id
34
qtest/numa-test: Specify CPU topology in aarch64_numa_cpu()
35
hw/arm/virt: Consider SMP configuration in CPU topology
36
qtest/numa-test: Correct CPU and NUMA association in aarch64_numa_cpu()
37
hw/arm/virt: Fix CPU's default NUMA node ID
38
hw/acpi/aml-build: Use existing CPU topology to build PPTT table
30
39
31
Peter Maydell (7):
40
Leif Lindholm (2):
32
target/arm: Compute TB_FLAGS for TBI for user-only
41
MAINTAINERS/.mailmap: update email for Leif Lindholm
33
hw/arm/boot: Fix block comment style in arm_load_kernel()
42
hw/arm: add versioning to sbsa-ref machine DT
34
hw/arm/boot: Factor out "direct kernel boot" code into its own function
35
hw/arm/boot: Factor out "set up firmware boot" code
36
hw/arm/boot: Clarify why arm_setup_firmware_boot() doesn't set env->boot_info
37
hw/arm/boot: Support DTB autoload for firmware-only boots
38
target/arm: Make FPSCR/FPCR trapped-exception bits RAZ/WI
39
43
40
Richard Henderson (14):
44
Richard Henderson (24):
41
target/arm: Introduce isar_feature_aa64_bti
45
target/arm: Handle cpreg registration for missing EL
42
target/arm: Add PSTATE.BTYPE
46
target/arm: Drop EL3 no EL2 fallbacks
43
target/arm: Add BT and BTYPE to tb->flags
47
target/arm: Merge zcr reginfo
44
exec: Add target-specific tlb bits to MemTxAttrs
48
target/arm: Adjust definition of CONTEXTIDR_EL2
45
target/arm: Cache the GP bit for a page in MemTxAttrs
49
target/arm: Move cortex impdef sysregs to cpu_tcg.c
46
target/arm: Default handling of BTYPE during translation
50
target/arm: Update qemu-system-arm -cpu max to cortex-a57
47
target/arm: Reset btype for direct branches
51
target/arm: Set ID_DFR0.PerfMon for qemu-system-arm -cpu max
48
target/arm: Set btype for indirect branches
52
target/arm: Split out aa32_max_features
49
target/arm: Enable BTI for -cpu max
53
target/arm: Annotate arm_max_initfn with FEAT identifiers
50
linux-user: Implement PR_PAC_RESET_KEYS
54
target/arm: Use field names for manipulating EL2 and EL3 modes
51
tests/tcg/aarch64: Add pauth smoke test
55
target/arm: Enable FEAT_Debugv8p2 for -cpu max
52
target/arm: Add TBFLAG_A64_TBID, split out gen_top_byte_ignore
56
target/arm: Enable FEAT_Debugv8p4 for -cpu max
53
target/arm: Clean TBI for data operations in the translator
57
target/arm: Add minimal RAS registers
54
target/arm: Enable TBI for user-only
58
target/arm: Enable SCR and HCR bits for RAS
59
target/arm: Implement virtual SError exceptions
60
target/arm: Implement ESB instruction
61
target/arm: Enable FEAT_RAS for -cpu max
62
target/arm: Enable FEAT_IESB for -cpu max
63
target/arm: Enable FEAT_CSV2 for -cpu max
64
target/arm: Enable FEAT_CSV2_2 for -cpu max
65
target/arm: Enable FEAT_CSV3 for -cpu max
66
target/arm: Enable FEAT_DGH for -cpu max
67
target/arm: Define cortex-a76
68
target/arm: Define neoverse-n1
55
69
56
tests/tcg/aarch64/Makefile.target | 6 +-
70
docs/system/arm/emulation.rst | 10 +
57
include/exec/memattrs.h | 10 +
71
docs/system/arm/virt.rst | 2 +
58
linux-user/aarch64/target_syscall.h | 7 +
72
qapi/machine.json | 6 +-
59
target/arm/cpu.h | 27 +-
73
target/arm/cpregs.h | 11 +
60
target/arm/internals.h | 27 +-
74
target/arm/cpu.h | 23 ++
61
target/arm/translate.h | 12 +-
75
target/arm/helper.h | 1 +
62
gdbstub.c | 4 +
76
target/arm/internals.h | 16 ++
63
hw/arm/boot.c | 166 +++++++------
77
target/arm/syndrome.h | 5 +
64
linux-user/syscall.c | 36 +++
78
target/arm/a32.decode | 16 +-
65
target/arm/cpu.c | 6 +
79
target/arm/t32.decode | 18 +-
66
target/arm/cpu64.c | 4 +
80
hw/acpi/aml-build.c | 111 ++++----
67
target/arm/helper.c | 80 +++---
81
hw/arm/sbsa-ref.c | 16 ++
68
target/arm/translate-a64.c | 476 +++++++++++++++++++++++++-----------
82
hw/arm/virt.c | 21 +-
69
tests/tcg/aarch64/pauth-1.c | 23 ++
83
hw/core/machine-hmp-cmds.c | 4 +
70
14 files changed, 623 insertions(+), 261 deletions(-)
84
hw/core/machine.c | 16 ++
71
create mode 100644 tests/tcg/aarch64/pauth-1.c
85
target/arm/cpu.c | 66 ++++-
72
86
target/arm/cpu64.c | 353 ++++++++++++++-----------
87
target/arm/cpu_tcg.c | 227 +++++++++++-----
88
target/arm/helper.c | 600 +++++++++++++++++++++++++-----------------
89
target/arm/op_helper.c | 43 +++
90
target/arm/translate-a64.c | 18 ++
91
target/arm/translate.c | 23 ++
92
tests/qtest/numa-test.c | 19 +-
93
.mailmap | 3 +-
94
MAINTAINERS | 2 +-
95
25 files changed, 1068 insertions(+), 562 deletions(-)
diff view generated by jsdifflib
1
The arm_boot_info struct has a skip_dtb_autoload flag: if this is
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
set to true by the board code then arm_load_kernel() will not
3
load the DTB itself, but will leave this for the board code to
4
do itself later. However, the check for this is done in a
5
code path which is only executed for the case where we load
6
a kernel image file. If we're taking the "boot via firmware"
7
code path then the flag isn't honoured and the DTB is never
8
loaded.
9
2
10
We didn't notice this because the only real user of "boot
3
NUVIA was acquired by Qualcomm in March 2021, but kept functioning on
11
via firmware" that cares about the DTB is the virt board
4
separate infrastructure for a transitional period. We've now switched
12
(for UEFI boot), and that always wants skip_dtb_autoload
5
over to contributing as Qualcomm Innovation Center (quicinc), so update
13
anyway. But the SBSA reference board model we're planning to
6
my email address to reflect this.
14
add will want the flag to behave correctly.
15
7
16
Now we've refactored the arm_load_kernel() function, the
8
Signed-off-by: Leif Lindholm <quic_llindhol@quicinc.com>
17
fix is simple: drop the early 'return' so we fall into
9
Message-id: 20220505113740.75565-1-quic_llindhol@quicinc.com
18
the same "load the DTB" code the boot-direct-kernel path uses.
10
Cc: Leif Lindholm <leif@nuviainc.com>
11
Cc: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
[Fixed commit message typo]
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
.mailmap | 3 ++-
17
MAINTAINERS | 2 +-
18
2 files changed, 3 insertions(+), 2 deletions(-)
19
19
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
diff --git a/.mailmap b/.mailmap
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
23
Message-id: 20190131112240.8395-6-peter.maydell@linaro.org
24
---
25
hw/arm/boot.c | 1 -
26
1 file changed, 1 deletion(-)
27
28
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
29
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/boot.c
22
--- a/.mailmap
31
+++ b/hw/arm/boot.c
23
+++ b/.mailmap
32
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
24
@@ -XXX,XX +XXX,XX @@ Greg Kurz <groug@kaod.org> <gkurz@linux.vnet.ibm.com>
33
/* Load the kernel. */
25
Huacai Chen <chenhuacai@kernel.org> <chenhc@lemote.com>
34
if (!info->kernel_filename || info->firmware_loaded) {
26
Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
35
arm_setup_firmware_boot(cpu, info);
27
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
36
- return;
28
-Leif Lindholm <leif@nuviainc.com> <leif.lindholm@linaro.org>
37
} else {
29
+Leif Lindholm <quic_llindhol@quicinc.com> <leif.lindholm@linaro.org>
38
arm_setup_direct_kernel_boot(cpu, info);
30
+Leif Lindholm <quic_llindhol@quicinc.com> <leif@nuviainc.com>
39
}
31
Radoslaw Biernacki <rad@semihalf.com> <radoslaw.biernacki@linaro.org>
32
Paul Burton <paulburton@kernel.org> <paul.burton@mips.com>
33
Paul Burton <paulburton@kernel.org> <paul.burton@imgtec.com>
34
diff --git a/MAINTAINERS b/MAINTAINERS
35
index XXXXXXX..XXXXXXX 100644
36
--- a/MAINTAINERS
37
+++ b/MAINTAINERS
38
@@ -XXX,XX +XXX,XX @@ F: include/hw/ssi/imx_spi.h
39
SBSA-REF
40
M: Radoslaw Biernacki <rad@semihalf.com>
41
M: Peter Maydell <peter.maydell@linaro.org>
42
-R: Leif Lindholm <leif@nuviainc.com>
43
+R: Leif Lindholm <quic_llindhol@quicinc.com>
44
L: qemu-arm@nongnu.org
45
S: Maintained
46
F: hw/arm/sbsa-ref.c
40
--
47
--
41
2.20.1
48
2.25.1
42
49
43
50
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This will allow TBI to be used in user-only mode, as well as
3
More gracefully handle cpregs when EL2 and/or EL3 are missing.
4
avoid ping-ponging the softmmu TLB when TBI is in use. It
4
If the reg is entirely inaccessible, do not register it at all.
5
will also enable other armv8 extensions.
5
If the reg is for EL2, and EL3 is present but EL2 is not,
6
either discard, squash to res0, const, or keep unchanged.
7
8
Per rule RJFFP, mark the 4 aarch32 hypervisor access registers
9
with ARM_CP_EL3_NO_EL2_KEEP, and mark all of the EL2 address
10
translation and tlb invalidation "regs" ARM_CP_EL3_NO_EL2_UNDEF.
11
Mark the 2 virtualization processor id regs ARM_CP_EL3_NO_EL2_C_NZ.
12
13
This will simplify cpreg registration for conditional arm features.
6
14
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190204132126.3255-3-richard.henderson@linaro.org
17
Message-id: 20220506180242.216785-2-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
19
---
12
target/arm/translate-a64.c | 217 ++++++++++++++++++++-----------------
20
target/arm/cpregs.h | 11 +++
13
1 file changed, 116 insertions(+), 101 deletions(-)
21
target/arm/helper.c | 178 ++++++++++++++++++++++++++++++--------------
14
22
2 files changed, 133 insertions(+), 56 deletions(-)
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
23
24
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
16
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
26
--- a/target/arm/cpregs.h
18
+++ b/target/arm/translate-a64.c
27
+++ b/target/arm/cpregs.h
19
@@ -XXX,XX +XXX,XX @@ static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
28
@@ -XXX,XX +XXX,XX @@ enum {
20
gen_top_byte_ignore(s, cpu_pc, src, s->tbii);
29
ARM_CP_SVE = 1 << 14,
21
}
30
/* Flag: Do not expose in gdb sysreg xml. */
22
31
ARM_CP_NO_GDB = 1 << 15,
23
+/*
32
+ /*
24
+ * Return a "clean" address for ADDR according to TBID.
33
+ * Flags: If EL3 but not EL2...
25
+ * This is always a fresh temporary, as we need to be able to
34
+ * - UNDEF: discard the cpreg,
26
+ * increment this independently of a dirty write-back address.
35
+ * - KEEP: retain the cpreg as is,
27
+ */
36
+ * - C_NZ: set const on the cpreg, but retain resetvalue,
28
+static TCGv_i64 clean_data_tbi(DisasContext *s, TCGv_i64 addr)
37
+ * - else: set const on the cpreg, zero resetvalue, aka RES0.
29
+{
38
+ * See rule RJFFP in section D1.1.3 of DDI0487H.a.
30
+ TCGv_i64 clean = new_tmp_a64(s);
39
+ */
31
+ gen_top_byte_ignore(s, clean, addr, s->tbid);
40
+ ARM_CP_EL3_NO_EL2_UNDEF = 1 << 16,
32
+ return clean;
41
+ ARM_CP_EL3_NO_EL2_KEEP = 1 << 17,
33
+}
42
+ ARM_CP_EL3_NO_EL2_C_NZ = 1 << 18,
34
+
43
};
35
typedef struct DisasCompare64 {
36
TCGCond cond;
37
TCGv_i64 value;
38
@@ -XXX,XX +XXX,XX @@ static void gen_compare_and_swap(DisasContext *s, int rs, int rt,
39
TCGv_i64 tcg_rs = cpu_reg(s, rs);
40
TCGv_i64 tcg_rt = cpu_reg(s, rt);
41
int memidx = get_mem_index(s);
42
- TCGv_i64 addr = cpu_reg_sp(s, rn);
43
+ TCGv_i64 clean_addr;
44
45
if (rn == 31) {
46
gen_check_sp_alignment(s);
47
}
48
- tcg_gen_atomic_cmpxchg_i64(tcg_rs, addr, tcg_rs, tcg_rt, memidx,
49
+ clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn));
50
+ tcg_gen_atomic_cmpxchg_i64(tcg_rs, clean_addr, tcg_rs, tcg_rt, memidx,
51
size | MO_ALIGN | s->be_data);
52
}
53
54
@@ -XXX,XX +XXX,XX @@ static void gen_compare_and_swap_pair(DisasContext *s, int rs, int rt,
55
TCGv_i64 s2 = cpu_reg(s, rs + 1);
56
TCGv_i64 t1 = cpu_reg(s, rt);
57
TCGv_i64 t2 = cpu_reg(s, rt + 1);
58
- TCGv_i64 addr = cpu_reg_sp(s, rn);
59
+ TCGv_i64 clean_addr;
60
int memidx = get_mem_index(s);
61
62
if (rn == 31) {
63
gen_check_sp_alignment(s);
64
}
65
+ clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn));
66
67
if (size == 2) {
68
TCGv_i64 cmp = tcg_temp_new_i64();
69
@@ -XXX,XX +XXX,XX @@ static void gen_compare_and_swap_pair(DisasContext *s, int rs, int rt,
70
tcg_gen_concat32_i64(cmp, s2, s1);
71
}
72
73
- tcg_gen_atomic_cmpxchg_i64(cmp, addr, cmp, val, memidx,
74
+ tcg_gen_atomic_cmpxchg_i64(cmp, clean_addr, cmp, val, memidx,
75
MO_64 | MO_ALIGN | s->be_data);
76
tcg_temp_free_i64(val);
77
78
@@ -XXX,XX +XXX,XX @@ static void gen_compare_and_swap_pair(DisasContext *s, int rs, int rt,
79
if (HAVE_CMPXCHG128) {
80
TCGv_i32 tcg_rs = tcg_const_i32(rs);
81
if (s->be_data == MO_LE) {
82
- gen_helper_casp_le_parallel(cpu_env, tcg_rs, addr, t1, t2);
83
+ gen_helper_casp_le_parallel(cpu_env, tcg_rs,
84
+ clean_addr, t1, t2);
85
} else {
86
- gen_helper_casp_be_parallel(cpu_env, tcg_rs, addr, t1, t2);
87
+ gen_helper_casp_be_parallel(cpu_env, tcg_rs,
88
+ clean_addr, t1, t2);
89
}
90
tcg_temp_free_i32(tcg_rs);
91
} else {
92
@@ -XXX,XX +XXX,XX @@ static void gen_compare_and_swap_pair(DisasContext *s, int rs, int rt,
93
TCGv_i64 zero = tcg_const_i64(0);
94
95
/* Load the two words, in memory order. */
96
- tcg_gen_qemu_ld_i64(d1, addr, memidx,
97
+ tcg_gen_qemu_ld_i64(d1, clean_addr, memidx,
98
MO_64 | MO_ALIGN_16 | s->be_data);
99
- tcg_gen_addi_i64(a2, addr, 8);
100
- tcg_gen_qemu_ld_i64(d2, addr, memidx, MO_64 | s->be_data);
101
+ tcg_gen_addi_i64(a2, clean_addr, 8);
102
+ tcg_gen_qemu_ld_i64(d2, clean_addr, memidx, MO_64 | s->be_data);
103
104
/* Compare the two words, also in memory order. */
105
tcg_gen_setcond_i64(TCG_COND_EQ, c1, d1, s1);
106
@@ -XXX,XX +XXX,XX @@ static void gen_compare_and_swap_pair(DisasContext *s, int rs, int rt,
107
/* If compare equal, write back new data, else write back old data. */
108
tcg_gen_movcond_i64(TCG_COND_NE, c1, c2, zero, t1, d1);
109
tcg_gen_movcond_i64(TCG_COND_NE, c2, c2, zero, t2, d2);
110
- tcg_gen_qemu_st_i64(c1, addr, memidx, MO_64 | s->be_data);
111
+ tcg_gen_qemu_st_i64(c1, clean_addr, memidx, MO_64 | s->be_data);
112
tcg_gen_qemu_st_i64(c2, a2, memidx, MO_64 | s->be_data);
113
tcg_temp_free_i64(a2);
114
tcg_temp_free_i64(c1);
115
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
116
int is_lasr = extract32(insn, 15, 1);
117
int o2_L_o1_o0 = extract32(insn, 21, 3) * 2 | is_lasr;
118
int size = extract32(insn, 30, 2);
119
- TCGv_i64 tcg_addr;
120
+ TCGv_i64 clean_addr;
121
122
switch (o2_L_o1_o0) {
123
case 0x0: /* STXR */
124
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
125
if (is_lasr) {
126
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
127
}
128
- tcg_addr = read_cpu_reg_sp(s, rn, 1);
129
- gen_store_exclusive(s, rs, rt, rt2, tcg_addr, size, false);
130
+ clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn));
131
+ gen_store_exclusive(s, rs, rt, rt2, clean_addr, size, false);
132
return;
133
134
case 0x4: /* LDXR */
135
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
136
if (rn == 31) {
137
gen_check_sp_alignment(s);
138
}
139
- tcg_addr = read_cpu_reg_sp(s, rn, 1);
140
+ clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn));
141
s->is_ldex = true;
142
- gen_load_exclusive(s, rt, rt2, tcg_addr, size, false);
143
+ gen_load_exclusive(s, rt, rt2, clean_addr, size, false);
144
if (is_lasr) {
145
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
146
}
147
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
148
gen_check_sp_alignment(s);
149
}
150
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
151
- tcg_addr = read_cpu_reg_sp(s, rn, 1);
152
- do_gpr_st(s, cpu_reg(s, rt), tcg_addr, size, true, rt,
153
+ clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn));
154
+ do_gpr_st(s, cpu_reg(s, rt), clean_addr, size, true, rt,
155
disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
156
return;
157
158
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
159
if (rn == 31) {
160
gen_check_sp_alignment(s);
161
}
162
- tcg_addr = read_cpu_reg_sp(s, rn, 1);
163
- do_gpr_ld(s, cpu_reg(s, rt), tcg_addr, size, false, false, true, rt,
164
+ clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn));
165
+ do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, false, false, true, rt,
166
disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
167
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
168
return;
169
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
170
if (is_lasr) {
171
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
172
}
173
- tcg_addr = read_cpu_reg_sp(s, rn, 1);
174
- gen_store_exclusive(s, rs, rt, rt2, tcg_addr, size, true);
175
+ clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn));
176
+ gen_store_exclusive(s, rs, rt, rt2, clean_addr, size, true);
177
return;
178
}
179
if (rt2 == 31
180
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
181
if (rn == 31) {
182
gen_check_sp_alignment(s);
183
}
184
- tcg_addr = read_cpu_reg_sp(s, rn, 1);
185
+ clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn));
186
s->is_ldex = true;
187
- gen_load_exclusive(s, rt, rt2, tcg_addr, size, true);
188
+ gen_load_exclusive(s, rt, rt2, clean_addr, size, true);
189
if (is_lasr) {
190
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
191
}
192
@@ -XXX,XX +XXX,XX @@ static void disas_ld_lit(DisasContext *s, uint32_t insn)
193
int opc = extract32(insn, 30, 2);
194
bool is_signed = false;
195
int size = 2;
196
- TCGv_i64 tcg_rt, tcg_addr;
197
+ TCGv_i64 tcg_rt, clean_addr;
198
199
if (is_vector) {
200
if (opc == 3) {
201
@@ -XXX,XX +XXX,XX @@ static void disas_ld_lit(DisasContext *s, uint32_t insn)
202
203
tcg_rt = cpu_reg(s, rt);
204
205
- tcg_addr = tcg_const_i64((s->pc - 4) + imm);
206
+ clean_addr = tcg_const_i64((s->pc - 4) + imm);
207
if (is_vector) {
208
- do_fp_ld(s, rt, tcg_addr, size);
209
+ do_fp_ld(s, rt, clean_addr, size);
210
} else {
211
/* Only unsigned 32bit loads target 32bit registers. */
212
bool iss_sf = opc != 0;
213
214
- do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false,
215
+ do_gpr_ld(s, tcg_rt, clean_addr, size, is_signed, false,
216
true, rt, iss_sf, false);
217
}
218
- tcg_temp_free_i64(tcg_addr);
219
+ tcg_temp_free_i64(clean_addr);
220
}
221
44
222
/*
45
/*
223
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn)
46
diff --git a/target/arm/helper.c b/target/arm/helper.c
224
bool postindex = false;
47
index XXXXXXX..XXXXXXX 100644
225
bool wback = false;
48
--- a/target/arm/helper.c
226
49
+++ b/target/arm/helper.c
227
- TCGv_i64 tcg_addr; /* calculated address */
50
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
228
+ TCGv_i64 clean_addr, dirty_addr;
51
.access = PL1_RW, .readfn = spsel_read, .writefn = spsel_write },
229
+
52
{ .name = "FPEXC32_EL2", .state = ARM_CP_STATE_AA64,
230
int size;
53
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 3, .opc2 = 0,
231
54
- .access = PL2_RW, .type = ARM_CP_ALIAS | ARM_CP_FPU,
232
if (opc == 3) {
55
+ .access = PL2_RW,
233
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn)
56
+ .type = ARM_CP_ALIAS | ARM_CP_FPU | ARM_CP_EL3_NO_EL2_KEEP,
234
gen_check_sp_alignment(s);
57
.fieldoffset = offsetof(CPUARMState, vfp.xregs[ARM_VFP_FPEXC]) },
235
}
58
{ .name = "DACR32_EL2", .state = ARM_CP_STATE_AA64,
236
59
.opc0 = 3, .opc1 = 4, .crn = 3, .crm = 0, .opc2 = 0,
237
- tcg_addr = read_cpu_reg_sp(s, rn, 1);
60
- .access = PL2_RW, .resetvalue = 0,
238
-
61
+ .access = PL2_RW, .resetvalue = 0, .type = ARM_CP_EL3_NO_EL2_KEEP,
239
+ dirty_addr = read_cpu_reg_sp(s, rn, 1);
62
.writefn = dacr_write, .raw_writefn = raw_write,
240
if (!postindex) {
63
.fieldoffset = offsetof(CPUARMState, cp15.dacr32_el2) },
241
- tcg_gen_addi_i64(tcg_addr, tcg_addr, offset);
64
{ .name = "IFSR32_EL2", .state = ARM_CP_STATE_AA64,
242
+ tcg_gen_addi_i64(dirty_addr, dirty_addr, offset);
65
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 0, .opc2 = 1,
243
}
66
- .access = PL2_RW, .resetvalue = 0,
244
+ clean_addr = clean_data_tbi(s, dirty_addr);
67
+ .access = PL2_RW, .resetvalue = 0, .type = ARM_CP_EL3_NO_EL2_KEEP,
245
68
.fieldoffset = offsetof(CPUARMState, cp15.ifsr32_el2) },
246
if (is_vector) {
69
{ .name = "SPSR_IRQ", .state = ARM_CP_STATE_AA64,
247
if (is_load) {
70
.type = ARM_CP_ALIAS,
248
- do_fp_ld(s, rt, tcg_addr, size);
71
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
249
+ do_fp_ld(s, rt, clean_addr, size);
72
.writefn = tlbimva_hyp_is_write },
250
} else {
73
{ .name = "TLBI_ALLE2", .state = ARM_CP_STATE_AA64,
251
- do_fp_st(s, rt, tcg_addr, size);
74
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0,
252
+ do_fp_st(s, rt, clean_addr, size);
75
- .type = ARM_CP_NO_RAW, .access = PL2_W,
253
}
76
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
254
- tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
77
.writefn = tlbi_aa64_alle2_write },
255
+ tcg_gen_addi_i64(clean_addr, clean_addr, 1 << size);
78
{ .name = "TLBI_VAE2", .state = ARM_CP_STATE_AA64,
256
if (is_load) {
79
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1,
257
- do_fp_ld(s, rt2, tcg_addr, size);
80
- .type = ARM_CP_NO_RAW, .access = PL2_W,
258
+ do_fp_ld(s, rt2, clean_addr, size);
81
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
259
} else {
82
.writefn = tlbi_aa64_vae2_write },
260
- do_fp_st(s, rt2, tcg_addr, size);
83
{ .name = "TLBI_VALE2", .state = ARM_CP_STATE_AA64,
261
+ do_fp_st(s, rt2, clean_addr, size);
84
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5,
262
}
85
- .access = PL2_W, .type = ARM_CP_NO_RAW,
263
} else {
86
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
264
TCGv_i64 tcg_rt = cpu_reg(s, rt);
87
.writefn = tlbi_aa64_vae2_write },
265
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn)
88
{ .name = "TLBI_ALLE2IS", .state = ARM_CP_STATE_AA64,
266
/* Do not modify tcg_rt before recognizing any exception
89
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 0,
267
* from the second load.
90
- .access = PL2_W, .type = ARM_CP_NO_RAW,
268
*/
91
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
269
- do_gpr_ld(s, tmp, tcg_addr, size, is_signed, false,
92
.writefn = tlbi_aa64_alle2is_write },
270
+ do_gpr_ld(s, tmp, clean_addr, size, is_signed, false,
93
{ .name = "TLBI_VAE2IS", .state = ARM_CP_STATE_AA64,
271
false, 0, false, false);
94
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1,
272
- tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
95
- .type = ARM_CP_NO_RAW, .access = PL2_W,
273
- do_gpr_ld(s, tcg_rt2, tcg_addr, size, is_signed, false,
96
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
274
+ tcg_gen_addi_i64(clean_addr, clean_addr, 1 << size);
97
.writefn = tlbi_aa64_vae2is_write },
275
+ do_gpr_ld(s, tcg_rt2, clean_addr, size, is_signed, false,
98
{ .name = "TLBI_VALE2IS", .state = ARM_CP_STATE_AA64,
276
false, 0, false, false);
99
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5,
277
100
- .access = PL2_W, .type = ARM_CP_NO_RAW,
278
tcg_gen_mov_i64(tcg_rt, tmp);
101
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
279
tcg_temp_free_i64(tmp);
102
.writefn = tlbi_aa64_vae2is_write },
280
} else {
103
#ifndef CONFIG_USER_ONLY
281
- do_gpr_st(s, tcg_rt, tcg_addr, size,
104
/* Unlike the other EL2-related AT operations, these must
282
+ do_gpr_st(s, tcg_rt, clean_addr, size,
105
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
283
false, 0, false, false);
106
{ .name = "AT_S1E2R", .state = ARM_CP_STATE_AA64,
284
- tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
107
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 0,
285
- do_gpr_st(s, tcg_rt2, tcg_addr, size,
108
.access = PL2_W, .accessfn = at_s1e2_access,
286
+ tcg_gen_addi_i64(clean_addr, clean_addr, 1 << size);
109
- .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, .writefn = ats_write64 },
287
+ do_gpr_st(s, tcg_rt2, clean_addr, size,
110
+ .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC | ARM_CP_EL3_NO_EL2_UNDEF,
288
false, 0, false, false);
111
+ .writefn = ats_write64 },
112
{ .name = "AT_S1E2W", .state = ARM_CP_STATE_AA64,
113
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 1,
114
.access = PL2_W, .accessfn = at_s1e2_access,
115
- .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, .writefn = ats_write64 },
116
+ .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC | ARM_CP_EL3_NO_EL2_UNDEF,
117
+ .writefn = ats_write64 },
118
/* The AArch32 ATS1H* operations are CONSTRAINED UNPREDICTABLE
119
* if EL2 is not implemented; we choose to UNDEF. Behaviour at EL3
120
* with SCR.NS == 0 outside Monitor mode is UNPREDICTABLE; we choose
121
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
122
{ .name = "DBGVCR32_EL2", .state = ARM_CP_STATE_AA64,
123
.opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0,
124
.access = PL2_RW, .accessfn = access_tda,
125
- .type = ARM_CP_NOP },
126
+ .type = ARM_CP_NOP | ARM_CP_EL3_NO_EL2_KEEP },
127
/* Dummy MDCCINT_EL1, since we don't implement the Debug Communications
128
* Channel but Linux may try to access this register. The 32-bit
129
* alias is DBGDCCINT.
130
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbirange_reginfo[] = {
131
.access = PL2_W, .type = ARM_CP_NOP },
132
{ .name = "TLBI_RVAE2IS", .state = ARM_CP_STATE_AA64,
133
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 2, .opc2 = 1,
134
- .access = PL2_W, .type = ARM_CP_NO_RAW,
135
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
136
.writefn = tlbi_aa64_rvae2is_write },
137
{ .name = "TLBI_RVALE2IS", .state = ARM_CP_STATE_AA64,
138
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 2, .opc2 = 5,
139
- .access = PL2_W, .type = ARM_CP_NO_RAW,
140
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
141
.writefn = tlbi_aa64_rvae2is_write },
142
{ .name = "TLBI_RIPAS2E1", .state = ARM_CP_STATE_AA64,
143
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 2,
144
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbirange_reginfo[] = {
145
.access = PL2_W, .type = ARM_CP_NOP },
146
{ .name = "TLBI_RVAE2OS", .state = ARM_CP_STATE_AA64,
147
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 5, .opc2 = 1,
148
- .access = PL2_W, .type = ARM_CP_NO_RAW,
149
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
150
.writefn = tlbi_aa64_rvae2is_write },
151
{ .name = "TLBI_RVALE2OS", .state = ARM_CP_STATE_AA64,
152
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 5, .opc2 = 5,
153
- .access = PL2_W, .type = ARM_CP_NO_RAW,
154
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
155
.writefn = tlbi_aa64_rvae2is_write },
156
{ .name = "TLBI_RVAE2", .state = ARM_CP_STATE_AA64,
157
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 6, .opc2 = 1,
158
- .access = PL2_W, .type = ARM_CP_NO_RAW,
159
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
160
.writefn = tlbi_aa64_rvae2_write },
161
{ .name = "TLBI_RVALE2", .state = ARM_CP_STATE_AA64,
162
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 6, .opc2 = 5,
163
- .access = PL2_W, .type = ARM_CP_NO_RAW,
164
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
165
.writefn = tlbi_aa64_rvae2_write },
166
{ .name = "TLBI_RVAE3IS", .state = ARM_CP_STATE_AA64,
167
.opc0 = 1, .opc1 = 6, .crn = 8, .crm = 2, .opc2 = 1,
168
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbios_reginfo[] = {
169
.writefn = tlbi_aa64_vae1is_write },
170
{ .name = "TLBI_ALLE2OS", .state = ARM_CP_STATE_AA64,
171
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 0,
172
- .access = PL2_W, .type = ARM_CP_NO_RAW,
173
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
174
.writefn = tlbi_aa64_alle2is_write },
175
{ .name = "TLBI_VAE2OS", .state = ARM_CP_STATE_AA64,
176
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 1,
177
- .access = PL2_W, .type = ARM_CP_NO_RAW,
178
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
179
.writefn = tlbi_aa64_vae2is_write },
180
{ .name = "TLBI_ALLE1OS", .state = ARM_CP_STATE_AA64,
181
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 4,
182
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbios_reginfo[] = {
183
.writefn = tlbi_aa64_alle1is_write },
184
{ .name = "TLBI_VALE2OS", .state = ARM_CP_STATE_AA64,
185
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 5,
186
- .access = PL2_W, .type = ARM_CP_NO_RAW,
187
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
188
.writefn = tlbi_aa64_vae2is_write },
189
{ .name = "TLBI_VMALLS12E1OS", .state = ARM_CP_STATE_AA64,
190
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 6,
191
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
192
{ .name = "VPIDR", .state = ARM_CP_STATE_AA32,
193
.cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,
194
.access = PL2_RW, .accessfn = access_el3_aa32ns,
195
- .resetvalue = cpu->midr, .type = ARM_CP_ALIAS,
196
+ .resetvalue = cpu->midr,
197
+ .type = ARM_CP_ALIAS | ARM_CP_EL3_NO_EL2_C_NZ,
198
.fieldoffset = offsetoflow32(CPUARMState, cp15.vpidr_el2) },
199
{ .name = "VPIDR_EL2", .state = ARM_CP_STATE_AA64,
200
.opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,
201
.access = PL2_RW, .resetvalue = cpu->midr,
202
+ .type = ARM_CP_EL3_NO_EL2_C_NZ,
203
.fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) },
204
{ .name = "VMPIDR", .state = ARM_CP_STATE_AA32,
205
.cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,
206
.access = PL2_RW, .accessfn = access_el3_aa32ns,
207
- .resetvalue = vmpidr_def, .type = ARM_CP_ALIAS,
208
+ .resetvalue = vmpidr_def,
209
+ .type = ARM_CP_ALIAS | ARM_CP_EL3_NO_EL2_C_NZ,
210
.fieldoffset = offsetoflow32(CPUARMState, cp15.vmpidr_el2) },
211
{ .name = "VMPIDR_EL2", .state = ARM_CP_STATE_AA64,
212
.opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,
213
- .access = PL2_RW,
214
- .resetvalue = vmpidr_def,
215
+ .access = PL2_RW, .resetvalue = vmpidr_def,
216
+ .type = ARM_CP_EL3_NO_EL2_C_NZ,
217
.fieldoffset = offsetof(CPUARMState, cp15.vmpidr_el2) },
218
};
219
define_arm_cp_regs(cpu, vpidr_regs);
220
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
221
int crm, int opc1, int opc2,
222
const char *name)
223
{
224
+ CPUARMState *env = &cpu->env;
225
uint32_t key;
226
ARMCPRegInfo *r2;
227
bool is64 = r->type & ARM_CP_64BIT;
228
bool ns = secstate & ARM_CP_SECSTATE_NS;
229
int cp = r->cp;
230
- bool isbanked;
231
size_t name_len;
232
+ bool make_const;
233
234
switch (state) {
235
case ARM_CP_STATE_AA32:
236
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
289
}
237
}
290
}
238
}
291
239
292
if (wback) {
240
+ /*
293
if (postindex) {
241
+ * Eliminate registers that are not present because the EL is missing.
294
- tcg_gen_addi_i64(tcg_addr, tcg_addr, offset - (1 << size));
242
+ * Doing this here makes it easier to put all registers for a given
295
- } else {
243
+ * feature into the same ARMCPRegInfo array and define them all at once.
296
- tcg_gen_subi_i64(tcg_addr, tcg_addr, 1 << size);
244
+ */
297
+ tcg_gen_addi_i64(dirty_addr, dirty_addr, offset);
245
+ make_const = false;
298
}
246
+ if (arm_feature(env, ARM_FEATURE_EL3)) {
299
- tcg_gen_mov_i64(cpu_reg_sp(s, rn), tcg_addr);
247
+ /*
300
+ tcg_gen_mov_i64(cpu_reg_sp(s, rn), dirty_addr);
248
+ * An EL2 register without EL2 but with EL3 is (usually) RES0.
249
+ * See rule RJFFP in section D1.1.3 of DDI0487H.a.
250
+ */
251
+ int min_el = ctz32(r->access) / 2;
252
+ if (min_el == 2 && !arm_feature(env, ARM_FEATURE_EL2)) {
253
+ if (r->type & ARM_CP_EL3_NO_EL2_UNDEF) {
254
+ return;
255
+ }
256
+ make_const = !(r->type & ARM_CP_EL3_NO_EL2_KEEP);
257
+ }
258
+ } else {
259
+ CPAccessRights max_el = (arm_feature(env, ARM_FEATURE_EL2)
260
+ ? PL2_RW : PL1_RW);
261
+ if ((r->access & max_el) == 0) {
262
+ return;
263
+ }
264
+ }
265
+
266
/* Combine cpreg and name into one allocation. */
267
name_len = strlen(name) + 1;
268
r2 = g_malloc(sizeof(*r2) + name_len);
269
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
270
r2->opaque = opaque;
301
}
271
}
302
}
272
303
273
- isbanked = r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1];
304
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn,
274
- if (isbanked) {
305
bool post_index;
275
+ if (make_const) {
306
bool writeback;
276
+ /* This should not have been a very special register to begin. */
307
277
+ int old_special = r2->type & ARM_CP_SPECIAL_MASK;
308
- TCGv_i64 tcg_addr;
278
+ assert(old_special == 0 || old_special == ARM_CP_NOP);
309
+ TCGv_i64 clean_addr, dirty_addr;
279
/*
310
280
- * Register is banked (using both entries in array).
311
if (is_vector) {
281
- * Overwriting fieldoffset as the array is only used to define
312
size |= (opc & 2) << 1;
282
- * banked registers but later only fieldoffset is used.
313
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn,
283
+ * Set the special function to CONST, retaining the other flags.
314
if (rn == 31) {
284
+ * This is important for e.g. ARM_CP_SVE so that we still
315
gen_check_sp_alignment(s);
285
+ * take the SVE trap if CPTR_EL3.EZ == 0.
316
}
286
*/
317
- tcg_addr = read_cpu_reg_sp(s, rn, 1);
287
- r2->fieldoffset = r->bank_fieldoffsets[ns];
318
288
- }
319
+ dirty_addr = read_cpu_reg_sp(s, rn, 1);
289
+ r2->type = (r2->type & ~ARM_CP_SPECIAL_MASK) | ARM_CP_CONST;
320
if (!post_index) {
290
+ /*
321
- tcg_gen_addi_i64(tcg_addr, tcg_addr, imm9);
291
+ * Usually, these registers become RES0, but there are a few
322
+ tcg_gen_addi_i64(dirty_addr, dirty_addr, imm9);
292
+ * special cases like VPIDR_EL2 which have a constant non-zero
323
}
293
+ * value with writes ignored.
324
+ clean_addr = clean_data_tbi(s, dirty_addr);
294
+ */
325
295
+ if (!(r->type & ARM_CP_EL3_NO_EL2_C_NZ)) {
326
if (is_vector) {
296
+ r2->resetvalue = 0;
327
if (is_store) {
297
+ }
328
- do_fp_st(s, rt, tcg_addr, size);
298
+ /*
329
+ do_fp_st(s, rt, clean_addr, size);
299
+ * ARM_CP_CONST has precedence, so removing the callbacks and
330
} else {
300
+ * offsets are not strictly necessary, but it is potentially
331
- do_fp_ld(s, rt, tcg_addr, size);
301
+ * less confusing to debug later.
332
+ do_fp_ld(s, rt, clean_addr, size);
302
+ */
333
}
303
+ r2->readfn = NULL;
334
} else {
304
+ r2->writefn = NULL;
335
TCGv_i64 tcg_rt = cpu_reg(s, rt);
305
+ r2->raw_readfn = NULL;
336
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn,
306
+ r2->raw_writefn = NULL;
337
bool iss_sf = disas_ldst_compute_iss_sf(size, is_signed, opc);
307
+ r2->resetfn = NULL;
338
308
+ r2->fieldoffset = 0;
339
if (is_store) {
309
+ r2->bank_fieldoffsets[0] = 0;
340
- do_gpr_st_memidx(s, tcg_rt, tcg_addr, size, memidx,
310
+ r2->bank_fieldoffsets[1] = 0;
341
+ do_gpr_st_memidx(s, tcg_rt, clean_addr, size, memidx,
311
+ } else {
342
iss_valid, rt, iss_sf, false);
312
+ bool isbanked = r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1];
343
} else {
313
344
- do_gpr_ld_memidx(s, tcg_rt, tcg_addr, size,
314
- if (state == ARM_CP_STATE_AA32) {
345
+ do_gpr_ld_memidx(s, tcg_rt, clean_addr, size,
315
if (isbanked) {
346
is_signed, is_extended, memidx,
316
/*
347
iss_valid, rt, iss_sf, false);
317
- * If the register is banked then we don't need to migrate or
348
}
318
- * reset the 32-bit instance in certain cases:
349
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn,
319
- *
350
if (writeback) {
320
- * 1) If the register has both 32-bit and 64-bit instances then we
351
TCGv_i64 tcg_rn = cpu_reg_sp(s, rn);
321
- * can count on the 64-bit instance taking care of the
352
if (post_index) {
322
- * non-secure bank.
353
- tcg_gen_addi_i64(tcg_addr, tcg_addr, imm9);
323
- * 2) If ARMv8 is enabled then we can count on a 64-bit version
354
+ tcg_gen_addi_i64(dirty_addr, dirty_addr, imm9);
324
- * taking care of the secure bank. This requires that separate
355
}
325
- * 32 and 64-bit definitions are provided.
356
- tcg_gen_mov_i64(tcg_rn, tcg_addr);
326
+ * Register is banked (using both entries in array).
357
+ tcg_gen_mov_i64(tcg_rn, dirty_addr);
327
+ * Overwriting fieldoffset as the array is only used to define
358
}
328
+ * banked registers but later only fieldoffset is used.
359
}
329
*/
360
330
- if ((r->state == ARM_CP_STATE_BOTH && ns) ||
361
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_roffset(DisasContext *s, uint32_t insn,
331
- (arm_feature(&cpu->env, ARM_FEATURE_V8) && !ns)) {
362
bool is_store = false;
332
+ r2->fieldoffset = r->bank_fieldoffsets[ns];
363
bool is_extended = false;
333
+ }
364
334
+ if (state == ARM_CP_STATE_AA32) {
365
- TCGv_i64 tcg_rm;
335
+ if (isbanked) {
366
- TCGv_i64 tcg_addr;
336
+ /*
367
+ TCGv_i64 tcg_rm, clean_addr, dirty_addr;
337
+ * If the register is banked then we don't need to migrate or
368
338
+ * reset the 32-bit instance in certain cases:
369
if (extract32(opt, 1, 1) == 0) {
339
+ *
370
unallocated_encoding(s);
340
+ * 1) If the register has both 32-bit and 64-bit instances
371
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_roffset(DisasContext *s, uint32_t insn,
341
+ * then we can count on the 64-bit instance taking care
372
if (rn == 31) {
342
+ * of the non-secure bank.
373
gen_check_sp_alignment(s);
343
+ * 2) If ARMv8 is enabled then we can count on a 64-bit
374
}
344
+ * version taking care of the secure bank. This requires
375
- tcg_addr = read_cpu_reg_sp(s, rn, 1);
345
+ * that separate 32 and 64-bit definitions are provided.
376
+ dirty_addr = read_cpu_reg_sp(s, rn, 1);
346
+ */
377
347
+ if ((r->state == ARM_CP_STATE_BOTH && ns) ||
378
tcg_rm = read_cpu_reg(s, rm, 1);
348
+ (arm_feature(env, ARM_FEATURE_V8) && !ns)) {
379
ext_and_shift_reg(tcg_rm, tcg_rm, opt, shift ? size : 0);
349
+ r2->type |= ARM_CP_ALIAS;
380
350
+ }
381
- tcg_gen_add_i64(tcg_addr, tcg_addr, tcg_rm);
351
+ } else if ((secstate != r->secure) && !ns) {
382
+ tcg_gen_add_i64(dirty_addr, dirty_addr, tcg_rm);
352
+ /*
383
+ clean_addr = clean_data_tbi(s, dirty_addr);
353
+ * The register is not banked so we only want to allow
384
354
+ * migration of the non-secure instance.
385
if (is_vector) {
355
+ */
386
if (is_store) {
356
r2->type |= ARM_CP_ALIAS;
387
- do_fp_st(s, rt, tcg_addr, size);
357
}
388
+ do_fp_st(s, rt, clean_addr, size);
358
- } else if ((secstate != r->secure) && !ns) {
389
} else {
359
- /*
390
- do_fp_ld(s, rt, tcg_addr, size);
360
- * The register is not banked so we only want to allow migration
391
+ do_fp_ld(s, rt, clean_addr, size);
361
- * of the non-secure instance.
392
}
362
- */
393
} else {
363
- r2->type |= ARM_CP_ALIAS;
394
TCGv_i64 tcg_rt = cpu_reg(s, rt);
364
- }
395
bool iss_sf = disas_ldst_compute_iss_sf(size, is_signed, opc);
365
396
if (is_store) {
366
- if (HOST_BIG_ENDIAN &&
397
- do_gpr_st(s, tcg_rt, tcg_addr, size,
367
- r->state == ARM_CP_STATE_BOTH && r2->fieldoffset) {
398
+ do_gpr_st(s, tcg_rt, clean_addr, size,
368
- r2->fieldoffset += sizeof(uint32_t);
399
true, rt, iss_sf, false);
369
+ if (HOST_BIG_ENDIAN &&
400
} else {
370
+ r->state == ARM_CP_STATE_BOTH && r2->fieldoffset) {
401
- do_gpr_ld(s, tcg_rt, tcg_addr, size,
371
+ r2->fieldoffset += sizeof(uint32_t);
402
+ do_gpr_ld(s, tcg_rt, clean_addr, size,
372
+ }
403
is_signed, is_extended,
404
true, rt, iss_sf, false);
405
}
406
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn,
407
unsigned int imm12 = extract32(insn, 10, 12);
408
unsigned int offset;
409
410
- TCGv_i64 tcg_addr;
411
+ TCGv_i64 clean_addr, dirty_addr;
412
413
bool is_store;
414
bool is_signed = false;
415
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn,
416
if (rn == 31) {
417
gen_check_sp_alignment(s);
418
}
419
- tcg_addr = read_cpu_reg_sp(s, rn, 1);
420
+ dirty_addr = read_cpu_reg_sp(s, rn, 1);
421
offset = imm12 << size;
422
- tcg_gen_addi_i64(tcg_addr, tcg_addr, offset);
423
+ tcg_gen_addi_i64(dirty_addr, dirty_addr, offset);
424
+ clean_addr = clean_data_tbi(s, dirty_addr);
425
426
if (is_vector) {
427
if (is_store) {
428
- do_fp_st(s, rt, tcg_addr, size);
429
+ do_fp_st(s, rt, clean_addr, size);
430
} else {
431
- do_fp_ld(s, rt, tcg_addr, size);
432
+ do_fp_ld(s, rt, clean_addr, size);
433
}
434
} else {
435
TCGv_i64 tcg_rt = cpu_reg(s, rt);
436
bool iss_sf = disas_ldst_compute_iss_sf(size, is_signed, opc);
437
if (is_store) {
438
- do_gpr_st(s, tcg_rt, tcg_addr, size,
439
+ do_gpr_st(s, tcg_rt, clean_addr, size,
440
true, rt, iss_sf, false);
441
} else {
442
- do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended,
443
+ do_gpr_ld(s, tcg_rt, clean_addr, size, is_signed, is_extended,
444
true, rt, iss_sf, false);
445
}
373
}
446
}
374
}
447
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
375
448
int rs = extract32(insn, 16, 5);
376
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
449
int rn = extract32(insn, 5, 5);
377
* multiple times. Special registers (ie NOP/WFI) are
450
int o3_opc = extract32(insn, 12, 4);
378
* never migratable and not even raw-accessible.
451
- TCGv_i64 tcg_rn, tcg_rs;
379
*/
452
+ TCGv_i64 tcg_rs, clean_addr;
380
- if (r->type & ARM_CP_SPECIAL_MASK) {
453
AtomicThreeOpFn *fn;
381
+ if (r2->type & ARM_CP_SPECIAL_MASK) {
454
382
r2->type |= ARM_CP_NO_RAW;
455
if (is_vector || !dc_isar_feature(aa64_atomics, s)) {
456
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
457
if (rn == 31) {
458
gen_check_sp_alignment(s);
459
}
383
}
460
- tcg_rn = cpu_reg_sp(s, rn);
384
if (((r->crm == CP_ANY) && crm != 0) ||
461
+ clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn));
462
tcg_rs = read_cpu_reg(s, rs, true);
463
464
if (o3_opc == 1) { /* LDCLR */
465
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
466
/* The tcg atomic primitives are all full barriers. Therefore we
467
* can ignore the Acquire and Release bits of this instruction.
468
*/
469
- fn(cpu_reg(s, rt), tcg_rn, tcg_rs, get_mem_index(s),
470
+ fn(cpu_reg(s, rt), clean_addr, tcg_rs, get_mem_index(s),
471
s->be_data | size | MO_ALIGN);
472
}
473
474
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_pac(DisasContext *s, uint32_t insn,
475
bool is_wback = extract32(insn, 11, 1);
476
bool use_key_a = !extract32(insn, 23, 1);
477
int offset;
478
- TCGv_i64 tcg_addr, tcg_rt;
479
+ TCGv_i64 clean_addr, dirty_addr, tcg_rt;
480
481
if (size != 3 || is_vector || !dc_isar_feature(aa64_pauth, s)) {
482
unallocated_encoding(s);
483
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_pac(DisasContext *s, uint32_t insn,
484
if (rn == 31) {
485
gen_check_sp_alignment(s);
486
}
487
- tcg_addr = read_cpu_reg_sp(s, rn, 1);
488
+ dirty_addr = read_cpu_reg_sp(s, rn, 1);
489
490
if (s->pauth_active) {
491
if (use_key_a) {
492
- gen_helper_autda(tcg_addr, cpu_env, tcg_addr, cpu_X[31]);
493
+ gen_helper_autda(dirty_addr, cpu_env, dirty_addr, cpu_X[31]);
494
} else {
495
- gen_helper_autdb(tcg_addr, cpu_env, tcg_addr, cpu_X[31]);
496
+ gen_helper_autdb(dirty_addr, cpu_env, dirty_addr, cpu_X[31]);
497
}
498
}
499
500
/* Form the 10-bit signed, scaled offset. */
501
offset = (extract32(insn, 22, 1) << 9) | extract32(insn, 12, 9);
502
offset = sextract32(offset << size, 0, 10 + size);
503
- tcg_gen_addi_i64(tcg_addr, tcg_addr, offset);
504
+ tcg_gen_addi_i64(dirty_addr, dirty_addr, offset);
505
+
506
+ /* Note that "clean" and "dirty" here refer to TBI not PAC. */
507
+ clean_addr = clean_data_tbi(s, dirty_addr);
508
509
tcg_rt = cpu_reg(s, rt);
510
-
511
- do_gpr_ld(s, tcg_rt, tcg_addr, size, /* is_signed */ false,
512
+ do_gpr_ld(s, tcg_rt, clean_addr, size, /* is_signed */ false,
513
/* extend */ false, /* iss_valid */ !is_wback,
514
/* iss_srt */ rt, /* iss_sf */ true, /* iss_ar */ false);
515
516
if (is_wback) {
517
- tcg_gen_mov_i64(cpu_reg_sp(s, rn), tcg_addr);
518
+ tcg_gen_mov_i64(cpu_reg_sp(s, rn), dirty_addr);
519
}
520
}
521
522
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
523
bool is_store = !extract32(insn, 22, 1);
524
bool is_postidx = extract32(insn, 23, 1);
525
bool is_q = extract32(insn, 30, 1);
526
- TCGv_i64 tcg_addr, tcg_rn, tcg_ebytes;
527
+ TCGv_i64 clean_addr, tcg_rn, tcg_ebytes;
528
TCGMemOp endian = s->be_data;
529
530
int ebytes; /* bytes per element */
531
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
532
elements = (is_q ? 16 : 8) / ebytes;
533
534
tcg_rn = cpu_reg_sp(s, rn);
535
- tcg_addr = tcg_temp_new_i64();
536
- tcg_gen_mov_i64(tcg_addr, tcg_rn);
537
+ clean_addr = clean_data_tbi(s, tcg_rn);
538
tcg_ebytes = tcg_const_i64(ebytes);
539
540
for (r = 0; r < rpt; r++) {
541
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
542
for (xs = 0; xs < selem; xs++) {
543
int tt = (rt + r + xs) % 32;
544
if (is_store) {
545
- do_vec_st(s, tt, e, tcg_addr, size, endian);
546
+ do_vec_st(s, tt, e, clean_addr, size, endian);
547
} else {
548
- do_vec_ld(s, tt, e, tcg_addr, size, endian);
549
+ do_vec_ld(s, tt, e, clean_addr, size, endian);
550
}
551
- tcg_gen_add_i64(tcg_addr, tcg_addr, tcg_ebytes);
552
+ tcg_gen_add_i64(clean_addr, clean_addr, tcg_ebytes);
553
}
554
}
555
}
556
+ tcg_temp_free_i64(tcg_ebytes);
557
558
if (!is_store) {
559
/* For non-quad operations, setting a slice of the low
560
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
561
562
if (is_postidx) {
563
if (rm == 31) {
564
- tcg_gen_mov_i64(tcg_rn, tcg_addr);
565
+ tcg_gen_addi_i64(tcg_rn, tcg_rn, rpt * elements * selem * ebytes);
566
} else {
567
tcg_gen_add_i64(tcg_rn, tcg_rn, cpu_reg(s, rm));
568
}
569
}
570
- tcg_temp_free_i64(tcg_ebytes);
571
- tcg_temp_free_i64(tcg_addr);
572
}
573
574
/* AdvSIMD load/store single structure
575
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
576
bool replicate = false;
577
int index = is_q << 3 | S << 2 | size;
578
int ebytes, xs;
579
- TCGv_i64 tcg_addr, tcg_rn, tcg_ebytes;
580
+ TCGv_i64 clean_addr, tcg_rn, tcg_ebytes;
581
582
if (extract32(insn, 31, 1)) {
583
unallocated_encoding(s);
584
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
585
}
586
587
tcg_rn = cpu_reg_sp(s, rn);
588
- tcg_addr = tcg_temp_new_i64();
589
- tcg_gen_mov_i64(tcg_addr, tcg_rn);
590
+ clean_addr = clean_data_tbi(s, tcg_rn);
591
tcg_ebytes = tcg_const_i64(ebytes);
592
593
for (xs = 0; xs < selem; xs++) {
594
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
595
/* Load and replicate to all elements */
596
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
597
598
- tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr,
599
+ tcg_gen_qemu_ld_i64(tcg_tmp, clean_addr,
600
get_mem_index(s), s->be_data + scale);
601
tcg_gen_gvec_dup_i64(scale, vec_full_reg_offset(s, rt),
602
(is_q + 1) * 8, vec_full_reg_size(s),
603
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
604
} else {
605
/* Load/store one element per register */
606
if (is_load) {
607
- do_vec_ld(s, rt, index, tcg_addr, scale, s->be_data);
608
+ do_vec_ld(s, rt, index, clean_addr, scale, s->be_data);
609
} else {
610
- do_vec_st(s, rt, index, tcg_addr, scale, s->be_data);
611
+ do_vec_st(s, rt, index, clean_addr, scale, s->be_data);
612
}
613
}
614
- tcg_gen_add_i64(tcg_addr, tcg_addr, tcg_ebytes);
615
+ tcg_gen_add_i64(clean_addr, clean_addr, tcg_ebytes);
616
rt = (rt + 1) % 32;
617
}
618
+ tcg_temp_free_i64(tcg_ebytes);
619
620
if (is_postidx) {
621
if (rm == 31) {
622
- tcg_gen_mov_i64(tcg_rn, tcg_addr);
623
+ tcg_gen_addi_i64(tcg_rn, tcg_rn, selem * ebytes);
624
} else {
625
tcg_gen_add_i64(tcg_rn, tcg_rn, cpu_reg(s, rm));
626
}
627
}
628
- tcg_temp_free_i64(tcg_ebytes);
629
- tcg_temp_free_i64(tcg_addr);
630
}
631
632
/* Loads and stores */
633
--
385
--
634
2.20.1
386
2.25.1
635
636
diff view generated by jsdifflib
New patch
1
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
Drop el3_no_el2_cp_reginfo, el3_no_el2_v8_cp_reginfo, and the local
4
vpidr_regs definition, and rely on the squashing to ARM_CP_CONST
5
while registering for v8.
6
7
This is a behavior change for v7 cpus with Security Extensions and
8
without Virtualization Extensions, in that the virtualization cpregs
9
are now correctly not present. This would be a migration compatibility
10
break, except that we have an existing bug in which migration of 32-bit
11
cpus with Security Extensions enabled does not work.
12
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220506180242.216785-3-richard.henderson@linaro.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
target/arm/helper.c | 158 ++++----------------------------------------
19
1 file changed, 13 insertions(+), 145 deletions(-)
20
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/helper.c
24
+++ b/target/arm/helper.c
25
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
26
.fieldoffset = offsetoflow32(CPUARMState, cp15.mdcr_el3) },
27
};
28
29
-/* Used to describe the behaviour of EL2 regs when EL2 does not exist. */
30
-static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
31
- { .name = "VBAR_EL2", .state = ARM_CP_STATE_BOTH,
32
- .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
33
- .access = PL2_RW,
34
- .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore },
35
- { .name = "HCR_EL2", .state = ARM_CP_STATE_BOTH,
36
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
37
- .access = PL2_RW,
38
- .type = ARM_CP_CONST, .resetvalue = 0 },
39
- { .name = "HACR_EL2", .state = ARM_CP_STATE_BOTH,
40
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 7,
41
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
42
- { .name = "ESR_EL2", .state = ARM_CP_STATE_BOTH,
43
- .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
44
- .access = PL2_RW,
45
- .type = ARM_CP_CONST, .resetvalue = 0 },
46
- { .name = "CPTR_EL2", .state = ARM_CP_STATE_BOTH,
47
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 2,
48
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
49
- { .name = "MAIR_EL2", .state = ARM_CP_STATE_BOTH,
50
- .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 0,
51
- .access = PL2_RW, .type = ARM_CP_CONST,
52
- .resetvalue = 0 },
53
- { .name = "HMAIR1", .state = ARM_CP_STATE_AA32,
54
- .cp = 15, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1,
55
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
56
- { .name = "AMAIR_EL2", .state = ARM_CP_STATE_BOTH,
57
- .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 0,
58
- .access = PL2_RW, .type = ARM_CP_CONST,
59
- .resetvalue = 0 },
60
- { .name = "HAMAIR1", .state = ARM_CP_STATE_AA32,
61
- .cp = 15, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1,
62
- .access = PL2_RW, .type = ARM_CP_CONST,
63
- .resetvalue = 0 },
64
- { .name = "AFSR0_EL2", .state = ARM_CP_STATE_BOTH,
65
- .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 0,
66
- .access = PL2_RW, .type = ARM_CP_CONST,
67
- .resetvalue = 0 },
68
- { .name = "AFSR1_EL2", .state = ARM_CP_STATE_BOTH,
69
- .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 1,
70
- .access = PL2_RW, .type = ARM_CP_CONST,
71
- .resetvalue = 0 },
72
- { .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH,
73
- .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2,
74
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
75
- { .name = "VTCR_EL2", .state = ARM_CP_STATE_BOTH,
76
- .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2,
77
- .access = PL2_RW, .accessfn = access_el3_aa32ns,
78
- .type = ARM_CP_CONST, .resetvalue = 0 },
79
- { .name = "VTTBR", .state = ARM_CP_STATE_AA32,
80
- .cp = 15, .opc1 = 6, .crm = 2,
81
- .access = PL2_RW, .accessfn = access_el3_aa32ns,
82
- .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
83
- { .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64,
84
- .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0,
85
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
86
- { .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH,
87
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0,
88
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
89
- { .name = "TPIDR_EL2", .state = ARM_CP_STATE_BOTH,
90
- .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 2,
91
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
92
- { .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64,
93
- .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0,
94
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
95
- { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2,
96
- .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST,
97
- .resetvalue = 0 },
98
- { .name = "CNTHCTL_EL2", .state = ARM_CP_STATE_BOTH,
99
- .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 1, .opc2 = 0,
100
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
101
- { .name = "CNTVOFF_EL2", .state = ARM_CP_STATE_AA64,
102
- .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 0, .opc2 = 3,
103
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
104
- { .name = "CNTVOFF", .cp = 15, .opc1 = 4, .crm = 14,
105
- .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST,
106
- .resetvalue = 0 },
107
- { .name = "CNTHP_CVAL_EL2", .state = ARM_CP_STATE_AA64,
108
- .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 2,
109
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
110
- { .name = "CNTHP_CVAL", .cp = 15, .opc1 = 6, .crm = 14,
111
- .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST,
112
- .resetvalue = 0 },
113
- { .name = "CNTHP_TVAL_EL2", .state = ARM_CP_STATE_BOTH,
114
- .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 0,
115
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
116
- { .name = "CNTHP_CTL_EL2", .state = ARM_CP_STATE_BOTH,
117
- .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 1,
118
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
119
- { .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH,
120
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1,
121
- .access = PL2_RW, .accessfn = access_tda,
122
- .type = ARM_CP_CONST, .resetvalue = 0 },
123
- { .name = "HPFAR_EL2", .state = ARM_CP_STATE_BOTH,
124
- .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4,
125
- .access = PL2_RW, .accessfn = access_el3_aa32ns,
126
- .type = ARM_CP_CONST, .resetvalue = 0 },
127
- { .name = "HSTR_EL2", .state = ARM_CP_STATE_BOTH,
128
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 3,
129
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
130
- { .name = "FAR_EL2", .state = ARM_CP_STATE_BOTH,
131
- .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
132
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
133
- { .name = "HIFAR", .state = ARM_CP_STATE_AA32,
134
- .type = ARM_CP_CONST,
135
- .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 2,
136
- .access = PL2_RW, .resetvalue = 0 },
137
-};
138
-
139
-/* Ditto, but for registers which exist in ARMv8 but not v7 */
140
-static const ARMCPRegInfo el3_no_el2_v8_cp_reginfo[] = {
141
- { .name = "HCR2", .state = ARM_CP_STATE_AA32,
142
- .cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4,
143
- .access = PL2_RW,
144
- .type = ARM_CP_CONST, .resetvalue = 0 },
145
-};
146
-
147
static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
148
{
149
ARMCPU *cpu = env_archcpu(env);
150
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
151
define_arm_cp_regs(cpu, v8_idregs);
152
define_arm_cp_regs(cpu, v8_cp_reginfo);
153
}
154
- if (arm_feature(env, ARM_FEATURE_EL2)) {
155
+
156
+ /*
157
+ * Register the base EL2 cpregs.
158
+ * Pre v8, these registers are implemented only as part of the
159
+ * Virtualization Extensions (EL2 present). Beginning with v8,
160
+ * if EL2 is missing but EL3 is enabled, mostly these become
161
+ * RES0 from EL3, with some specific exceptions.
162
+ */
163
+ if (arm_feature(env, ARM_FEATURE_EL2)
164
+ || (arm_feature(env, ARM_FEATURE_EL3)
165
+ && arm_feature(env, ARM_FEATURE_V8))) {
166
uint64_t vmpidr_def = mpidr_read_val(env);
167
ARMCPRegInfo vpidr_regs[] = {
168
{ .name = "VPIDR", .state = ARM_CP_STATE_AA32,
169
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
170
};
171
define_one_arm_cp_reg(cpu, &rvbar);
172
}
173
- } else {
174
- /* If EL2 is missing but higher ELs are enabled, we need to
175
- * register the no_el2 reginfos.
176
- */
177
- if (arm_feature(env, ARM_FEATURE_EL3)) {
178
- /* When EL3 exists but not EL2, VPIDR and VMPIDR take the value
179
- * of MIDR_EL1 and MPIDR_EL1.
180
- */
181
- ARMCPRegInfo vpidr_regs[] = {
182
- { .name = "VPIDR_EL2", .state = ARM_CP_STATE_BOTH,
183
- .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,
184
- .access = PL2_RW, .accessfn = access_el3_aa32ns,
185
- .type = ARM_CP_CONST, .resetvalue = cpu->midr,
186
- .fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) },
187
- { .name = "VMPIDR_EL2", .state = ARM_CP_STATE_BOTH,
188
- .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,
189
- .access = PL2_RW, .accessfn = access_el3_aa32ns,
190
- .type = ARM_CP_NO_RAW,
191
- .writefn = arm_cp_write_ignore, .readfn = mpidr_read },
192
- };
193
- define_arm_cp_regs(cpu, vpidr_regs);
194
- define_arm_cp_regs(cpu, el3_no_el2_cp_reginfo);
195
- if (arm_feature(env, ARM_FEATURE_V8)) {
196
- define_arm_cp_regs(cpu, el3_no_el2_v8_cp_reginfo);
197
- }
198
- }
199
}
200
+
201
+ /* Register the base EL3 cpregs. */
202
if (arm_feature(env, ARM_FEATURE_EL3)) {
203
define_arm_cp_regs(cpu, el3_cp_reginfo);
204
ARMCPRegInfo el3_regs[] = {
205
--
206
2.25.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
Drop zcr_no_el2_reginfo and merge the 3 registers into one array,
4
now that ZCR_EL2 can be squashed to RES0 and ZCR_EL3 dropped
5
while registering.
2
6
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190128223118.5255-9-richard.henderson@linaro.org
9
Message-id: 20220506180242.216785-4-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
target/arm/translate-a64.c | 37 ++++++++++++++++++++++++++++++++++++-
12
target/arm/helper.c | 55 ++++++++++++++-------------------------------
9
1 file changed, 36 insertions(+), 1 deletion(-)
13
1 file changed, 17 insertions(+), 38 deletions(-)
10
14
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
17
--- a/target/arm/helper.c
14
+++ b/target/arm/translate-a64.c
18
+++ b/target/arm/helper.c
15
@@ -XXX,XX +XXX,XX @@ static void reset_btype(DisasContext *s)
19
@@ -XXX,XX +XXX,XX @@ static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
16
}
20
}
17
}
21
}
18
22
19
+static void set_btype(DisasContext *s, int val)
23
-static const ARMCPRegInfo zcr_el1_reginfo = {
20
+{
24
- .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
21
+ TCGv_i32 tcg_val;
25
- .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
22
+
26
- .access = PL1_RW, .type = ARM_CP_SVE,
23
+ /* BTYPE is a 2-bit field, and 0 should be done with reset_btype. */
27
- .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
24
+ tcg_debug_assert(val >= 1 && val <= 3);
28
- .writefn = zcr_write, .raw_writefn = raw_write
25
+
29
-};
26
+ tcg_val = tcg_const_i32(val);
27
+ tcg_gen_st_i32(tcg_val, cpu_env, offsetof(CPUARMState, btype));
28
+ tcg_temp_free_i32(tcg_val);
29
+ s->btype = -1;
30
+}
31
+
32
void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
33
fprintf_function cpu_fprintf, int flags)
34
{
35
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
36
static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
37
{
38
unsigned int opc, op2, op3, rn, op4;
39
+ unsigned btype_mod = 2; /* 0: BR, 1: BLR, 2: other */
40
TCGv_i64 dst;
41
TCGv_i64 modifier;
42
43
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
44
case 0: /* BR */
45
case 1: /* BLR */
46
case 2: /* RET */
47
+ btype_mod = opc;
48
switch (op3) {
49
case 0:
50
/* BR, BLR, RET */
51
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
52
default:
53
goto do_unallocated;
54
}
55
-
30
-
56
gen_a64_set_pc(s, dst);
31
-static const ARMCPRegInfo zcr_el2_reginfo = {
57
/* BLR also needs to load return address */
32
- .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
58
if (opc == 1) {
33
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
59
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
34
- .access = PL2_RW, .type = ARM_CP_SVE,
60
if ((op3 & ~1) != 2) {
35
- .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
61
goto do_unallocated;
36
- .writefn = zcr_write, .raw_writefn = raw_write
62
}
37
-};
63
+ btype_mod = opc & 1;
38
-
64
if (s->pauth_active) {
39
-static const ARMCPRegInfo zcr_no_el2_reginfo = {
65
dst = new_tmp_a64(s);
40
- .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
66
modifier = cpu_reg_sp(s, op4);
41
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
67
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
42
- .access = PL2_RW, .type = ARM_CP_SVE,
68
return;
43
- .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore
44
-};
45
-
46
-static const ARMCPRegInfo zcr_el3_reginfo = {
47
- .name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
48
- .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
49
- .access = PL3_RW, .type = ARM_CP_SVE,
50
- .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
51
- .writefn = zcr_write, .raw_writefn = raw_write
52
+static const ARMCPRegInfo zcr_reginfo[] = {
53
+ { .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
54
+ .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
55
+ .access = PL1_RW, .type = ARM_CP_SVE,
56
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
57
+ .writefn = zcr_write, .raw_writefn = raw_write },
58
+ { .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
59
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
60
+ .access = PL2_RW, .type = ARM_CP_SVE,
61
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
62
+ .writefn = zcr_write, .raw_writefn = raw_write },
63
+ { .name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
64
+ .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
65
+ .access = PL3_RW, .type = ARM_CP_SVE,
66
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
67
+ .writefn = zcr_write, .raw_writefn = raw_write },
68
};
69
70
void hw_watchpoint_update(ARMCPU *cpu, int n)
71
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
69
}
72
}
70
73
71
+ switch (btype_mod) {
74
if (cpu_isar_feature(aa64_sve, cpu)) {
72
+ case 0: /* BR */
75
- define_one_arm_cp_reg(cpu, &zcr_el1_reginfo);
73
+ if (dc_isar_feature(aa64_bti, s)) {
76
- if (arm_feature(env, ARM_FEATURE_EL2)) {
74
+ /* BR to {x16,x17} or !guard -> 1, else 3. */
77
- define_one_arm_cp_reg(cpu, &zcr_el2_reginfo);
75
+ set_btype(s, rn == 16 || rn == 17 || !s->guarded_page ? 1 : 3);
78
- } else {
76
+ }
79
- define_one_arm_cp_reg(cpu, &zcr_no_el2_reginfo);
77
+ break;
80
- }
78
+
81
- if (arm_feature(env, ARM_FEATURE_EL3)) {
79
+ case 1: /* BLR */
82
- define_one_arm_cp_reg(cpu, &zcr_el3_reginfo);
80
+ if (dc_isar_feature(aa64_bti, s)) {
83
- }
81
+ /* BLR sets BTYPE to 2, regardless of source guarded page. */
84
+ define_arm_cp_regs(cpu, zcr_reginfo);
82
+ set_btype(s, 2);
85
}
83
+ }
86
84
+ break;
87
#ifdef TARGET_AARCH64
85
+
86
+ default: /* RET or none of the above. */
87
+ /* BTYPE will be set to 0 by normal end-of-insn processing. */
88
+ break;
89
+ }
90
+
91
s->base.is_jmp = DISAS_JUMP;
92
}
93
94
--
88
--
95
2.20.1
89
2.25.1
96
97
diff view generated by jsdifflib
1
The {IOE, DZE, OFE, UFE, IXE, IDE} bits in the FPSCR/FPCR are for
1
From: Richard Henderson <richard.henderson@linaro.org>
2
enabling trapped IEEE floating point exceptions (where IEEE exception
3
conditions cause a CPU exception rather than updating the FPSR status
4
bits). QEMU doesn't implement this (and nor does the hardware we're
5
modelling), but for implementations which don't implement trapped
6
exception handling these control bits are supposed to be RAZ/WI.
7
This allows guest code to test for whether the feature is present
8
by trying to write to the bit and checking whether it sticks.
9
2
10
QEMU is incorrectly making these bits read as written. Make them
3
This register is present for either VHE or Debugv8p2.
11
RAZ/WI as the architecture requires.
12
4
13
In particular this was causing problems for the NetBSD automatic
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
test suite.
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220506180242.216785-5-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/helper.c | 15 +++++++++++----
11
1 file changed, 11 insertions(+), 4 deletions(-)
15
12
16
Reported-by: Martin Husemann <martin@netbsd.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20190131130700.28392-1-peter.maydell@linaro.org
20
---
21
target/arm/cpu.h | 6 ++++++
22
target/arm/helper.c | 6 ++++++
23
2 files changed, 12 insertions(+)
24
25
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/cpu.h
28
+++ b/target/arm/cpu.h
29
@@ -XXX,XX +XXX,XX @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val);
30
#define FPSR_MASK 0xf800009f
31
#define FPCR_MASK 0x07ff9f00
32
33
+#define FPCR_IOE (1 << 8) /* Invalid Operation exception trap enable */
34
+#define FPCR_DZE (1 << 9) /* Divide by Zero exception trap enable */
35
+#define FPCR_OFE (1 << 10) /* Overflow exception trap enable */
36
+#define FPCR_UFE (1 << 11) /* Underflow exception trap enable */
37
+#define FPCR_IXE (1 << 12) /* Inexact exception trap enable */
38
+#define FPCR_IDE (1 << 15) /* Input Denormal exception trap enable */
39
#define FPCR_FZ16 (1 << 19) /* ARMv8.2+, FP16 flush-to-zero */
40
#define FPCR_FZ (1 << 24) /* Flush-to-zero enable bit */
41
#define FPCR_DN (1 << 25) /* Default NaN enable bit */
42
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
43
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/helper.c
15
--- a/target/arm/helper.c
45
+++ b/target/arm/helper.c
16
+++ b/target/arm/helper.c
46
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
17
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo jazelle_regs[] = {
47
val &= ~FPCR_FZ16;
18
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
19
};
20
21
+static const ARMCPRegInfo contextidr_el2 = {
22
+ .name = "CONTEXTIDR_EL2", .state = ARM_CP_STATE_AA64,
23
+ .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 1,
24
+ .access = PL2_RW,
25
+ .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[2])
26
+};
27
+
28
static const ARMCPRegInfo vhe_reginfo[] = {
29
- { .name = "CONTEXTIDR_EL2", .state = ARM_CP_STATE_AA64,
30
- .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 1,
31
- .access = PL2_RW,
32
- .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[2]) },
33
{ .name = "TTBR1_EL2", .state = ARM_CP_STATE_AA64,
34
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 1,
35
.access = PL2_RW, .writefn = vmsa_tcr_ttbr_el2_write,
36
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
37
define_one_arm_cp_reg(cpu, &ssbs_reginfo);
48
}
38
}
49
39
50
+ /*
40
+ if (cpu_isar_feature(aa64_vh, cpu) ||
51
+ * We don't implement trapped exception handling, so the
41
+ cpu_isar_feature(aa64_debugv8p2, cpu)) {
52
+ * trap enable bits are all RAZ/WI (not RES0!)
42
+ define_one_arm_cp_reg(cpu, &contextidr_el2);
53
+ */
43
+ }
54
+ val &= ~(FPCR_IDE | FPCR_IXE | FPCR_UFE | FPCR_OFE | FPCR_DZE | FPCR_IOE);
44
if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
55
+
45
define_arm_cp_regs(cpu, vhe_reginfo);
56
changed = env->vfp.xregs[ARM_VFP_FPSCR];
46
}
57
env->vfp.xregs[ARM_VFP_FPSCR] = (val & 0xffc8ffff);
58
env->vfp.vec_len = (val >> 16) & 7;
59
--
47
--
60
2.20.1
48
2.25.1
61
62
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The branch target exception for guarded pages has high priority,
3
Previously we were defining some of these in user-only mode,
4
and only 8 instructions are valid for that case. Perform this
4
but none of them are accessible from user-only, therefore
5
check before doing any other decode.
5
define them only in system mode.
6
6
7
Clear BTYPE after all insns that neither set BTYPE nor exit via
7
This will shortly be used from cpu_tcg.c also.
8
exception (DISAS_NORETURN).
9
10
Not yet handled are insns that exit via DISAS_NORETURN for some
11
other reason, like direct branches.
12
8
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20190128223118.5255-7-richard.henderson@linaro.org
11
Message-id: 20220506180242.216785-6-richard.henderson@linaro.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
13
---
18
target/arm/internals.h | 6 ++
14
target/arm/internals.h | 6 ++++
19
target/arm/translate.h | 9 ++-
15
target/arm/cpu64.c | 64 +++---------------------------------------
20
target/arm/translate-a64.c | 139 +++++++++++++++++++++++++++++++++++++
16
target/arm/cpu_tcg.c | 59 ++++++++++++++++++++++++++++++++++++++
21
3 files changed, 152 insertions(+), 2 deletions(-)
17
3 files changed, 69 insertions(+), 60 deletions(-)
22
18
23
diff --git a/target/arm/internals.h b/target/arm/internals.h
19
diff --git a/target/arm/internals.h b/target/arm/internals.h
24
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/internals.h
21
--- a/target/arm/internals.h
26
+++ b/target/arm/internals.h
22
+++ b/target/arm/internals.h
27
@@ -XXX,XX +XXX,XX @@ enum arm_exception_class {
23
@@ -XXX,XX +XXX,XX @@ int aarch64_fpu_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg);
28
EC_FPIDTRAP = 0x08,
24
int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg);
29
EC_PACTRAP = 0x09,
25
#endif
30
EC_CP14RRTTRAP = 0x0c,
26
31
+ EC_BTITRAP = 0x0d,
27
+#ifdef CONFIG_USER_ONLY
32
EC_ILLEGALSTATE = 0x0e,
28
+static inline void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu) { }
33
EC_AA32_SVC = 0x11,
29
+#else
34
EC_AA32_HVC = 0x12,
30
+void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu);
35
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_pactrap(void)
31
+#endif
36
return EC_PACTRAP << ARM_EL_EC_SHIFT;
32
+
33
#endif
34
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/cpu64.c
37
+++ b/target/arm/cpu64.c
38
@@ -XXX,XX +XXX,XX @@
39
#include "hvf_arm.h"
40
#include "qapi/visitor.h"
41
#include "hw/qdev-properties.h"
42
-#include "cpregs.h"
43
+#include "internals.h"
44
45
46
-#ifndef CONFIG_USER_ONLY
47
-static uint64_t a57_a53_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
48
-{
49
- ARMCPU *cpu = env_archcpu(env);
50
-
51
- /* Number of cores is in [25:24]; otherwise we RAZ */
52
- return (cpu->core_count - 1) << 24;
53
-}
54
-#endif
55
-
56
-static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = {
57
-#ifndef CONFIG_USER_ONLY
58
- { .name = "L2CTLR_EL1", .state = ARM_CP_STATE_AA64,
59
- .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 2,
60
- .access = PL1_RW, .readfn = a57_a53_l2ctlr_read,
61
- .writefn = arm_cp_write_ignore },
62
- { .name = "L2CTLR",
63
- .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 2,
64
- .access = PL1_RW, .readfn = a57_a53_l2ctlr_read,
65
- .writefn = arm_cp_write_ignore },
66
-#endif
67
- { .name = "L2ECTLR_EL1", .state = ARM_CP_STATE_AA64,
68
- .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 3,
69
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
70
- { .name = "L2ECTLR",
71
- .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 3,
72
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
73
- { .name = "L2ACTLR", .state = ARM_CP_STATE_BOTH,
74
- .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 0, .opc2 = 0,
75
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
76
- { .name = "CPUACTLR_EL1", .state = ARM_CP_STATE_AA64,
77
- .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 0,
78
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
79
- { .name = "CPUACTLR",
80
- .cp = 15, .opc1 = 0, .crm = 15,
81
- .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
82
- { .name = "CPUECTLR_EL1", .state = ARM_CP_STATE_AA64,
83
- .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 1,
84
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
85
- { .name = "CPUECTLR",
86
- .cp = 15, .opc1 = 1, .crm = 15,
87
- .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
88
- { .name = "CPUMERRSR_EL1", .state = ARM_CP_STATE_AA64,
89
- .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 2,
90
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
91
- { .name = "CPUMERRSR",
92
- .cp = 15, .opc1 = 2, .crm = 15,
93
- .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
94
- { .name = "L2MERRSR_EL1", .state = ARM_CP_STATE_AA64,
95
- .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 3,
96
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
97
- { .name = "L2MERRSR",
98
- .cp = 15, .opc1 = 3, .crm = 15,
99
- .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
100
-};
101
-
102
static void aarch64_a57_initfn(Object *obj)
103
{
104
ARMCPU *cpu = ARM_CPU(obj);
105
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
106
cpu->gic_num_lrs = 4;
107
cpu->gic_vpribits = 5;
108
cpu->gic_vprebits = 5;
109
- define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
110
+ define_cortex_a72_a57_a53_cp_reginfo(cpu);
37
}
111
}
38
112
39
+static inline uint32_t syn_btitrap(int btype)
113
static void aarch64_a53_initfn(Object *obj)
114
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
115
cpu->gic_num_lrs = 4;
116
cpu->gic_vpribits = 5;
117
cpu->gic_vprebits = 5;
118
- define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
119
+ define_cortex_a72_a57_a53_cp_reginfo(cpu);
120
}
121
122
static void aarch64_a72_initfn(Object *obj)
123
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
124
cpu->gic_num_lrs = 4;
125
cpu->gic_vpribits = 5;
126
cpu->gic_vprebits = 5;
127
- define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
128
+ define_cortex_a72_a57_a53_cp_reginfo(cpu);
129
}
130
131
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
132
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/target/arm/cpu_tcg.c
135
+++ b/target/arm/cpu_tcg.c
136
@@ -XXX,XX +XXX,XX @@
137
#endif
138
#include "cpregs.h"
139
140
+#ifndef CONFIG_USER_ONLY
141
+static uint64_t l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
40
+{
142
+{
41
+ return (EC_BTITRAP << ARM_EL_EC_SHIFT) | btype;
143
+ ARMCPU *cpu = env_archcpu(env);
144
+
145
+ /* Number of cores is in [25:24]; otherwise we RAZ */
146
+ return (cpu->core_count - 1) << 24;
42
+}
147
+}
43
+
148
+
44
static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
149
+static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = {
45
{
150
+ { .name = "L2CTLR_EL1", .state = ARM_CP_STATE_AA64,
46
return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
151
+ .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 2,
47
diff --git a/target/arm/translate.h b/target/arm/translate.h
152
+ .access = PL1_RW, .readfn = l2ctlr_read,
48
index XXXXXXX..XXXXXXX 100644
153
+ .writefn = arm_cp_write_ignore },
49
--- a/target/arm/translate.h
154
+ { .name = "L2CTLR",
50
+++ b/target/arm/translate.h
155
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 2,
51
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
156
+ .access = PL1_RW, .readfn = l2ctlr_read,
52
bool pauth_active;
157
+ .writefn = arm_cp_write_ignore },
53
/* True with v8.5-BTI and SCTLR_ELx.BT* set. */
158
+ { .name = "L2ECTLR_EL1", .state = ARM_CP_STATE_AA64,
54
bool bt;
159
+ .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 3,
55
- /* A copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI. */
160
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
56
- uint8_t btype;
161
+ { .name = "L2ECTLR",
57
+ /*
162
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 3,
58
+ * >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
163
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
59
+ * < 0, set by the current instruction.
164
+ { .name = "L2ACTLR", .state = ARM_CP_STATE_BOTH,
60
+ */
165
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 0, .opc2 = 0,
61
+ int8_t btype;
166
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
62
+ /* True if this page is guarded. */
167
+ { .name = "CPUACTLR_EL1", .state = ARM_CP_STATE_AA64,
63
+ bool guarded_page;
168
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 0,
64
/* Bottom two bits of XScale c15_cpar coprocessor access control reg */
169
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
65
int c15_cpar;
170
+ { .name = "CPUACTLR",
66
/* TCG op of the current insn_start. */
171
+ .cp = 15, .opc1 = 0, .crm = 15,
67
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
172
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
68
index XXXXXXX..XXXXXXX 100644
173
+ { .name = "CPUECTLR_EL1", .state = ARM_CP_STATE_AA64,
69
--- a/target/arm/translate-a64.c
174
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 1,
70
+++ b/target/arm/translate-a64.c
175
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
71
@@ -XXX,XX +XXX,XX @@ static inline int get_a64_user_mem_index(DisasContext *s)
176
+ { .name = "CPUECTLR",
72
return arm_to_core_mmu_idx(useridx);
177
+ .cp = 15, .opc1 = 1, .crm = 15,
73
}
178
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
74
179
+ { .name = "CPUMERRSR_EL1", .state = ARM_CP_STATE_AA64,
75
+static void reset_btype(DisasContext *s)
180
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 2,
181
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
182
+ { .name = "CPUMERRSR",
183
+ .cp = 15, .opc1 = 2, .crm = 15,
184
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
185
+ { .name = "L2MERRSR_EL1", .state = ARM_CP_STATE_AA64,
186
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 3,
187
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
188
+ { .name = "L2MERRSR",
189
+ .cp = 15, .opc1 = 3, .crm = 15,
190
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
191
+};
192
+
193
+void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu)
76
+{
194
+{
77
+ if (s->btype != 0) {
195
+ define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
78
+ TCGv_i32 zero = tcg_const_i32(0);
79
+ tcg_gen_st_i32(zero, cpu_env, offsetof(CPUARMState, btype));
80
+ tcg_temp_free_i32(zero);
81
+ s->btype = 0;
82
+ }
83
+}
196
+}
84
+
197
+#endif /* !CONFIG_USER_ONLY */
85
void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
198
+
86
fprintf_function cpu_fprintf, int flags)
199
/* CPU models. These are not needed for the AArch64 linux-user build. */
87
{
200
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
88
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn)
201
89
}
90
}
91
92
+/**
93
+ * is_guarded_page:
94
+ * @env: The cpu environment
95
+ * @s: The DisasContext
96
+ *
97
+ * Return true if the page is guarded.
98
+ */
99
+static bool is_guarded_page(CPUARMState *env, DisasContext *s)
100
+{
101
+#ifdef CONFIG_USER_ONLY
102
+ return false; /* FIXME */
103
+#else
104
+ uint64_t addr = s->base.pc_first;
105
+ int mmu_idx = arm_to_core_mmu_idx(s->mmu_idx);
106
+ unsigned int index = tlb_index(env, mmu_idx, addr);
107
+ CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
108
+
109
+ /*
110
+ * We test this immediately after reading an insn, which means
111
+ * that any normal page must be in the TLB. The only exception
112
+ * would be for executing from flash or device memory, which
113
+ * does not retain the TLB entry.
114
+ *
115
+ * FIXME: Assume false for those, for now. We could use
116
+ * arm_cpu_get_phys_page_attrs_debug to re-read the page
117
+ * table entry even for that case.
118
+ */
119
+ return (tlb_hit(entry->addr_code, addr) &&
120
+ env->iotlb[mmu_idx][index].attrs.target_tlb_bit0);
121
+#endif
122
+}
123
+
124
+/**
125
+ * btype_destination_ok:
126
+ * @insn: The instruction at the branch destination
127
+ * @bt: SCTLR_ELx.BT
128
+ * @btype: PSTATE.BTYPE, and is non-zero
129
+ *
130
+ * On a guarded page, there are a limited number of insns
131
+ * that may be present at the branch target:
132
+ * - branch target identifiers,
133
+ * - paciasp, pacibsp,
134
+ * - BRK insn
135
+ * - HLT insn
136
+ * Anything else causes a Branch Target Exception.
137
+ *
138
+ * Return true if the branch is compatible, false to raise BTITRAP.
139
+ */
140
+static bool btype_destination_ok(uint32_t insn, bool bt, int btype)
141
+{
142
+ if ((insn & 0xfffff01fu) == 0xd503201fu) {
143
+ /* HINT space */
144
+ switch (extract32(insn, 5, 7)) {
145
+ case 0b011001: /* PACIASP */
146
+ case 0b011011: /* PACIBSP */
147
+ /*
148
+ * If SCTLR_ELx.BT, then PACI*SP are not compatible
149
+ * with btype == 3. Otherwise all btype are ok.
150
+ */
151
+ return !bt || btype != 3;
152
+ case 0b100000: /* BTI */
153
+ /* Not compatible with any btype. */
154
+ return false;
155
+ case 0b100010: /* BTI c */
156
+ /* Not compatible with btype == 3 */
157
+ return btype != 3;
158
+ case 0b100100: /* BTI j */
159
+ /* Not compatible with btype == 2 */
160
+ return btype != 2;
161
+ case 0b100110: /* BTI jc */
162
+ /* Compatible with any btype. */
163
+ return true;
164
+ }
165
+ } else {
166
+ switch (insn & 0xffe0001fu) {
167
+ case 0xd4200000u: /* BRK */
168
+ case 0xd4400000u: /* HLT */
169
+ /* Give priority to the breakpoint exception. */
170
+ return true;
171
+ }
172
+ }
173
+ return false;
174
+}
175
+
176
/* C3.1 A64 instruction index by encoding */
177
static void disas_a64_insn(CPUARMState *env, DisasContext *s)
178
{
179
@@ -XXX,XX +XXX,XX @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
180
181
s->fp_access_checked = false;
182
183
+ if (dc_isar_feature(aa64_bti, s)) {
184
+ if (s->base.num_insns == 1) {
185
+ /*
186
+ * At the first insn of the TB, compute s->guarded_page.
187
+ * We delayed computing this until successfully reading
188
+ * the first insn of the TB, above. This (mostly) ensures
189
+ * that the softmmu tlb entry has been populated, and the
190
+ * page table GP bit is available.
191
+ *
192
+ * Note that we need to compute this even if btype == 0,
193
+ * because this value is used for BR instructions later
194
+ * where ENV is not available.
195
+ */
196
+ s->guarded_page = is_guarded_page(env, s);
197
+
198
+ /* First insn can have btype set to non-zero. */
199
+ tcg_debug_assert(s->btype >= 0);
200
+
201
+ /*
202
+ * Note that the Branch Target Exception has fairly high
203
+ * priority -- below debugging exceptions but above most
204
+ * everything else. This allows us to handle this now
205
+ * instead of waiting until the insn is otherwise decoded.
206
+ */
207
+ if (s->btype != 0
208
+ && s->guarded_page
209
+ && !btype_destination_ok(insn, s->bt, s->btype)) {
210
+ gen_exception_insn(s, 4, EXCP_UDEF, syn_btitrap(s->btype),
211
+ default_exception_el(s));
212
+ return;
213
+ }
214
+ } else {
215
+ /* Not the first insn: btype must be 0. */
216
+ tcg_debug_assert(s->btype == 0);
217
+ }
218
+ }
219
+
220
switch (extract32(insn, 25, 4)) {
221
case 0x0: case 0x1: case 0x3: /* UNALLOCATED */
222
unallocated_encoding(s);
223
@@ -XXX,XX +XXX,XX @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
224
225
/* if we allocated any temporaries, free them here */
226
free_tmp_a64(s);
227
+
228
+ /*
229
+ * After execution of most insns, btype is reset to 0.
230
+ * Note that we set btype == -1 when the insn sets btype.
231
+ */
232
+ if (s->btype > 0 && s->base.is_jmp != DISAS_NORETURN) {
233
+ reset_btype(s);
234
+ }
235
}
236
237
static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
238
--
202
--
239
2.20.1
203
2.25.1
240
241
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Instead of starting with cortex-a15 and adding v8 features to
4
a v7 cpu, begin with a v8 cpu stripped of its aarch64 features.
5
This fixes the long-standing to-do where we only enabled v8
6
features for user-only.
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20220506180242.216785-7-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/cpu_tcg.c | 151 ++++++++++++++++++++++++++-----------------
14
1 file changed, 92 insertions(+), 59 deletions(-)
15
16
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu_tcg.c
19
+++ b/target/arm/cpu_tcg.c
20
@@ -XXX,XX +XXX,XX @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
21
static void arm_max_initfn(Object *obj)
22
{
23
ARMCPU *cpu = ARM_CPU(obj);
24
+ uint32_t t;
25
26
- cortex_a15_initfn(obj);
27
+ /* aarch64_a57_initfn, advertising none of the aarch64 features */
28
+ cpu->dtb_compatible = "arm,cortex-a57";
29
+ set_feature(&cpu->env, ARM_FEATURE_V8);
30
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
31
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
32
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
33
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
34
+ set_feature(&cpu->env, ARM_FEATURE_EL3);
35
+ set_feature(&cpu->env, ARM_FEATURE_PMU);
36
+ cpu->midr = 0x411fd070;
37
+ cpu->revidr = 0x00000000;
38
+ cpu->reset_fpsid = 0x41034070;
39
+ cpu->isar.mvfr0 = 0x10110222;
40
+ cpu->isar.mvfr1 = 0x12111111;
41
+ cpu->isar.mvfr2 = 0x00000043;
42
+ cpu->ctr = 0x8444c004;
43
+ cpu->reset_sctlr = 0x00c50838;
44
+ cpu->isar.id_pfr0 = 0x00000131;
45
+ cpu->isar.id_pfr1 = 0x00011011;
46
+ cpu->isar.id_dfr0 = 0x03010066;
47
+ cpu->id_afr0 = 0x00000000;
48
+ cpu->isar.id_mmfr0 = 0x10101105;
49
+ cpu->isar.id_mmfr1 = 0x40000000;
50
+ cpu->isar.id_mmfr2 = 0x01260000;
51
+ cpu->isar.id_mmfr3 = 0x02102211;
52
+ cpu->isar.id_isar0 = 0x02101110;
53
+ cpu->isar.id_isar1 = 0x13112111;
54
+ cpu->isar.id_isar2 = 0x21232042;
55
+ cpu->isar.id_isar3 = 0x01112131;
56
+ cpu->isar.id_isar4 = 0x00011142;
57
+ cpu->isar.id_isar5 = 0x00011121;
58
+ cpu->isar.id_isar6 = 0;
59
+ cpu->isar.dbgdidr = 0x3516d000;
60
+ cpu->clidr = 0x0a200023;
61
+ cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
62
+ cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */
63
+ cpu->ccsidr[2] = 0x70ffe07a; /* 2048KB L2 cache */
64
+ define_cortex_a72_a57_a53_cp_reginfo(cpu);
65
66
- /* old-style VFP short-vector support */
67
- cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
68
+ /* Add additional features supported by QEMU */
69
+ t = cpu->isar.id_isar5;
70
+ t = FIELD_DP32(t, ID_ISAR5, AES, 2);
71
+ t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
72
+ t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
73
+ t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
74
+ t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
75
+ t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
76
+ cpu->isar.id_isar5 = t;
77
+
78
+ t = cpu->isar.id_isar6;
79
+ t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
80
+ t = FIELD_DP32(t, ID_ISAR6, DP, 1);
81
+ t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
82
+ t = FIELD_DP32(t, ID_ISAR6, SB, 1);
83
+ t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
84
+ t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
85
+ t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
86
+ cpu->isar.id_isar6 = t;
87
+
88
+ t = cpu->isar.mvfr1;
89
+ t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */
90
+ t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
91
+ cpu->isar.mvfr1 = t;
92
+
93
+ t = cpu->isar.mvfr2;
94
+ t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
95
+ t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
96
+ cpu->isar.mvfr2 = t;
97
+
98
+ t = cpu->isar.id_mmfr3;
99
+ t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
100
+ cpu->isar.id_mmfr3 = t;
101
+
102
+ t = cpu->isar.id_mmfr4;
103
+ t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
104
+ t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
105
+ t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
106
+ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
107
+ cpu->isar.id_mmfr4 = t;
108
+
109
+ t = cpu->isar.id_pfr0;
110
+ t = FIELD_DP32(t, ID_PFR0, DIT, 1);
111
+ cpu->isar.id_pfr0 = t;
112
+
113
+ t = cpu->isar.id_pfr2;
114
+ t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
115
+ cpu->isar.id_pfr2 = t;
116
117
#ifdef CONFIG_USER_ONLY
118
/*
119
- * We don't set these in system emulation mode for the moment,
120
- * since we don't correctly set (all of) the ID registers to
121
- * advertise them.
122
+ * Break with true ARMv8 and add back old-style VFP short-vector support.
123
+ * Only do this for user-mode, where -cpu max is the default, so that
124
+ * older v6 and v7 programs are more likely to work without adjustment.
125
*/
126
- set_feature(&cpu->env, ARM_FEATURE_V8);
127
- {
128
- uint32_t t;
129
-
130
- t = cpu->isar.id_isar5;
131
- t = FIELD_DP32(t, ID_ISAR5, AES, 2);
132
- t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
133
- t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
134
- t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
135
- t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
136
- t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
137
- cpu->isar.id_isar5 = t;
138
-
139
- t = cpu->isar.id_isar6;
140
- t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
141
- t = FIELD_DP32(t, ID_ISAR6, DP, 1);
142
- t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
143
- t = FIELD_DP32(t, ID_ISAR6, SB, 1);
144
- t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
145
- t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
146
- t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
147
- cpu->isar.id_isar6 = t;
148
-
149
- t = cpu->isar.mvfr1;
150
- t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */
151
- t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
152
- cpu->isar.mvfr1 = t;
153
-
154
- t = cpu->isar.mvfr2;
155
- t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
156
- t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
157
- cpu->isar.mvfr2 = t;
158
-
159
- t = cpu->isar.id_mmfr3;
160
- t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
161
- cpu->isar.id_mmfr3 = t;
162
-
163
- t = cpu->isar.id_mmfr4;
164
- t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
165
- t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
166
- t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
167
- t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
168
- cpu->isar.id_mmfr4 = t;
169
-
170
- t = cpu->isar.id_pfr0;
171
- t = FIELD_DP32(t, ID_PFR0, DIT, 1);
172
- cpu->isar.id_pfr0 = t;
173
-
174
- t = cpu->isar.id_pfr2;
175
- t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
176
- cpu->isar.id_pfr2 = t;
177
- }
178
-#endif /* CONFIG_USER_ONLY */
179
+ cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
180
+#endif
181
}
182
#endif /* !TARGET_AARCH64 */
183
184
--
185
2.25.1
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
We set this for qemu-system-aarch64, but failed to do so
4
for the strictly 32-bit emulation.
5
6
Fixes: 3bec78447a9 ("target/arm: Provide ARMv8.4-PMU in '-cpu max'")
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220506180242.216785-8-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu_tcg.c | 4 ++++
13
1 file changed, 4 insertions(+)
14
15
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu_tcg.c
18
+++ b/target/arm/cpu_tcg.c
19
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
20
t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
21
cpu->isar.id_pfr2 = t;
22
23
+ t = cpu->isar.id_dfr0;
24
+ t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
25
+ cpu->isar.id_dfr0 = t;
26
+
27
#ifdef CONFIG_USER_ONLY
28
/*
29
* Break with true ARMv8 and add back old-style VFP short-vector support.
30
--
31
2.25.1
diff view generated by jsdifflib
1
Enables, but does not turn on, TBI for CONFIG_USER_ONLY.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
Share the code to set AArch32 max features so that we no
4
longer have code drift between qemu{-system,}-{arm,aarch64}.
2
5
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190204132126.3255-4-richard.henderson@linaro.org
8
Message-id: 20220506180242.216785-9-richard.henderson@linaro.org
6
[PMM: adjusted #ifdeffery to placate clang, which otherwise complains
7
about static functions that are unused in the CONFIG_USER_ONLY build]
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/internals.h | 21 --------------------
11
target/arm/internals.h | 2 +
11
target/arm/helper.c | 45 ++++++++++++++++++++++--------------------
12
target/arm/cpu64.c | 50 +-----------------
12
2 files changed, 24 insertions(+), 42 deletions(-)
13
target/arm/cpu_tcg.c | 114 ++++++++++++++++++++++-------------------
14
3 files changed, 65 insertions(+), 101 deletions(-)
13
15
14
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/internals.h
18
--- a/target/arm/internals.h
17
+++ b/target/arm/internals.h
19
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
20
@@ -XXX,XX +XXX,XX @@ static inline void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu) { }
19
bool using64k : 1;
21
void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu);
20
} ARMVAParameters;
21
22
-#ifdef CONFIG_USER_ONLY
23
-static inline ARMVAParameters aa64_va_parameters_both(CPUARMState *env,
24
- uint64_t va,
25
- ARMMMUIdx mmu_idx)
26
-{
27
- return (ARMVAParameters) {
28
- /* 48-bit address space */
29
- .tsz = 16,
30
- /* We can't handle tagged addresses properly in user-only mode */
31
- .tbi = false,
32
- };
33
-}
34
-
35
-static inline ARMVAParameters aa64_va_parameters(CPUARMState *env,
36
- uint64_t va,
37
- ARMMMUIdx mmu_idx, bool data)
38
-{
39
- return aa64_va_parameters_both(env, va, mmu_idx);
40
-}
41
-#else
42
ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
43
ARMMMUIdx mmu_idx);
44
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
45
ARMMMUIdx mmu_idx, bool data);
46
-#endif
47
48
#endif
22
#endif
49
diff --git a/target/arm/helper.c b/target/arm/helper.c
23
24
+void aa32_max_features(ARMCPU *cpu);
25
+
26
#endif
27
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
50
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/helper.c
29
--- a/target/arm/cpu64.c
52
+++ b/target/arm/helper.c
30
+++ b/target/arm/cpu64.c
53
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(rbit)(uint32_t x)
31
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
54
return revbit32(x);
55
}
56
57
-#if defined(CONFIG_USER_ONLY)
58
+#ifdef CONFIG_USER_ONLY
59
60
/* These should probably raise undefined insn exceptions. */
61
void HELPER(v7m_msr)(CPUARMState *env, uint32_t reg, uint32_t val)
62
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_interrupt(CPUState *cs)
63
cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
64
}
65
}
66
+#endif /* !CONFIG_USER_ONLY */
67
68
/* Return the exception level which controls this address translation regime */
69
static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
70
@@ -XXX,XX +XXX,XX @@ static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
71
}
72
}
73
74
+#ifndef CONFIG_USER_ONLY
75
+
76
/* Return the SCTLR value which controls this address translation regime */
77
static inline uint32_t regime_sctlr(CPUARMState *env, ARMMMUIdx mmu_idx)
78
{
32
{
79
@@ -XXX,XX +XXX,XX @@ static inline bool regime_translation_big_endian(CPUARMState *env,
33
ARMCPU *cpu = ARM_CPU(obj);
80
return (regime_sctlr(env, mmu_idx) & SCTLR_EE) != 0;
34
uint64_t t;
81
}
35
- uint32_t u;
82
36
83
+/* Return the TTBR associated with this translation regime */
37
if (kvm_enabled() || hvf_enabled()) {
84
+static inline uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx,
38
/* With KVM or HVF, '-cpu max' is identical to '-cpu host' */
85
+ int ttbrn)
39
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
40
t = FIELD_DP64(t, ID_AA64ZFR0, F64MM, 1);
41
cpu->isar.id_aa64zfr0 = t;
42
43
- /* Replicate the same data to the 32-bit id registers. */
44
- u = cpu->isar.id_isar5;
45
- u = FIELD_DP32(u, ID_ISAR5, AES, 2); /* AES + PMULL */
46
- u = FIELD_DP32(u, ID_ISAR5, SHA1, 1);
47
- u = FIELD_DP32(u, ID_ISAR5, SHA2, 1);
48
- u = FIELD_DP32(u, ID_ISAR5, CRC32, 1);
49
- u = FIELD_DP32(u, ID_ISAR5, RDM, 1);
50
- u = FIELD_DP32(u, ID_ISAR5, VCMA, 1);
51
- cpu->isar.id_isar5 = u;
52
-
53
- u = cpu->isar.id_isar6;
54
- u = FIELD_DP32(u, ID_ISAR6, JSCVT, 1);
55
- u = FIELD_DP32(u, ID_ISAR6, DP, 1);
56
- u = FIELD_DP32(u, ID_ISAR6, FHM, 1);
57
- u = FIELD_DP32(u, ID_ISAR6, SB, 1);
58
- u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1);
59
- u = FIELD_DP32(u, ID_ISAR6, BF16, 1);
60
- u = FIELD_DP32(u, ID_ISAR6, I8MM, 1);
61
- cpu->isar.id_isar6 = u;
62
-
63
- u = cpu->isar.id_pfr0;
64
- u = FIELD_DP32(u, ID_PFR0, DIT, 1);
65
- cpu->isar.id_pfr0 = u;
66
-
67
- u = cpu->isar.id_pfr2;
68
- u = FIELD_DP32(u, ID_PFR2, SSBS, 1);
69
- cpu->isar.id_pfr2 = u;
70
-
71
- u = cpu->isar.id_mmfr3;
72
- u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */
73
- cpu->isar.id_mmfr3 = u;
74
-
75
- u = cpu->isar.id_mmfr4;
76
- u = FIELD_DP32(u, ID_MMFR4, HPDS, 1); /* AA32HPD */
77
- u = FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
78
- u = FIELD_DP32(u, ID_MMFR4, CNP, 1); /* TTCNP */
79
- u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
80
- cpu->isar.id_mmfr4 = u;
81
-
82
t = cpu->isar.id_aa64dfr0;
83
t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
84
cpu->isar.id_aa64dfr0 = t;
85
86
- u = cpu->isar.id_dfr0;
87
- u = FIELD_DP32(u, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
88
- cpu->isar.id_dfr0 = u;
89
-
90
- u = cpu->isar.mvfr1;
91
- u = FIELD_DP32(u, MVFR1, FPHP, 3); /* v8.2-FP16 */
92
- u = FIELD_DP32(u, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
93
- cpu->isar.mvfr1 = u;
94
+ /* Replicate the same data to the 32-bit id registers. */
95
+ aa32_max_features(cpu);
96
97
#ifdef CONFIG_USER_ONLY
98
/*
99
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/target/arm/cpu_tcg.c
102
+++ b/target/arm/cpu_tcg.c
103
@@ -XXX,XX +XXX,XX @@
104
#endif
105
#include "cpregs.h"
106
107
+
108
+/* Share AArch32 -cpu max features with AArch64. */
109
+void aa32_max_features(ARMCPU *cpu)
86
+{
110
+{
87
+ if (mmu_idx == ARMMMUIdx_S2NS) {
111
+ uint32_t t;
88
+ return env->cp15.vttbr_el2;
112
+
89
+ }
113
+ /* Add additional features supported by QEMU */
90
+ if (ttbrn == 0) {
114
+ t = cpu->isar.id_isar5;
91
+ return env->cp15.ttbr0_el[regime_el(env, mmu_idx)];
115
+ t = FIELD_DP32(t, ID_ISAR5, AES, 2);
92
+ } else {
116
+ t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
93
+ return env->cp15.ttbr1_el[regime_el(env, mmu_idx)];
117
+ t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
94
+ }
118
+ t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
119
+ t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
120
+ t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
121
+ cpu->isar.id_isar5 = t;
122
+
123
+ t = cpu->isar.id_isar6;
124
+ t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
125
+ t = FIELD_DP32(t, ID_ISAR6, DP, 1);
126
+ t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
127
+ t = FIELD_DP32(t, ID_ISAR6, SB, 1);
128
+ t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
129
+ t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
130
+ t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
131
+ cpu->isar.id_isar6 = t;
132
+
133
+ t = cpu->isar.mvfr1;
134
+ t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */
135
+ t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
136
+ cpu->isar.mvfr1 = t;
137
+
138
+ t = cpu->isar.mvfr2;
139
+ t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
140
+ t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
141
+ cpu->isar.mvfr2 = t;
142
+
143
+ t = cpu->isar.id_mmfr3;
144
+ t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
145
+ cpu->isar.id_mmfr3 = t;
146
+
147
+ t = cpu->isar.id_mmfr4;
148
+ t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
149
+ t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
150
+ t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
151
+ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
152
+ cpu->isar.id_mmfr4 = t;
153
+
154
+ t = cpu->isar.id_pfr0;
155
+ t = FIELD_DP32(t, ID_PFR0, DIT, 1);
156
+ cpu->isar.id_pfr0 = t;
157
+
158
+ t = cpu->isar.id_pfr2;
159
+ t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
160
+ cpu->isar.id_pfr2 = t;
161
+
162
+ t = cpu->isar.id_dfr0;
163
+ t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
164
+ cpu->isar.id_dfr0 = t;
95
+}
165
+}
96
+
166
+
97
+#endif /* !CONFIG_USER_ONLY */
167
#ifndef CONFIG_USER_ONLY
98
+
168
static uint64_t l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
99
/* Return the TCR controlling this translation regime */
100
static inline TCR *regime_tcr(CPUARMState *env, ARMMMUIdx mmu_idx)
101
{
169
{
102
@@ -XXX,XX +XXX,XX @@ static inline ARMMMUIdx stage_1_mmu_idx(ARMMMUIdx mmu_idx)
170
@@ -XXX,XX +XXX,XX @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
103
return mmu_idx;
171
static void arm_max_initfn(Object *obj)
104
}
105
106
-/* Return the TTBR associated with this translation regime */
107
-static inline uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx,
108
- int ttbrn)
109
-{
110
- if (mmu_idx == ARMMMUIdx_S2NS) {
111
- return env->cp15.vttbr_el2;
112
- }
113
- if (ttbrn == 0) {
114
- return env->cp15.ttbr0_el[regime_el(env, mmu_idx)];
115
- } else {
116
- return env->cp15.ttbr1_el[regime_el(env, mmu_idx)];
117
- }
118
-}
119
-
120
/* Return true if the translation regime is using LPAE format page tables */
121
static inline bool regime_using_lpae_format(CPUARMState *env,
122
ARMMMUIdx mmu_idx)
123
@@ -XXX,XX +XXX,XX @@ bool arm_s1_regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx)
124
return regime_using_lpae_format(env, mmu_idx);
125
}
126
127
+#ifndef CONFIG_USER_ONLY
128
static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
129
{
172
{
130
switch (mmu_idx) {
173
ARMCPU *cpu = ARM_CPU(obj);
131
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
174
- uint32_t t;
132
175
133
return (hiattr << 6) | (hihint << 4) | (loattr << 2) | lohint;
176
/* aarch64_a57_initfn, advertising none of the aarch64 features */
134
}
177
cpu->dtb_compatible = "arm,cortex-a57";
135
+#endif /* !CONFIG_USER_ONLY */
178
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
136
179
cpu->ccsidr[2] = 0x70ffe07a; /* 2048KB L2 cache */
137
ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
180
define_cortex_a72_a57_a53_cp_reginfo(cpu);
138
ARMMMUIdx mmu_idx)
181
139
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
182
- /* Add additional features supported by QEMU */
140
return ret;
183
- t = cpu->isar.id_isar5;
141
}
184
- t = FIELD_DP32(t, ID_ISAR5, AES, 2);
142
185
- t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
143
+#ifndef CONFIG_USER_ONLY
186
- t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
144
static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
187
- t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
145
ARMMMUIdx mmu_idx)
188
- t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
146
{
189
- t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
147
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
190
- cpu->isar.id_isar5 = t;
148
*pc = env->pc;
191
-
149
flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
192
- t = cpu->isar.id_isar6;
150
193
- t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
151
-#ifndef CONFIG_USER_ONLY
194
- t = FIELD_DP32(t, ID_ISAR6, DP, 1);
152
- /*
195
- t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
153
- * Get control bits for tagged addresses. Note that the
196
- t = FIELD_DP32(t, ID_ISAR6, SB, 1);
154
- * translator only uses this for instruction addresses.
197
- t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
155
- */
198
- t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
156
+ /* Get control bits for tagged addresses. */
199
- t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
157
{
200
- cpu->isar.id_isar6 = t;
158
ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
201
-
159
ARMVAParameters p0 = aa64_va_parameters_both(env, 0, stage1);
202
- t = cpu->isar.mvfr1;
160
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
203
- t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */
161
flags = FIELD_DP32(flags, TBFLAG_A64, TBII, tbii);
204
- t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
162
flags = FIELD_DP32(flags, TBFLAG_A64, TBID, tbid);
205
- cpu->isar.mvfr1 = t;
163
}
206
-
164
-#endif
207
- t = cpu->isar.mvfr2;
165
208
- t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
166
if (cpu_isar_feature(aa64_sve, cpu)) {
209
- t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
167
int sve_el = sve_exception_el(env, current_el);
210
- cpu->isar.mvfr2 = t;
211
-
212
- t = cpu->isar.id_mmfr3;
213
- t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
214
- cpu->isar.id_mmfr3 = t;
215
-
216
- t = cpu->isar.id_mmfr4;
217
- t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
218
- t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
219
- t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
220
- t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
221
- cpu->isar.id_mmfr4 = t;
222
-
223
- t = cpu->isar.id_pfr0;
224
- t = FIELD_DP32(t, ID_PFR0, DIT, 1);
225
- cpu->isar.id_pfr0 = t;
226
-
227
- t = cpu->isar.id_pfr2;
228
- t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
229
- cpu->isar.id_pfr2 = t;
230
-
231
- t = cpu->isar.id_dfr0;
232
- t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
233
- cpu->isar.id_dfr0 = t;
234
+ aa32_max_features(cpu);
235
236
#ifdef CONFIG_USER_ONLY
237
/*
168
--
238
--
169
2.20.1
239
2.25.1
170
171
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
Update the legacy feature names to the current names.
4
Provide feature names for id changes that were not marked.
5
Sort the field updates into increasing bitfield order.
2
6
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190128223118.5255-11-richard.henderson@linaro.org
9
Message-id: 20220506180242.216785-10-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
target/arm/cpu64.c | 4 ++++
12
target/arm/cpu64.c | 100 +++++++++++++++++++++----------------------
9
1 file changed, 4 insertions(+)
13
target/arm/cpu_tcg.c | 48 ++++++++++-----------
14
2 files changed, 74 insertions(+), 74 deletions(-)
10
15
11
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
16
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu64.c
18
--- a/target/arm/cpu64.c
14
+++ b/target/arm/cpu64.c
19
+++ b/target/arm/cpu64.c
15
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
20
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
16
t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1);
21
cpu->midr = t;
17
cpu->isar.id_aa64pfr0 = t;
22
18
23
t = cpu->isar.id_aa64isar0;
19
+ t = cpu->isar.id_aa64pfr1;
24
- t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* AES + PMULL */
20
+ t = FIELD_DP64(t, ID_AA64PFR1, BT, 1);
25
- t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1);
21
+ cpu->isar.id_aa64pfr1 = t;
26
- t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* SHA512 */
22
+
27
+ t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* FEAT_PMULL */
23
t = cpu->isar.id_aa64mmfr1;
28
+ t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1); /* FEAT_SHA1 */
24
t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */
29
+ t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* FEAT_SHA512 */
25
t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1);
30
t = FIELD_DP64(t, ID_AA64ISAR0, CRC32, 1);
31
- t = FIELD_DP64(t, ID_AA64ISAR0, ATOMIC, 2);
32
- t = FIELD_DP64(t, ID_AA64ISAR0, RDM, 1);
33
- t = FIELD_DP64(t, ID_AA64ISAR0, SHA3, 1);
34
- t = FIELD_DP64(t, ID_AA64ISAR0, SM3, 1);
35
- t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 1);
36
- t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
37
- t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1);
38
- t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* v8.5-CondM */
39
- t = FIELD_DP64(t, ID_AA64ISAR0, TLB, 2); /* FEAT_TLBIRANGE */
40
- t = FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1);
41
+ t = FIELD_DP64(t, ID_AA64ISAR0, ATOMIC, 2); /* FEAT_LSE */
42
+ t = FIELD_DP64(t, ID_AA64ISAR0, RDM, 1); /* FEAT_RDM */
43
+ t = FIELD_DP64(t, ID_AA64ISAR0, SHA3, 1); /* FEAT_SHA3 */
44
+ t = FIELD_DP64(t, ID_AA64ISAR0, SM3, 1); /* FEAT_SM3 */
45
+ t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 1); /* FEAT_SM4 */
46
+ t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1); /* FEAT_DotProd */
47
+ t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1); /* FEAT_FHM */
48
+ t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* FEAT_FlagM2 */
49
+ t = FIELD_DP64(t, ID_AA64ISAR0, TLB, 2); /* FEAT_TLBIRANGE */
50
+ t = FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1); /* FEAT_RNG */
51
cpu->isar.id_aa64isar0 = t;
52
53
t = cpu->isar.id_aa64isar1;
54
- t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2);
55
- t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1);
56
- t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
57
- t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
58
- t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
59
- t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 1);
60
- t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1);
61
- t = FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 2); /* ARMv8.4-RCPC */
62
- t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1);
63
+ t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2); /* FEAT_DPB2 */
64
+ t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1); /* FEAT_JSCVT */
65
+ t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1); /* FEAT_FCMA */
66
+ t = FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 2); /* FEAT_LRCPC2 */
67
+ t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1); /* FEAT_FRINTTS */
68
+ t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1); /* FEAT_SB */
69
+ t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1); /* FEAT_SPECRES */
70
+ t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 1); /* FEAT_BF16 */
71
+ t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1); /* FEAT_I8MM */
72
cpu->isar.id_aa64isar1 = t;
73
74
t = cpu->isar.id_aa64pfr0;
75
+ t = FIELD_DP64(t, ID_AA64PFR0, FP, 1); /* FEAT_FP16 */
76
+ t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1); /* FEAT_FP16 */
77
t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
78
- t = FIELD_DP64(t, ID_AA64PFR0, FP, 1);
79
- t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1);
80
- t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1);
81
- t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1);
82
+ t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); /* FEAT_SEL2 */
83
+ t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
84
cpu->isar.id_aa64pfr0 = t;
85
86
t = cpu->isar.id_aa64pfr1;
87
- t = FIELD_DP64(t, ID_AA64PFR1, BT, 1);
88
- t = FIELD_DP64(t, ID_AA64PFR1, SSBS, 2);
89
+ t = FIELD_DP64(t, ID_AA64PFR1, BT, 1); /* FEAT_BTI */
90
+ t = FIELD_DP64(t, ID_AA64PFR1, SSBS, 2); /* FEAT_SSBS2 */
91
/*
92
* Begin with full support for MTE. This will be downgraded to MTE=0
93
* during realize if the board provides no tag memory, much like
94
* we do for EL2 with the virtualization=on property.
95
*/
96
- t = FIELD_DP64(t, ID_AA64PFR1, MTE, 3);
97
+ t = FIELD_DP64(t, ID_AA64PFR1, MTE, 3); /* FEAT_MTE3 */
98
cpu->isar.id_aa64pfr1 = t;
99
100
t = cpu->isar.id_aa64mmfr0;
101
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
102
cpu->isar.id_aa64mmfr0 = t;
103
104
t = cpu->isar.id_aa64mmfr1;
105
- t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */
106
- t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1);
107
- t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1);
108
- t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */
109
- t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */
110
- t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* TTS2UXN */
111
+ t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* FEAT_VMID16 */
112
+ t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); /* FEAT_VHE */
113
+ t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* FEAT_HPDS */
114
+ t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1); /* FEAT_LOR */
115
+ t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* FEAT_PAN2 */
116
+ t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* FEAT_XNX */
117
cpu->isar.id_aa64mmfr1 = t;
118
119
t = cpu->isar.id_aa64mmfr2;
120
- t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1);
121
- t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* TTCNP */
122
- t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* TTST */
123
- t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1); /* FEAT_LVA */
124
- t = FIELD_DP64(t, ID_AA64MMFR2, TTL, 1); /* FEAT_TTL */
125
- t = FIELD_DP64(t, ID_AA64MMFR2, BBM, 2); /* FEAT_BBM at level 2 */
126
+ t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* FEAT_TTCNP */
127
+ t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1); /* FEAT_UAO */
128
+ t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1); /* FEAT_LVA */
129
+ t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* FEAT_TTST */
130
+ t = FIELD_DP64(t, ID_AA64MMFR2, TTL, 1); /* FEAT_TTL */
131
+ t = FIELD_DP64(t, ID_AA64MMFR2, BBM, 2); /* FEAT_BBM at level 2 */
132
cpu->isar.id_aa64mmfr2 = t;
133
134
t = cpu->isar.id_aa64zfr0;
135
t = FIELD_DP64(t, ID_AA64ZFR0, SVEVER, 1);
136
- t = FIELD_DP64(t, ID_AA64ZFR0, AES, 2); /* PMULL */
137
- t = FIELD_DP64(t, ID_AA64ZFR0, BITPERM, 1);
138
- t = FIELD_DP64(t, ID_AA64ZFR0, BFLOAT16, 1);
139
- t = FIELD_DP64(t, ID_AA64ZFR0, SHA3, 1);
140
- t = FIELD_DP64(t, ID_AA64ZFR0, SM4, 1);
141
- t = FIELD_DP64(t, ID_AA64ZFR0, I8MM, 1);
142
- t = FIELD_DP64(t, ID_AA64ZFR0, F32MM, 1);
143
- t = FIELD_DP64(t, ID_AA64ZFR0, F64MM, 1);
144
+ t = FIELD_DP64(t, ID_AA64ZFR0, AES, 2); /* FEAT_SVE_PMULL128 */
145
+ t = FIELD_DP64(t, ID_AA64ZFR0, BITPERM, 1); /* FEAT_SVE_BitPerm */
146
+ t = FIELD_DP64(t, ID_AA64ZFR0, BFLOAT16, 1); /* FEAT_BF16 */
147
+ t = FIELD_DP64(t, ID_AA64ZFR0, SHA3, 1); /* FEAT_SVE_SHA3 */
148
+ t = FIELD_DP64(t, ID_AA64ZFR0, SM4, 1); /* FEAT_SVE_SM4 */
149
+ t = FIELD_DP64(t, ID_AA64ZFR0, I8MM, 1); /* FEAT_I8MM */
150
+ t = FIELD_DP64(t, ID_AA64ZFR0, F32MM, 1); /* FEAT_F32MM */
151
+ t = FIELD_DP64(t, ID_AA64ZFR0, F64MM, 1); /* FEAT_F64MM */
152
cpu->isar.id_aa64zfr0 = t;
153
154
t = cpu->isar.id_aa64dfr0;
155
- t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
156
+ t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* FEAT_PMUv3p4 */
157
cpu->isar.id_aa64dfr0 = t;
158
159
/* Replicate the same data to the 32-bit id registers. */
160
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
161
index XXXXXXX..XXXXXXX 100644
162
--- a/target/arm/cpu_tcg.c
163
+++ b/target/arm/cpu_tcg.c
164
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
165
166
/* Add additional features supported by QEMU */
167
t = cpu->isar.id_isar5;
168
- t = FIELD_DP32(t, ID_ISAR5, AES, 2);
169
- t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
170
- t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
171
+ t = FIELD_DP32(t, ID_ISAR5, AES, 2); /* FEAT_PMULL */
172
+ t = FIELD_DP32(t, ID_ISAR5, SHA1, 1); /* FEAT_SHA1 */
173
+ t = FIELD_DP32(t, ID_ISAR5, SHA2, 1); /* FEAT_SHA256 */
174
t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
175
- t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
176
- t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
177
+ t = FIELD_DP32(t, ID_ISAR5, RDM, 1); /* FEAT_RDM */
178
+ t = FIELD_DP32(t, ID_ISAR5, VCMA, 1); /* FEAT_FCMA */
179
cpu->isar.id_isar5 = t;
180
181
t = cpu->isar.id_isar6;
182
- t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
183
- t = FIELD_DP32(t, ID_ISAR6, DP, 1);
184
- t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
185
- t = FIELD_DP32(t, ID_ISAR6, SB, 1);
186
- t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
187
- t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
188
- t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
189
+ t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1); /* FEAT_JSCVT */
190
+ t = FIELD_DP32(t, ID_ISAR6, DP, 1); /* Feat_DotProd */
191
+ t = FIELD_DP32(t, ID_ISAR6, FHM, 1); /* FEAT_FHM */
192
+ t = FIELD_DP32(t, ID_ISAR6, SB, 1); /* FEAT_SB */
193
+ t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1); /* FEAT_SPECRES */
194
+ t = FIELD_DP32(t, ID_ISAR6, BF16, 1); /* FEAT_AA32BF16 */
195
+ t = FIELD_DP32(t, ID_ISAR6, I8MM, 1); /* FEAT_AA32I8MM */
196
cpu->isar.id_isar6 = t;
197
198
t = cpu->isar.mvfr1;
199
- t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */
200
- t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
201
+ t = FIELD_DP32(t, MVFR1, FPHP, 3); /* FEAT_FP16 */
202
+ t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* FEAT_FP16 */
203
cpu->isar.mvfr1 = t;
204
205
t = cpu->isar.mvfr2;
206
- t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
207
- t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
208
+ t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
209
+ t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
210
cpu->isar.mvfr2 = t;
211
212
t = cpu->isar.id_mmfr3;
213
- t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
214
+ t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* FEAT_PAN2 */
215
cpu->isar.id_mmfr3 = t;
216
217
t = cpu->isar.id_mmfr4;
218
- t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
219
- t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
220
- t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
221
- t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
222
+ t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* FEAT_AA32HPD */
223
+ t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
224
+ t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* FEAT_TTCNP */
225
+ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* FEAT_XNX*/
226
cpu->isar.id_mmfr4 = t;
227
228
t = cpu->isar.id_pfr0;
229
- t = FIELD_DP32(t, ID_PFR0, DIT, 1);
230
+ t = FIELD_DP32(t, ID_PFR0, DIT, 1); /* FEAT_DIT */
231
cpu->isar.id_pfr0 = t;
232
233
t = cpu->isar.id_pfr2;
234
- t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
235
+ t = FIELD_DP32(t, ID_PFR2, SSBS, 1); /* FEAT_SSBS */
236
cpu->isar.id_pfr2 = t;
237
238
t = cpu->isar.id_dfr0;
239
- t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
240
+ t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* FEAT_PMUv3p4 */
241
cpu->isar.id_dfr0 = t;
242
}
243
26
--
244
--
27
2.20.1
245
2.25.1
28
29
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This has been enabled in the linux kernel since v3.11
3
Use FIELD_DP{32,64} to manipulate id_pfr1 and id_aa64pfr0
4
(commit d50240a5f6cea, 2013-09-03,
4
during arm_cpu_realizefn.
5
"arm64: mm: permit use of tagged pointers at EL0").
6
5
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190204132126.3255-5-richard.henderson@linaro.org
8
Message-id: 20220506180242.216785-11-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
target/arm/cpu.c | 6 ++++++
11
target/arm/cpu.c | 22 +++++++++++++---------
13
1 file changed, 6 insertions(+)
12
1 file changed, 13 insertions(+), 9 deletions(-)
14
13
15
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.c
16
--- a/target/arm/cpu.c
18
+++ b/target/arm/cpu.c
17
+++ b/target/arm/cpu.c
19
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
18
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
20
env->vfp.zcr_el[1] = cpu->sve_max_vq - 1;
19
*/
21
env->vfp.zcr_el[2] = env->vfp.zcr_el[1];
20
unset_feature(env, ARM_FEATURE_EL3);
22
env->vfp.zcr_el[3] = env->vfp.zcr_el[1];
21
22
- /* Disable the security extension feature bits in the processor feature
23
- * registers as well. These are id_pfr1[7:4] and id_aa64pfr0[15:12].
23
+ /*
24
+ /*
24
+ * Enable TBI0 and TBI1. While the real kernel only enables TBI0,
25
+ * Disable the security extension feature bits in the processor
25
+ * turning on both here will produce smaller code and otherwise
26
+ * feature registers as well.
26
+ * make no difference to the user-level emulation.
27
*/
27
+ */
28
- cpu->isar.id_pfr1 &= ~0xf0;
28
+ env->cp15.tcr_el[1].raw_tcr = (3ULL << 37);
29
- cpu->isar.id_aa64pfr0 &= ~0xf000;
29
#else
30
+ cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1, ID_PFR1, SECURITY, 0);
30
/* Reset into the highest available EL */
31
+ cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
31
if (arm_feature(env, ARM_FEATURE_EL3)) {
32
+ ID_AA64PFR0, EL3, 0);
33
}
34
35
if (!cpu->has_el2) {
36
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
37
}
38
39
if (!arm_feature(env, ARM_FEATURE_EL2)) {
40
- /* Disable the hypervisor feature bits in the processor feature
41
- * registers if we don't have EL2. These are id_pfr1[15:12] and
42
- * id_aa64pfr0_el1[11:8].
43
+ /*
44
+ * Disable the hypervisor feature bits in the processor feature
45
+ * registers if we don't have EL2.
46
*/
47
- cpu->isar.id_aa64pfr0 &= ~0xf00;
48
- cpu->isar.id_pfr1 &= ~0xf000;
49
+ cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
50
+ ID_AA64PFR0, EL2, 0);
51
+ cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1,
52
+ ID_PFR1, VIRTUALIZATION, 0);
53
}
54
55
#ifndef CONFIG_USER_ONLY
32
--
56
--
33
2.20.1
57
2.25.1
34
35
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
The only portion of FEAT_Debugv8p2 that is relevant to QEMU
4
is CONTEXTIDR_EL2, which is also conditionally implemented
5
with FEAT_VHE. The rest of the debug extension concerns the
6
External debug interface, which is outside the scope of QEMU.
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20220506180242.216785-12-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
docs/system/arm/emulation.rst | 1 +
14
target/arm/cpu.c | 1 +
15
target/arm/cpu64.c | 1 +
16
target/arm/cpu_tcg.c | 2 ++
17
4 files changed, 5 insertions(+)
18
19
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
20
index XXXXXXX..XXXXXXX 100644
21
--- a/docs/system/arm/emulation.rst
22
+++ b/docs/system/arm/emulation.rst
23
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
24
- FEAT_BTI (Branch Target Identification)
25
- FEAT_DIT (Data Independent Timing instructions)
26
- FEAT_DPB (DC CVAP instruction)
27
+- FEAT_Debugv8p2 (Debug changes for v8.2)
28
- FEAT_DotProd (Advanced SIMD dot product instructions)
29
- FEAT_FCMA (Floating-point complex number instructions)
30
- FEAT_FHM (Floating-point half-precision multiplication instructions)
31
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/cpu.c
34
+++ b/target/arm/cpu.c
35
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
36
* feature registers as well.
37
*/
38
cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1, ID_PFR1, SECURITY, 0);
39
+ cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPSDBG, 0);
40
cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
41
ID_AA64PFR0, EL3, 0);
42
}
43
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/cpu64.c
46
+++ b/target/arm/cpu64.c
47
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
48
cpu->isar.id_aa64zfr0 = t;
49
50
t = cpu->isar.id_aa64dfr0;
51
+ t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 8); /* FEAT_Debugv8p2 */
52
t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* FEAT_PMUv3p4 */
53
cpu->isar.id_aa64dfr0 = t;
54
55
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/arm/cpu_tcg.c
58
+++ b/target/arm/cpu_tcg.c
59
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
60
cpu->isar.id_pfr2 = t;
61
62
t = cpu->isar.id_dfr0;
63
+ t = FIELD_DP32(t, ID_DFR0, COPDBG, 8); /* FEAT_Debugv8p2 */
64
+ t = FIELD_DP32(t, ID_DFR0, COPSDBG, 8); /* FEAT_Debugv8p2 */
65
t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* FEAT_PMUv3p4 */
66
cpu->isar.id_dfr0 = t;
67
}
68
--
69
2.25.1
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
This extension concerns changes to the External Debug interface,
4
with Secure and Non-secure access to the debug registers, and all
5
of it is outside the scope of QEMU. Indicating support for this
6
is mandatory with FEAT_SEL2, which we do implement.
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20220506180242.216785-13-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
docs/system/arm/emulation.rst | 1 +
14
target/arm/cpu64.c | 2 +-
15
target/arm/cpu_tcg.c | 4 ++--
16
3 files changed, 4 insertions(+), 3 deletions(-)
17
18
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
19
index XXXXXXX..XXXXXXX 100644
20
--- a/docs/system/arm/emulation.rst
21
+++ b/docs/system/arm/emulation.rst
22
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
23
- FEAT_DIT (Data Independent Timing instructions)
24
- FEAT_DPB (DC CVAP instruction)
25
- FEAT_Debugv8p2 (Debug changes for v8.2)
26
+- FEAT_Debugv8p4 (Debug changes for v8.4)
27
- FEAT_DotProd (Advanced SIMD dot product instructions)
28
- FEAT_FCMA (Floating-point complex number instructions)
29
- FEAT_FHM (Floating-point half-precision multiplication instructions)
30
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/cpu64.c
33
+++ b/target/arm/cpu64.c
34
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
35
cpu->isar.id_aa64zfr0 = t;
36
37
t = cpu->isar.id_aa64dfr0;
38
- t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 8); /* FEAT_Debugv8p2 */
39
+ t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 9); /* FEAT_Debugv8p4 */
40
t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* FEAT_PMUv3p4 */
41
cpu->isar.id_aa64dfr0 = t;
42
43
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/cpu_tcg.c
46
+++ b/target/arm/cpu_tcg.c
47
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
48
cpu->isar.id_pfr2 = t;
49
50
t = cpu->isar.id_dfr0;
51
- t = FIELD_DP32(t, ID_DFR0, COPDBG, 8); /* FEAT_Debugv8p2 */
52
- t = FIELD_DP32(t, ID_DFR0, COPSDBG, 8); /* FEAT_Debugv8p2 */
53
+ t = FIELD_DP32(t, ID_DFR0, COPDBG, 9); /* FEAT_Debugv8p4 */
54
+ t = FIELD_DP32(t, ID_DFR0, COPSDBG, 9); /* FEAT_Debugv8p4 */
55
t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* FEAT_PMUv3p4 */
56
cpu->isar.id_dfr0 = t;
57
}
58
--
59
2.25.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Split out gen_top_byte_ignore in preparation of handling these
3
Add only the system registers required to implement zero error
4
data accesses; the new tbflags field is not yet honored.
4
records. This means that all values for ERRSELR are out of range,
5
which means that it and all of the indexed error record registers
6
need not be implemented.
7
8
Add the EL2 registers required for injecting virtual SError.
5
9
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190204132126.3255-2-richard.henderson@linaro.org
12
Message-id: 20220506180242.216785-14-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
14
---
11
target/arm/cpu.h | 1 +
15
target/arm/cpu.h | 5 +++
12
target/arm/translate.h | 3 +-
16
target/arm/helper.c | 84 +++++++++++++++++++++++++++++++++++++++++++++
13
target/arm/helper.c | 1 +
17
2 files changed, 89 insertions(+)
14
target/arm/translate-a64.c | 72 +++++++++++++++++++-------------------
15
4 files changed, 40 insertions(+), 37 deletions(-)
16
18
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
21
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, ZCR_LEN, 4, 4)
23
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
22
FIELD(TBFLAG_A64, PAUTH_ACTIVE, 8, 1)
24
uint64_t tfsr_el[4]; /* tfsre0_el1 is index 0. */
23
FIELD(TBFLAG_A64, BT, 9, 1)
25
uint64_t gcr_el1;
24
FIELD(TBFLAG_A64, BTYPE, 10, 2)
26
uint64_t rgsr_el1;
25
+FIELD(TBFLAG_A64, TBID, 12, 2)
27
+
26
28
+ /* Minimal RAS registers */
27
static inline bool bswap_code(bool sctlr_b)
29
+ uint64_t disr_el1;
28
{
30
+ uint64_t vdisr_el2;
29
diff --git a/target/arm/translate.h b/target/arm/translate.h
31
+ uint64_t vsesr_el2;
30
index XXXXXXX..XXXXXXX 100644
32
} cp15;
31
--- a/target/arm/translate.h
33
32
+++ b/target/arm/translate.h
34
struct {
33
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
34
int user;
35
#endif
36
ARMMMUIdx mmu_idx; /* MMU index to use for normal loads/stores */
37
- uint8_t tbii; /* TBI1|TBI0 for EL0/1 or TBI for EL2/3 */
38
+ uint8_t tbii; /* TBI1|TBI0 for insns */
39
+ uint8_t tbid; /* TBI1|TBI0 for data */
40
bool ns; /* Use non-secure CPREG bank on access */
41
int fp_excp_el; /* FP exception EL or 0 if enabled */
42
int sve_excp_el; /* SVE exception EL or 0 if enabled */
43
diff --git a/target/arm/helper.c b/target/arm/helper.c
35
diff --git a/target/arm/helper.c b/target/arm/helper.c
44
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/helper.c
37
--- a/target/arm/helper.c
46
+++ b/target/arm/helper.c
38
+++ b/target/arm/helper.c
47
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
39
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
48
}
40
.access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
49
41
};
50
flags = FIELD_DP32(flags, TBFLAG_A64, TBII, tbii);
42
51
+ flags = FIELD_DP32(flags, TBFLAG_A64, TBID, tbid);
52
}
53
#endif
54
55
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/arm/translate-a64.c
58
+++ b/target/arm/translate-a64.c
59
@@ -XXX,XX +XXX,XX @@ void gen_a64_set_pc_im(uint64_t val)
60
tcg_gen_movi_i64(cpu_pc, val);
61
}
62
63
-/* Load the PC from a generic TCG variable.
64
+/*
43
+/*
65
+ * Handle Top Byte Ignore (TBI) bits.
44
+ * Check for traps to RAS registers, which are controlled
66
*
45
+ * by HCR_EL2.TERR and SCR_EL3.TERR.
67
- * If address tagging is enabled via the TCR TBI bits, then loading
46
+ */
68
- * an address into the PC will clear out any tag in it:
47
+static CPAccessResult access_terr(CPUARMState *env, const ARMCPRegInfo *ri,
69
+ * If address tagging is enabled via the TCR TBI bits:
48
+ bool isread)
70
* + for EL2 and EL3 there is only one TBI bit, and if it is set
49
+{
71
* then the address is zero-extended, clearing bits [63:56]
50
+ int el = arm_current_el(env);
72
* + for EL0 and EL1, TBI0 controls addresses with bit 55 == 0
73
@@ -XXX,XX +XXX,XX @@ void gen_a64_set_pc_im(uint64_t val)
74
* If the appropriate TBI bit is set for the address then
75
* the address is sign-extended from bit 55 into bits [63:56]
76
*
77
- * We can avoid doing this for relative-branches, because the
78
- * PC + offset can never overflow into the tag bits (assuming
79
- * that virtual addresses are less than 56 bits wide, as they
80
- * are currently), but we must handle it for branch-to-register.
81
+ * Here We have concatenated TBI{1,0} into tbi.
82
*/
83
-static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
84
+static void gen_top_byte_ignore(DisasContext *s, TCGv_i64 dst,
85
+ TCGv_i64 src, int tbi)
86
{
87
- /* Note that TBII is TBI1:TBI0. */
88
- int tbi = s->tbii;
89
-
90
- if (s->current_el <= 1) {
91
- if (tbi != 0) {
92
- /* Sign-extend from bit 55. */
93
- tcg_gen_sextract_i64(cpu_pc, src, 0, 56);
94
-
95
- if (tbi != 3) {
96
- TCGv_i64 tcg_zero = tcg_const_i64(0);
97
-
98
- /*
99
- * The two TBI bits differ.
100
- * If tbi0, then !tbi1: only use the extension if positive.
101
- * if !tbi0, then tbi1: only use the extension if negative.
102
- */
103
- tcg_gen_movcond_i64(tbi == 1 ? TCG_COND_GE : TCG_COND_LT,
104
- cpu_pc, cpu_pc, tcg_zero, cpu_pc, src);
105
- tcg_temp_free_i64(tcg_zero);
106
- }
107
- return;
108
- }
109
+ if (tbi == 0) {
110
+ /* Load unmodified address */
111
+ tcg_gen_mov_i64(dst, src);
112
+ } else if (s->current_el >= 2) {
113
+ /* FIXME: ARMv8.1-VHE S2 translation regime. */
114
+ /* Force tag byte to all zero */
115
+ tcg_gen_extract_i64(dst, src, 0, 56);
116
} else {
117
- if (tbi != 0) {
118
- /* Force tag byte to all zero */
119
- tcg_gen_extract_i64(cpu_pc, src, 0, 56);
120
- return;
121
+ /* Sign-extend from bit 55. */
122
+ tcg_gen_sextract_i64(dst, src, 0, 56);
123
+
51
+
124
+ if (tbi != 3) {
52
+ if (el < 2 && (arm_hcr_el2_eff(env) & HCR_TERR)) {
125
+ TCGv_i64 tcg_zero = tcg_const_i64(0);
53
+ return CP_ACCESS_TRAP_EL2;
54
+ }
55
+ if (el < 3 && (env->cp15.scr_el3 & SCR_TERR)) {
56
+ return CP_ACCESS_TRAP_EL3;
57
+ }
58
+ return CP_ACCESS_OK;
59
+}
126
+
60
+
127
+ /*
61
+static uint64_t disr_read(CPUARMState *env, const ARMCPRegInfo *ri)
128
+ * The two TBI bits differ.
62
+{
129
+ * If tbi0, then !tbi1: only use the extension if positive.
63
+ int el = arm_current_el(env);
130
+ * if !tbi0, then tbi1: only use the extension if negative.
64
+
131
+ */
65
+ if (el < 2 && (arm_hcr_el2_eff(env) & HCR_AMO)) {
132
+ tcg_gen_movcond_i64(tbi == 1 ? TCG_COND_GE : TCG_COND_LT,
66
+ return env->cp15.vdisr_el2;
133
+ dst, dst, tcg_zero, dst, src);
67
+ }
134
+ tcg_temp_free_i64(tcg_zero);
68
+ if (el < 3 && (env->cp15.scr_el3 & SCR_EA)) {
135
}
69
+ return 0; /* RAZ/WI */
70
+ }
71
+ return env->cp15.disr_el1;
72
+}
73
+
74
+static void disr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t val)
75
+{
76
+ int el = arm_current_el(env);
77
+
78
+ if (el < 2 && (arm_hcr_el2_eff(env) & HCR_AMO)) {
79
+ env->cp15.vdisr_el2 = val;
80
+ return;
81
+ }
82
+ if (el < 3 && (env->cp15.scr_el3 & SCR_EA)) {
83
+ return; /* RAZ/WI */
84
+ }
85
+ env->cp15.disr_el1 = val;
86
+}
87
+
88
+/*
89
+ * Minimal RAS implementation with no Error Records.
90
+ * Which means that all of the Error Record registers:
91
+ * ERXADDR_EL1
92
+ * ERXCTLR_EL1
93
+ * ERXFR_EL1
94
+ * ERXMISC0_EL1
95
+ * ERXMISC1_EL1
96
+ * ERXMISC2_EL1
97
+ * ERXMISC3_EL1
98
+ * ERXPFGCDN_EL1 (RASv1p1)
99
+ * ERXPFGCTL_EL1 (RASv1p1)
100
+ * ERXPFGF_EL1 (RASv1p1)
101
+ * ERXSTATUS_EL1
102
+ * and
103
+ * ERRSELR_EL1
104
+ * may generate UNDEFINED, which is the effect we get by not
105
+ * listing them at all.
106
+ */
107
+static const ARMCPRegInfo minimal_ras_reginfo[] = {
108
+ { .name = "DISR_EL1", .state = ARM_CP_STATE_BOTH,
109
+ .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 1, .opc2 = 1,
110
+ .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.disr_el1),
111
+ .readfn = disr_read, .writefn = disr_write, .raw_writefn = raw_write },
112
+ { .name = "ERRIDR_EL1", .state = ARM_CP_STATE_BOTH,
113
+ .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 3, .opc2 = 0,
114
+ .access = PL1_R, .accessfn = access_terr,
115
+ .type = ARM_CP_CONST, .resetvalue = 0 },
116
+ { .name = "VDISR_EL2", .state = ARM_CP_STATE_BOTH,
117
+ .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 1, .opc2 = 1,
118
+ .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.vdisr_el2) },
119
+ { .name = "VSESR_EL2", .state = ARM_CP_STATE_BOTH,
120
+ .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 3,
121
+ .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.vsesr_el2) },
122
+};
123
+
124
/* Return the exception level to which exceptions should be taken
125
* via SVEAccessTrap. If an exception should be routed through
126
* AArch64.AdvSIMDFPAccessTrap, return 0; fp_exception_el should
127
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
128
if (cpu_isar_feature(aa64_ssbs, cpu)) {
129
define_one_arm_cp_reg(cpu, &ssbs_reginfo);
136
}
130
}
137
+}
131
+ if (cpu_isar_feature(any_ras, cpu)) {
138
132
+ define_arm_cp_regs(cpu, minimal_ras_reginfo);
139
- /* Load unmodified address */
133
+ }
140
- tcg_gen_mov_i64(cpu_pc, src);
134
141
+static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
135
if (cpu_isar_feature(aa64_vh, cpu) ||
142
+{
136
cpu_isar_feature(aa64_debugv8p2, cpu)) {
143
+ /*
144
+ * If address tagging is enabled for instructions via the TCR TBI bits,
145
+ * then loading an address into the PC will clear out any tag.
146
+ */
147
+ gen_top_byte_ignore(s, cpu_pc, src, s->tbii);
148
}
149
150
typedef struct DisasCompare64 {
151
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
152
core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
153
dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
154
dc->tbii = FIELD_EX32(tb_flags, TBFLAG_A64, TBII);
155
+ dc->tbid = FIELD_EX32(tb_flags, TBFLAG_A64, TBID);
156
dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
157
#if !defined(CONFIG_USER_ONLY)
158
dc->user = (dc->current_el == 0);
159
--
137
--
160
2.20.1
138
2.25.1
161
162
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Caching the bit means that we will not have to re-walk the
3
Enable writes to the TERR and TEA bits when RAS is enabled.
4
page tables to look up the bit during translation.
4
These bits are otherwise RES0.
5
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20220506180242.216785-15-richard.henderson@linaro.org
8
Message-id: 20190128223118.5255-6-richard.henderson@linaro.org
9
[PMM: no need to OR in guarded bit status]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
target/arm/helper.c | 6 ++++++
11
target/arm/helper.c | 9 +++++++++
13
1 file changed, 6 insertions(+)
12
1 file changed, 9 insertions(+)
14
13
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
16
--- a/target/arm/helper.c
18
+++ b/target/arm/helper.c
17
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
18
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
20
bool ttbr1_valid;
21
uint64_t descaddrmask;
22
bool aarch64 = arm_el_is_aa64(env, el);
23
+ bool guarded = false;
24
25
/* TODO:
26
* This code does not handle the different format TCR for VTCR_EL2.
27
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
28
}
19
}
29
/* Merge in attributes from table descriptors */
20
valid_mask &= ~SCR_NET;
30
attrs |= nstable << 3; /* NS */
21
31
+ guarded = extract64(descriptor, 50, 1); /* GP */
22
+ if (cpu_isar_feature(aa64_ras, cpu)) {
32
if (param.hpd) {
23
+ valid_mask |= SCR_TERR;
33
/* HPD disables all the table attributes except NSTable. */
24
+ }
34
break;
25
if (cpu_isar_feature(aa64_lor, cpu)) {
35
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
26
valid_mask |= SCR_TLOR;
36
*/
27
}
37
txattrs->secure = false;
28
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
29
}
30
} else {
31
valid_mask &= ~(SCR_RW | SCR_ST);
32
+ if (cpu_isar_feature(aa32_ras, cpu)) {
33
+ valid_mask |= SCR_TERR;
34
+ }
38
}
35
}
39
+ /* When in aarch64 mode, and BTI is enabled, remember GP in the IOTLB. */
36
40
+ if (aarch64 && guarded && cpu_isar_feature(aa64_bti, cpu)) {
37
if (!arm_feature(env, ARM_FEATURE_EL2)) {
41
+ txattrs->target_tlb_bit0 = true;
38
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
42
+ }
39
if (cpu_isar_feature(aa64_vh, cpu)) {
43
40
valid_mask |= HCR_E2H;
44
if (cacheattrs != NULL) {
41
}
45
if (mmu_idx == ARMMMUIdx_S2NS) {
42
+ if (cpu_isar_feature(aa64_ras, cpu)) {
43
+ valid_mask |= HCR_TERR | HCR_TEA;
44
+ }
45
if (cpu_isar_feature(aa64_lor, cpu)) {
46
valid_mask |= HCR_TLOR;
47
}
46
--
48
--
47
2.20.1
49
2.25.1
48
49
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Also create field definitions for id_aa64pfr1 from ARMv8.5.
3
Virtual SError exceptions are raised by setting HCR_EL2.VSE,
4
and are routed to EL1 just like other virtual exceptions.
4
5
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190128223118.5255-2-richard.henderson@linaro.org
8
Message-id: 20220506180242.216785-16-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/cpu.h | 10 ++++++++++
11
target/arm/cpu.h | 2 ++
11
1 file changed, 10 insertions(+)
12
target/arm/internals.h | 8 ++++++++
13
target/arm/syndrome.h | 5 +++++
14
target/arm/cpu.c | 38 +++++++++++++++++++++++++++++++++++++-
15
target/arm/helper.c | 40 +++++++++++++++++++++++++++++++++++++++-
16
5 files changed, 91 insertions(+), 2 deletions(-)
12
17
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
20
--- a/target/arm/cpu.h
16
+++ b/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@ FIELD(ID_AA64PFR0, GIC, 24, 4)
22
@@ -XXX,XX +XXX,XX @@
18
FIELD(ID_AA64PFR0, RAS, 28, 4)
23
#define EXCP_LSERR 21 /* v8M LSERR SecureFault */
19
FIELD(ID_AA64PFR0, SVE, 32, 4)
24
#define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */
20
25
#define EXCP_DIVBYZERO 23 /* v7M DIVBYZERO UsageFault */
21
+FIELD(ID_AA64PFR1, BT, 0, 4)
26
+#define EXCP_VSERR 24
22
+FIELD(ID_AA64PFR1, SBSS, 4, 4)
27
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
23
+FIELD(ID_AA64PFR1, MTE, 8, 4)
28
24
+FIELD(ID_AA64PFR1, RAS_FRAC, 12, 4)
29
#define ARMV7M_EXCP_RESET 1
25
+
30
@@ -XXX,XX +XXX,XX @@ enum {
26
FIELD(ID_AA64MMFR0, PARANGE, 0, 4)
31
#define CPU_INTERRUPT_FIQ CPU_INTERRUPT_TGT_EXT_1
27
FIELD(ID_AA64MMFR0, ASIDBITS, 4, 4)
32
#define CPU_INTERRUPT_VIRQ CPU_INTERRUPT_TGT_EXT_2
28
FIELD(ID_AA64MMFR0, BIGEND, 8, 4)
33
#define CPU_INTERRUPT_VFIQ CPU_INTERRUPT_TGT_EXT_3
29
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_lor(const ARMISARegisters *id)
34
+#define CPU_INTERRUPT_VSERR CPU_INTERRUPT_TGT_INT_0
30
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, LO) != 0;
35
31
}
36
/* The usual mapping for an AArch64 system register to its AArch32
32
37
* counterpart is for the 32 bit world to have access to the lower
33
+static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
38
diff --git a/target/arm/internals.h b/target/arm/internals.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/internals.h
41
+++ b/target/arm/internals.h
42
@@ -XXX,XX +XXX,XX @@ void arm_cpu_update_virq(ARMCPU *cpu);
43
*/
44
void arm_cpu_update_vfiq(ARMCPU *cpu);
45
46
+/**
47
+ * arm_cpu_update_vserr: Update CPU_INTERRUPT_VSERR bit
48
+ *
49
+ * Update the CPU_INTERRUPT_VSERR bit in cs->interrupt_request,
50
+ * following a change to the HCR_EL2.VSE bit.
51
+ */
52
+void arm_cpu_update_vserr(ARMCPU *cpu);
53
+
54
/**
55
* arm_mmu_idx_el:
56
* @env: The cpu environment
57
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/syndrome.h
60
+++ b/target/arm/syndrome.h
61
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_pcalignment(void)
62
return (EC_PCALIGNMENT << ARM_EL_EC_SHIFT) | ARM_EL_IL;
63
}
64
65
+static inline uint32_t syn_serror(uint32_t extra)
34
+{
66
+{
35
+ return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
67
+ return (EC_SERROR << ARM_EL_EC_SHIFT) | ARM_EL_IL | extra;
36
+}
68
+}
37
+
69
+
38
/*
70
#endif /* TARGET_ARM_SYNDROME_H */
39
* Forward to the above feature tests given an ARMCPU pointer.
71
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
40
*/
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/cpu.c
74
+++ b/target/arm/cpu.c
75
@@ -XXX,XX +XXX,XX @@ static bool arm_cpu_has_work(CPUState *cs)
76
return (cpu->power_state != PSCI_OFF)
77
&& cs->interrupt_request &
78
(CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD
79
- | CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ
80
+ | CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ | CPU_INTERRUPT_VSERR
81
| CPU_INTERRUPT_EXITTB);
82
}
83
84
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
85
return false;
86
}
87
return !(env->daif & PSTATE_I);
88
+ case EXCP_VSERR:
89
+ if (!(hcr_el2 & HCR_AMO) || (hcr_el2 & HCR_TGE)) {
90
+ /* VIRQs are only taken when hypervized. */
91
+ return false;
92
+ }
93
+ return !(env->daif & PSTATE_A);
94
default:
95
g_assert_not_reached();
96
}
97
@@ -XXX,XX +XXX,XX @@ static bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
98
goto found;
99
}
100
}
101
+ if (interrupt_request & CPU_INTERRUPT_VSERR) {
102
+ excp_idx = EXCP_VSERR;
103
+ target_el = 1;
104
+ if (arm_excp_unmasked(cs, excp_idx, target_el,
105
+ cur_el, secure, hcr_el2)) {
106
+ /* Taking a virtual abort clears HCR_EL2.VSE */
107
+ env->cp15.hcr_el2 &= ~HCR_VSE;
108
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_VSERR);
109
+ goto found;
110
+ }
111
+ }
112
return false;
113
114
found:
115
@@ -XXX,XX +XXX,XX @@ void arm_cpu_update_vfiq(ARMCPU *cpu)
116
}
117
}
118
119
+void arm_cpu_update_vserr(ARMCPU *cpu)
120
+{
121
+ /*
122
+ * Update the interrupt level for VSERR, which is the HCR_EL2.VSE bit.
123
+ */
124
+ CPUARMState *env = &cpu->env;
125
+ CPUState *cs = CPU(cpu);
126
+
127
+ bool new_state = env->cp15.hcr_el2 & HCR_VSE;
128
+
129
+ if (new_state != ((cs->interrupt_request & CPU_INTERRUPT_VSERR) != 0)) {
130
+ if (new_state) {
131
+ cpu_interrupt(cs, CPU_INTERRUPT_VSERR);
132
+ } else {
133
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_VSERR);
134
+ }
135
+ }
136
+}
137
+
138
#ifndef CONFIG_USER_ONLY
139
static void arm_cpu_set_irq(void *opaque, int irq, int level)
140
{
141
diff --git a/target/arm/helper.c b/target/arm/helper.c
142
index XXXXXXX..XXXXXXX 100644
143
--- a/target/arm/helper.c
144
+++ b/target/arm/helper.c
145
@@ -XXX,XX +XXX,XX @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
146
}
147
}
148
149
- /* External aborts are not possible in QEMU so A bit is always clear */
150
+ if (hcr_el2 & HCR_AMO) {
151
+ if (cs->interrupt_request & CPU_INTERRUPT_VSERR) {
152
+ ret |= CPSR_A;
153
+ }
154
+ }
155
+
156
return ret;
157
}
158
159
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
160
g_assert(qemu_mutex_iothread_locked());
161
arm_cpu_update_virq(cpu);
162
arm_cpu_update_vfiq(cpu);
163
+ arm_cpu_update_vserr(cpu);
164
}
165
166
static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
167
@@ -XXX,XX +XXX,XX @@ void arm_log_exception(CPUState *cs)
168
[EXCP_LSERR] = "v8M LSERR UsageFault",
169
[EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
170
[EXCP_DIVBYZERO] = "v7M DIVBYZERO UsageFault",
171
+ [EXCP_VSERR] = "Virtual SERR",
172
};
173
174
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
175
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
176
mask = CPSR_A | CPSR_I | CPSR_F;
177
offset = 4;
178
break;
179
+ case EXCP_VSERR:
180
+ {
181
+ /*
182
+ * Note that this is reported as a data abort, but the DFAR
183
+ * has an UNKNOWN value. Construct the SError syndrome from
184
+ * AET and ExT fields.
185
+ */
186
+ ARMMMUFaultInfo fi = { .type = ARMFault_AsyncExternal, };
187
+
188
+ if (extended_addresses_enabled(env)) {
189
+ env->exception.fsr = arm_fi_to_lfsc(&fi);
190
+ } else {
191
+ env->exception.fsr = arm_fi_to_sfsc(&fi);
192
+ }
193
+ env->exception.fsr |= env->cp15.vsesr_el2 & 0xd000;
194
+ A32_BANKED_CURRENT_REG_SET(env, dfsr, env->exception.fsr);
195
+ qemu_log_mask(CPU_LOG_INT, "...with IFSR 0x%x\n",
196
+ env->exception.fsr);
197
+
198
+ new_mode = ARM_CPU_MODE_ABT;
199
+ addr = 0x10;
200
+ mask = CPSR_A | CPSR_I;
201
+ offset = 8;
202
+ }
203
+ break;
204
case EXCP_SMC:
205
new_mode = ARM_CPU_MODE_MON;
206
addr = 0x08;
207
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
208
case EXCP_VFIQ:
209
addr += 0x100;
210
break;
211
+ case EXCP_VSERR:
212
+ addr += 0x180;
213
+ /* Construct the SError syndrome from IDS and ISS fields. */
214
+ env->exception.syndrome = syn_serror(env->cp15.vsesr_el2 & 0x1ffffff);
215
+ env->cp15.esr_el[new_el] = env->exception.syndrome;
216
+ break;
217
default:
218
cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
219
}
41
--
220
--
42
2.20.1
221
2.25.1
43
44
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This is all of the non-exception cases of DISAS_NORETURN.
3
Check for and defer any pending virtual SError.
4
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20220506180242.216785-17-richard.henderson@linaro.org
7
Message-id: 20190128223118.5255-8-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
9
---
10
target/arm/translate-a64.c | 6 ++++++
10
target/arm/helper.h | 1 +
11
1 file changed, 6 insertions(+)
11
target/arm/a32.decode | 16 ++++++++------
12
target/arm/t32.decode | 18 ++++++++--------
13
target/arm/op_helper.c | 43 ++++++++++++++++++++++++++++++++++++++
14
target/arm/translate-a64.c | 17 +++++++++++++++
15
target/arm/translate.c | 23 ++++++++++++++++++++
16
6 files changed, 103 insertions(+), 15 deletions(-)
12
17
18
diff --git a/target/arm/helper.h b/target/arm/helper.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.h
21
+++ b/target/arm/helper.h
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(wfe, void, env)
23
DEF_HELPER_1(yield, void, env)
24
DEF_HELPER_1(pre_hvc, void, env)
25
DEF_HELPER_2(pre_smc, void, env, i32)
26
+DEF_HELPER_1(vesb, void, env)
27
28
DEF_HELPER_3(cpsr_write, void, env, i32, i32)
29
DEF_HELPER_2(cpsr_write_eret, void, env, i32)
30
diff --git a/target/arm/a32.decode b/target/arm/a32.decode
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/a32.decode
33
+++ b/target/arm/a32.decode
34
@@ -XXX,XX +XXX,XX @@ SMULTT .... 0001 0110 .... 0000 .... 1110 .... @rd0mn
35
36
{
37
{
38
- YIELD ---- 0011 0010 0000 1111 ---- 0000 0001
39
- WFE ---- 0011 0010 0000 1111 ---- 0000 0010
40
- WFI ---- 0011 0010 0000 1111 ---- 0000 0011
41
+ [
42
+ YIELD ---- 0011 0010 0000 1111 ---- 0000 0001
43
+ WFE ---- 0011 0010 0000 1111 ---- 0000 0010
44
+ WFI ---- 0011 0010 0000 1111 ---- 0000 0011
45
46
- # TODO: Implement SEV, SEVL; may help SMP performance.
47
- # SEV ---- 0011 0010 0000 1111 ---- 0000 0100
48
- # SEVL ---- 0011 0010 0000 1111 ---- 0000 0101
49
+ # TODO: Implement SEV, SEVL; may help SMP performance.
50
+ # SEV ---- 0011 0010 0000 1111 ---- 0000 0100
51
+ # SEVL ---- 0011 0010 0000 1111 ---- 0000 0101
52
+
53
+ ESB ---- 0011 0010 0000 1111 ---- 0001 0000
54
+ ]
55
56
# The canonical nop ends in 00000000, but the whole of the
57
# rest of the space executes as nop if otherwise unsupported.
58
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/t32.decode
61
+++ b/target/arm/t32.decode
62
@@ -XXX,XX +XXX,XX @@ CLZ 1111 1010 1011 ---- 1111 .... 1000 .... @rdm
63
[
64
# Hints, and CPS
65
{
66
- YIELD 1111 0011 1010 1111 1000 0000 0000 0001
67
- WFE 1111 0011 1010 1111 1000 0000 0000 0010
68
- WFI 1111 0011 1010 1111 1000 0000 0000 0011
69
+ [
70
+ YIELD 1111 0011 1010 1111 1000 0000 0000 0001
71
+ WFE 1111 0011 1010 1111 1000 0000 0000 0010
72
+ WFI 1111 0011 1010 1111 1000 0000 0000 0011
73
74
- # TODO: Implement SEV, SEVL; may help SMP performance.
75
- # SEV 1111 0011 1010 1111 1000 0000 0000 0100
76
- # SEVL 1111 0011 1010 1111 1000 0000 0000 0101
77
+ # TODO: Implement SEV, SEVL; may help SMP performance.
78
+ # SEV 1111 0011 1010 1111 1000 0000 0000 0100
79
+ # SEVL 1111 0011 1010 1111 1000 0000 0000 0101
80
81
- # For M-profile minimal-RAS ESB can be a NOP, which is the
82
- # default behaviour since it is in the hint space.
83
- # ESB 1111 0011 1010 1111 1000 0000 0001 0000
84
+ ESB 1111 0011 1010 1111 1000 0000 0001 0000
85
+ ]
86
87
# The canonical nop ends in 0000 0000, but the whole rest
88
# of the space is "reserved hint, behaves as nop".
89
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/target/arm/op_helper.c
92
+++ b/target/arm/op_helper.c
93
@@ -XXX,XX +XXX,XX @@ void HELPER(probe_access)(CPUARMState *env, target_ulong ptr,
94
access_type, mmu_idx, ra);
95
}
96
}
97
+
98
+/*
99
+ * This function corresponds to AArch64.vESBOperation().
100
+ * Note that the AArch32 version is not functionally different.
101
+ */
102
+void HELPER(vesb)(CPUARMState *env)
103
+{
104
+ /*
105
+ * The EL2Enabled() check is done inside arm_hcr_el2_eff,
106
+ * and will return HCR_EL2.VSE == 0, so nothing happens.
107
+ */
108
+ uint64_t hcr = arm_hcr_el2_eff(env);
109
+ bool enabled = !(hcr & HCR_TGE) && (hcr & HCR_AMO);
110
+ bool pending = enabled && (hcr & HCR_VSE);
111
+ bool masked = (env->daif & PSTATE_A);
112
+
113
+ /* If VSE pending and masked, defer the exception. */
114
+ if (pending && masked) {
115
+ uint32_t syndrome;
116
+
117
+ if (arm_el_is_aa64(env, 1)) {
118
+ /* Copy across IDS and ISS from VSESR. */
119
+ syndrome = env->cp15.vsesr_el2 & 0x1ffffff;
120
+ } else {
121
+ ARMMMUFaultInfo fi = { .type = ARMFault_AsyncExternal };
122
+
123
+ if (extended_addresses_enabled(env)) {
124
+ syndrome = arm_fi_to_lfsc(&fi);
125
+ } else {
126
+ syndrome = arm_fi_to_sfsc(&fi);
127
+ }
128
+ /* Copy across AET and ExT from VSESR. */
129
+ syndrome |= env->cp15.vsesr_el2 & 0xd000;
130
+ }
131
+
132
+ /* Set VDISR_EL2.A along with the syndrome. */
133
+ env->cp15.vdisr_el2 = syndrome | (1u << 31);
134
+
135
+ /* Clear pending virtual SError */
136
+ env->cp15.hcr_el2 &= ~HCR_VSE;
137
+ cpu_reset_interrupt(env_cpu(env), CPU_INTERRUPT_VSERR);
138
+ }
139
+}
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
140
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
141
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
142
--- a/target/arm/translate-a64.c
16
+++ b/target/arm/translate-a64.c
143
+++ b/target/arm/translate-a64.c
17
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
144
@@ -XXX,XX +XXX,XX @@ static void handle_hint(DisasContext *s, uint32_t insn,
18
}
145
gen_helper_autib(cpu_X[17], cpu_env, cpu_X[17], cpu_X[16]);
19
146
}
20
/* B Branch / BL Branch with link */
147
break;
21
+ reset_btype(s);
148
+ case 0b10000: /* ESB */
22
gen_goto_tb(s, 0, addr);
149
+ /* Without RAS, we must implement this as NOP. */
150
+ if (dc_isar_feature(aa64_ras, s)) {
151
+ /*
152
+ * QEMU does not have a source of physical SErrors,
153
+ * so we are only concerned with virtual SErrors.
154
+ * The pseudocode in the ARM for this case is
155
+ * if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then
156
+ * AArch64.vESBOperation();
157
+ * Most of the condition can be evaluated at translation time.
158
+ * Test for EL2 present, and defer test for SEL2 to runtime.
159
+ */
160
+ if (s->current_el <= 1 && arm_dc_feature(s, ARM_FEATURE_EL2)) {
161
+ gen_helper_vesb(cpu_env);
162
+ }
163
+ }
164
+ break;
165
case 0b11000: /* PACIAZ */
166
if (s->pauth_active) {
167
gen_helper_pacia(cpu_X[30], cpu_env, cpu_X[30],
168
diff --git a/target/arm/translate.c b/target/arm/translate.c
169
index XXXXXXX..XXXXXXX 100644
170
--- a/target/arm/translate.c
171
+++ b/target/arm/translate.c
172
@@ -XXX,XX +XXX,XX @@ static bool trans_WFI(DisasContext *s, arg_WFI *a)
173
return true;
23
}
174
}
24
175
25
@@ -XXX,XX +XXX,XX @@ static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
176
+static bool trans_ESB(DisasContext *s, arg_ESB *a)
26
tcg_cmp = read_cpu_reg(s, rt, sf);
177
+{
27
label_match = gen_new_label();
178
+ /*
28
179
+ * For M-profile, minimal-RAS ESB can be a NOP.
29
+ reset_btype(s);
180
+ * Without RAS, we must implement this as NOP.
30
tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
181
+ */
31
tcg_cmp, 0, label_match);
182
+ if (!arm_dc_feature(s, ARM_FEATURE_M) && dc_isar_feature(aa32_ras, s)) {
32
183
+ /*
33
@@ -XXX,XX +XXX,XX @@ static void disas_test_b_imm(DisasContext *s, uint32_t insn)
184
+ * QEMU does not have a source of physical SErrors,
34
tcg_cmp = tcg_temp_new_i64();
185
+ * so we are only concerned with virtual SErrors.
35
tcg_gen_andi_i64(tcg_cmp, cpu_reg(s, rt), (1ULL << bit_pos));
186
+ * The pseudocode in the ARM for this case is
36
label_match = gen_new_label();
187
+ * if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then
37
+
188
+ * AArch32.vESBOperation();
38
+ reset_btype(s);
189
+ * Most of the condition can be evaluated at translation time.
39
tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
190
+ * Test for EL2 present, and defer test for SEL2 to runtime.
40
tcg_cmp, 0, label_match);
191
+ */
41
tcg_temp_free_i64(tcg_cmp);
192
+ if (s->current_el <= 1 && arm_dc_feature(s, ARM_FEATURE_EL2)) {
42
@@ -XXX,XX +XXX,XX @@ static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
193
+ gen_helper_vesb(cpu_env);
43
addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
194
+ }
44
cond = extract32(insn, 0, 4);
195
+ }
45
196
+ return true;
46
+ reset_btype(s);
197
+}
47
if (cond < 0x0e) {
198
+
48
/* genuinely conditional branches */
199
static bool trans_NOP(DisasContext *s, arg_NOP *a)
49
TCGLabel *label_match = gen_new_label();
200
{
50
@@ -XXX,XX +XXX,XX @@ static void handle_sync(DisasContext *s, uint32_t insn,
201
return true;
51
* a self-modified code correctly and also to take
52
* any pending interrupts immediately.
53
*/
54
+ reset_btype(s);
55
gen_goto_tb(s, 0, s->pc);
56
return;
57
default:
58
--
202
--
59
2.20.1
203
2.25.1
60
61
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190201195404.30486-2-richard.henderson@linaro.org
5
Message-id: 20220506180242.216785-18-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
linux-user/aarch64/target_syscall.h | 7 ++++++
8
docs/system/arm/emulation.rst | 1 +
9
linux-user/syscall.c | 36 +++++++++++++++++++++++++++++
9
target/arm/cpu64.c | 1 +
10
2 files changed, 43 insertions(+)
10
target/arm/cpu_tcg.c | 1 +
11
3 files changed, 3 insertions(+)
11
12
12
diff --git a/linux-user/aarch64/target_syscall.h b/linux-user/aarch64/target_syscall.h
13
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
13
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
14
--- a/linux-user/aarch64/target_syscall.h
15
--- a/docs/system/arm/emulation.rst
15
+++ b/linux-user/aarch64/target_syscall.h
16
+++ b/docs/system/arm/emulation.rst
16
@@ -XXX,XX +XXX,XX @@ struct target_pt_regs {
17
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
17
#define TARGET_PR_SVE_SET_VL 50
18
- FEAT_PMULL (PMULL, PMULL2 instructions)
18
#define TARGET_PR_SVE_GET_VL 51
19
- FEAT_PMUv3p1 (PMU Extensions v3.1)
19
20
- FEAT_PMUv3p4 (PMU Extensions v3.4)
20
+#define TARGET_PR_PAC_RESET_KEYS 54
21
+- FEAT_RAS (Reliability, availability, and serviceability)
21
+# define TARGET_PR_PAC_APIAKEY (1 << 0)
22
- FEAT_RDM (Advanced SIMD rounding double multiply accumulate instructions)
22
+# define TARGET_PR_PAC_APIBKEY (1 << 1)
23
- FEAT_RNG (Random number generator)
23
+# define TARGET_PR_PAC_APDAKEY (1 << 2)
24
- FEAT_SB (Speculation Barrier)
24
+# define TARGET_PR_PAC_APDBKEY (1 << 3)
25
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
25
+# define TARGET_PR_PAC_APGAKEY (1 << 4)
26
+
27
void arm_init_pauth_key(ARMPACKey *key);
28
29
#endif /* AARCH64_TARGET_SYSCALL_H */
30
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
31
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
32
--- a/linux-user/syscall.c
27
--- a/target/arm/cpu64.c
33
+++ b/linux-user/syscall.c
28
+++ b/target/arm/cpu64.c
34
@@ -XXX,XX +XXX,XX @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
29
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
35
}
30
t = cpu->isar.id_aa64pfr0;
36
}
31
t = FIELD_DP64(t, ID_AA64PFR0, FP, 1); /* FEAT_FP16 */
37
return ret;
32
t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1); /* FEAT_FP16 */
38
+ case TARGET_PR_PAC_RESET_KEYS:
33
+ t = FIELD_DP64(t, ID_AA64PFR0, RAS, 1); /* FEAT_RAS */
39
+ {
34
t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
40
+ CPUARMState *env = cpu_env;
35
t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); /* FEAT_SEL2 */
41
+ ARMCPU *cpu = arm_env_get_cpu(env);
36
t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
42
+
37
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
43
+ if (arg3 || arg4 || arg5) {
38
index XXXXXXX..XXXXXXX 100644
44
+ return -TARGET_EINVAL;
39
--- a/target/arm/cpu_tcg.c
45
+ }
40
+++ b/target/arm/cpu_tcg.c
46
+ if (cpu_isar_feature(aa64_pauth, cpu)) {
41
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
47
+ int all = (TARGET_PR_PAC_APIAKEY | TARGET_PR_PAC_APIBKEY |
42
48
+ TARGET_PR_PAC_APDAKEY | TARGET_PR_PAC_APDBKEY |
43
t = cpu->isar.id_pfr0;
49
+ TARGET_PR_PAC_APGAKEY);
44
t = FIELD_DP32(t, ID_PFR0, DIT, 1); /* FEAT_DIT */
50
+ if (arg2 == 0) {
45
+ t = FIELD_DP32(t, ID_PFR0, RAS, 1); /* FEAT_RAS */
51
+ arg2 = all;
46
cpu->isar.id_pfr0 = t;
52
+ } else if (arg2 & ~all) {
47
53
+ return -TARGET_EINVAL;
48
t = cpu->isar.id_pfr2;
54
+ }
55
+ if (arg2 & TARGET_PR_PAC_APIAKEY) {
56
+ arm_init_pauth_key(&env->apia_key);
57
+ }
58
+ if (arg2 & TARGET_PR_PAC_APIBKEY) {
59
+ arm_init_pauth_key(&env->apib_key);
60
+ }
61
+ if (arg2 & TARGET_PR_PAC_APDAKEY) {
62
+ arm_init_pauth_key(&env->apda_key);
63
+ }
64
+ if (arg2 & TARGET_PR_PAC_APDBKEY) {
65
+ arm_init_pauth_key(&env->apdb_key);
66
+ }
67
+ if (arg2 & TARGET_PR_PAC_APGAKEY) {
68
+ arm_init_pauth_key(&env->apga_key);
69
+ }
70
+ return 0;
71
+ }
72
+ }
73
+ return -TARGET_EINVAL;
74
#endif /* AARCH64 */
75
case PR_GET_SECCOMP:
76
case PR_SET_SECCOMP:
77
--
49
--
78
2.20.1
50
2.25.1
79
80
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
This feature is AArch64 only, and applies to physical SErrors,
4
which QEMU does not implement, thus the feature is a nop.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220506180242.216785-19-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
docs/system/arm/emulation.rst | 1 +
12
target/arm/cpu64.c | 1 +
13
2 files changed, 2 insertions(+)
14
15
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
16
index XXXXXXX..XXXXXXX 100644
17
--- a/docs/system/arm/emulation.rst
18
+++ b/docs/system/arm/emulation.rst
19
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
20
- FEAT_FlagM2 (Enhancements to flag manipulation instructions)
21
- FEAT_HPDS (Hierarchical permission disables)
22
- FEAT_I8MM (AArch64 Int8 matrix multiplication instructions)
23
+- FEAT_IESB (Implicit error synchronization event)
24
- FEAT_JSCVT (JavaScript conversion instructions)
25
- FEAT_LOR (Limited ordering regions)
26
- FEAT_LPA (Large Physical Address space)
27
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/cpu64.c
30
+++ b/target/arm/cpu64.c
31
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
32
t = cpu->isar.id_aa64mmfr2;
33
t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* FEAT_TTCNP */
34
t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1); /* FEAT_UAO */
35
+ t = FIELD_DP64(t, ID_AA64MMFR2, IESB, 1); /* FEAT_IESB */
36
t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1); /* FEAT_LVA */
37
t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* FEAT_TTST */
38
t = FIELD_DP64(t, ID_AA64MMFR2, TTL, 1); /* FEAT_TTL */
39
--
40
2.25.1
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
This extension concerns branch speculation, which TCG does
4
not implement. Thus we can trivially enable this feature.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220506180242.216785-20-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
docs/system/arm/emulation.rst | 1 +
12
target/arm/cpu64.c | 1 +
13
target/arm/cpu_tcg.c | 1 +
14
3 files changed, 3 insertions(+)
15
16
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
17
index XXXXXXX..XXXXXXX 100644
18
--- a/docs/system/arm/emulation.rst
19
+++ b/docs/system/arm/emulation.rst
20
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
21
- FEAT_BBM at level 2 (Translation table break-before-make levels)
22
- FEAT_BF16 (AArch64 BFloat16 instructions)
23
- FEAT_BTI (Branch Target Identification)
24
+- FEAT_CSV2 (Cache speculation variant 2)
25
- FEAT_DIT (Data Independent Timing instructions)
26
- FEAT_DPB (DC CVAP instruction)
27
- FEAT_Debugv8p2 (Debug changes for v8.2)
28
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu64.c
31
+++ b/target/arm/cpu64.c
32
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
33
t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
34
t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); /* FEAT_SEL2 */
35
t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
36
+ t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 1); /* FEAT_CSV2 */
37
cpu->isar.id_aa64pfr0 = t;
38
39
t = cpu->isar.id_aa64pfr1;
40
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/cpu_tcg.c
43
+++ b/target/arm/cpu_tcg.c
44
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
45
cpu->isar.id_mmfr4 = t;
46
47
t = cpu->isar.id_pfr0;
48
+ t = FIELD_DP32(t, ID_PFR0, CSV2, 2); /* FEAT_CVS2 */
49
t = FIELD_DP32(t, ID_PFR0, DIT, 1); /* FEAT_DIT */
50
t = FIELD_DP32(t, ID_PFR0, RAS, 1); /* FEAT_RAS */
51
cpu->isar.id_pfr0 = t;
52
--
53
2.25.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
There is no branch prediction in TCG, therefore there is no
4
need to actually include the context number into the predictor.
5
Therefore all we need to do is add the state for SCXTNUM_ELx.
2
6
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190128223118.5255-4-richard.henderson@linaro.org
9
Message-id: 20220506180242.216785-21-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
target/arm/cpu.h | 2 ++
12
docs/system/arm/emulation.rst | 3 ++
9
target/arm/translate.h | 4 ++++
13
target/arm/cpu.h | 16 +++++++++
10
target/arm/helper.c | 22 +++++++++++++++-------
14
target/arm/cpu.c | 5 +++
11
target/arm/translate-a64.c | 2 ++
15
target/arm/cpu64.c | 3 +-
12
4 files changed, 23 insertions(+), 7 deletions(-)
16
target/arm/helper.c | 61 ++++++++++++++++++++++++++++++++++-
17
5 files changed, 86 insertions(+), 2 deletions(-)
13
18
19
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
20
index XXXXXXX..XXXXXXX 100644
21
--- a/docs/system/arm/emulation.rst
22
+++ b/docs/system/arm/emulation.rst
23
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
24
- FEAT_BF16 (AArch64 BFloat16 instructions)
25
- FEAT_BTI (Branch Target Identification)
26
- FEAT_CSV2 (Cache speculation variant 2)
27
+- FEAT_CSV2_1p1 (Cache speculation variant 2, version 1.1)
28
+- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
29
+- FEAT_CSV2_2 (Cache speculation variant 2, version 2)
30
- FEAT_DIT (Data Independent Timing instructions)
31
- FEAT_DPB (DC CVAP instruction)
32
- FEAT_Debugv8p2 (Debug changes for v8.2)
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
33
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
35
--- a/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
36
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, TBII, 0, 2)
37
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
19
FIELD(TBFLAG_A64, SVEEXC_EL, 2, 2)
38
ARMPACKey apdb;
20
FIELD(TBFLAG_A64, ZCR_LEN, 4, 4)
39
ARMPACKey apga;
21
FIELD(TBFLAG_A64, PAUTH_ACTIVE, 8, 1)
40
} keys;
22
+FIELD(TBFLAG_A64, BT, 9, 1)
41
+
23
+FIELD(TBFLAG_A64, BTYPE, 10, 2)
42
+ uint64_t scxtnum_el[4];
24
43
#endif
25
static inline bool bswap_code(bool sctlr_b)
44
45
#if defined(CONFIG_USER_ONLY)
46
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
47
#define SCTLR_WXN (1U << 19)
48
#define SCTLR_ST (1U << 20) /* up to ??, RAZ in v6 */
49
#define SCTLR_UWXN (1U << 20) /* v7 onward, AArch32 only */
50
+#define SCTLR_TSCXT (1U << 20) /* FEAT_CSV2_1p2, AArch64 only */
51
#define SCTLR_FI (1U << 21) /* up to v7, v8 RES0 */
52
#define SCTLR_IESB (1U << 21) /* v8.2-IESB, AArch64 only */
53
#define SCTLR_U (1U << 22) /* up to v6, RAO in v7 */
54
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_dit(const ARMISARegisters *id)
55
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0;
56
}
57
58
+static inline bool isar_feature_aa64_scxtnum(const ARMISARegisters *id)
59
+{
60
+ int key = FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, CSV2);
61
+ if (key >= 2) {
62
+ return true; /* FEAT_CSV2_2 */
63
+ }
64
+ if (key == 1) {
65
+ key = FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, CSV2_FRAC);
66
+ return key >= 2; /* FEAT_CSV2_1p2 */
67
+ }
68
+ return false;
69
+}
70
+
71
static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id)
26
{
72
{
27
diff --git a/target/arm/translate.h b/target/arm/translate.h
73
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SSBS) != 0;
28
index XXXXXXX..XXXXXXX 100644
74
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
29
--- a/target/arm/translate.h
75
index XXXXXXX..XXXXXXX 100644
30
+++ b/target/arm/translate.h
76
--- a/target/arm/cpu.c
31
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
77
+++ b/target/arm/cpu.c
32
bool ss_same_el;
78
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
33
/* True if v8.3-PAuth is active. */
79
*/
34
bool pauth_active;
80
env->cp15.gcr_el1 = 0x1ffff;
35
+ /* True with v8.5-BTI and SCTLR_ELx.BT* set. */
81
}
36
+ bool bt;
82
+ /*
37
+ /* A copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI. */
83
+ * Disable access to SCXTNUM_EL0 from CSV2_1p2.
38
+ uint8_t btype;
84
+ * This is not yet exposed from the Linux kernel in any way.
39
/* Bottom two bits of XScale c15_cpar coprocessor access control reg */
85
+ */
40
int c15_cpar;
86
+ env->cp15.sctlr_el[1] |= SCTLR_TSCXT;
41
/* TCG op of the current insn_start. */
87
#else
88
/* Reset into the highest available EL */
89
if (arm_feature(env, ARM_FEATURE_EL3)) {
90
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/cpu64.c
93
+++ b/target/arm/cpu64.c
94
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
95
t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
96
t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); /* FEAT_SEL2 */
97
t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
98
- t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 1); /* FEAT_CSV2 */
99
+ t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 2); /* FEAT_CSV2_2 */
100
cpu->isar.id_aa64pfr0 = t;
101
102
t = cpu->isar.id_aa64pfr1;
103
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
104
* we do for EL2 with the virtualization=on property.
105
*/
106
t = FIELD_DP64(t, ID_AA64PFR1, MTE, 3); /* FEAT_MTE3 */
107
+ t = FIELD_DP64(t, ID_AA64PFR1, CSV2_FRAC, 0); /* FEAT_CSV2_2 */
108
cpu->isar.id_aa64pfr1 = t;
109
110
t = cpu->isar.id_aa64mmfr0;
42
diff --git a/target/arm/helper.c b/target/arm/helper.c
111
diff --git a/target/arm/helper.c b/target/arm/helper.c
43
index XXXXXXX..XXXXXXX 100644
112
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/helper.c
113
--- a/target/arm/helper.c
45
+++ b/target/arm/helper.c
114
+++ b/target/arm/helper.c
46
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
115
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
47
116
if (cpu_isar_feature(aa64_mte, cpu)) {
48
if (is_a64(env)) {
117
valid_mask |= SCR_ATA;
49
ARMCPU *cpu = arm_env_get_cpu(env);
50
+ uint64_t sctlr;
51
52
*pc = env->pc;
53
flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
54
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
55
flags = FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len);
56
}
118
}
57
119
+ if (cpu_isar_feature(aa64_scxtnum, cpu)) {
58
+ if (current_el == 0) {
120
+ valid_mask |= SCR_ENSCXT;
59
+ /* FIXME: ARMv8.1-VHE S2 translation regime. */
60
+ sctlr = env->cp15.sctlr_el[1];
61
+ } else {
62
+ sctlr = env->cp15.sctlr_el[current_el];
63
+ }
64
if (cpu_isar_feature(aa64_pauth, cpu)) {
65
/*
66
* In order to save space in flags, we record only whether
67
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
68
* a nop, or "active" when some action must be performed.
69
* The decision of which action to take is left to a helper.
70
*/
71
- uint64_t sctlr;
72
- if (current_el == 0) {
73
- /* FIXME: ARMv8.1-VHE S2 translation regime. */
74
- sctlr = env->cp15.sctlr_el[1];
75
- } else {
76
- sctlr = env->cp15.sctlr_el[current_el];
77
- }
78
if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) {
79
flags = FIELD_DP32(flags, TBFLAG_A64, PAUTH_ACTIVE, 1);
80
}
81
}
82
+
83
+ if (cpu_isar_feature(aa64_bti, cpu)) {
84
+ /* Note that SCTLR_EL[23].BT == SCTLR_BT1. */
85
+ if (sctlr & (current_el == 0 ? SCTLR_BT0 : SCTLR_BT1)) {
86
+ flags = FIELD_DP32(flags, TBFLAG_A64, BT, 1);
87
+ }
88
+ flags = FIELD_DP32(flags, TBFLAG_A64, BTYPE, env->btype);
89
+ }
121
+ }
90
} else {
122
} else {
91
*pc = env->regs[15];
123
valid_mask &= ~(SCR_RW | SCR_ST);
92
flags = FIELD_DP32(flags, TBFLAG_A32, THUMB, env->thumb);
124
if (cpu_isar_feature(aa32_ras, cpu)) {
93
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
125
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
94
index XXXXXXX..XXXXXXX 100644
126
if (cpu_isar_feature(aa64_mte, cpu)) {
95
--- a/target/arm/translate-a64.c
127
valid_mask |= HCR_ATA | HCR_DCT | HCR_TID5;
96
+++ b/target/arm/translate-a64.c
128
}
97
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
129
+ if (cpu_isar_feature(aa64_scxtnum, cpu)) {
98
dc->sve_excp_el = FIELD_EX32(tb_flags, TBFLAG_A64, SVEEXC_EL);
130
+ valid_mask |= HCR_ENSCXT;
99
dc->sve_len = (FIELD_EX32(tb_flags, TBFLAG_A64, ZCR_LEN) + 1) * 16;
131
+ }
100
dc->pauth_active = FIELD_EX32(tb_flags, TBFLAG_A64, PAUTH_ACTIVE);
132
}
101
+ dc->bt = FIELD_EX32(tb_flags, TBFLAG_A64, BT);
133
102
+ dc->btype = FIELD_EX32(tb_flags, TBFLAG_A64, BTYPE);
134
/* Clear RES0 bits. */
103
dc->vec_len = 0;
135
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
104
dc->vec_stride = 0;
136
{ K(3, 0, 5, 6, 0), K(3, 4, 5, 6, 0), K(3, 5, 5, 6, 0),
105
dc->cp_regs = arm_cpu->cp_regs;
137
"TFSR_EL1", "TFSR_EL2", "TFSR_EL12", isar_feature_aa64_mte },
138
139
+ { K(3, 0, 13, 0, 7), K(3, 4, 13, 0, 7), K(3, 5, 13, 0, 7),
140
+ "SCXTNUM_EL1", "SCXTNUM_EL2", "SCXTNUM_EL12",
141
+ isar_feature_aa64_scxtnum },
142
+
143
/* TODO: ARMv8.2-SPE -- PMSCR_EL2 */
144
/* TODO: ARMv8.4-Trace -- TRFCR_EL2 */
145
};
146
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_el0_cacheop_reginfo[] = {
147
},
148
};
149
150
-#endif
151
+static CPAccessResult access_scxtnum(CPUARMState *env, const ARMCPRegInfo *ri,
152
+ bool isread)
153
+{
154
+ uint64_t hcr = arm_hcr_el2_eff(env);
155
+ int el = arm_current_el(env);
156
+
157
+ if (el == 0 && !((hcr & HCR_E2H) && (hcr & HCR_TGE))) {
158
+ if (env->cp15.sctlr_el[1] & SCTLR_TSCXT) {
159
+ if (hcr & HCR_TGE) {
160
+ return CP_ACCESS_TRAP_EL2;
161
+ }
162
+ return CP_ACCESS_TRAP;
163
+ }
164
+ } else if (el < 2 && (env->cp15.sctlr_el[2] & SCTLR_TSCXT)) {
165
+ return CP_ACCESS_TRAP_EL2;
166
+ }
167
+ if (el < 2 && arm_is_el2_enabled(env) && !(hcr & HCR_ENSCXT)) {
168
+ return CP_ACCESS_TRAP_EL2;
169
+ }
170
+ if (el < 3
171
+ && arm_feature(env, ARM_FEATURE_EL3)
172
+ && !(env->cp15.scr_el3 & SCR_ENSCXT)) {
173
+ return CP_ACCESS_TRAP_EL3;
174
+ }
175
+ return CP_ACCESS_OK;
176
+}
177
+
178
+static const ARMCPRegInfo scxtnum_reginfo[] = {
179
+ { .name = "SCXTNUM_EL0", .state = ARM_CP_STATE_AA64,
180
+ .opc0 = 3, .opc1 = 3, .crn = 13, .crm = 0, .opc2 = 7,
181
+ .access = PL0_RW, .accessfn = access_scxtnum,
182
+ .fieldoffset = offsetof(CPUARMState, scxtnum_el[0]) },
183
+ { .name = "SCXTNUM_EL1", .state = ARM_CP_STATE_AA64,
184
+ .opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 7,
185
+ .access = PL1_RW, .accessfn = access_scxtnum,
186
+ .fieldoffset = offsetof(CPUARMState, scxtnum_el[1]) },
187
+ { .name = "SCXTNUM_EL2", .state = ARM_CP_STATE_AA64,
188
+ .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 7,
189
+ .access = PL2_RW, .accessfn = access_scxtnum,
190
+ .fieldoffset = offsetof(CPUARMState, scxtnum_el[2]) },
191
+ { .name = "SCXTNUM_EL3", .state = ARM_CP_STATE_AA64,
192
+ .opc0 = 3, .opc1 = 6, .crn = 13, .crm = 0, .opc2 = 7,
193
+ .access = PL3_RW,
194
+ .fieldoffset = offsetof(CPUARMState, scxtnum_el[3]) },
195
+};
196
+#endif /* TARGET_AARCH64 */
197
198
static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
199
bool isread)
200
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
201
define_arm_cp_regs(cpu, mte_tco_ro_reginfo);
202
define_arm_cp_regs(cpu, mte_el0_cacheop_reginfo);
203
}
204
+
205
+ if (cpu_isar_feature(aa64_scxtnum, cpu)) {
206
+ define_arm_cp_regs(cpu, scxtnum_reginfo);
207
+ }
208
#endif
209
210
if (cpu_isar_feature(any_predinv, cpu)) {
106
--
211
--
107
2.20.1
212
2.25.1
108
109
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
3
This extension concerns cache speculation, which TCG does
4
not implement. Thus we can trivially enable this feature.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190201195404.30486-3-richard.henderson@linaro.org
8
Message-id: 20220506180242.216785-22-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
tests/tcg/aarch64/Makefile.target | 6 +++++-
11
docs/system/arm/emulation.rst | 1 +
9
tests/tcg/aarch64/pauth-1.c | 23 +++++++++++++++++++++++
12
target/arm/cpu64.c | 1 +
10
2 files changed, 28 insertions(+), 1 deletion(-)
13
target/arm/cpu_tcg.c | 1 +
11
create mode 100644 tests/tcg/aarch64/pauth-1.c
14
3 files changed, 3 insertions(+)
12
15
13
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
16
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/tests/tcg/aarch64/Makefile.target
18
--- a/docs/system/arm/emulation.rst
16
+++ b/tests/tcg/aarch64/Makefile.target
19
+++ b/docs/system/arm/emulation.rst
17
@@ -XXX,XX +XXX,XX @@ VPATH         += $(AARCH64_SRC)
20
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
18
# we don't build any of the ARM tests
21
- FEAT_CSV2_1p1 (Cache speculation variant 2, version 1.1)
19
AARCH64_TESTS=$(filter-out $(ARM_TESTS), $(TESTS))
22
- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
20
AARCH64_TESTS+=fcvt
23
- FEAT_CSV2_2 (Cache speculation variant 2, version 2)
21
-TESTS:=$(AARCH64_TESTS)
24
+- FEAT_CSV3 (Cache speculation variant 3)
22
25
- FEAT_DIT (Data Independent Timing instructions)
23
fcvt: LDFLAGS+=-lm
26
- FEAT_DPB (DC CVAP instruction)
24
27
- FEAT_Debugv8p2 (Debug changes for v8.2)
25
run-fcvt: fcvt
28
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
26
    $(call run-test,$<,$(QEMU) $<, "$< on $(TARGET_NAME)")
29
index XXXXXXX..XXXXXXX 100644
27
    $(call diff-out,$<,$(AARCH64_SRC)/fcvt.ref)
30
--- a/target/arm/cpu64.c
28
+
31
+++ b/target/arm/cpu64.c
29
+AARCH64_TESTS += pauth-1
32
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
30
+run-pauth-%: QEMU += -cpu max
33
t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); /* FEAT_SEL2 */
31
+
34
t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
32
+TESTS:=$(AARCH64_TESTS)
35
t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 2); /* FEAT_CSV2_2 */
33
diff --git a/tests/tcg/aarch64/pauth-1.c b/tests/tcg/aarch64/pauth-1.c
36
+ t = FIELD_DP64(t, ID_AA64PFR0, CSV3, 1); /* FEAT_CSV3 */
34
new file mode 100644
37
cpu->isar.id_aa64pfr0 = t;
35
index XXXXXXX..XXXXXXX
38
36
--- /dev/null
39
t = cpu->isar.id_aa64pfr1;
37
+++ b/tests/tcg/aarch64/pauth-1.c
40
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
38
@@ -XXX,XX +XXX,XX @@
41
index XXXXXXX..XXXXXXX 100644
39
+#include <assert.h>
42
--- a/target/arm/cpu_tcg.c
40
+#include <sys/prctl.h>
43
+++ b/target/arm/cpu_tcg.c
41
+
44
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
42
+asm(".arch armv8.4-a");
45
cpu->isar.id_pfr0 = t;
43
+
46
44
+#ifndef PR_PAC_RESET_KEYS
47
t = cpu->isar.id_pfr2;
45
+#define PR_PAC_RESET_KEYS 54
48
+ t = FIELD_DP32(t, ID_PFR2, CSV3, 1); /* FEAT_CSV3 */
46
+#define PR_PAC_APDAKEY (1 << 2)
49
t = FIELD_DP32(t, ID_PFR2, SSBS, 1); /* FEAT_SSBS */
47
+#endif
50
cpu->isar.id_pfr2 = t;
48
+
51
49
+int main()
50
+{
51
+ int x;
52
+ void *p0 = &x, *p1, *p2;
53
+
54
+ asm volatile("pacdza %0" : "=r"(p1) : "0"(p0));
55
+ prctl(PR_PAC_RESET_KEYS, PR_PAC_APDAKEY, 0, 0, 0);
56
+ asm volatile("pacdza %0" : "=r"(p2) : "0"(p0));
57
+
58
+ assert(p1 != p0);
59
+ assert(p1 != p2);
60
+ return 0;
61
+}
62
--
52
--
63
2.20.1
53
2.25.1
64
65
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Place this in its own field within ENV, as that will
3
This extension concerns not merging memory access, which TCG does
4
make it easier to reset from within TCG generated code.
4
not implement. Thus we can trivially enable this feature.
5
5
Add a comment to handle_hint for the DGH instruction, but no code.
6
With the change to pstate_read/write, exception entry
7
and return are automatically handled.
8
6
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20190128223118.5255-3-richard.henderson@linaro.org
9
Message-id: 20220506180242.216785-23-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
11
---
14
target/arm/cpu.h | 8 ++++++--
12
docs/system/arm/emulation.rst | 1 +
15
target/arm/translate-a64.c | 3 +++
13
target/arm/cpu64.c | 1 +
16
2 files changed, 9 insertions(+), 2 deletions(-)
14
target/arm/translate-a64.c | 1 +
15
3 files changed, 3 insertions(+)
17
16
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
19
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
19
--- a/docs/system/arm/emulation.rst
21
+++ b/target/arm/cpu.h
20
+++ b/docs/system/arm/emulation.rst
22
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
21
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
23
* semantics as for AArch32, as described in the comments on each field)
22
- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
24
* nRW (also known as M[4]) is kept, inverted, in env->aarch64
23
- FEAT_CSV2_2 (Cache speculation variant 2, version 2)
25
* DAIF (exception masks) are kept in env->daif
24
- FEAT_CSV3 (Cache speculation variant 3)
26
+ * BTYPE is kept in env->btype
25
+- FEAT_DGH (Data gathering hint)
27
* all other bits are stored in their correct places in env->pstate
26
- FEAT_DIT (Data Independent Timing instructions)
28
*/
27
- FEAT_DPB (DC CVAP instruction)
29
uint32_t pstate;
28
- FEAT_Debugv8p2 (Debug changes for v8.2)
30
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
29
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
31
uint32_t GE; /* cpsr[19:16] */
30
index XXXXXXX..XXXXXXX 100644
32
uint32_t thumb; /* cpsr[5]. 0 = arm mode, 1 = thumb mode. */
31
--- a/target/arm/cpu64.c
33
uint32_t condexec_bits; /* IT bits. cpsr[15:10,26:25]. */
32
+++ b/target/arm/cpu64.c
34
+ uint32_t btype; /* BTI branch type. spsr[11:10]. */
33
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
35
uint64_t daif; /* exception masks, in the bits they are in PSTATE */
34
t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1); /* FEAT_SB */
36
35
t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1); /* FEAT_SPECRES */
37
uint64_t elr_el[4]; /* AArch64 exception link regs */
36
t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 1); /* FEAT_BF16 */
38
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
37
+ t = FIELD_DP64(t, ID_AA64ISAR1, DGH, 1); /* FEAT_DGH */
39
#define PSTATE_I (1U << 7)
38
t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1); /* FEAT_I8MM */
40
#define PSTATE_A (1U << 8)
39
cpu->isar.id_aa64isar1 = t;
41
#define PSTATE_D (1U << 9)
42
+#define PSTATE_BTYPE (3U << 10)
43
#define PSTATE_IL (1U << 20)
44
#define PSTATE_SS (1U << 21)
45
#define PSTATE_V (1U << 28)
46
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
47
#define PSTATE_N (1U << 31)
48
#define PSTATE_NZCV (PSTATE_N | PSTATE_Z | PSTATE_C | PSTATE_V)
49
#define PSTATE_DAIF (PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F)
50
-#define CACHED_PSTATE_BITS (PSTATE_NZCV | PSTATE_DAIF)
51
+#define CACHED_PSTATE_BITS (PSTATE_NZCV | PSTATE_DAIF | PSTATE_BTYPE)
52
/* Mode values for AArch64 */
53
#define PSTATE_MODE_EL3h 13
54
#define PSTATE_MODE_EL3t 12
55
@@ -XXX,XX +XXX,XX @@ static inline uint32_t pstate_read(CPUARMState *env)
56
ZF = (env->ZF == 0);
57
return (env->NF & 0x80000000) | (ZF << 30)
58
| (env->CF << 29) | ((env->VF & 0x80000000) >> 3)
59
- | env->pstate | env->daif;
60
+ | env->pstate | env->daif | (env->btype << 10);
61
}
62
63
static inline void pstate_write(CPUARMState *env, uint32_t val)
64
@@ -XXX,XX +XXX,XX @@ static inline void pstate_write(CPUARMState *env, uint32_t val)
65
env->CF = (val >> 29) & 1;
66
env->VF = (val << 3) & 0x80000000;
67
env->daif = val & PSTATE_DAIF;
68
+ env->btype = (val >> 10) & 3;
69
env->pstate = val & ~CACHED_PSTATE_BITS;
70
}
71
40
72
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
41
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
73
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/translate-a64.c
43
--- a/target/arm/translate-a64.c
75
+++ b/target/arm/translate-a64.c
44
+++ b/target/arm/translate-a64.c
76
@@ -XXX,XX +XXX,XX @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
45
@@ -XXX,XX +XXX,XX @@ static void handle_hint(DisasContext *s, uint32_t insn,
77
el,
46
break;
78
psr & PSTATE_SP ? 'h' : 't');
47
case 0b00100: /* SEV */
79
48
case 0b00101: /* SEVL */
80
+ if (cpu_isar_feature(aa64_bti, cpu)) {
49
+ case 0b00110: /* DGH */
81
+ cpu_fprintf(f, " BTYPE=%d", (psr & PSTATE_BTYPE) >> 10);
50
/* we treat all as NOP at least for now */
82
+ }
51
break;
83
if (!(flags & CPU_DUMP_FPU)) {
52
case 0b00111: /* XPACLRI */
84
cpu_fprintf(f, "\n");
85
return;
86
--
53
--
87
2.20.1
54
2.25.1
88
89
diff view generated by jsdifflib
1
Factor out the "boot via firmware" code path from arm_load_kernel()
1
From: Richard Henderson <richard.henderson@linaro.org>
2
into its own function.
3
2
4
This commit only moves code around; no semantic changes.
3
Enable the a76 for virt and sbsa board use.
5
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220506180242.216785-24-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
9
Message-id: 20190131112240.8395-4-peter.maydell@linaro.org
10
---
9
---
11
hw/arm/boot.c | 92 +++++++++++++++++++++++++++------------------------
10
docs/system/arm/virt.rst | 1 +
12
1 file changed, 49 insertions(+), 43 deletions(-)
11
hw/arm/sbsa-ref.c | 1 +
12
hw/arm/virt.c | 1 +
13
target/arm/cpu64.c | 66 ++++++++++++++++++++++++++++++++++++++++
14
4 files changed, 69 insertions(+)
13
15
14
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
16
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/boot.c
18
--- a/docs/system/arm/virt.rst
17
+++ b/hw/arm/boot.c
19
+++ b/docs/system/arm/virt.rst
18
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
20
@@ -XXX,XX +XXX,XX @@ Supported guest CPU types:
19
}
21
- ``cortex-a53`` (64-bit)
22
- ``cortex-a57`` (64-bit)
23
- ``cortex-a72`` (64-bit)
24
+- ``cortex-a76`` (64-bit)
25
- ``a64fx`` (64-bit)
26
- ``host`` (with KVM only)
27
- ``max`` (same as ``host`` for KVM; best possible emulation with TCG)
28
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/sbsa-ref.c
31
+++ b/hw/arm/sbsa-ref.c
32
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
33
static const char * const valid_cpus[] = {
34
ARM_CPU_TYPE_NAME("cortex-a57"),
35
ARM_CPU_TYPE_NAME("cortex-a72"),
36
+ ARM_CPU_TYPE_NAME("cortex-a76"),
37
ARM_CPU_TYPE_NAME("max"),
38
};
39
40
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/arm/virt.c
43
+++ b/hw/arm/virt.c
44
@@ -XXX,XX +XXX,XX @@ static const char *valid_cpus[] = {
45
ARM_CPU_TYPE_NAME("cortex-a53"),
46
ARM_CPU_TYPE_NAME("cortex-a57"),
47
ARM_CPU_TYPE_NAME("cortex-a72"),
48
+ ARM_CPU_TYPE_NAME("cortex-a76"),
49
ARM_CPU_TYPE_NAME("a64fx"),
50
ARM_CPU_TYPE_NAME("host"),
51
ARM_CPU_TYPE_NAME("max"),
52
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/cpu64.c
55
+++ b/target/arm/cpu64.c
56
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
57
define_cortex_a72_a57_a53_cp_reginfo(cpu);
20
}
58
}
21
59
22
+static void arm_setup_firmware_boot(ARMCPU *cpu, struct arm_boot_info *info)
60
+static void aarch64_a76_initfn(Object *obj)
23
+{
61
+{
24
+ /* Set up for booting firmware (which might load a kernel via fw_cfg) */
62
+ ARMCPU *cpu = ARM_CPU(obj);
25
+
63
+
26
+ if (have_dtb(info)) {
64
+ cpu->dtb_compatible = "arm,cortex-a76";
27
+ /*
65
+ set_feature(&cpu->env, ARM_FEATURE_V8);
28
+ * If we have a device tree blob, but no kernel to supply it to (or
66
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
29
+ * the kernel is supposed to be loaded by the bootloader), copy the
67
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
30
+ * DTB to the base of RAM for the bootloader to pick up.
68
+ set_feature(&cpu->env, ARM_FEATURE_AARCH64);
31
+ */
69
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
32
+ info->dtb_start = info->loader_start;
70
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
33
+ }
71
+ set_feature(&cpu->env, ARM_FEATURE_EL3);
72
+ set_feature(&cpu->env, ARM_FEATURE_PMU);
34
+
73
+
35
+ if (info->kernel_filename) {
74
+ /* Ordered by B2.4 AArch64 registers by functional group */
36
+ FWCfgState *fw_cfg;
75
+ cpu->clidr = 0x82000023;
37
+ bool try_decompressing_kernel;
76
+ cpu->ctr = 0x8444C004;
77
+ cpu->dcz_blocksize = 4;
78
+ cpu->isar.id_aa64dfr0 = 0x0000000010305408ull;
79
+ cpu->isar.id_aa64isar0 = 0x0000100010211120ull;
80
+ cpu->isar.id_aa64isar1 = 0x0000000000100001ull;
81
+ cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull;
82
+ cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
83
+ cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull;
84
+ cpu->isar.id_aa64pfr0 = 0x1100000010111112ull; /* GIC filled in later */
85
+ cpu->isar.id_aa64pfr1 = 0x0000000000000010ull;
86
+ cpu->id_afr0 = 0x00000000;
87
+ cpu->isar.id_dfr0 = 0x04010088;
88
+ cpu->isar.id_isar0 = 0x02101110;
89
+ cpu->isar.id_isar1 = 0x13112111;
90
+ cpu->isar.id_isar2 = 0x21232042;
91
+ cpu->isar.id_isar3 = 0x01112131;
92
+ cpu->isar.id_isar4 = 0x00010142;
93
+ cpu->isar.id_isar5 = 0x01011121;
94
+ cpu->isar.id_isar6 = 0x00000010;
95
+ cpu->isar.id_mmfr0 = 0x10201105;
96
+ cpu->isar.id_mmfr1 = 0x40000000;
97
+ cpu->isar.id_mmfr2 = 0x01260000;
98
+ cpu->isar.id_mmfr3 = 0x02122211;
99
+ cpu->isar.id_mmfr4 = 0x00021110;
100
+ cpu->isar.id_pfr0 = 0x10010131;
101
+ cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */
102
+ cpu->isar.id_pfr2 = 0x00000011;
103
+ cpu->midr = 0x414fd0b1; /* r4p1 */
104
+ cpu->revidr = 0;
38
+
105
+
39
+ fw_cfg = fw_cfg_find();
106
+ /* From B2.18 CCSIDR_EL1 */
40
+ try_decompressing_kernel = arm_feature(&cpu->env,
107
+ cpu->ccsidr[0] = 0x701fe01a; /* 64KB L1 dcache */
41
+ ARM_FEATURE_AARCH64);
108
+ cpu->ccsidr[1] = 0x201fe01a; /* 64KB L1 icache */
109
+ cpu->ccsidr[2] = 0x707fe03a; /* 512KB L2 cache */
42
+
110
+
43
+ /*
111
+ /* From B2.93 SCTLR_EL3 */
44
+ * Expose the kernel, the command line, and the initrd in fw_cfg.
112
+ cpu->reset_sctlr = 0x30c50838;
45
+ * We don't process them here at all, it's all left to the
46
+ * firmware.
47
+ */
48
+ load_image_to_fw_cfg(fw_cfg,
49
+ FW_CFG_KERNEL_SIZE, FW_CFG_KERNEL_DATA,
50
+ info->kernel_filename,
51
+ try_decompressing_kernel);
52
+ load_image_to_fw_cfg(fw_cfg,
53
+ FW_CFG_INITRD_SIZE, FW_CFG_INITRD_DATA,
54
+ info->initrd_filename, false);
55
+
113
+
56
+ if (info->kernel_cmdline) {
114
+ /* From B4.23 ICH_VTR_EL2 */
57
+ fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
115
+ cpu->gic_num_lrs = 4;
58
+ strlen(info->kernel_cmdline) + 1);
116
+ cpu->gic_vpribits = 5;
59
+ fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA,
117
+ cpu->gic_vprebits = 5;
60
+ info->kernel_cmdline);
61
+ }
62
+ }
63
+
118
+
64
+ /*
119
+ /* From B5.1 AdvSIMD AArch64 register summary */
65
+ * We will start from address 0 (typically a boot ROM image) in the
120
+ cpu->isar.mvfr0 = 0x10110222;
66
+ * same way as hardware.
121
+ cpu->isar.mvfr1 = 0x13211111;
67
+ */
122
+ cpu->isar.mvfr2 = 0x00000043;
68
+}
123
+}
69
+
124
+
70
void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
125
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
71
{
126
{
72
CPUState *cs;
127
/*
73
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
128
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo aarch64_cpus[] = {
74
129
{ .name = "cortex-a57", .initfn = aarch64_a57_initfn },
75
/* Load the kernel. */
130
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
76
if (!info->kernel_filename || info->firmware_loaded) {
131
{ .name = "cortex-a72", .initfn = aarch64_a72_initfn },
77
-
132
+ { .name = "cortex-a76", .initfn = aarch64_a76_initfn },
78
- if (have_dtb(info)) {
133
{ .name = "a64fx", .initfn = aarch64_a64fx_initfn },
79
- /*
134
{ .name = "max", .initfn = aarch64_max_initfn },
80
- * If we have a device tree blob, but no kernel to supply it to (or
135
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
81
- * the kernel is supposed to be loaded by the bootloader), copy the
82
- * DTB to the base of RAM for the bootloader to pick up.
83
- */
84
- info->dtb_start = info->loader_start;
85
- }
86
-
87
- if (info->kernel_filename) {
88
- FWCfgState *fw_cfg;
89
- bool try_decompressing_kernel;
90
-
91
- fw_cfg = fw_cfg_find();
92
- try_decompressing_kernel = arm_feature(&cpu->env,
93
- ARM_FEATURE_AARCH64);
94
-
95
- /*
96
- * Expose the kernel, the command line, and the initrd in fw_cfg.
97
- * We don't process them here at all, it's all left to the
98
- * firmware.
99
- */
100
- load_image_to_fw_cfg(fw_cfg,
101
- FW_CFG_KERNEL_SIZE, FW_CFG_KERNEL_DATA,
102
- info->kernel_filename,
103
- try_decompressing_kernel);
104
- load_image_to_fw_cfg(fw_cfg,
105
- FW_CFG_INITRD_SIZE, FW_CFG_INITRD_DATA,
106
- info->initrd_filename, false);
107
-
108
- if (info->kernel_cmdline) {
109
- fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
110
- strlen(info->kernel_cmdline) + 1);
111
- fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA,
112
- info->kernel_cmdline);
113
- }
114
- }
115
-
116
- /*
117
- * We will start from address 0 (typically a boot ROM image) in the
118
- * same way as hardware.
119
- */
120
+ arm_setup_firmware_boot(cpu, info);
121
return;
122
} else {
123
arm_setup_direct_kernel_boot(cpu, info);
124
--
136
--
125
2.20.1
137
2.25.1
126
127
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
These bits can be used to cache target-specific data in cputlb
3
Enable the n1 for virt and sbsa board use.
4
read from the page tables.
5
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20220506180242.216785-25-richard.henderson@linaro.org
8
Message-id: 20190128223118.5255-5-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
include/exec/memattrs.h | 10 ++++++++++
10
docs/system/arm/virt.rst | 1 +
12
1 file changed, 10 insertions(+)
11
hw/arm/sbsa-ref.c | 1 +
12
hw/arm/virt.c | 1 +
13
target/arm/cpu64.c | 66 ++++++++++++++++++++++++++++++++++++++++
14
4 files changed, 69 insertions(+)
13
15
14
diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h
16
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/include/exec/memattrs.h
18
--- a/docs/system/arm/virt.rst
17
+++ b/include/exec/memattrs.h
19
+++ b/docs/system/arm/virt.rst
18
@@ -XXX,XX +XXX,XX @@ typedef struct MemTxAttrs {
20
@@ -XXX,XX +XXX,XX @@ Supported guest CPU types:
19
unsigned int user:1;
21
- ``cortex-a76`` (64-bit)
20
/* Requester ID (for MSI for example) */
22
- ``a64fx`` (64-bit)
21
unsigned int requester_id:16;
23
- ``host`` (with KVM only)
22
+ /*
24
+- ``neoverse-n1`` (64-bit)
23
+ * The following are target-specific page-table bits. These are not
25
- ``max`` (same as ``host`` for KVM; best possible emulation with TCG)
24
+ * related to actual memory transactions at all. However, this structure
26
25
+ * is part of the tlb_fill interface, cached in the cputlb structure,
27
Note that the default is ``cortex-a15``, so for an AArch64 guest you must
26
+ * and has unused bits. These fields will be read by target-specific
28
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
27
+ * helpers using env->iotlb[mmu_idx][tlb_index()].attrs.target_tlb_bitN.
29
index XXXXXXX..XXXXXXX 100644
28
+ */
30
--- a/hw/arm/sbsa-ref.c
29
+ unsigned int target_tlb_bit0 : 1;
31
+++ b/hw/arm/sbsa-ref.c
30
+ unsigned int target_tlb_bit1 : 1;
32
@@ -XXX,XX +XXX,XX @@ static const char * const valid_cpus[] = {
31
+ unsigned int target_tlb_bit2 : 1;
33
ARM_CPU_TYPE_NAME("cortex-a57"),
32
} MemTxAttrs;
34
ARM_CPU_TYPE_NAME("cortex-a72"),
33
35
ARM_CPU_TYPE_NAME("cortex-a76"),
34
/* Bus masters which don't specify any attributes will get this,
36
+ ARM_CPU_TYPE_NAME("neoverse-n1"),
37
ARM_CPU_TYPE_NAME("max"),
38
};
39
40
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/arm/virt.c
43
+++ b/hw/arm/virt.c
44
@@ -XXX,XX +XXX,XX @@ static const char *valid_cpus[] = {
45
ARM_CPU_TYPE_NAME("cortex-a72"),
46
ARM_CPU_TYPE_NAME("cortex-a76"),
47
ARM_CPU_TYPE_NAME("a64fx"),
48
+ ARM_CPU_TYPE_NAME("neoverse-n1"),
49
ARM_CPU_TYPE_NAME("host"),
50
ARM_CPU_TYPE_NAME("max"),
51
};
52
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/cpu64.c
55
+++ b/target/arm/cpu64.c
56
@@ -XXX,XX +XXX,XX @@ static void aarch64_a76_initfn(Object *obj)
57
cpu->isar.mvfr2 = 0x00000043;
58
}
59
60
+static void aarch64_neoverse_n1_initfn(Object *obj)
61
+{
62
+ ARMCPU *cpu = ARM_CPU(obj);
63
+
64
+ cpu->dtb_compatible = "arm,neoverse-n1";
65
+ set_feature(&cpu->env, ARM_FEATURE_V8);
66
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
67
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
68
+ set_feature(&cpu->env, ARM_FEATURE_AARCH64);
69
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
70
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
71
+ set_feature(&cpu->env, ARM_FEATURE_EL3);
72
+ set_feature(&cpu->env, ARM_FEATURE_PMU);
73
+
74
+ /* Ordered by B2.4 AArch64 registers by functional group */
75
+ cpu->clidr = 0x82000023;
76
+ cpu->ctr = 0x8444c004;
77
+ cpu->dcz_blocksize = 4;
78
+ cpu->isar.id_aa64dfr0 = 0x0000000110305408ull;
79
+ cpu->isar.id_aa64isar0 = 0x0000100010211120ull;
80
+ cpu->isar.id_aa64isar1 = 0x0000000000100001ull;
81
+ cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull;
82
+ cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
83
+ cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull;
84
+ cpu->isar.id_aa64pfr0 = 0x1100000010111112ull; /* GIC filled in later */
85
+ cpu->isar.id_aa64pfr1 = 0x0000000000000020ull;
86
+ cpu->id_afr0 = 0x00000000;
87
+ cpu->isar.id_dfr0 = 0x04010088;
88
+ cpu->isar.id_isar0 = 0x02101110;
89
+ cpu->isar.id_isar1 = 0x13112111;
90
+ cpu->isar.id_isar2 = 0x21232042;
91
+ cpu->isar.id_isar3 = 0x01112131;
92
+ cpu->isar.id_isar4 = 0x00010142;
93
+ cpu->isar.id_isar5 = 0x01011121;
94
+ cpu->isar.id_isar6 = 0x00000010;
95
+ cpu->isar.id_mmfr0 = 0x10201105;
96
+ cpu->isar.id_mmfr1 = 0x40000000;
97
+ cpu->isar.id_mmfr2 = 0x01260000;
98
+ cpu->isar.id_mmfr3 = 0x02122211;
99
+ cpu->isar.id_mmfr4 = 0x00021110;
100
+ cpu->isar.id_pfr0 = 0x10010131;
101
+ cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */
102
+ cpu->isar.id_pfr2 = 0x00000011;
103
+ cpu->midr = 0x414fd0c1; /* r4p1 */
104
+ cpu->revidr = 0;
105
+
106
+ /* From B2.23 CCSIDR_EL1 */
107
+ cpu->ccsidr[0] = 0x701fe01a; /* 64KB L1 dcache */
108
+ cpu->ccsidr[1] = 0x201fe01a; /* 64KB L1 icache */
109
+ cpu->ccsidr[2] = 0x70ffe03a; /* 1MB L2 cache */
110
+
111
+ /* From B2.98 SCTLR_EL3 */
112
+ cpu->reset_sctlr = 0x30c50838;
113
+
114
+ /* From B4.23 ICH_VTR_EL2 */
115
+ cpu->gic_num_lrs = 4;
116
+ cpu->gic_vpribits = 5;
117
+ cpu->gic_vprebits = 5;
118
+
119
+ /* From B5.1 AdvSIMD AArch64 register summary */
120
+ cpu->isar.mvfr0 = 0x10110222;
121
+ cpu->isar.mvfr1 = 0x13211111;
122
+ cpu->isar.mvfr2 = 0x00000043;
123
+}
124
+
125
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
126
{
127
/*
128
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo aarch64_cpus[] = {
129
{ .name = "cortex-a72", .initfn = aarch64_a72_initfn },
130
{ .name = "cortex-a76", .initfn = aarch64_a76_initfn },
131
{ .name = "a64fx", .initfn = aarch64_a64fx_initfn },
132
+ { .name = "neoverse-n1", .initfn = aarch64_neoverse_n1_initfn },
133
{ .name = "max", .initfn = aarch64_max_initfn },
134
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
135
{ .name = "host", .initfn = aarch64_host_initfn },
35
--
136
--
36
2.20.1
137
2.25.1
37
38
diff view generated by jsdifflib
1
From: Max Filippov <jcmvbkbc@gmail.com>
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
2
3
With multiprocess extensions gdb uses 'vKill' packet instead of 'k' to
3
The sbsa-ref machine is continuously evolving. Some of the changes we
4
kill the inferior. Handle 'vKill' the same way 'k' was handled in the
4
want to make in the near future, to align with real components (e.g.
5
presence of single process.
5
the GIC-700), will break compatibility for existing firmware.
6
6
7
Fixes: 7cf48f6752e5 ("gdbstub: add multiprocess support to
7
Introduce two new properties to the DT generated on machine generation:
8
(f|s)ThreadInfo and ThreadExtraInfo")
8
- machine-version-major
9
To be incremented when a platform change makes the machine
10
incompatible with existing firmware.
11
- machine-version-minor
12
To be incremented when functionality is added to the machine
13
without causing incompatibility with existing firmware.
14
to be reset to 0 when machine-version-major is incremented.
9
15
10
Cc: Luc Michel <luc.michel@greensocs.com>
16
This versioning scheme is *neither*:
11
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
17
- A QEMU versioned machine type; a given version of QEMU will emulate
12
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
18
a given version of the platform.
13
Reviewed-by: KONRAD Frederic <frederic.konrad@adacore.com>
19
- A reflection of level of SBSA (now SystemReady SR) support provided.
14
Tested-by: KONRAD Frederic <frederic.konrad@adacore.com>
20
15
Message-id: 20190130192403.13754-1-jcmvbkbc@gmail.com
21
The version will increment on guest-visible functional changes only,
22
akin to a revision ID register found on a physical platform.
23
24
These properties are both introduced with the value 0.
25
(Hence, a machine where the DT is lacking these nodes is equivalent
26
to version 0.0.)
27
28
Signed-off-by: Leif Lindholm <quic_llindhol@quicinc.com>
29
Message-id: 20220505113947.75714-1-quic_llindhol@quicinc.com
30
Cc: Peter Maydell <peter.maydell@linaro.org>
31
Cc: Radoslaw Biernacki <rad@semihalf.com>
32
Cc: Cédric Le Goater <clg@kaod.org>
33
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
35
---
18
gdbstub.c | 4 ++++
36
hw/arm/sbsa-ref.c | 14 ++++++++++++++
19
1 file changed, 4 insertions(+)
37
1 file changed, 14 insertions(+)
20
38
21
diff --git a/gdbstub.c b/gdbstub.c
39
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
22
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
23
--- a/gdbstub.c
41
--- a/hw/arm/sbsa-ref.c
24
+++ b/gdbstub.c
42
+++ b/hw/arm/sbsa-ref.c
25
@@ -XXX,XX +XXX,XX @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
43
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SBSAMachineState *sms)
26
44
qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
27
put_packet(s, buf);
45
qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
28
break;
46
29
+ } else if (strncmp(p, "Kill;", 5) == 0) {
47
+ /*
30
+ /* Kill the target */
48
+ * This versioning scheme is for informing platform fw only. It is neither:
31
+ error_report("QEMU: Terminated via GDBstub");
49
+ * - A QEMU versioned machine type; a given version of QEMU will emulate
32
+ exit(0);
50
+ * a given version of the platform.
33
} else {
51
+ * - A reflection of level of SBSA (now SystemReady SR) support provided.
34
goto unknown_command;
52
+ *
35
}
53
+ * machine-version-major: updated when changes breaking fw compatibility
54
+ * are introduced.
55
+ * machine-version-minor: updated when features are added that don't break
56
+ * fw compatibility.
57
+ */
58
+ qemu_fdt_setprop_cell(fdt, "/", "machine-version-major", 0);
59
+ qemu_fdt_setprop_cell(fdt, "/", "machine-version-minor", 0);
60
+
61
if (ms->numa_state->have_numa_distance) {
62
int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
63
uint32_t *matrix = g_malloc0(size);
36
--
64
--
37
2.20.1
65
2.25.1
38
66
39
67
diff view generated by jsdifflib
1
Factor out the "direct kernel boot" code path from arm_load_kernel()
1
From: Gavin Shan <gshan@redhat.com>
2
into its own function; this function is getting long enough that
3
the code flow is a bit confusing.
4
2
5
This commit only moves code around; no semantic changes.
3
This adds cluster-id in CPU instance properties, which will be used
4
by arm/virt machine. Besides, the cluster-id is also verified or
5
dumped in various spots:
6
6
7
We leave the "load the dtb" code in arm_load_kernel() -- this
7
* hw/core/machine.c::machine_set_cpu_numa_node() to associate
8
is currently only used by the "direct kernel boot" path, but
8
CPU with its NUMA node.
9
this is a bug which we will fix shortly.
10
9
10
* hw/core/machine.c::machine_numa_finish_cpu_init() to record
11
CPU slots with no NUMA mapping set.
12
13
* hw/core/machine-hmp-cmds.c::hmp_hotpluggable_cpus() to dump
14
cluster-id.
15
16
Signed-off-by: Gavin Shan <gshan@redhat.com>
17
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
18
Acked-by: Igor Mammedov <imammedo@redhat.com>
19
Message-id: 20220503140304.855514-2-gshan@redhat.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
14
Message-id: 20190131112240.8395-3-peter.maydell@linaro.org
15
---
21
---
16
hw/arm/boot.c | 150 +++++++++++++++++++++++++++-----------------------
22
qapi/machine.json | 6 ++++--
17
1 file changed, 80 insertions(+), 70 deletions(-)
23
hw/core/machine-hmp-cmds.c | 4 ++++
24
hw/core/machine.c | 16 ++++++++++++++++
25
3 files changed, 24 insertions(+), 2 deletions(-)
18
26
19
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
27
diff --git a/qapi/machine.json b/qapi/machine.json
20
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/boot.c
29
--- a/qapi/machine.json
22
+++ b/hw/arm/boot.c
30
+++ b/qapi/machine.json
23
@@ -XXX,XX +XXX,XX @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
31
@@ -XXX,XX +XXX,XX @@
24
return size;
32
# @node-id: NUMA node ID the CPU belongs to
25
}
33
# @socket-id: socket number within node/board the CPU belongs to
26
34
# @die-id: die number within socket the CPU belongs to (since 4.1)
27
-void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
35
-# @core-id: core number within die the CPU belongs to
28
+static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
36
+# @cluster-id: cluster number within die the CPU belongs to (since 7.1)
29
+ struct arm_boot_info *info)
37
+# @core-id: core number within cluster the CPU belongs to
30
{
38
# @thread-id: thread number within core the CPU belongs to
31
+ /* Set up for a direct boot of a kernel image file. */
39
#
32
CPUState *cs;
40
-# Note: currently there are 5 properties that could be present
33
+ AddressSpace *as = arm_boot_address_space(cpu, info);
41
+# Note: currently there are 6 properties that could be present
34
int kernel_size;
42
# but management should be prepared to pass through other
35
int initrd_size;
43
# properties with device_add command to allow for future
36
int is_linux = 0;
44
# interface extension. This also requires the filed names to be kept in
37
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
45
@@ -XXX,XX +XXX,XX @@
38
int elf_machine;
46
'data': { '*node-id': 'int',
39
hwaddr entry;
47
'*socket-id': 'int',
40
static const ARMInsnFixup *primary_loader;
48
'*die-id': 'int',
41
- AddressSpace *as = arm_boot_address_space(cpu, info);
49
+ '*cluster-id': 'int',
42
-
50
'*core-id': 'int',
43
- /*
51
'*thread-id': 'int'
44
- * CPU objects (unlike devices) are not automatically reset on system
52
}
45
- * reset, so we must always register a handler to do so. If we're
53
diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
46
- * actually loading a kernel, the handler is also responsible for
54
index XXXXXXX..XXXXXXX 100644
47
- * arranging that we start it correctly.
55
--- a/hw/core/machine-hmp-cmds.c
48
- */
56
+++ b/hw/core/machine-hmp-cmds.c
49
- for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
57
@@ -XXX,XX +XXX,XX @@ void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict)
50
- qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
58
if (c->has_die_id) {
51
- }
59
monitor_printf(mon, " die-id: \"%" PRIu64 "\"\n", c->die_id);
52
-
60
}
53
- /*
61
+ if (c->has_cluster_id) {
54
- * The board code is not supposed to set secure_board_setup unless
62
+ monitor_printf(mon, " cluster-id: \"%" PRIu64 "\"\n",
55
- * running its code in secure mode is actually possible, and KVM
63
+ c->cluster_id);
56
- * doesn't support secure.
64
+ }
57
- */
65
if (c->has_core_id) {
58
- assert(!(info->secure_board_setup && kvm_enabled()));
66
monitor_printf(mon, " core-id: \"%" PRIu64 "\"\n", c->core_id);
59
-
67
}
60
- info->dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
68
diff --git a/hw/core/machine.c b/hw/core/machine.c
61
- info->dtb_limit = 0;
69
index XXXXXXX..XXXXXXX 100644
62
-
70
--- a/hw/core/machine.c
63
- /* Load the kernel. */
71
+++ b/hw/core/machine.c
64
- if (!info->kernel_filename || info->firmware_loaded) {
72
@@ -XXX,XX +XXX,XX @@ void machine_set_cpu_numa_node(MachineState *machine,
65
-
73
return;
66
- if (have_dtb(info)) {
74
}
67
- /*
75
68
- * If we have a device tree blob, but no kernel to supply it to (or
76
+ if (props->has_cluster_id && !slot->props.has_cluster_id) {
69
- * the kernel is supposed to be loaded by the bootloader), copy the
77
+ error_setg(errp, "cluster-id is not supported");
70
- * DTB to the base of RAM for the bootloader to pick up.
78
+ return;
71
- */
72
- info->dtb_start = info->loader_start;
73
- }
74
-
75
- if (info->kernel_filename) {
76
- FWCfgState *fw_cfg;
77
- bool try_decompressing_kernel;
78
-
79
- fw_cfg = fw_cfg_find();
80
- try_decompressing_kernel = arm_feature(&cpu->env,
81
- ARM_FEATURE_AARCH64);
82
-
83
- /*
84
- * Expose the kernel, the command line, and the initrd in fw_cfg.
85
- * We don't process them here at all, it's all left to the
86
- * firmware.
87
- */
88
- load_image_to_fw_cfg(fw_cfg,
89
- FW_CFG_KERNEL_SIZE, FW_CFG_KERNEL_DATA,
90
- info->kernel_filename,
91
- try_decompressing_kernel);
92
- load_image_to_fw_cfg(fw_cfg,
93
- FW_CFG_INITRD_SIZE, FW_CFG_INITRD_DATA,
94
- info->initrd_filename, false);
95
-
96
- if (info->kernel_cmdline) {
97
- fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
98
- strlen(info->kernel_cmdline) + 1);
99
- fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA,
100
- info->kernel_cmdline);
101
- }
102
- }
103
-
104
- /*
105
- * We will start from address 0 (typically a boot ROM image) in the
106
- * same way as hardware.
107
- */
108
- return;
109
- }
110
111
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
112
primary_loader = bootloader_aarch64;
113
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
114
for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
115
ARM_CPU(cs)->env.boot_info = info;
116
}
117
+}
118
+
119
+void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
120
+{
121
+ CPUState *cs;
122
+ AddressSpace *as = arm_boot_address_space(cpu, info);
123
+
124
+ /*
125
+ * CPU objects (unlike devices) are not automatically reset on system
126
+ * reset, so we must always register a handler to do so. If we're
127
+ * actually loading a kernel, the handler is also responsible for
128
+ * arranging that we start it correctly.
129
+ */
130
+ for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
131
+ qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
132
+ }
133
+
134
+ /*
135
+ * The board code is not supposed to set secure_board_setup unless
136
+ * running its code in secure mode is actually possible, and KVM
137
+ * doesn't support secure.
138
+ */
139
+ assert(!(info->secure_board_setup && kvm_enabled()));
140
+
141
+ info->dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
142
+ info->dtb_limit = 0;
143
+
144
+ /* Load the kernel. */
145
+ if (!info->kernel_filename || info->firmware_loaded) {
146
+
147
+ if (have_dtb(info)) {
148
+ /*
149
+ * If we have a device tree blob, but no kernel to supply it to (or
150
+ * the kernel is supposed to be loaded by the bootloader), copy the
151
+ * DTB to the base of RAM for the bootloader to pick up.
152
+ */
153
+ info->dtb_start = info->loader_start;
154
+ }
79
+ }
155
+
80
+
156
+ if (info->kernel_filename) {
81
if (props->has_socket_id && !slot->props.has_socket_id) {
157
+ FWCfgState *fw_cfg;
82
error_setg(errp, "socket-id is not supported");
158
+ bool try_decompressing_kernel;
83
return;
159
+
84
@@ -XXX,XX +XXX,XX @@ void machine_set_cpu_numa_node(MachineState *machine,
160
+ fw_cfg = fw_cfg_find();
85
continue;
161
+ try_decompressing_kernel = arm_feature(&cpu->env,
86
}
162
+ ARM_FEATURE_AARCH64);
87
163
+
88
+ if (props->has_cluster_id &&
164
+ /*
89
+ props->cluster_id != slot->props.cluster_id) {
165
+ * Expose the kernel, the command line, and the initrd in fw_cfg.
90
+ continue;
166
+ * We don't process them here at all, it's all left to the
167
+ * firmware.
168
+ */
169
+ load_image_to_fw_cfg(fw_cfg,
170
+ FW_CFG_KERNEL_SIZE, FW_CFG_KERNEL_DATA,
171
+ info->kernel_filename,
172
+ try_decompressing_kernel);
173
+ load_image_to_fw_cfg(fw_cfg,
174
+ FW_CFG_INITRD_SIZE, FW_CFG_INITRD_DATA,
175
+ info->initrd_filename, false);
176
+
177
+ if (info->kernel_cmdline) {
178
+ fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
179
+ strlen(info->kernel_cmdline) + 1);
180
+ fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA,
181
+ info->kernel_cmdline);
182
+ }
183
+ }
91
+ }
184
+
92
+
185
+ /*
93
if (props->has_die_id && props->die_id != slot->props.die_id) {
186
+ * We will start from address 0 (typically a boot ROM image) in the
94
continue;
187
+ * same way as hardware.
95
}
188
+ */
96
@@ -XXX,XX +XXX,XX @@ static char *cpu_slot_to_string(const CPUArchId *cpu)
189
+ return;
97
}
190
+ } else {
98
g_string_append_printf(s, "die-id: %"PRId64, cpu->props.die_id);
191
+ arm_setup_direct_kernel_boot(cpu, info);
99
}
100
+ if (cpu->props.has_cluster_id) {
101
+ if (s->len) {
102
+ g_string_append_printf(s, ", ");
103
+ }
104
+ g_string_append_printf(s, "cluster-id: %"PRId64, cpu->props.cluster_id);
192
+ }
105
+ }
193
106
if (cpu->props.has_core_id) {
194
if (!info->skip_dtb_autoload && have_dtb(info)) {
107
if (s->len) {
195
if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as) < 0) {
108
g_string_append_printf(s, ", ");
196
--
109
--
197
2.20.1
110
2.25.1
198
199
diff view generated by jsdifflib
1
Fix the block comment style in arm_load_kernel() to QEMU's
1
From: Gavin Shan <gshan@redhat.com>
2
current style preferences. This will allow us to do some
3
refactoring of this function without checkpatch complaining
4
about the code-motion patches.
5
2
3
The CPU topology isn't enabled on arm/virt machine yet, but we're
4
going to do it in next patch. After the CPU topology is enabled by
5
next patch, "thread-id=1" becomes invalid because the CPU core is
6
preferred on arm/virt machine. It means these two CPUs have 0/1
7
as their core IDs, but their thread IDs are all 0. It will trigger
8
test failure as the following message indicates:
9
10
[14/21 qemu:qtest+qtest-aarch64 / qtest-aarch64/numa-test ERROR
11
1.48s killed by signal 6 SIGABRT
12
>>> G_TEST_DBUS_DAEMON=/home/gavin/sandbox/qemu.main/tests/dbus-vmstate-daemon.sh \
13
QTEST_QEMU_STORAGE_DAEMON_BINARY=./storage-daemon/qemu-storage-daemon \
14
QTEST_QEMU_BINARY=./qemu-system-aarch64 \
15
QTEST_QEMU_IMG=./qemu-img MALLOC_PERTURB_=83 \
16
/home/gavin/sandbox/qemu.main/build/tests/qtest/numa-test --tap -k
17
――――――――――――――――――――――――――――――――――――――――――――――
18
stderr:
19
qemu-system-aarch64: -numa cpu,node-id=0,thread-id=1: no match found
20
21
This fixes the issue by providing comprehensive SMP configurations
22
in aarch64_numa_cpu(). The SMP configurations aren't used before
23
the CPU topology is enabled in next patch.
24
25
Signed-off-by: Gavin Shan <gshan@redhat.com>
26
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
27
Message-id: 20220503140304.855514-3-gshan@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
9
Message-id: 20190131112240.8395-2-peter.maydell@linaro.org
10
---
29
---
11
hw/arm/boot.c | 30 ++++++++++++++++++++----------
30
tests/qtest/numa-test.c | 3 ++-
12
1 file changed, 20 insertions(+), 10 deletions(-)
31
1 file changed, 2 insertions(+), 1 deletion(-)
13
32
14
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
33
diff --git a/tests/qtest/numa-test.c b/tests/qtest/numa-test.c
15
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/boot.c
35
--- a/tests/qtest/numa-test.c
17
+++ b/hw/arm/boot.c
36
+++ b/tests/qtest/numa-test.c
18
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
37
@@ -XXX,XX +XXX,XX @@ static void aarch64_numa_cpu(const void *data)
19
static const ARMInsnFixup *primary_loader;
38
QTestState *qts;
20
AddressSpace *as = arm_boot_address_space(cpu, info);
39
g_autofree char *cli = NULL;
21
40
22
- /* CPU objects (unlike devices) are not automatically reset on system
41
- cli = make_cli(data, "-machine smp.cpus=2 "
23
+ /*
42
+ cli = make_cli(data, "-machine "
24
+ * CPU objects (unlike devices) are not automatically reset on system
43
+ "smp.cpus=2,smp.sockets=1,smp.clusters=1,smp.cores=1,smp.threads=2 "
25
* reset, so we must always register a handler to do so. If we're
44
"-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 "
26
* actually loading a kernel, the handler is also responsible for
45
"-numa cpu,node-id=1,thread-id=0 "
27
* arranging that we start it correctly.
46
"-numa cpu,node-id=0,thread-id=1");
28
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
29
qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
30
}
31
32
- /* The board code is not supposed to set secure_board_setup unless
33
+ /*
34
+ * The board code is not supposed to set secure_board_setup unless
35
* running its code in secure mode is actually possible, and KVM
36
* doesn't support secure.
37
*/
38
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
39
if (!info->kernel_filename || info->firmware_loaded) {
40
41
if (have_dtb(info)) {
42
- /* If we have a device tree blob, but no kernel to supply it to (or
43
+ /*
44
+ * If we have a device tree blob, but no kernel to supply it to (or
45
* the kernel is supposed to be loaded by the bootloader), copy the
46
* DTB to the base of RAM for the bootloader to pick up.
47
*/
48
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
49
try_decompressing_kernel = arm_feature(&cpu->env,
50
ARM_FEATURE_AARCH64);
51
52
- /* Expose the kernel, the command line, and the initrd in fw_cfg.
53
+ /*
54
+ * Expose the kernel, the command line, and the initrd in fw_cfg.
55
* We don't process them here at all, it's all left to the
56
* firmware.
57
*/
58
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
59
}
60
}
61
62
- /* We will start from address 0 (typically a boot ROM image) in the
63
+ /*
64
+ * We will start from address 0 (typically a boot ROM image) in the
65
* same way as hardware.
66
*/
67
return;
68
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
69
if (info->nb_cpus == 0)
70
info->nb_cpus = 1;
71
72
- /* We want to put the initrd far enough into RAM that when the
73
+ /*
74
+ * We want to put the initrd far enough into RAM that when the
75
* kernel is uncompressed it will not clobber the initrd. However
76
* on boards without much RAM we must ensure that we still leave
77
* enough room for a decent sized initrd, and on boards with large
78
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
79
kernel_size = arm_load_elf(info, &elf_entry, &elf_low_addr,
80
&elf_high_addr, elf_machine, as);
81
if (kernel_size > 0 && have_dtb(info)) {
82
- /* If there is still some room left at the base of RAM, try and put
83
+ /*
84
+ * If there is still some room left at the base of RAM, try and put
85
* the DTB there like we do for images loaded with -bios or -pflash.
86
*/
87
if (elf_low_addr > info->loader_start
88
|| elf_high_addr < info->loader_start) {
89
- /* Set elf_low_addr as address limit for arm_load_dtb if it may be
90
+ /*
91
+ * Set elf_low_addr as address limit for arm_load_dtb if it may be
92
* pointing into RAM, otherwise pass '0' (no limit)
93
*/
94
if (elf_low_addr < info->loader_start) {
95
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
96
fixupcontext[FIXUP_BOARDID] = info->board_id;
97
fixupcontext[FIXUP_BOARD_SETUP] = info->board_setup_addr;
98
99
- /* for device tree boot, we pass the DTB directly in r2. Otherwise
100
+ /*
101
+ * for device tree boot, we pass the DTB directly in r2. Otherwise
102
* we point to the kernel args.
103
*/
104
if (have_dtb(info)) {
105
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
106
info->write_board_setup(cpu, info);
107
}
108
109
- /* Notify devices which need to fake up firmware initialization
110
+ /*
111
+ * Notify devices which need to fake up firmware initialization
112
* that we're doing a direct kernel boot.
113
*/
114
object_child_foreach_recursive(object_get_root(),
115
--
47
--
116
2.20.1
48
2.25.1
117
49
118
50
diff view generated by jsdifflib
New patch
1
From: Gavin Shan <gshan@redhat.com>
1
2
3
Currently, the SMP configuration isn't considered when the CPU
4
topology is populated. In this case, it's impossible to provide
5
the default CPU-to-NUMA mapping or association based on the socket
6
ID of the given CPU.
7
8
This takes account of SMP configuration when the CPU topology
9
is populated. The die ID for the given CPU isn't assigned since
10
it's not supported on arm/virt machine. Besides, the used SMP
11
configuration in qtest/numa-test/aarch64_numa_cpu() is corrcted
12
to avoid testing failure
13
14
Signed-off-by: Gavin Shan <gshan@redhat.com>
15
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
16
Acked-by: Igor Mammedov <imammedo@redhat.com>
17
Message-id: 20220503140304.855514-4-gshan@redhat.com
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
20
hw/arm/virt.c | 15 ++++++++++++++-
21
1 file changed, 14 insertions(+), 1 deletion(-)
22
23
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/virt.c
26
+++ b/hw/arm/virt.c
27
@@ -XXX,XX +XXX,XX @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
28
int n;
29
unsigned int max_cpus = ms->smp.max_cpus;
30
VirtMachineState *vms = VIRT_MACHINE(ms);
31
+ MachineClass *mc = MACHINE_GET_CLASS(vms);
32
33
if (ms->possible_cpus) {
34
assert(ms->possible_cpus->len == max_cpus);
35
@@ -XXX,XX +XXX,XX @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
36
ms->possible_cpus->cpus[n].type = ms->cpu_type;
37
ms->possible_cpus->cpus[n].arch_id =
38
virt_cpu_mp_affinity(vms, n);
39
+
40
+ assert(!mc->smp_props.dies_supported);
41
+ ms->possible_cpus->cpus[n].props.has_socket_id = true;
42
+ ms->possible_cpus->cpus[n].props.socket_id =
43
+ n / (ms->smp.clusters * ms->smp.cores * ms->smp.threads);
44
+ ms->possible_cpus->cpus[n].props.has_cluster_id = true;
45
+ ms->possible_cpus->cpus[n].props.cluster_id =
46
+ (n / (ms->smp.cores * ms->smp.threads)) % ms->smp.clusters;
47
+ ms->possible_cpus->cpus[n].props.has_core_id = true;
48
+ ms->possible_cpus->cpus[n].props.core_id =
49
+ (n / ms->smp.threads) % ms->smp.cores;
50
ms->possible_cpus->cpus[n].props.has_thread_id = true;
51
- ms->possible_cpus->cpus[n].props.thread_id = n;
52
+ ms->possible_cpus->cpus[n].props.thread_id =
53
+ n % ms->smp.threads;
54
}
55
return ms->possible_cpus;
56
}
57
--
58
2.25.1
diff view generated by jsdifflib
New patch
1
From: Gavin Shan <gshan@redhat.com>
1
2
3
In aarch64_numa_cpu(), the CPU and NUMA association is something
4
like below. Two threads in the same core/cluster/socket are
5
associated with two individual NUMA nodes, which is unreal as
6
Igor Mammedov mentioned. We don't expect the association to break
7
NUMA-to-socket boundary, which matches with the real world.
8
9
NUMA-node socket cluster core thread
10
------------------------------------------
11
0 0 0 0 0
12
1 0 0 0 1
13
14
This corrects the topology for CPUs and their association with
15
NUMA nodes. After this patch is applied, the CPU and NUMA
16
association becomes something like below, which looks real.
17
Besides, socket/cluster/core/thread IDs are all checked when
18
the NUMA node IDs are verified. It helps to check if the CPU
19
topology is properly populated or not.
20
21
NUMA-node socket cluster core thread
22
------------------------------------------
23
0 1 0 0 0
24
1 0 0 0 0
25
26
Suggested-by: Igor Mammedov <imammedo@redhat.com>
27
Signed-off-by: Gavin Shan <gshan@redhat.com>
28
Acked-by: Igor Mammedov <imammedo@redhat.com>
29
Message-id: 20220503140304.855514-5-gshan@redhat.com
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
---
32
tests/qtest/numa-test.c | 18 ++++++++++++------
33
1 file changed, 12 insertions(+), 6 deletions(-)
34
35
diff --git a/tests/qtest/numa-test.c b/tests/qtest/numa-test.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/tests/qtest/numa-test.c
38
+++ b/tests/qtest/numa-test.c
39
@@ -XXX,XX +XXX,XX @@ static void aarch64_numa_cpu(const void *data)
40
g_autofree char *cli = NULL;
41
42
cli = make_cli(data, "-machine "
43
- "smp.cpus=2,smp.sockets=1,smp.clusters=1,smp.cores=1,smp.threads=2 "
44
+ "smp.cpus=2,smp.sockets=2,smp.clusters=1,smp.cores=1,smp.threads=1 "
45
"-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 "
46
- "-numa cpu,node-id=1,thread-id=0 "
47
- "-numa cpu,node-id=0,thread-id=1");
48
+ "-numa cpu,node-id=0,socket-id=1,cluster-id=0,core-id=0,thread-id=0 "
49
+ "-numa cpu,node-id=1,socket-id=0,cluster-id=0,core-id=0,thread-id=0");
50
qts = qtest_init(cli);
51
cpus = get_cpus(qts, &resp);
52
g_assert(cpus);
53
54
while ((e = qlist_pop(cpus))) {
55
QDict *cpu, *props;
56
- int64_t thread, node;
57
+ int64_t socket, cluster, core, thread, node;
58
59
cpu = qobject_to(QDict, e);
60
g_assert(qdict_haskey(cpu, "props"));
61
@@ -XXX,XX +XXX,XX @@ static void aarch64_numa_cpu(const void *data)
62
63
g_assert(qdict_haskey(props, "node-id"));
64
node = qdict_get_int(props, "node-id");
65
+ g_assert(qdict_haskey(props, "socket-id"));
66
+ socket = qdict_get_int(props, "socket-id");
67
+ g_assert(qdict_haskey(props, "cluster-id"));
68
+ cluster = qdict_get_int(props, "cluster-id");
69
+ g_assert(qdict_haskey(props, "core-id"));
70
+ core = qdict_get_int(props, "core-id");
71
g_assert(qdict_haskey(props, "thread-id"));
72
thread = qdict_get_int(props, "thread-id");
73
74
- if (thread == 0) {
75
+ if (socket == 0 && cluster == 0 && core == 0 && thread == 0) {
76
g_assert_cmpint(node, ==, 1);
77
- } else if (thread == 1) {
78
+ } else if (socket == 1 && cluster == 0 && core == 0 && thread == 0) {
79
g_assert_cmpint(node, ==, 0);
80
} else {
81
g_assert(false);
82
--
83
2.25.1
diff view generated by jsdifflib
New patch
1
From: Gavin Shan <gshan@redhat.com>
1
2
3
When CPU-to-NUMA association isn't explicitly provided by users,
4
the default one is given by mc->get_default_cpu_node_id(). However,
5
the CPU topology isn't fully considered in the default association
6
and this causes CPU topology broken warnings on booting Linux guest.
7
8
For example, the following warning messages are observed when the
9
Linux guest is booted with the following command lines.
10
11
/home/gavin/sandbox/qemu.main/build/qemu-system-aarch64 \
12
-accel kvm -machine virt,gic-version=host \
13
-cpu host \
14
-smp 6,sockets=2,cores=3,threads=1 \
15
-m 1024M,slots=16,maxmem=64G \
16
-object memory-backend-ram,id=mem0,size=128M \
17
-object memory-backend-ram,id=mem1,size=128M \
18
-object memory-backend-ram,id=mem2,size=128M \
19
-object memory-backend-ram,id=mem3,size=128M \
20
-object memory-backend-ram,id=mem4,size=128M \
21
-object memory-backend-ram,id=mem4,size=384M \
22
-numa node,nodeid=0,memdev=mem0 \
23
-numa node,nodeid=1,memdev=mem1 \
24
-numa node,nodeid=2,memdev=mem2 \
25
-numa node,nodeid=3,memdev=mem3 \
26
-numa node,nodeid=4,memdev=mem4 \
27
-numa node,nodeid=5,memdev=mem5
28
:
29
alternatives: patching kernel code
30
BUG: arch topology borken
31
the CLS domain not a subset of the MC domain
32
<the above error log repeats>
33
BUG: arch topology borken
34
the DIE domain not a subset of the NODE domain
35
36
With current implementation of mc->get_default_cpu_node_id(),
37
CPU#0 to CPU#5 are associated with NODE#0 to NODE#5 separately.
38
That's incorrect because CPU#0/1/2 should be associated with same
39
NUMA node because they're seated in same socket.
40
41
This fixes the issue by considering the socket ID when the default
42
CPU-to-NUMA association is provided in virt_possible_cpu_arch_ids().
43
With this applied, no more CPU topology broken warnings are seen
44
from the Linux guest. The 6 CPUs are associated with NODE#0/1, but
45
there are no CPUs associated with NODE#2/3/4/5.
46
47
Signed-off-by: Gavin Shan <gshan@redhat.com>
48
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
49
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
50
Message-id: 20220503140304.855514-6-gshan@redhat.com
51
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
52
---
53
hw/arm/virt.c | 4 +++-
54
1 file changed, 3 insertions(+), 1 deletion(-)
55
56
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/arm/virt.c
59
+++ b/hw/arm/virt.c
60
@@ -XXX,XX +XXX,XX @@ virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
61
62
static int64_t virt_get_default_cpu_node_id(const MachineState *ms, int idx)
63
{
64
- return idx % ms->numa_state->num_nodes;
65
+ int64_t socket_id = ms->possible_cpus->cpus[idx].props.socket_id;
66
+
67
+ return socket_id % ms->numa_state->num_nodes;
68
}
69
70
static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
71
--
72
2.25.1
diff view generated by jsdifflib
1
The code path for booting firmware doesn't set env->boot_info. At
1
From: Gavin Shan <gshan@redhat.com>
2
first sight this looks odd, so add a comment saying why we don't.
3
2
3
When the PPTT table is built, the CPU topology is re-calculated, but
4
it's unecessary because the CPU topology has been populated in
5
virt_possible_cpu_arch_ids() on arm/virt machine.
6
7
This reworks build_pptt() to avoid by reusing the existing IDs in
8
ms->possible_cpus. Currently, the only user of build_pptt() is
9
arm/virt machine.
10
11
Signed-off-by: Gavin Shan <gshan@redhat.com>
12
Tested-by: Yanan Wang <wangyanan55@huawei.com>
13
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
14
Acked-by: Igor Mammedov <imammedo@redhat.com>
15
Acked-by: Michael S. Tsirkin <mst@redhat.com>
16
Message-id: 20220503140304.855514-7-gshan@redhat.com
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
7
Message-id: 20190131112240.8395-5-peter.maydell@linaro.org
8
---
18
---
9
hw/arm/boot.c | 3 ++-
19
hw/acpi/aml-build.c | 111 +++++++++++++++++++-------------------------
10
1 file changed, 2 insertions(+), 1 deletion(-)
20
1 file changed, 48 insertions(+), 63 deletions(-)
11
21
12
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
22
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
13
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/boot.c
24
--- a/hw/acpi/aml-build.c
15
+++ b/hw/arm/boot.c
25
+++ b/hw/acpi/aml-build.c
16
@@ -XXX,XX +XXX,XX @@ static void arm_setup_firmware_boot(ARMCPU *cpu, struct arm_boot_info *info)
26
@@ -XXX,XX +XXX,XX @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
17
27
const char *oem_id, const char *oem_table_id)
18
/*
28
{
19
* We will start from address 0 (typically a boot ROM image) in the
29
MachineClass *mc = MACHINE_GET_CLASS(ms);
20
- * same way as hardware.
30
- GQueue *list = g_queue_new();
21
+ * same way as hardware. Leave env->boot_info NULL, so that
31
- guint pptt_start = table_data->len;
22
+ * do_cpu_reset() knows it does not need to alter the PC on reset.
32
- guint parent_offset;
23
*/
33
- guint length, i;
34
- int uid = 0;
35
- int socket;
36
+ CPUArchIdList *cpus = ms->possible_cpus;
37
+ int64_t socket_id = -1, cluster_id = -1, core_id = -1;
38
+ uint32_t socket_offset = 0, cluster_offset = 0, core_offset = 0;
39
+ uint32_t pptt_start = table_data->len;
40
+ int n;
41
AcpiTable table = { .sig = "PPTT", .rev = 2,
42
.oem_id = oem_id, .oem_table_id = oem_table_id };
43
44
acpi_table_begin(&table, table_data);
45
46
- for (socket = 0; socket < ms->smp.sockets; socket++) {
47
- g_queue_push_tail(list,
48
- GUINT_TO_POINTER(table_data->len - pptt_start));
49
- build_processor_hierarchy_node(
50
- table_data,
51
- /*
52
- * Physical package - represents the boundary
53
- * of a physical package
54
- */
55
- (1 << 0),
56
- 0, socket, NULL, 0);
57
- }
58
-
59
- if (mc->smp_props.clusters_supported) {
60
- length = g_queue_get_length(list);
61
- for (i = 0; i < length; i++) {
62
- int cluster;
63
-
64
- parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
65
- for (cluster = 0; cluster < ms->smp.clusters; cluster++) {
66
- g_queue_push_tail(list,
67
- GUINT_TO_POINTER(table_data->len - pptt_start));
68
- build_processor_hierarchy_node(
69
- table_data,
70
- (0 << 0), /* not a physical package */
71
- parent_offset, cluster, NULL, 0);
72
- }
73
+ /*
74
+ * This works with the assumption that cpus[n].props.*_id has been
75
+ * sorted from top to down levels in mc->possible_cpu_arch_ids().
76
+ * Otherwise, the unexpected and duplicated containers will be
77
+ * created.
78
+ */
79
+ for (n = 0; n < cpus->len; n++) {
80
+ if (cpus->cpus[n].props.socket_id != socket_id) {
81
+ assert(cpus->cpus[n].props.socket_id > socket_id);
82
+ socket_id = cpus->cpus[n].props.socket_id;
83
+ cluster_id = -1;
84
+ core_id = -1;
85
+ socket_offset = table_data->len - pptt_start;
86
+ build_processor_hierarchy_node(table_data,
87
+ (1 << 0), /* Physical package */
88
+ 0, socket_id, NULL, 0);
89
}
90
- }
91
92
- length = g_queue_get_length(list);
93
- for (i = 0; i < length; i++) {
94
- int core;
95
-
96
- parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
97
- for (core = 0; core < ms->smp.cores; core++) {
98
- if (ms->smp.threads > 1) {
99
- g_queue_push_tail(list,
100
- GUINT_TO_POINTER(table_data->len - pptt_start));
101
- build_processor_hierarchy_node(
102
- table_data,
103
- (0 << 0), /* not a physical package */
104
- parent_offset, core, NULL, 0);
105
- } else {
106
- build_processor_hierarchy_node(
107
- table_data,
108
- (1 << 1) | /* ACPI Processor ID valid */
109
- (1 << 3), /* Node is a Leaf */
110
- parent_offset, uid++, NULL, 0);
111
+ if (mc->smp_props.clusters_supported) {
112
+ if (cpus->cpus[n].props.cluster_id != cluster_id) {
113
+ assert(cpus->cpus[n].props.cluster_id > cluster_id);
114
+ cluster_id = cpus->cpus[n].props.cluster_id;
115
+ core_id = -1;
116
+ cluster_offset = table_data->len - pptt_start;
117
+ build_processor_hierarchy_node(table_data,
118
+ (0 << 0), /* Not a physical package */
119
+ socket_offset, cluster_id, NULL, 0);
120
}
121
+ } else {
122
+ cluster_offset = socket_offset;
123
}
124
- }
125
126
- length = g_queue_get_length(list);
127
- for (i = 0; i < length; i++) {
128
- int thread;
129
+ if (ms->smp.threads == 1) {
130
+ build_processor_hierarchy_node(table_data,
131
+ (1 << 1) | /* ACPI Processor ID valid */
132
+ (1 << 3), /* Node is a Leaf */
133
+ cluster_offset, n, NULL, 0);
134
+ } else {
135
+ if (cpus->cpus[n].props.core_id != core_id) {
136
+ assert(cpus->cpus[n].props.core_id > core_id);
137
+ core_id = cpus->cpus[n].props.core_id;
138
+ core_offset = table_data->len - pptt_start;
139
+ build_processor_hierarchy_node(table_data,
140
+ (0 << 0), /* Not a physical package */
141
+ cluster_offset, core_id, NULL, 0);
142
+ }
143
144
- parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
145
- for (thread = 0; thread < ms->smp.threads; thread++) {
146
- build_processor_hierarchy_node(
147
- table_data,
148
+ build_processor_hierarchy_node(table_data,
149
(1 << 1) | /* ACPI Processor ID valid */
150
(1 << 2) | /* Processor is a Thread */
151
(1 << 3), /* Node is a Leaf */
152
- parent_offset, uid++, NULL, 0);
153
+ core_offset, n, NULL, 0);
154
}
155
}
156
157
- g_queue_free(list);
158
acpi_table_end(linker, &table);
24
}
159
}
25
160
26
--
161
--
27
2.20.1
162
2.25.1
28
29
diff view generated by jsdifflib