1
The following changes since commit 4cc10cae64c51e17844dc4358481c393d7bf1ed4:
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
Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging (2021-05-06 18:56:17 +0100)
5
thanks
6
-- PMM
7
8
The following changes since commit 554623226f800acf48a2ed568900c1c968ec9a8b:
9
10
Merge tag 'qemu-sparc-20220508' of https://github.com/mcayland/qemu into staging (2022-05-08 17:03:26 -0500)
4
11
5
are available in the Git repository at:
12
are available in the Git repository at:
6
13
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210510
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220509
8
15
9
for you to fetch changes up to 8f96812baa53005f32aece3e30b140826c20aa19:
16
for you to fetch changes up to ae9141d4a3265553503bf07d3574b40f84615a34:
10
17
11
hw/arm/xlnx: Fix PHY address for xilinx-zynq-a9 (2021-05-10 13:24:09 +0100)
18
hw/acpi/aml-build: Use existing CPU topology to build PPTT table (2022-05-09 11:47:55 +0100)
12
19
13
----------------------------------------------------------------
20
----------------------------------------------------------------
14
target-arm queue:
21
target-arm queue:
15
* docs: fix link in sbsa description
22
* MAINTAINERS/.mailmap: update email for Leif Lindholm
16
* linux-user/aarch64: Enable hwcap for RND, BTI, and MTE
23
* hw/arm: add version information to sbsa-ref machine DT
17
* target/arm: Fix tlbbits calculation in tlbi_aa64_vae2is_write()
24
* Enable new features for -cpu max:
18
* target/arm: Split neon and vfp translation to their own
25
FEAT_Debugv8p2, FEAT_Debugv8p4, FEAT_RAS (minimal version only),
19
compilation units
26
FEAT_IESB, FEAT_CSV2, FEAT_CSV2_2, FEAT_CSV3, FEAT_DGH
20
* target/arm: Make WFI a NOP for userspace emulators
27
* Emulate Cortex-A76
21
* hw/sd/omap_mmc: Use device_cold_reset() instead of
28
* Emulate Neoverse-N1
22
device_legacy_reset()
29
* Fix the virt board default NUMA topology
23
* include: More fixes for 'extern "C"' block use
24
* hw/arm/imx25_pdk: Fix error message for invalid RAM size
25
* hw/arm/mps2-tz: Implement AN524 memory remapping via machine property
26
* hw/arm/xlnx: Fix PHY address for xilinx-zynq-a9
27
30
28
----------------------------------------------------------------
31
----------------------------------------------------------------
29
Alex Bennée (1):
32
Gavin Shan (6):
30
docs: fix link in sbsa description
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
31
39
32
Guenter Roeck (1):
40
Leif Lindholm (2):
33
hw/arm/xlnx: Fix PHY address for xilinx-zynq-a9
41
MAINTAINERS/.mailmap: update email for Leif Lindholm
42
hw/arm: add versioning to sbsa-ref machine DT
34
43
35
Peter Maydell (22):
44
Richard Henderson (24):
36
target/arm: Fix tlbbits calculation in tlbi_aa64_vae2is_write()
45
target/arm: Handle cpreg registration for missing EL
37
target/arm: Move constant expanders to translate.h
46
target/arm: Drop EL3 no EL2 fallbacks
38
target/arm: Share unallocated_encoding() and gen_exception_insn()
47
target/arm: Merge zcr reginfo
39
target/arm: Make functions used by m-nocp global
48
target/arm: Adjust definition of CONTEXTIDR_EL2
40
target/arm: Split m-nocp trans functions into their own file
49
target/arm: Move cortex impdef sysregs to cpu_tcg.c
41
target/arm: Move gen_aa32 functions to translate-a32.h
50
target/arm: Update qemu-system-arm -cpu max to cortex-a57
42
target/arm: Move vfp_{load, store}_reg{32, 64} to translate-vfp.c.inc
51
target/arm: Set ID_DFR0.PerfMon for qemu-system-arm -cpu max
43
target/arm: Make functions used by translate-vfp global
52
target/arm: Split out aa32_max_features
44
target/arm: Make translate-vfp.c.inc its own compilation unit
53
target/arm: Annotate arm_max_initfn with FEAT identifiers
45
target/arm: Move vfp_reg_ptr() to translate-neon.c.inc
54
target/arm: Use field names for manipulating EL2 and EL3 modes
46
target/arm: Delete unused typedef
55
target/arm: Enable FEAT_Debugv8p2 for -cpu max
47
target/arm: Move NeonGenThreeOpEnvFn typedef to translate.h
56
target/arm: Enable FEAT_Debugv8p4 for -cpu max
48
target/arm: Make functions used by translate-neon global
57
target/arm: Add minimal RAS registers
49
target/arm: Make translate-neon.c.inc its own compilation unit
58
target/arm: Enable SCR and HCR bits for RAS
50
target/arm: Make WFI a NOP for userspace emulators
59
target/arm: Implement virtual SError exceptions
51
hw/sd/omap_mmc: Use device_cold_reset() instead of device_legacy_reset()
60
target/arm: Implement ESB instruction
52
osdep: Make os-win32.h and os-posix.h handle 'extern "C"' themselves
61
target/arm: Enable FEAT_RAS for -cpu max
53
include/qemu/bswap.h: Handle being included outside extern "C" block
62
target/arm: Enable FEAT_IESB for -cpu max
54
include/disas/dis-asm.h: Handle being included outside 'extern "C"'
63
target/arm: Enable FEAT_CSV2 for -cpu max
55
hw/misc/mps2-scc: Add "QEMU interface" comment
64
target/arm: Enable FEAT_CSV2_2 for -cpu max
56
hw/misc/mps2-scc: Support using CFG0 bit 0 for remapping
65
target/arm: Enable FEAT_CSV3 for -cpu max
57
hw/arm/mps2-tz: Implement AN524 memory remapping via machine property
66
target/arm: Enable FEAT_DGH for -cpu max
67
target/arm: Define cortex-a76
68
target/arm: Define neoverse-n1
58
69
59
Philippe Mathieu-Daudé (1):
70
docs/system/arm/emulation.rst | 10 +
60
hw/arm/imx25_pdk: Fix error message for invalid RAM size
71
docs/system/arm/virt.rst | 2 +
61
72
qapi/machine.json | 6 +-
62
Richard Henderson (1):
73
target/arm/cpregs.h | 11 +
63
linux-user/aarch64: Enable hwcap for RND, BTI, and MTE
74
target/arm/cpu.h | 23 ++
64
75
target/arm/helper.h | 1 +
65
docs/system/arm/mps2.rst | 10 +
76
target/arm/internals.h | 16 ++
66
docs/system/arm/sbsa.rst | 2 +-
77
target/arm/syndrome.h | 5 +
67
include/disas/dis-asm.h | 12 +-
78
target/arm/a32.decode | 16 +-
68
include/hw/misc/mps2-scc.h | 21 ++
79
target/arm/t32.decode | 18 +-
69
include/qemu/bswap.h | 26 ++-
80
hw/acpi/aml-build.c | 111 ++++----
70
include/qemu/osdep.h | 8 +-
81
hw/arm/sbsa-ref.c | 16 ++
71
include/sysemu/os-posix.h | 8 +
82
hw/arm/virt.c | 21 +-
72
include/sysemu/os-win32.h | 8 +
83
hw/core/machine-hmp-cmds.c | 4 +
73
target/arm/translate-a32.h | 144 +++++++++++++
84
hw/core/machine.c | 16 ++
74
target/arm/translate-a64.h | 2 -
85
target/arm/cpu.c | 66 ++++-
75
target/arm/translate.h | 29 +++
86
target/arm/cpu64.c | 353 ++++++++++++++-----------
76
hw/arm/imx25_pdk.c | 5 +-
87
target/arm/cpu_tcg.c | 227 +++++++++++-----
77
hw/arm/mps2-tz.c | 108 +++++++++-
88
target/arm/helper.c | 600 +++++++++++++++++++++++++-----------------
78
hw/arm/xilinx_zynq.c | 2 +-
89
target/arm/op_helper.c | 43 +++
79
hw/misc/mps2-scc.c | 13 +-
90
target/arm/translate-a64.c | 18 ++
80
hw/sd/omap_mmc.c | 2 +-
91
target/arm/translate.c | 23 ++
81
linux-user/elfload.c | 13 ++
92
tests/qtest/numa-test.c | 19 +-
82
target/arm/helper.c | 2 +-
93
.mailmap | 3 +-
83
target/arm/op_helper.c | 12 ++
94
MAINTAINERS | 2 +-
84
target/arm/translate-a64.c | 15 --
95
25 files changed, 1068 insertions(+), 562 deletions(-)
85
target/arm/translate-m-nocp.c | 221 ++++++++++++++++++++
86
.../arm/{translate-neon.c.inc => translate-neon.c} | 19 +-
87
.../arm/{translate-vfp.c.inc => translate-vfp.c} | 230 +++------------------
88
target/arm/translate.c | 200 ++++--------------
89
disas/arm-a64.cc | 2 -
90
disas/nanomips.cpp | 2 -
91
target/arm/meson.build | 15 +-
92
27 files changed, 718 insertions(+), 413 deletions(-)
93
create mode 100644 target/arm/translate-a32.h
94
create mode 100644 target/arm/translate-m-nocp.c
95
rename target/arm/{translate-neon.c.inc => translate-neon.c} (99%)
96
rename target/arm/{translate-vfp.c.inc => translate-vfp.c} (94%)
97
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
2
3
Commit dfc388797cc4 ("hw/arm: xlnx: Set all boards' GEM 'phy-addr'
3
NUVIA was acquired by Qualcomm in March 2021, but kept functioning on
4
property value to 23") configured the PHY address for xilinx-zynq-a9
4
separate infrastructure for a transitional period. We've now switched
5
to 23. When trying to boot xilinx-zynq-a9 with zynq-zc702.dtb or
5
over to contributing as Qualcomm Innovation Center (quicinc), so update
6
zynq-zc706.dtb, this results in the following error message when
6
my email address to reflect this.
7
trying to use the Ethernet interface.
8
7
9
macb e000b000.ethernet eth0: Could not attach PHY (-19)
8
Signed-off-by: Leif Lindholm <quic_llindhol@quicinc.com>
10
9
Message-id: 20220505113740.75565-1-quic_llindhol@quicinc.com
11
The devicetree files for ZC702 and ZC706 configure PHY address 7. The
10
Cc: Leif Lindholm <leif@nuviainc.com>
12
documentation for the ZC702 and ZC706 evaluation boards suggest that the
11
Cc: Peter Maydell <peter.maydell@linaro.org>
13
PHY address is 7, not 23. Other boards use PHY address 0, 1, 3, or 7.
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
I was unable to find a documentation or a devicetree file suggesting
13
[Fixed commit message typo]
15
or using PHY address 23. The Ethernet interface starts working with
16
zynq-zc702.dtb and zynq-zc706.dtb when setting the PHY address to 7,
17
so let's use it.
18
19
Cc: Bin Meng <bin.meng@windriver.com>
20
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
21
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
22
Acked-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
23
Message-id: 20210504124140.1100346-1-linux@roeck-us.net
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
---
15
---
26
hw/arm/xilinx_zynq.c | 2 +-
16
.mailmap | 3 ++-
27
1 file changed, 1 insertion(+), 1 deletion(-)
17
MAINTAINERS | 2 +-
18
2 files changed, 3 insertions(+), 2 deletions(-)
28
19
29
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
20
diff --git a/.mailmap b/.mailmap
30
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/xilinx_zynq.c
22
--- a/.mailmap
32
+++ b/hw/arm/xilinx_zynq.c
23
+++ b/.mailmap
33
@@ -XXX,XX +XXX,XX @@ static void gem_init(NICInfo *nd, uint32_t base, qemu_irq irq)
24
@@ -XXX,XX +XXX,XX @@ Greg Kurz <groug@kaod.org> <gkurz@linux.vnet.ibm.com>
34
qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
25
Huacai Chen <chenhuacai@kernel.org> <chenhc@lemote.com>
35
qdev_set_nic_properties(dev, nd);
26
Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
36
}
27
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
37
- object_property_set_int(OBJECT(dev), "phy-addr", 23, &error_abort);
28
-Leif Lindholm <leif@nuviainc.com> <leif.lindholm@linaro.org>
38
+ object_property_set_int(OBJECT(dev), "phy-addr", 7, &error_abort);
29
+Leif Lindholm <quic_llindhol@quicinc.com> <leif.lindholm@linaro.org>
39
s = SYS_BUS_DEVICE(dev);
30
+Leif Lindholm <quic_llindhol@quicinc.com> <leif@nuviainc.com>
40
sysbus_realize_and_unref(s, &error_fatal);
31
Radoslaw Biernacki <rad@semihalf.com> <radoslaw.biernacki@linaro.org>
41
sysbus_mmio_map(s, 0, base);
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
42
--
47
--
43
2.20.1
48
2.25.1
44
49
45
50
diff view generated by jsdifflib
1
Currently the trans functions for m-nocp.decode all live in
1
From: Richard Henderson <richard.henderson@linaro.org>
2
translate-vfp.inc.c; move them out into their own translation unit,
2
3
translate-m-nocp.c.
3
More gracefully handle cpregs when EL2 and/or EL3 are missing.
4
4
If the reg is entirely inaccessible, do not register it at all.
5
The trans_* functions here are pure code motion with no changes.
5
If the reg is for EL2, and EL3 is present but EL2 is not,
6
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.
14
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20220506180242.216785-2-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210430132740.10391-5-peter.maydell@linaro.org
10
---
19
---
11
target/arm/translate-a32.h | 3 +
20
target/arm/cpregs.h | 11 +++
12
target/arm/translate-m-nocp.c | 221 +++++++++++++++++++++++++++++++++
21
target/arm/helper.c | 178 ++++++++++++++++++++++++++++++--------------
13
target/arm/translate.c | 1 -
22
2 files changed, 133 insertions(+), 56 deletions(-)
14
target/arm/translate-vfp.c.inc | 196 -----------------------------
23
15
target/arm/meson.build | 3 +-
24
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
16
5 files changed, 226 insertions(+), 198 deletions(-)
17
create mode 100644 target/arm/translate-m-nocp.c
18
19
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
20
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate-a32.h
26
--- a/target/arm/cpregs.h
22
+++ b/target/arm/translate-a32.h
27
+++ b/target/arm/cpregs.h
23
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@ enum {
24
#ifndef TARGET_ARM_TRANSLATE_A64_H
29
ARM_CP_SVE = 1 << 14,
25
#define TARGET_ARM_TRANSLATE_A64_H
30
/* Flag: Do not expose in gdb sysreg xml. */
26
31
ARM_CP_NO_GDB = 1 << 15,
27
+/* Prototypes for autogenerated disassembler functions */
32
+ /*
28
+bool disas_m_nocp(DisasContext *dc, uint32_t insn);
33
+ * Flags: If EL3 but not EL2...
29
+
34
+ * - UNDEF: discard the cpreg,
30
void load_reg_var(DisasContext *s, TCGv_i32 var, int reg);
35
+ * - KEEP: retain the cpreg as is,
31
void arm_gen_condlabel(DisasContext *s);
36
+ * - C_NZ: set const on the cpreg, but retain resetvalue,
32
bool vfp_access_check(DisasContext *s);
37
+ * - else: set const on the cpreg, zero resetvalue, aka RES0.
33
diff --git a/target/arm/translate-m-nocp.c b/target/arm/translate-m-nocp.c
38
+ * See rule RJFFP in section D1.1.3 of DDI0487H.a.
34
new file mode 100644
39
+ */
35
index XXXXXXX..XXXXXXX
40
+ ARM_CP_EL3_NO_EL2_UNDEF = 1 << 16,
36
--- /dev/null
41
+ ARM_CP_EL3_NO_EL2_KEEP = 1 << 17,
37
+++ b/target/arm/translate-m-nocp.c
42
+ ARM_CP_EL3_NO_EL2_C_NZ = 1 << 18,
38
@@ -XXX,XX +XXX,XX @@
43
};
39
+/*
44
40
+ * ARM translation: M-profile NOCP special-case instructions
45
/*
41
+ *
46
diff --git a/target/arm/helper.c b/target/arm/helper.c
42
+ * Copyright (c) 2020 Linaro, Ltd.
47
index XXXXXXX..XXXXXXX 100644
43
+ *
48
--- a/target/arm/helper.c
44
+ * This library is free software; you can redistribute it and/or
49
+++ b/target/arm/helper.c
45
+ * modify it under the terms of the GNU Lesser General Public
50
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
46
+ * License as published by the Free Software Foundation; either
51
.access = PL1_RW, .readfn = spsel_read, .writefn = spsel_write },
47
+ * version 2.1 of the License, or (at your option) any later version.
52
{ .name = "FPEXC32_EL2", .state = ARM_CP_STATE_AA64,
48
+ *
53
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 3, .opc2 = 0,
49
+ * This library is distributed in the hope that it will be useful,
54
- .access = PL2_RW, .type = ARM_CP_ALIAS | ARM_CP_FPU,
50
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
55
+ .access = PL2_RW,
51
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
56
+ .type = ARM_CP_ALIAS | ARM_CP_FPU | ARM_CP_EL3_NO_EL2_KEEP,
52
+ * Lesser General Public License for more details.
57
.fieldoffset = offsetof(CPUARMState, vfp.xregs[ARM_VFP_FPEXC]) },
53
+ *
58
{ .name = "DACR32_EL2", .state = ARM_CP_STATE_AA64,
54
+ * You should have received a copy of the GNU Lesser General Public
59
.opc0 = 3, .opc1 = 4, .crn = 3, .crm = 0, .opc2 = 0,
55
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
60
- .access = PL2_RW, .resetvalue = 0,
56
+ */
61
+ .access = PL2_RW, .resetvalue = 0, .type = ARM_CP_EL3_NO_EL2_KEEP,
57
+
62
.writefn = dacr_write, .raw_writefn = raw_write,
58
+#include "qemu/osdep.h"
63
.fieldoffset = offsetof(CPUARMState, cp15.dacr32_el2) },
59
+#include "tcg/tcg-op.h"
64
{ .name = "IFSR32_EL2", .state = ARM_CP_STATE_AA64,
60
+#include "translate.h"
65
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 0, .opc2 = 1,
61
+#include "translate-a32.h"
66
- .access = PL2_RW, .resetvalue = 0,
62
+
67
+ .access = PL2_RW, .resetvalue = 0, .type = ARM_CP_EL3_NO_EL2_KEEP,
63
+#include "decode-m-nocp.c.inc"
68
.fieldoffset = offsetof(CPUARMState, cp15.ifsr32_el2) },
64
+
69
{ .name = "SPSR_IRQ", .state = ARM_CP_STATE_AA64,
65
+/*
70
.type = ARM_CP_ALIAS,
66
+ * Decode VLLDM and VLSTM are nonstandard because:
71
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
67
+ * * if there is no FPU then these insns must NOP in
72
.writefn = tlbimva_hyp_is_write },
68
+ * Secure state and UNDEF in Nonsecure state
73
{ .name = "TLBI_ALLE2", .state = ARM_CP_STATE_AA64,
69
+ * * if there is an FPU then these insns do not have
74
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0,
70
+ * the usual behaviour that vfp_access_check() provides of
75
- .type = ARM_CP_NO_RAW, .access = PL2_W,
71
+ * being controlled by CPACR/NSACR enable bits or the
76
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
72
+ * lazy-stacking logic.
77
.writefn = tlbi_aa64_alle2_write },
73
+ */
78
{ .name = "TLBI_VAE2", .state = ARM_CP_STATE_AA64,
74
+static bool trans_VLLDM_VLSTM(DisasContext *s, arg_VLLDM_VLSTM *a)
79
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1,
75
+{
80
- .type = ARM_CP_NO_RAW, .access = PL2_W,
76
+ TCGv_i32 fptr;
81
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
77
+
82
.writefn = tlbi_aa64_vae2_write },
78
+ if (!arm_dc_feature(s, ARM_FEATURE_M) ||
83
{ .name = "TLBI_VALE2", .state = ARM_CP_STATE_AA64,
79
+ !arm_dc_feature(s, ARM_FEATURE_V8)) {
84
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5,
80
+ return false;
85
- .access = PL2_W, .type = ARM_CP_NO_RAW,
81
+ }
86
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
82
+
87
.writefn = tlbi_aa64_vae2_write },
83
+ if (a->op) {
88
{ .name = "TLBI_ALLE2IS", .state = ARM_CP_STATE_AA64,
89
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 0,
90
- .access = PL2_W, .type = ARM_CP_NO_RAW,
91
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
92
.writefn = tlbi_aa64_alle2is_write },
93
{ .name = "TLBI_VAE2IS", .state = ARM_CP_STATE_AA64,
94
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1,
95
- .type = ARM_CP_NO_RAW, .access = PL2_W,
96
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
97
.writefn = tlbi_aa64_vae2is_write },
98
{ .name = "TLBI_VALE2IS", .state = ARM_CP_STATE_AA64,
99
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5,
100
- .access = PL2_W, .type = ARM_CP_NO_RAW,
101
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
102
.writefn = tlbi_aa64_vae2is_write },
103
#ifndef CONFIG_USER_ONLY
104
/* Unlike the other EL2-related AT operations, these must
105
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
106
{ .name = "AT_S1E2R", .state = ARM_CP_STATE_AA64,
107
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 0,
108
.access = PL2_W, .accessfn = at_s1e2_access,
109
- .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, .writefn = ats_write64 },
110
+ .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC | ARM_CP_EL3_NO_EL2_UNDEF,
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,
237
}
238
}
239
240
+ /*
241
+ * Eliminate registers that are not present because the EL is missing.
242
+ * Doing this here makes it easier to put all registers for a given
243
+ * feature into the same ARMCPRegInfo array and define them all at once.
244
+ */
245
+ make_const = false;
246
+ if (arm_feature(env, ARM_FEATURE_EL3)) {
84
+ /*
247
+ /*
85
+ * T2 encoding ({D0-D31} reglist): v8.1M and up. We choose not
248
+ * An EL2 register without EL2 but with EL3 is (usually) RES0.
86
+ * to take the IMPDEF option to make memory accesses to the stack
249
+ * See rule RJFFP in section D1.1.3 of DDI0487H.a.
87
+ * slots that correspond to the D16-D31 registers (discarding
88
+ * read data and writing UNKNOWN values), so for us the T2
89
+ * encoding behaves identically to the T1 encoding.
90
+ */
250
+ */
91
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
251
+ int min_el = ctz32(r->access) / 2;
92
+ return false;
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);
93
+ }
257
+ }
94
+ } else {
258
+ } else {
95
+ /*
259
+ CPAccessRights max_el = (arm_feature(env, ARM_FEATURE_EL2)
96
+ * T1 encoding ({D0-D15} reglist); undef if we have 32 Dregs.
260
+ ? PL2_RW : PL1_RW);
97
+ * This is currently architecturally impossible, but we add the
261
+ if ((r->access & max_el) == 0) {
98
+ * check to stay in line with the pseudocode. Note that we must
262
+ return;
99
+ * emit code for the UNDEF so it takes precedence over the NOCP.
100
+ */
101
+ if (dc_isar_feature(aa32_simd_r32, s)) {
102
+ unallocated_encoding(s);
103
+ return true;
104
+ }
263
+ }
105
+ }
264
+ }
106
+
265
+
107
+ /*
266
/* Combine cpreg and name into one allocation. */
108
+ * If not secure, UNDEF. We must emit code for this
267
name_len = strlen(name) + 1;
109
+ * rather than returning false so that this takes
268
r2 = g_malloc(sizeof(*r2) + name_len);
110
+ * precedence over the m-nocp.decode NOCP fallback.
269
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
111
+ */
270
r2->opaque = opaque;
112
+ if (!s->v8m_secure) {
271
}
113
+ unallocated_encoding(s);
272
114
+ return true;
273
- isbanked = r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1];
115
+ }
274
- if (isbanked) {
116
+ /* If no fpu, NOP. */
275
+ if (make_const) {
117
+ if (!dc_isar_feature(aa32_vfp, s)) {
276
+ /* This should not have been a very special register to begin. */
118
+ return true;
277
+ int old_special = r2->type & ARM_CP_SPECIAL_MASK;
119
+ }
278
+ assert(old_special == 0 || old_special == ARM_CP_NOP);
120
+
279
/*
121
+ fptr = load_reg(s, a->rn);
280
- * Register is banked (using both entries in array).
122
+ if (a->l) {
281
- * Overwriting fieldoffset as the array is only used to define
123
+ gen_helper_v7m_vlldm(cpu_env, fptr);
282
- * banked registers but later only fieldoffset is used.
283
+ * Set the special function to CONST, retaining the other flags.
284
+ * This is important for e.g. ARM_CP_SVE so that we still
285
+ * take the SVE trap if CPTR_EL3.EZ == 0.
286
*/
287
- r2->fieldoffset = r->bank_fieldoffsets[ns];
288
- }
289
+ r2->type = (r2->type & ~ARM_CP_SPECIAL_MASK) | ARM_CP_CONST;
290
+ /*
291
+ * Usually, these registers become RES0, but there are a few
292
+ * special cases like VPIDR_EL2 which have a constant non-zero
293
+ * value with writes ignored.
294
+ */
295
+ if (!(r->type & ARM_CP_EL3_NO_EL2_C_NZ)) {
296
+ r2->resetvalue = 0;
297
+ }
298
+ /*
299
+ * ARM_CP_CONST has precedence, so removing the callbacks and
300
+ * offsets are not strictly necessary, but it is potentially
301
+ * less confusing to debug later.
302
+ */
303
+ r2->readfn = NULL;
304
+ r2->writefn = NULL;
305
+ r2->raw_readfn = NULL;
306
+ r2->raw_writefn = NULL;
307
+ r2->resetfn = NULL;
308
+ r2->fieldoffset = 0;
309
+ r2->bank_fieldoffsets[0] = 0;
310
+ r2->bank_fieldoffsets[1] = 0;
124
+ } else {
311
+ } else {
125
+ gen_helper_v7m_vlstm(cpu_env, fptr);
312
+ bool isbanked = r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1];
126
+ }
313
127
+ tcg_temp_free_i32(fptr);
314
- if (state == ARM_CP_STATE_AA32) {
128
+
315
if (isbanked) {
129
+ /* End the TB, because we have updated FP control bits */
316
/*
130
+ s->base.is_jmp = DISAS_UPDATE_EXIT;
317
- * If the register is banked then we don't need to migrate or
131
+ return true;
318
- * reset the 32-bit instance in certain cases:
132
+}
319
- *
133
+
320
- * 1) If the register has both 32-bit and 64-bit instances then we
134
+static bool trans_VSCCLRM(DisasContext *s, arg_VSCCLRM *a)
321
- * can count on the 64-bit instance taking care of the
135
+{
322
- * non-secure bank.
136
+ int btmreg, topreg;
323
- * 2) If ARMv8 is enabled then we can count on a 64-bit version
137
+ TCGv_i64 zero;
324
- * taking care of the secure bank. This requires that separate
138
+ TCGv_i32 aspen, sfpa;
325
- * 32 and 64-bit definitions are provided.
139
+
326
+ * Register is banked (using both entries in array).
140
+ if (!dc_isar_feature(aa32_m_sec_state, s)) {
327
+ * Overwriting fieldoffset as the array is only used to define
141
+ /* Before v8.1M, fall through in decode to NOCP check */
328
+ * banked registers but later only fieldoffset is used.
142
+ return false;
329
*/
143
+ }
330
- if ((r->state == ARM_CP_STATE_BOTH && ns) ||
144
+
331
- (arm_feature(&cpu->env, ARM_FEATURE_V8) && !ns)) {
145
+ /* Explicitly UNDEF because this takes precedence over NOCP */
332
+ r2->fieldoffset = r->bank_fieldoffsets[ns];
146
+ if (!arm_dc_feature(s, ARM_FEATURE_M_MAIN) || !s->v8m_secure) {
333
+ }
147
+ unallocated_encoding(s);
334
+ if (state == ARM_CP_STATE_AA32) {
148
+ return true;
335
+ if (isbanked) {
149
+ }
336
+ /*
150
+
337
+ * If the register is banked then we don't need to migrate or
151
+ if (!dc_isar_feature(aa32_vfp_simd, s)) {
338
+ * reset the 32-bit instance in certain cases:
152
+ /* NOP if we have neither FP nor MVE */
339
+ *
153
+ return true;
340
+ * 1) If the register has both 32-bit and 64-bit instances
154
+ }
341
+ * then we can count on the 64-bit instance taking care
155
+
342
+ * of the non-secure bank.
156
+ /*
343
+ * 2) If ARMv8 is enabled then we can count on a 64-bit
157
+ * If FPCCR.ASPEN != 0 && CONTROL_S.SFPA == 0 then there is no
344
+ * version taking care of the secure bank. This requires
158
+ * active floating point context so we must NOP (without doing
345
+ * that separate 32 and 64-bit definitions are provided.
159
+ * any lazy state preservation or the NOCP check).
346
+ */
160
+ */
347
+ if ((r->state == ARM_CP_STATE_BOTH && ns) ||
161
+ aspen = load_cpu_field(v7m.fpccr[M_REG_S]);
348
+ (arm_feature(env, ARM_FEATURE_V8) && !ns)) {
162
+ sfpa = load_cpu_field(v7m.control[M_REG_S]);
349
+ r2->type |= ARM_CP_ALIAS;
163
+ tcg_gen_andi_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
350
+ }
164
+ tcg_gen_xori_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
351
+ } else if ((secstate != r->secure) && !ns) {
165
+ tcg_gen_andi_i32(sfpa, sfpa, R_V7M_CONTROL_SFPA_MASK);
352
+ /*
166
+ tcg_gen_or_i32(sfpa, sfpa, aspen);
353
+ * The register is not banked so we only want to allow
167
+ arm_gen_condlabel(s);
354
+ * migration of the non-secure instance.
168
+ tcg_gen_brcondi_i32(TCG_COND_EQ, sfpa, 0, s->condlabel);
355
+ */
169
+
356
r2->type |= ARM_CP_ALIAS;
170
+ if (s->fp_excp_el != 0) {
357
}
171
+ gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
358
- } else if ((secstate != r->secure) && !ns) {
172
+ syn_uncategorized(), s->fp_excp_el);
359
- /*
173
+ return true;
360
- * The register is not banked so we only want to allow migration
174
+ }
361
- * of the non-secure instance.
175
+
362
- */
176
+ topreg = a->vd + a->imm - 1;
363
- r2->type |= ARM_CP_ALIAS;
177
+ btmreg = a->vd;
178
+
179
+ /* Convert to Sreg numbers if the insn specified in Dregs */
180
+ if (a->size == 3) {
181
+ topreg = topreg * 2 + 1;
182
+ btmreg *= 2;
183
+ }
184
+
185
+ if (topreg > 63 || (topreg > 31 && !(topreg & 1))) {
186
+ /* UNPREDICTABLE: we choose to undef */
187
+ unallocated_encoding(s);
188
+ return true;
189
+ }
190
+
191
+ /* Silently ignore requests to clear D16-D31 if they don't exist */
192
+ if (topreg > 31 && !dc_isar_feature(aa32_simd_r32, s)) {
193
+ topreg = 31;
194
+ }
195
+
196
+ if (!vfp_access_check(s)) {
197
+ return true;
198
+ }
199
+
200
+ /* Zero the Sregs from btmreg to topreg inclusive. */
201
+ zero = tcg_const_i64(0);
202
+ if (btmreg & 1) {
203
+ write_neon_element64(zero, btmreg >> 1, 1, MO_32);
204
+ btmreg++;
205
+ }
206
+ for (; btmreg + 1 <= topreg; btmreg += 2) {
207
+ write_neon_element64(zero, btmreg >> 1, 0, MO_64);
208
+ }
209
+ if (btmreg == topreg) {
210
+ write_neon_element64(zero, btmreg >> 1, 0, MO_32);
211
+ btmreg++;
212
+ }
213
+ assert(btmreg == topreg + 1);
214
+ /* TODO: when MVE is implemented, zero VPR here */
215
+ return true;
216
+}
217
+
218
+static bool trans_NOCP(DisasContext *s, arg_nocp *a)
219
+{
220
+ /*
221
+ * Handle M-profile early check for disabled coprocessor:
222
+ * all we need to do here is emit the NOCP exception if
223
+ * the coprocessor is disabled. Otherwise we return false
224
+ * and the real VFP/etc decode will handle the insn.
225
+ */
226
+ assert(arm_dc_feature(s, ARM_FEATURE_M));
227
+
228
+ if (a->cp == 11) {
229
+ a->cp = 10;
230
+ }
231
+ if (arm_dc_feature(s, ARM_FEATURE_V8_1M) &&
232
+ (a->cp == 8 || a->cp == 9 || a->cp == 14 || a->cp == 15)) {
233
+ /* in v8.1M cp 8, 9, 14, 15 also are governed by the cp10 enable */
234
+ a->cp = 10;
235
+ }
236
+
237
+ if (a->cp != 10) {
238
+ gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
239
+ syn_uncategorized(), default_exception_el(s));
240
+ return true;
241
+ }
242
+
243
+ if (s->fp_excp_el != 0) {
244
+ gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
245
+ syn_uncategorized(), s->fp_excp_el);
246
+ return true;
247
+ }
248
+
249
+ return false;
250
+}
251
+
252
+static bool trans_NOCP_8_1(DisasContext *s, arg_nocp *a)
253
+{
254
+ /* This range needs a coprocessor check for v8.1M and later only */
255
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
256
+ return false;
257
+ }
258
+ return trans_NOCP(s, a);
259
+}
260
diff --git a/target/arm/translate.c b/target/arm/translate.c
261
index XXXXXXX..XXXXXXX 100644
262
--- a/target/arm/translate.c
263
+++ b/target/arm/translate.c
264
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
265
#define ARM_CP_RW_BIT (1 << 20)
266
267
/* Include the VFP and Neon decoders */
268
-#include "decode-m-nocp.c.inc"
269
#include "translate-vfp.c.inc"
270
#include "translate-neon.c.inc"
271
272
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
273
index XXXXXXX..XXXXXXX 100644
274
--- a/target/arm/translate-vfp.c.inc
275
+++ b/target/arm/translate-vfp.c.inc
276
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
277
return true;
278
}
279
280
-/*
281
- * Decode VLLDM and VLSTM are nonstandard because:
282
- * * if there is no FPU then these insns must NOP in
283
- * Secure state and UNDEF in Nonsecure state
284
- * * if there is an FPU then these insns do not have
285
- * the usual behaviour that vfp_access_check() provides of
286
- * being controlled by CPACR/NSACR enable bits or the
287
- * lazy-stacking logic.
288
- */
289
-static bool trans_VLLDM_VLSTM(DisasContext *s, arg_VLLDM_VLSTM *a)
290
-{
291
- TCGv_i32 fptr;
292
-
293
- if (!arm_dc_feature(s, ARM_FEATURE_M) ||
294
- !arm_dc_feature(s, ARM_FEATURE_V8)) {
295
- return false;
296
- }
297
-
298
- if (a->op) {
299
- /*
300
- * T2 encoding ({D0-D31} reglist): v8.1M and up. We choose not
301
- * to take the IMPDEF option to make memory accesses to the stack
302
- * slots that correspond to the D16-D31 registers (discarding
303
- * read data and writing UNKNOWN values), so for us the T2
304
- * encoding behaves identically to the T1 encoding.
305
- */
306
- if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
307
- return false;
308
- }
364
- }
309
- } else {
365
310
- /*
366
- if (HOST_BIG_ENDIAN &&
311
- * T1 encoding ({D0-D15} reglist); undef if we have 32 Dregs.
367
- r->state == ARM_CP_STATE_BOTH && r2->fieldoffset) {
312
- * This is currently architecturally impossible, but we add the
368
- r2->fieldoffset += sizeof(uint32_t);
313
- * check to stay in line with the pseudocode. Note that we must
369
+ if (HOST_BIG_ENDIAN &&
314
- * emit code for the UNDEF so it takes precedence over the NOCP.
370
+ r->state == ARM_CP_STATE_BOTH && r2->fieldoffset) {
315
- */
371
+ r2->fieldoffset += sizeof(uint32_t);
316
- if (dc_isar_feature(aa32_simd_r32, s)) {
372
+ }
317
- unallocated_encoding(s);
373
}
318
- return true;
374
}
319
- }
375
320
- }
376
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
321
-
377
* multiple times. Special registers (ie NOP/WFI) are
322
- /*
378
* never migratable and not even raw-accessible.
323
- * If not secure, UNDEF. We must emit code for this
379
*/
324
- * rather than returning false so that this takes
380
- if (r->type & ARM_CP_SPECIAL_MASK) {
325
- * precedence over the m-nocp.decode NOCP fallback.
381
+ if (r2->type & ARM_CP_SPECIAL_MASK) {
326
- */
382
r2->type |= ARM_CP_NO_RAW;
327
- if (!s->v8m_secure) {
383
}
328
- unallocated_encoding(s);
384
if (((r->crm == CP_ANY) && crm != 0) ||
329
- return true;
330
- }
331
- /* If no fpu, NOP. */
332
- if (!dc_isar_feature(aa32_vfp, s)) {
333
- return true;
334
- }
335
-
336
- fptr = load_reg(s, a->rn);
337
- if (a->l) {
338
- gen_helper_v7m_vlldm(cpu_env, fptr);
339
- } else {
340
- gen_helper_v7m_vlstm(cpu_env, fptr);
341
- }
342
- tcg_temp_free_i32(fptr);
343
-
344
- /* End the TB, because we have updated FP control bits */
345
- s->base.is_jmp = DISAS_UPDATE_EXIT;
346
- return true;
347
-}
348
-
349
-static bool trans_VSCCLRM(DisasContext *s, arg_VSCCLRM *a)
350
-{
351
- int btmreg, topreg;
352
- TCGv_i64 zero;
353
- TCGv_i32 aspen, sfpa;
354
-
355
- if (!dc_isar_feature(aa32_m_sec_state, s)) {
356
- /* Before v8.1M, fall through in decode to NOCP check */
357
- return false;
358
- }
359
-
360
- /* Explicitly UNDEF because this takes precedence over NOCP */
361
- if (!arm_dc_feature(s, ARM_FEATURE_M_MAIN) || !s->v8m_secure) {
362
- unallocated_encoding(s);
363
- return true;
364
- }
365
-
366
- if (!dc_isar_feature(aa32_vfp_simd, s)) {
367
- /* NOP if we have neither FP nor MVE */
368
- return true;
369
- }
370
-
371
- /*
372
- * If FPCCR.ASPEN != 0 && CONTROL_S.SFPA == 0 then there is no
373
- * active floating point context so we must NOP (without doing
374
- * any lazy state preservation or the NOCP check).
375
- */
376
- aspen = load_cpu_field(v7m.fpccr[M_REG_S]);
377
- sfpa = load_cpu_field(v7m.control[M_REG_S]);
378
- tcg_gen_andi_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
379
- tcg_gen_xori_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
380
- tcg_gen_andi_i32(sfpa, sfpa, R_V7M_CONTROL_SFPA_MASK);
381
- tcg_gen_or_i32(sfpa, sfpa, aspen);
382
- arm_gen_condlabel(s);
383
- tcg_gen_brcondi_i32(TCG_COND_EQ, sfpa, 0, s->condlabel);
384
-
385
- if (s->fp_excp_el != 0) {
386
- gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
387
- syn_uncategorized(), s->fp_excp_el);
388
- return true;
389
- }
390
-
391
- topreg = a->vd + a->imm - 1;
392
- btmreg = a->vd;
393
-
394
- /* Convert to Sreg numbers if the insn specified in Dregs */
395
- if (a->size == 3) {
396
- topreg = topreg * 2 + 1;
397
- btmreg *= 2;
398
- }
399
-
400
- if (topreg > 63 || (topreg > 31 && !(topreg & 1))) {
401
- /* UNPREDICTABLE: we choose to undef */
402
- unallocated_encoding(s);
403
- return true;
404
- }
405
-
406
- /* Silently ignore requests to clear D16-D31 if they don't exist */
407
- if (topreg > 31 && !dc_isar_feature(aa32_simd_r32, s)) {
408
- topreg = 31;
409
- }
410
-
411
- if (!vfp_access_check(s)) {
412
- return true;
413
- }
414
-
415
- /* Zero the Sregs from btmreg to topreg inclusive. */
416
- zero = tcg_const_i64(0);
417
- if (btmreg & 1) {
418
- write_neon_element64(zero, btmreg >> 1, 1, MO_32);
419
- btmreg++;
420
- }
421
- for (; btmreg + 1 <= topreg; btmreg += 2) {
422
- write_neon_element64(zero, btmreg >> 1, 0, MO_64);
423
- }
424
- if (btmreg == topreg) {
425
- write_neon_element64(zero, btmreg >> 1, 0, MO_32);
426
- btmreg++;
427
- }
428
- assert(btmreg == topreg + 1);
429
- /* TODO: when MVE is implemented, zero VPR here */
430
- return true;
431
-}
432
-
433
-static bool trans_NOCP(DisasContext *s, arg_nocp *a)
434
-{
435
- /*
436
- * Handle M-profile early check for disabled coprocessor:
437
- * all we need to do here is emit the NOCP exception if
438
- * the coprocessor is disabled. Otherwise we return false
439
- * and the real VFP/etc decode will handle the insn.
440
- */
441
- assert(arm_dc_feature(s, ARM_FEATURE_M));
442
-
443
- if (a->cp == 11) {
444
- a->cp = 10;
445
- }
446
- if (arm_dc_feature(s, ARM_FEATURE_V8_1M) &&
447
- (a->cp == 8 || a->cp == 9 || a->cp == 14 || a->cp == 15)) {
448
- /* in v8.1M cp 8, 9, 14, 15 also are governed by the cp10 enable */
449
- a->cp = 10;
450
- }
451
-
452
- if (a->cp != 10) {
453
- gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
454
- syn_uncategorized(), default_exception_el(s));
455
- return true;
456
- }
457
-
458
- if (s->fp_excp_el != 0) {
459
- gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
460
- syn_uncategorized(), s->fp_excp_el);
461
- return true;
462
- }
463
-
464
- return false;
465
-}
466
-
467
-static bool trans_NOCP_8_1(DisasContext *s, arg_nocp *a)
468
-{
469
- /* This range needs a coprocessor check for v8.1M and later only */
470
- if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
471
- return false;
472
- }
473
- return trans_NOCP(s, a);
474
-}
475
-
476
static bool trans_VINS(DisasContext *s, arg_VINS *a)
477
{
478
TCGv_i32 rd, rm;
479
diff --git a/target/arm/meson.build b/target/arm/meson.build
480
index XXXXXXX..XXXXXXX 100644
481
--- a/target/arm/meson.build
482
+++ b/target/arm/meson.build
483
@@ -XXX,XX +XXX,XX @@ gen = [
484
decodetree.process('neon-ls.decode', extra_args: '--static-decode=disas_neon_ls'),
485
decodetree.process('vfp.decode', extra_args: '--static-decode=disas_vfp'),
486
decodetree.process('vfp-uncond.decode', extra_args: '--static-decode=disas_vfp_uncond'),
487
- decodetree.process('m-nocp.decode', extra_args: '--static-decode=disas_m_nocp'),
488
+ decodetree.process('m-nocp.decode', extra_args: '--decode=disas_m_nocp'),
489
decodetree.process('a32.decode', extra_args: '--static-decode=disas_a32'),
490
decodetree.process('a32-uncond.decode', extra_args: '--static-decode=disas_a32_uncond'),
491
decodetree.process('t32.decode', extra_args: '--static-decode=disas_t32'),
492
@@ -XXX,XX +XXX,XX @@ arm_ss.add(files(
493
'op_helper.c',
494
'tlb_helper.c',
495
'translate.c',
496
+ 'translate-m-nocp.c',
497
'vec_helper.c',
498
'vfp_helper.c',
499
'cpu_tcg.c',
500
--
385
--
501
2.20.1
386
2.25.1
502
503
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
We want to split out the .c.inc files which are currently included
1
From: Richard Henderson <richard.henderson@linaro.org>
2
into translate.c so they are separate compilation units. To do this
3
we need to make some functions which are currently file-local to
4
translate.c have global scope; create a translate-a32.h paralleling
5
the existing translate-a64.h as a place for these declarations to
6
live, so that code moved into the new compilation units can call
7
them.
8
2
9
The functions made global here are those required by the
3
Drop zcr_no_el2_reginfo and merge the 3 registers into one array,
10
m-nocp.decode functions, except that I have converted the whole
4
now that ZCR_EL2 can be squashed to RES0 and ZCR_EL3 dropped
11
family of {read,write}_neon_element* and also both the load_cpu and
5
while registering.
12
store_cpu functions for consistency, even though m-nocp only wants a
13
few functions from each.
14
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220506180242.216785-4-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20210430132740.10391-4-peter.maydell@linaro.org
18
---
11
---
19
target/arm/translate-a32.h | 57 ++++++++++++++++++++++++++++++++++
12
target/arm/helper.c | 55 ++++++++++++++-------------------------------
20
target/arm/translate.c | 39 +++++------------------
13
1 file changed, 17 insertions(+), 38 deletions(-)
21
target/arm/translate-vfp.c.inc | 2 +-
22
3 files changed, 65 insertions(+), 33 deletions(-)
23
create mode 100644 target/arm/translate-a32.h
24
14
25
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
26
new file mode 100644
27
index XXXXXXX..XXXXXXX
28
--- /dev/null
29
+++ b/target/arm/translate-a32.h
30
@@ -XXX,XX +XXX,XX @@
31
+/*
32
+ * AArch32 translation, common definitions.
33
+ *
34
+ * Copyright (c) 2021 Linaro, Ltd.
35
+ *
36
+ * This library is free software; you can redistribute it and/or
37
+ * modify it under the terms of the GNU Lesser General Public
38
+ * License as published by the Free Software Foundation; either
39
+ * version 2.1 of the License, or (at your option) any later version.
40
+ *
41
+ * This library is distributed in the hope that it will be useful,
42
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
43
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
44
+ * Lesser General Public License for more details.
45
+ *
46
+ * You should have received a copy of the GNU Lesser General Public
47
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
48
+ */
49
+
50
+#ifndef TARGET_ARM_TRANSLATE_A64_H
51
+#define TARGET_ARM_TRANSLATE_A64_H
52
+
53
+void load_reg_var(DisasContext *s, TCGv_i32 var, int reg);
54
+void arm_gen_condlabel(DisasContext *s);
55
+bool vfp_access_check(DisasContext *s);
56
+void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop);
57
+void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop);
58
+void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop);
59
+void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop);
60
+
61
+static inline TCGv_i32 load_cpu_offset(int offset)
62
+{
63
+ TCGv_i32 tmp = tcg_temp_new_i32();
64
+ tcg_gen_ld_i32(tmp, cpu_env, offset);
65
+ return tmp;
66
+}
67
+
68
+#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
69
+
70
+static inline void store_cpu_offset(TCGv_i32 var, int offset)
71
+{
72
+ tcg_gen_st_i32(var, cpu_env, offset);
73
+ tcg_temp_free_i32(var);
74
+}
75
+
76
+#define store_cpu_field(var, name) \
77
+ store_cpu_offset(var, offsetof(CPUARMState, name))
78
+
79
+/* Create a new temporary and set it to the value of a CPU register. */
80
+static inline TCGv_i32 load_reg(DisasContext *s, int reg)
81
+{
82
+ TCGv_i32 tmp = tcg_temp_new_i32();
83
+ load_reg_var(s, tmp, reg);
84
+ return tmp;
85
+}
86
+
87
+#endif
88
diff --git a/target/arm/translate.c b/target/arm/translate.c
89
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/translate.c
17
--- a/target/arm/helper.c
91
+++ b/target/arm/translate.c
18
+++ b/target/arm/helper.c
92
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
93
#define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
94
95
#include "translate.h"
96
+#include "translate-a32.h"
97
98
#if defined(CONFIG_USER_ONLY)
99
#define IS_USER(s) 1
100
@@ -XXX,XX +XXX,XX @@ void arm_translate_init(void)
101
}
102
103
/* Generate a label used for skipping this instruction */
104
-static void arm_gen_condlabel(DisasContext *s)
105
+void arm_gen_condlabel(DisasContext *s)
106
{
107
if (!s->condjmp) {
108
s->condlabel = gen_new_label();
109
@@ -XXX,XX +XXX,XX @@ static inline int get_a32_user_mem_index(DisasContext *s)
110
}
20
}
111
}
21
}
112
22
113
-static inline TCGv_i32 load_cpu_offset(int offset)
23
-static const ARMCPRegInfo zcr_el1_reginfo = {
114
-{
24
- .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
115
- TCGv_i32 tmp = tcg_temp_new_i32();
25
- .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
116
- tcg_gen_ld_i32(tmp, cpu_env, offset);
26
- .access = PL1_RW, .type = ARM_CP_SVE,
117
- return tmp;
27
- .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
118
-}
28
- .writefn = zcr_write, .raw_writefn = raw_write
29
-};
119
-
30
-
120
-#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
31
-static const ARMCPRegInfo zcr_el2_reginfo = {
32
- .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
33
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
34
- .access = PL2_RW, .type = ARM_CP_SVE,
35
- .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
36
- .writefn = zcr_write, .raw_writefn = raw_write
37
-};
121
-
38
-
122
-static inline void store_cpu_offset(TCGv_i32 var, int offset)
39
-static const ARMCPRegInfo zcr_no_el2_reginfo = {
123
-{
40
- .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
124
- tcg_gen_st_i32(var, cpu_env, offset);
41
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
125
- tcg_temp_free_i32(var);
42
- .access = PL2_RW, .type = ARM_CP_SVE,
126
-}
43
- .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore
44
-};
127
-
45
-
128
-#define store_cpu_field(var, name) \
46
-static const ARMCPRegInfo zcr_el3_reginfo = {
129
- store_cpu_offset(var, offsetof(CPUARMState, name))
47
- .name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
130
-
48
- .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
131
/* The architectural value of PC. */
49
- .access = PL3_RW, .type = ARM_CP_SVE,
132
static uint32_t read_pc(DisasContext *s)
50
- .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
133
{
51
- .writefn = zcr_write, .raw_writefn = raw_write
134
@@ -XXX,XX +XXX,XX @@ static uint32_t read_pc(DisasContext *s)
52
+static const ARMCPRegInfo zcr_reginfo[] = {
135
}
53
+ { .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
136
54
+ .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
137
/* Set a variable to the value of a CPU register. */
55
+ .access = PL1_RW, .type = ARM_CP_SVE,
138
-static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
56
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
139
+void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
57
+ .writefn = zcr_write, .raw_writefn = raw_write },
140
{
58
+ { .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
141
if (reg == 15) {
59
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
142
tcg_gen_movi_i32(var, read_pc(s));
60
+ .access = PL2_RW, .type = ARM_CP_SVE,
143
@@ -XXX,XX +XXX,XX @@ static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
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)
144
}
72
}
145
}
73
146
74
if (cpu_isar_feature(aa64_sve, cpu)) {
147
-/* Create a new temporary and set it to the value of a CPU register. */
75
- define_one_arm_cp_reg(cpu, &zcr_el1_reginfo);
148
-static inline TCGv_i32 load_reg(DisasContext *s, int reg)
76
- if (arm_feature(env, ARM_FEATURE_EL2)) {
149
-{
77
- define_one_arm_cp_reg(cpu, &zcr_el2_reginfo);
150
- TCGv_i32 tmp = tcg_temp_new_i32();
78
- } else {
151
- load_reg_var(s, tmp, reg);
79
- define_one_arm_cp_reg(cpu, &zcr_no_el2_reginfo);
152
- return tmp;
80
- }
153
-}
81
- if (arm_feature(env, ARM_FEATURE_EL3)) {
154
-
82
- define_one_arm_cp_reg(cpu, &zcr_el3_reginfo);
155
/*
83
- }
156
* Create a new temp, REG + OFS, except PC is ALIGN(PC, 4).
84
+ define_arm_cp_regs(cpu, zcr_reginfo);
157
* This is used for load/store for which use of PC implies (literal),
158
@@ -XXX,XX +XXX,XX @@ static inline void vfp_store_reg32(TCGv_i32 var, int reg)
159
tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
160
}
161
162
-static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
163
+void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
164
{
165
long off = neon_element_offset(reg, ele, memop);
166
167
@@ -XXX,XX +XXX,XX @@ static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
168
}
85
}
169
}
86
170
87
#ifdef TARGET_AARCH64
171
-static void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
172
+void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
173
{
174
long off = neon_element_offset(reg, ele, memop);
175
176
@@ -XXX,XX +XXX,XX @@ static void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
177
}
178
}
179
180
-static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
181
+void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
182
{
183
long off = neon_element_offset(reg, ele, memop);
184
185
@@ -XXX,XX +XXX,XX @@ static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
186
}
187
}
188
189
-static void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
190
+void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
191
{
192
long off = neon_element_offset(reg, ele, memop);
193
194
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
195
index XXXXXXX..XXXXXXX 100644
196
--- a/target/arm/translate-vfp.c.inc
197
+++ b/target/arm/translate-vfp.c.inc
198
@@ -XXX,XX +XXX,XX @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
199
* The most usual kind of VFP access check, for everything except
200
* FMXR/FMRX to the always-available special registers.
201
*/
202
-static bool vfp_access_check(DisasContext *s)
203
+bool vfp_access_check(DisasContext *s)
204
{
205
return full_vfp_access_check(s, false);
206
}
207
--
88
--
208
2.20.1
89
2.25.1
209
210
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The i.MX25 PDK board has 2 banks for SDRAM, each can
3
This register is present for either VHE or Debugv8p2.
4
address up to 256 MiB. So the total RAM usable for this
5
board is 512M. When we ask for more we get a misleading
6
error message:
7
4
8
$ qemu-system-arm -M imx25-pdk -m 513M
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
qemu-system-arm: Invalid RAM size, should be 128 MiB
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
7
Message-id: 20220506180242.216785-5-richard.henderson@linaro.org
11
Update the error message to better match the reality:
12
13
$ qemu-system-arm -M imx25-pdk -m 513M
14
qemu-system-arm: RAM size more than 512 MiB is not supported
15
16
Fixes: bf350daae02 ("arm/imx25_pdk: drop RAM size fixup")
17
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
20
Message-id: 20210407225608.1882855-1-f4bug@amsat.org
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
9
---
23
hw/arm/imx25_pdk.c | 5 ++---
10
target/arm/helper.c | 15 +++++++++++----
24
1 file changed, 2 insertions(+), 3 deletions(-)
11
1 file changed, 11 insertions(+), 4 deletions(-)
25
12
26
diff --git a/hw/arm/imx25_pdk.c b/hw/arm/imx25_pdk.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
27
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/imx25_pdk.c
15
--- a/target/arm/helper.c
29
+++ b/hw/arm/imx25_pdk.c
16
+++ b/target/arm/helper.c
30
@@ -XXX,XX +XXX,XX @@ static struct arm_boot_info imx25_pdk_binfo;
17
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo jazelle_regs[] = {
31
18
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
32
static void imx25_pdk_init(MachineState *machine)
19
};
33
{
20
34
- MachineClass *mc = MACHINE_GET_CLASS(machine);
21
+static const ARMCPRegInfo contextidr_el2 = {
35
IMX25PDK *s = g_new0(IMX25PDK, 1);
22
+ .name = "CONTEXTIDR_EL2", .state = ARM_CP_STATE_AA64,
36
unsigned int ram_size;
23
+ .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 1,
37
unsigned int alias_offset;
24
+ .access = PL2_RW,
38
@@ -XXX,XX +XXX,XX @@ static void imx25_pdk_init(MachineState *machine)
25
+ .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[2])
39
26
+};
40
/* We need to initialize our memory */
27
+
41
if (machine->ram_size > (FSL_IMX25_SDRAM0_SIZE + FSL_IMX25_SDRAM1_SIZE)) {
28
static const ARMCPRegInfo vhe_reginfo[] = {
42
- char *sz = size_to_str(mc->default_ram_size);
29
- { .name = "CONTEXTIDR_EL2", .state = ARM_CP_STATE_AA64,
43
- error_report("Invalid RAM size, should be %s", sz);
30
- .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 1,
44
+ char *sz = size_to_str(FSL_IMX25_SDRAM0_SIZE + FSL_IMX25_SDRAM1_SIZE);
31
- .access = PL2_RW,
45
+ error_report("RAM size more than %s is not supported", sz);
32
- .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[2]) },
46
g_free(sz);
33
{ .name = "TTBR1_EL2", .state = ARM_CP_STATE_AA64,
47
exit(EXIT_FAILURE);
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);
38
}
39
40
+ if (cpu_isar_feature(aa64_vh, cpu) ||
41
+ cpu_isar_feature(aa64_debugv8p2, cpu)) {
42
+ define_one_arm_cp_reg(cpu, &contextidr_el2);
43
+ }
44
if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
45
define_arm_cp_regs(cpu, vhe_reginfo);
48
}
46
}
49
--
47
--
50
2.20.1
48
2.25.1
51
52
diff view generated by jsdifflib
1
Make the remaining functions which are needed by translate-vfp.c.inc
1
From: Richard Henderson <richard.henderson@linaro.org>
2
global.
2
3
3
Previously we were defining some of these in user-only mode,
4
but none of them are accessible from user-only, therefore
5
define them only in system mode.
6
7
This will shortly be used from cpu_tcg.c also.
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220506180242.216785-6-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-8-peter.maydell@linaro.org
8
---
13
---
9
target/arm/translate-a32.h | 18 ++++++++++++++++++
14
target/arm/internals.h | 6 ++++
10
target/arm/translate.c | 25 ++++++++-----------------
15
target/arm/cpu64.c | 64 +++---------------------------------------
11
2 files changed, 26 insertions(+), 17 deletions(-)
16
target/arm/cpu_tcg.c | 59 ++++++++++++++++++++++++++++++++++++++
12
17
3 files changed, 69 insertions(+), 60 deletions(-)
13
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
18
19
diff --git a/target/arm/internals.h b/target/arm/internals.h
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a32.h
21
--- a/target/arm/internals.h
16
+++ b/target/arm/translate-a32.h
22
+++ b/target/arm/internals.h
17
@@ -XXX,XX +XXX,XX @@ void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop);
23
@@ -XXX,XX +XXX,XX @@ int aarch64_fpu_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg);
18
void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop);
24
int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg);
19
void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop);
25
#endif
20
void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop);
26
21
+TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs);
27
+#ifdef CONFIG_USER_ONLY
22
+void gen_set_cpsr(TCGv_i32 var, uint32_t mask);
28
+static inline void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu) { }
23
+void gen_set_condexec(DisasContext *s);
24
+void gen_set_pc_im(DisasContext *s, target_ulong val);
25
+void gen_lookup_tb(DisasContext *s);
26
+long vfp_reg_offset(bool dp, unsigned reg);
27
+long neon_full_reg_offset(unsigned reg);
28
29
static inline TCGv_i32 load_cpu_offset(int offset)
30
{
31
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 load_reg(DisasContext *s, int reg)
32
return tmp;
33
}
34
35
+void store_reg(DisasContext *s, int reg, TCGv_i32 var);
36
+
37
void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
38
TCGv_i32 a32, int index, MemOp opc);
39
void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
40
@@ -XXX,XX +XXX,XX @@ DO_GEN_ST(32, MO_UL)
41
#undef DO_GEN_LD
42
#undef DO_GEN_ST
43
44
+#if defined(CONFIG_USER_ONLY)
45
+#define IS_USER(s) 1
46
+#else
29
+#else
47
+#define IS_USER(s) (s->user)
30
+void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu);
48
+#endif
31
+#endif
49
+
32
+
50
+/* Set NZCV flags from the high 4 bits of var. */
51
+#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
52
+
53
#endif
33
#endif
54
diff --git a/target/arm/translate.c b/target/arm/translate.c
34
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
55
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/translate.c
36
--- a/target/arm/cpu64.c
57
+++ b/target/arm/translate.c
37
+++ b/target/arm/cpu64.c
58
@@ -XXX,XX +XXX,XX @@
38
@@ -XXX,XX +XXX,XX @@
59
#include "translate.h"
39
#include "hvf_arm.h"
60
#include "translate-a32.h"
40
#include "qapi/visitor.h"
61
41
#include "hw/qdev-properties.h"
62
-#if defined(CONFIG_USER_ONLY)
42
-#include "cpregs.h"
63
-#define IS_USER(s) 1
43
+#include "internals.h"
64
-#else
44
65
-#define IS_USER(s) (s->user)
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
-}
66
-#endif
54
-#endif
67
-
55
-
68
/* These are TCG temporaries used only by the legacy iwMMXt decoder */
56
-static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = {
69
static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
57
-#ifndef CONFIG_USER_ONLY
70
/* These are TCG globals which alias CPUARMState fields */
58
- { .name = "L2CTLR_EL1", .state = ARM_CP_STATE_AA64,
71
@@ -XXX,XX +XXX,XX @@ void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
59
- .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 2,
72
* This is used for load/store for which use of PC implies (literal),
60
- .access = PL1_RW, .readfn = a57_a53_l2ctlr_read,
73
* or ADD that implies ADR.
61
- .writefn = arm_cp_write_ignore },
74
*/
62
- { .name = "L2CTLR",
75
-static TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
63
- .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 2,
76
+TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
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)
77
{
103
{
78
TCGv_i32 tmp = tcg_temp_new_i32();
104
ARMCPU *cpu = ARM_CPU(obj);
79
105
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
80
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
106
cpu->gic_num_lrs = 4;
81
107
cpu->gic_vpribits = 5;
82
/* Set a CPU register. The source must be a temporary and will be
108
cpu->gic_vprebits = 5;
83
marked as dead. */
109
- define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
84
-static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
110
+ define_cortex_a72_a57_a53_cp_reginfo(cpu);
85
+void store_reg(DisasContext *s, int reg, TCGv_i32 var)
86
{
87
if (reg == 15) {
88
/* In Thumb mode, we must ignore bit 0.
89
@@ -XXX,XX +XXX,XX @@ static void store_sp_checked(DisasContext *s, TCGv_i32 var)
90
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
91
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
92
93
-
94
-static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
95
+void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
96
{
97
TCGv_i32 tmp_mask = tcg_const_i32(mask);
98
gen_helper_cpsr_write(cpu_env, var, tmp_mask);
99
tcg_temp_free_i32(tmp_mask);
100
}
111
}
101
-/* Set NZCV flags from the high 4 bits of var. */
112
102
-#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
113
static void aarch64_a53_initfn(Object *obj)
103
114
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
104
static void gen_exception_internal(int excp)
115
cpu->gic_num_lrs = 4;
105
{
116
cpu->gic_vpribits = 5;
106
@@ -XXX,XX +XXX,XX @@ void arm_gen_test_cc(int cc, TCGLabel *label)
117
cpu->gic_vprebits = 5;
107
arm_free_cc(&cmp);
118
- define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
119
+ define_cortex_a72_a57_a53_cp_reginfo(cpu);
108
}
120
}
109
121
110
-static inline void gen_set_condexec(DisasContext *s)
122
static void aarch64_a72_initfn(Object *obj)
111
+void gen_set_condexec(DisasContext *s)
123
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
112
{
124
cpu->gic_num_lrs = 4;
113
if (s->condexec_mask) {
125
cpu->gic_vpribits = 5;
114
uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
126
cpu->gic_vprebits = 5;
115
@@ -XXX,XX +XXX,XX @@ static inline void gen_set_condexec(DisasContext *s)
127
- define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
116
}
128
+ define_cortex_a72_a57_a53_cp_reginfo(cpu);
117
}
129
}
118
130
119
-static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
131
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
120
+void gen_set_pc_im(DisasContext *s, target_ulong val)
132
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
121
{
133
index XXXXXXX..XXXXXXX 100644
122
tcg_gen_movi_i32(cpu_R[15], val);
134
--- a/target/arm/cpu_tcg.c
123
}
135
+++ b/target/arm/cpu_tcg.c
124
@@ -XXX,XX +XXX,XX @@ static void gen_exception_el(DisasContext *s, int excp, uint32_t syn,
136
@@ -XXX,XX +XXX,XX @@
125
}
137
#endif
126
138
#include "cpregs.h"
127
/* Force a TB lookup after an instruction that changes the CPU state. */
139
128
-static inline void gen_lookup_tb(DisasContext *s)
140
+#ifndef CONFIG_USER_ONLY
129
+void gen_lookup_tb(DisasContext *s)
141
+static uint64_t l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
130
{
142
+{
131
tcg_gen_movi_i32(cpu_R[15], s->base.pc_next);
143
+ ARMCPU *cpu = env_archcpu(env);
132
s->base.is_jmp = DISAS_EXIT;
144
+
133
@@ -XXX,XX +XXX,XX @@ static inline void gen_hlt(DisasContext *s, int imm)
145
+ /* Number of cores is in [25:24]; otherwise we RAZ */
134
/*
146
+ return (cpu->core_count - 1) << 24;
135
* Return the offset of a "full" NEON Dreg.
147
+}
136
*/
148
+
137
-static long neon_full_reg_offset(unsigned reg)
149
+static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = {
138
+long neon_full_reg_offset(unsigned reg)
150
+ { .name = "L2CTLR_EL1", .state = ARM_CP_STATE_AA64,
139
{
151
+ .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 2,
140
return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
152
+ .access = PL1_RW, .readfn = l2ctlr_read,
141
}
153
+ .writefn = arm_cp_write_ignore },
142
@@ -XXX,XX +XXX,XX @@ static long neon_element_offset(int reg, int element, MemOp memop)
154
+ { .name = "L2CTLR",
143
}
155
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 2,
144
156
+ .access = PL1_RW, .readfn = l2ctlr_read,
145
/* Return the offset of a VFP Dreg (dp = true) or VFP Sreg (dp = false). */
157
+ .writefn = arm_cp_write_ignore },
146
-static long vfp_reg_offset(bool dp, unsigned reg)
158
+ { .name = "L2ECTLR_EL1", .state = ARM_CP_STATE_AA64,
147
+long vfp_reg_offset(bool dp, unsigned reg)
159
+ .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 3,
148
{
160
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
149
if (dp) {
161
+ { .name = "L2ECTLR",
150
return neon_element_offset(reg, 0, MO_64);
162
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 3,
163
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
164
+ { .name = "L2ACTLR", .state = ARM_CP_STATE_BOTH,
165
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 0, .opc2 = 0,
166
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
167
+ { .name = "CPUACTLR_EL1", .state = ARM_CP_STATE_AA64,
168
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 0,
169
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
170
+ { .name = "CPUACTLR",
171
+ .cp = 15, .opc1 = 0, .crm = 15,
172
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
173
+ { .name = "CPUECTLR_EL1", .state = ARM_CP_STATE_AA64,
174
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 1,
175
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
176
+ { .name = "CPUECTLR",
177
+ .cp = 15, .opc1 = 1, .crm = 15,
178
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
179
+ { .name = "CPUMERRSR_EL1", .state = ARM_CP_STATE_AA64,
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)
194
+{
195
+ define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
196
+}
197
+#endif /* !CONFIG_USER_ONLY */
198
+
199
/* CPU models. These are not needed for the AArch64 linux-user build. */
200
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
201
151
--
202
--
152
2.20.1
203
2.25.1
153
154
diff view generated by jsdifflib
1
The WFI insn is not system-mode only, though it doesn't usually make
1
From: Richard Henderson <richard.henderson@linaro.org>
2
a huge amount of sense for userspace code to execute it. Currently
3
if you try it in qemu-arm then the helper function will raise an
4
EXCP_HLT exception, which is not covered by the switch in cpu_loop()
5
and results in an abort:
6
2
7
qemu: unhandled CPU exception 0x10001 - aborting
3
Instead of starting with cortex-a15 and adding v8 features to
8
R00=00000001 R01=408003e4 R02=408003ec R03=000102ec
4
a v7 cpu, begin with a v8 cpu stripped of its aarch64 features.
9
R04=00010a28 R05=00010158 R06=00087460 R07=00010158
5
This fixes the long-standing to-do where we only enabled v8
10
R08=00000000 R09=00000000 R10=00085b7c R11=408002a4
6
features for user-only.
11
R12=408002b8 R13=408002a0 R14=0001057c R15=000102f8
12
PSR=60000010 -ZC- A usr32
13
qemu:handle_cpu_signal received signal outside vCPU context @ pc=0x7fcbfa4f0a12
14
7
15
Make the WFI helper function return immediately in the usermode
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
emulator. This turns WFI into a NOP, which is OK because:
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
* architecturally "WFI is a NOP" is a permitted implementation
10
Message-id: 20220506180242.216785-7-richard.henderson@linaro.org
18
* aarch64 Linux kernels use the SCTLR_EL1.nTWI bit to trap
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
userspace WFI and NOP it (though aarch32 kernels currently
12
---
20
just let WFI do whatever it would do)
13
target/arm/cpu_tcg.c | 151 ++++++++++++++++++++++++++-----------------
14
1 file changed, 92 insertions(+), 59 deletions(-)
21
15
22
We could in theory make the translate.c code special case user-mode
16
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
23
emulation and NOP the insn entirely rather than making the helper
24
do nothing, but because no real world code will be trying to
25
execute WFI we don't care about efficiency and the helper provides
26
a single place where we can make the change rather than having
27
to touch multiple places in translate.c and translate-a64.c.
28
29
Fixes: https://bugs.launchpad.net/qemu/+bug/1926759
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
32
Message-id: 20210430162212.825-1-peter.maydell@linaro.org
33
---
34
target/arm/op_helper.c | 12 ++++++++++++
35
1 file changed, 12 insertions(+)
36
37
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
38
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/op_helper.c
18
--- a/target/arm/cpu_tcg.c
40
+++ b/target/arm/op_helper.c
19
+++ b/target/arm/cpu_tcg.c
41
@@ -XXX,XX +XXX,XX @@ static inline int check_wfx_trap(CPUARMState *env, bool is_wfe)
20
@@ -XXX,XX +XXX,XX @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
42
21
static void arm_max_initfn(Object *obj)
43
void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
44
{
22
{
45
+#ifdef CONFIG_USER_ONLY
23
ARMCPU *cpu = ARM_CPU(obj);
46
+ /*
24
+ uint32_t t;
47
+ * WFI in the user-mode emulator is technically permitted but not
25
48
+ * something any real-world code would do. AArch64 Linux kernels
26
- cortex_a15_initfn(obj);
49
+ * trap it via SCTRL_EL1.nTWI and make it an (expensive) NOP;
27
+ /* aarch64_a57_initfn, advertising none of the aarch64 features */
50
+ * AArch32 kernels don't trap it so it will delay a bit.
28
+ cpu->dtb_compatible = "arm,cortex-a57";
51
+ * For QEMU, make it NOP here, because trying to raise EXCP_HLT
29
+ set_feature(&cpu->env, ARM_FEATURE_V8);
52
+ * would trigger an abort.
30
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
53
+ */
31
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
54
+ return;
32
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
55
+#else
33
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
56
CPUState *cs = env_cpu(env);
34
+ set_feature(&cpu->env, ARM_FEATURE_EL3);
57
int target_el = check_wfx_trap(env, false);
35
+ set_feature(&cpu->env, ARM_FEATURE_PMU);
58
36
+ cpu->midr = 0x411fd070;
59
@@ -XXX,XX +XXX,XX @@ void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
37
+ cpu->revidr = 0x00000000;
60
cs->exception_index = EXCP_HLT;
38
+ cpu->reset_fpsid = 0x41034070;
61
cs->halted = 1;
39
+ cpu->isar.mvfr0 = 0x10110222;
62
cpu_loop_exit(cs);
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);
63
+#endif
180
+#endif
64
}
181
}
65
182
#endif /* !TARGET_AARCH64 */
66
void HELPER(wfe)(CPUARMState *env)
183
67
--
184
--
68
2.20.1
185
2.25.1
69
70
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
Make the remaining functions needed by the translate-neon code
1
From: Richard Henderson <richard.henderson@linaro.org>
2
global.
3
2
3
Share the code to set AArch32 max features so that we no
4
longer have code drift between qemu{-system,}-{arm,aarch64}.
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-9-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-13-peter.maydell@linaro.org
8
---
10
---
9
target/arm/translate-a32.h | 8 ++++++++
11
target/arm/internals.h | 2 +
10
target/arm/translate.c | 10 ++--------
12
target/arm/cpu64.c | 50 +-----------------
11
2 files changed, 10 insertions(+), 8 deletions(-)
13
target/arm/cpu_tcg.c | 114 ++++++++++++++++++++++-------------------
14
3 files changed, 65 insertions(+), 101 deletions(-)
12
15
13
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a32.h
18
--- a/target/arm/internals.h
16
+++ b/target/arm/translate-a32.h
19
+++ b/target/arm/internals.h
17
@@ -XXX,XX +XXX,XX @@ void gen_set_pc_im(DisasContext *s, target_ulong val);
20
@@ -XXX,XX +XXX,XX @@ static inline void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu) { }
18
void gen_lookup_tb(DisasContext *s);
21
void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu);
19
long vfp_reg_offset(bool dp, unsigned reg);
22
#endif
20
long neon_full_reg_offset(unsigned reg);
23
21
+long neon_element_offset(int reg, int element, MemOp memop);
24
+void aa32_max_features(ARMCPU *cpu);
22
+void gen_rev16(TCGv_i32 dest, TCGv_i32 var);
25
+
23
26
#endif
24
static inline TCGv_i32 load_cpu_offset(int offset)
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)
25
{
32
{
26
@@ -XXX,XX +XXX,XX @@ DO_GEN_ST(32, MO_UL)
33
ARMCPU *cpu = ARM_CPU(obj);
27
/* Set NZCV flags from the high 4 bits of var. */
34
uint64_t t;
28
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
35
- uint32_t u;
29
36
30
+/* Swap low and high halfwords. */
37
if (kvm_enabled() || hvf_enabled()) {
31
+static inline void gen_swap_half(TCGv_i32 dest, TCGv_i32 var)
38
/* With KVM or HVF, '-cpu max' is identical to '-cpu host' */
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)
32
+{
110
+{
33
+ tcg_gen_rotri_i32(dest, var, 16);
111
+ uint32_t t;
112
+
113
+ /* Add additional features supported by QEMU */
114
+ t = cpu->isar.id_isar5;
115
+ t = FIELD_DP32(t, ID_ISAR5, AES, 2);
116
+ t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
117
+ t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
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;
34
+}
165
+}
35
+
166
+
36
#endif
167
#ifndef CONFIG_USER_ONLY
37
diff --git a/target/arm/translate.c b/target/arm/translate.c
168
static uint64_t l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate.c
40
+++ b/target/arm/translate.c
41
@@ -XXX,XX +XXX,XX @@ static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
42
}
43
44
/* Byteswap each halfword. */
45
-static void gen_rev16(TCGv_i32 dest, TCGv_i32 var)
46
+void gen_rev16(TCGv_i32 dest, TCGv_i32 var)
47
{
169
{
48
TCGv_i32 tmp = tcg_temp_new_i32();
170
@@ -XXX,XX +XXX,XX @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
49
TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
171
static void arm_max_initfn(Object *obj)
50
@@ -XXX,XX +XXX,XX @@ static void gen_revsh(TCGv_i32 dest, TCGv_i32 var)
51
tcg_gen_ext16s_i32(dest, var);
52
}
53
54
-/* Swap low and high halfwords. */
55
-static void gen_swap_half(TCGv_i32 dest, TCGv_i32 var)
56
-{
57
- tcg_gen_rotri_i32(dest, var, 16);
58
-}
59
-
60
/* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
61
tmp = (t0 ^ t1) & 0x8000;
62
t0 &= ~0x8000;
63
@@ -XXX,XX +XXX,XX @@ long neon_full_reg_offset(unsigned reg)
64
* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
65
* where 0 is the least significant end of the register.
66
*/
67
-static long neon_element_offset(int reg, int element, MemOp memop)
68
+long neon_element_offset(int reg, int element, MemOp memop)
69
{
172
{
70
int element_size = 1 << (memop & MO_SIZE);
173
ARMCPU *cpu = ARM_CPU(obj);
71
int ofs = element * element_size;
174
- uint32_t t;
175
176
/* aarch64_a57_initfn, advertising none of the aarch64 features */
177
cpu->dtb_compatible = "arm,cortex-a57";
178
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
179
cpu->ccsidr[2] = 0x70ffe07a; /* 2048KB L2 cache */
180
define_cortex_a72_a57_a53_cp_reginfo(cpu);
181
182
- /* Add additional features supported by QEMU */
183
- t = cpu->isar.id_isar5;
184
- t = FIELD_DP32(t, ID_ISAR5, AES, 2);
185
- t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
186
- t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
187
- t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
188
- t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
189
- t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
190
- cpu->isar.id_isar5 = t;
191
-
192
- t = cpu->isar.id_isar6;
193
- t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
194
- t = FIELD_DP32(t, ID_ISAR6, DP, 1);
195
- t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
196
- t = FIELD_DP32(t, ID_ISAR6, SB, 1);
197
- t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
198
- t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
199
- t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
200
- cpu->isar.id_isar6 = t;
201
-
202
- t = cpu->isar.mvfr1;
203
- t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */
204
- t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
205
- cpu->isar.mvfr1 = t;
206
-
207
- t = cpu->isar.mvfr2;
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
- 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
/*
72
--
238
--
73
2.20.1
239
2.25.1
74
75
diff view generated by jsdifflib
1
On some boards, SCC config register CFG0 bit 0 controls whether
1
From: Richard Henderson <richard.henderson@linaro.org>
2
parts of the board memory map are remapped. Support this with:
3
* a device property scc-cfg0 so the board can specify the
4
initial value of the CFG0 register
5
* an outbound GPIO line which tracks bit 0 and which the board
6
can wire up to provide the remapping
7
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.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220506180242.216785-10-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20210504120912.23094-3-peter.maydell@linaro.org
12
---
11
---
13
include/hw/misc/mps2-scc.h | 9 +++++++++
12
target/arm/cpu64.c | 100 +++++++++++++++++++++----------------------
14
hw/misc/mps2-scc.c | 13 ++++++++++---
13
target/arm/cpu_tcg.c | 48 ++++++++++-----------
15
2 files changed, 19 insertions(+), 3 deletions(-)
14
2 files changed, 74 insertions(+), 74 deletions(-)
16
15
17
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
16
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/misc/mps2-scc.h
18
--- a/target/arm/cpu64.c
20
+++ b/include/hw/misc/mps2-scc.h
19
+++ b/target/arm/cpu64.c
21
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
22
* + QOM property "scc-cfg4": value of the read-only CFG4 register
21
cpu->midr = t;
23
* + QOM property "scc-aid": value of the read-only SCC_AID register
22
24
* + QOM property "scc-id": value of the read-only SCC_ID register
23
t = cpu->isar.id_aa64isar0;
25
+ * + QOM property "scc-cfg0": reset value of the CFG0 register
24
- t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* AES + PMULL */
26
* + QOM property array "oscclk": reset values of the OSCCLK registers
25
- t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1);
27
* (which are accessed via the SYS_CFG channel provided by this device)
26
- t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* SHA512 */
28
+ * + named GPIO output "remap": this tracks the value of CFG0 register
27
+ t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* FEAT_PMULL */
29
+ * bit 0. Boards where this bit controls memory remapping should
28
+ t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1); /* FEAT_SHA1 */
30
+ * connect this GPIO line to a function performing that mapping.
29
+ t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* FEAT_SHA512 */
31
+ * Boards where bit 0 has no special function should leave the GPIO
30
t = FIELD_DP64(t, ID_AA64ISAR0, CRC32, 1);
32
+ * output disconnected.
31
- t = FIELD_DP64(t, ID_AA64ISAR0, ATOMIC, 2);
33
*/
32
- t = FIELD_DP64(t, ID_AA64ISAR0, RDM, 1);
34
#ifndef MPS2_SCC_H
33
- t = FIELD_DP64(t, ID_AA64ISAR0, SHA3, 1);
35
#define MPS2_SCC_H
34
- t = FIELD_DP64(t, ID_AA64ISAR0, SM3, 1);
36
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
35
- t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 1);
37
uint32_t num_oscclk;
36
- t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
38
uint32_t *oscclk;
37
- t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1);
39
uint32_t *oscclk_reset;
38
- t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* v8.5-CondM */
40
+ uint32_t cfg0_reset;
39
- t = FIELD_DP64(t, ID_AA64ISAR0, TLB, 2); /* FEAT_TLBIRANGE */
41
+
40
- t = FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1);
42
+ qemu_irq remap;
41
+ t = FIELD_DP64(t, ID_AA64ISAR0, ATOMIC, 2); /* FEAT_LSE */
43
};
42
+ t = FIELD_DP64(t, ID_AA64ISAR0, RDM, 1); /* FEAT_RDM */
44
43
+ t = FIELD_DP64(t, ID_AA64ISAR0, SHA3, 1); /* FEAT_SHA3 */
45
#endif
44
+ t = FIELD_DP64(t, ID_AA64ISAR0, SM3, 1); /* FEAT_SM3 */
46
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
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
47
index XXXXXXX..XXXXXXX 100644
161
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/misc/mps2-scc.c
162
--- a/target/arm/cpu_tcg.c
49
+++ b/hw/misc/mps2-scc.c
163
+++ b/target/arm/cpu_tcg.c
50
@@ -XXX,XX +XXX,XX @@
164
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
51
#include "qemu/bitops.h"
165
52
#include "trace.h"
166
/* Add additional features supported by QEMU */
53
#include "hw/sysbus.h"
167
t = cpu->isar.id_isar5;
54
+#include "hw/irq.h"
168
- t = FIELD_DP32(t, ID_ISAR5, AES, 2);
55
#include "migration/vmstate.h"
169
- t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
56
#include "hw/registerfields.h"
170
- t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
57
#include "hw/misc/mps2-scc.h"
171
+ t = FIELD_DP32(t, ID_ISAR5, AES, 2); /* FEAT_PMULL */
58
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
172
+ t = FIELD_DP32(t, ID_ISAR5, SHA1, 1); /* FEAT_SHA1 */
59
switch (offset) {
173
+ t = FIELD_DP32(t, ID_ISAR5, SHA2, 1); /* FEAT_SHA256 */
60
case A_CFG0:
174
t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
61
/*
175
- t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
62
- * TODO on some boards bit 0 controls RAM remapping;
176
- t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
63
- * on others bit 1 is CPU_WAIT.
177
+ t = FIELD_DP32(t, ID_ISAR5, RDM, 1); /* FEAT_RDM */
64
+ * On some boards bit 0 controls board-specific remapping;
178
+ t = FIELD_DP32(t, ID_ISAR5, VCMA, 1); /* FEAT_FCMA */
65
+ * we always reflect bit 0 in the 'remap' GPIO output line,
179
cpu->isar.id_isar5 = t;
66
+ * and let the board wire it up or not as it chooses.
180
67
+ * TODO on some boards bit 1 is CPU_WAIT.
181
t = cpu->isar.id_isar6;
68
*/
182
- t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
69
s->cfg0 = value;
183
- t = FIELD_DP32(t, ID_ISAR6, DP, 1);
70
+ qemu_set_irq(s->remap, s->cfg0 & 1);
184
- t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
71
break;
185
- t = FIELD_DP32(t, ID_ISAR6, SB, 1);
72
case A_CFG1:
186
- t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
73
s->cfg1 = value;
187
- t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
74
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_reset(DeviceState *dev)
188
- t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
75
int i;
189
+ t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1); /* FEAT_JSCVT */
76
190
+ t = FIELD_DP32(t, ID_ISAR6, DP, 1); /* Feat_DotProd */
77
trace_mps2_scc_reset();
191
+ t = FIELD_DP32(t, ID_ISAR6, FHM, 1); /* FEAT_FHM */
78
- s->cfg0 = 0;
192
+ t = FIELD_DP32(t, ID_ISAR6, SB, 1); /* FEAT_SB */
79
+ s->cfg0 = s->cfg0_reset;
193
+ t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1); /* FEAT_SPECRES */
80
s->cfg1 = 0;
194
+ t = FIELD_DP32(t, ID_ISAR6, BF16, 1); /* FEAT_AA32BF16 */
81
s->cfg2 = 0;
195
+ t = FIELD_DP32(t, ID_ISAR6, I8MM, 1); /* FEAT_AA32I8MM */
82
s->cfg5 = 0;
196
cpu->isar.id_isar6 = t;
83
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_init(Object *obj)
197
84
198
t = cpu->isar.mvfr1;
85
memory_region_init_io(&s->iomem, obj, &mps2_scc_ops, s, "mps2-scc", 0x1000);
199
- t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */
86
sysbus_init_mmio(sbd, &s->iomem);
200
- t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
87
+ qdev_init_gpio_out_named(DEVICE(obj), &s->remap, "remap", 1);
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;
88
}
242
}
89
243
90
static void mps2_scc_realize(DeviceState *dev, Error **errp)
91
@@ -XXX,XX +XXX,XX @@ static Property mps2_scc_properties[] = {
92
DEFINE_PROP_UINT32("scc-cfg4", MPS2SCC, cfg4, 0),
93
DEFINE_PROP_UINT32("scc-aid", MPS2SCC, aid, 0),
94
DEFINE_PROP_UINT32("scc-id", MPS2SCC, id, 0),
95
+ /* Reset value for CFG0 register */
96
+ DEFINE_PROP_UINT32("scc-cfg0", MPS2SCC, cfg0_reset, 0),
97
/*
98
* These are the initial settings for the source clocks on the board.
99
* In hardware they can be configured via a config file read by the
100
--
244
--
101
2.20.1
245
2.25.1
102
103
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Use FIELD_DP{32,64} to manipulate id_pfr1 and id_aa64pfr0
4
during arm_cpu_realizefn.
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-11-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/cpu.c | 22 +++++++++++++---------
12
1 file changed, 13 insertions(+), 9 deletions(-)
13
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.c
17
+++ b/target/arm/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
19
*/
20
unset_feature(env, ARM_FEATURE_EL3);
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].
24
+ /*
25
+ * Disable the security extension feature bits in the processor
26
+ * feature registers as well.
27
*/
28
- cpu->isar.id_pfr1 &= ~0xf0;
29
- cpu->isar.id_aa64pfr0 &= ~0xf000;
30
+ cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1, ID_PFR1, SECURITY, 0);
31
+ cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
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
56
--
57
2.25.1
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
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
These three features are already enabled by TCG, but are missing
3
This extension concerns changes to the External Debug interface,
4
their hwcap bits. Update HWCAP2 from linux v5.12.
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.
5
7
6
Cc: qemu-stable@nongnu.org (for 6.0.1)
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Buglink: https://bugs.launchpad.net/bugs/1926044
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210427214108.88503-1-richard.henderson@linaro.org
10
Message-id: 20220506180242.216785-13-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
linux-user/elfload.c | 13 +++++++++++++
13
docs/system/arm/emulation.rst | 1 +
13
1 file changed, 13 insertions(+)
14
target/arm/cpu64.c | 2 +-
15
target/arm/cpu_tcg.c | 4 ++--
16
3 files changed, 4 insertions(+), 3 deletions(-)
14
17
15
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
18
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/elfload.c
20
--- a/docs/system/arm/emulation.rst
18
+++ b/linux-user/elfload.c
21
+++ b/docs/system/arm/emulation.rst
19
@@ -XXX,XX +XXX,XX @@ enum {
22
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
20
ARM_HWCAP2_A64_SVESM4 = 1 << 6,
23
- FEAT_DIT (Data Independent Timing instructions)
21
ARM_HWCAP2_A64_FLAGM2 = 1 << 7,
24
- FEAT_DPB (DC CVAP instruction)
22
ARM_HWCAP2_A64_FRINT = 1 << 8,
25
- FEAT_Debugv8p2 (Debug changes for v8.2)
23
+ ARM_HWCAP2_A64_SVEI8MM = 1 << 9,
26
+- FEAT_Debugv8p4 (Debug changes for v8.4)
24
+ ARM_HWCAP2_A64_SVEF32MM = 1 << 10,
27
- FEAT_DotProd (Advanced SIMD dot product instructions)
25
+ ARM_HWCAP2_A64_SVEF64MM = 1 << 11,
28
- FEAT_FCMA (Floating-point complex number instructions)
26
+ ARM_HWCAP2_A64_SVEBF16 = 1 << 12,
29
- FEAT_FHM (Floating-point half-precision multiplication instructions)
27
+ ARM_HWCAP2_A64_I8MM = 1 << 13,
30
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
28
+ ARM_HWCAP2_A64_BF16 = 1 << 14,
31
index XXXXXXX..XXXXXXX 100644
29
+ ARM_HWCAP2_A64_DGH = 1 << 15,
32
--- a/target/arm/cpu64.c
30
+ ARM_HWCAP2_A64_RNG = 1 << 16,
33
+++ b/target/arm/cpu64.c
31
+ ARM_HWCAP2_A64_BTI = 1 << 17,
34
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
32
+ ARM_HWCAP2_A64_MTE = 1 << 18,
35
cpu->isar.id_aa64zfr0 = t;
33
};
36
34
37
t = cpu->isar.id_aa64dfr0;
35
#define ELF_HWCAP get_elf_hwcap()
38
- t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 8); /* FEAT_Debugv8p2 */
36
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap2(void)
39
+ t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 9); /* FEAT_Debugv8p4 */
37
GET_FEATURE_ID(aa64_dcpodp, ARM_HWCAP2_A64_DCPODP);
40
t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* FEAT_PMUv3p4 */
38
GET_FEATURE_ID(aa64_condm_5, ARM_HWCAP2_A64_FLAGM2);
41
cpu->isar.id_aa64dfr0 = t;
39
GET_FEATURE_ID(aa64_frint, ARM_HWCAP2_A64_FRINT);
42
40
+ GET_FEATURE_ID(aa64_rndr, ARM_HWCAP2_A64_RNG);
43
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
41
+ GET_FEATURE_ID(aa64_bti, ARM_HWCAP2_A64_BTI);
44
index XXXXXXX..XXXXXXX 100644
42
+ GET_FEATURE_ID(aa64_mte, ARM_HWCAP2_A64_MTE);
45
--- a/target/arm/cpu_tcg.c
43
46
+++ b/target/arm/cpu_tcg.c
44
return hwcaps;
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;
45
}
57
}
46
--
58
--
47
2.20.1
59
2.25.1
48
49
diff view generated by jsdifflib
1
Some of the constant expanders defined in translate.c are generically
1
From: Richard Henderson <richard.henderson@linaro.org>
2
useful and will be used by the separate C files for VFP and Neon once
3
they are created; move the expander definitions to translate.h.
4
2
3
Add only the system registers required to implement zero error
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.
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20220506180242.216785-14-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210430132740.10391-2-peter.maydell@linaro.org
9
---
14
---
10
target/arm/translate.h | 24 ++++++++++++++++++++++++
15
target/arm/cpu.h | 5 +++
11
target/arm/translate.c | 24 ------------------------
16
target/arm/helper.c | 84 +++++++++++++++++++++++++++++++++++++++++++++
12
2 files changed, 24 insertions(+), 24 deletions(-)
17
2 files changed, 89 insertions(+)
13
18
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.h
21
--- a/target/arm/cpu.h
17
+++ b/target/arm/translate.h
22
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ extern TCGv_i32 cpu_NF, cpu_ZF, cpu_CF, cpu_VF;
23
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
19
extern TCGv_i64 cpu_exclusive_addr;
24
uint64_t tfsr_el[4]; /* tfsre0_el1 is index 0. */
20
extern TCGv_i64 cpu_exclusive_val;
25
uint64_t gcr_el1;
26
uint64_t rgsr_el1;
27
+
28
+ /* Minimal RAS registers */
29
+ uint64_t disr_el1;
30
+ uint64_t vdisr_el2;
31
+ uint64_t vsesr_el2;
32
} cp15;
33
34
struct {
35
diff --git a/target/arm/helper.c b/target/arm/helper.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper.c
38
+++ b/target/arm/helper.c
39
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
40
.access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
41
};
21
42
22
+/*
43
+/*
23
+ * Constant expanders for the decoders.
44
+ * Check for traps to RAS registers, which are controlled
45
+ * by HCR_EL2.TERR and SCR_EL3.TERR.
24
+ */
46
+ */
47
+static CPAccessResult access_terr(CPUARMState *env, const ARMCPRegInfo *ri,
48
+ bool isread)
49
+{
50
+ int el = arm_current_el(env);
25
+
51
+
26
+static inline int negate(DisasContext *s, int x)
52
+ if (el < 2 && (arm_hcr_el2_eff(env) & HCR_TERR)) {
27
+{
53
+ return CP_ACCESS_TRAP_EL2;
28
+ return -x;
54
+ }
55
+ if (el < 3 && (env->cp15.scr_el3 & SCR_TERR)) {
56
+ return CP_ACCESS_TRAP_EL3;
57
+ }
58
+ return CP_ACCESS_OK;
29
+}
59
+}
30
+
60
+
31
+static inline int plus_2(DisasContext *s, int x)
61
+static uint64_t disr_read(CPUARMState *env, const ARMCPRegInfo *ri)
32
+{
62
+{
33
+ return x + 2;
63
+ int el = arm_current_el(env);
64
+
65
+ if (el < 2 && (arm_hcr_el2_eff(env) & HCR_AMO)) {
66
+ return env->cp15.vdisr_el2;
67
+ }
68
+ if (el < 3 && (env->cp15.scr_el3 & SCR_EA)) {
69
+ return 0; /* RAZ/WI */
70
+ }
71
+ return env->cp15.disr_el1;
34
+}
72
+}
35
+
73
+
36
+static inline int times_2(DisasContext *s, int x)
74
+static void disr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t val)
37
+{
75
+{
38
+ return x * 2;
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;
39
+}
86
+}
40
+
87
+
41
+static inline int times_4(DisasContext *s, int x)
88
+/*
42
+{
89
+ * Minimal RAS implementation with no Error Records.
43
+ return x * 4;
90
+ * Which means that all of the Error Record registers:
44
+}
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
+};
45
+
123
+
46
static inline int arm_dc_feature(DisasContext *dc, int feature)
124
/* Return the exception level to which exceptions should be taken
47
{
125
* via SVEAccessTrap. If an exception should be routed through
48
return (dc->features & (1ULL << feature)) != 0;
126
* AArch64.AdvSIMDFPAccessTrap, return 0; fp_exception_el should
49
diff --git a/target/arm/translate.c b/target/arm/translate.c
127
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
50
index XXXXXXX..XXXXXXX 100644
128
if (cpu_isar_feature(aa64_ssbs, cpu)) {
51
--- a/target/arm/translate.c
129
define_one_arm_cp_reg(cpu, &ssbs_reginfo);
52
+++ b/target/arm/translate.c
53
@@ -XXX,XX +XXX,XX @@ static void arm_gen_condlabel(DisasContext *s)
54
}
130
}
55
}
131
+ if (cpu_isar_feature(any_ras, cpu)) {
56
132
+ define_arm_cp_regs(cpu, minimal_ras_reginfo);
57
-/*
133
+ }
58
- * Constant expanders for the decoders.
134
59
- */
135
if (cpu_isar_feature(aa64_vh, cpu) ||
60
-
136
cpu_isar_feature(aa64_debugv8p2, cpu)) {
61
-static int negate(DisasContext *s, int x)
62
-{
63
- return -x;
64
-}
65
-
66
-static int plus_2(DisasContext *s, int x)
67
-{
68
- return x + 2;
69
-}
70
-
71
-static int times_2(DisasContext *s, int x)
72
-{
73
- return x * 2;
74
-}
75
-
76
-static int times_4(DisasContext *s, int x)
77
-{
78
- return x * 4;
79
-}
80
-
81
/* Flags for the disas_set_da_iss info argument:
82
* lower bits hold the Rt register number, higher bits are flags.
83
*/
84
--
137
--
85
2.20.1
138
2.25.1
86
87
diff view generated by jsdifflib
1
In tlbi_aa64_vae2is_write() the calculation
1
From: Richard Henderson <richard.henderson@linaro.org>
2
bits = tlbbits_for_regime(env, secure ? ARMMMUIdx_E2 : ARMMMUIdx_SE2,
3
pageaddr)
4
2
5
has the two arms of the ?: expression reversed. Fix the bug.
3
Enable writes to the TERR and TEA bits when RAS is enabled.
4
These bits are otherwise RES0.
6
5
7
Fixes: b6ad6062f1e5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reported-by: Rebecca Cran <rebecca@nuviainc.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220506180242.216785-15-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
12
Reviewed-by: Rebecca Cran <rebecca@nuviainc.com>
13
Message-id: 20210420123106.10861-1-peter.maydell@linaro.org
14
---
10
---
15
target/arm/helper.c | 2 +-
11
target/arm/helper.c | 9 +++++++++
16
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 9 insertions(+)
17
13
18
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
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.c
16
--- a/target/arm/helper.c
21
+++ b/target/arm/helper.c
17
+++ b/target/arm/helper.c
22
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
18
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
23
uint64_t pageaddr = sextract64(value << 12, 0, 56);
19
}
24
bool secure = arm_is_secure_below_el3(env);
20
valid_mask &= ~SCR_NET;
25
int mask = secure ? ARMMMUIdxBit_SE2 : ARMMMUIdxBit_E2;
21
26
- int bits = tlbbits_for_regime(env, secure ? ARMMMUIdx_E2 : ARMMMUIdx_SE2,
22
+ if (cpu_isar_feature(aa64_ras, cpu)) {
27
+ int bits = tlbbits_for_regime(env, secure ? ARMMMUIdx_SE2 : ARMMMUIdx_E2,
23
+ valid_mask |= SCR_TERR;
28
pageaddr);
24
+ }
29
25
if (cpu_isar_feature(aa64_lor, cpu)) {
30
tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
26
valid_mask |= SCR_TLOR;
27
}
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
+ }
35
}
36
37
if (!arm_feature(env, ARM_FEATURE_EL2)) {
38
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
39
if (cpu_isar_feature(aa64_vh, cpu)) {
40
valid_mask |= HCR_E2H;
41
}
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
}
31
--
48
--
32
2.20.1
49
2.25.1
33
34
diff view generated by jsdifflib
1
The AN524 FPGA image supports two memory maps, which differ in where
1
From: Richard Henderson <richard.henderson@linaro.org>
2
the QSPI and BRAM are. In the default map, the BRAM is at
3
0x0000_0000, and the QSPI at 0x2800_0000. In the second map, they
4
are the other way around.
5
2
6
In hardware, the initial mapping can be selected by the user by
3
Virtual SError exceptions are raised by setting HCR_EL2.VSE,
7
writing either "REMAP: BRAM" (the default) or "REMAP: QSPI" in the
4
and are routed to EL1 just like other virtual exceptions.
8
board configuration file. The board config file is acted on by the
9
"Motherboard Configuration Controller", which is an entirely separate
10
microcontroller on the dev board but outside the FPGA.
11
5
12
The guest can also dynamically change the mapping via the SCC
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
CFG_REG0 register.
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220506180242.216785-16-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/cpu.h | 2 ++
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(-)
14
17
15
Implement this functionality for QEMU, using a machine property
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
"remap" with valid values "BRAM" and "QSPI" to allow the user to set
19
index XXXXXXX..XXXXXXX 100644
17
the initial mapping, in the same way they can on the FPGA, and
20
--- a/target/arm/cpu.h
18
wiring up the bit from the SCC register to also switch the mapping.
21
+++ b/target/arm/cpu.h
19
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
23
Message-id: 20210504120912.23094-4-peter.maydell@linaro.org
24
---
25
docs/system/arm/mps2.rst | 10 ++++
26
hw/arm/mps2-tz.c | 108 ++++++++++++++++++++++++++++++++++++++-
27
2 files changed, 117 insertions(+), 1 deletion(-)
28
29
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
30
index XXXXXXX..XXXXXXX 100644
31
--- a/docs/system/arm/mps2.rst
32
+++ b/docs/system/arm/mps2.rst
33
@@ -XXX,XX +XXX,XX @@ Differences between QEMU and real hardware:
34
flash, but only as simple ROM, so attempting to rewrite the flash
35
from the guest will fail
36
- QEMU does not model the USB controller in MPS3 boards
37
+
38
+Machine-specific options
39
+""""""""""""""""""""""""
40
+
41
+The following machine-specific options are supported:
42
+
43
+remap
44
+ Supported for ``mps3-an524`` only.
45
+ Set ``BRAM``/``QSPI`` to select the initial memory mapping. The
46
+ default is ``BRAM``.
47
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/mps2-tz.c
50
+++ b/hw/arm/mps2-tz.c
51
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@
52
#include "hw/boards.h"
23
#define EXCP_LSERR 21 /* v8M LSERR SecureFault */
53
#include "exec/address-spaces.h"
24
#define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */
54
#include "sysemu/sysemu.h"
25
#define EXCP_DIVBYZERO 23 /* v7M DIVBYZERO UsageFault */
55
+#include "sysemu/reset.h"
26
+#define EXCP_VSERR 24
56
#include "hw/misc/unimp.h"
27
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
57
#include "hw/char/cmsdk-apb-uart.h"
28
58
#include "hw/timer/cmsdk-apb-timer.h"
29
#define ARMV7M_EXCP_RESET 1
59
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@ enum {
60
#include "hw/core/split-irq.h"
31
#define CPU_INTERRUPT_FIQ CPU_INTERRUPT_TGT_EXT_1
61
#include "hw/qdev-clock.h"
32
#define CPU_INTERRUPT_VIRQ CPU_INTERRUPT_TGT_EXT_2
62
#include "qom/object.h"
33
#define CPU_INTERRUPT_VFIQ CPU_INTERRUPT_TGT_EXT_3
63
+#include "hw/irq.h"
34
+#define CPU_INTERRUPT_VSERR CPU_INTERRUPT_TGT_INT_0
64
35
65
#define MPS2TZ_NUMIRQ_MAX 96
36
/* The usual mapping for an AArch64 system register to its AArch32
66
#define MPS2TZ_RAM_MAX 5
37
* counterpart is for the 32 bit world to have access to the lower
67
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
38
diff --git a/target/arm/internals.h b/target/arm/internals.h
68
SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ_MAX];
39
index XXXXXXX..XXXXXXX 100644
69
Clock *sysclk;
40
--- a/target/arm/internals.h
70
Clock *s32kclk;
41
+++ b/target/arm/internals.h
71
+
42
@@ -XXX,XX +XXX,XX @@ void arm_cpu_update_virq(ARMCPU *cpu);
72
+ bool remap;
43
*/
73
+ qemu_irq remap_irq;
44
void arm_cpu_update_vfiq(ARMCPU *cpu);
74
};
45
75
46
+/**
76
#define TYPE_MPS2TZ_MACHINE "mps2tz"
47
+ * arm_cpu_update_vserr: Update CPU_INTERRUPT_VSERR bit
77
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an505_raminfo[] = { {
48
+ *
78
},
49
+ * Update the CPU_INTERRUPT_VSERR bit in cs->interrupt_request,
79
};
50
+ * following a change to the HCR_EL2.VSE bit.
80
81
+/*
82
+ * Note that the addresses and MPC numbering here should match up
83
+ * with those used in remap_memory(), which can swap the BRAM and QSPI.
84
+ */
51
+ */
85
static const RAMInfo an524_raminfo[] = { {
52
+void arm_cpu_update_vserr(ARMCPU *cpu);
86
.name = "bram",
53
+
87
.base = 0x00000000,
54
/**
88
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
55
* arm_mmu_idx_el:
89
56
* @env: The cpu environment
90
object_initialize_child(OBJECT(mms), "scc", scc, TYPE_MPS2_SCC);
57
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
91
sccdev = DEVICE(scc);
58
index XXXXXXX..XXXXXXX 100644
92
+ qdev_prop_set_uint32(sccdev, "scc-cfg0", mms->remap ? 1 : 0);
59
--- a/target/arm/syndrome.h
93
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
60
+++ b/target/arm/syndrome.h
94
qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
61
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_pcalignment(void)
95
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
62
return (EC_PCALIGNMENT << ARM_EL_EC_SHIFT) | ARM_EL_IL;
96
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
63
}
97
return sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 0);
64
98
}
65
+static inline uint32_t syn_serror(uint32_t extra)
99
66
+{
100
+static hwaddr boot_mem_base(MPS2TZMachineState *mms)
67
+ return (EC_SERROR << ARM_EL_EC_SHIFT) | ARM_EL_IL | extra;
68
+}
69
+
70
#endif /* TARGET_ARM_SYNDROME_H */
71
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
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)
101
+{
120
+{
102
+ /*
121
+ /*
103
+ * Return the canonical address of the block which will be mapped
122
+ * Update the interrupt level for VSERR, which is the HCR_EL2.VSE bit.
104
+ * at address 0x0 (i.e. where the vector table is).
105
+ * This is usually 0, but if the AN524 alternate memory map is
106
+ * enabled it will be the base address of the QSPI block.
107
+ */
123
+ */
108
+ return mms->remap ? 0x28000000 : 0;
124
+ CPUARMState *env = &cpu->env;
109
+}
125
+ CPUState *cs = CPU(cpu);
110
+
126
+
111
+static void remap_memory(MPS2TZMachineState *mms, int map)
127
+ bool new_state = env->cp15.hcr_el2 & HCR_VSE;
112
+{
128
+
113
+ /*
129
+ if (new_state != ((cs->interrupt_request & CPU_INTERRUPT_VSERR) != 0)) {
114
+ * Remap the memory for the AN524. 'map' is the value of
130
+ if (new_state) {
115
+ * SCC CFG_REG0 bit 0, i.e. 0 for the default map and 1
131
+ cpu_interrupt(cs, CPU_INTERRUPT_VSERR);
116
+ * for the "option 1" mapping where QSPI is at address 0.
132
+ } else {
117
+ *
133
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_VSERR);
118
+ * Effectively we need to swap around the "upstream" ends of
134
+ }
119
+ * MPC 0 and MPC 1.
120
+ */
121
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
122
+ int i;
123
+
124
+ if (mmc->fpga_type != FPGA_AN524) {
125
+ return;
126
+ }
127
+
128
+ memory_region_transaction_begin();
129
+ for (i = 0; i < 2; i++) {
130
+ TZMPC *mpc = &mms->mpc[i];
131
+ MemoryRegion *upstream = sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 1);
132
+ hwaddr addr = (i ^ map) ? 0x28000000 : 0;
133
+
134
+ memory_region_set_address(upstream, addr);
135
+ }
136
+ memory_region_transaction_commit();
137
+}
138
+
139
+static void remap_irq_fn(void *opaque, int n, int level)
140
+{
141
+ MPS2TZMachineState *mms = opaque;
142
+
143
+ remap_memory(mms, level);
144
+}
145
+
146
static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
147
const char *name, hwaddr size,
148
const int *irqs)
149
@@ -XXX,XX +XXX,XX @@ static uint32_t boot_ram_size(MPS2TZMachineState *mms)
150
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
151
152
for (p = mmc->raminfo; p->name; p++) {
153
- if (p->base == 0) {
154
+ if (p->base == boot_mem_base(mms)) {
155
return p->size;
156
}
157
}
158
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
159
160
create_non_mpc_ram(mms);
161
162
+ if (mmc->fpga_type == FPGA_AN524) {
163
+ /*
164
+ * Connect the line from the SCC so that we can remap when the
165
+ * guest updates that register.
166
+ */
167
+ mms->remap_irq = qemu_allocate_irq(remap_irq_fn, mms, 0);
168
+ qdev_connect_gpio_out_named(DEVICE(&mms->scc), "remap", 0,
169
+ mms->remap_irq);
170
+ }
171
+
172
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
173
boot_ram_size(mms));
174
}
175
@@ -XXX,XX +XXX,XX @@ static void mps2_tz_idau_check(IDAUInterface *ii, uint32_t address,
176
*iregion = region;
177
}
178
179
+static char *mps2_get_remap(Object *obj, Error **errp)
180
+{
181
+ MPS2TZMachineState *mms = MPS2TZ_MACHINE(obj);
182
+ const char *val = mms->remap ? "QSPI" : "BRAM";
183
+ return g_strdup(val);
184
+}
185
+
186
+static void mps2_set_remap(Object *obj, const char *value, Error **errp)
187
+{
188
+ MPS2TZMachineState *mms = MPS2TZ_MACHINE(obj);
189
+
190
+ if (!strcmp(value, "BRAM")) {
191
+ mms->remap = false;
192
+ } else if (!strcmp(value, "QSPI")) {
193
+ mms->remap = true;
194
+ } else {
195
+ error_setg(errp, "Invalid remap value");
196
+ error_append_hint(errp, "Valid values are BRAM and QSPI.\n");
197
+ }
135
+ }
198
+}
136
+}
199
+
137
+
200
+static void mps2_machine_reset(MachineState *machine)
138
#ifndef CONFIG_USER_ONLY
201
+{
139
static void arm_cpu_set_irq(void *opaque, int irq, int level)
202
+ MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
203
+
204
+ /*
205
+ * Set the initial memory mapping before triggering the reset of
206
+ * the rest of the system, so that the guest image loader and CPU
207
+ * reset see the correct mapping.
208
+ */
209
+ remap_memory(mms, mms->remap);
210
+ qemu_devices_reset();
211
+}
212
+
213
static void mps2tz_class_init(ObjectClass *oc, void *data)
214
{
140
{
215
MachineClass *mc = MACHINE_CLASS(oc);
141
diff --git a/target/arm/helper.c b/target/arm/helper.c
216
IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(oc);
142
index XXXXXXX..XXXXXXX 100644
217
143
--- a/target/arm/helper.c
218
mc->init = mps2tz_common_init;
144
+++ b/target/arm/helper.c
219
+ mc->reset = mps2_machine_reset;
145
@@ -XXX,XX +XXX,XX @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
220
iic->check = mps2_tz_idau_check;
146
}
221
}
147
}
222
148
223
@@ -XXX,XX +XXX,XX @@ static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
149
- /* External aborts are not possible in QEMU so A bit is always clear */
224
mmc->raminfo = an524_raminfo;
150
+ if (hcr_el2 & HCR_AMO) {
225
mmc->armsse_type = TYPE_SSE200;
151
+ if (cs->interrupt_request & CPU_INTERRUPT_VSERR) {
226
mps2tz_set_default_ram_info(mmc);
152
+ ret |= CPSR_A;
227
+
153
+ }
228
+ object_class_property_add_str(oc, "remap", mps2_get_remap, mps2_set_remap);
154
+ }
229
+ object_class_property_set_description(oc, "remap",
155
+
230
+ "Set memory mapping. Valid values "
156
return ret;
231
+ "are BRAM (default) and QSPI.");
157
}
232
}
158
233
159
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
234
static void mps3tz_an547_class_init(ObjectClass *oc, void *data)
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
}
235
--
220
--
236
2.20.1
221
2.25.1
237
238
diff view generated by jsdifflib
1
The unallocated_encoding() function is the same in both
1
From: Richard Henderson <richard.henderson@linaro.org>
2
translate-a64.c and translate.c; make the translate.c function global
3
and drop the translate-a64.c version. To do this we need to also
4
share gen_exception_insn(), which currently exists in two slightly
5
different versions for A32 and A64: merge those into a single
6
function that can work for both.
7
2
8
This will be useful for splitting up translate.c, which will require
3
Check for and defer any pending virtual SError.
9
unallocated_encoding() to no longer be file-local. It's also
10
hopefully less confusing to have only one version of the function
11
rather than two.
12
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-17-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20210430132740.10391-3-peter.maydell@linaro.org
16
---
9
---
17
target/arm/translate-a64.h | 2 --
10
target/arm/helper.h | 1 +
18
target/arm/translate.h | 3 +++
11
target/arm/a32.decode | 16 ++++++++------
19
target/arm/translate-a64.c | 15 ---------------
12
target/arm/t32.decode | 18 ++++++++--------
20
target/arm/translate.c | 14 +++++++++-----
13
target/arm/op_helper.c | 43 ++++++++++++++++++++++++++++++++++++++
21
4 files changed, 12 insertions(+), 22 deletions(-)
14
target/arm/translate-a64.c | 17 +++++++++++++++
15
target/arm/translate.c | 23 ++++++++++++++++++++
16
6 files changed, 103 insertions(+), 15 deletions(-)
22
17
23
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
18
diff --git a/target/arm/helper.h b/target/arm/helper.h
24
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/translate-a64.h
20
--- a/target/arm/helper.h
26
+++ b/target/arm/translate-a64.h
21
+++ b/target/arm/helper.h
27
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(wfe, void, env)
28
#ifndef TARGET_ARM_TRANSLATE_A64_H
23
DEF_HELPER_1(yield, void, env)
29
#define TARGET_ARM_TRANSLATE_A64_H
24
DEF_HELPER_1(pre_hvc, void, env)
30
25
DEF_HELPER_2(pre_smc, void, env, i32)
31
-void unallocated_encoding(DisasContext *s);
26
+DEF_HELPER_1(vesb, void, env)
32
-
27
33
#define unsupported_encoding(s, insn) \
28
DEF_HELPER_3(cpsr_write, void, env, i32, i32)
34
do { \
29
DEF_HELPER_2(cpsr_write_eret, void, env, i32)
35
qemu_log_mask(LOG_UNIMP, \
30
diff --git a/target/arm/a32.decode b/target/arm/a32.decode
36
diff --git a/target/arm/translate.h b/target/arm/translate.h
31
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/a32.decode
38
--- a/target/arm/translate.h
33
+++ b/target/arm/a32.decode
39
+++ b/target/arm/translate.h
34
@@ -XXX,XX +XXX,XX @@ SMULTT .... 0001 0110 .... 0000 .... 1110 .... @rd0mn
40
@@ -XXX,XX +XXX,XX @@ void arm_free_cc(DisasCompare *cmp);
35
41
void arm_jump_cc(DisasCompare *cmp, TCGLabel *label);
36
{
42
void arm_gen_test_cc(int cc, TCGLabel *label);
37
{
43
MemOp pow2_align(unsigned i);
38
- YIELD ---- 0011 0010 0000 1111 ---- 0000 0001
44
+void unallocated_encoding(DisasContext *s);
39
- WFE ---- 0011 0010 0000 1111 ---- 0000 0010
45
+void gen_exception_insn(DisasContext *s, uint64_t pc, int excp,
40
- WFI ---- 0011 0010 0000 1111 ---- 0000 0011
46
+ uint32_t syn, uint32_t target_el);
41
+ [
47
42
+ YIELD ---- 0011 0010 0000 1111 ---- 0000 0001
48
/* Return state of Alternate Half-precision flag, caller frees result */
43
+ WFE ---- 0011 0010 0000 1111 ---- 0000 0010
49
static inline TCGv_i32 get_ahp_flag(void)
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
+}
50
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
51
index XXXXXXX..XXXXXXX 100644
141
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/translate-a64.c
142
--- a/target/arm/translate-a64.c
53
+++ b/target/arm/translate-a64.c
143
+++ b/target/arm/translate-a64.c
54
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal_insn(DisasContext *s, uint64_t pc, int excp)
144
@@ -XXX,XX +XXX,XX @@ static void handle_hint(DisasContext *s, uint32_t insn,
55
s->base.is_jmp = DISAS_NORETURN;
145
gen_helper_autib(cpu_X[17], cpu_env, cpu_X[17], cpu_X[16]);
56
}
146
}
57
147
break;
58
-static void gen_exception_insn(DisasContext *s, uint64_t pc, int excp,
148
+ case 0b10000: /* ESB */
59
- uint32_t syndrome, uint32_t target_el)
149
+ /* Without RAS, we must implement this as NOP. */
60
-{
150
+ if (dc_isar_feature(aa64_ras, s)) {
61
- gen_a64_set_pc_im(pc);
151
+ /*
62
- gen_exception(excp, syndrome, target_el);
152
+ * QEMU does not have a source of physical SErrors,
63
- s->base.is_jmp = DISAS_NORETURN;
153
+ * so we are only concerned with virtual SErrors.
64
-}
154
+ * The pseudocode in the ARM for this case is
65
-
155
+ * if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then
66
static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syndrome)
156
+ * AArch64.vESBOperation();
67
{
157
+ * Most of the condition can be evaluated at translation time.
68
TCGv_i32 tcg_syn;
158
+ * Test for EL2 present, and defer test for SEL2 to runtime.
69
@@ -XXX,XX +XXX,XX @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
159
+ */
70
}
160
+ if (s->current_el <= 1 && arm_dc_feature(s, ARM_FEATURE_EL2)) {
71
}
161
+ gen_helper_vesb(cpu_env);
72
162
+ }
73
-void unallocated_encoding(DisasContext *s)
163
+ }
74
-{
164
+ break;
75
- /* Unallocated and reserved encodings are uncategorized */
165
case 0b11000: /* PACIAZ */
76
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
166
if (s->pauth_active) {
77
- default_exception_el(s));
167
gen_helper_pacia(cpu_X[30], cpu_env, cpu_X[30],
78
-}
79
-
80
static void init_tmp_a64_array(DisasContext *s)
81
{
82
#ifdef CONFIG_DEBUG_TCG
83
diff --git a/target/arm/translate.c b/target/arm/translate.c
168
diff --git a/target/arm/translate.c b/target/arm/translate.c
84
index XXXXXXX..XXXXXXX 100644
169
index XXXXXXX..XXXXXXX 100644
85
--- a/target/arm/translate.c
170
--- a/target/arm/translate.c
86
+++ b/target/arm/translate.c
171
+++ b/target/arm/translate.c
87
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal_insn(DisasContext *s, uint32_t pc, int excp)
172
@@ -XXX,XX +XXX,XX @@ static bool trans_WFI(DisasContext *s, arg_WFI *a)
88
s->base.is_jmp = DISAS_NORETURN;
173
return true;
89
}
174
}
90
175
91
-static void gen_exception_insn(DisasContext *s, uint32_t pc, int excp,
176
+static bool trans_ESB(DisasContext *s, arg_ESB *a)
92
- int syn, uint32_t target_el)
177
+{
93
+void gen_exception_insn(DisasContext *s, uint64_t pc, int excp,
178
+ /*
94
+ uint32_t syn, uint32_t target_el)
179
+ * For M-profile, minimal-RAS ESB can be a NOP.
180
+ * Without RAS, we must implement this as NOP.
181
+ */
182
+ if (!arm_dc_feature(s, ARM_FEATURE_M) && dc_isar_feature(aa32_ras, s)) {
183
+ /*
184
+ * QEMU does not have a source of physical SErrors,
185
+ * so we are only concerned with virtual SErrors.
186
+ * The pseudocode in the ARM for this case is
187
+ * if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then
188
+ * AArch32.vESBOperation();
189
+ * Most of the condition can be evaluated at translation time.
190
+ * Test for EL2 present, and defer test for SEL2 to runtime.
191
+ */
192
+ if (s->current_el <= 1 && arm_dc_feature(s, ARM_FEATURE_EL2)) {
193
+ gen_helper_vesb(cpu_env);
194
+ }
195
+ }
196
+ return true;
197
+}
198
+
199
static bool trans_NOP(DisasContext *s, arg_NOP *a)
95
{
200
{
96
- gen_set_condexec(s);
201
return true;
97
- gen_set_pc_im(s, pc);
98
+ if (s->aarch64) {
99
+ gen_a64_set_pc_im(pc);
100
+ } else {
101
+ gen_set_condexec(s);
102
+ gen_set_pc_im(s, pc);
103
+ }
104
gen_exception(excp, syn, target_el);
105
s->base.is_jmp = DISAS_NORETURN;
106
}
107
@@ -XXX,XX +XXX,XX @@ static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn)
108
s->base.is_jmp = DISAS_NORETURN;
109
}
110
111
-static void unallocated_encoding(DisasContext *s)
112
+void unallocated_encoding(DisasContext *s)
113
{
114
/* Unallocated and reserved encodings are uncategorized */
115
gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
116
--
202
--
117
2.20.1
203
2.25.1
118
119
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20220506180242.216785-18-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
docs/system/arm/emulation.rst | 1 +
9
target/arm/cpu64.c | 1 +
10
target/arm/cpu_tcg.c | 1 +
11
3 files changed, 3 insertions(+)
12
13
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
14
index XXXXXXX..XXXXXXX 100644
15
--- a/docs/system/arm/emulation.rst
16
+++ b/docs/system/arm/emulation.rst
17
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
18
- FEAT_PMULL (PMULL, PMULL2 instructions)
19
- FEAT_PMUv3p1 (PMU Extensions v3.1)
20
- FEAT_PMUv3p4 (PMU Extensions v3.4)
21
+- FEAT_RAS (Reliability, availability, and serviceability)
22
- FEAT_RDM (Advanced SIMD rounding double multiply accumulate instructions)
23
- FEAT_RNG (Random number generator)
24
- FEAT_SB (Speculation Barrier)
25
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/cpu64.c
28
+++ b/target/arm/cpu64.c
29
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
30
t = cpu->isar.id_aa64pfr0;
31
t = FIELD_DP64(t, ID_AA64PFR0, FP, 1); /* FEAT_FP16 */
32
t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1); /* FEAT_FP16 */
33
+ t = FIELD_DP64(t, ID_AA64PFR0, RAS, 1); /* FEAT_RAS */
34
t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
35
t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); /* FEAT_SEL2 */
36
t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
37
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/cpu_tcg.c
40
+++ b/target/arm/cpu_tcg.c
41
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
42
43
t = cpu->isar.id_pfr0;
44
t = FIELD_DP32(t, ID_PFR0, DIT, 1); /* FEAT_DIT */
45
+ t = FIELD_DP32(t, ID_PFR0, RAS, 1); /* FEAT_RAS */
46
cpu->isar.id_pfr0 = t;
47
48
t = cpu->isar.id_pfr2;
49
--
50
2.25.1
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
1
Make dis-asm.h handle being included outside an 'extern "C"' block;
1
From: Richard Henderson <richard.henderson@linaro.org>
2
this allows us to remove the 'extern "C"' blocks that our two C++
3
files that include it are using.
4
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
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
---
10
---
8
include/disas/dis-asm.h | 12 ++++++++++--
11
docs/system/arm/emulation.rst | 1 +
9
disas/arm-a64.cc | 2 --
12
target/arm/cpu64.c | 1 +
10
disas/nanomips.cpp | 2 --
13
target/arm/cpu_tcg.c | 1 +
11
3 files changed, 10 insertions(+), 6 deletions(-)
14
3 files changed, 3 insertions(+)
12
15
13
diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
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/include/disas/dis-asm.h
18
--- a/docs/system/arm/emulation.rst
16
+++ b/include/disas/dis-asm.h
19
+++ b/docs/system/arm/emulation.rst
17
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
18
#ifndef DISAS_DIS_ASM_H
21
- FEAT_BBM at level 2 (Translation table break-before-make levels)
19
#define DISAS_DIS_ASM_H
22
- FEAT_BF16 (AArch64 BFloat16 instructions)
20
23
- FEAT_BTI (Branch Target Identification)
21
+#include "qemu/bswap.h"
24
+- FEAT_CSV2 (Cache speculation variant 2)
22
+
25
- FEAT_DIT (Data Independent Timing instructions)
23
+#ifdef __cplusplus
26
- FEAT_DPB (DC CVAP instruction)
24
+extern "C" {
27
- FEAT_Debugv8p2 (Debug changes for v8.2)
25
+#endif
28
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
26
+
27
typedef void *PTR;
28
typedef uint64_t bfd_vma;
29
typedef int64_t bfd_signed_vma;
30
@@ -XXX,XX +XXX,XX @@ bool cap_disas_plugin(disassemble_info *info, uint64_t pc, size_t size);
31
32
/* from libbfd */
33
34
-#include "qemu/bswap.h"
35
-
36
static inline bfd_vma bfd_getl64(const bfd_byte *addr)
37
{
38
return ldq_le_p(addr);
39
@@ -XXX,XX +XXX,XX @@ static inline bfd_vma bfd_getb16(const bfd_byte *addr)
40
41
typedef bool bfd_boolean;
42
43
+#ifdef __cplusplus
44
+}
45
+#endif
46
+
47
#endif /* DISAS_DIS_ASM_H */
48
diff --git a/disas/arm-a64.cc b/disas/arm-a64.cc
49
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
50
--- a/disas/arm-a64.cc
30
--- a/target/arm/cpu64.c
51
+++ b/disas/arm-a64.cc
31
+++ b/target/arm/cpu64.c
52
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
53
*/
33
t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
54
34
t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); /* FEAT_SEL2 */
55
#include "qemu/osdep.h"
35
t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
56
-extern "C" {
36
+ t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 1); /* FEAT_CSV2 */
57
#include "disas/dis-asm.h"
37
cpu->isar.id_aa64pfr0 = t;
58
-}
38
59
39
t = cpu->isar.id_aa64pfr1;
60
#include "vixl/a64/disasm-a64.h"
40
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
61
62
diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
63
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
64
--- a/disas/nanomips.cpp
42
--- a/target/arm/cpu_tcg.c
65
+++ b/disas/nanomips.cpp
43
+++ b/target/arm/cpu_tcg.c
66
@@ -XXX,XX +XXX,XX @@
44
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
67
*/
45
cpu->isar.id_mmfr4 = t;
68
46
69
#include "qemu/osdep.h"
47
t = cpu->isar.id_pfr0;
70
-extern "C" {
48
+ t = FIELD_DP32(t, ID_PFR0, CSV2, 2); /* FEAT_CVS2 */
71
#include "disas/dis-asm.h"
49
t = FIELD_DP32(t, ID_PFR0, DIT, 1); /* FEAT_DIT */
72
-}
50
t = FIELD_DP32(t, ID_PFR0, RAS, 1); /* FEAT_RAS */
73
51
cpu->isar.id_pfr0 = t;
74
#include <cstring>
75
#include <stdexcept>
76
--
52
--
77
2.20.1
53
2.25.1
78
79
diff view generated by jsdifflib
1
Move the various gen_aa32* functions and macros out of translate.c
1
From: Richard Henderson <richard.henderson@linaro.org>
2
and into translate-a32.h.
3
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.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220506180242.216785-21-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-6-peter.maydell@linaro.org
8
---
11
---
9
target/arm/translate-a32.h | 53 ++++++++++++++++++++++++++++++++++++++
12
docs/system/arm/emulation.rst | 3 ++
10
target/arm/translate.c | 51 ++++++++++++------------------------
13
target/arm/cpu.h | 16 +++++++++
11
2 files changed, 69 insertions(+), 35 deletions(-)
14
target/arm/cpu.c | 5 +++
15
target/arm/cpu64.c | 3 +-
16
target/arm/helper.c | 61 ++++++++++++++++++++++++++++++++++-
17
5 files changed, 86 insertions(+), 2 deletions(-)
12
18
13
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
19
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a32.h
21
--- a/docs/system/arm/emulation.rst
16
+++ b/target/arm/translate-a32.h
22
+++ b/docs/system/arm/emulation.rst
17
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 load_reg(DisasContext *s, int reg)
23
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
18
return tmp;
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)
33
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/cpu.h
36
+++ b/target/arm/cpu.h
37
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
38
ARMPACKey apdb;
39
ARMPACKey apga;
40
} keys;
41
+
42
+ uint64_t scxtnum_el[4];
43
#endif
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;
19
}
56
}
20
57
21
+void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
58
+static inline bool isar_feature_aa64_scxtnum(const ARMISARegisters *id)
22
+ TCGv_i32 a32, int index, MemOp opc);
23
+void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
24
+ TCGv_i32 a32, int index, MemOp opc);
25
+void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
26
+ TCGv_i32 a32, int index, MemOp opc);
27
+void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
28
+ TCGv_i32 a32, int index, MemOp opc);
29
+void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
30
+ int index, MemOp opc);
31
+void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
32
+ int index, MemOp opc);
33
+void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
34
+ int index, MemOp opc);
35
+void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
36
+ int index, MemOp opc);
37
+
38
+#define DO_GEN_LD(SUFF, OPC) \
39
+ static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
40
+ TCGv_i32 a32, int index) \
41
+ { \
42
+ gen_aa32_ld_i32(s, val, a32, index, OPC); \
43
+ }
44
+
45
+#define DO_GEN_ST(SUFF, OPC) \
46
+ static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
47
+ TCGv_i32 a32, int index) \
48
+ { \
49
+ gen_aa32_st_i32(s, val, a32, index, OPC); \
50
+ }
51
+
52
+static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
53
+ TCGv_i32 a32, int index)
54
+{
59
+{
55
+ gen_aa32_ld_i64(s, val, a32, index, MO_Q);
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;
56
+}
69
+}
57
+
70
+
58
+static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
71
static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id)
59
+ TCGv_i32 a32, int index)
72
{
73
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SSBS) != 0;
74
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/arm/cpu.c
77
+++ b/target/arm/cpu.c
78
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
79
*/
80
env->cp15.gcr_el1 = 0x1ffff;
81
}
82
+ /*
83
+ * Disable access to SCXTNUM_EL0 from CSV2_1p2.
84
+ * This is not yet exposed from the Linux kernel in any way.
85
+ */
86
+ env->cp15.sctlr_el[1] |= SCTLR_TSCXT;
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;
111
diff --git a/target/arm/helper.c b/target/arm/helper.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/target/arm/helper.c
114
+++ b/target/arm/helper.c
115
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
116
if (cpu_isar_feature(aa64_mte, cpu)) {
117
valid_mask |= SCR_ATA;
118
}
119
+ if (cpu_isar_feature(aa64_scxtnum, cpu)) {
120
+ valid_mask |= SCR_ENSCXT;
121
+ }
122
} else {
123
valid_mask &= ~(SCR_RW | SCR_ST);
124
if (cpu_isar_feature(aa32_ras, cpu)) {
125
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
126
if (cpu_isar_feature(aa64_mte, cpu)) {
127
valid_mask |= HCR_ATA | HCR_DCT | HCR_TID5;
128
}
129
+ if (cpu_isar_feature(aa64_scxtnum, cpu)) {
130
+ valid_mask |= HCR_ENSCXT;
131
+ }
132
}
133
134
/* Clear RES0 bits. */
135
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
136
{ K(3, 0, 5, 6, 0), K(3, 4, 5, 6, 0), K(3, 5, 5, 6, 0),
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)
60
+{
153
+{
61
+ gen_aa32_st_i64(s, val, a32, index, MO_Q);
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;
62
+}
176
+}
63
+
177
+
64
+DO_GEN_LD(8u, MO_UB)
178
+static const ARMCPRegInfo scxtnum_reginfo[] = {
65
+DO_GEN_LD(16u, MO_UW)
179
+ { .name = "SCXTNUM_EL0", .state = ARM_CP_STATE_AA64,
66
+DO_GEN_LD(32u, MO_UL)
180
+ .opc0 = 3, .opc1 = 3, .crn = 13, .crm = 0, .opc2 = 7,
67
+DO_GEN_ST(8, MO_UB)
181
+ .access = PL0_RW, .accessfn = access_scxtnum,
68
+DO_GEN_ST(16, MO_UW)
182
+ .fieldoffset = offsetof(CPUARMState, scxtnum_el[0]) },
69
+DO_GEN_ST(32, MO_UL)
183
+ { .name = "SCXTNUM_EL1", .state = ARM_CP_STATE_AA64,
70
+
184
+ .opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 7,
71
+#undef DO_GEN_LD
185
+ .access = PL1_RW, .accessfn = access_scxtnum,
72
+#undef DO_GEN_ST
186
+ .fieldoffset = offsetof(CPUARMState, scxtnum_el[1]) },
73
+
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
+ }
74
#endif
208
#endif
75
diff --git a/target/arm/translate.c b/target/arm/translate.c
209
76
index XXXXXXX..XXXXXXX 100644
210
if (cpu_isar_feature(any_predinv, cpu)) {
77
--- a/target/arm/translate.c
78
+++ b/target/arm/translate.c
79
@@ -XXX,XX +XXX,XX @@ static TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, MemOp op)
80
* Internal routines are used for NEON cases where the endianness
81
* and/or alignment has already been taken into account and manipulated.
82
*/
83
-static void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
84
- TCGv_i32 a32, int index, MemOp opc)
85
+void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
86
+ TCGv_i32 a32, int index, MemOp opc)
87
{
88
TCGv addr = gen_aa32_addr(s, a32, opc);
89
tcg_gen_qemu_ld_i32(val, addr, index, opc);
90
tcg_temp_free(addr);
91
}
92
93
-static void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
94
- TCGv_i32 a32, int index, MemOp opc)
95
+void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
96
+ TCGv_i32 a32, int index, MemOp opc)
97
{
98
TCGv addr = gen_aa32_addr(s, a32, opc);
99
tcg_gen_qemu_st_i32(val, addr, index, opc);
100
tcg_temp_free(addr);
101
}
102
103
-static void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
104
- TCGv_i32 a32, int index, MemOp opc)
105
+void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
106
+ TCGv_i32 a32, int index, MemOp opc)
107
{
108
TCGv addr = gen_aa32_addr(s, a32, opc);
109
110
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
111
tcg_temp_free(addr);
112
}
113
114
-static void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
115
- TCGv_i32 a32, int index, MemOp opc)
116
+void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
117
+ TCGv_i32 a32, int index, MemOp opc)
118
{
119
TCGv addr = gen_aa32_addr(s, a32, opc);
120
121
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
122
tcg_temp_free(addr);
123
}
124
125
-static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
126
- int index, MemOp opc)
127
+void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
128
+ int index, MemOp opc)
129
{
130
gen_aa32_ld_internal_i32(s, val, a32, index, finalize_memop(s, opc));
131
}
132
133
-static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
134
- int index, MemOp opc)
135
+void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
136
+ int index, MemOp opc)
137
{
138
gen_aa32_st_internal_i32(s, val, a32, index, finalize_memop(s, opc));
139
}
140
141
-static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
142
- int index, MemOp opc)
143
+void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
144
+ int index, MemOp opc)
145
{
146
gen_aa32_ld_internal_i64(s, val, a32, index, finalize_memop(s, opc));
147
}
148
149
-static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
150
- int index, MemOp opc)
151
+void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
152
+ int index, MemOp opc)
153
{
154
gen_aa32_st_internal_i64(s, val, a32, index, finalize_memop(s, opc));
155
}
156
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
157
gen_aa32_st_i32(s, val, a32, index, OPC); \
158
}
159
160
-static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
161
- TCGv_i32 a32, int index)
162
-{
163
- gen_aa32_ld_i64(s, val, a32, index, MO_Q);
164
-}
165
-
166
-static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
167
- TCGv_i32 a32, int index)
168
-{
169
- gen_aa32_st_i64(s, val, a32, index, MO_Q);
170
-}
171
-
172
-DO_GEN_LD(8u, MO_UB)
173
-DO_GEN_LD(16u, MO_UW)
174
-DO_GEN_LD(32u, MO_UL)
175
-DO_GEN_ST(8, MO_UB)
176
-DO_GEN_ST(16, MO_UW)
177
-DO_GEN_ST(32, MO_UL)
178
-
179
static inline void gen_hvc(DisasContext *s, int imm16)
180
{
181
/* The pre HVC helper handles cases when HVC gets trapped
182
--
211
--
183
2.20.1
212
2.25.1
184
185
diff view generated by jsdifflib
1
The MPS2 SCC device doesn't have any documentation of its properties;
1
From: Richard Henderson <richard.henderson@linaro.org>
2
add a "QEMU interface" format comment describing them.
3
2
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>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220506180242.216785-22-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210504120912.23094-2-peter.maydell@linaro.org
7
---
10
---
8
include/hw/misc/mps2-scc.h | 12 ++++++++++++
11
docs/system/arm/emulation.rst | 1 +
9
1 file changed, 12 insertions(+)
12
target/arm/cpu64.c | 1 +
13
target/arm/cpu_tcg.c | 1 +
14
3 files changed, 3 insertions(+)
10
15
11
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
16
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/include/hw/misc/mps2-scc.h
18
--- a/docs/system/arm/emulation.rst
14
+++ b/include/hw/misc/mps2-scc.h
19
+++ b/docs/system/arm/emulation.rst
15
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
16
* (at your option) any later version.
21
- FEAT_CSV2_1p1 (Cache speculation variant 2, version 1.1)
17
*/
22
- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
18
23
- FEAT_CSV2_2 (Cache speculation variant 2, version 2)
19
+/*
24
+- FEAT_CSV3 (Cache speculation variant 3)
20
+ * This is a model of the Serial Communication Controller (SCC)
25
- FEAT_DIT (Data Independent Timing instructions)
21
+ * block found in most MPS FPGA images.
26
- FEAT_DPB (DC CVAP instruction)
22
+ *
27
- FEAT_Debugv8p2 (Debug changes for v8.2)
23
+ * QEMU interface:
28
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
24
+ * + sysbus MMIO region 0: the register bank
29
index XXXXXXX..XXXXXXX 100644
25
+ * + QOM property "scc-cfg4": value of the read-only CFG4 register
30
--- a/target/arm/cpu64.c
26
+ * + QOM property "scc-aid": value of the read-only SCC_AID register
31
+++ b/target/arm/cpu64.c
27
+ * + QOM property "scc-id": value of the read-only SCC_ID register
32
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
28
+ * + QOM property array "oscclk": reset values of the OSCCLK registers
33
t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); /* FEAT_SEL2 */
29
+ * (which are accessed via the SYS_CFG channel provided by this device)
34
t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
30
+ */
35
t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 2); /* FEAT_CSV2_2 */
31
#ifndef MPS2_SCC_H
36
+ t = FIELD_DP64(t, ID_AA64PFR0, CSV3, 1); /* FEAT_CSV3 */
32
#define MPS2_SCC_H
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_pfr0 = t;
46
47
t = cpu->isar.id_pfr2;
48
+ t = FIELD_DP32(t, ID_PFR2, CSV3, 1); /* FEAT_CSV3 */
49
t = FIELD_DP32(t, ID_PFR2, SSBS, 1); /* FEAT_SSBS */
50
cpu->isar.id_pfr2 = t;
33
51
34
--
52
--
35
2.20.1
53
2.25.1
36
37
diff view generated by jsdifflib
1
Make bswap.h handle being included outside an 'extern "C"' block:
1
From: Richard Henderson <richard.henderson@linaro.org>
2
all system headers are included first, then all declarations are
3
put inside an 'extern "C"' block.
4
2
5
This requires a little rearrangement as currently we have an ifdef
3
This extension concerns not merging memory access, which TCG does
6
ladder that has some system includes and some local declarations
4
not implement. Thus we can trivially enable this feature.
7
or definitions, and we need to separate those out.
5
Add a comment to handle_hint for the DGH instruction, but no code.
8
6
9
We want to do this because dis-asm.h includes bswap.h, dis-asm.h
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
may need to be included from C++ files, and system headers should
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
not be included within 'extern "C"' blocks.
9
Message-id: 20220506180242.216785-23-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
docs/system/arm/emulation.rst | 1 +
13
target/arm/cpu64.c | 1 +
14
target/arm/translate-a64.c | 1 +
15
3 files changed, 3 insertions(+)
12
16
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
---
16
include/qemu/bswap.h | 26 ++++++++++++++++++++++----
17
1 file changed, 22 insertions(+), 4 deletions(-)
18
19
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/include/qemu/bswap.h
19
--- a/docs/system/arm/emulation.rst
22
+++ b/include/qemu/bswap.h
20
+++ b/docs/system/arm/emulation.rst
23
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
24
#ifndef BSWAP_H
22
- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
25
#define BSWAP_H
23
- FEAT_CSV2_2 (Cache speculation variant 2, version 2)
26
24
- FEAT_CSV3 (Cache speculation variant 3)
27
-#include "fpu/softfloat-types.h"
25
+- FEAT_DGH (Data gathering hint)
28
-
26
- FEAT_DIT (Data Independent Timing instructions)
29
#ifdef CONFIG_MACHINE_BSWAP_H
27
- FEAT_DPB (DC CVAP instruction)
30
# include <sys/endian.h>
28
- FEAT_Debugv8p2 (Debug changes for v8.2)
31
# include <machine/bswap.h>
29
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
32
@@ -XXX,XX +XXX,XX @@
30
index XXXXXXX..XXXXXXX 100644
33
# include <endian.h>
31
--- a/target/arm/cpu64.c
34
#elif defined(CONFIG_BYTESWAP_H)
32
+++ b/target/arm/cpu64.c
35
# include <byteswap.h>
33
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
36
+#define BSWAP_FROM_BYTESWAP
34
t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1); /* FEAT_SB */
37
+# else
35
t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1); /* FEAT_SPECRES */
38
+#define BSWAP_FROM_FALLBACKS
36
t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 1); /* FEAT_BF16 */
39
+#endif /* ! CONFIG_MACHINE_BSWAP_H */
37
+ t = FIELD_DP64(t, ID_AA64ISAR1, DGH, 1); /* FEAT_DGH */
40
38
t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1); /* FEAT_I8MM */
41
+#ifdef __cplusplus
39
cpu->isar.id_aa64isar1 = t;
42
+extern "C" {
40
43
+#endif
41
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
44
+
42
index XXXXXXX..XXXXXXX 100644
45
+#include "fpu/softfloat-types.h"
43
--- a/target/arm/translate-a64.c
46
+
44
+++ b/target/arm/translate-a64.c
47
+#ifdef BSWAP_FROM_BYTESWAP
45
@@ -XXX,XX +XXX,XX @@ static void handle_hint(DisasContext *s, uint32_t insn,
48
static inline uint16_t bswap16(uint16_t x)
46
break;
49
{
47
case 0b00100: /* SEV */
50
return bswap_16(x);
48
case 0b00101: /* SEVL */
51
@@ -XXX,XX +XXX,XX @@ static inline uint64_t bswap64(uint64_t x)
49
+ case 0b00110: /* DGH */
52
{
50
/* we treat all as NOP at least for now */
53
return bswap_64(x);
51
break;
54
}
52
case 0b00111: /* XPACLRI */
55
-# else
56
+#endif
57
+
58
+#ifdef BSWAP_FROM_FALLBACKS
59
static inline uint16_t bswap16(uint16_t x)
60
{
61
return (((x & 0x00ff) << 8) |
62
@@ -XXX,XX +XXX,XX @@ static inline uint64_t bswap64(uint64_t x)
63
((x & 0x00ff000000000000ULL) >> 40) |
64
((x & 0xff00000000000000ULL) >> 56));
65
}
66
-#endif /* ! CONFIG_MACHINE_BSWAP_H */
67
+#endif
68
+
69
+#undef BSWAP_FROM_BYTESWAP
70
+#undef BSWAP_FROM_FALLBACKS
71
72
static inline void bswap16s(uint16_t *s)
73
{
74
@@ -XXX,XX +XXX,XX @@ DO_STN_LDN_P(be)
75
#undef le_bswaps
76
#undef be_bswaps
77
78
+#ifdef __cplusplus
79
+}
80
+#endif
81
+
82
#endif /* BSWAP_H */
83
--
53
--
84
2.20.1
54
2.25.1
85
86
diff view generated by jsdifflib
1
The function vfp_reg_ptr() is used only in translate-neon.c.inc;
1
From: Richard Henderson <richard.henderson@linaro.org>
2
move it there.
3
2
3
Enable the a76 for virt and sbsa board use.
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
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-10-peter.maydell@linaro.org
8
---
9
---
9
target/arm/translate.c | 7 -------
10
docs/system/arm/virt.rst | 1 +
10
target/arm/translate-neon.c.inc | 7 +++++++
11
hw/arm/sbsa-ref.c | 1 +
11
2 files changed, 7 insertions(+), 7 deletions(-)
12
hw/arm/virt.c | 1 +
13
target/arm/cpu64.c | 66 ++++++++++++++++++++++++++++++++++++++++
14
4 files changed, 69 insertions(+)
12
15
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
18
--- a/docs/system/arm/virt.rst
16
+++ b/target/arm/translate.c
19
+++ b/docs/system/arm/virt.rst
17
@@ -XXX,XX +XXX,XX @@ void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
20
@@ -XXX,XX +XXX,XX @@ Supported guest CPU types:
18
}
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);
19
}
58
}
20
59
21
-static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
60
+static void aarch64_a76_initfn(Object *obj)
22
-{
23
- TCGv_ptr ret = tcg_temp_new_ptr();
24
- tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
25
- return ret;
26
-}
27
-
28
#define ARM_CP_RW_BIT (1 << 20)
29
30
/* Include the Neon decoder */
31
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/translate-neon.c.inc
34
+++ b/target/arm/translate-neon.c.inc
35
@@ -XXX,XX +XXX,XX @@ static inline int neon_3same_fp_size(DisasContext *s, int x)
36
#include "decode-neon-ls.c.inc"
37
#include "decode-neon-shared.c.inc"
38
39
+static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
40
+{
61
+{
41
+ TCGv_ptr ret = tcg_temp_new_ptr();
62
+ ARMCPU *cpu = ARM_CPU(obj);
42
+ tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
63
+
43
+ return ret;
64
+ cpu->dtb_compatible = "arm,cortex-a76";
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 = 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;
105
+
106
+ /* From B2.18 CCSIDR_EL1 */
107
+ cpu->ccsidr[0] = 0x701fe01a; /* 64KB L1 dcache */
108
+ cpu->ccsidr[1] = 0x201fe01a; /* 64KB L1 icache */
109
+ cpu->ccsidr[2] = 0x707fe03a; /* 512KB L2 cache */
110
+
111
+ /* From B2.93 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;
44
+}
123
+}
45
+
124
+
46
static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
125
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
47
{
126
{
48
long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
127
/*
128
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo aarch64_cpus[] = {
129
{ .name = "cortex-a57", .initfn = aarch64_a57_initfn },
130
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
131
{ .name = "cortex-a72", .initfn = aarch64_a72_initfn },
132
+ { .name = "cortex-a76", .initfn = aarch64_a76_initfn },
133
{ .name = "a64fx", .initfn = aarch64_a64fx_initfn },
134
{ .name = "max", .initfn = aarch64_max_initfn },
135
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
49
--
136
--
50
2.20.1
137
2.25.1
51
52
diff view generated by jsdifflib
1
The functions vfp_load_reg32(), vfp_load_reg64(), vfp_store_reg32()
1
From: Richard Henderson <richard.henderson@linaro.org>
2
and vfp_store_reg64() are used only in translate-vfp.c.inc. Move
3
them to that file.
4
2
3
Enable the n1 for virt and sbsa board use.
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-25-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210430132740.10391-7-peter.maydell@linaro.org
9
---
9
---
10
target/arm/translate.c | 20 --------------------
10
docs/system/arm/virt.rst | 1 +
11
target/arm/translate-vfp.c.inc | 20 ++++++++++++++++++++
11
hw/arm/sbsa-ref.c | 1 +
12
2 files changed, 20 insertions(+), 20 deletions(-)
12
hw/arm/virt.c | 1 +
13
target/arm/cpu64.c | 66 ++++++++++++++++++++++++++++++++++++++++
14
4 files changed, 69 insertions(+)
13
15
14
diff --git a/target/arm/translate.c b/target/arm/translate.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/target/arm/translate.c
18
--- a/docs/system/arm/virt.rst
17
+++ b/target/arm/translate.c
19
+++ b/docs/system/arm/virt.rst
18
@@ -XXX,XX +XXX,XX @@ static long vfp_reg_offset(bool dp, unsigned reg)
20
@@ -XXX,XX +XXX,XX @@ Supported guest CPU types:
19
}
21
- ``cortex-a76`` (64-bit)
22
- ``a64fx`` (64-bit)
23
- ``host`` (with KVM only)
24
+- ``neoverse-n1`` (64-bit)
25
- ``max`` (same as ``host`` for KVM; best possible emulation with TCG)
26
27
Note that the default is ``cortex-a15``, so for an AArch64 guest you must
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 char * const valid_cpus[] = {
33
ARM_CPU_TYPE_NAME("cortex-a57"),
34
ARM_CPU_TYPE_NAME("cortex-a72"),
35
ARM_CPU_TYPE_NAME("cortex-a76"),
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;
20
}
58
}
21
59
22
-static inline void vfp_load_reg64(TCGv_i64 var, int reg)
60
+static void aarch64_neoverse_n1_initfn(Object *obj)
23
-{
24
- tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(true, reg));
25
-}
26
-
27
-static inline void vfp_store_reg64(TCGv_i64 var, int reg)
28
-{
29
- tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(true, reg));
30
-}
31
-
32
-static inline void vfp_load_reg32(TCGv_i32 var, int reg)
33
-{
34
- tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
35
-}
36
-
37
-static inline void vfp_store_reg32(TCGv_i32 var, int reg)
38
-{
39
- tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
40
-}
41
-
42
void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
43
{
44
long off = neon_element_offset(reg, ele, memop);
45
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/translate-vfp.c.inc
48
+++ b/target/arm/translate-vfp.c.inc
49
@@ -XXX,XX +XXX,XX @@
50
#include "decode-vfp.c.inc"
51
#include "decode-vfp-uncond.c.inc"
52
53
+static inline void vfp_load_reg64(TCGv_i64 var, int reg)
54
+{
61
+{
55
+ tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(true, reg));
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;
56
+}
123
+}
57
+
124
+
58
+static inline void vfp_store_reg64(TCGv_i64 var, int reg)
125
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
59
+{
126
{
60
+ tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(true, reg));
127
/*
61
+}
128
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo aarch64_cpus[] = {
62
+
129
{ .name = "cortex-a72", .initfn = aarch64_a72_initfn },
63
+static inline void vfp_load_reg32(TCGv_i32 var, int reg)
130
{ .name = "cortex-a76", .initfn = aarch64_a76_initfn },
64
+{
131
{ .name = "a64fx", .initfn = aarch64_a64fx_initfn },
65
+ tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
132
+ { .name = "neoverse-n1", .initfn = aarch64_neoverse_n1_initfn },
66
+}
133
{ .name = "max", .initfn = aarch64_max_initfn },
67
+
134
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
68
+static inline void vfp_store_reg32(TCGv_i32 var, int reg)
135
{ .name = "host", .initfn = aarch64_host_initfn },
69
+{
70
+ tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
71
+}
72
+
73
/*
74
* The imm8 encodes the sign bit, enough bits to represent an exponent in
75
* the range 01....1xx to 10....0xx, and the most significant 4 bits of
76
--
136
--
77
2.20.1
137
2.25.1
78
79
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
2
3
A trailing _ makes all the difference to the rendered link.
3
The sbsa-ref machine is continuously evolving. Some of the changes we
4
want to make in the near future, to align with real components (e.g.
5
the GIC-700), will break compatibility for existing firmware.
4
6
5
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Introduce two new properties to the DT generated on machine generation:
6
Message-id: 20210428131316.31390-1-alex.bennee@linaro.org
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.
15
16
This versioning scheme is *neither*:
17
- A QEMU versioned machine type; a given version of QEMU will emulate
18
a given version of the platform.
19
- A reflection of level of SBSA (now SystemReady SR) support provided.
20
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>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
33
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
35
---
10
docs/system/arm/sbsa.rst | 2 +-
36
hw/arm/sbsa-ref.c | 14 ++++++++++++++
11
1 file changed, 1 insertion(+), 1 deletion(-)
37
1 file changed, 14 insertions(+)
12
38
13
diff --git a/docs/system/arm/sbsa.rst b/docs/system/arm/sbsa.rst
39
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
14
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
15
--- a/docs/system/arm/sbsa.rst
41
--- a/hw/arm/sbsa-ref.c
16
+++ b/docs/system/arm/sbsa.rst
42
+++ b/hw/arm/sbsa-ref.c
17
@@ -XXX,XX +XXX,XX @@ Arm Server Base System Architecture Reference board (``sbsa-ref``)
43
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SBSAMachineState *sms)
18
While the `virt` board is a generic board platform that doesn't match
44
qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
19
any real hardware the `sbsa-ref` board intends to look like real
45
qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
20
hardware. The `Server Base System Architecture
46
21
-<https://developer.arm.com/documentation/den0029/latest>` defines a
47
+ /*
22
+<https://developer.arm.com/documentation/den0029/latest>`_ defines a
48
+ * This versioning scheme is for informing platform fw only. It is neither:
23
minimum base line of hardware support and importantly how the firmware
49
+ * - A QEMU versioned machine type; a given version of QEMU will emulate
24
reports that to any operating system. It is a static system that
50
+ * a given version of the platform.
25
reports a very minimal DT to the firmware for non-discoverable
51
+ * - A reflection of level of SBSA (now SystemReady SR) support provided.
52
+ *
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);
26
--
64
--
27
2.20.1
65
2.25.1
28
66
29
67
diff view generated by jsdifflib
1
Switch translate-neon.c.inc from being #included into translate.c
1
From: Gavin Shan <gshan@redhat.com>
2
to being its own compilation unit.
3
2
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
7
* hw/core/machine.c::machine_set_cpu_numa_node() to associate
8
CPU with its NUMA node.
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
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-14-peter.maydell@linaro.org
8
---
21
---
9
target/arm/translate-a32.h | 3 +++
22
qapi/machine.json | 6 ++++--
10
.../arm/{translate-neon.c.inc => translate-neon.c} | 12 +++++++-----
23
hw/core/machine-hmp-cmds.c | 4 ++++
11
target/arm/translate.c | 3 ---
24
hw/core/machine.c | 16 ++++++++++++++++
12
target/arm/meson.build | 7 ++++---
25
3 files changed, 24 insertions(+), 2 deletions(-)
13
4 files changed, 14 insertions(+), 11 deletions(-)
14
rename target/arm/{translate-neon.c.inc => translate-neon.c} (99%)
15
26
16
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
27
diff --git a/qapi/machine.json b/qapi/machine.json
17
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a32.h
29
--- a/qapi/machine.json
19
+++ b/target/arm/translate-a32.h
30
+++ b/qapi/machine.json
20
@@ -XXX,XX +XXX,XX @@
31
@@ -XXX,XX +XXX,XX @@
21
bool disas_m_nocp(DisasContext *dc, uint32_t insn);
32
# @node-id: NUMA node ID the CPU belongs to
22
bool disas_vfp(DisasContext *s, uint32_t insn);
33
# @socket-id: socket number within node/board the CPU belongs to
23
bool disas_vfp_uncond(DisasContext *s, uint32_t insn);
34
# @die-id: die number within socket the CPU belongs to (since 4.1)
24
+bool disas_neon_dp(DisasContext *s, uint32_t insn);
35
-# @core-id: core number within die the CPU belongs to
25
+bool disas_neon_ls(DisasContext *s, uint32_t insn);
36
+# @cluster-id: cluster number within die the CPU belongs to (since 7.1)
26
+bool disas_neon_shared(DisasContext *s, uint32_t insn);
37
+# @core-id: core number within cluster the CPU belongs to
27
38
# @thread-id: thread number within core the CPU belongs to
28
void load_reg_var(DisasContext *s, TCGv_i32 var, int reg);
39
#
29
void arm_gen_condlabel(DisasContext *s);
40
-# Note: currently there are 5 properties that could be present
30
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c
41
+# Note: currently there are 6 properties that could be present
31
similarity index 99%
42
# but management should be prepared to pass through other
32
rename from target/arm/translate-neon.c.inc
43
# properties with device_add command to allow for future
33
rename to target/arm/translate-neon.c
44
# interface extension. This also requires the filed names to be kept in
45
@@ -XXX,XX +XXX,XX @@
46
'data': { '*node-id': 'int',
47
'*socket-id': 'int',
48
'*die-id': 'int',
49
+ '*cluster-id': 'int',
50
'*core-id': 'int',
51
'*thread-id': 'int'
52
}
53
diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
34
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-neon.c.inc
55
--- a/hw/core/machine-hmp-cmds.c
36
+++ b/target/arm/translate-neon.c
56
+++ b/hw/core/machine-hmp-cmds.c
37
@@ -XXX,XX +XXX,XX @@
57
@@ -XXX,XX +XXX,XX @@ void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict)
38
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
58
if (c->has_die_id) {
39
*/
59
monitor_printf(mon, " die-id: \"%" PRIu64 "\"\n", c->die_id);
40
60
}
41
-/*
61
+ if (c->has_cluster_id) {
42
- * This file is intended to be included from translate.c; it uses
62
+ monitor_printf(mon, " cluster-id: \"%" PRIu64 "\"\n",
43
- * some macros and definitions provided by that file.
63
+ c->cluster_id);
44
- * It might be possible to convert it to a standalone .c file eventually.
64
+ }
45
- */
65
if (c->has_core_id) {
46
+#include "qemu/osdep.h"
66
monitor_printf(mon, " core-id: \"%" PRIu64 "\"\n", c->core_id);
47
+#include "tcg/tcg-op.h"
67
}
48
+#include "tcg/tcg-op-gvec.h"
68
diff --git a/hw/core/machine.c b/hw/core/machine.c
49
+#include "exec/exec-all.h"
50
+#include "exec/gen-icount.h"
51
+#include "translate.h"
52
+#include "translate-a32.h"
53
54
static inline int plus1(DisasContext *s, int x)
55
{
56
diff --git a/target/arm/translate.c b/target/arm/translate.c
57
index XXXXXXX..XXXXXXX 100644
69
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/translate.c
70
--- a/hw/core/machine.c
59
+++ b/target/arm/translate.c
71
+++ b/hw/core/machine.c
60
@@ -XXX,XX +XXX,XX @@ void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
72
@@ -XXX,XX +XXX,XX @@ void machine_set_cpu_numa_node(MachineState *machine,
61
73
return;
62
#define ARM_CP_RW_BIT (1 << 20)
74
}
63
75
64
-/* Include the Neon decoder */
76
+ if (props->has_cluster_id && !slot->props.has_cluster_id) {
65
-#include "translate-neon.c.inc"
77
+ error_setg(errp, "cluster-id is not supported");
66
-
78
+ return;
67
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
79
+ }
68
{
80
+
69
tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
81
if (props->has_socket_id && !slot->props.has_socket_id) {
70
diff --git a/target/arm/meson.build b/target/arm/meson.build
82
error_setg(errp, "socket-id is not supported");
71
index XXXXXXX..XXXXXXX 100644
83
return;
72
--- a/target/arm/meson.build
84
@@ -XXX,XX +XXX,XX @@ void machine_set_cpu_numa_node(MachineState *machine,
73
+++ b/target/arm/meson.build
85
continue;
74
@@ -XXX,XX +XXX,XX @@
86
}
75
gen = [
87
76
decodetree.process('sve.decode', extra_args: '--decode=disas_sve'),
88
+ if (props->has_cluster_id &&
77
- decodetree.process('neon-shared.decode', extra_args: '--static-decode=disas_neon_shared'),
89
+ props->cluster_id != slot->props.cluster_id) {
78
- decodetree.process('neon-dp.decode', extra_args: '--static-decode=disas_neon_dp'),
90
+ continue;
79
- decodetree.process('neon-ls.decode', extra_args: '--static-decode=disas_neon_ls'),
91
+ }
80
+ decodetree.process('neon-shared.decode', extra_args: '--decode=disas_neon_shared'),
92
+
81
+ decodetree.process('neon-dp.decode', extra_args: '--decode=disas_neon_dp'),
93
if (props->has_die_id && props->die_id != slot->props.die_id) {
82
+ decodetree.process('neon-ls.decode', extra_args: '--decode=disas_neon_ls'),
94
continue;
83
decodetree.process('vfp.decode', extra_args: '--decode=disas_vfp'),
95
}
84
decodetree.process('vfp-uncond.decode', extra_args: '--decode=disas_vfp_uncond'),
96
@@ -XXX,XX +XXX,XX @@ static char *cpu_slot_to_string(const CPUArchId *cpu)
85
decodetree.process('m-nocp.decode', extra_args: '--decode=disas_m_nocp'),
97
}
86
@@ -XXX,XX +XXX,XX @@ arm_ss.add(files(
98
g_string_append_printf(s, "die-id: %"PRId64, cpu->props.die_id);
87
'tlb_helper.c',
99
}
88
'translate.c',
100
+ if (cpu->props.has_cluster_id) {
89
'translate-m-nocp.c',
101
+ if (s->len) {
90
+ 'translate-neon.c',
102
+ g_string_append_printf(s, ", ");
91
'translate-vfp.c',
103
+ }
92
'vec_helper.c',
104
+ g_string_append_printf(s, "cluster-id: %"PRId64, cpu->props.cluster_id);
93
'vfp_helper.c',
105
+ }
106
if (cpu->props.has_core_id) {
107
if (s->len) {
108
g_string_append_printf(s, ", ");
94
--
109
--
95
2.20.1
110
2.25.1
96
97
diff view generated by jsdifflib
1
Move the NeonGenThreeOpEnvFn typedef to translate.h together
1
From: Gavin Shan <gshan@redhat.com>
2
with the other similar typedefs.
3
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
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210430132740.10391-12-peter.maydell@linaro.org
8
---
29
---
9
target/arm/translate.h | 2 ++
30
tests/qtest/numa-test.c | 3 ++-
10
target/arm/translate.c | 3 ---
31
1 file changed, 2 insertions(+), 1 deletion(-)
11
2 files changed, 2 insertions(+), 3 deletions(-)
12
32
13
diff --git a/target/arm/translate.h b/target/arm/translate.h
33
diff --git a/tests/qtest/numa-test.c b/tests/qtest/numa-test.c
14
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.h
35
--- a/tests/qtest/numa-test.c
16
+++ b/target/arm/translate.h
36
+++ b/tests/qtest/numa-test.c
17
@@ -XXX,XX +XXX,XX @@ typedef void NeonGenOneOpFn(TCGv_i32, TCGv_i32);
37
@@ -XXX,XX +XXX,XX @@ static void aarch64_numa_cpu(const void *data)
18
typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
38
QTestState *qts;
19
typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
39
g_autofree char *cli = NULL;
20
typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
40
21
+typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
41
- cli = make_cli(data, "-machine smp.cpus=2 "
22
+ TCGv_i32, TCGv_i32);
42
+ cli = make_cli(data, "-machine "
23
typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
43
+ "smp.cpus=2,smp.sockets=1,smp.clusters=1,smp.cores=1,smp.threads=2 "
24
typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
44
"-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 "
25
typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
45
"-numa cpu,node-id=1,thread-id=0 "
26
diff --git a/target/arm/translate.c b/target/arm/translate.c
46
"-numa cpu,node-id=0,thread-id=1");
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/translate.c
29
+++ b/target/arm/translate.c
30
@@ -XXX,XX +XXX,XX @@ static const char * const regnames[] =
31
{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
32
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
33
34
-/* Function prototypes for gen_ functions calling Neon helpers. */
35
-typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
36
- TCGv_i32, TCGv_i32);
37
38
/* initialize TCG globals. */
39
void arm_translate_init(void)
40
--
47
--
41
2.20.1
48
2.25.1
42
49
43
50
diff view generated by jsdifflib
1
The VFPGenFixPointFn typedef is unused; delete it.
1
From: Gavin Shan <gshan@redhat.com>
2
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
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20210430132740.10391-11-peter.maydell@linaro.org
7
---
19
---
8
target/arm/translate.c | 2 --
20
hw/arm/virt.c | 15 ++++++++++++++-
9
1 file changed, 2 deletions(-)
21
1 file changed, 14 insertions(+), 1 deletion(-)
10
22
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
23
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
12
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
25
--- a/hw/arm/virt.c
14
+++ b/target/arm/translate.c
26
+++ b/hw/arm/virt.c
15
@@ -XXX,XX +XXX,XX @@ static const char * const regnames[] =
27
@@ -XXX,XX +XXX,XX @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
16
/* Function prototypes for gen_ functions calling Neon helpers. */
28
int n;
17
typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
29
unsigned int max_cpus = ms->smp.max_cpus;
18
TCGv_i32, TCGv_i32);
30
VirtMachineState *vms = VIRT_MACHINE(ms);
19
-/* Function prototypes for gen_ functions for fix point conversions */
31
+ MachineClass *mc = MACHINE_GET_CLASS(vms);
20
-typedef void VFPGenFixPointFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
32
21
33
if (ms->possible_cpus) {
22
/* initialize TCG globals. */
34
assert(ms->possible_cpus->len == max_cpus);
23
void arm_translate_init(void)
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
}
24
--
57
--
25
2.20.1
58
2.25.1
26
27
diff view generated by jsdifflib
1
Switch translate-vfp.c.inc from being #included into translate.c
1
From: Gavin Shan <gshan@redhat.com>
2
to being its own compilation unit.
3
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
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-9-peter.maydell@linaro.org
8
---
31
---
9
target/arm/translate-a32.h | 2 ++
32
tests/qtest/numa-test.c | 18 ++++++++++++------
10
target/arm/{translate-vfp.c.inc => translate-vfp.c} | 12 +++++++-----
33
1 file changed, 12 insertions(+), 6 deletions(-)
11
target/arm/translate.c | 3 +--
12
target/arm/meson.build | 5 +++--
13
4 files changed, 13 insertions(+), 9 deletions(-)
14
rename target/arm/{translate-vfp.c.inc => translate-vfp.c} (99%)
15
34
16
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
35
diff --git a/tests/qtest/numa-test.c b/tests/qtest/numa-test.c
17
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a32.h
37
--- a/tests/qtest/numa-test.c
19
+++ b/target/arm/translate-a32.h
38
+++ b/tests/qtest/numa-test.c
20
@@ -XXX,XX +XXX,XX @@
39
@@ -XXX,XX +XXX,XX @@ static void aarch64_numa_cpu(const void *data)
21
40
g_autofree char *cli = NULL;
22
/* Prototypes for autogenerated disassembler functions */
41
23
bool disas_m_nocp(DisasContext *dc, uint32_t insn);
42
cli = make_cli(data, "-machine "
24
+bool disas_vfp(DisasContext *s, uint32_t insn);
43
- "smp.cpus=2,smp.sockets=1,smp.clusters=1,smp.cores=1,smp.threads=2 "
25
+bool disas_vfp_uncond(DisasContext *s, uint32_t insn);
44
+ "smp.cpus=2,smp.sockets=2,smp.clusters=1,smp.cores=1,smp.threads=1 "
26
45
"-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 "
27
void load_reg_var(DisasContext *s, TCGv_i32 var, int reg);
46
- "-numa cpu,node-id=1,thread-id=0 "
28
void arm_gen_condlabel(DisasContext *s);
47
- "-numa cpu,node-id=0,thread-id=1");
29
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c
48
+ "-numa cpu,node-id=0,socket-id=1,cluster-id=0,core-id=0,thread-id=0 "
30
similarity index 99%
49
+ "-numa cpu,node-id=1,socket-id=0,cluster-id=0,core-id=0,thread-id=0");
31
rename from target/arm/translate-vfp.c.inc
50
qts = qtest_init(cli);
32
rename to target/arm/translate-vfp.c
51
cpus = get_cpus(qts, &resp);
33
index XXXXXXX..XXXXXXX 100644
52
g_assert(cpus);
34
--- a/target/arm/translate-vfp.c.inc
53
35
+++ b/target/arm/translate-vfp.c
54
while ((e = qlist_pop(cpus))) {
36
@@ -XXX,XX +XXX,XX @@
55
QDict *cpu, *props;
37
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
56
- int64_t thread, node;
38
*/
57
+ int64_t socket, cluster, core, thread, node;
39
58
40
-/*
59
cpu = qobject_to(QDict, e);
41
- * This file is intended to be included from translate.c; it uses
60
g_assert(qdict_haskey(cpu, "props"));
42
- * some macros and definitions provided by that file.
61
@@ -XXX,XX +XXX,XX @@ static void aarch64_numa_cpu(const void *data)
43
- * It might be possible to convert it to a standalone .c file eventually.
62
44
- */
63
g_assert(qdict_haskey(props, "node-id"));
45
+#include "qemu/osdep.h"
64
node = qdict_get_int(props, "node-id");
46
+#include "tcg/tcg-op.h"
65
+ g_assert(qdict_haskey(props, "socket-id"));
47
+#include "tcg/tcg-op-gvec.h"
66
+ socket = qdict_get_int(props, "socket-id");
48
+#include "exec/exec-all.h"
67
+ g_assert(qdict_haskey(props, "cluster-id"));
49
+#include "exec/gen-icount.h"
68
+ cluster = qdict_get_int(props, "cluster-id");
50
+#include "translate.h"
69
+ g_assert(qdict_haskey(props, "core-id"));
51
+#include "translate-a32.h"
70
+ core = qdict_get_int(props, "core-id");
52
71
g_assert(qdict_haskey(props, "thread-id"));
53
/* Include the generated VFP decoder */
72
thread = qdict_get_int(props, "thread-id");
54
#include "decode-vfp.c.inc"
73
55
diff --git a/target/arm/translate.c b/target/arm/translate.c
74
- if (thread == 0) {
56
index XXXXXXX..XXXXXXX 100644
75
+ if (socket == 0 && cluster == 0 && core == 0 && thread == 0) {
57
--- a/target/arm/translate.c
76
g_assert_cmpint(node, ==, 1);
58
+++ b/target/arm/translate.c
77
- } else if (thread == 1) {
59
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
78
+ } else if (socket == 1 && cluster == 0 && core == 0 && thread == 0) {
60
79
g_assert_cmpint(node, ==, 0);
61
#define ARM_CP_RW_BIT (1 << 20)
80
} else {
62
81
g_assert(false);
63
-/* Include the VFP and Neon decoders */
64
-#include "translate-vfp.c.inc"
65
+/* Include the Neon decoder */
66
#include "translate-neon.c.inc"
67
68
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
69
diff --git a/target/arm/meson.build b/target/arm/meson.build
70
index XXXXXXX..XXXXXXX 100644
71
--- a/target/arm/meson.build
72
+++ b/target/arm/meson.build
73
@@ -XXX,XX +XXX,XX @@ gen = [
74
decodetree.process('neon-shared.decode', extra_args: '--static-decode=disas_neon_shared'),
75
decodetree.process('neon-dp.decode', extra_args: '--static-decode=disas_neon_dp'),
76
decodetree.process('neon-ls.decode', extra_args: '--static-decode=disas_neon_ls'),
77
- decodetree.process('vfp.decode', extra_args: '--static-decode=disas_vfp'),
78
- decodetree.process('vfp-uncond.decode', extra_args: '--static-decode=disas_vfp_uncond'),
79
+ decodetree.process('vfp.decode', extra_args: '--decode=disas_vfp'),
80
+ decodetree.process('vfp-uncond.decode', extra_args: '--decode=disas_vfp_uncond'),
81
decodetree.process('m-nocp.decode', extra_args: '--decode=disas_m_nocp'),
82
decodetree.process('a32.decode', extra_args: '--static-decode=disas_a32'),
83
decodetree.process('a32-uncond.decode', extra_args: '--static-decode=disas_a32_uncond'),
84
@@ -XXX,XX +XXX,XX @@ arm_ss.add(files(
85
'tlb_helper.c',
86
'translate.c',
87
'translate-m-nocp.c',
88
+ 'translate-vfp.c',
89
'vec_helper.c',
90
'vfp_helper.c',
91
'cpu_tcg.c',
92
--
82
--
93
2.20.1
83
2.25.1
94
95
diff view generated by jsdifflib
1
Both os-win32.h and os-posix.h include system header files. Instead
1
From: Gavin Shan <gshan@redhat.com>
2
of having osdep.h include them inside its 'extern "C"' block, make
3
these headers handle that themselves, so that we don't include the
4
system headers inside 'extern "C"'.
5
2
6
This doesn't fix any current problems, but it's conceptually the
3
When CPU-to-NUMA association isn't explicitly provided by users,
7
right way to handle system headers.
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.
8
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
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
51
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
---
52
---
12
include/qemu/osdep.h | 8 ++++----
53
hw/arm/virt.c | 4 +++-
13
include/sysemu/os-posix.h | 8 ++++++++
54
1 file changed, 3 insertions(+), 1 deletion(-)
14
include/sysemu/os-win32.h | 8 ++++++++
15
3 files changed, 20 insertions(+), 4 deletions(-)
16
55
17
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
56
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
18
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
19
--- a/include/qemu/osdep.h
58
--- a/hw/arm/virt.c
20
+++ b/include/qemu/osdep.h
59
+++ b/hw/arm/virt.c
21
@@ -XXX,XX +XXX,XX @@ QEMU_EXTERN_C int daemon(int, int);
60
@@ -XXX,XX +XXX,XX @@ virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
22
*/
61
23
#include "glib-compat.h"
62
static int64_t virt_get_default_cpu_node_id(const MachineState *ms, int idx)
24
63
{
25
-#ifdef __cplusplus
64
- return idx % ms->numa_state->num_nodes;
26
-extern "C" {
65
+ int64_t socket_id = ms->possible_cpus->cpus[idx].props.socket_id;
27
-#endif
28
-
29
#ifdef _WIN32
30
#include "sysemu/os-win32.h"
31
#endif
32
@@ -XXX,XX +XXX,XX @@ extern "C" {
33
#include "sysemu/os-posix.h"
34
#endif
35
36
+#ifdef __cplusplus
37
+extern "C" {
38
+#endif
39
+
66
+
40
#include "qemu/typedefs.h"
67
+ return socket_id % ms->numa_state->num_nodes;
41
42
/*
43
diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/include/sysemu/os-posix.h
46
+++ b/include/sysemu/os-posix.h
47
@@ -XXX,XX +XXX,XX @@
48
#include <sys/sysmacros.h>
49
#endif
50
51
+#ifdef __cplusplus
52
+extern "C" {
53
+#endif
54
+
55
void os_set_line_buffering(void);
56
void os_set_proc_name(const char *s);
57
void os_setup_signal_handling(void);
58
@@ -XXX,XX +XXX,XX @@ static inline void qemu_funlockfile(FILE *f)
59
funlockfile(f);
60
}
68
}
61
69
62
+#ifdef __cplusplus
70
static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
63
+}
64
+#endif
65
+
66
#endif
67
diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h
68
index XXXXXXX..XXXXXXX 100644
69
--- a/include/sysemu/os-win32.h
70
+++ b/include/sysemu/os-win32.h
71
@@ -XXX,XX +XXX,XX @@
72
#include <windows.h>
73
#include <ws2tcpip.h>
74
75
+#ifdef __cplusplus
76
+extern "C" {
77
+#endif
78
+
79
#if defined(_WIN64)
80
/* On w64, setjmp is implemented by _setjmp which needs a second parameter.
81
* If this parameter is NULL, longjump does no stack unwinding.
82
@@ -XXX,XX +XXX,XX @@ ssize_t qemu_recv_wrap(int sockfd, void *buf, size_t len, int flags);
83
ssize_t qemu_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags,
84
struct sockaddr *addr, socklen_t *addrlen);
85
86
+#ifdef __cplusplus
87
+}
88
+#endif
89
+
90
#endif
91
--
71
--
92
2.20.1
72
2.25.1
93
94
diff view generated by jsdifflib
1
The omap_mmc_reset() function resets its SD card via
1
From: Gavin Shan <gshan@redhat.com>
2
device_legacy_reset(). We know that the SD card does not have a qbus
3
of its own, so the new device_cold_reset() function (which resets
4
both the device and its child buses) is equivalent here to
5
device_legacy_reset() and we can just switch to the new API.
6
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
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210430222348.8514-1-peter.maydell@linaro.org
10
---
18
---
11
hw/sd/omap_mmc.c | 2 +-
19
hw/acpi/aml-build.c | 111 +++++++++++++++++++-------------------------
12
1 file changed, 1 insertion(+), 1 deletion(-)
20
1 file changed, 48 insertions(+), 63 deletions(-)
13
21
14
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
22
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
15
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/sd/omap_mmc.c
24
--- a/hw/acpi/aml-build.c
17
+++ b/hw/sd/omap_mmc.c
25
+++ b/hw/acpi/aml-build.c
18
@@ -XXX,XX +XXX,XX @@ void omap_mmc_reset(struct omap_mmc_s *host)
26
@@ -XXX,XX +XXX,XX @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
19
* into any bus, and we must reset it manually. When omap_mmc is
27
const char *oem_id, const char *oem_table_id)
20
* QOMified this must move into the QOM reset function.
28
{
21
*/
29
MachineClass *mc = MACHINE_GET_CLASS(ms);
22
- device_legacy_reset(DEVICE(host->card));
30
- GQueue *list = g_queue_new();
23
+ device_cold_reset(DEVICE(host->card));
31
- guint pptt_start = table_data->len;
32
- guint parent_offset;
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
static uint64_t omap_mmc_read(void *opaque, hwaddr offset,
27
--
161
--
28
2.20.1
162
2.25.1
29
30
diff view generated by jsdifflib