1
ARM pullreq; contains some patches that arrived while I
1
target-arm queue: the big stuff here is the final part of
2
was on holiday, plus the series I sent off before going
2
rth's patches for Cortex-A76 and Neoverse-N1 support;
3
away, which got reviewed while I was away.
3
also present are Gavin's NUMA series and a few other things.
4
4
5
thanks
5
thanks
6
-- PMM
6
-- PMM
7
7
8
The following changes since commit 554623226f800acf48a2ed568900c1c968ec9a8b:
8
9
9
The following changes since commit c077a998eb3fcae2d048e3baeb5bc592d30fddde:
10
Merge tag 'qemu-sparc-20220508' of https://github.com/mcayland/qemu into staging (2022-05-08 17:03:26 -0500)
10
11
11
Merge remote-tracking branch 'remotes/riku/tags/pull-linux-user-20170531' into staging (2017-06-01 15:50:40 +0100)
12
are available in the Git repository at:
12
13
13
are available in the git repository at:
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220509
14
15
15
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20170601
16
for you to fetch changes up to ae9141d4a3265553503bf07d3574b40f84615a34:
16
17
17
for you to fetch changes up to cdc58be430b0bdeaef282e2e70f8135ae531616d:
18
hw/acpi/aml-build: Use existing CPU topology to build PPTT table (2022-05-09 11:47:55 +0100)
18
19
hw/arm/virt: fdt: generate distance-map when needed (2017-06-01 17:27:07 +0100)
20
19
21
----------------------------------------------------------------
20
----------------------------------------------------------------
22
target-arm queue:
21
target-arm queue:
23
* virt: numa: provide ACPI distance info when needed
22
* MAINTAINERS/.mailmap: update email for Leif Lindholm
24
* aspeed: fix i2c controller bugs
23
* hw/arm: add version information to sbsa-ref machine DT
25
* aspeed: add temperature sensor device
24
* Enable new features for -cpu max:
26
* M profile: support MPU
25
FEAT_Debugv8p2, FEAT_Debugv8p4, FEAT_RAS (minimal version only),
27
* gicv3: fix mishandling of BPR1, VBPR1
26
FEAT_IESB, FEAT_CSV2, FEAT_CSV2_2, FEAT_CSV3, FEAT_DGH
28
* load_uboot_image: don't assume a full header read
27
* Emulate Cortex-A76
29
* libvixl: Correct build failures on NetBSD
28
* Emulate Neoverse-N1
29
* Fix the virt board default NUMA topology
30
30
31
----------------------------------------------------------------
31
----------------------------------------------------------------
32
Andrew Jones (3):
32
Gavin Shan (6):
33
load_uboot_image: don't assume a full header read
33
qapi/machine.json: Add cluster-id
34
hw/arm/virt-acpi-build: build SLIT when needed
34
qtest/numa-test: Specify CPU topology in aarch64_numa_cpu()
35
hw/arm/virt: fdt: generate distance-map when needed
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
36
39
37
Cédric Le Goater (6):
40
Leif Lindholm (2):
38
aspeed/i2c: improve command handling
41
MAINTAINERS/.mailmap: update email for Leif Lindholm
39
aspeed/i2c: handle LAST command under the RX command
42
hw/arm: add versioning to sbsa-ref machine DT
40
aspeed/i2c: introduce a state machine
41
aspeed: add some I2C devices to the Aspeed machines
42
hw/misc: add a TMP42{1,2,3} device model
43
aspeed: add a temp sensor device on I2C bus 3
44
43
45
Kamil Rytarowski (1):
44
Richard Henderson (24):
46
libvixl: Correct build failures on NetBSD
45
target/arm: Handle cpreg registration for missing EL
46
target/arm: Drop EL3 no EL2 fallbacks
47
target/arm: Merge zcr reginfo
48
target/arm: Adjust definition of CONTEXTIDR_EL2
49
target/arm: Move cortex impdef sysregs to cpu_tcg.c
50
target/arm: Update qemu-system-arm -cpu max to cortex-a57
51
target/arm: Set ID_DFR0.PerfMon for qemu-system-arm -cpu max
52
target/arm: Split out aa32_max_features
53
target/arm: Annotate arm_max_initfn with FEAT identifiers
54
target/arm: Use field names for manipulating EL2 and EL3 modes
55
target/arm: Enable FEAT_Debugv8p2 for -cpu max
56
target/arm: Enable FEAT_Debugv8p4 for -cpu max
57
target/arm: Add minimal RAS registers
58
target/arm: Enable SCR and HCR bits for RAS
59
target/arm: Implement virtual SError exceptions
60
target/arm: Implement ESB instruction
61
target/arm: Enable FEAT_RAS for -cpu max
62
target/arm: Enable FEAT_IESB for -cpu max
63
target/arm: Enable FEAT_CSV2 for -cpu max
64
target/arm: Enable FEAT_CSV2_2 for -cpu max
65
target/arm: Enable FEAT_CSV3 for -cpu max
66
target/arm: Enable FEAT_DGH for -cpu max
67
target/arm: Define cortex-a76
68
target/arm: Define neoverse-n1
47
69
48
Michael Davidsaver (4):
70
docs/system/arm/emulation.rst | 10 +
49
armv7m: Improve "-d mmu" tracing for PMSAv7 MPU
71
docs/system/arm/virt.rst | 2 +
50
armv7m: Implement M profile default memory map
72
qapi/machine.json | 6 +-
51
armv7m: Classify faults as MemManage or BusFault
73
target/arm/cpregs.h | 11 +
52
arm: add MPU support to M profile CPUs
74
target/arm/cpu.h | 23 ++
53
75
target/arm/helper.h | 1 +
54
Peter Maydell (12):
76
target/arm/internals.h | 16 ++
55
hw/intc/arm_gicv3_cpuif: Fix reset value for VMCR_EL2.VBPR1
77
target/arm/syndrome.h | 5 +
56
hw/intc/arm_gicv3_cpuif: Don't let BPR be set below its minimum
78
target/arm/a32.decode | 16 +-
57
hw/intc/arm_gicv3_cpuif: Fix priority masking for NS BPR1
79
target/arm/t32.decode | 18 +-
58
arm: Use the mmu_idx we're passed in arm_cpu_do_unaligned_access()
80
hw/acpi/aml-build.c | 111 ++++----
59
arm: Add support for M profile CPUs having different MMU index semantics
81
hw/arm/sbsa-ref.c | 16 ++
60
arm: Use different ARMMMUIdx values for M profile
82
hw/arm/virt.c | 21 +-
61
arm: Clean up handling of no-MPU PMSA CPUs
83
hw/core/machine-hmp-cmds.c | 4 +
62
arm: Don't clear ARM_FEATURE_PMSA for no-mpu configs
84
hw/core/machine.c | 16 ++
63
arm: Don't let no-MPU PMSA cores write to SCTLR.M
85
target/arm/cpu.c | 66 ++++-
64
arm: Remove unnecessary check on cpu->pmsav7_dregion
86
target/arm/cpu64.c | 353 ++++++++++++++-----------
65
arm: All M profile cores are PMSA
87
target/arm/cpu_tcg.c | 227 +++++++++++-----
66
arm: Implement HFNMIENA support for M profile MPU
88
target/arm/helper.c | 600 +++++++++++++++++++++++++-----------------
67
89
target/arm/op_helper.c | 43 +++
68
Wei Huang (1):
90
target/arm/translate-a64.c | 18 ++
69
target/arm: clear PMUVER field of AA64DFR0 when vPMU=off
91
target/arm/translate.c | 23 ++
70
92
tests/qtest/numa-test.c | 19 +-
71
disas/libvixl/Makefile.objs | 3 +
93
.mailmap | 3 +-
72
hw/misc/Makefile.objs | 1 +
94
MAINTAINERS | 2 +-
73
target/arm/cpu.h | 118 ++++++++++--
95
25 files changed, 1068 insertions(+), 562 deletions(-)
74
target/arm/translate.h | 2 +-
75
hw/arm/aspeed.c | 36 ++++
76
hw/arm/virt-acpi-build.c | 4 +
77
hw/arm/virt.c | 21 +++
78
hw/core/loader.c | 3 +-
79
hw/i2c/aspeed_i2c.c | 65 ++++++-
80
hw/intc/arm_gicv3_cpuif.c | 50 ++++-
81
hw/intc/armv7m_nvic.c | 104 +++++++++++
82
hw/misc/tmp421.c | 401 ++++++++++++++++++++++++++++++++++++++++
83
target/arm/cpu.c | 28 ++-
84
target/arm/helper.c | 338 ++++++++++++++++++++++-----------
85
target/arm/machine.c | 7 +-
86
target/arm/op_helper.c | 3 +-
87
target/arm/translate-a64.c | 18 +-
88
target/arm/translate.c | 14 +-
89
default-configs/arm-softmmu.mak | 1 +
90
19 files changed, 1060 insertions(+), 157 deletions(-)
91
create mode 100644 hw/misc/tmp421.c
92
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
2
3
Temperatures can be changed from the monitor with :
3
NUVIA was acquired by Qualcomm in March 2021, but kept functioning on
4
separate infrastructure for a transitional period. We've now switched
5
over to contributing as Qualcomm Innovation Center (quicinc), so update
6
my email address to reflect this.
4
7
5
    (qemu) qom-set /machine/unattached/device[2] temperature0 12000
8
Signed-off-by: Leif Lindholm <quic_llindhol@quicinc.com>
9
Message-id: 20220505113740.75565-1-quic_llindhol@quicinc.com
10
Cc: Leif Lindholm <leif@nuviainc.com>
11
Cc: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
[Fixed commit message typo]
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
.mailmap | 3 ++-
17
MAINTAINERS | 2 +-
18
2 files changed, 3 insertions(+), 2 deletions(-)
6
19
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
20
diff --git a/.mailmap b/.mailmap
8
Message-id: 1494827476-1487-7-git-send-email-clg@kaod.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/aspeed.c | 9 +++++++++
13
1 file changed, 9 insertions(+)
14
15
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/aspeed.c
22
--- a/.mailmap
18
+++ b/hw/arm/aspeed.c
23
+++ b/.mailmap
19
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
24
@@ -XXX,XX +XXX,XX @@ Greg Kurz <groug@kaod.org> <gkurz@linux.vnet.ibm.com>
20
static void palmetto_bmc_i2c_init(AspeedBoardState *bmc)
25
Huacai Chen <chenhuacai@kernel.org> <chenhc@lemote.com>
21
{
26
Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
22
AspeedSoCState *soc = &bmc->soc;
27
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
23
+ DeviceState *dev;
28
-Leif Lindholm <leif@nuviainc.com> <leif.lindholm@linaro.org>
24
29
+Leif Lindholm <quic_llindhol@quicinc.com> <leif.lindholm@linaro.org>
25
/* The palmetto platform expects a ds3231 RTC but a ds1338 is
30
+Leif Lindholm <quic_llindhol@quicinc.com> <leif@nuviainc.com>
26
* enough to provide basic RTC features. Alarms will be missing */
31
Radoslaw Biernacki <rad@semihalf.com> <radoslaw.biernacki@linaro.org>
27
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 0), "ds1338", 0x68);
32
Paul Burton <paulburton@kernel.org> <paul.burton@mips.com>
28
+
33
Paul Burton <paulburton@kernel.org> <paul.burton@imgtec.com>
29
+ /* add a TMP423 temperature sensor */
34
diff --git a/MAINTAINERS b/MAINTAINERS
30
+ dev = i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 2),
35
index XXXXXXX..XXXXXXX 100644
31
+ "tmp423", 0x4c);
36
--- a/MAINTAINERS
32
+ object_property_set_int(OBJECT(dev), 31000, "temperature0", &error_abort);
37
+++ b/MAINTAINERS
33
+ object_property_set_int(OBJECT(dev), 28000, "temperature1", &error_abort);
38
@@ -XXX,XX +XXX,XX @@ F: include/hw/ssi/imx_spi.h
34
+ object_property_set_int(OBJECT(dev), 20000, "temperature2", &error_abort);
39
SBSA-REF
35
+ object_property_set_int(OBJECT(dev), 110000, "temperature3", &error_abort);
40
M: Radoslaw Biernacki <rad@semihalf.com>
36
}
41
M: Peter Maydell <peter.maydell@linaro.org>
37
42
-R: Leif Lindholm <leif@nuviainc.com>
38
static void palmetto_bmc_init(MachineState *machine)
43
+R: Leif Lindholm <quic_llindhol@quicinc.com>
44
L: qemu-arm@nongnu.org
45
S: Maintained
46
F: hw/arm/sbsa-ref.c
39
--
47
--
40
2.7.4
48
2.25.1
41
49
42
50
diff view generated by jsdifflib
1
If the CPU is a PMSA config with no MPU implemented, then the
1
From: Richard Henderson <richard.henderson@linaro.org>
2
SCTLR.M bit should be RAZ/WI, so that the guest can never
2
3
turn on the non-existent MPU.
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
If the reg is for EL2, and EL3 is present but EL2 is not,
6
either discard, squash to res0, const, or keep unchanged.
7
8
Per rule RJFFP, mark the 4 aarch32 hypervisor access registers
9
with ARM_CP_EL3_NO_EL2_KEEP, and mark all of the EL2 address
10
translation and tlb invalidation "regs" ARM_CP_EL3_NO_EL2_UNDEF.
11
Mark the 2 virtualization processor id regs ARM_CP_EL3_NO_EL2_C_NZ.
12
13
This will simplify cpreg registration for conditional arm features.
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
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 1493122030-32191-7-git-send-email-peter.maydell@linaro.org
9
---
19
---
10
target/arm/helper.c | 5 +++++
20
target/arm/cpregs.h | 11 +++
11
1 file changed, 5 insertions(+)
21
target/arm/helper.c | 178 ++++++++++++++++++++++++++++++--------------
12
22
2 files changed, 133 insertions(+), 56 deletions(-)
23
24
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/cpregs.h
27
+++ b/target/arm/cpregs.h
28
@@ -XXX,XX +XXX,XX @@ enum {
29
ARM_CP_SVE = 1 << 14,
30
/* Flag: Do not expose in gdb sysreg xml. */
31
ARM_CP_NO_GDB = 1 << 15,
32
+ /*
33
+ * Flags: If EL3 but not EL2...
34
+ * - UNDEF: discard the cpreg,
35
+ * - KEEP: retain the cpreg as is,
36
+ * - C_NZ: set const on the cpreg, but retain resetvalue,
37
+ * - else: set const on the cpreg, zero resetvalue, aka RES0.
38
+ * See rule RJFFP in section D1.1.3 of DDI0487H.a.
39
+ */
40
+ ARM_CP_EL3_NO_EL2_UNDEF = 1 << 16,
41
+ ARM_CP_EL3_NO_EL2_KEEP = 1 << 17,
42
+ ARM_CP_EL3_NO_EL2_C_NZ = 1 << 18,
43
};
44
45
/*
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
46
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
48
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
49
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
50
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
18
return;
51
.access = PL1_RW, .readfn = spsel_read, .writefn = spsel_write },
52
{ .name = "FPEXC32_EL2", .state = ARM_CP_STATE_AA64,
53
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 3, .opc2 = 0,
54
- .access = PL2_RW, .type = ARM_CP_ALIAS | ARM_CP_FPU,
55
+ .access = PL2_RW,
56
+ .type = ARM_CP_ALIAS | ARM_CP_FPU | ARM_CP_EL3_NO_EL2_KEEP,
57
.fieldoffset = offsetof(CPUARMState, vfp.xregs[ARM_VFP_FPEXC]) },
58
{ .name = "DACR32_EL2", .state = ARM_CP_STATE_AA64,
59
.opc0 = 3, .opc1 = 4, .crn = 3, .crm = 0, .opc2 = 0,
60
- .access = PL2_RW, .resetvalue = 0,
61
+ .access = PL2_RW, .resetvalue = 0, .type = ARM_CP_EL3_NO_EL2_KEEP,
62
.writefn = dacr_write, .raw_writefn = raw_write,
63
.fieldoffset = offsetof(CPUARMState, cp15.dacr32_el2) },
64
{ .name = "IFSR32_EL2", .state = ARM_CP_STATE_AA64,
65
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 0, .opc2 = 1,
66
- .access = PL2_RW, .resetvalue = 0,
67
+ .access = PL2_RW, .resetvalue = 0, .type = ARM_CP_EL3_NO_EL2_KEEP,
68
.fieldoffset = offsetof(CPUARMState, cp15.ifsr32_el2) },
69
{ .name = "SPSR_IRQ", .state = ARM_CP_STATE_AA64,
70
.type = ARM_CP_ALIAS,
71
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
72
.writefn = tlbimva_hyp_is_write },
73
{ .name = "TLBI_ALLE2", .state = ARM_CP_STATE_AA64,
74
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0,
75
- .type = ARM_CP_NO_RAW, .access = PL2_W,
76
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
77
.writefn = tlbi_aa64_alle2_write },
78
{ .name = "TLBI_VAE2", .state = ARM_CP_STATE_AA64,
79
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1,
80
- .type = ARM_CP_NO_RAW, .access = PL2_W,
81
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
82
.writefn = tlbi_aa64_vae2_write },
83
{ .name = "TLBI_VALE2", .state = ARM_CP_STATE_AA64,
84
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5,
85
- .access = PL2_W, .type = ARM_CP_NO_RAW,
86
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
87
.writefn = tlbi_aa64_vae2_write },
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
}
19
}
238
}
20
239
21
+ if (arm_feature(env, ARM_FEATURE_PMSA) && !cpu->has_mpu) {
240
+ /*
22
+ /* M bit is RAZ/WI for PMSA with no MPU implemented */
241
+ * Eliminate registers that are not present because the EL is missing.
23
+ value &= ~SCTLR_M;
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)) {
247
+ /*
248
+ * An EL2 register without EL2 but with EL3 is (usually) RES0.
249
+ * See rule RJFFP in section D1.1.3 of DDI0487H.a.
250
+ */
251
+ int min_el = ctz32(r->access) / 2;
252
+ if (min_el == 2 && !arm_feature(env, ARM_FEATURE_EL2)) {
253
+ if (r->type & ARM_CP_EL3_NO_EL2_UNDEF) {
254
+ return;
255
+ }
256
+ make_const = !(r->type & ARM_CP_EL3_NO_EL2_KEEP);
257
+ }
258
+ } else {
259
+ CPAccessRights max_el = (arm_feature(env, ARM_FEATURE_EL2)
260
+ ? PL2_RW : PL1_RW);
261
+ if ((r->access & max_el) == 0) {
262
+ return;
263
+ }
24
+ }
264
+ }
25
+
265
+
26
raw_write(env, ri, value);
266
/* Combine cpreg and name into one allocation. */
27
/* ??? Lots of these bits are not implemented. */
267
name_len = strlen(name) + 1;
28
/* This may enable/disable the MMU, so do a TLB flush. */
268
r2 = g_malloc(sizeof(*r2) + name_len);
269
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
270
r2->opaque = opaque;
271
}
272
273
- isbanked = r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1];
274
- if (isbanked) {
275
+ if (make_const) {
276
+ /* This should not have been a very special register to begin. */
277
+ int old_special = r2->type & ARM_CP_SPECIAL_MASK;
278
+ assert(old_special == 0 || old_special == ARM_CP_NOP);
279
/*
280
- * Register is banked (using both entries in array).
281
- * Overwriting fieldoffset as the array is only used to define
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;
311
+ } else {
312
+ bool isbanked = r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1];
313
314
- if (state == ARM_CP_STATE_AA32) {
315
if (isbanked) {
316
/*
317
- * If the register is banked then we don't need to migrate or
318
- * reset the 32-bit instance in certain cases:
319
- *
320
- * 1) If the register has both 32-bit and 64-bit instances then we
321
- * can count on the 64-bit instance taking care of the
322
- * non-secure bank.
323
- * 2) If ARMv8 is enabled then we can count on a 64-bit version
324
- * taking care of the secure bank. This requires that separate
325
- * 32 and 64-bit definitions are provided.
326
+ * Register is banked (using both entries in array).
327
+ * Overwriting fieldoffset as the array is only used to define
328
+ * banked registers but later only fieldoffset is used.
329
*/
330
- if ((r->state == ARM_CP_STATE_BOTH && ns) ||
331
- (arm_feature(&cpu->env, ARM_FEATURE_V8) && !ns)) {
332
+ r2->fieldoffset = r->bank_fieldoffsets[ns];
333
+ }
334
+ if (state == ARM_CP_STATE_AA32) {
335
+ if (isbanked) {
336
+ /*
337
+ * If the register is banked then we don't need to migrate or
338
+ * reset the 32-bit instance in certain cases:
339
+ *
340
+ * 1) If the register has both 32-bit and 64-bit instances
341
+ * then we can count on the 64-bit instance taking care
342
+ * of the non-secure bank.
343
+ * 2) If ARMv8 is enabled then we can count on a 64-bit
344
+ * version taking care of the secure bank. This requires
345
+ * that separate 32 and 64-bit definitions are provided.
346
+ */
347
+ if ((r->state == ARM_CP_STATE_BOTH && ns) ||
348
+ (arm_feature(env, ARM_FEATURE_V8) && !ns)) {
349
+ r2->type |= ARM_CP_ALIAS;
350
+ }
351
+ } else if ((secstate != r->secure) && !ns) {
352
+ /*
353
+ * The register is not banked so we only want to allow
354
+ * migration of the non-secure instance.
355
+ */
356
r2->type |= ARM_CP_ALIAS;
357
}
358
- } else if ((secstate != r->secure) && !ns) {
359
- /*
360
- * The register is not banked so we only want to allow migration
361
- * of the non-secure instance.
362
- */
363
- r2->type |= ARM_CP_ALIAS;
364
- }
365
366
- if (HOST_BIG_ENDIAN &&
367
- r->state == ARM_CP_STATE_BOTH && r2->fieldoffset) {
368
- r2->fieldoffset += sizeof(uint32_t);
369
+ if (HOST_BIG_ENDIAN &&
370
+ r->state == ARM_CP_STATE_BOTH && r2->fieldoffset) {
371
+ r2->fieldoffset += sizeof(uint32_t);
372
+ }
373
}
374
}
375
376
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
377
* multiple times. Special registers (ie NOP/WFI) are
378
* never migratable and not even raw-accessible.
379
*/
380
- if (r->type & ARM_CP_SPECIAL_MASK) {
381
+ if (r2->type & ARM_CP_SPECIAL_MASK) {
382
r2->type |= ARM_CP_NO_RAW;
383
}
384
if (((r->crm == CP_ANY) && crm != 0) ||
29
--
385
--
30
2.7.4
386
2.25.1
31
32
diff view generated by jsdifflib
1
From: Michael Davidsaver <mdavidsaver@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add support for the M profile default memory map which is used
3
Drop el3_no_el2_cp_reginfo, el3_no_el2_v8_cp_reginfo, and the local
4
if the MPU is not present or disabled.
4
vpidr_regs definition, and rely on the squashing to ARM_CP_CONST
5
5
while registering for v8.
6
The main differences in behaviour from implementing this
6
7
correctly are that we set the PAGE_EXEC attribute on
7
This is a behavior change for v7 cpus with Security Extensions and
8
the right regions of memory, such that device regions
8
without Virtualization Extensions, in that the virtualization cpregs
9
are not executable.
9
are now correctly not present. This would be a migration compatibility
10
10
break, except that we have an existing bug in which migration of 32-bit
11
Signed-off-by: Michael Davidsaver <mdavidsaver@gmail.com>
11
cpus with Security Extensions enabled does not work.
12
Message-id: 1493122030-32191-10-git-send-email-peter.maydell@linaro.org
12
13
[PMM: rephrased comment and commit message; don't mark
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
the flash memory region as not-writable; list all
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
the cases in the default map explicitly rather than
15
Message-id: 20220506180242.216785-3-richard.henderson@linaro.org
16
using a 'default' case for the non-executable regions]
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
17
---
19
target/arm/helper.c | 41 ++++++++++++++++++++++++++++++++---------
18
target/arm/helper.c | 158 ++++----------------------------------------
20
1 file changed, 32 insertions(+), 9 deletions(-)
19
1 file changed, 13 insertions(+), 145 deletions(-)
21
20
22
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
23
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/helper.c
23
--- a/target/arm/helper.c
25
+++ b/target/arm/helper.c
24
+++ b/target/arm/helper.c
26
@@ -XXX,XX +XXX,XX @@ static inline void get_phys_addr_pmsav7_default(CPUARMState *env,
25
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
27
ARMMMUIdx mmu_idx,
26
.fieldoffset = offsetoflow32(CPUARMState, cp15.mdcr_el3) },
28
int32_t address, int *prot)
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)
29
{
148
{
30
- *prot = PAGE_READ | PAGE_WRITE;
149
ARMCPU *cpu = env_archcpu(env);
31
- switch (address) {
150
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
32
- case 0xF0000000 ... 0xFFFFFFFF:
151
define_arm_cp_regs(cpu, v8_idregs);
33
- if (regime_sctlr(env, mmu_idx) & SCTLR_V) { /* hivecs execing is ok */
152
define_arm_cp_regs(cpu, v8_cp_reginfo);
34
+ if (!arm_feature(env, ARM_FEATURE_M)) {
153
}
35
+ *prot = PAGE_READ | PAGE_WRITE;
154
- if (arm_feature(env, ARM_FEATURE_EL2)) {
36
+ switch (address) {
155
+
37
+ case 0xF0000000 ... 0xFFFFFFFF:
156
+ /*
38
+ if (regime_sctlr(env, mmu_idx) & SCTLR_V) {
157
+ * Register the base EL2 cpregs.
39
+ /* hivecs execing is ok */
158
+ * Pre v8, these registers are implemented only as part of the
40
+ *prot |= PAGE_EXEC;
159
+ * Virtualization Extensions (EL2 present). Beginning with v8,
41
+ }
160
+ * if EL2 is missing but EL3 is enabled, mostly these become
42
+ break;
161
+ * RES0 from EL3, with some specific exceptions.
43
+ case 0x00000000 ... 0x7FFFFFFF:
162
+ */
44
*prot |= PAGE_EXEC;
163
+ if (arm_feature(env, ARM_FEATURE_EL2)
45
+ break;
164
+ || (arm_feature(env, ARM_FEATURE_EL3)
46
+ }
165
+ && arm_feature(env, ARM_FEATURE_V8))) {
47
+ } else {
166
uint64_t vmpidr_def = mpidr_read_val(env);
48
+ /* Default system address map for M profile cores.
167
ARMCPRegInfo vpidr_regs[] = {
49
+ * The architecture specifies which regions are execute-never;
168
{ .name = "VPIDR", .state = ARM_CP_STATE_AA32,
50
+ * at the MPU level no other checks are defined.
169
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
51
+ */
170
};
52
+ switch (address) {
171
define_one_arm_cp_reg(cpu, &rvbar);
53
+ case 0x00000000 ... 0x1fffffff: /* ROM */
54
+ case 0x20000000 ... 0x3fffffff: /* SRAM */
55
+ case 0x60000000 ... 0x7fffffff: /* RAM */
56
+ case 0x80000000 ... 0x9fffffff: /* RAM */
57
+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
58
+ break;
59
+ case 0x40000000 ... 0x5fffffff: /* Peripheral */
60
+ case 0xa0000000 ... 0xbfffffff: /* Device */
61
+ case 0xc0000000 ... 0xdfffffff: /* Device */
62
+ case 0xe0000000 ... 0xffffffff: /* System */
63
+ *prot = PAGE_READ | PAGE_WRITE;
64
+ break;
65
+ default:
66
+ g_assert_not_reached();
67
}
172
}
68
- break;
173
- } else {
69
- case 0x00000000 ... 0x7FFFFFFF:
174
- /* If EL2 is missing but higher ELs are enabled, we need to
70
- *prot |= PAGE_EXEC;
175
- * register the no_el2 reginfos.
71
- break;
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
- }
72
}
199
}
73
-
200
+
74
}
201
+ /* Register the base EL3 cpregs. */
75
202
if (arm_feature(env, ARM_FEATURE_EL3)) {
76
static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
203
define_arm_cp_regs(cpu, el3_cp_reginfo);
204
ARMCPRegInfo el3_regs[] = {
77
--
205
--
78
2.7.4
206
2.25.1
79
80
diff view generated by jsdifflib
1
From: Michael Davidsaver <mdavidsaver@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
General logic is that operations stopped by the MPU are MemManage,
3
Drop zcr_no_el2_reginfo and merge the 3 registers into one array,
4
and those which go through the MPU and are caught by the unassigned
4
now that ZCR_EL2 can be squashed to RES0 and ZCR_EL3 dropped
5
handle are BusFault. Distinguish these by looking at the
5
while registering.
6
exception.fsr values, and set the CFSR bits and (if appropriate)
7
fill in the BFAR or MMFAR with the exception address.
8
6
9
Signed-off-by: Michael Davidsaver <mdavidsaver@gmail.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 1493122030-32191-12-git-send-email-peter.maydell@linaro.org
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
[PMM: i-side faults do not set BFAR/MMFAR, only d-side;
9
Message-id: 20220506180242.216785-4-richard.henderson@linaro.org
12
added some CPU_LOG_INT logging]
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
---
11
---
16
target/arm/helper.c | 45 ++++++++++++++++++++++++++++++++++++++++++---
12
target/arm/helper.c | 55 ++++++++++++++-------------------------------
17
1 file changed, 42 insertions(+), 3 deletions(-)
13
1 file changed, 17 insertions(+), 38 deletions(-)
18
14
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
17
--- a/target/arm/helper.c
22
+++ b/target/arm/helper.c
18
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
19
@@ -XXX,XX +XXX,XX @@ static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
24
break;
20
}
25
case EXCP_PREFETCH_ABORT:
21
}
26
case EXCP_DATA_ABORT:
22
27
- /* TODO: if we implemented the MPU registers, this is where we
23
-static const ARMCPRegInfo zcr_el1_reginfo = {
28
- * should set the MMFAR, etc from exception.fsr and exception.vaddress.
24
- .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
29
+ /* Note that for M profile we don't have a guest facing FSR, but
25
- .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
30
+ * the env->exception.fsr will be populated by the code that
26
- .access = PL1_RW, .type = ARM_CP_SVE,
31
+ * raises the fault, in the A profile short-descriptor format.
27
- .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
32
*/
28
- .writefn = zcr_write, .raw_writefn = raw_write
33
- armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM);
29
-};
34
+ switch (env->exception.fsr & 0xf) {
30
-
35
+ case 0x8: /* External Abort */
31
-static const ARMCPRegInfo zcr_el2_reginfo = {
36
+ switch (cs->exception_index) {
32
- .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
37
+ case EXCP_PREFETCH_ABORT:
33
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
38
+ env->v7m.cfsr |= R_V7M_CFSR_PRECISERR_MASK;
34
- .access = PL2_RW, .type = ARM_CP_SVE,
39
+ qemu_log_mask(CPU_LOG_INT, "...with CFSR.PRECISERR\n");
35
- .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
40
+ break;
36
- .writefn = zcr_write, .raw_writefn = raw_write
41
+ case EXCP_DATA_ABORT:
37
-};
42
+ env->v7m.cfsr |=
38
-
43
+ (R_V7M_CFSR_IBUSERR_MASK | R_V7M_CFSR_BFARVALID_MASK);
39
-static const ARMCPRegInfo zcr_no_el2_reginfo = {
44
+ env->v7m.bfar = env->exception.vaddress;
40
- .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
45
+ qemu_log_mask(CPU_LOG_INT,
41
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
46
+ "...with CFSR.IBUSERR and BFAR 0x%x\n",
42
- .access = PL2_RW, .type = ARM_CP_SVE,
47
+ env->v7m.bfar);
43
- .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore
48
+ break;
44
-};
49
+ }
45
-
50
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS);
46
-static const ARMCPRegInfo zcr_el3_reginfo = {
51
+ break;
47
- .name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
52
+ default:
48
- .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
53
+ /* All other FSR values are either MPU faults or "can't happen
49
- .access = PL3_RW, .type = ARM_CP_SVE,
54
+ * for M profile" cases.
50
- .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
55
+ */
51
- .writefn = zcr_write, .raw_writefn = raw_write
56
+ switch (cs->exception_index) {
52
+static const ARMCPRegInfo zcr_reginfo[] = {
57
+ case EXCP_PREFETCH_ABORT:
53
+ { .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
58
+ env->v7m.cfsr |= R_V7M_CFSR_IACCVIOL_MASK;
54
+ .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
59
+ qemu_log_mask(CPU_LOG_INT, "...with CFSR.IACCVIOL\n");
55
+ .access = PL1_RW, .type = ARM_CP_SVE,
60
+ break;
56
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
61
+ case EXCP_DATA_ABORT:
57
+ .writefn = zcr_write, .raw_writefn = raw_write },
62
+ env->v7m.cfsr |=
58
+ { .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
63
+ (R_V7M_CFSR_DACCVIOL_MASK | R_V7M_CFSR_MMARVALID_MASK);
59
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
64
+ env->v7m.mmfar = env->exception.vaddress;
60
+ .access = PL2_RW, .type = ARM_CP_SVE,
65
+ qemu_log_mask(CPU_LOG_INT,
61
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
66
+ "...with CFSR.DACCVIOL and MMFAR 0x%x\n",
62
+ .writefn = zcr_write, .raw_writefn = raw_write },
67
+ env->v7m.mmfar);
63
+ { .name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
68
+ break;
64
+ .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
69
+ }
65
+ .access = PL3_RW, .type = ARM_CP_SVE,
70
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM);
66
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
71
+ break;
67
+ .writefn = zcr_write, .raw_writefn = raw_write },
72
+ }
68
};
73
break;
69
74
case EXCP_BKPT:
70
void hw_watchpoint_update(ARMCPU *cpu, int n)
75
if (semihosting_enabled()) {
71
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
72
}
73
74
if (cpu_isar_feature(aa64_sve, cpu)) {
75
- define_one_arm_cp_reg(cpu, &zcr_el1_reginfo);
76
- if (arm_feature(env, ARM_FEATURE_EL2)) {
77
- define_one_arm_cp_reg(cpu, &zcr_el2_reginfo);
78
- } else {
79
- define_one_arm_cp_reg(cpu, &zcr_no_el2_reginfo);
80
- }
81
- if (arm_feature(env, ARM_FEATURE_EL3)) {
82
- define_one_arm_cp_reg(cpu, &zcr_el3_reginfo);
83
- }
84
+ define_arm_cp_regs(cpu, zcr_reginfo);
85
}
86
87
#ifdef TARGET_AARCH64
76
--
88
--
77
2.7.4
89
2.25.1
78
79
diff view generated by jsdifflib
1
Now that we enforce both:
1
From: Richard Henderson <richard.henderson@linaro.org>
2
* pmsav7_dregion == 0 implies has_mpu == false
3
* PMSA with has_mpu == false means SCTLR.M cannot be set
4
we can remove a check on pmsav7_dregion from get_phys_addr_pmsav7(),
5
because we can only reach this code path if the MPU is enabled
6
(and so region_translation_disabled() returned false).
7
2
3
This register is present for either VHE or Debugv8p2.
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-5-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 1493122030-32191-8-git-send-email-peter.maydell@linaro.org
11
---
9
---
12
target/arm/helper.c | 3 +--
10
target/arm/helper.c | 15 +++++++++++----
13
1 file changed, 1 insertion(+), 2 deletions(-)
11
1 file changed, 11 insertions(+), 4 deletions(-)
14
12
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
15
--- a/target/arm/helper.c
18
+++ b/target/arm/helper.c
16
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
17
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo jazelle_regs[] = {
20
}
18
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
21
19
};
22
if (n == -1) { /* no hits */
20
23
- if (cpu->pmsav7_dregion &&
21
+static const ARMCPRegInfo contextidr_el2 = {
24
- (is_user || !(regime_sctlr(env, mmu_idx) & SCTLR_BR))) {
22
+ .name = "CONTEXTIDR_EL2", .state = ARM_CP_STATE_AA64,
25
+ if (is_user || !(regime_sctlr(env, mmu_idx) & SCTLR_BR)) {
23
+ .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 1,
26
/* background fault */
24
+ .access = PL2_RW,
27
*fsr = 0;
25
+ .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[2])
28
return true;
26
+};
27
+
28
static const ARMCPRegInfo vhe_reginfo[] = {
29
- { .name = "CONTEXTIDR_EL2", .state = ARM_CP_STATE_AA64,
30
- .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 1,
31
- .access = PL2_RW,
32
- .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[2]) },
33
{ .name = "TTBR1_EL2", .state = ARM_CP_STATE_AA64,
34
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 1,
35
.access = PL2_RW, .writefn = vmsa_tcr_ttbr_el2_write,
36
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
37
define_one_arm_cp_reg(cpu, &ssbs_reginfo);
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);
46
}
29
--
47
--
30
2.7.4
48
2.25.1
31
32
diff view generated by jsdifflib
1
When we calculate the mask to use to get the group priority from
1
From: Richard Henderson <richard.henderson@linaro.org>
2
an interrupt priority, the way that NS BPR1 is handled differs
2
3
from how BPR0 and S BPR1 work -- a BPR1 value of 1 means
3
Previously we were defining some of these in user-only mode,
4
the group priority is in bits [7:1], whereas for BPR0 and S BPR1
4
but none of them are accessible from user-only, therefore
5
this is indicated by a 0 BPR value.
5
define them only in system mode.
6
6
7
Subtract 1 from the BPR value before creating the mask if
7
This will shortly be used from cpu_tcg.c also.
8
we're using the NS BPR value, for both hardware and virtual
8
9
interrupts, as the GICv3 pseudocode does, and fix the comments
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
accordingly.
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
11
Message-id: 20220506180242.216785-6-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 1493226792-3237-4-git-send-email-peter.maydell@linaro.org
15
---
13
---
16
hw/intc/arm_gicv3_cpuif.c | 42 ++++++++++++++++++++++++++++++++++++++----
14
target/arm/internals.h | 6 ++++
17
1 file changed, 38 insertions(+), 4 deletions(-)
15
target/arm/cpu64.c | 64 +++---------------------------------------
18
16
target/arm/cpu_tcg.c | 59 ++++++++++++++++++++++++++++++++++++++
19
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
17
3 files changed, 69 insertions(+), 60 deletions(-)
18
19
diff --git a/target/arm/internals.h b/target/arm/internals.h
20
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/intc/arm_gicv3_cpuif.c
21
--- a/target/arm/internals.h
22
+++ b/hw/intc/arm_gicv3_cpuif.c
22
+++ b/target/arm/internals.h
23
@@ -XXX,XX +XXX,XX @@ static uint32_t icv_gprio_mask(GICv3CPUState *cs, int group)
23
@@ -XXX,XX +XXX,XX @@ int aarch64_fpu_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg);
24
int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg);
25
#endif
26
27
+#ifdef CONFIG_USER_ONLY
28
+static inline void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu) { }
29
+#else
30
+void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu);
31
+#endif
32
+
33
#endif
34
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/cpu64.c
37
+++ b/target/arm/cpu64.c
38
@@ -XXX,XX +XXX,XX @@
39
#include "hvf_arm.h"
40
#include "qapi/visitor.h"
41
#include "hw/qdev-properties.h"
42
-#include "cpregs.h"
43
+#include "internals.h"
44
45
46
-#ifndef CONFIG_USER_ONLY
47
-static uint64_t a57_a53_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
48
-{
49
- ARMCPU *cpu = env_archcpu(env);
50
-
51
- /* Number of cores is in [25:24]; otherwise we RAZ */
52
- return (cpu->core_count - 1) << 24;
53
-}
54
-#endif
55
-
56
-static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = {
57
-#ifndef CONFIG_USER_ONLY
58
- { .name = "L2CTLR_EL1", .state = ARM_CP_STATE_AA64,
59
- .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 2,
60
- .access = PL1_RW, .readfn = a57_a53_l2ctlr_read,
61
- .writefn = arm_cp_write_ignore },
62
- { .name = "L2CTLR",
63
- .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 2,
64
- .access = PL1_RW, .readfn = a57_a53_l2ctlr_read,
65
- .writefn = arm_cp_write_ignore },
66
-#endif
67
- { .name = "L2ECTLR_EL1", .state = ARM_CP_STATE_AA64,
68
- .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 3,
69
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
70
- { .name = "L2ECTLR",
71
- .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 3,
72
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
73
- { .name = "L2ACTLR", .state = ARM_CP_STATE_BOTH,
74
- .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 0, .opc2 = 0,
75
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
76
- { .name = "CPUACTLR_EL1", .state = ARM_CP_STATE_AA64,
77
- .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 0,
78
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
79
- { .name = "CPUACTLR",
80
- .cp = 15, .opc1 = 0, .crm = 15,
81
- .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
82
- { .name = "CPUECTLR_EL1", .state = ARM_CP_STATE_AA64,
83
- .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 1,
84
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
85
- { .name = "CPUECTLR",
86
- .cp = 15, .opc1 = 1, .crm = 15,
87
- .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
88
- { .name = "CPUMERRSR_EL1", .state = ARM_CP_STATE_AA64,
89
- .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 2,
90
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
91
- { .name = "CPUMERRSR",
92
- .cp = 15, .opc1 = 2, .crm = 15,
93
- .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
94
- { .name = "L2MERRSR_EL1", .state = ARM_CP_STATE_AA64,
95
- .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 3,
96
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
97
- { .name = "L2MERRSR",
98
- .cp = 15, .opc1 = 3, .crm = 15,
99
- .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
100
-};
101
-
102
static void aarch64_a57_initfn(Object *obj)
24
{
103
{
25
/* Return a mask word which clears the subpriority bits from
104
ARMCPU *cpu = ARM_CPU(obj);
26
* a priority value for a virtual interrupt in the specified group.
105
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
27
- * This depends on the VBPR value:
106
cpu->gic_num_lrs = 4;
28
+ * This depends on the VBPR value.
107
cpu->gic_vpribits = 5;
29
+ * If using VBPR0 then:
108
cpu->gic_vprebits = 5;
30
* a BPR of 0 means the group priority bits are [7:1];
109
- define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
31
* a BPR of 1 means they are [7:2], and so on down to
110
+ define_cortex_a72_a57_a53_cp_reginfo(cpu);
32
* a BPR of 7 meaning no group priority bits at all.
33
+ * If using VBPR1 then:
34
+ * a BPR of 0 is impossible (the minimum value is 1)
35
+ * a BPR of 1 means the group priority bits are [7:1];
36
+ * a BPR of 2 means they are [7:2], and so on down to
37
+ * a BPR of 7 meaning the group priority is [7].
38
+ *
39
* Which BPR to use depends on the group of the interrupt and
40
* the current ICH_VMCR_EL2.VCBPR settings.
41
+ *
42
+ * This corresponds to the VGroupBits() pseudocode.
43
*/
44
+ int bpr;
45
+
46
if (group == GICV3_G1NS && cs->ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR) {
47
group = GICV3_G0;
48
}
49
50
- return ~0U << (read_vbpr(cs, group) + 1);
51
+ bpr = read_vbpr(cs, group);
52
+ if (group == GICV3_G1NS) {
53
+ assert(bpr > 0);
54
+ bpr--;
55
+ }
56
+
57
+ return ~0U << (bpr + 1);
58
}
111
}
59
112
60
static bool icv_hppi_can_preempt(GICv3CPUState *cs, uint64_t lr)
113
static void aarch64_a53_initfn(Object *obj)
61
@@ -XXX,XX +XXX,XX @@ static uint32_t icc_gprio_mask(GICv3CPUState *cs, int group)
114
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
62
{
115
cpu->gic_num_lrs = 4;
63
/* Return a mask word which clears the subpriority bits from
116
cpu->gic_vpribits = 5;
64
* a priority value for an interrupt in the specified group.
117
cpu->gic_vprebits = 5;
65
- * This depends on the BPR value:
118
- define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
66
+ * This depends on the BPR value. For CBPR0 (S or NS):
119
+ define_cortex_a72_a57_a53_cp_reginfo(cpu);
67
* a BPR of 0 means the group priority bits are [7:1];
68
* a BPR of 1 means they are [7:2], and so on down to
69
* a BPR of 7 meaning no group priority bits at all.
70
+ * For CBPR1 NS:
71
+ * a BPR of 0 is impossible (the minimum value is 1)
72
+ * a BPR of 1 means the group priority bits are [7:1];
73
+ * a BPR of 2 means they are [7:2], and so on down to
74
+ * a BPR of 7 meaning the group priority is [7].
75
+ *
76
* Which BPR to use depends on the group of the interrupt and
77
* the current ICC_CTLR.CBPR settings.
78
+ *
79
+ * This corresponds to the GroupBits() pseudocode.
80
*/
81
+ int bpr;
82
+
83
if ((group == GICV3_G1 && cs->icc_ctlr_el1[GICV3_S] & ICC_CTLR_EL1_CBPR) ||
84
(group == GICV3_G1NS &&
85
cs->icc_ctlr_el1[GICV3_NS] & ICC_CTLR_EL1_CBPR)) {
86
group = GICV3_G0;
87
}
88
89
- return ~0U << ((cs->icc_bpr[group] & 7) + 1);
90
+ bpr = cs->icc_bpr[group] & 7;
91
+
92
+ if (group == GICV3_G1NS) {
93
+ assert(bpr > 0);
94
+ bpr--;
95
+ }
96
+
97
+ return ~0U << (bpr + 1);
98
}
120
}
99
121
100
static bool icc_no_enabled_hppi(GICv3CPUState *cs)
122
static void aarch64_a72_initfn(Object *obj)
123
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
124
cpu->gic_num_lrs = 4;
125
cpu->gic_vpribits = 5;
126
cpu->gic_vprebits = 5;
127
- define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
128
+ define_cortex_a72_a57_a53_cp_reginfo(cpu);
129
}
130
131
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
132
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/target/arm/cpu_tcg.c
135
+++ b/target/arm/cpu_tcg.c
136
@@ -XXX,XX +XXX,XX @@
137
#endif
138
#include "cpregs.h"
139
140
+#ifndef CONFIG_USER_ONLY
141
+static uint64_t l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
142
+{
143
+ ARMCPU *cpu = env_archcpu(env);
144
+
145
+ /* Number of cores is in [25:24]; otherwise we RAZ */
146
+ return (cpu->core_count - 1) << 24;
147
+}
148
+
149
+static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = {
150
+ { .name = "L2CTLR_EL1", .state = ARM_CP_STATE_AA64,
151
+ .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 2,
152
+ .access = PL1_RW, .readfn = l2ctlr_read,
153
+ .writefn = arm_cp_write_ignore },
154
+ { .name = "L2CTLR",
155
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 2,
156
+ .access = PL1_RW, .readfn = l2ctlr_read,
157
+ .writefn = arm_cp_write_ignore },
158
+ { .name = "L2ECTLR_EL1", .state = ARM_CP_STATE_AA64,
159
+ .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 3,
160
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
161
+ { .name = "L2ECTLR",
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
101
--
202
--
102
2.7.4
203
2.25.1
103
104
diff view generated by jsdifflib
1
All M profile CPUs are PMSA, so set the feature bit.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
(We haven't actually implemented the M profile MPU register
3
interface yet, but setting this feature bit gives us closer
4
to correct behaviour for the MPU-disabled case.)
5
2
3
Instead of starting with cortex-a15 and adding v8 features to
4
a v7 cpu, begin with a v8 cpu stripped of its aarch64 features.
5
This fixes the long-standing to-do where we only enabled v8
6
features for user-only.
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20220506180242.216785-7-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 1493122030-32191-11-git-send-email-peter.maydell@linaro.org
9
---
12
---
10
target/arm/cpu.c | 8 ++++++++
13
target/arm/cpu_tcg.c | 151 ++++++++++++++++++++++++++-----------------
11
1 file changed, 8 insertions(+)
14
1 file changed, 92 insertions(+), 59 deletions(-)
12
15
13
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.c
18
--- a/target/arm/cpu_tcg.c
16
+++ b/target/arm/cpu.c
19
+++ b/target/arm/cpu_tcg.c
17
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_post_init(Object *obj)
20
@@ -XXX,XX +XXX,XX @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
21
static void arm_max_initfn(Object *obj)
18
{
22
{
19
ARMCPU *cpu = ARM_CPU(obj);
23
ARMCPU *cpu = ARM_CPU(obj);
20
24
+ uint32_t t;
21
+ /* M profile implies PMSA. We have to do this here rather than
25
22
+ * in realize with the other feature-implication checks because
26
- cortex_a15_initfn(obj);
23
+ * we look at the PMSA bit to see if we should add some properties.
27
+ /* aarch64_a57_initfn, advertising none of the aarch64 features */
24
+ */
28
+ cpu->dtb_compatible = "arm,cortex-a57";
25
+ if (arm_feature(&cpu->env, ARM_FEATURE_M)) {
29
+ set_feature(&cpu->env, ARM_FEATURE_V8);
26
+ set_feature(&cpu->env, ARM_FEATURE_PMSA);
30
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
27
+ }
31
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
32
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
33
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
34
+ set_feature(&cpu->env, ARM_FEATURE_EL3);
35
+ set_feature(&cpu->env, ARM_FEATURE_PMU);
36
+ cpu->midr = 0x411fd070;
37
+ cpu->revidr = 0x00000000;
38
+ cpu->reset_fpsid = 0x41034070;
39
+ cpu->isar.mvfr0 = 0x10110222;
40
+ cpu->isar.mvfr1 = 0x12111111;
41
+ cpu->isar.mvfr2 = 0x00000043;
42
+ cpu->ctr = 0x8444c004;
43
+ cpu->reset_sctlr = 0x00c50838;
44
+ cpu->isar.id_pfr0 = 0x00000131;
45
+ cpu->isar.id_pfr1 = 0x00011011;
46
+ cpu->isar.id_dfr0 = 0x03010066;
47
+ cpu->id_afr0 = 0x00000000;
48
+ cpu->isar.id_mmfr0 = 0x10101105;
49
+ cpu->isar.id_mmfr1 = 0x40000000;
50
+ cpu->isar.id_mmfr2 = 0x01260000;
51
+ cpu->isar.id_mmfr3 = 0x02102211;
52
+ cpu->isar.id_isar0 = 0x02101110;
53
+ cpu->isar.id_isar1 = 0x13112111;
54
+ cpu->isar.id_isar2 = 0x21232042;
55
+ cpu->isar.id_isar3 = 0x01112131;
56
+ cpu->isar.id_isar4 = 0x00011142;
57
+ cpu->isar.id_isar5 = 0x00011121;
58
+ cpu->isar.id_isar6 = 0;
59
+ cpu->isar.dbgdidr = 0x3516d000;
60
+ cpu->clidr = 0x0a200023;
61
+ cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
62
+ cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */
63
+ cpu->ccsidr[2] = 0x70ffe07a; /* 2048KB L2 cache */
64
+ define_cortex_a72_a57_a53_cp_reginfo(cpu);
65
66
- /* old-style VFP short-vector support */
67
- cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
68
+ /* Add additional features supported by QEMU */
69
+ t = cpu->isar.id_isar5;
70
+ t = FIELD_DP32(t, ID_ISAR5, AES, 2);
71
+ t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
72
+ t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
73
+ t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
74
+ t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
75
+ t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
76
+ cpu->isar.id_isar5 = t;
28
+
77
+
29
if (arm_feature(&cpu->env, ARM_FEATURE_CBAR) ||
78
+ t = cpu->isar.id_isar6;
30
arm_feature(&cpu->env, ARM_FEATURE_CBAR_RO)) {
79
+ t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
31
qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_cbar_property,
80
+ t = FIELD_DP32(t, ID_ISAR6, DP, 1);
81
+ t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
82
+ t = FIELD_DP32(t, ID_ISAR6, SB, 1);
83
+ t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
84
+ t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
85
+ t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
86
+ cpu->isar.id_isar6 = t;
87
+
88
+ t = cpu->isar.mvfr1;
89
+ t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */
90
+ t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
91
+ cpu->isar.mvfr1 = t;
92
+
93
+ t = cpu->isar.mvfr2;
94
+ t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
95
+ t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
96
+ cpu->isar.mvfr2 = t;
97
+
98
+ t = cpu->isar.id_mmfr3;
99
+ t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
100
+ cpu->isar.id_mmfr3 = t;
101
+
102
+ t = cpu->isar.id_mmfr4;
103
+ t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
104
+ t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
105
+ t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
106
+ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
107
+ cpu->isar.id_mmfr4 = t;
108
+
109
+ t = cpu->isar.id_pfr0;
110
+ t = FIELD_DP32(t, ID_PFR0, DIT, 1);
111
+ cpu->isar.id_pfr0 = t;
112
+
113
+ t = cpu->isar.id_pfr2;
114
+ t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
115
+ cpu->isar.id_pfr2 = t;
116
117
#ifdef CONFIG_USER_ONLY
118
/*
119
- * We don't set these in system emulation mode for the moment,
120
- * since we don't correctly set (all of) the ID registers to
121
- * advertise them.
122
+ * Break with true ARMv8 and add back old-style VFP short-vector support.
123
+ * Only do this for user-mode, where -cpu max is the default, so that
124
+ * older v6 and v7 programs are more likely to work without adjustment.
125
*/
126
- set_feature(&cpu->env, ARM_FEATURE_V8);
127
- {
128
- uint32_t t;
129
-
130
- t = cpu->isar.id_isar5;
131
- t = FIELD_DP32(t, ID_ISAR5, AES, 2);
132
- t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
133
- t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
134
- t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
135
- t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
136
- t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
137
- cpu->isar.id_isar5 = t;
138
-
139
- t = cpu->isar.id_isar6;
140
- t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
141
- t = FIELD_DP32(t, ID_ISAR6, DP, 1);
142
- t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
143
- t = FIELD_DP32(t, ID_ISAR6, SB, 1);
144
- t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
145
- t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
146
- t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
147
- cpu->isar.id_isar6 = t;
148
-
149
- t = cpu->isar.mvfr1;
150
- t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */
151
- t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
152
- cpu->isar.mvfr1 = t;
153
-
154
- t = cpu->isar.mvfr2;
155
- t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
156
- t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
157
- cpu->isar.mvfr2 = t;
158
-
159
- t = cpu->isar.id_mmfr3;
160
- t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
161
- cpu->isar.id_mmfr3 = t;
162
-
163
- t = cpu->isar.id_mmfr4;
164
- t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
165
- t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
166
- t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
167
- t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
168
- cpu->isar.id_mmfr4 = t;
169
-
170
- t = cpu->isar.id_pfr0;
171
- t = FIELD_DP32(t, ID_PFR0, DIT, 1);
172
- cpu->isar.id_pfr0 = t;
173
-
174
- t = cpu->isar.id_pfr2;
175
- t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
176
- cpu->isar.id_pfr2 = t;
177
- }
178
-#endif /* CONFIG_USER_ONLY */
179
+ cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
180
+#endif
181
}
182
#endif /* !TARGET_AARCH64 */
183
32
--
184
--
33
2.7.4
185
2.25.1
34
35
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Cc: Shannon Zhao <zhaoshenglong@huawei.com>
3
We set this for qemu-system-aarch64, but failed to do so
4
Signed-off-by: Andrew Jones <drjones@redhat.com>
4
for the strictly 32-bit emulation.
5
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
5
6
Reviewed-by: Shannon Zhao <shannon.zhao@linaro.org>
6
Fixes: 3bec78447a9 ("target/arm: Provide ARMv8.4-PMU in '-cpu max'")
7
Message-id: 20170529173751.3443-2-drjones@redhat.com
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
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
11
---
10
hw/arm/virt-acpi-build.c | 4 ++++
12
target/arm/cpu_tcg.c | 4 ++++
11
1 file changed, 4 insertions(+)
13
1 file changed, 4 insertions(+)
12
14
13
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
15
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/virt-acpi-build.c
17
--- a/target/arm/cpu_tcg.c
16
+++ b/hw/arm/virt-acpi-build.c
18
+++ b/target/arm/cpu_tcg.c
17
@@ -XXX,XX +XXX,XX @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
19
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
18
if (nb_numa_nodes > 0) {
20
t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
19
acpi_add_table(table_offsets, tables_blob);
21
cpu->isar.id_pfr2 = t;
20
build_srat(tables_blob, tables->linker, vms);
22
21
+ if (have_numa_distance) {
23
+ t = cpu->isar.id_dfr0;
22
+ acpi_add_table(table_offsets, tables_blob);
24
+ t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
23
+ build_slit(tables_blob, tables->linker);
25
+ cpu->isar.id_dfr0 = t;
24
+ }
26
+
25
}
27
#ifdef CONFIG_USER_ONLY
26
28
/*
27
if (its_class_name() && !vmc->no_its) {
29
* Break with true ARMv8 and add back old-style VFP short-vector support.
28
--
30
--
29
2.7.4
31
2.25.1
30
31
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Largely inspired by the TMP105 temperature sensor, here is a model for
3
Share the code to set AArch32 max features so that we no
4
the TMP42{1,2,3} temperature sensors.
4
longer have code drift between qemu{-system,}-{arm,aarch64}.
5
5
6
Specs can be found here :
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
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/internals.h | 2 +
12
target/arm/cpu64.c | 50 +-----------------
13
target/arm/cpu_tcg.c | 114 ++++++++++++++++++++++-------------------
14
3 files changed, 65 insertions(+), 101 deletions(-)
7
15
8
    http://www.ti.com/lit/gpn/tmp421
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
9
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Message-id: 1494827476-1487-6-git-send-email-clg@kaod.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/misc/Makefile.objs | 1 +
16
hw/misc/tmp421.c | 401 ++++++++++++++++++++++++++++++++++++++++
17
default-configs/arm-softmmu.mak | 1 +
18
3 files changed, 403 insertions(+)
19
create mode 100644 hw/misc/tmp421.c
20
21
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
22
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/misc/Makefile.objs
18
--- a/target/arm/internals.h
24
+++ b/hw/misc/Makefile.objs
19
+++ b/target/arm/internals.h
20
@@ -XXX,XX +XXX,XX @@ static inline void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu) { }
21
void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu);
22
#endif
23
24
+void aa32_max_features(ARMCPU *cpu);
25
+
26
#endif
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
{
33
ARMCPU *cpu = ARM_CPU(obj);
34
uint64_t t;
35
- uint32_t u;
36
37
if (kvm_enabled() || hvf_enabled()) {
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
25
@@ -XXX,XX +XXX,XX @@
103
@@ -XXX,XX +XXX,XX @@
26
common-obj-$(CONFIG_APPLESMC) += applesmc.o
104
#endif
27
common-obj-$(CONFIG_MAX111X) += max111x.o
105
#include "cpregs.h"
28
common-obj-$(CONFIG_TMP105) += tmp105.o
106
29
+common-obj-$(CONFIG_TMP421) += tmp421.o
107
+
30
common-obj-$(CONFIG_ISA_DEBUG) += debugexit.o
108
+/* Share AArch32 -cpu max features with AArch64. */
31
common-obj-$(CONFIG_SGA) += sga.o
109
+void aa32_max_features(ARMCPU *cpu)
32
common-obj-$(CONFIG_ISA_TESTDEV) += pc-testdev.o
33
diff --git a/hw/misc/tmp421.c b/hw/misc/tmp421.c
34
new file mode 100644
35
index XXXXXXX..XXXXXXX
36
--- /dev/null
37
+++ b/hw/misc/tmp421.c
38
@@ -XXX,XX +XXX,XX @@
39
+/*
40
+ * Texas Instruments TMP421 temperature sensor.
41
+ *
42
+ * Copyright (c) 2016 IBM Corporation.
43
+ *
44
+ * Largely inspired by :
45
+ *
46
+ * Texas Instruments TMP105 temperature sensor.
47
+ *
48
+ * Copyright (C) 2008 Nokia Corporation
49
+ * Written by Andrzej Zaborowski <andrew@openedhand.com>
50
+ *
51
+ * This program is free software; you can redistribute it and/or
52
+ * modify it under the terms of the GNU General Public License as
53
+ * published by the Free Software Foundation; either version 2 or
54
+ * (at your option) version 3 of the License.
55
+ *
56
+ * This program is distributed in the hope that it will be useful,
57
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
58
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
59
+ * GNU General Public License for more details.
60
+ *
61
+ * You should have received a copy of the GNU General Public License along
62
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
63
+ */
64
+
65
+#include "qemu/osdep.h"
66
+#include "hw/hw.h"
67
+#include "hw/i2c/i2c.h"
68
+#include "qapi/error.h"
69
+#include "qapi/visitor.h"
70
+
71
+/* Manufacturer / Device ID's */
72
+#define TMP421_MANUFACTURER_ID 0x55
73
+#define TMP421_DEVICE_ID 0x21
74
+#define TMP422_DEVICE_ID 0x22
75
+#define TMP423_DEVICE_ID 0x23
76
+
77
+typedef struct DeviceInfo {
78
+ int model;
79
+ const char *name;
80
+} DeviceInfo;
81
+
82
+static const DeviceInfo devices[] = {
83
+ { TMP421_DEVICE_ID, "tmp421" },
84
+ { TMP422_DEVICE_ID, "tmp422" },
85
+ { TMP423_DEVICE_ID, "tmp423" },
86
+};
87
+
88
+typedef struct TMP421State {
89
+ /*< private >*/
90
+ I2CSlave i2c;
91
+ /*< public >*/
92
+
93
+ int16_t temperature[4];
94
+
95
+ uint8_t status;
96
+ uint8_t config[2];
97
+ uint8_t rate;
98
+
99
+ uint8_t len;
100
+ uint8_t buf[2];
101
+ uint8_t pointer;
102
+
103
+} TMP421State;
104
+
105
+typedef struct TMP421Class {
106
+ I2CSlaveClass parent_class;
107
+ DeviceInfo *dev;
108
+} TMP421Class;
109
+
110
+#define TYPE_TMP421 "tmp421-generic"
111
+#define TMP421(obj) OBJECT_CHECK(TMP421State, (obj), TYPE_TMP421)
112
+
113
+#define TMP421_CLASS(klass) \
114
+ OBJECT_CLASS_CHECK(TMP421Class, (klass), TYPE_TMP421)
115
+#define TMP421_GET_CLASS(obj) \
116
+ OBJECT_GET_CLASS(TMP421Class, (obj), TYPE_TMP421)
117
+
118
+/* the TMP421 registers */
119
+#define TMP421_STATUS_REG 0x08
120
+#define TMP421_STATUS_BUSY (1 << 7)
121
+#define TMP421_CONFIG_REG_1 0x09
122
+#define TMP421_CONFIG_RANGE (1 << 2)
123
+#define TMP421_CONFIG_SHUTDOWN (1 << 6)
124
+#define TMP421_CONFIG_REG_2 0x0A
125
+#define TMP421_CONFIG_RC (1 << 2)
126
+#define TMP421_CONFIG_LEN (1 << 3)
127
+#define TMP421_CONFIG_REN (1 << 4)
128
+#define TMP421_CONFIG_REN2 (1 << 5)
129
+#define TMP421_CONFIG_REN3 (1 << 6)
130
+
131
+#define TMP421_CONVERSION_RATE_REG 0x0B
132
+#define TMP421_ONE_SHOT 0x0F
133
+
134
+#define TMP421_RESET 0xFC
135
+#define TMP421_MANUFACTURER_ID_REG 0xFE
136
+#define TMP421_DEVICE_ID_REG 0xFF
137
+
138
+#define TMP421_TEMP_MSB0 0x00
139
+#define TMP421_TEMP_MSB1 0x01
140
+#define TMP421_TEMP_MSB2 0x02
141
+#define TMP421_TEMP_MSB3 0x03
142
+#define TMP421_TEMP_LSB0 0x10
143
+#define TMP421_TEMP_LSB1 0x11
144
+#define TMP421_TEMP_LSB2 0x12
145
+#define TMP421_TEMP_LSB3 0x13
146
+
147
+static const int32_t mins[2] = { -40000, -55000 };
148
+static const int32_t maxs[2] = { 127000, 150000 };
149
+
150
+static void tmp421_get_temperature(Object *obj, Visitor *v, const char *name,
151
+ void *opaque, Error **errp)
152
+{
110
+{
153
+ TMP421State *s = TMP421(obj);
111
+ uint32_t t;
154
+ bool ext_range = (s->config[0] & TMP421_CONFIG_RANGE);
112
+
155
+ int offset = ext_range * 64 * 256;
113
+ /* Add additional features supported by QEMU */
156
+ int64_t value;
114
+ t = cpu->isar.id_isar5;
157
+ int tempid;
115
+ t = FIELD_DP32(t, ID_ISAR5, AES, 2);
158
+
116
+ t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
159
+ if (sscanf(name, "temperature%d", &tempid) != 1) {
117
+ t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
160
+ error_setg(errp, "error reading %s: %m", name);
118
+ t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
161
+ return;
119
+ t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
162
+ }
120
+ t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
163
+
121
+ cpu->isar.id_isar5 = t;
164
+ if (tempid >= 4 || tempid < 0) {
122
+
165
+ error_setg(errp, "error reading %s", name);
123
+ t = cpu->isar.id_isar6;
166
+ return;
124
+ t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
167
+ }
125
+ t = FIELD_DP32(t, ID_ISAR6, DP, 1);
168
+
126
+ t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
169
+ value = ((s->temperature[tempid] - offset) * 1000 + 128) / 256;
127
+ t = FIELD_DP32(t, ID_ISAR6, SB, 1);
170
+
128
+ t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
171
+ visit_type_int(v, name, &value, errp);
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;
172
+}
165
+}
173
+
166
+
174
+/* Units are 0.001 centigrades relative to 0 C. s->temperature is 8.8
167
#ifndef CONFIG_USER_ONLY
175
+ * fixed point, so units are 1/256 centigrades. A simple ratio will do.
168
static uint64_t l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
176
+ */
169
{
177
+static void tmp421_set_temperature(Object *obj, Visitor *v, const char *name,
170
@@ -XXX,XX +XXX,XX @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
178
+ void *opaque, Error **errp)
171
static void arm_max_initfn(Object *obj)
179
+{
172
{
180
+ TMP421State *s = TMP421(obj);
173
ARMCPU *cpu = ARM_CPU(obj);
181
+ Error *local_err = NULL;
174
- uint32_t t;
182
+ int64_t temp;
175
183
+ bool ext_range = (s->config[0] & TMP421_CONFIG_RANGE);
176
/* aarch64_a57_initfn, advertising none of the aarch64 features */
184
+ int offset = ext_range * 64 * 256;
177
cpu->dtb_compatible = "arm,cortex-a57";
185
+ int tempid;
178
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
186
+
179
cpu->ccsidr[2] = 0x70ffe07a; /* 2048KB L2 cache */
187
+ visit_type_int(v, name, &temp, &local_err);
180
define_cortex_a72_a57_a53_cp_reginfo(cpu);
188
+ if (local_err) {
181
189
+ error_propagate(errp, local_err);
182
- /* Add additional features supported by QEMU */
190
+ return;
183
- t = cpu->isar.id_isar5;
191
+ }
184
- t = FIELD_DP32(t, ID_ISAR5, AES, 2);
192
+
185
- t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
193
+ if (temp >= maxs[ext_range] || temp < mins[ext_range]) {
186
- t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
194
+ error_setg(errp, "value %" PRId64 ".%03" PRIu64 " °C is out of range",
187
- t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
195
+ temp / 1000, temp % 1000);
188
- t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
196
+ return;
189
- t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
197
+ }
190
- cpu->isar.id_isar5 = t;
198
+
191
-
199
+ if (sscanf(name, "temperature%d", &tempid) != 1) {
192
- t = cpu->isar.id_isar6;
200
+ error_setg(errp, "error reading %s: %m", name);
193
- t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
201
+ return;
194
- t = FIELD_DP32(t, ID_ISAR6, DP, 1);
202
+ }
195
- t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
203
+
196
- t = FIELD_DP32(t, ID_ISAR6, SB, 1);
204
+ if (tempid >= 4 || tempid < 0) {
197
- t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
205
+ error_setg(errp, "error reading %s", name);
198
- t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
206
+ return;
199
- t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
207
+ }
200
- cpu->isar.id_isar6 = t;
208
+
201
-
209
+ s->temperature[tempid] = (int16_t) ((temp * 256 - 128) / 1000) + offset;
202
- t = cpu->isar.mvfr1;
210
+}
203
- t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */
211
+
204
- t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
212
+static void tmp421_read(TMP421State *s)
205
- cpu->isar.mvfr1 = t;
213
+{
206
-
214
+ TMP421Class *sc = TMP421_GET_CLASS(s);
207
- t = cpu->isar.mvfr2;
215
+
208
- t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
216
+ s->len = 0;
209
- t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
217
+
210
- cpu->isar.mvfr2 = t;
218
+ switch (s->pointer) {
211
-
219
+ case TMP421_MANUFACTURER_ID_REG:
212
- t = cpu->isar.id_mmfr3;
220
+ s->buf[s->len++] = TMP421_MANUFACTURER_ID;
213
- t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
221
+ break;
214
- cpu->isar.id_mmfr3 = t;
222
+ case TMP421_DEVICE_ID_REG:
215
-
223
+ s->buf[s->len++] = sc->dev->model;
216
- t = cpu->isar.id_mmfr4;
224
+ break;
217
- t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
225
+ case TMP421_CONFIG_REG_1:
218
- t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
226
+ s->buf[s->len++] = s->config[0];
219
- t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
227
+ break;
220
- t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
228
+ case TMP421_CONFIG_REG_2:
221
- cpu->isar.id_mmfr4 = t;
229
+ s->buf[s->len++] = s->config[1];
222
-
230
+ break;
223
- t = cpu->isar.id_pfr0;
231
+ case TMP421_CONVERSION_RATE_REG:
224
- t = FIELD_DP32(t, ID_PFR0, DIT, 1);
232
+ s->buf[s->len++] = s->rate;
225
- cpu->isar.id_pfr0 = t;
233
+ break;
226
-
234
+ case TMP421_STATUS_REG:
227
- t = cpu->isar.id_pfr2;
235
+ s->buf[s->len++] = s->status;
228
- t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
236
+ break;
229
- cpu->isar.id_pfr2 = t;
237
+
230
-
238
+ /* FIXME: check for channel enablement in config registers */
231
- t = cpu->isar.id_dfr0;
239
+ case TMP421_TEMP_MSB0:
232
- t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
240
+ s->buf[s->len++] = (((uint16_t) s->temperature[0]) >> 8);
233
- cpu->isar.id_dfr0 = t;
241
+ s->buf[s->len++] = (((uint16_t) s->temperature[0]) >> 0) & 0xf0;
234
+ aa32_max_features(cpu);
242
+ break;
235
243
+ case TMP421_TEMP_MSB1:
236
#ifdef CONFIG_USER_ONLY
244
+ s->buf[s->len++] = (((uint16_t) s->temperature[1]) >> 8);
237
/*
245
+ s->buf[s->len++] = (((uint16_t) s->temperature[1]) >> 0) & 0xf0;
246
+ break;
247
+ case TMP421_TEMP_MSB2:
248
+ s->buf[s->len++] = (((uint16_t) s->temperature[2]) >> 8);
249
+ s->buf[s->len++] = (((uint16_t) s->temperature[2]) >> 0) & 0xf0;
250
+ break;
251
+ case TMP421_TEMP_MSB3:
252
+ s->buf[s->len++] = (((uint16_t) s->temperature[3]) >> 8);
253
+ s->buf[s->len++] = (((uint16_t) s->temperature[3]) >> 0) & 0xf0;
254
+ break;
255
+ case TMP421_TEMP_LSB0:
256
+ s->buf[s->len++] = (((uint16_t) s->temperature[0]) >> 0) & 0xf0;
257
+ break;
258
+ case TMP421_TEMP_LSB1:
259
+ s->buf[s->len++] = (((uint16_t) s->temperature[1]) >> 0) & 0xf0;
260
+ break;
261
+ case TMP421_TEMP_LSB2:
262
+ s->buf[s->len++] = (((uint16_t) s->temperature[2]) >> 0) & 0xf0;
263
+ break;
264
+ case TMP421_TEMP_LSB3:
265
+ s->buf[s->len++] = (((uint16_t) s->temperature[3]) >> 0) & 0xf0;
266
+ break;
267
+ }
268
+}
269
+
270
+static void tmp421_reset(I2CSlave *i2c);
271
+
272
+static void tmp421_write(TMP421State *s)
273
+{
274
+ switch (s->pointer) {
275
+ case TMP421_CONVERSION_RATE_REG:
276
+ s->rate = s->buf[0];
277
+ break;
278
+ case TMP421_CONFIG_REG_1:
279
+ s->config[0] = s->buf[0];
280
+ break;
281
+ case TMP421_CONFIG_REG_2:
282
+ s->config[1] = s->buf[0];
283
+ break;
284
+ case TMP421_RESET:
285
+ tmp421_reset(I2C_SLAVE(s));
286
+ break;
287
+ }
288
+}
289
+
290
+static int tmp421_rx(I2CSlave *i2c)
291
+{
292
+ TMP421State *s = TMP421(i2c);
293
+
294
+ if (s->len < 2) {
295
+ return s->buf[s->len++];
296
+ } else {
297
+ return 0xff;
298
+ }
299
+}
300
+
301
+static int tmp421_tx(I2CSlave *i2c, uint8_t data)
302
+{
303
+ TMP421State *s = TMP421(i2c);
304
+
305
+ if (s->len == 0) {
306
+ /* first byte is the register pointer for a read or write
307
+ * operation */
308
+ s->pointer = data;
309
+ s->len++;
310
+ } else if (s->len == 1) {
311
+ /* second byte is the data to write. The device only supports
312
+ * one byte writes */
313
+ s->buf[0] = data;
314
+ tmp421_write(s);
315
+ }
316
+
317
+ return 0;
318
+}
319
+
320
+static int tmp421_event(I2CSlave *i2c, enum i2c_event event)
321
+{
322
+ TMP421State *s = TMP421(i2c);
323
+
324
+ if (event == I2C_START_RECV) {
325
+ tmp421_read(s);
326
+ }
327
+
328
+ s->len = 0;
329
+ return 0;
330
+}
331
+
332
+static const VMStateDescription vmstate_tmp421 = {
333
+ .name = "TMP421",
334
+ .version_id = 0,
335
+ .minimum_version_id = 0,
336
+ .fields = (VMStateField[]) {
337
+ VMSTATE_UINT8(len, TMP421State),
338
+ VMSTATE_UINT8_ARRAY(buf, TMP421State, 2),
339
+ VMSTATE_UINT8(pointer, TMP421State),
340
+ VMSTATE_UINT8_ARRAY(config, TMP421State, 2),
341
+ VMSTATE_UINT8(status, TMP421State),
342
+ VMSTATE_UINT8(rate, TMP421State),
343
+ VMSTATE_INT16_ARRAY(temperature, TMP421State, 4),
344
+ VMSTATE_I2C_SLAVE(i2c, TMP421State),
345
+ VMSTATE_END_OF_LIST()
346
+ }
347
+};
348
+
349
+static void tmp421_reset(I2CSlave *i2c)
350
+{
351
+ TMP421State *s = TMP421(i2c);
352
+ TMP421Class *sc = TMP421_GET_CLASS(s);
353
+
354
+ memset(s->temperature, 0, sizeof(s->temperature));
355
+ s->pointer = 0;
356
+
357
+ s->config[0] = 0; /* TMP421_CONFIG_RANGE */
358
+
359
+ /* resistance correction and channel enablement */
360
+ switch (sc->dev->model) {
361
+ case TMP421_DEVICE_ID:
362
+ s->config[1] = 0x1c;
363
+ break;
364
+ case TMP422_DEVICE_ID:
365
+ s->config[1] = 0x3c;
366
+ break;
367
+ case TMP423_DEVICE_ID:
368
+ s->config[1] = 0x7c;
369
+ break;
370
+ }
371
+
372
+ s->rate = 0x7; /* 8Hz */
373
+ s->status = 0;
374
+}
375
+
376
+static int tmp421_init(I2CSlave *i2c)
377
+{
378
+ TMP421State *s = TMP421(i2c);
379
+
380
+ tmp421_reset(&s->i2c);
381
+
382
+ return 0;
383
+}
384
+
385
+static void tmp421_initfn(Object *obj)
386
+{
387
+ object_property_add(obj, "temperature0", "int",
388
+ tmp421_get_temperature,
389
+ tmp421_set_temperature, NULL, NULL, NULL);
390
+ object_property_add(obj, "temperature1", "int",
391
+ tmp421_get_temperature,
392
+ tmp421_set_temperature, NULL, NULL, NULL);
393
+ object_property_add(obj, "temperature2", "int",
394
+ tmp421_get_temperature,
395
+ tmp421_set_temperature, NULL, NULL, NULL);
396
+ object_property_add(obj, "temperature3", "int",
397
+ tmp421_get_temperature,
398
+ tmp421_set_temperature, NULL, NULL, NULL);
399
+}
400
+
401
+static void tmp421_class_init(ObjectClass *klass, void *data)
402
+{
403
+ DeviceClass *dc = DEVICE_CLASS(klass);
404
+ I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
405
+ TMP421Class *sc = TMP421_CLASS(klass);
406
+
407
+ k->init = tmp421_init;
408
+ k->event = tmp421_event;
409
+ k->recv = tmp421_rx;
410
+ k->send = tmp421_tx;
411
+ dc->vmsd = &vmstate_tmp421;
412
+ sc->dev = (DeviceInfo *) data;
413
+}
414
+
415
+static const TypeInfo tmp421_info = {
416
+ .name = TYPE_TMP421,
417
+ .parent = TYPE_I2C_SLAVE,
418
+ .instance_size = sizeof(TMP421State),
419
+ .instance_init = tmp421_initfn,
420
+ .class_init = tmp421_class_init,
421
+};
422
+
423
+static void tmp421_register_types(void)
424
+{
425
+ int i;
426
+
427
+ type_register_static(&tmp421_info);
428
+ for (i = 0; i < ARRAY_SIZE(devices); ++i) {
429
+ TypeInfo ti = {
430
+ .name = devices[i].name,
431
+ .parent = TYPE_TMP421,
432
+ .class_init = tmp421_class_init,
433
+ .class_data = (void *) &devices[i],
434
+ };
435
+ type_register(&ti);
436
+ }
437
+}
438
+
439
+type_init(tmp421_register_types)
440
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
441
index XXXXXXX..XXXXXXX 100644
442
--- a/default-configs/arm-softmmu.mak
443
+++ b/default-configs/arm-softmmu.mak
444
@@ -XXX,XX +XXX,XX @@ CONFIG_TWL92230=y
445
CONFIG_TSC2005=y
446
CONFIG_LM832X=y
447
CONFIG_TMP105=y
448
+CONFIG_TMP421=y
449
CONFIG_STELLARIS=y
450
CONFIG_STELLARIS_INPUT=y
451
CONFIG_STELLARIS_ENET=y
452
--
238
--
453
2.7.4
239
2.25.1
454
455
diff view generated by jsdifflib
1
We were setting the VBPR1 field of VMCR_EL2 to icv_min_vbpr()
1
From: Richard Henderson <richard.henderson@linaro.org>
2
on reset, but this is not correct. The field should reset to
3
the minimum value of ICV_BPR0_EL1 plus one.
4
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
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 1493226792-3237-2-git-send-email-peter.maydell@linaro.org
8
---
11
---
9
hw/intc/arm_gicv3_cpuif.c | 2 +-
12
target/arm/cpu64.c | 100 +++++++++++++++++++++----------------------
10
1 file changed, 1 insertion(+), 1 deletion(-)
13
target/arm/cpu_tcg.c | 48 ++++++++++-----------
14
2 files changed, 74 insertions(+), 74 deletions(-)
11
15
12
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
16
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/intc/arm_gicv3_cpuif.c
18
--- a/target/arm/cpu64.c
15
+++ b/hw/intc/arm_gicv3_cpuif.c
19
+++ b/target/arm/cpu64.c
16
@@ -XXX,XX +XXX,XX @@ static void icc_reset(CPUARMState *env, const ARMCPRegInfo *ri)
20
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
17
cs->ich_hcr_el2 = 0;
21
cpu->midr = t;
18
memset(cs->ich_lr_el2, 0, sizeof(cs->ich_lr_el2));
22
19
cs->ich_vmcr_el2 = ICH_VMCR_EL2_VFIQEN |
23
t = cpu->isar.id_aa64isar0;
20
- (icv_min_vbpr(cs) << ICH_VMCR_EL2_VBPR1_SHIFT) |
24
- t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* AES + PMULL */
21
+ ((icv_min_vbpr(cs) + 1) << ICH_VMCR_EL2_VBPR1_SHIFT) |
25
- t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1);
22
(icv_min_vbpr(cs) << ICH_VMCR_EL2_VBPR0_SHIFT);
26
- t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* SHA512 */
27
+ t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* FEAT_PMULL */
28
+ t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1); /* FEAT_SHA1 */
29
+ t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* FEAT_SHA512 */
30
t = FIELD_DP64(t, ID_AA64ISAR0, CRC32, 1);
31
- t = FIELD_DP64(t, ID_AA64ISAR0, ATOMIC, 2);
32
- t = FIELD_DP64(t, ID_AA64ISAR0, RDM, 1);
33
- t = FIELD_DP64(t, ID_AA64ISAR0, SHA3, 1);
34
- t = FIELD_DP64(t, ID_AA64ISAR0, SM3, 1);
35
- t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 1);
36
- t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
37
- t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1);
38
- t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* v8.5-CondM */
39
- t = FIELD_DP64(t, ID_AA64ISAR0, TLB, 2); /* FEAT_TLBIRANGE */
40
- t = FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1);
41
+ t = FIELD_DP64(t, ID_AA64ISAR0, ATOMIC, 2); /* FEAT_LSE */
42
+ t = FIELD_DP64(t, ID_AA64ISAR0, RDM, 1); /* FEAT_RDM */
43
+ t = FIELD_DP64(t, ID_AA64ISAR0, SHA3, 1); /* FEAT_SHA3 */
44
+ t = FIELD_DP64(t, ID_AA64ISAR0, SM3, 1); /* FEAT_SM3 */
45
+ t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 1); /* FEAT_SM4 */
46
+ t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1); /* FEAT_DotProd */
47
+ t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1); /* FEAT_FHM */
48
+ t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* FEAT_FlagM2 */
49
+ t = FIELD_DP64(t, ID_AA64ISAR0, TLB, 2); /* FEAT_TLBIRANGE */
50
+ t = FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1); /* FEAT_RNG */
51
cpu->isar.id_aa64isar0 = t;
52
53
t = cpu->isar.id_aa64isar1;
54
- t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2);
55
- t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1);
56
- t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
57
- t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
58
- t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
59
- t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 1);
60
- t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1);
61
- t = FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 2); /* ARMv8.4-RCPC */
62
- t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1);
63
+ t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2); /* FEAT_DPB2 */
64
+ t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1); /* FEAT_JSCVT */
65
+ t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1); /* FEAT_FCMA */
66
+ t = FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 2); /* FEAT_LRCPC2 */
67
+ t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1); /* FEAT_FRINTTS */
68
+ t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1); /* FEAT_SB */
69
+ t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1); /* FEAT_SPECRES */
70
+ t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 1); /* FEAT_BF16 */
71
+ t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1); /* FEAT_I8MM */
72
cpu->isar.id_aa64isar1 = t;
73
74
t = cpu->isar.id_aa64pfr0;
75
+ t = FIELD_DP64(t, ID_AA64PFR0, FP, 1); /* FEAT_FP16 */
76
+ t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1); /* FEAT_FP16 */
77
t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
78
- t = FIELD_DP64(t, ID_AA64PFR0, FP, 1);
79
- t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1);
80
- t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1);
81
- t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1);
82
+ t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); /* FEAT_SEL2 */
83
+ t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
84
cpu->isar.id_aa64pfr0 = t;
85
86
t = cpu->isar.id_aa64pfr1;
87
- t = FIELD_DP64(t, ID_AA64PFR1, BT, 1);
88
- t = FIELD_DP64(t, ID_AA64PFR1, SSBS, 2);
89
+ t = FIELD_DP64(t, ID_AA64PFR1, BT, 1); /* FEAT_BTI */
90
+ t = FIELD_DP64(t, ID_AA64PFR1, SSBS, 2); /* FEAT_SSBS2 */
91
/*
92
* Begin with full support for MTE. This will be downgraded to MTE=0
93
* during realize if the board provides no tag memory, much like
94
* we do for EL2 with the virtualization=on property.
95
*/
96
- t = FIELD_DP64(t, ID_AA64PFR1, MTE, 3);
97
+ t = FIELD_DP64(t, ID_AA64PFR1, MTE, 3); /* FEAT_MTE3 */
98
cpu->isar.id_aa64pfr1 = t;
99
100
t = cpu->isar.id_aa64mmfr0;
101
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
102
cpu->isar.id_aa64mmfr0 = t;
103
104
t = cpu->isar.id_aa64mmfr1;
105
- t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */
106
- t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1);
107
- t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1);
108
- t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */
109
- t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */
110
- t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* TTS2UXN */
111
+ t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* FEAT_VMID16 */
112
+ t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); /* FEAT_VHE */
113
+ t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* FEAT_HPDS */
114
+ t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1); /* FEAT_LOR */
115
+ t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* FEAT_PAN2 */
116
+ t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* FEAT_XNX */
117
cpu->isar.id_aa64mmfr1 = t;
118
119
t = cpu->isar.id_aa64mmfr2;
120
- t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1);
121
- t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* TTCNP */
122
- t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* TTST */
123
- t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1); /* FEAT_LVA */
124
- t = FIELD_DP64(t, ID_AA64MMFR2, TTL, 1); /* FEAT_TTL */
125
- t = FIELD_DP64(t, ID_AA64MMFR2, BBM, 2); /* FEAT_BBM at level 2 */
126
+ t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* FEAT_TTCNP */
127
+ t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1); /* FEAT_UAO */
128
+ t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1); /* FEAT_LVA */
129
+ t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* FEAT_TTST */
130
+ t = FIELD_DP64(t, ID_AA64MMFR2, TTL, 1); /* FEAT_TTL */
131
+ t = FIELD_DP64(t, ID_AA64MMFR2, BBM, 2); /* FEAT_BBM at level 2 */
132
cpu->isar.id_aa64mmfr2 = t;
133
134
t = cpu->isar.id_aa64zfr0;
135
t = FIELD_DP64(t, ID_AA64ZFR0, SVEVER, 1);
136
- t = FIELD_DP64(t, ID_AA64ZFR0, AES, 2); /* PMULL */
137
- t = FIELD_DP64(t, ID_AA64ZFR0, BITPERM, 1);
138
- t = FIELD_DP64(t, ID_AA64ZFR0, BFLOAT16, 1);
139
- t = FIELD_DP64(t, ID_AA64ZFR0, SHA3, 1);
140
- t = FIELD_DP64(t, ID_AA64ZFR0, SM4, 1);
141
- t = FIELD_DP64(t, ID_AA64ZFR0, I8MM, 1);
142
- t = FIELD_DP64(t, ID_AA64ZFR0, F32MM, 1);
143
- t = FIELD_DP64(t, ID_AA64ZFR0, F64MM, 1);
144
+ t = FIELD_DP64(t, ID_AA64ZFR0, AES, 2); /* FEAT_SVE_PMULL128 */
145
+ t = FIELD_DP64(t, ID_AA64ZFR0, BITPERM, 1); /* FEAT_SVE_BitPerm */
146
+ t = FIELD_DP64(t, ID_AA64ZFR0, BFLOAT16, 1); /* FEAT_BF16 */
147
+ t = FIELD_DP64(t, ID_AA64ZFR0, SHA3, 1); /* FEAT_SVE_SHA3 */
148
+ t = FIELD_DP64(t, ID_AA64ZFR0, SM4, 1); /* FEAT_SVE_SM4 */
149
+ t = FIELD_DP64(t, ID_AA64ZFR0, I8MM, 1); /* FEAT_I8MM */
150
+ t = FIELD_DP64(t, ID_AA64ZFR0, F32MM, 1); /* FEAT_F32MM */
151
+ t = FIELD_DP64(t, ID_AA64ZFR0, F64MM, 1); /* FEAT_F64MM */
152
cpu->isar.id_aa64zfr0 = t;
153
154
t = cpu->isar.id_aa64dfr0;
155
- t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
156
+ t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* FEAT_PMUv3p4 */
157
cpu->isar.id_aa64dfr0 = t;
158
159
/* Replicate the same data to the 32-bit id registers. */
160
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
161
index XXXXXXX..XXXXXXX 100644
162
--- a/target/arm/cpu_tcg.c
163
+++ b/target/arm/cpu_tcg.c
164
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
165
166
/* Add additional features supported by QEMU */
167
t = cpu->isar.id_isar5;
168
- t = FIELD_DP32(t, ID_ISAR5, AES, 2);
169
- t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
170
- t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
171
+ t = FIELD_DP32(t, ID_ISAR5, AES, 2); /* FEAT_PMULL */
172
+ t = FIELD_DP32(t, ID_ISAR5, SHA1, 1); /* FEAT_SHA1 */
173
+ t = FIELD_DP32(t, ID_ISAR5, SHA2, 1); /* FEAT_SHA256 */
174
t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
175
- t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
176
- t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
177
+ t = FIELD_DP32(t, ID_ISAR5, RDM, 1); /* FEAT_RDM */
178
+ t = FIELD_DP32(t, ID_ISAR5, VCMA, 1); /* FEAT_FCMA */
179
cpu->isar.id_isar5 = t;
180
181
t = cpu->isar.id_isar6;
182
- t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
183
- t = FIELD_DP32(t, ID_ISAR6, DP, 1);
184
- t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
185
- t = FIELD_DP32(t, ID_ISAR6, SB, 1);
186
- t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
187
- t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
188
- t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
189
+ t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1); /* FEAT_JSCVT */
190
+ t = FIELD_DP32(t, ID_ISAR6, DP, 1); /* Feat_DotProd */
191
+ t = FIELD_DP32(t, ID_ISAR6, FHM, 1); /* FEAT_FHM */
192
+ t = FIELD_DP32(t, ID_ISAR6, SB, 1); /* FEAT_SB */
193
+ t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1); /* FEAT_SPECRES */
194
+ t = FIELD_DP32(t, ID_ISAR6, BF16, 1); /* FEAT_AA32BF16 */
195
+ t = FIELD_DP32(t, ID_ISAR6, I8MM, 1); /* FEAT_AA32I8MM */
196
cpu->isar.id_isar6 = t;
197
198
t = cpu->isar.mvfr1;
199
- t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */
200
- t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
201
+ t = FIELD_DP32(t, MVFR1, FPHP, 3); /* FEAT_FP16 */
202
+ t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* FEAT_FP16 */
203
cpu->isar.mvfr1 = t;
204
205
t = cpu->isar.mvfr2;
206
- t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
207
- t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
208
+ t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
209
+ t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
210
cpu->isar.mvfr2 = t;
211
212
t = cpu->isar.id_mmfr3;
213
- t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
214
+ t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* FEAT_PAN2 */
215
cpu->isar.id_mmfr3 = t;
216
217
t = cpu->isar.id_mmfr4;
218
- t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
219
- t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
220
- t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
221
- t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
222
+ t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* FEAT_AA32HPD */
223
+ t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
224
+ t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* FEAT_TTCNP */
225
+ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* FEAT_XNX*/
226
cpu->isar.id_mmfr4 = t;
227
228
t = cpu->isar.id_pfr0;
229
- t = FIELD_DP32(t, ID_PFR0, DIT, 1);
230
+ t = FIELD_DP32(t, ID_PFR0, DIT, 1); /* FEAT_DIT */
231
cpu->isar.id_pfr0 = t;
232
233
t = cpu->isar.id_pfr2;
234
- t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
235
+ t = FIELD_DP32(t, ID_PFR2, SSBS, 1); /* FEAT_SSBS */
236
cpu->isar.id_pfr2 = t;
237
238
t = cpu->isar.id_dfr0;
239
- t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
240
+ t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* FEAT_PMUv3p4 */
241
cpu->isar.id_dfr0 = t;
23
}
242
}
24
243
25
--
244
--
26
2.7.4
245
2.25.1
27
28
diff view generated by jsdifflib
1
From: Wei Huang <wei@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The PMUv3 driver of linux kernel (in arch/arm64/kernel/perf_event.c)
3
Use FIELD_DP{32,64} to manipulate id_pfr1 and id_aa64pfr0
4
relies on the PMUVER field of id_aa64dfr0_el1 to decide if PMU support
4
during arm_cpu_realizefn.
5
is present or not. This patch clears the PMUVER field under TCG mode
6
when vPMU=off. Without it, PMUv3 will init insider guest VMs even
7
with vPMU=off. This patch also removes a redundant line inside the
8
if-statement.
9
5
10
Signed-off-by: Wei Huang <wei@redhat.com>
11
Message-id: 1495123889-32301-1-git-send-email-wei@redhat.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
10
---
15
target/arm/cpu.c | 2 +-
11
target/arm/cpu.c | 22 +++++++++++++---------
16
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 13 insertions(+), 9 deletions(-)
17
13
18
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.c
16
--- a/target/arm/cpu.c
21
+++ b/target/arm/cpu.c
17
+++ b/target/arm/cpu.c
22
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
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);
23
}
33
}
24
34
25
if (!cpu->has_pmu) {
35
if (!cpu->has_el2) {
26
- cpu->has_pmu = false;
36
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
27
unset_feature(env, ARM_FEATURE_PMU);
28
+ cpu->id_aa64dfr0 &= ~0xf00;
29
}
37
}
30
38
31
if (!arm_feature(env, ARM_FEATURE_EL2)) {
39
if (!arm_feature(env, ARM_FEATURE_EL2)) {
40
- /* Disable the hypervisor feature bits in the processor feature
41
- * registers if we don't have EL2. These are id_pfr1[15:12] and
42
- * id_aa64pfr0_el1[11:8].
43
+ /*
44
+ * Disable the hypervisor feature bits in the processor feature
45
+ * registers if we don't have EL2.
46
*/
47
- cpu->isar.id_aa64pfr0 &= ~0xf00;
48
- cpu->isar.id_pfr1 &= ~0xf000;
49
+ cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
50
+ ID_AA64PFR0, EL2, 0);
51
+ cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1,
52
+ ID_PFR1, VIRTUALIZATION, 0);
53
}
54
55
#ifndef CONFIG_USER_ONLY
32
--
56
--
33
2.7.4
57
2.25.1
34
35
diff view generated by jsdifflib
1
Fix the handling of QOM properties for PMSA CPUs with no MPU:
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Allow no-MPU to be specified by either:
3
The only portion of FEAT_Debugv8p2 that is relevant to QEMU
4
* has-mpu = false
4
is CONTEXTIDR_EL2, which is also conditionally implemented
5
* pmsav7_dregion = 0
5
with FEAT_VHE. The rest of the debug extension concerns the
6
and make setting one imply the other. Don't clear the PMSA
6
External debug interface, which is outside the scope of QEMU.
7
feature bit in this situation.
8
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
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Message-id: 1493122030-32191-6-git-send-email-peter.maydell@linaro.org
13
---
12
---
14
target/arm/cpu.c | 8 +++++++-
13
docs/system/arm/emulation.rst | 1 +
15
1 file changed, 7 insertions(+), 1 deletion(-)
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(+)
16
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)
17
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
31
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
18
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.c
33
--- a/target/arm/cpu.c
20
+++ b/target/arm/cpu.c
34
+++ b/target/arm/cpu.c
21
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
35
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
22
cpu->id_pfr1 &= ~0xf000;
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);
23
}
42
}
24
43
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
25
+ /* MPU can be configured out of a PMSA CPU either by setting has-mpu
44
index XXXXXXX..XXXXXXX 100644
26
+ * to false or by setting pmsav7-dregion to 0.
45
--- a/target/arm/cpu64.c
27
+ */
46
+++ b/target/arm/cpu64.c
28
if (!cpu->has_mpu) {
47
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
29
- unset_feature(env, ARM_FEATURE_PMSA);
48
cpu->isar.id_aa64zfr0 = t;
30
+ cpu->pmsav7_dregion = 0;
49
31
+ }
50
t = cpu->isar.id_aa64dfr0;
32
+ if (cpu->pmsav7_dregion == 0) {
51
+ t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 8); /* FEAT_Debugv8p2 */
33
+ cpu->has_mpu = false;
52
t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* FEAT_PMUv3p4 */
34
}
53
cpu->isar.id_aa64dfr0 = t;
35
54
36
if (arm_feature(env, ARM_FEATURE_PMSA) &&
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
}
37
--
68
--
38
2.7.4
69
2.25.1
39
40
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
This extension concerns changes to the External Debug interface,
4
with Secure and Non-secure access to the debug registers, and all
5
of it is outside the scope of QEMU. Indicating support for this
6
is mandatory with FEAT_SEL2, which we do implement.
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20220506180242.216785-13-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
docs/system/arm/emulation.rst | 1 +
14
target/arm/cpu64.c | 2 +-
15
target/arm/cpu_tcg.c | 4 ++--
16
3 files changed, 4 insertions(+), 3 deletions(-)
17
18
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
19
index XXXXXXX..XXXXXXX 100644
20
--- a/docs/system/arm/emulation.rst
21
+++ b/docs/system/arm/emulation.rst
22
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
23
- FEAT_DIT (Data Independent Timing instructions)
24
- FEAT_DPB (DC CVAP instruction)
25
- FEAT_Debugv8p2 (Debug changes for v8.2)
26
+- FEAT_Debugv8p4 (Debug changes for v8.4)
27
- FEAT_DotProd (Advanced SIMD dot product instructions)
28
- FEAT_FCMA (Floating-point complex number instructions)
29
- FEAT_FHM (Floating-point half-precision multiplication instructions)
30
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/cpu64.c
33
+++ b/target/arm/cpu64.c
34
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
35
cpu->isar.id_aa64zfr0 = t;
36
37
t = cpu->isar.id_aa64dfr0;
38
- t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 8); /* FEAT_Debugv8p2 */
39
+ t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 9); /* FEAT_Debugv8p4 */
40
t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* FEAT_PMUv3p4 */
41
cpu->isar.id_aa64dfr0 = t;
42
43
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/cpu_tcg.c
46
+++ b/target/arm/cpu_tcg.c
47
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
48
cpu->isar.id_pfr2 = t;
49
50
t = cpu->isar.id_dfr0;
51
- t = FIELD_DP32(t, ID_DFR0, COPDBG, 8); /* FEAT_Debugv8p2 */
52
- t = FIELD_DP32(t, ID_DFR0, COPSDBG, 8); /* FEAT_Debugv8p2 */
53
+ t = FIELD_DP32(t, ID_DFR0, COPDBG, 9); /* FEAT_Debugv8p4 */
54
+ t = FIELD_DP32(t, ID_DFR0, COPSDBG, 9); /* FEAT_Debugv8p4 */
55
t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* FEAT_PMUv3p4 */
56
cpu->isar.id_dfr0 = t;
57
}
58
--
59
2.25.1
diff view generated by jsdifflib
1
Make M profile use completely separate ARMMMUIdx values from
1
From: Richard Henderson <richard.henderson@linaro.org>
2
those that A profile CPUs use. This is a prelude to adding
3
support for the MPU and for v8M, which together will require
4
6 MMU indexes which don't map cleanly onto the A profile
5
uses:
6
non secure User
7
non secure Privileged
8
non secure Privileged, execution priority < 0
9
secure User
10
secure Privileged
11
secure Privileged, execution priority < 0
12
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
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 1493122030-32191-4-git-send-email-peter.maydell@linaro.org
15
---
14
---
16
target/arm/cpu.h | 21 +++++++++++++++++++--
15
target/arm/cpu.h | 5 +++
17
target/arm/helper.c | 5 +++++
16
target/arm/helper.c | 84 +++++++++++++++++++++++++++++++++++++++++++++
18
target/arm/translate.c | 3 +++
17
2 files changed, 89 insertions(+)
19
3 files changed, 27 insertions(+), 2 deletions(-)
20
18
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.h
21
--- a/target/arm/cpu.h
24
+++ b/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
25
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
23
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
26
* of the AT/ATS operations.
24
uint64_t tfsr_el[4]; /* tfsre0_el1 is index 0. */
27
* The values used are carefully arranged to make mmu_idx => EL lookup easy.
25
uint64_t gcr_el1;
28
*/
26
uint64_t rgsr_el1;
29
-#define ARM_MMU_IDX_A 0x10 /* A profile (and M profile, for the moment) */
30
+#define ARM_MMU_IDX_A 0x10 /* A profile */
31
#define ARM_MMU_IDX_NOTLB 0x20 /* does not have a TLB */
32
+#define ARM_MMU_IDX_M 0x40 /* M profile */
33
34
#define ARM_MMU_IDX_TYPE_MASK (~0x7)
35
#define ARM_MMU_IDX_COREIDX_MASK 0x7
36
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
37
ARMMMUIdx_S1SE0 = 4 | ARM_MMU_IDX_A,
38
ARMMMUIdx_S1SE1 = 5 | ARM_MMU_IDX_A,
39
ARMMMUIdx_S2NS = 6 | ARM_MMU_IDX_A,
40
+ ARMMMUIdx_MUser = 0 | ARM_MMU_IDX_M,
41
+ ARMMMUIdx_MPriv = 1 | ARM_MMU_IDX_M,
42
/* Indexes below here don't have TLBs and are used only for AT system
43
* instructions or for the first stage of an S12 page table walk.
44
*/
45
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
46
ARMMMUIdxBit_S1SE0 = 1 << 4,
47
ARMMMUIdxBit_S1SE1 = 1 << 5,
48
ARMMMUIdxBit_S2NS = 1 << 6,
49
+ ARMMMUIdxBit_MUser = 1 << 0,
50
+ ARMMMUIdxBit_MPriv = 1 << 1,
51
} ARMMMUIdxBit;
52
53
#define MMU_USER_IDX 0
54
@@ -XXX,XX +XXX,XX @@ static inline int arm_to_core_mmu_idx(ARMMMUIdx mmu_idx)
55
56
static inline ARMMMUIdx core_to_arm_mmu_idx(CPUARMState *env, int mmu_idx)
57
{
58
- return mmu_idx | ARM_MMU_IDX_A;
59
+ if (arm_feature(env, ARM_FEATURE_M)) {
60
+ return mmu_idx | ARM_MMU_IDX_M;
61
+ } else {
62
+ return mmu_idx | ARM_MMU_IDX_A;
63
+ }
64
}
65
66
/* Return the exception level we're running at if this is our mmu_idx */
67
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
68
switch (mmu_idx & ARM_MMU_IDX_TYPE_MASK) {
69
case ARM_MMU_IDX_A:
70
return mmu_idx & 3;
71
+ case ARM_MMU_IDX_M:
72
+ return mmu_idx & 1;
73
default:
74
g_assert_not_reached();
75
}
76
@@ -XXX,XX +XXX,XX @@ static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
77
{
78
int el = arm_current_el(env);
79
80
+ if (arm_feature(env, ARM_FEATURE_M)) {
81
+ ARMMMUIdx mmu_idx = el == 0 ? ARMMMUIdx_MUser : ARMMMUIdx_MPriv;
82
+
27
+
83
+ return arm_to_core_mmu_idx(mmu_idx);
28
+ /* Minimal RAS registers */
84
+ }
29
+ uint64_t disr_el1;
85
+
30
+ uint64_t vdisr_el2;
86
if (el < 2 && arm_is_secure_below_el3(env)) {
31
+ uint64_t vsesr_el2;
87
return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0 + el);
32
} cp15;
88
}
33
34
struct {
89
diff --git a/target/arm/helper.c b/target/arm/helper.c
35
diff --git a/target/arm/helper.c b/target/arm/helper.c
90
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
91
--- a/target/arm/helper.c
37
--- a/target/arm/helper.c
92
+++ b/target/arm/helper.c
38
+++ b/target/arm/helper.c
93
@@ -XXX,XX +XXX,XX @@ static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
39
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
94
case ARMMMUIdx_S1SE1:
40
.access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
95
case ARMMMUIdx_S1NSE0:
41
};
96
case ARMMMUIdx_S1NSE1:
42
97
+ case ARMMMUIdx_MPriv:
43
+/*
98
+ case ARMMMUIdx_MUser:
44
+ * Check for traps to RAS registers, which are controlled
99
return 1;
45
+ * by HCR_EL2.TERR and SCR_EL3.TERR.
100
default:
46
+ */
101
g_assert_not_reached();
47
+static CPAccessResult access_terr(CPUARMState *env, const ARMCPRegInfo *ri,
102
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
48
+ bool isread)
103
case ARMMMUIdx_S1NSE1:
49
+{
104
case ARMMMUIdx_S1E2:
50
+ int el = arm_current_el(env);
105
case ARMMMUIdx_S2NS:
51
+
106
+ case ARMMMUIdx_MPriv:
52
+ if (el < 2 && (arm_hcr_el2_eff(env) & HCR_TERR)) {
107
+ case ARMMMUIdx_MUser:
53
+ return CP_ACCESS_TRAP_EL2;
108
return false;
54
+ }
109
case ARMMMUIdx_S1E3:
55
+ if (el < 3 && (env->cp15.scr_el3 & SCR_TERR)) {
110
case ARMMMUIdx_S1SE0:
56
+ return CP_ACCESS_TRAP_EL3;
111
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
57
+ }
112
switch (mmu_idx) {
58
+ return CP_ACCESS_OK;
113
case ARMMMUIdx_S1SE0:
59
+}
114
case ARMMMUIdx_S1NSE0:
60
+
115
+ case ARMMMUIdx_MUser:
61
+static uint64_t disr_read(CPUARMState *env, const ARMCPRegInfo *ri)
116
return true;
62
+{
117
default:
63
+ int el = arm_current_el(env);
118
return false;
64
+
119
diff --git a/target/arm/translate.c b/target/arm/translate.c
65
+ if (el < 2 && (arm_hcr_el2_eff(env) & HCR_AMO)) {
120
index XXXXXXX..XXXXXXX 100644
66
+ return env->cp15.vdisr_el2;
121
--- a/target/arm/translate.c
67
+ }
122
+++ b/target/arm/translate.c
68
+ if (el < 3 && (env->cp15.scr_el3 & SCR_EA)) {
123
@@ -XXX,XX +XXX,XX @@ static inline int get_a32_user_mem_index(DisasContext *s)
69
+ return 0; /* RAZ/WI */
124
case ARMMMUIdx_S1SE0:
70
+ }
125
case ARMMMUIdx_S1SE1:
71
+ return env->cp15.disr_el1;
126
return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
72
+}
127
+ case ARMMMUIdx_MUser:
73
+
128
+ case ARMMMUIdx_MPriv:
74
+static void disr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t val)
129
+ return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
75
+{
130
case ARMMMUIdx_S2NS:
76
+ int el = arm_current_el(env);
131
default:
77
+
132
g_assert_not_reached();
78
+ if (el < 2 && (arm_hcr_el2_eff(env) & HCR_AMO)) {
79
+ env->cp15.vdisr_el2 = val;
80
+ return;
81
+ }
82
+ if (el < 3 && (env->cp15.scr_el3 & SCR_EA)) {
83
+ return; /* RAZ/WI */
84
+ }
85
+ env->cp15.disr_el1 = val;
86
+}
87
+
88
+/*
89
+ * Minimal RAS implementation with no Error Records.
90
+ * Which means that all of the Error Record registers:
91
+ * ERXADDR_EL1
92
+ * ERXCTLR_EL1
93
+ * ERXFR_EL1
94
+ * ERXMISC0_EL1
95
+ * ERXMISC1_EL1
96
+ * ERXMISC2_EL1
97
+ * ERXMISC3_EL1
98
+ * ERXPFGCDN_EL1 (RASv1p1)
99
+ * ERXPFGCTL_EL1 (RASv1p1)
100
+ * ERXPFGF_EL1 (RASv1p1)
101
+ * ERXSTATUS_EL1
102
+ * and
103
+ * ERRSELR_EL1
104
+ * may generate UNDEFINED, which is the effect we get by not
105
+ * listing them at all.
106
+ */
107
+static const ARMCPRegInfo minimal_ras_reginfo[] = {
108
+ { .name = "DISR_EL1", .state = ARM_CP_STATE_BOTH,
109
+ .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 1, .opc2 = 1,
110
+ .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.disr_el1),
111
+ .readfn = disr_read, .writefn = disr_write, .raw_writefn = raw_write },
112
+ { .name = "ERRIDR_EL1", .state = ARM_CP_STATE_BOTH,
113
+ .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 3, .opc2 = 0,
114
+ .access = PL1_R, .accessfn = access_terr,
115
+ .type = ARM_CP_CONST, .resetvalue = 0 },
116
+ { .name = "VDISR_EL2", .state = ARM_CP_STATE_BOTH,
117
+ .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 1, .opc2 = 1,
118
+ .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.vdisr_el2) },
119
+ { .name = "VSESR_EL2", .state = ARM_CP_STATE_BOTH,
120
+ .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 3,
121
+ .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.vsesr_el2) },
122
+};
123
+
124
/* Return the exception level to which exceptions should be taken
125
* via SVEAccessTrap. If an exception should be routed through
126
* AArch64.AdvSIMDFPAccessTrap, return 0; fp_exception_el should
127
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
128
if (cpu_isar_feature(aa64_ssbs, cpu)) {
129
define_one_arm_cp_reg(cpu, &ssbs_reginfo);
130
}
131
+ if (cpu_isar_feature(any_ras, cpu)) {
132
+ define_arm_cp_regs(cpu, minimal_ras_reginfo);
133
+ }
134
135
if (cpu_isar_feature(aa64_vh, cpu) ||
136
cpu_isar_feature(aa64_debugv8p2, cpu)) {
133
--
137
--
134
2.7.4
138
2.25.1
135
136
diff view generated by jsdifflib
1
From: Michael Davidsaver <mdavidsaver@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Improve the "-d mmu" tracing for the PMSAv7 MPU translation
3
Enable writes to the TERR and TEA bits when RAS is enabled.
4
process as an aid in debugging guest MPU configurations:
4
These bits are otherwise RES0.
5
* fix a missing newline for a guest-error log
6
* report the region number with guest-error or unimp
7
logs of bad region register values
8
* add a log message for the overall result of the lookup
9
* print "0x" prefix for hex values
10
5
11
Signed-off-by: Michael Davidsaver <mdavidsaver@gmail.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20220506180242.216785-15-richard.henderson@linaro.org
14
Message-id: 1493122030-32191-9-git-send-email-peter.maydell@linaro.org
15
[PMM: a little tidyup, report region number in all messages
16
rather than just one]
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
10
---
19
target/arm/helper.c | 39 +++++++++++++++++++++++++++------------
11
target/arm/helper.c | 9 +++++++++
20
1 file changed, 27 insertions(+), 12 deletions(-)
12
1 file changed, 9 insertions(+)
21
13
22
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
23
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/helper.c
16
--- a/target/arm/helper.c
25
+++ b/target/arm/helper.c
17
+++ b/target/arm/helper.c
26
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
18
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
27
}
19
}
28
20
valid_mask &= ~SCR_NET;
29
if (!rsize) {
21
30
- qemu_log_mask(LOG_GUEST_ERROR, "DRSR.Rsize field can not be 0");
22
+ if (cpu_isar_feature(aa64_ras, cpu)) {
31
+ qemu_log_mask(LOG_GUEST_ERROR,
23
+ valid_mask |= SCR_TERR;
32
+ "DRSR[%d]: Rsize field cannot be 0\n", n);
24
+ }
33
continue;
25
if (cpu_isar_feature(aa64_lor, cpu)) {
34
}
26
valid_mask |= SCR_TLOR;
35
rsize++;
27
}
36
rmask = (1ull << rsize) - 1;
28
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
37
29
}
38
if (base & rmask) {
30
} else {
39
- qemu_log_mask(LOG_GUEST_ERROR, "DRBAR %" PRIx32 " misaligned "
31
valid_mask &= ~(SCR_RW | SCR_ST);
40
- "to DRSR region size, mask = %" PRIx32,
32
+ if (cpu_isar_feature(aa32_ras, cpu)) {
41
- base, rmask);
33
+ valid_mask |= SCR_TERR;
42
+ qemu_log_mask(LOG_GUEST_ERROR,
34
+ }
43
+ "DRBAR[%d]: 0x%" PRIx32 " misaligned "
44
+ "to DRSR region size, mask = 0x%" PRIx32 "\n",
45
+ n, base, rmask);
46
continue;
47
}
48
49
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
50
}
51
}
52
if (rsize < TARGET_PAGE_BITS) {
53
- qemu_log_mask(LOG_UNIMP, "No support for MPU (sub)region"
54
+ qemu_log_mask(LOG_UNIMP,
55
+ "DRSR[%d]: No support for MPU (sub)region "
56
"alignment of %" PRIu32 " bits. Minimum is %d\n",
57
- rsize, TARGET_PAGE_BITS);
58
+ n, rsize, TARGET_PAGE_BITS);
59
continue;
60
}
61
if (srdis) {
62
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
63
break;
64
default:
65
qemu_log_mask(LOG_GUEST_ERROR,
66
- "Bad value for AP bits in DRACR %"
67
- PRIx32 "\n", ap);
68
+ "DRACR[%d]: Bad value for AP bits: 0x%"
69
+ PRIx32 "\n", n, ap);
70
}
71
} else { /* Priv. mode AP bits decoding */
72
switch (ap) {
73
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
74
break;
75
default:
76
qemu_log_mask(LOG_GUEST_ERROR,
77
- "Bad value for AP bits in DRACR %"
78
- PRIx32 "\n", ap);
79
+ "DRACR[%d]: Bad value for AP bits: 0x%"
80
+ PRIx32 "\n", n, ap);
81
}
82
}
83
84
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
85
*/
86
if (arm_feature(env, ARM_FEATURE_PMSA) &&
87
arm_feature(env, ARM_FEATURE_V7)) {
88
+ bool ret;
89
*page_size = TARGET_PAGE_SIZE;
90
- return get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
91
- phys_ptr, prot, fsr);
92
+ ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
93
+ phys_ptr, prot, fsr);
94
+ qemu_log_mask(CPU_LOG_MMU, "PMSAv7 MPU lookup for %s at 0x%08" PRIx32
95
+ " mmu_idx %u -> %s (prot %c%c%c)\n",
96
+ access_type == 1 ? "reading" :
97
+ (access_type == 2 ? "writing" : "execute"),
98
+ (uint32_t)address, mmu_idx,
99
+ ret ? "Miss" : "Hit",
100
+ *prot & PAGE_READ ? 'r' : '-',
101
+ *prot & PAGE_WRITE ? 'w' : '-',
102
+ *prot & PAGE_EXEC ? 'x' : '-');
103
+
104
+ return ret;
105
}
35
}
106
36
107
if (regime_translation_disabled(env, mmu_idx)) {
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
}
108
--
48
--
109
2.7.4
49
2.25.1
110
111
diff view generated by jsdifflib
1
ARM CPUs come in two flavours:
1
From: Richard Henderson <richard.henderson@linaro.org>
2
* proper MMU ("VMSA")
3
* only an MPU ("PMSA")
4
For PMSA, the MPU may be implemented, or not (in which case there
5
is default "always acts the same" behaviour, but it isn't guest
6
programmable).
7
2
8
QEMU is a bit confused about how we indicate this: we have an
3
Virtual SError exceptions are raised by setting HCR_EL2.VSE,
9
ARM_FEATURE_MPU, but it's not clear whether this indicates
4
and are routed to EL1 just like other virtual exceptions.
10
"PMSA, not VMSA" or "PMSA and MPU present" , and sometimes we
11
use it for one purpose and sometimes the other.
12
5
13
Currently trying to implement a PMSA-without-MPU core won't
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
work correctly because we turn off the ARM_FEATURE_MPU bit
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
and then a lot of things which should still exist get
8
Message-id: 20220506180242.216785-16-richard.henderson@linaro.org
16
turned off too.
17
18
As the first step in cleaning this up, rename the feature
19
bit to ARM_FEATURE_PMSA, which indicates a PMSA CPU (with
20
or without MPU).
21
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
24
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
25
Message-id: 1493122030-32191-5-git-send-email-peter.maydell@linaro.org
26
---
10
---
27
target/arm/cpu.h | 2 +-
11
target/arm/cpu.h | 2 ++
28
target/arm/cpu.c | 12 ++++++------
12
target/arm/internals.h | 8 ++++++++
29
target/arm/helper.c | 12 ++++++------
13
target/arm/syndrome.h | 5 +++++
30
target/arm/machine.c | 2 +-
14
target/arm/cpu.c | 38 +++++++++++++++++++++++++++++++++++++-
31
4 files changed, 14 insertions(+), 14 deletions(-)
15
target/arm/helper.c | 40 +++++++++++++++++++++++++++++++++++++++-
16
5 files changed, 91 insertions(+), 2 deletions(-)
32
17
33
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
34
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/cpu.h
20
--- a/target/arm/cpu.h
36
+++ b/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
37
@@ -XXX,XX +XXX,XX @@ enum arm_features {
22
@@ -XXX,XX +XXX,XX @@
38
ARM_FEATURE_V6K,
23
#define EXCP_LSERR 21 /* v8M LSERR SecureFault */
39
ARM_FEATURE_V7,
24
#define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */
40
ARM_FEATURE_THUMB2,
25
#define EXCP_DIVBYZERO 23 /* v7M DIVBYZERO UsageFault */
41
- ARM_FEATURE_MPU, /* Only has Memory Protection Unit, not full MMU. */
26
+#define EXCP_VSERR 24
42
+ ARM_FEATURE_PMSA, /* no MMU; may have Memory Protection Unit */
27
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
43
ARM_FEATURE_VFP3,
28
44
ARM_FEATURE_VFP_FP16,
29
#define ARMV7M_EXCP_RESET 1
45
ARM_FEATURE_NEON,
30
@@ -XXX,XX +XXX,XX @@ enum {
31
#define CPU_INTERRUPT_FIQ CPU_INTERRUPT_TGT_EXT_1
32
#define CPU_INTERRUPT_VIRQ CPU_INTERRUPT_TGT_EXT_2
33
#define CPU_INTERRUPT_VFIQ CPU_INTERRUPT_TGT_EXT_3
34
+#define CPU_INTERRUPT_VSERR CPU_INTERRUPT_TGT_INT_0
35
36
/* The usual mapping for an AArch64 system register to its AArch32
37
* counterpart is for the 32 bit world to have access to the lower
38
diff --git a/target/arm/internals.h b/target/arm/internals.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/internals.h
41
+++ b/target/arm/internals.h
42
@@ -XXX,XX +XXX,XX @@ void arm_cpu_update_virq(ARMCPU *cpu);
43
*/
44
void arm_cpu_update_vfiq(ARMCPU *cpu);
45
46
+/**
47
+ * arm_cpu_update_vserr: Update CPU_INTERRUPT_VSERR bit
48
+ *
49
+ * Update the CPU_INTERRUPT_VSERR bit in cs->interrupt_request,
50
+ * following a change to the HCR_EL2.VSE bit.
51
+ */
52
+void arm_cpu_update_vserr(ARMCPU *cpu);
53
+
54
/**
55
* arm_mmu_idx_el:
56
* @env: The cpu environment
57
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/syndrome.h
60
+++ b/target/arm/syndrome.h
61
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_pcalignment(void)
62
return (EC_PCALIGNMENT << ARM_EL_EC_SHIFT) | ARM_EL_IL;
63
}
64
65
+static inline uint32_t syn_serror(uint32_t extra)
66
+{
67
+ return (EC_SERROR << ARM_EL_EC_SHIFT) | ARM_EL_IL | extra;
68
+}
69
+
70
#endif /* TARGET_ARM_SYNDROME_H */
46
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
71
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
47
index XXXXXXX..XXXXXXX 100644
72
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/cpu.c
73
--- a/target/arm/cpu.c
49
+++ b/target/arm/cpu.c
74
+++ b/target/arm/cpu.c
50
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_post_init(Object *obj)
75
@@ -XXX,XX +XXX,XX @@ static bool arm_cpu_has_work(CPUState *cs)
51
&error_abort);
76
return (cpu->power_state != PSCI_OFF)
52
}
77
&& cs->interrupt_request &
53
78
(CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD
54
- if (arm_feature(&cpu->env, ARM_FEATURE_MPU)) {
79
- | CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ
55
+ if (arm_feature(&cpu->env, ARM_FEATURE_PMSA)) {
80
+ | CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ | CPU_INTERRUPT_VSERR
56
qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property,
81
| CPU_INTERRUPT_EXITTB);
57
&error_abort);
82
}
58
if (arm_feature(&cpu->env, ARM_FEATURE_V7)) {
83
59
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
84
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
60
85
return false;
61
if (arm_feature(env, ARM_FEATURE_V7) &&
86
}
62
!arm_feature(env, ARM_FEATURE_M) &&
87
return !(env->daif & PSTATE_I);
63
- !arm_feature(env, ARM_FEATURE_MPU)) {
88
+ case EXCP_VSERR:
64
+ !arm_feature(env, ARM_FEATURE_PMSA)) {
89
+ if (!(hcr_el2 & HCR_AMO) || (hcr_el2 & HCR_TGE)) {
65
/* v7VMSA drops support for the old ARMv5 tiny pages, so we
90
+ /* VIRQs are only taken when hypervized. */
66
* can use 4K pages.
91
+ return false;
67
*/
92
+ }
68
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
93
+ return !(env->daif & PSTATE_A);
69
}
94
default:
70
95
g_assert_not_reached();
71
if (!cpu->has_mpu) {
96
}
72
- unset_feature(env, ARM_FEATURE_MPU);
97
@@ -XXX,XX +XXX,XX @@ static bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
73
+ unset_feature(env, ARM_FEATURE_PMSA);
98
goto found;
74
}
99
}
75
100
}
76
- if (arm_feature(env, ARM_FEATURE_MPU) &&
101
+ if (interrupt_request & CPU_INTERRUPT_VSERR) {
77
+ if (arm_feature(env, ARM_FEATURE_PMSA) &&
102
+ excp_idx = EXCP_VSERR;
78
arm_feature(env, ARM_FEATURE_V7)) {
103
+ target_el = 1;
79
uint32_t nr = cpu->pmsav7_dregion;
104
+ if (arm_excp_unmasked(cs, excp_idx, target_el,
80
105
+ cur_el, secure, hcr_el2)) {
81
@@ -XXX,XX +XXX,XX @@ static void arm946_initfn(Object *obj)
106
+ /* Taking a virtual abort clears HCR_EL2.VSE */
82
107
+ env->cp15.hcr_el2 &= ~HCR_VSE;
83
cpu->dtb_compatible = "arm,arm946";
108
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_VSERR);
84
set_feature(&cpu->env, ARM_FEATURE_V5);
109
+ goto found;
85
- set_feature(&cpu->env, ARM_FEATURE_MPU);
110
+ }
86
+ set_feature(&cpu->env, ARM_FEATURE_PMSA);
111
+ }
87
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
112
return false;
88
cpu->midr = 0x41059461;
113
89
cpu->ctr = 0x0f004006;
114
found:
90
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
115
@@ -XXX,XX +XXX,XX @@ void arm_cpu_update_vfiq(ARMCPU *cpu)
91
set_feature(&cpu->env, ARM_FEATURE_THUMB_DIV);
116
}
92
set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
117
}
93
set_feature(&cpu->env, ARM_FEATURE_V7MP);
118
94
- set_feature(&cpu->env, ARM_FEATURE_MPU);
119
+void arm_cpu_update_vserr(ARMCPU *cpu)
95
+ set_feature(&cpu->env, ARM_FEATURE_PMSA);
120
+{
96
cpu->midr = 0x411fc153; /* r1p3 */
121
+ /*
97
cpu->id_pfr0 = 0x0131;
122
+ * Update the interrupt level for VSERR, which is the HCR_EL2.VSE bit.
98
cpu->id_pfr1 = 0x001;
123
+ */
124
+ CPUARMState *env = &cpu->env;
125
+ CPUState *cs = CPU(cpu);
126
+
127
+ bool new_state = env->cp15.hcr_el2 & HCR_VSE;
128
+
129
+ if (new_state != ((cs->interrupt_request & CPU_INTERRUPT_VSERR) != 0)) {
130
+ if (new_state) {
131
+ cpu_interrupt(cs, CPU_INTERRUPT_VSERR);
132
+ } else {
133
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_VSERR);
134
+ }
135
+ }
136
+}
137
+
138
#ifndef CONFIG_USER_ONLY
139
static void arm_cpu_set_irq(void *opaque, int irq, int level)
140
{
99
diff --git a/target/arm/helper.c b/target/arm/helper.c
141
diff --git a/target/arm/helper.c b/target/arm/helper.c
100
index XXXXXXX..XXXXXXX 100644
142
index XXXXXXX..XXXXXXX 100644
101
--- a/target/arm/helper.c
143
--- a/target/arm/helper.c
102
+++ b/target/arm/helper.c
144
+++ b/target/arm/helper.c
103
@@ -XXX,XX +XXX,XX @@ static void contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri,
145
@@ -XXX,XX +XXX,XX @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
104
{
105
ARMCPU *cpu = arm_env_get_cpu(env);
106
107
- if (raw_read(env, ri) != value && !arm_feature(env, ARM_FEATURE_MPU)
108
+ if (raw_read(env, ri) != value && !arm_feature(env, ARM_FEATURE_PMSA)
109
&& !extended_addresses_enabled(env)) {
110
/* For VMSA (when not using the LPAE long descriptor page table
111
* format) this register includes the ASID, so do a TLB flush.
112
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
113
define_arm_cp_regs(cpu, v6k_cp_reginfo);
114
}
115
if (arm_feature(env, ARM_FEATURE_V7MP) &&
116
- !arm_feature(env, ARM_FEATURE_MPU)) {
117
+ !arm_feature(env, ARM_FEATURE_PMSA)) {
118
define_arm_cp_regs(cpu, v7mp_cp_reginfo);
119
}
120
if (arm_feature(env, ARM_FEATURE_V7)) {
121
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
122
}
146
}
123
}
147
}
124
148
125
- if (arm_feature(env, ARM_FEATURE_MPU)) {
149
- /* External aborts are not possible in QEMU so A bit is always clear */
126
+ if (arm_feature(env, ARM_FEATURE_PMSA)) {
150
+ if (hcr_el2 & HCR_AMO) {
127
if (arm_feature(env, ARM_FEATURE_V6)) {
151
+ if (cs->interrupt_request & CPU_INTERRUPT_VSERR) {
128
/* PMSAv6 not implemented */
152
+ ret |= CPSR_A;
129
assert(arm_feature(env, ARM_FEATURE_V7));
153
+ }
130
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
154
+ }
131
define_arm_cp_regs(cpu, id_pre_v8_midr_cp_reginfo);
155
+
132
}
156
return ret;
133
define_arm_cp_regs(cpu, id_cp_reginfo);
157
}
134
- if (!arm_feature(env, ARM_FEATURE_MPU)) {
158
135
+ if (!arm_feature(env, ARM_FEATURE_PMSA)) {
159
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
136
define_one_arm_cp_reg(cpu, &id_tlbtr_reginfo);
160
g_assert(qemu_mutex_iothread_locked());
137
} else if (arm_feature(env, ARM_FEATURE_V7)) {
161
arm_cpu_update_virq(cpu);
138
define_one_arm_cp_reg(cpu, &id_mpuir_reginfo);
162
arm_cpu_update_vfiq(cpu);
139
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
163
+ arm_cpu_update_vserr(cpu);
140
/* pmsav7 has special handling for when MPU is disabled so call it before
164
}
141
* the common MMU/MPU disabled check below.
165
142
*/
166
static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
143
- if (arm_feature(env, ARM_FEATURE_MPU) &&
167
@@ -XXX,XX +XXX,XX @@ void arm_log_exception(CPUState *cs)
144
+ if (arm_feature(env, ARM_FEATURE_PMSA) &&
168
[EXCP_LSERR] = "v8M LSERR UsageFault",
145
arm_feature(env, ARM_FEATURE_V7)) {
169
[EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
146
*page_size = TARGET_PAGE_SIZE;
170
[EXCP_DIVBYZERO] = "v7M DIVBYZERO UsageFault",
147
return get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
171
+ [EXCP_VSERR] = "Virtual SERR",
148
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
172
};
149
return 0;
173
150
}
174
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
151
175
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
152
- if (arm_feature(env, ARM_FEATURE_MPU)) {
176
mask = CPSR_A | CPSR_I | CPSR_F;
153
+ if (arm_feature(env, ARM_FEATURE_PMSA)) {
177
offset = 4;
154
/* Pre-v7 MPU */
178
break;
155
*page_size = TARGET_PAGE_SIZE;
179
+ case EXCP_VSERR:
156
return get_phys_addr_pmsav5(env, address, access_type, mmu_idx,
180
+ {
157
diff --git a/target/arm/machine.c b/target/arm/machine.c
181
+ /*
158
index XXXXXXX..XXXXXXX 100644
182
+ * Note that this is reported as a data abort, but the DFAR
159
--- a/target/arm/machine.c
183
+ * has an UNKNOWN value. Construct the SError syndrome from
160
+++ b/target/arm/machine.c
184
+ * AET and ExT fields.
161
@@ -XXX,XX +XXX,XX @@ static bool pmsav7_needed(void *opaque)
185
+ */
162
ARMCPU *cpu = opaque;
186
+ ARMMMUFaultInfo fi = { .type = ARMFault_AsyncExternal, };
163
CPUARMState *env = &cpu->env;
187
+
164
188
+ if (extended_addresses_enabled(env)) {
165
- return arm_feature(env, ARM_FEATURE_MPU) &&
189
+ env->exception.fsr = arm_fi_to_lfsc(&fi);
166
+ return arm_feature(env, ARM_FEATURE_PMSA) &&
190
+ } else {
167
arm_feature(env, ARM_FEATURE_V7);
191
+ env->exception.fsr = arm_fi_to_sfsc(&fi);
168
}
192
+ }
169
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
}
170
--
220
--
171
2.7.4
221
2.25.1
172
173
diff view generated by jsdifflib
1
The M profile CPU's MPU has an awkward corner case which we
1
From: Richard Henderson <richard.henderson@linaro.org>
2
would like to implement with a different MMU index.
3
2
4
We can avoid having to bump the number of MMU modes ARM
3
Check for and defer any pending virtual SError.
5
uses, because some of our existing MMU indexes are only
6
used by non-M-profile CPUs, so we can borrow one.
7
To avoid that getting too confusing, clean up the code
8
to try to keep the two meanings of the index separate.
9
4
10
Instead of ARMMMUIdx enum values being identical to core QEMU
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
MMU index values, they are now the core index values with some
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
high bits set. Any particular CPU always uses the same high
7
Message-id: 20220506180242.216785-17-richard.henderson@linaro.org
13
bits (so eventually A profile cores and M profile cores will
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
use different bits). New functions arm_to_core_mmu_idx()
9
---
15
and core_to_arm_mmu_idx() convert between the two.
10
target/arm/helper.h | 1 +
11
target/arm/a32.decode | 16 ++++++++------
12
target/arm/t32.decode | 18 ++++++++--------
13
target/arm/op_helper.c | 43 ++++++++++++++++++++++++++++++++++++++
14
target/arm/translate-a64.c | 17 +++++++++++++++
15
target/arm/translate.c | 23 ++++++++++++++++++++
16
6 files changed, 103 insertions(+), 15 deletions(-)
16
17
17
In general core index values are stored in 'int' types, and
18
diff --git a/target/arm/helper.h b/target/arm/helper.h
18
ARM values are stored in ARMMMUIdx types.
19
index XXXXXXX..XXXXXXX 100644
19
20
--- a/target/arm/helper.h
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
+++ b/target/arm/helper.h
21
Message-id: 1493122030-32191-3-git-send-email-peter.maydell@linaro.org
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(wfe, void, env)
22
---
23
DEF_HELPER_1(yield, void, env)
23
target/arm/cpu.h | 71 ++++++++++++++++-----
24
DEF_HELPER_1(pre_hvc, void, env)
24
target/arm/translate.h | 2 +-
25
DEF_HELPER_2(pre_smc, void, env, i32)
25
target/arm/helper.c | 151 ++++++++++++++++++++++++---------------------
26
+DEF_HELPER_1(vesb, void, env)
26
target/arm/op_helper.c | 3 +-
27
27
target/arm/translate-a64.c | 18 ++++--
28
DEF_HELPER_3(cpsr_write, void, env, i32, i32)
28
target/arm/translate.c | 10 +--
29
DEF_HELPER_2(cpsr_write_eret, void, env, i32)
29
6 files changed, 156 insertions(+), 99 deletions(-)
30
diff --git a/target/arm/a32.decode b/target/arm/a32.decode
30
31
index XXXXXXX..XXXXXXX 100644
31
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
32
--- a/target/arm/a32.decode
32
index XXXXXXX..XXXXXXX 100644
33
+++ b/target/arm/a32.decode
33
--- a/target/arm/cpu.h
34
@@ -XXX,XX +XXX,XX @@ SMULTT .... 0001 0110 .... 0000 .... 1110 .... @rd0mn
34
+++ b/target/arm/cpu.h
35
35
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
36
* for the accesses done as part of a stage 1 page table walk, rather than
37
* having to walk the stage 2 page table over and over.)
38
*
39
+ * The ARMMMUIdx and the mmu index value used by the core QEMU TLB code
40
+ * are not quite the same -- different CPU types (most notably M profile
41
+ * vs A/R profile) would like to use MMU indexes with different semantics,
42
+ * but since we don't ever need to use all of those in a single CPU we
43
+ * can avoid setting NB_MMU_MODES to more than 8. The lower bits of
44
+ * ARMMMUIdx are the core TLB mmu index, and the higher bits are always
45
+ * the same for any particular CPU.
46
+ * Variables of type ARMMUIdx are always full values, and the core
47
+ * index values are in variables of type 'int'.
48
+ *
49
* Our enumeration includes at the end some entries which are not "true"
50
* mmu_idx values in that they don't have corresponding TLBs and are only
51
* valid for doing slow path page table walks.
52
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
53
* of the AT/ATS operations.
54
* The values used are carefully arranged to make mmu_idx => EL lookup easy.
55
*/
56
+#define ARM_MMU_IDX_A 0x10 /* A profile (and M profile, for the moment) */
57
+#define ARM_MMU_IDX_NOTLB 0x20 /* does not have a TLB */
58
+
59
+#define ARM_MMU_IDX_TYPE_MASK (~0x7)
60
+#define ARM_MMU_IDX_COREIDX_MASK 0x7
61
+
62
typedef enum ARMMMUIdx {
63
- ARMMMUIdx_S12NSE0 = 0,
64
- ARMMMUIdx_S12NSE1 = 1,
65
- ARMMMUIdx_S1E2 = 2,
66
- ARMMMUIdx_S1E3 = 3,
67
- ARMMMUIdx_S1SE0 = 4,
68
- ARMMMUIdx_S1SE1 = 5,
69
- ARMMMUIdx_S2NS = 6,
70
+ ARMMMUIdx_S12NSE0 = 0 | ARM_MMU_IDX_A,
71
+ ARMMMUIdx_S12NSE1 = 1 | ARM_MMU_IDX_A,
72
+ ARMMMUIdx_S1E2 = 2 | ARM_MMU_IDX_A,
73
+ ARMMMUIdx_S1E3 = 3 | ARM_MMU_IDX_A,
74
+ ARMMMUIdx_S1SE0 = 4 | ARM_MMU_IDX_A,
75
+ ARMMMUIdx_S1SE1 = 5 | ARM_MMU_IDX_A,
76
+ ARMMMUIdx_S2NS = 6 | ARM_MMU_IDX_A,
77
/* Indexes below here don't have TLBs and are used only for AT system
78
* instructions or for the first stage of an S12 page table walk.
79
*/
80
- ARMMMUIdx_S1NSE0 = 7,
81
- ARMMMUIdx_S1NSE1 = 8,
82
+ ARMMMUIdx_S1NSE0 = 0 | ARM_MMU_IDX_NOTLB,
83
+ ARMMMUIdx_S1NSE1 = 1 | ARM_MMU_IDX_NOTLB,
84
} ARMMMUIdx;
85
86
+/* Bit macros for the core-mmu-index values for each index,
87
+ * for use when calling tlb_flush_by_mmuidx() and friends.
88
+ */
89
+typedef enum ARMMMUIdxBit {
90
+ ARMMMUIdxBit_S12NSE0 = 1 << 0,
91
+ ARMMMUIdxBit_S12NSE1 = 1 << 1,
92
+ ARMMMUIdxBit_S1E2 = 1 << 2,
93
+ ARMMMUIdxBit_S1E3 = 1 << 3,
94
+ ARMMMUIdxBit_S1SE0 = 1 << 4,
95
+ ARMMMUIdxBit_S1SE1 = 1 << 5,
96
+ ARMMMUIdxBit_S2NS = 1 << 6,
97
+} ARMMMUIdxBit;
98
+
99
#define MMU_USER_IDX 0
100
101
+static inline int arm_to_core_mmu_idx(ARMMMUIdx mmu_idx)
102
+{
103
+ return mmu_idx & ARM_MMU_IDX_COREIDX_MASK;
104
+}
105
+
106
+static inline ARMMMUIdx core_to_arm_mmu_idx(CPUARMState *env, int mmu_idx)
107
+{
108
+ return mmu_idx | ARM_MMU_IDX_A;
109
+}
110
+
111
/* Return the exception level we're running at if this is our mmu_idx */
112
static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
113
{
36
{
114
- assert(mmu_idx < ARMMMUIdx_S2NS);
37
{
115
- return mmu_idx & 3;
38
- YIELD ---- 0011 0010 0000 1111 ---- 0000 0001
116
+ switch (mmu_idx & ARM_MMU_IDX_TYPE_MASK) {
39
- WFE ---- 0011 0010 0000 1111 ---- 0000 0010
117
+ case ARM_MMU_IDX_A:
40
- WFI ---- 0011 0010 0000 1111 ---- 0000 0011
118
+ return mmu_idx & 3;
41
+ [
119
+ default:
42
+ YIELD ---- 0011 0010 0000 1111 ---- 0000 0001
120
+ g_assert_not_reached();
43
+ WFE ---- 0011 0010 0000 1111 ---- 0000 0010
121
+ }
44
+ WFI ---- 0011 0010 0000 1111 ---- 0000 0011
122
}
45
123
46
- # TODO: Implement SEV, SEVL; may help SMP performance.
124
/* Determine the current mmu_idx to use for normal loads/stores */
47
- # SEV ---- 0011 0010 0000 1111 ---- 0000 0100
125
@@ -XXX,XX +XXX,XX @@ static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
48
- # SEVL ---- 0011 0010 0000 1111 ---- 0000 0101
126
int el = arm_current_el(env);
49
+ # TODO: Implement SEV, SEVL; may help SMP performance.
127
50
+ # SEV ---- 0011 0010 0000 1111 ---- 0000 0100
128
if (el < 2 && arm_is_secure_below_el3(env)) {
51
+ # SEVL ---- 0011 0010 0000 1111 ---- 0000 0101
129
- return ARMMMUIdx_S1SE0 + el;
52
+
130
+ return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0 + el);
53
+ ESB ---- 0011 0010 0000 1111 ---- 0001 0000
131
}
54
+ ]
132
return el;
55
133
}
56
# The canonical nop ends in 00000000, but the whole of the
134
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx)
57
# rest of the space executes as nop if otherwise unsupported.
135
static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
58
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
136
target_ulong *cs_base, uint32_t *flags)
59
index XXXXXXX..XXXXXXX 100644
137
{
60
--- a/target/arm/t32.decode
138
- ARMMMUIdx mmu_idx = cpu_mmu_index(env, false);
61
+++ b/target/arm/t32.decode
139
+ ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
62
@@ -XXX,XX +XXX,XX @@ CLZ 1111 1010 1011 ---- 1111 .... 1000 .... @rdm
140
if (is_a64(env)) {
63
[
141
*pc = env->pc;
64
# Hints, and CPS
142
*flags = ARM_TBFLAG_AARCH64_STATE_MASK;
65
{
143
@@ -XXX,XX +XXX,XX @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
66
- YIELD 1111 0011 1010 1111 1000 0000 0000 0001
144
<< ARM_TBFLAG_XSCALE_CPAR_SHIFT);
67
- WFE 1111 0011 1010 1111 1000 0000 0000 0010
145
}
68
- WFI 1111 0011 1010 1111 1000 0000 0000 0011
146
69
+ [
147
- *flags |= (mmu_idx << ARM_TBFLAG_MMUIDX_SHIFT);
70
+ YIELD 1111 0011 1010 1111 1000 0000 0000 0001
148
+ *flags |= (arm_to_core_mmu_idx(mmu_idx) << ARM_TBFLAG_MMUIDX_SHIFT);
71
+ WFE 1111 0011 1010 1111 1000 0000 0000 0010
149
72
+ WFI 1111 0011 1010 1111 1000 0000 0000 0011
150
/* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
73
151
* states defined in the ARM ARM for software singlestep:
74
- # TODO: Implement SEV, SEVL; may help SMP performance.
152
diff --git a/target/arm/translate.h b/target/arm/translate.h
75
- # SEV 1111 0011 1010 1111 1000 0000 0000 0100
153
index XXXXXXX..XXXXXXX 100644
76
- # SEVL 1111 0011 1010 1111 1000 0000 0000 0101
154
--- a/target/arm/translate.h
77
+ # TODO: Implement SEV, SEVL; may help SMP performance.
155
+++ b/target/arm/translate.h
78
+ # SEV 1111 0011 1010 1111 1000 0000 0000 0100
156
@@ -XXX,XX +XXX,XX @@ static inline int arm_dc_feature(DisasContext *dc, int feature)
79
+ # SEVL 1111 0011 1010 1111 1000 0000 0000 0101
157
80
158
static inline int get_mem_index(DisasContext *s)
81
- # For M-profile minimal-RAS ESB can be a NOP, which is the
159
{
82
- # default behaviour since it is in the hint space.
160
- return s->mmu_idx;
83
- # ESB 1111 0011 1010 1111 1000 0000 0001 0000
161
+ return arm_to_core_mmu_idx(s->mmu_idx);
84
+ ESB 1111 0011 1010 1111 1000 0000 0001 0000
162
}
85
+ ]
163
86
164
/* Function used to determine the target exception EL when otherwise not known
87
# The canonical nop ends in 0000 0000, but the whole rest
165
diff --git a/target/arm/helper.c b/target/arm/helper.c
88
# of the space is "reserved hint, behaves as nop".
166
index XXXXXXX..XXXXXXX 100644
89
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
167
--- a/target/arm/helper.c
90
index XXXXXXX..XXXXXXX 100644
168
+++ b/target/arm/helper.c
91
--- a/target/arm/op_helper.c
169
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
92
+++ b/target/arm/op_helper.c
170
CPUState *cs = ENV_GET_CPU(env);
93
@@ -XXX,XX +XXX,XX @@ void HELPER(probe_access)(CPUARMState *env, target_ulong ptr,
171
94
access_type, mmu_idx, ra);
172
tlb_flush_by_mmuidx(cs,
173
- (1 << ARMMMUIdx_S12NSE1) |
174
- (1 << ARMMMUIdx_S12NSE0) |
175
- (1 << ARMMMUIdx_S2NS));
176
+ ARMMMUIdxBit_S12NSE1 |
177
+ ARMMMUIdxBit_S12NSE0 |
178
+ ARMMMUIdxBit_S2NS);
179
}
180
181
static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
182
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
183
CPUState *cs = ENV_GET_CPU(env);
184
185
tlb_flush_by_mmuidx_all_cpus_synced(cs,
186
- (1 << ARMMMUIdx_S12NSE1) |
187
- (1 << ARMMMUIdx_S12NSE0) |
188
- (1 << ARMMMUIdx_S2NS));
189
+ ARMMMUIdxBit_S12NSE1 |
190
+ ARMMMUIdxBit_S12NSE0 |
191
+ ARMMMUIdxBit_S2NS);
192
}
193
194
static void tlbiipas2_write(CPUARMState *env, const ARMCPRegInfo *ri,
195
@@ -XXX,XX +XXX,XX @@ static void tlbiipas2_write(CPUARMState *env, const ARMCPRegInfo *ri,
196
197
pageaddr = sextract64(value << 12, 0, 40);
198
199
- tlb_flush_page_by_mmuidx(cs, pageaddr, (1 << ARMMMUIdx_S2NS));
200
+ tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_S2NS);
201
}
202
203
static void tlbiipas2_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
204
@@ -XXX,XX +XXX,XX @@ static void tlbiipas2_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
205
pageaddr = sextract64(value << 12, 0, 40);
206
207
tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
208
- (1 << ARMMMUIdx_S2NS));
209
+ ARMMMUIdxBit_S2NS);
210
}
211
212
static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
213
@@ -XXX,XX +XXX,XX @@ static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
214
{
215
CPUState *cs = ENV_GET_CPU(env);
216
217
- tlb_flush_by_mmuidx(cs, (1 << ARMMMUIdx_S1E2));
218
+ tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_S1E2);
219
}
220
221
static void tlbiall_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
222
@@ -XXX,XX +XXX,XX @@ static void tlbiall_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
223
{
224
CPUState *cs = ENV_GET_CPU(env);
225
226
- tlb_flush_by_mmuidx_all_cpus_synced(cs, (1 << ARMMMUIdx_S1E2));
227
+ tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_S1E2);
228
}
229
230
static void tlbimva_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
231
@@ -XXX,XX +XXX,XX @@ static void tlbimva_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
232
CPUState *cs = ENV_GET_CPU(env);
233
uint64_t pageaddr = value & ~MAKE_64BIT_MASK(0, 12);
234
235
- tlb_flush_page_by_mmuidx(cs, pageaddr, (1 << ARMMMUIdx_S1E2));
236
+ tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_S1E2);
237
}
238
239
static void tlbimva_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
240
@@ -XXX,XX +XXX,XX @@ static void tlbimva_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
241
uint64_t pageaddr = value & ~MAKE_64BIT_MASK(0, 12);
242
243
tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
244
- (1 << ARMMMUIdx_S1E2));
245
+ ARMMMUIdxBit_S1E2);
246
}
247
248
static const ARMCPRegInfo cp_reginfo[] = {
249
@@ -XXX,XX +XXX,XX @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
250
/* Accesses to VTTBR may change the VMID so we must flush the TLB. */
251
if (raw_read(env, ri) != value) {
252
tlb_flush_by_mmuidx(cs,
253
- (1 << ARMMMUIdx_S12NSE1) |
254
- (1 << ARMMMUIdx_S12NSE0) |
255
- (1 << ARMMMUIdx_S2NS));
256
+ ARMMMUIdxBit_S12NSE1 |
257
+ ARMMMUIdxBit_S12NSE0 |
258
+ ARMMMUIdxBit_S2NS);
259
raw_write(env, ri, value);
260
}
95
}
261
}
96
}
262
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
97
+
263
98
+/*
264
if (arm_is_secure_below_el3(env)) {
99
+ * This function corresponds to AArch64.vESBOperation().
265
tlb_flush_by_mmuidx(cs,
100
+ * Note that the AArch32 version is not functionally different.
266
- (1 << ARMMMUIdx_S1SE1) |
267
- (1 << ARMMMUIdx_S1SE0));
268
+ ARMMMUIdxBit_S1SE1 |
269
+ ARMMMUIdxBit_S1SE0);
270
} else {
271
tlb_flush_by_mmuidx(cs,
272
- (1 << ARMMMUIdx_S12NSE1) |
273
- (1 << ARMMMUIdx_S12NSE0));
274
+ ARMMMUIdxBit_S12NSE1 |
275
+ ARMMMUIdxBit_S12NSE0);
276
}
277
}
278
279
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vmalle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
280
281
if (sec) {
282
tlb_flush_by_mmuidx_all_cpus_synced(cs,
283
- (1 << ARMMMUIdx_S1SE1) |
284
- (1 << ARMMMUIdx_S1SE0));
285
+ ARMMMUIdxBit_S1SE1 |
286
+ ARMMMUIdxBit_S1SE0);
287
} else {
288
tlb_flush_by_mmuidx_all_cpus_synced(cs,
289
- (1 << ARMMMUIdx_S12NSE1) |
290
- (1 << ARMMMUIdx_S12NSE0));
291
+ ARMMMUIdxBit_S12NSE1 |
292
+ ARMMMUIdxBit_S12NSE0);
293
}
294
}
295
296
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
297
298
if (arm_is_secure_below_el3(env)) {
299
tlb_flush_by_mmuidx(cs,
300
- (1 << ARMMMUIdx_S1SE1) |
301
- (1 << ARMMMUIdx_S1SE0));
302
+ ARMMMUIdxBit_S1SE1 |
303
+ ARMMMUIdxBit_S1SE0);
304
} else {
305
if (arm_feature(env, ARM_FEATURE_EL2)) {
306
tlb_flush_by_mmuidx(cs,
307
- (1 << ARMMMUIdx_S12NSE1) |
308
- (1 << ARMMMUIdx_S12NSE0) |
309
- (1 << ARMMMUIdx_S2NS));
310
+ ARMMMUIdxBit_S12NSE1 |
311
+ ARMMMUIdxBit_S12NSE0 |
312
+ ARMMMUIdxBit_S2NS);
313
} else {
314
tlb_flush_by_mmuidx(cs,
315
- (1 << ARMMMUIdx_S12NSE1) |
316
- (1 << ARMMMUIdx_S12NSE0));
317
+ ARMMMUIdxBit_S12NSE1 |
318
+ ARMMMUIdxBit_S12NSE0);
319
}
320
}
321
}
322
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle2_write(CPUARMState *env, const ARMCPRegInfo *ri,
323
ARMCPU *cpu = arm_env_get_cpu(env);
324
CPUState *cs = CPU(cpu);
325
326
- tlb_flush_by_mmuidx(cs, (1 << ARMMMUIdx_S1E2));
327
+ tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_S1E2);
328
}
329
330
static void tlbi_aa64_alle3_write(CPUARMState *env, const ARMCPRegInfo *ri,
331
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle3_write(CPUARMState *env, const ARMCPRegInfo *ri,
332
ARMCPU *cpu = arm_env_get_cpu(env);
333
CPUState *cs = CPU(cpu);
334
335
- tlb_flush_by_mmuidx(cs, (1 << ARMMMUIdx_S1E3));
336
+ tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_S1E3);
337
}
338
339
static void tlbi_aa64_alle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
340
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
341
342
if (sec) {
343
tlb_flush_by_mmuidx_all_cpus_synced(cs,
344
- (1 << ARMMMUIdx_S1SE1) |
345
- (1 << ARMMMUIdx_S1SE0));
346
+ ARMMMUIdxBit_S1SE1 |
347
+ ARMMMUIdxBit_S1SE0);
348
} else if (has_el2) {
349
tlb_flush_by_mmuidx_all_cpus_synced(cs,
350
- (1 << ARMMMUIdx_S12NSE1) |
351
- (1 << ARMMMUIdx_S12NSE0) |
352
- (1 << ARMMMUIdx_S2NS));
353
+ ARMMMUIdxBit_S12NSE1 |
354
+ ARMMMUIdxBit_S12NSE0 |
355
+ ARMMMUIdxBit_S2NS);
356
} else {
357
tlb_flush_by_mmuidx_all_cpus_synced(cs,
358
- (1 << ARMMMUIdx_S12NSE1) |
359
- (1 << ARMMMUIdx_S12NSE0));
360
+ ARMMMUIdxBit_S12NSE1 |
361
+ ARMMMUIdxBit_S12NSE0);
362
}
363
}
364
365
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
366
{
367
CPUState *cs = ENV_GET_CPU(env);
368
369
- tlb_flush_by_mmuidx_all_cpus_synced(cs, (1 << ARMMMUIdx_S1E2));
370
+ tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_S1E2);
371
}
372
373
static void tlbi_aa64_alle3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
374
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
375
{
376
CPUState *cs = ENV_GET_CPU(env);
377
378
- tlb_flush_by_mmuidx_all_cpus_synced(cs, (1 << ARMMMUIdx_S1E3));
379
+ tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_S1E3);
380
}
381
382
static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
383
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
384
385
if (arm_is_secure_below_el3(env)) {
386
tlb_flush_page_by_mmuidx(cs, pageaddr,
387
- (1 << ARMMMUIdx_S1SE1) |
388
- (1 << ARMMMUIdx_S1SE0));
389
+ ARMMMUIdxBit_S1SE1 |
390
+ ARMMMUIdxBit_S1SE0);
391
} else {
392
tlb_flush_page_by_mmuidx(cs, pageaddr,
393
- (1 << ARMMMUIdx_S12NSE1) |
394
- (1 << ARMMMUIdx_S12NSE0));
395
+ ARMMMUIdxBit_S12NSE1 |
396
+ ARMMMUIdxBit_S12NSE0);
397
}
398
}
399
400
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri,
401
CPUState *cs = CPU(cpu);
402
uint64_t pageaddr = sextract64(value << 12, 0, 56);
403
404
- tlb_flush_page_by_mmuidx(cs, pageaddr, (1 << ARMMMUIdx_S1E2));
405
+ tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_S1E2);
406
}
407
408
static void tlbi_aa64_vae3_write(CPUARMState *env, const ARMCPRegInfo *ri,
409
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3_write(CPUARMState *env, const ARMCPRegInfo *ri,
410
CPUState *cs = CPU(cpu);
411
uint64_t pageaddr = sextract64(value << 12, 0, 56);
412
413
- tlb_flush_page_by_mmuidx(cs, pageaddr, (1 << ARMMMUIdx_S1E3));
414
+ tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_S1E3);
415
}
416
417
static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
418
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
419
420
if (sec) {
421
tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
422
- (1 << ARMMMUIdx_S1SE1) |
423
- (1 << ARMMMUIdx_S1SE0));
424
+ ARMMMUIdxBit_S1SE1 |
425
+ ARMMMUIdxBit_S1SE0);
426
} else {
427
tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
428
- (1 << ARMMMUIdx_S12NSE1) |
429
- (1 << ARMMMUIdx_S12NSE0));
430
+ ARMMMUIdxBit_S12NSE1 |
431
+ ARMMMUIdxBit_S12NSE0);
432
}
433
}
434
435
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
436
uint64_t pageaddr = sextract64(value << 12, 0, 56);
437
438
tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
439
- (1 << ARMMMUIdx_S1E2));
440
+ ARMMMUIdxBit_S1E2);
441
}
442
443
static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
444
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
445
uint64_t pageaddr = sextract64(value << 12, 0, 56);
446
447
tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
448
- (1 << ARMMMUIdx_S1E3));
449
+ ARMMMUIdxBit_S1E3);
450
}
451
452
static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri,
453
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri,
454
455
pageaddr = sextract64(value << 12, 0, 48);
456
457
- tlb_flush_page_by_mmuidx(cs, pageaddr, (1 << ARMMMUIdx_S2NS));
458
+ tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_S2NS);
459
}
460
461
static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
462
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
463
pageaddr = sextract64(value << 12, 0, 48);
464
465
tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
466
- (1 << ARMMMUIdx_S2NS));
467
+ ARMMMUIdxBit_S2NS);
468
}
469
470
static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
471
@@ -XXX,XX +XXX,XX @@ static inline TCR *regime_tcr(CPUARMState *env, ARMMMUIdx mmu_idx)
472
return &env->cp15.tcr_el[regime_el(env, mmu_idx)];
473
}
474
475
+/* Convert a possible stage1+2 MMU index into the appropriate
476
+ * stage 1 MMU index
477
+ */
101
+ */
478
+static inline ARMMMUIdx stage_1_mmu_idx(ARMMMUIdx mmu_idx)
102
+void HELPER(vesb)(CPUARMState *env)
479
+{
103
+{
480
+ if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
104
+ /*
481
+ mmu_idx += (ARMMMUIdx_S1NSE0 - ARMMMUIdx_S12NSE0);
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);
482
+ }
138
+ }
483
+ return mmu_idx;
484
+}
139
+}
485
+
486
/* Returns TBI0 value for current regime el */
487
uint32_t arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx)
488
{
489
@@ -XXX,XX +XXX,XX @@ uint32_t arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx)
490
uint32_t el;
491
492
/* For EL0 and EL1, TBI is controlled by stage 1's TCR, so convert
493
- * a stage 1+2 mmu index into the appropriate stage 1 mmu index.
494
- */
495
- if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
496
- mmu_idx += ARMMMUIdx_S1NSE0;
497
- }
498
+ * a stage 1+2 mmu index into the appropriate stage 1 mmu index.
499
+ */
500
+ mmu_idx = stage_1_mmu_idx(mmu_idx);
501
502
tcr = regime_tcr(env, mmu_idx);
503
el = regime_el(env, mmu_idx);
504
@@ -XXX,XX +XXX,XX @@ uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx)
505
uint32_t el;
506
507
/* For EL0 and EL1, TBI is controlled by stage 1's TCR, so convert
508
- * a stage 1+2 mmu index into the appropriate stage 1 mmu index.
509
- */
510
- if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
511
- mmu_idx += ARMMMUIdx_S1NSE0;
512
- }
513
+ * a stage 1+2 mmu index into the appropriate stage 1 mmu index.
514
+ */
515
+ mmu_idx = stage_1_mmu_idx(mmu_idx);
516
517
tcr = regime_tcr(env, mmu_idx);
518
el = regime_el(env, mmu_idx);
519
@@ -XXX,XX +XXX,XX @@ static inline bool regime_using_lpae_format(CPUARMState *env,
520
* on whether the long or short descriptor format is in use. */
521
bool arm_s1_regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx)
522
{
523
- if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
524
- mmu_idx += ARMMMUIdx_S1NSE0;
525
- }
526
+ mmu_idx = stage_1_mmu_idx(mmu_idx);
527
528
return regime_using_lpae_format(env, mmu_idx);
529
}
530
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
531
int ret;
532
533
ret = get_phys_addr(env, address, access_type,
534
- mmu_idx + ARMMMUIdx_S1NSE0, &ipa, attrs,
535
+ stage_1_mmu_idx(mmu_idx), &ipa, attrs,
536
prot, page_size, fsr, fi);
537
538
/* If S1 fails or S2 is disabled, return early. */
539
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
540
/*
541
* For non-EL2 CPUs a stage1+stage2 translation is just stage 1.
542
*/
543
- mmu_idx += ARMMMUIdx_S1NSE0;
544
+ mmu_idx = stage_1_mmu_idx(mmu_idx);
545
}
546
}
547
548
@@ -XXX,XX +XXX,XX @@ bool arm_tlb_fill(CPUState *cs, vaddr address,
549
int ret;
550
MemTxAttrs attrs = {};
551
552
- ret = get_phys_addr(env, address, access_type, mmu_idx, &phys_addr,
553
+ ret = get_phys_addr(env, address, access_type,
554
+ core_to_arm_mmu_idx(env, mmu_idx), &phys_addr,
555
&attrs, &prot, &page_size, fsr, fi);
556
if (!ret) {
557
/* Map a single [sub]page. */
558
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
559
bool ret;
560
uint32_t fsr;
561
ARMMMUFaultInfo fi = {};
562
+ ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
563
564
*attrs = (MemTxAttrs) {};
565
566
- ret = get_phys_addr(env, addr, 0, cpu_mmu_index(env, false), &phys_addr,
567
+ ret = get_phys_addr(env, addr, 0, mmu_idx, &phys_addr,
568
attrs, &prot, &page_size, &fsr, &fi);
569
570
if (ret) {
571
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
572
index XXXXXXX..XXXXXXX 100644
573
--- a/target/arm/op_helper.c
574
+++ b/target/arm/op_helper.c
575
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
576
int target_el;
577
bool same_el;
578
uint32_t syn;
579
+ ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
580
581
if (retaddr) {
582
/* now we have a real cpu fault */
583
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
584
/* the DFSR for an alignment fault depends on whether we're using
585
* the LPAE long descriptor format, or the short descriptor format
586
*/
587
- if (arm_s1_regime_using_lpae_format(env, mmu_idx)) {
588
+ if (arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
589
env->exception.fsr = (1 << 9) | 0x21;
590
} else {
591
env->exception.fsr = 0x1;
592
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
593
index XXXXXXX..XXXXXXX 100644
141
index XXXXXXX..XXXXXXX 100644
594
--- a/target/arm/translate-a64.c
142
--- a/target/arm/translate-a64.c
595
+++ b/target/arm/translate-a64.c
143
+++ b/target/arm/translate-a64.c
596
@@ -XXX,XX +XXX,XX @@ void a64_translate_init(void)
144
@@ -XXX,XX +XXX,XX @@ static void handle_hint(DisasContext *s, uint32_t insn,
597
offsetof(CPUARMState, exclusive_high), "exclusive_high");
145
gen_helper_autib(cpu_X[17], cpu_env, cpu_X[17], cpu_X[16]);
598
}
146
}
599
147
break;
600
-static inline ARMMMUIdx get_a64_user_mem_index(DisasContext *s)
148
+ case 0b10000: /* ESB */
601
+static inline int get_a64_user_mem_index(DisasContext *s)
149
+ /* Without RAS, we must implement this as NOP. */
602
{
150
+ if (dc_isar_feature(aa64_ras, s)) {
603
- /* Return the mmu_idx to use for A64 "unprivileged load/store" insns:
151
+ /*
604
+ /* Return the core mmu_idx to use for A64 "unprivileged load/store" insns:
152
+ * QEMU does not have a source of physical SErrors,
605
* if EL1, access as if EL0; otherwise access at current EL
153
+ * so we are only concerned with virtual SErrors.
606
*/
154
+ * The pseudocode in the ARM for this case is
607
+ ARMMMUIdx useridx;
155
+ * if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then
608
+
156
+ * AArch64.vESBOperation();
609
switch (s->mmu_idx) {
157
+ * Most of the condition can be evaluated at translation time.
610
case ARMMMUIdx_S12NSE1:
158
+ * Test for EL2 present, and defer test for SEL2 to runtime.
611
- return ARMMMUIdx_S12NSE0;
159
+ */
612
+ useridx = ARMMMUIdx_S12NSE0;
160
+ if (s->current_el <= 1 && arm_dc_feature(s, ARM_FEATURE_EL2)) {
161
+ gen_helper_vesb(cpu_env);
162
+ }
163
+ }
613
+ break;
164
+ break;
614
case ARMMMUIdx_S1SE1:
165
case 0b11000: /* PACIAZ */
615
- return ARMMMUIdx_S1SE0;
166
if (s->pauth_active) {
616
+ useridx = ARMMMUIdx_S1SE0;
167
gen_helper_pacia(cpu_X[30], cpu_env, cpu_X[30],
617
+ break;
618
case ARMMMUIdx_S2NS:
619
g_assert_not_reached();
620
default:
621
- return s->mmu_idx;
622
+ useridx = s->mmu_idx;
623
+ break;
624
}
625
+ return arm_to_core_mmu_idx(useridx);
626
}
627
628
void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
629
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code_a64(ARMCPU *cpu, TranslationBlock *tb)
630
dc->be_data = ARM_TBFLAG_BE_DATA(tb->flags) ? MO_BE : MO_LE;
631
dc->condexec_mask = 0;
632
dc->condexec_cond = 0;
633
- dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
634
+ dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(tb->flags));
635
dc->tbi0 = ARM_TBFLAG_TBI0(tb->flags);
636
dc->tbi1 = ARM_TBFLAG_TBI1(tb->flags);
637
dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
638
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
639
index XXXXXXX..XXXXXXX 100644
169
index XXXXXXX..XXXXXXX 100644
640
--- a/target/arm/translate.c
170
--- a/target/arm/translate.c
641
+++ b/target/arm/translate.c
171
+++ b/target/arm/translate.c
642
@@ -XXX,XX +XXX,XX @@ static void disas_set_da_iss(DisasContext *s, TCGMemOp memop, ISSInfo issinfo)
172
@@ -XXX,XX +XXX,XX @@ static bool trans_WFI(DisasContext *s, arg_WFI *a)
643
disas_set_insn_syndrome(s, syn);
173
return true;
644
}
174
}
645
175
646
-static inline ARMMMUIdx get_a32_user_mem_index(DisasContext *s)
176
+static bool trans_ESB(DisasContext *s, arg_ESB *a)
647
+static inline int get_a32_user_mem_index(DisasContext *s)
177
+{
178
+ /*
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)
648
{
200
{
649
- /* Return the mmu_idx to use for A32/T32 "unprivileged load/store"
201
return true;
650
+ /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
651
* insns:
652
* if PL2, UNPREDICTABLE (we choose to implement as if PL0)
653
* otherwise, access as if at PL0.
654
@@ -XXX,XX +XXX,XX @@ static inline ARMMMUIdx get_a32_user_mem_index(DisasContext *s)
655
case ARMMMUIdx_S1E2: /* this one is UNPREDICTABLE */
656
case ARMMMUIdx_S12NSE0:
657
case ARMMMUIdx_S12NSE1:
658
- return ARMMMUIdx_S12NSE0;
659
+ return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0);
660
case ARMMMUIdx_S1E3:
661
case ARMMMUIdx_S1SE0:
662
case ARMMMUIdx_S1SE1:
663
- return ARMMMUIdx_S1SE0;
664
+ return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
665
case ARMMMUIdx_S2NS:
666
default:
667
g_assert_not_reached();
668
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
669
dc->be_data = ARM_TBFLAG_BE_DATA(tb->flags) ? MO_BE : MO_LE;
670
dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
671
dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
672
- dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
673
+ dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(tb->flags));
674
dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
675
#if !defined(CONFIG_USER_ONLY)
676
dc->user = (dc->current_el == 0);
677
--
202
--
678
2.7.4
203
2.25.1
679
680
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
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
This extension concerns branch speculation, which TCG does
4
not implement. Thus we can trivially enable this feature.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220506180242.216785-20-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
docs/system/arm/emulation.rst | 1 +
12
target/arm/cpu64.c | 1 +
13
target/arm/cpu_tcg.c | 1 +
14
3 files changed, 3 insertions(+)
15
16
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
17
index XXXXXXX..XXXXXXX 100644
18
--- a/docs/system/arm/emulation.rst
19
+++ b/docs/system/arm/emulation.rst
20
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
21
- FEAT_BBM at level 2 (Translation table break-before-make levels)
22
- FEAT_BF16 (AArch64 BFloat16 instructions)
23
- FEAT_BTI (Branch Target Identification)
24
+- FEAT_CSV2 (Cache speculation variant 2)
25
- FEAT_DIT (Data Independent Timing instructions)
26
- FEAT_DPB (DC CVAP instruction)
27
- FEAT_Debugv8p2 (Debug changes for v8.2)
28
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu64.c
31
+++ b/target/arm/cpu64.c
32
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
33
t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
34
t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); /* FEAT_SEL2 */
35
t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
36
+ t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 1); /* FEAT_CSV2 */
37
cpu->isar.id_aa64pfr0 = t;
38
39
t = cpu->isar.id_aa64pfr1;
40
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/cpu_tcg.c
43
+++ b/target/arm/cpu_tcg.c
44
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
45
cpu->isar.id_mmfr4 = t;
46
47
t = cpu->isar.id_pfr0;
48
+ t = FIELD_DP32(t, ID_PFR0, CSV2, 2); /* FEAT_CVS2 */
49
t = FIELD_DP32(t, ID_PFR0, DIT, 1); /* FEAT_DIT */
50
t = FIELD_DP32(t, ID_PFR0, RAS, 1); /* FEAT_RAS */
51
cpu->isar.id_pfr0 = t;
52
--
53
2.25.1
diff view generated by jsdifflib
1
Implement HFNMIENA support for the M profile MPU. This bit controls
1
From: Richard Henderson <richard.henderson@linaro.org>
2
whether the MPU is treated as enabled when executing at execution
3
priorities of less than zero (in NMI, HardFault or with the FAULTMASK
4
bit set).
5
2
6
Doing this requires us to use a different MMU index for "running
3
There is no branch prediction in TCG, therefore there is no
7
at execution priority < 0", because we will have different
4
need to actually include the context number into the predictor.
8
access permissions for that case versus the normal case.
5
Therefore all we need to do is add the state for SCXTNUM_ELx.
9
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
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 1493122030-32191-14-git-send-email-peter.maydell@linaro.org
12
---
11
---
13
target/arm/cpu.h | 24 +++++++++++++++++++++++-
12
docs/system/arm/emulation.rst | 3 ++
14
target/arm/helper.c | 18 +++++++++++++++++-
13
target/arm/cpu.h | 16 +++++++++
15
target/arm/translate.c | 1 +
14
target/arm/cpu.c | 5 +++
16
3 files changed, 41 insertions(+), 2 deletions(-)
15
target/arm/cpu64.c | 3 +-
16
target/arm/helper.c | 61 ++++++++++++++++++++++++++++++++++-
17
5 files changed, 86 insertions(+), 2 deletions(-)
17
18
19
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
20
index XXXXXXX..XXXXXXX 100644
21
--- a/docs/system/arm/emulation.rst
22
+++ b/docs/system/arm/emulation.rst
23
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
24
- FEAT_BF16 (AArch64 BFloat16 instructions)
25
- FEAT_BTI (Branch Target Identification)
26
- FEAT_CSV2 (Cache speculation variant 2)
27
+- FEAT_CSV2_1p1 (Cache speculation variant 2, version 1.1)
28
+- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
29
+- FEAT_CSV2_2 (Cache speculation variant 2, version 2)
30
- FEAT_DIT (Data Independent Timing instructions)
31
- FEAT_DPB (DC CVAP instruction)
32
- FEAT_Debugv8p2 (Debug changes for v8.2)
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
33
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
35
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
36
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
37
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
23
* for the accesses done as part of a stage 1 page table walk, rather than
38
ARMPACKey apdb;
24
* having to walk the stage 2 page table over and over.)
39
ARMPACKey apga;
25
*
40
} keys;
26
+ * R profile CPUs have an MPU, but can use the same set of MMU indexes
41
+
27
+ * as A profile. They only need to distinguish NS EL0 and NS EL1 (and
42
+ uint64_t scxtnum_el[4];
28
+ * NS EL2 if we ever model a Cortex-R52).
43
#endif
29
+ *
44
30
+ * M profile CPUs are rather different as they do not have a true MMU.
45
#if defined(CONFIG_USER_ONLY)
31
+ * They have the following different MMU indexes:
46
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
32
+ * User
47
#define SCTLR_WXN (1U << 19)
33
+ * Privileged
48
#define SCTLR_ST (1U << 20) /* up to ??, RAZ in v6 */
34
+ * Execution priority negative (this is like privileged, but the
49
#define SCTLR_UWXN (1U << 20) /* v7 onward, AArch32 only */
35
+ * MPU HFNMIENA bit means that it may have different access permission
50
+#define SCTLR_TSCXT (1U << 20) /* FEAT_CSV2_1p2, AArch64 only */
36
+ * check results to normal privileged code, so can't share a TLB).
51
#define SCTLR_FI (1U << 21) /* up to v7, v8 RES0 */
37
+ *
52
#define SCTLR_IESB (1U << 21) /* v8.2-IESB, AArch64 only */
38
* The ARMMMUIdx and the mmu index value used by the core QEMU TLB code
53
#define SCTLR_U (1U << 22) /* up to v6, RAO in v7 */
39
* are not quite the same -- different CPU types (most notably M profile
54
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_dit(const ARMISARegisters *id)
40
* vs A/R profile) would like to use MMU indexes with different semantics,
55
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0;
41
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
56
}
42
ARMMMUIdx_S2NS = 6 | ARM_MMU_IDX_A,
57
43
ARMMMUIdx_MUser = 0 | ARM_MMU_IDX_M,
58
+static inline bool isar_feature_aa64_scxtnum(const ARMISARegisters *id)
44
ARMMMUIdx_MPriv = 1 | ARM_MMU_IDX_M,
59
+{
45
+ ARMMMUIdx_MNegPri = 2 | ARM_MMU_IDX_M,
60
+ int key = FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, CSV2);
46
/* Indexes below here don't have TLBs and are used only for AT system
61
+ if (key >= 2) {
47
* instructions or for the first stage of an S12 page table walk.
62
+ return true; /* FEAT_CSV2_2 */
63
+ }
64
+ if (key == 1) {
65
+ key = FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, CSV2_FRAC);
66
+ return key >= 2; /* FEAT_CSV2_1p2 */
67
+ }
68
+ return false;
69
+}
70
+
71
static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id)
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.
48
*/
105
*/
49
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
106
t = FIELD_DP64(t, ID_AA64PFR1, MTE, 3); /* FEAT_MTE3 */
50
ARMMMUIdxBit_S2NS = 1 << 6,
107
+ t = FIELD_DP64(t, ID_AA64PFR1, CSV2_FRAC, 0); /* FEAT_CSV2_2 */
51
ARMMMUIdxBit_MUser = 1 << 0,
108
cpu->isar.id_aa64pfr1 = t;
52
ARMMMUIdxBit_MPriv = 1 << 1,
109
53
+ ARMMMUIdxBit_MNegPri = 1 << 2,
110
t = cpu->isar.id_aa64mmfr0;
54
} ARMMMUIdxBit;
55
56
#define MMU_USER_IDX 0
57
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
58
case ARM_MMU_IDX_A:
59
return mmu_idx & 3;
60
case ARM_MMU_IDX_M:
61
- return mmu_idx & 1;
62
+ return mmu_idx == ARMMMUIdx_MUser ? 0 : 1;
63
default:
64
g_assert_not_reached();
65
}
66
@@ -XXX,XX +XXX,XX @@ static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
67
if (arm_feature(env, ARM_FEATURE_M)) {
68
ARMMMUIdx mmu_idx = el == 0 ? ARMMMUIdx_MUser : ARMMMUIdx_MPriv;
69
70
+ /* Execution priority is negative if FAULTMASK is set or
71
+ * we're in a HardFault or NMI handler.
72
+ */
73
+ if ((env->v7m.exception > 0 && env->v7m.exception <= 3)
74
+ || env->daif & PSTATE_F) {
75
+ return arm_to_core_mmu_idx(ARMMMUIdx_MNegPri);
76
+ }
77
+
78
return arm_to_core_mmu_idx(mmu_idx);
79
}
80
81
diff --git a/target/arm/helper.c b/target/arm/helper.c
111
diff --git a/target/arm/helper.c b/target/arm/helper.c
82
index XXXXXXX..XXXXXXX 100644
112
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/helper.c
113
--- a/target/arm/helper.c
84
+++ b/target/arm/helper.c
114
+++ b/target/arm/helper.c
85
@@ -XXX,XX +XXX,XX @@ static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
115
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
86
case ARMMMUIdx_S1NSE0:
116
if (cpu_isar_feature(aa64_mte, cpu)) {
87
case ARMMMUIdx_S1NSE1:
117
valid_mask |= SCR_ATA;
88
case ARMMMUIdx_MPriv:
118
}
89
+ case ARMMMUIdx_MNegPri:
119
+ if (cpu_isar_feature(aa64_scxtnum, cpu)) {
90
case ARMMMUIdx_MUser:
120
+ valid_mask |= SCR_ENSCXT;
91
return 1;
121
+ }
92
default:
122
} else {
93
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
123
valid_mask &= ~(SCR_RW | SCR_ST);
94
case ARMMMUIdx_S1E2:
124
if (cpu_isar_feature(aa32_ras, cpu)) {
95
case ARMMMUIdx_S2NS:
125
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
96
case ARMMMUIdx_MPriv:
126
if (cpu_isar_feature(aa64_mte, cpu)) {
97
+ case ARMMMUIdx_MNegPri:
127
valid_mask |= HCR_ATA | HCR_DCT | HCR_TID5;
98
case ARMMMUIdx_MUser:
128
}
99
return false;
129
+ if (cpu_isar_feature(aa64_scxtnum, cpu)) {
100
case ARMMMUIdx_S1E3:
130
+ valid_mask |= HCR_ENSCXT;
101
@@ -XXX,XX +XXX,XX @@ static inline bool regime_translation_disabled(CPUARMState *env,
102
ARMMMUIdx mmu_idx)
103
{
104
if (arm_feature(env, ARM_FEATURE_M)) {
105
- return !(env->v7m.mpu_ctrl & R_V7M_MPU_CTRL_ENABLE_MASK);
106
+ switch (env->v7m.mpu_ctrl &
107
+ (R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK)) {
108
+ case R_V7M_MPU_CTRL_ENABLE_MASK:
109
+ /* Enabled, but not for HardFault and NMI */
110
+ return mmu_idx == ARMMMUIdx_MNegPri;
111
+ case R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK:
112
+ /* Enabled for all cases */
113
+ return false;
114
+ case 0:
115
+ default:
116
+ /* HFNMIENA set and ENABLE clear is UNPREDICTABLE, but
117
+ * we warned about that in armv7m_nvic.c when the guest set it.
118
+ */
119
+ return true;
120
+ }
131
+ }
121
}
132
}
122
133
123
if (mmu_idx == ARMMMUIdx_S2NS) {
134
/* Clear RES0 bits. */
124
diff --git a/target/arm/translate.c b/target/arm/translate.c
135
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
125
index XXXXXXX..XXXXXXX 100644
136
{ K(3, 0, 5, 6, 0), K(3, 4, 5, 6, 0), K(3, 5, 5, 6, 0),
126
--- a/target/arm/translate.c
137
"TFSR_EL1", "TFSR_EL2", "TFSR_EL12", isar_feature_aa64_mte },
127
+++ b/target/arm/translate.c
138
128
@@ -XXX,XX +XXX,XX @@ static inline int get_a32_user_mem_index(DisasContext *s)
139
+ { K(3, 0, 13, 0, 7), K(3, 4, 13, 0, 7), K(3, 5, 13, 0, 7),
129
return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
140
+ "SCXTNUM_EL1", "SCXTNUM_EL2", "SCXTNUM_EL12",
130
case ARMMMUIdx_MUser:
141
+ isar_feature_aa64_scxtnum },
131
case ARMMMUIdx_MPriv:
142
+
132
+ case ARMMMUIdx_MNegPri:
143
/* TODO: ARMv8.2-SPE -- PMSCR_EL2 */
133
return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
144
/* TODO: ARMv8.4-Trace -- TRFCR_EL2 */
134
case ARMMMUIdx_S2NS:
145
};
135
default:
146
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_el0_cacheop_reginfo[] = {
147
},
148
};
149
150
-#endif
151
+static CPAccessResult access_scxtnum(CPUARMState *env, const ARMCPRegInfo *ri,
152
+ bool isread)
153
+{
154
+ uint64_t hcr = arm_hcr_el2_eff(env);
155
+ int el = arm_current_el(env);
156
+
157
+ if (el == 0 && !((hcr & HCR_E2H) && (hcr & HCR_TGE))) {
158
+ if (env->cp15.sctlr_el[1] & SCTLR_TSCXT) {
159
+ if (hcr & HCR_TGE) {
160
+ return CP_ACCESS_TRAP_EL2;
161
+ }
162
+ return CP_ACCESS_TRAP;
163
+ }
164
+ } else if (el < 2 && (env->cp15.sctlr_el[2] & SCTLR_TSCXT)) {
165
+ return CP_ACCESS_TRAP_EL2;
166
+ }
167
+ if (el < 2 && arm_is_el2_enabled(env) && !(hcr & HCR_ENSCXT)) {
168
+ return CP_ACCESS_TRAP_EL2;
169
+ }
170
+ if (el < 3
171
+ && arm_feature(env, ARM_FEATURE_EL3)
172
+ && !(env->cp15.scr_el3 & SCR_ENSCXT)) {
173
+ return CP_ACCESS_TRAP_EL3;
174
+ }
175
+ return CP_ACCESS_OK;
176
+}
177
+
178
+static const ARMCPRegInfo scxtnum_reginfo[] = {
179
+ { .name = "SCXTNUM_EL0", .state = ARM_CP_STATE_AA64,
180
+ .opc0 = 3, .opc1 = 3, .crn = 13, .crm = 0, .opc2 = 7,
181
+ .access = PL0_RW, .accessfn = access_scxtnum,
182
+ .fieldoffset = offsetof(CPUARMState, scxtnum_el[0]) },
183
+ { .name = "SCXTNUM_EL1", .state = ARM_CP_STATE_AA64,
184
+ .opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 7,
185
+ .access = PL1_RW, .accessfn = access_scxtnum,
186
+ .fieldoffset = offsetof(CPUARMState, scxtnum_el[1]) },
187
+ { .name = "SCXTNUM_EL2", .state = ARM_CP_STATE_AA64,
188
+ .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 7,
189
+ .access = PL2_RW, .accessfn = access_scxtnum,
190
+ .fieldoffset = offsetof(CPUARMState, scxtnum_el[2]) },
191
+ { .name = "SCXTNUM_EL3", .state = ARM_CP_STATE_AA64,
192
+ .opc0 = 3, .opc1 = 6, .crn = 13, .crm = 0, .opc2 = 7,
193
+ .access = PL3_RW,
194
+ .fieldoffset = offsetof(CPUARMState, scxtnum_el[3]) },
195
+};
196
+#endif /* TARGET_AARCH64 */
197
198
static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
199
bool isread)
200
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
201
define_arm_cp_regs(cpu, mte_tco_ro_reginfo);
202
define_arm_cp_regs(cpu, mte_el0_cacheop_reginfo);
203
}
204
+
205
+ if (cpu_isar_feature(aa64_scxtnum, cpu)) {
206
+ define_arm_cp_regs(cpu, scxtnum_reginfo);
207
+ }
208
#endif
209
210
if (cpu_isar_feature(any_predinv, cpu)) {
136
--
211
--
137
2.7.4
212
2.25.1
138
139
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
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
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
docs/system/arm/emulation.rst | 1 +
12
target/arm/cpu64.c | 1 +
13
target/arm/cpu_tcg.c | 1 +
14
3 files changed, 3 insertions(+)
15
16
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
17
index XXXXXXX..XXXXXXX 100644
18
--- a/docs/system/arm/emulation.rst
19
+++ b/docs/system/arm/emulation.rst
20
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
21
- FEAT_CSV2_1p1 (Cache speculation variant 2, version 1.1)
22
- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
23
- FEAT_CSV2_2 (Cache speculation variant 2, version 2)
24
+- FEAT_CSV3 (Cache speculation variant 3)
25
- FEAT_DIT (Data Independent Timing instructions)
26
- FEAT_DPB (DC CVAP instruction)
27
- FEAT_Debugv8p2 (Debug changes for v8.2)
28
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu64.c
31
+++ b/target/arm/cpu64.c
32
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
33
t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); /* FEAT_SEL2 */
34
t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
35
t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 2); /* FEAT_CSV2_2 */
36
+ t = FIELD_DP64(t, ID_AA64PFR0, CSV3, 1); /* FEAT_CSV3 */
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;
51
52
--
53
2.25.1
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Today, the LAST command is handled with the STOP command but this is
3
This extension concerns not merging memory access, which TCG does
4
incorrect. Also nack the I2C bus when a LAST is issued.
4
not implement. Thus we can trivially enable this feature.
5
Add a comment to handle_hint for the DGH instruction, but no code.
5
6
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 1494827476-1487-3-git-send-email-clg@kaod.org
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220506180242.216785-23-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
---
11
---
10
hw/i2c/aspeed_i2c.c | 9 ++++++---
12
docs/system/arm/emulation.rst | 1 +
11
1 file changed, 6 insertions(+), 3 deletions(-)
13
target/arm/cpu64.c | 1 +
14
target/arm/translate-a64.c | 1 +
15
3 files changed, 3 insertions(+)
12
16
13
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
17
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/i2c/aspeed_i2c.c
19
--- a/docs/system/arm/emulation.rst
16
+++ b/hw/i2c/aspeed_i2c.c
20
+++ b/docs/system/arm/emulation.rst
17
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
21
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
18
bus->cmd &= ~I2CD_M_TX_CMD;
22
- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
19
}
23
- FEAT_CSV2_2 (Cache speculation variant 2, version 2)
20
24
- FEAT_CSV3 (Cache speculation variant 3)
21
- if (bus->cmd & I2CD_M_RX_CMD) {
25
+- FEAT_DGH (Data gathering hint)
22
+ if (bus->cmd & (I2CD_M_RX_CMD | I2CD_M_S_RX_CMD_LAST)) {
26
- FEAT_DIT (Data Independent Timing instructions)
23
int ret = i2c_recv(bus->bus);
27
- FEAT_DPB (DC CVAP instruction)
24
if (ret < 0) {
28
- FEAT_Debugv8p2 (Debug changes for v8.2)
25
qemu_log_mask(LOG_GUEST_ERROR, "%s: read failed\n", __func__);
29
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
26
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
30
index XXXXXXX..XXXXXXX 100644
27
bus->intr_status |= I2CD_INTR_RX_DONE;
31
--- a/target/arm/cpu64.c
28
}
32
+++ b/target/arm/cpu64.c
29
bus->buf = (ret & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
33
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
30
- bus->cmd &= ~I2CD_M_RX_CMD;
34
t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1); /* FEAT_SB */
31
+ if (bus->cmd & I2CD_M_S_RX_CMD_LAST) {
35
t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1); /* FEAT_SPECRES */
32
+ i2c_nack(bus->bus);
36
t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 1); /* FEAT_BF16 */
33
+ }
37
+ t = FIELD_DP64(t, ID_AA64ISAR1, DGH, 1); /* FEAT_DGH */
34
+ bus->cmd &= ~(I2CD_M_RX_CMD | I2CD_M_S_RX_CMD_LAST);
38
t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1); /* FEAT_I8MM */
35
}
39
cpu->isar.id_aa64isar1 = t;
36
40
37
- if (bus->cmd & (I2CD_M_STOP_CMD | I2CD_M_S_RX_CMD_LAST)) {
41
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
38
+ if (bus->cmd & I2CD_M_STOP_CMD) {
42
index XXXXXXX..XXXXXXX 100644
39
if (!i2c_bus_busy(bus->bus)) {
43
--- a/target/arm/translate-a64.c
40
bus->intr_status |= I2CD_INTR_ABNORMAL;
44
+++ b/target/arm/translate-a64.c
41
} else {
45
@@ -XXX,XX +XXX,XX @@ static void handle_hint(DisasContext *s, uint32_t insn,
46
break;
47
case 0b00100: /* SEV */
48
case 0b00101: /* SEVL */
49
+ case 0b00110: /* DGH */
50
/* we treat all as NOP at least for now */
51
break;
52
case 0b00111: /* XPACLRI */
42
--
53
--
43
2.7.4
54
2.25.1
44
45
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Let's add an RTC to the palmetto BMC and a LM75 temperature sensor to
3
Enable the a76 for virt and sbsa board use.
4
the AST2500 EVB to start with.
5
4
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 1494827476-1487-5-git-send-email-clg@kaod.org
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220506180242.216785-24-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
hw/arm/aspeed.c | 27 +++++++++++++++++++++++++++
10
docs/system/arm/virt.rst | 1 +
12
1 file changed, 27 insertions(+)
11
hw/arm/sbsa-ref.c | 1 +
12
hw/arm/virt.c | 1 +
13
target/arm/cpu64.c | 66 ++++++++++++++++++++++++++++++++++++++++
14
4 files changed, 69 insertions(+)
13
15
14
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
16
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/aspeed.c
18
--- a/docs/system/arm/virt.rst
17
+++ b/hw/arm/aspeed.c
19
+++ b/docs/system/arm/virt.rst
18
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedBoardConfig {
20
@@ -XXX,XX +XXX,XX @@ Supported guest CPU types:
19
const char *fmc_model;
21
- ``cortex-a53`` (64-bit)
20
const char *spi_model;
22
- ``cortex-a57`` (64-bit)
21
uint32_t num_cs;
23
- ``cortex-a72`` (64-bit)
22
+ void (*i2c_init)(AspeedBoardState *bmc);
24
+- ``cortex-a76`` (64-bit)
23
} AspeedBoardConfig;
25
- ``a64fx`` (64-bit)
24
26
- ``host`` (with KVM only)
25
enum {
27
- ``max`` (same as ``host`` for KVM; best possible emulation with TCG)
26
@@ -XXX,XX +XXX,XX @@ enum {
28
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
27
SCU_AST2500_HW_STRAP_ACPI_ENABLE | \
29
index XXXXXXX..XXXXXXX 100644
28
SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_MASTER))
30
--- a/hw/arm/sbsa-ref.c
29
31
+++ b/hw/arm/sbsa-ref.c
30
+static void palmetto_bmc_i2c_init(AspeedBoardState *bmc);
32
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
31
+static void ast2500_evb_i2c_init(AspeedBoardState *bmc);
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);
58
}
59
60
+static void aarch64_a76_initfn(Object *obj)
61
+{
62
+ ARMCPU *cpu = ARM_CPU(obj);
32
+
63
+
33
static const AspeedBoardConfig aspeed_boards[] = {
64
+ cpu->dtb_compatible = "arm,cortex-a76";
34
[PALMETTO_BMC] = {
65
+ set_feature(&cpu->env, ARM_FEATURE_V8);
35
.soc_name = "ast2400-a1",
66
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
36
@@ -XXX,XX +XXX,XX @@ static const AspeedBoardConfig aspeed_boards[] = {
67
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
37
.fmc_model = "n25q256a",
68
+ set_feature(&cpu->env, ARM_FEATURE_AARCH64);
38
.spi_model = "mx25l25635e",
69
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
39
.num_cs = 1,
70
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
40
+ .i2c_init = palmetto_bmc_i2c_init,
71
+ set_feature(&cpu->env, ARM_FEATURE_EL3);
41
},
72
+ set_feature(&cpu->env, ARM_FEATURE_PMU);
42
[AST2500_EVB] = {
43
.soc_name = "ast2500-a1",
44
@@ -XXX,XX +XXX,XX @@ static const AspeedBoardConfig aspeed_boards[] = {
45
.fmc_model = "n25q256a",
46
.spi_model = "mx25l25635e",
47
.num_cs = 1,
48
+ .i2c_init = ast2500_evb_i2c_init,
49
},
50
[ROMULUS_BMC] = {
51
.soc_name = "ast2500-a1",
52
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
53
aspeed_board_binfo.ram_size = ram_size;
54
aspeed_board_binfo.loader_start = sc->info->sdram_base;
55
56
+ if (cfg->i2c_init) {
57
+ cfg->i2c_init(bmc);
58
+ }
59
+
73
+
60
arm_load_kernel(ARM_CPU(first_cpu), &aspeed_board_binfo);
74
+ /* Ordered by B2.4 AArch64 registers by functional group */
61
}
75
+ cpu->clidr = 0x82000023;
62
76
+ cpu->ctr = 0x8444C004;
63
+static void palmetto_bmc_i2c_init(AspeedBoardState *bmc)
77
+ cpu->dcz_blocksize = 4;
64
+{
78
+ cpu->isar.id_aa64dfr0 = 0x0000000010305408ull;
65
+ AspeedSoCState *soc = &bmc->soc;
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;
66
+
105
+
67
+ /* The palmetto platform expects a ds3231 RTC but a ds1338 is
106
+ /* From B2.18 CCSIDR_EL1 */
68
+ * enough to provide basic RTC features. Alarms will be missing */
107
+ cpu->ccsidr[0] = 0x701fe01a; /* 64KB L1 dcache */
69
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 0), "ds1338", 0x68);
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;
70
+}
123
+}
71
+
124
+
72
static void palmetto_bmc_init(MachineState *machine)
125
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
73
{
126
{
74
aspeed_board_init(machine, &aspeed_boards[PALMETTO_BMC]);
127
/*
75
@@ -XXX,XX +XXX,XX @@ static const TypeInfo palmetto_bmc_type = {
128
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo aarch64_cpus[] = {
76
.class_init = palmetto_bmc_class_init,
129
{ .name = "cortex-a57", .initfn = aarch64_a57_initfn },
77
};
130
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
78
131
{ .name = "cortex-a72", .initfn = aarch64_a72_initfn },
79
+static void ast2500_evb_i2c_init(AspeedBoardState *bmc)
132
+ { .name = "cortex-a76", .initfn = aarch64_a76_initfn },
80
+{
133
{ .name = "a64fx", .initfn = aarch64_a64fx_initfn },
81
+ AspeedSoCState *soc = &bmc->soc;
134
{ .name = "max", .initfn = aarch64_max_initfn },
82
+
135
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
83
+ /* The AST2500 EVB expects a LM75 but a TMP105 is compatible */
84
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7), "tmp105", 0x4d);
85
+}
86
+
87
static void ast2500_evb_init(MachineState *machine)
88
{
89
aspeed_board_init(machine, &aspeed_boards[AST2500_EVB]);
90
--
136
--
91
2.7.4
137
2.25.1
92
93
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The Aspeed I2C controller maintains a state machine in the command
3
Enable the n1 for virt and sbsa board use.
4
register, which is mostly used for debug.
5
4
6
Let's start adding a few states to handle abnormal STOP
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
commands. Today, the model uses the busy status of the bus as a
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
condition to do so but it is not precise enough.
7
Message-id: 20220506180242.216785-25-richard.henderson@linaro.org
9
10
Also remove the ABNORMAL bit for failing TX commands. This is
11
incorrect with respect to the specs.
12
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
Message-id: 1494827476-1487-4-git-send-email-clg@kaod.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
9
---
17
hw/i2c/aspeed_i2c.c | 36 +++++++++++++++++++++++++++++++++---
10
docs/system/arm/virt.rst | 1 +
18
1 file changed, 33 insertions(+), 3 deletions(-)
11
hw/arm/sbsa-ref.c | 1 +
12
hw/arm/virt.c | 1 +
13
target/arm/cpu64.c | 66 ++++++++++++++++++++++++++++++++++++++++
14
4 files changed, 69 insertions(+)
19
15
20
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
16
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/i2c/aspeed_i2c.c
18
--- a/docs/system/arm/virt.rst
23
+++ b/hw/i2c/aspeed_i2c.c
19
+++ b/docs/system/arm/virt.rst
24
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
20
@@ -XXX,XX +XXX,XX @@ Supported guest CPU types:
25
}
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;
26
}
58
}
27
59
28
+static void aspeed_i2c_set_state(AspeedI2CBus *bus, uint8_t state)
60
+static void aarch64_neoverse_n1_initfn(Object *obj)
29
+{
61
+{
30
+ bus->cmd &= ~(I2CD_TX_STATE_MASK << I2CD_TX_STATE_SHIFT);
62
+ ARMCPU *cpu = ARM_CPU(obj);
31
+ bus->cmd |= (state & I2CD_TX_STATE_MASK) << I2CD_TX_STATE_SHIFT;
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;
32
+}
123
+}
33
+
124
+
34
+static uint8_t aspeed_i2c_get_state(AspeedI2CBus *bus)
125
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
35
+{
36
+ return (bus->cmd >> I2CD_TX_STATE_SHIFT) & I2CD_TX_STATE_MASK;
37
+}
38
+
39
+/*
40
+ * The state machine needs some refinement. It is only used to track
41
+ * invalid STOP commands for the moment.
42
+ */
43
static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
44
{
126
{
45
bus->cmd &= ~0xFFFF;
127
/*
46
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
128
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo aarch64_cpus[] = {
47
bus->intr_status = 0;
129
{ .name = "cortex-a72", .initfn = aarch64_a72_initfn },
48
130
{ .name = "cortex-a76", .initfn = aarch64_a76_initfn },
49
if (bus->cmd & I2CD_M_START_CMD) {
131
{ .name = "a64fx", .initfn = aarch64_a64fx_initfn },
50
+ uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
132
+ { .name = "neoverse-n1", .initfn = aarch64_neoverse_n1_initfn },
51
+ I2CD_MSTARTR : I2CD_MSTART;
133
{ .name = "max", .initfn = aarch64_max_initfn },
52
+
134
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
53
+ aspeed_i2c_set_state(bus, state);
135
{ .name = "host", .initfn = aarch64_host_initfn },
54
+
55
if (i2c_start_transfer(bus->bus, extract32(bus->buf, 1, 7),
56
extract32(bus->buf, 0, 1))) {
57
bus->intr_status |= I2CD_INTR_TX_NAK;
58
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
59
if (!i2c_bus_busy(bus->bus)) {
60
return;
61
}
62
+ aspeed_i2c_set_state(bus, I2CD_MACTIVE);
63
}
64
65
if (bus->cmd & I2CD_M_TX_CMD) {
66
+ aspeed_i2c_set_state(bus, I2CD_MTXD);
67
if (i2c_send(bus->bus, bus->buf)) {
68
- bus->intr_status |= (I2CD_INTR_TX_NAK | I2CD_INTR_ABNORMAL);
69
+ bus->intr_status |= (I2CD_INTR_TX_NAK);
70
i2c_end_transfer(bus->bus);
71
} else {
72
bus->intr_status |= I2CD_INTR_TX_ACK;
73
}
74
bus->cmd &= ~I2CD_M_TX_CMD;
75
+ aspeed_i2c_set_state(bus, I2CD_MACTIVE);
76
}
77
78
if (bus->cmd & (I2CD_M_RX_CMD | I2CD_M_S_RX_CMD_LAST)) {
79
- int ret = i2c_recv(bus->bus);
80
+ int ret;
81
+
82
+ aspeed_i2c_set_state(bus, I2CD_MRXD);
83
+ ret = i2c_recv(bus->bus);
84
if (ret < 0) {
85
qemu_log_mask(LOG_GUEST_ERROR, "%s: read failed\n", __func__);
86
ret = 0xff;
87
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
88
i2c_nack(bus->bus);
89
}
90
bus->cmd &= ~(I2CD_M_RX_CMD | I2CD_M_S_RX_CMD_LAST);
91
+ aspeed_i2c_set_state(bus, I2CD_MACTIVE);
92
}
93
94
if (bus->cmd & I2CD_M_STOP_CMD) {
95
- if (!i2c_bus_busy(bus->bus)) {
96
+ if (!(aspeed_i2c_get_state(bus) & I2CD_MACTIVE)) {
97
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: abnormal stop\n", __func__);
98
bus->intr_status |= I2CD_INTR_ABNORMAL;
99
} else {
100
+ aspeed_i2c_set_state(bus, I2CD_MSTOP);
101
i2c_end_transfer(bus->bus);
102
bus->intr_status |= I2CD_INTR_NORMAL_STOP;
103
}
104
bus->cmd &= ~I2CD_M_STOP_CMD;
105
+ aspeed_i2c_set_state(bus, I2CD_IDLE);
106
}
107
}
108
109
--
136
--
110
2.7.4
137
2.25.1
111
112
diff view generated by jsdifflib
1
From: Kamil Rytarowski <n54@gmx.com>
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
2
3
Ensure that C99 macros are defined regardless of the inclusion order of
3
The sbsa-ref machine is continuously evolving. Some of the changes we
4
headers in vixl. This is required at least on NetBSD.
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.
5
6
6
The vixl/globals.h headers defines __STDC_CONSTANT_MACROS and must be
7
Introduce two new properties to the DT generated on machine generation:
7
included before other system headers.
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.
8
15
9
This file defines unconditionally the following macros, without altering
16
This versioning scheme is *neither*:
10
the original sources:
17
- A QEMU versioned machine type; a given version of QEMU will emulate
11
- __STDC_CONSTANT_MACROS
18
a given version of the platform.
12
- __STDC_LIMIT_MACROS
19
- A reflection of level of SBSA (now SystemReady SR) support provided.
13
- __STDC_FORMAT_MACROS
14
20
15
Signed-off-by: Kamil Rytarowski <n54@gmx.com>
21
The version will increment on guest-visible functional changes only,
16
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
akin to a revision ID register found on a physical platform.
17
Message-id: 20170514051820.15985-1-n54@gmx.com
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>
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
33
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
35
---
21
disas/libvixl/Makefile.objs | 3 +++
36
hw/arm/sbsa-ref.c | 14 ++++++++++++++
22
1 file changed, 3 insertions(+)
37
1 file changed, 14 insertions(+)
23
38
24
diff --git a/disas/libvixl/Makefile.objs b/disas/libvixl/Makefile.objs
39
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
25
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
26
--- a/disas/libvixl/Makefile.objs
41
--- a/hw/arm/sbsa-ref.c
27
+++ b/disas/libvixl/Makefile.objs
42
+++ b/hw/arm/sbsa-ref.c
28
@@ -XXX,XX +XXX,XX @@ libvixl_OBJS = vixl/utils.o \
43
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SBSAMachineState *sms)
29
# The -Wno-sign-compare is needed only for gcc 4.6, which complains about
44
qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
30
# some signed-unsigned equality comparisons which later gcc versions do not.
45
qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
31
$(addprefix $(obj)/,$(libvixl_OBJS)): QEMU_CFLAGS := -I$(SRC_PATH)/disas/libvixl $(QEMU_CFLAGS) -Wno-sign-compare
46
32
+# Ensure that C99 macros are defined regardless of the inclusion order of
47
+ /*
33
+# headers in vixl. This is required at least on NetBSD.
48
+ * This versioning scheme is for informing platform fw only. It is neither:
34
+$(addprefix $(obj)/,$(libvixl_OBJS)): QEMU_CFLAGS += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS
49
+ * - A QEMU versioned machine type; a given version of QEMU will emulate
35
50
+ * a given version of the platform.
36
common-obj-$(CONFIG_ARM_A64_DIS) += $(libvixl_OBJS)
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);
37
--
64
--
38
2.7.4
65
2.25.1
39
66
40
67
diff view generated by jsdifflib
1
From: Michael Davidsaver <mdavidsaver@gmail.com>
1
From: Gavin Shan <gshan@redhat.com>
2
2
3
The M series MPU is almost the same as the already implemented R
3
This adds cluster-id in CPU instance properties, which will be used
4
profile MPU (v7 PMSA). So all we need to implement here is the MPU
4
by arm/virt machine. Besides, the cluster-id is also verified or
5
register interface in the system register space.
5
dumped in various spots:
6
6
7
This implementation has the same restriction as the R profile MPU
7
* hw/core/machine.c::machine_set_cpu_numa_node() to associate
8
that it doesn't permit regions to be sized down smaller than 1K.
8
CPU with its NUMA node.
9
9
10
We also do not yet implement support for MPU_CTRL.HFNMIENA; this
10
* hw/core/machine.c::machine_numa_finish_cpu_init() to record
11
bit should if zero disable use of the MPU when running HardFault,
11
CPU slots with no NUMA mapping set.
12
NMI or with FAULTMASK set to 1 (ie at an execution priority of
13
less than zero) -- if the MPU is enabled we don't treat these
14
cases any differently.
15
12
16
Signed-off-by: Michael Davidsaver <mdavidsaver@gmail.com>
13
* hw/core/machine-hmp-cmds.c::hmp_hotpluggable_cpus() to dump
17
Message-id: 1493122030-32191-13-git-send-email-peter.maydell@linaro.org
14
cluster-id.
18
[PMM: Keep all the bits in mpu_ctrl field, rather than
15
19
using SCTLR bits for them; drop broken HFNMIENA support;
16
Signed-off-by: Gavin Shan <gshan@redhat.com>
20
various cleanup]
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
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
21
---
23
target/arm/cpu.h | 6 +++
22
qapi/machine.json | 6 ++++--
24
hw/intc/armv7m_nvic.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++
23
hw/core/machine-hmp-cmds.c | 4 ++++
25
target/arm/helper.c | 25 +++++++++++-
24
hw/core/machine.c | 16 ++++++++++++++++
26
target/arm/machine.c | 5 ++-
25
3 files changed, 24 insertions(+), 2 deletions(-)
27
4 files changed, 137 insertions(+), 3 deletions(-)
28
26
29
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
27
diff --git a/qapi/machine.json b/qapi/machine.json
30
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/cpu.h
29
--- a/qapi/machine.json
32
+++ b/target/arm/cpu.h
30
+++ b/qapi/machine.json
33
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
31
@@ -XXX,XX +XXX,XX @@
34
uint32_t dfsr; /* Debug Fault Status Register */
32
# @node-id: NUMA node ID the CPU belongs to
35
uint32_t mmfar; /* MemManage Fault Address */
33
# @socket-id: socket number within node/board the CPU belongs to
36
uint32_t bfar; /* BusFault Address */
34
# @die-id: die number within socket the CPU belongs to (since 4.1)
37
+ unsigned mpu_ctrl; /* MPU_CTRL (some bits kept in sctlr_el[1]) */
35
-# @core-id: core number within die the CPU belongs to
38
int exception;
36
+# @cluster-id: cluster number within die the CPU belongs to (since 7.1)
39
} v7m;
37
+# @core-id: core number within cluster the CPU belongs to
40
38
# @thread-id: thread number within core the CPU belongs to
41
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_DFSR, DWTTRAP, 2, 1)
39
#
42
FIELD(V7M_DFSR, VCATCH, 3, 1)
40
-# Note: currently there are 5 properties that could be present
43
FIELD(V7M_DFSR, EXTERNAL, 4, 1)
41
+# Note: currently there are 6 properties that could be present
44
42
# but management should be prepared to pass through other
45
+/* v7M MPU_CTRL bits */
43
# properties with device_add command to allow for future
46
+FIELD(V7M_MPU_CTRL, ENABLE, 0, 1)
44
# interface extension. This also requires the filed names to be kept in
47
+FIELD(V7M_MPU_CTRL, HFNMIENA, 1, 1)
45
@@ -XXX,XX +XXX,XX @@
48
+FIELD(V7M_MPU_CTRL, PRIVDEFENA, 2, 1)
46
'data': { '*node-id': 'int',
49
+
47
'*socket-id': 'int',
50
/* If adding a feature bit which corresponds to a Linux ELF
48
'*die-id': 'int',
51
* HWCAP bit, remember to update the feature-bit-to-hwcap
49
+ '*cluster-id': 'int',
52
* mapping in linux-user/elfload.c:get_elf_hwcap().
50
'*core-id': 'int',
53
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
51
'*thread-id': 'int'
52
}
53
diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
54
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/intc/armv7m_nvic.c
55
--- a/hw/core/machine-hmp-cmds.c
56
+++ b/hw/intc/armv7m_nvic.c
56
+++ b/hw/core/machine-hmp-cmds.c
57
@@ -XXX,XX +XXX,XX @@
57
@@ -XXX,XX +XXX,XX @@ void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict)
58
#include "hw/arm/arm.h"
58
if (c->has_die_id) {
59
#include "hw/arm/armv7m_nvic.h"
59
monitor_printf(mon, " die-id: \"%" PRIu64 "\"\n", c->die_id);
60
#include "target/arm/cpu.h"
60
}
61
+#include "exec/exec-all.h"
61
+ if (c->has_cluster_id) {
62
#include "qemu/log.h"
62
+ monitor_printf(mon, " cluster-id: \"%" PRIu64 "\"\n",
63
#include "trace.h"
63
+ c->cluster_id);
64
65
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset)
66
case 0xd70: /* ISAR4. */
67
return 0x01310102;
68
/* TODO: Implement debug registers. */
69
+ case 0xd90: /* MPU_TYPE */
70
+ /* Unified MPU; if the MPU is not present this value is zero */
71
+ return cpu->pmsav7_dregion << 8;
72
+ break;
73
+ case 0xd94: /* MPU_CTRL */
74
+ return cpu->env.v7m.mpu_ctrl;
75
+ case 0xd98: /* MPU_RNR */
76
+ return cpu->env.cp15.c6_rgnr;
77
+ case 0xd9c: /* MPU_RBAR */
78
+ case 0xda4: /* MPU_RBAR_A1 */
79
+ case 0xdac: /* MPU_RBAR_A2 */
80
+ case 0xdb4: /* MPU_RBAR_A3 */
81
+ {
82
+ int region = cpu->env.cp15.c6_rgnr;
83
+
84
+ if (region >= cpu->pmsav7_dregion) {
85
+ return 0;
86
+ }
64
+ }
87
+ return (cpu->env.pmsav7.drbar[region] & 0x1f) | (region & 0xf);
65
if (c->has_core_id) {
88
+ }
66
monitor_printf(mon, " core-id: \"%" PRIu64 "\"\n", c->core_id);
89
+ case 0xda0: /* MPU_RASR */
67
}
90
+ case 0xda8: /* MPU_RASR_A1 */
68
diff --git a/hw/core/machine.c b/hw/core/machine.c
91
+ case 0xdb0: /* MPU_RASR_A2 */
69
index XXXXXXX..XXXXXXX 100644
92
+ case 0xdb8: /* MPU_RASR_A3 */
70
--- a/hw/core/machine.c
93
+ {
71
+++ b/hw/core/machine.c
94
+ int region = cpu->env.cp15.c6_rgnr;
72
@@ -XXX,XX +XXX,XX @@ void machine_set_cpu_numa_node(MachineState *machine,
95
+
73
return;
96
+ if (region >= cpu->pmsav7_dregion) {
74
}
97
+ return 0;
75
98
+ }
76
+ if (props->has_cluster_id && !slot->props.has_cluster_id) {
99
+ return ((cpu->env.pmsav7.dracr[region] & 0xffff) << 16) |
77
+ error_setg(errp, "cluster-id is not supported");
100
+ (cpu->env.pmsav7.drsr[region] & 0xffff);
101
+ }
102
default:
103
qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
104
return 0;
105
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
106
qemu_log_mask(LOG_UNIMP,
107
"NVIC: Aux fault status registers unimplemented\n");
108
break;
109
+ case 0xd90: /* MPU_TYPE */
110
+ return; /* RO */
111
+ case 0xd94: /* MPU_CTRL */
112
+ if ((value &
113
+ (R_V7M_MPU_CTRL_HFNMIENA_MASK | R_V7M_MPU_CTRL_ENABLE_MASK))
114
+ == R_V7M_MPU_CTRL_HFNMIENA_MASK) {
115
+ qemu_log_mask(LOG_GUEST_ERROR, "MPU_CTRL: HFNMIENA and !ENABLE is "
116
+ "UNPREDICTABLE\n");
117
+ }
118
+ cpu->env.v7m.mpu_ctrl = value & (R_V7M_MPU_CTRL_ENABLE_MASK |
119
+ R_V7M_MPU_CTRL_HFNMIENA_MASK |
120
+ R_V7M_MPU_CTRL_PRIVDEFENA_MASK);
121
+ tlb_flush(CPU(cpu));
122
+ break;
123
+ case 0xd98: /* MPU_RNR */
124
+ if (value >= cpu->pmsav7_dregion) {
125
+ qemu_log_mask(LOG_GUEST_ERROR, "MPU region out of range %"
126
+ PRIu32 "/%" PRIu32 "\n",
127
+ value, cpu->pmsav7_dregion);
128
+ } else {
129
+ cpu->env.cp15.c6_rgnr = value;
130
+ }
131
+ break;
132
+ case 0xd9c: /* MPU_RBAR */
133
+ case 0xda4: /* MPU_RBAR_A1 */
134
+ case 0xdac: /* MPU_RBAR_A2 */
135
+ case 0xdb4: /* MPU_RBAR_A3 */
136
+ {
137
+ int region;
138
+
139
+ if (value & (1 << 4)) {
140
+ /* VALID bit means use the region number specified in this
141
+ * value and also update MPU_RNR.REGION with that value.
142
+ */
143
+ region = extract32(value, 0, 4);
144
+ if (region >= cpu->pmsav7_dregion) {
145
+ qemu_log_mask(LOG_GUEST_ERROR,
146
+ "MPU region out of range %u/%" PRIu32 "\n",
147
+ region, cpu->pmsav7_dregion);
148
+ return;
149
+ }
150
+ cpu->env.cp15.c6_rgnr = region;
151
+ } else {
152
+ region = cpu->env.cp15.c6_rgnr;
153
+ }
154
+
155
+ if (region >= cpu->pmsav7_dregion) {
156
+ return;
78
+ return;
157
+ }
79
+ }
158
+
80
+
159
+ cpu->env.pmsav7.drbar[region] = value & ~0x1f;
81
if (props->has_socket_id && !slot->props.has_socket_id) {
160
+ tlb_flush(CPU(cpu));
82
error_setg(errp, "socket-id is not supported");
161
+ break;
83
return;
162
+ }
84
@@ -XXX,XX +XXX,XX @@ void machine_set_cpu_numa_node(MachineState *machine,
163
+ case 0xda0: /* MPU_RASR */
85
continue;
164
+ case 0xda8: /* MPU_RASR_A1 */
86
}
165
+ case 0xdb0: /* MPU_RASR_A2 */
87
166
+ case 0xdb8: /* MPU_RASR_A3 */
88
+ if (props->has_cluster_id &&
167
+ {
89
+ props->cluster_id != slot->props.cluster_id) {
168
+ int region = cpu->env.cp15.c6_rgnr;
90
+ continue;
169
+
170
+ if (region >= cpu->pmsav7_dregion) {
171
+ return;
172
+ }
91
+ }
173
+
92
+
174
+ cpu->env.pmsav7.drsr[region] = value & 0xff3f;
93
if (props->has_die_id && props->die_id != slot->props.die_id) {
175
+ cpu->env.pmsav7.dracr[region] = (value >> 16) & 0x173f;
94
continue;
176
+ tlb_flush(CPU(cpu));
95
}
177
+ break;
96
@@ -XXX,XX +XXX,XX @@ static char *cpu_slot_to_string(const CPUArchId *cpu)
97
}
98
g_string_append_printf(s, "die-id: %"PRId64, cpu->props.die_id);
99
}
100
+ if (cpu->props.has_cluster_id) {
101
+ if (s->len) {
102
+ g_string_append_printf(s, ", ");
103
+ }
104
+ g_string_append_printf(s, "cluster-id: %"PRId64, cpu->props.cluster_id);
178
+ }
105
+ }
179
case 0xf00: /* Software Triggered Interrupt Register */
106
if (cpu->props.has_core_id) {
180
{
107
if (s->len) {
181
/* user mode can only write to STIR if CCR.USERSETMPEND permits it */
108
g_string_append_printf(s, ", ");
182
diff --git a/target/arm/helper.c b/target/arm/helper.c
183
index XXXXXXX..XXXXXXX 100644
184
--- a/target/arm/helper.c
185
+++ b/target/arm/helper.c
186
@@ -XXX,XX +XXX,XX @@ static inline uint32_t regime_sctlr(CPUARMState *env, ARMMMUIdx mmu_idx)
187
static inline bool regime_translation_disabled(CPUARMState *env,
188
ARMMMUIdx mmu_idx)
189
{
190
+ if (arm_feature(env, ARM_FEATURE_M)) {
191
+ return !(env->v7m.mpu_ctrl & R_V7M_MPU_CTRL_ENABLE_MASK);
192
+ }
193
+
194
if (mmu_idx == ARMMMUIdx_S2NS) {
195
return (env->cp15.hcr_el2 & HCR_VM) == 0;
196
}
197
@@ -XXX,XX +XXX,XX @@ static inline void get_phys_addr_pmsav7_default(CPUARMState *env,
198
}
199
}
200
201
+static bool pmsav7_use_background_region(ARMCPU *cpu,
202
+ ARMMMUIdx mmu_idx, bool is_user)
203
+{
204
+ /* Return true if we should use the default memory map as a
205
+ * "background" region if there are no hits against any MPU regions.
206
+ */
207
+ CPUARMState *env = &cpu->env;
208
+
209
+ if (is_user) {
210
+ return false;
211
+ }
212
+
213
+ if (arm_feature(env, ARM_FEATURE_M)) {
214
+ return env->v7m.mpu_ctrl & R_V7M_MPU_CTRL_PRIVDEFENA_MASK;
215
+ } else {
216
+ return regime_sctlr(env, mmu_idx) & SCTLR_BR;
217
+ }
218
+}
219
+
220
static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
221
int access_type, ARMMMUIdx mmu_idx,
222
hwaddr *phys_ptr, int *prot, uint32_t *fsr)
223
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
224
}
225
226
if (n == -1) { /* no hits */
227
- if (is_user || !(regime_sctlr(env, mmu_idx) & SCTLR_BR)) {
228
+ if (!pmsav7_use_background_region(cpu, mmu_idx, is_user)) {
229
/* background fault */
230
*fsr = 0;
231
return true;
232
diff --git a/target/arm/machine.c b/target/arm/machine.c
233
index XXXXXXX..XXXXXXX 100644
234
--- a/target/arm/machine.c
235
+++ b/target/arm/machine.c
236
@@ -XXX,XX +XXX,XX @@ static bool m_needed(void *opaque)
237
238
static const VMStateDescription vmstate_m = {
239
.name = "cpu/m",
240
- .version_id = 3,
241
- .minimum_version_id = 3,
242
+ .version_id = 4,
243
+ .minimum_version_id = 4,
244
.needed = m_needed,
245
.fields = (VMStateField[]) {
246
VMSTATE_UINT32(env.v7m.vecbase, ARMCPU),
247
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
248
VMSTATE_UINT32(env.v7m.dfsr, ARMCPU),
249
VMSTATE_UINT32(env.v7m.mmfar, ARMCPU),
250
VMSTATE_UINT32(env.v7m.bfar, ARMCPU),
251
+ VMSTATE_UINT32(env.v7m.mpu_ctrl, ARMCPU),
252
VMSTATE_INT32(env.v7m.exception, ARMCPU),
253
VMSTATE_END_OF_LIST()
254
}
255
--
109
--
256
2.7.4
110
2.25.1
257
258
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
From: Gavin Shan <gshan@redhat.com>
2
2
3
Don't allow load_uboot_image() to proceed when less bytes than
3
The CPU topology isn't enabled on arm/virt machine yet, but we're
4
header-size was read.
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:
5
9
6
Signed-off-by: Andrew Jones <drjones@redhat.com>
10
[14/21 qemu:qtest+qtest-aarch64 / qtest-aarch64/numa-test ERROR
7
Message-id: 20170524091315.20284-1-drjones@redhat.com
11
1.48s killed by signal 6 SIGABRT
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
29
---
11
hw/core/loader.c | 3 ++-
30
tests/qtest/numa-test.c | 3 ++-
12
1 file changed, 2 insertions(+), 1 deletion(-)
31
1 file changed, 2 insertions(+), 1 deletion(-)
13
32
14
diff --git a/hw/core/loader.c b/hw/core/loader.c
33
diff --git a/tests/qtest/numa-test.c b/tests/qtest/numa-test.c
15
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/core/loader.c
35
--- a/tests/qtest/numa-test.c
17
+++ b/hw/core/loader.c
36
+++ b/tests/qtest/numa-test.c
18
@@ -XXX,XX +XXX,XX @@ static int load_uboot_image(const char *filename, hwaddr *ep, hwaddr *loadaddr,
37
@@ -XXX,XX +XXX,XX @@ static void aarch64_numa_cpu(const void *data)
19
return -1;
38
QTestState *qts;
20
39
g_autofree char *cli = NULL;
21
size = read(fd, hdr, sizeof(uboot_image_header_t));
40
22
- if (size < 0)
41
- cli = make_cli(data, "-machine smp.cpus=2 "
23
+ if (size < sizeof(uboot_image_header_t)) {
42
+ cli = make_cli(data, "-machine "
24
goto out;
43
+ "smp.cpus=2,smp.sockets=1,smp.clusters=1,smp.cores=1,smp.threads=2 "
25
+ }
44
"-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 "
26
45
"-numa cpu,node-id=1,thread-id=0 "
27
bswap_uboot_header(hdr);
46
"-numa cpu,node-id=0,thread-id=1");
28
29
--
47
--
30
2.7.4
48
2.25.1
31
49
32
50
diff view generated by jsdifflib
1
icc_bpr_write() was not enforcing that writing a value below the
1
From: Gavin Shan <gshan@redhat.com>
2
minimum for the BPR should behave as if the BPR was set to the
3
minimum value. This doesn't make a difference for the secure
4
BPRs (since we define the minimum for the QEMU implementation
5
as zero) but did mean we were allowing the NS BPR1 to be set to
6
0 when 1 should be the lowest value.
7
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
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 1493226792-3237-3-git-send-email-peter.maydell@linaro.org
11
---
19
---
12
hw/intc/arm_gicv3_cpuif.c | 6 ++++++
20
hw/arm/virt.c | 15 ++++++++++++++-
13
1 file changed, 6 insertions(+)
21
1 file changed, 14 insertions(+), 1 deletion(-)
14
22
15
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
23
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
16
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/intc/arm_gicv3_cpuif.c
25
--- a/hw/arm/virt.c
18
+++ b/hw/intc/arm_gicv3_cpuif.c
26
+++ b/hw/arm/virt.c
19
@@ -XXX,XX +XXX,XX @@ static void icc_bpr_write(CPUARMState *env, const ARMCPRegInfo *ri,
27
@@ -XXX,XX +XXX,XX @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
20
{
28
int n;
21
GICv3CPUState *cs = icc_cs_from_env(env);
29
unsigned int max_cpus = ms->smp.max_cpus;
22
int grp = (ri->crm == 8) ? GICV3_G0 : GICV3_G1;
30
VirtMachineState *vms = VIRT_MACHINE(ms);
23
+ uint64_t minval;
31
+ MachineClass *mc = MACHINE_GET_CLASS(vms);
24
32
25
if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
33
if (ms->possible_cpus) {
26
icv_bpr_write(env, ri, value);
34
assert(ms->possible_cpus->len == max_cpus);
27
@@ -XXX,XX +XXX,XX @@ static void icc_bpr_write(CPUARMState *env, const ARMCPRegInfo *ri,
35
@@ -XXX,XX +XXX,XX @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
28
return;
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;
29
}
54
}
30
55
return ms->possible_cpus;
31
+ minval = (grp == GICV3_G1NS) ? GIC_MIN_BPR_NS : GIC_MIN_BPR;
32
+ if (value < minval) {
33
+ value = minval;
34
+ }
35
+
36
cs->icc_bpr[grp] = value & 7;
37
gicv3_cpuif_update(cs);
38
}
56
}
39
--
57
--
40
2.7.4
58
2.25.1
41
42
diff view generated by jsdifflib
1
When identifying the DFSR format for an alignment fault, use
1
From: Gavin Shan <gshan@redhat.com>
2
the mmu index that we are passed, rather than calling cpu_mmu_index()
3
to get the mmu index for the current CPU state. This doesn't actually
4
make any difference since the only cases where the current MMU index
5
differs from the index used for the load are the "unprivileged
6
load/store" instructions, and in that case the mmu index may
7
differ but the translation regime is the same (apart from the
8
"use from Hyp mode" case which is UNPREDICTABLE).
9
However it's the more logical thing to do.
10
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
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 1493122030-32191-2-git-send-email-peter.maydell@linaro.org
15
---
31
---
16
target/arm/op_helper.c | 2 +-
32
tests/qtest/numa-test.c | 18 ++++++++++++------
17
1 file changed, 1 insertion(+), 1 deletion(-)
33
1 file changed, 12 insertions(+), 6 deletions(-)
18
34
19
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
35
diff --git a/tests/qtest/numa-test.c b/tests/qtest/numa-test.c
20
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/op_helper.c
37
--- a/tests/qtest/numa-test.c
22
+++ b/target/arm/op_helper.c
38
+++ b/tests/qtest/numa-test.c
23
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
39
@@ -XXX,XX +XXX,XX @@ static void aarch64_numa_cpu(const void *data)
24
/* the DFSR for an alignment fault depends on whether we're using
40
g_autofree char *cli = NULL;
25
* the LPAE long descriptor format, or the short descriptor format
41
26
*/
42
cli = make_cli(data, "-machine "
27
- if (arm_s1_regime_using_lpae_format(env, cpu_mmu_index(env, false))) {
43
- "smp.cpus=2,smp.sockets=1,smp.clusters=1,smp.cores=1,smp.threads=2 "
28
+ if (arm_s1_regime_using_lpae_format(env, mmu_idx)) {
44
+ "smp.cpus=2,smp.sockets=2,smp.clusters=1,smp.cores=1,smp.threads=1 "
29
env->exception.fsr = (1 << 9) | 0x21;
45
"-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 "
30
} else {
46
- "-numa cpu,node-id=1,thread-id=0 "
31
env->exception.fsr = 0x1;
47
- "-numa cpu,node-id=0,thread-id=1");
48
+ "-numa cpu,node-id=0,socket-id=1,cluster-id=0,core-id=0,thread-id=0 "
49
+ "-numa cpu,node-id=1,socket-id=0,cluster-id=0,core-id=0,thread-id=0");
50
qts = qtest_init(cli);
51
cpus = get_cpus(qts, &resp);
52
g_assert(cpus);
53
54
while ((e = qlist_pop(cpus))) {
55
QDict *cpu, *props;
56
- int64_t thread, node;
57
+ int64_t socket, cluster, core, thread, node;
58
59
cpu = qobject_to(QDict, e);
60
g_assert(qdict_haskey(cpu, "props"));
61
@@ -XXX,XX +XXX,XX @@ static void aarch64_numa_cpu(const void *data)
62
63
g_assert(qdict_haskey(props, "node-id"));
64
node = qdict_get_int(props, "node-id");
65
+ g_assert(qdict_haskey(props, "socket-id"));
66
+ socket = qdict_get_int(props, "socket-id");
67
+ g_assert(qdict_haskey(props, "cluster-id"));
68
+ cluster = qdict_get_int(props, "cluster-id");
69
+ g_assert(qdict_haskey(props, "core-id"));
70
+ core = qdict_get_int(props, "core-id");
71
g_assert(qdict_haskey(props, "thread-id"));
72
thread = qdict_get_int(props, "thread-id");
73
74
- if (thread == 0) {
75
+ if (socket == 0 && cluster == 0 && core == 0 && thread == 0) {
76
g_assert_cmpint(node, ==, 1);
77
- } else if (thread == 1) {
78
+ } else if (socket == 1 && cluster == 0 && core == 0 && thread == 0) {
79
g_assert_cmpint(node, ==, 0);
80
} else {
81
g_assert(false);
32
--
82
--
33
2.7.4
83
2.25.1
34
35
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
From: Gavin Shan <gshan@redhat.com>
2
2
3
This is based on patch Shannon Zhao originally posted.
3
When CPU-to-NUMA association isn't explicitly provided by users,
4
the default one is given by mc->get_default_cpu_node_id(). However,
5
the CPU topology isn't fully considered in the default association
6
and this causes CPU topology broken warnings on booting Linux guest.
4
7
5
Cc: Shannon Zhao <zhaoshenglong@huawei.com>
8
For example, the following warning messages are observed when the
6
Signed-off-by: Andrew Jones <drjones@redhat.com>
9
Linux guest is booted with the following command lines.
7
Reviewed-by: Shannon Zhao <shannon.zhao@linaro.org>
10
8
Message-id: 20170529173751.3443-3-drjones@redhat.com
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
---
52
---
11
hw/arm/virt.c | 21 +++++++++++++++++++++
53
hw/arm/virt.c | 4 +++-
12
1 file changed, 21 insertions(+)
54
1 file changed, 3 insertions(+), 1 deletion(-)
13
55
14
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
56
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
15
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/virt.c
58
--- a/hw/arm/virt.c
17
+++ b/hw/arm/virt.c
59
+++ b/hw/arm/virt.c
18
@@ -XXX,XX +XXX,XX @@ static void create_fdt(VirtMachineState *vms)
60
@@ -XXX,XX +XXX,XX @@ virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
19
"clk24mhz");
61
20
qemu_fdt_setprop_cell(fdt, "/apb-pclk", "phandle", vms->clock_phandle);
62
static int64_t virt_get_default_cpu_node_id(const MachineState *ms, int idx)
21
63
{
22
+ if (have_numa_distance) {
64
- return idx % ms->numa_state->num_nodes;
23
+ int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
65
+ int64_t socket_id = ms->possible_cpus->cpus[idx].props.socket_id;
24
+ uint32_t *matrix = g_malloc0(size);
25
+ int idx, i, j;
26
+
66
+
27
+ for (i = 0; i < nb_numa_nodes; i++) {
67
+ return socket_id % ms->numa_state->num_nodes;
28
+ for (j = 0; j < nb_numa_nodes; j++) {
29
+ idx = (i * nb_numa_nodes + j) * 3;
30
+ matrix[idx + 0] = cpu_to_be32(i);
31
+ matrix[idx + 1] = cpu_to_be32(j);
32
+ matrix[idx + 2] = cpu_to_be32(numa_info[i].distance[j]);
33
+ }
34
+ }
35
+
36
+ qemu_fdt_add_subnode(fdt, "/distance-map");
37
+ qemu_fdt_setprop_string(fdt, "/distance-map", "compatible",
38
+ "numa-distance-map-v1");
39
+ qemu_fdt_setprop(fdt, "/distance-map", "distance-matrix",
40
+ matrix, size);
41
+ g_free(matrix);
42
+ }
43
}
68
}
44
69
45
static void fdt_add_psci_node(const VirtMachineState *vms)
70
static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
46
--
71
--
47
2.7.4
72
2.25.1
48
49
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Gavin Shan <gshan@redhat.com>
2
2
3
Multiple I2C commands can be fired simultaneously and the controller
3
When the PPTT table is built, the CPU topology is re-calculated, but
4
execute the commands following these priorities:
4
it's unecessary because the CPU topology has been populated in
5
virt_possible_cpu_arch_ids() on arm/virt machine.
5
6
6
(1) Master Start Command
7
This reworks build_pptt() to avoid by reusing the existing IDs in
7
(2) Master Transmit Command
8
ms->possible_cpus. Currently, the only user of build_pptt() is
8
(3) Slave Transmit Command or Master Receive Command
9
arm/virt machine.
9
(4) Master Stop Command
10
10
11
The current code is incorrect with respect to the above sequence and
11
Signed-off-by: Gavin Shan <gshan@redhat.com>
12
needs to be reworked to handle each individual command.
12
Tested-by: Yanan Wang <wangyanan55@huawei.com>
13
13
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
14
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
Acked-by: Igor Mammedov <imammedo@redhat.com>
15
Message-id: 1494827476-1487-2-git-send-email-clg@kaod.org
15
Acked-by: Michael S. Tsirkin <mst@redhat.com>
16
Message-id: 20220503140304.855514-7-gshan@redhat.com
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
---
18
hw/i2c/aspeed_i2c.c | 24 ++++++++++++++++++------
19
hw/acpi/aml-build.c | 111 +++++++++++++++++++-------------------------
19
1 file changed, 18 insertions(+), 6 deletions(-)
20
1 file changed, 48 insertions(+), 63 deletions(-)
20
21
21
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
22
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
22
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/i2c/aspeed_i2c.c
24
--- a/hw/acpi/aml-build.c
24
+++ b/hw/i2c/aspeed_i2c.c
25
+++ b/hw/acpi/aml-build.c
25
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
26
@@ -XXX,XX +XXX,XX @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
26
27
const char *oem_id, const char *oem_table_id)
27
static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
28
{
28
{
29
+ bus->cmd &= ~0xFFFF;
29
MachineClass *mc = MACHINE_GET_CLASS(ms);
30
bus->cmd |= value & 0xFFFF;
30
- GQueue *list = g_queue_new();
31
bus->intr_status = 0;
31
- guint pptt_start = table_data->len;
32
32
- guint parent_offset;
33
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
33
- guint length, i;
34
bus->intr_status |= I2CD_INTR_TX_ACK;
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);
35
}
89
}
36
90
- }
37
- } else if (bus->cmd & I2CD_M_TX_CMD) {
91
38
+ /* START command is also a TX command, as the slave address is
92
- length = g_queue_get_length(list);
39
+ * sent on the bus */
93
- for (i = 0; i < length; i++) {
40
+ bus->cmd &= ~(I2CD_M_START_CMD | I2CD_M_TX_CMD);
94
- int core;
41
+
95
-
42
+ /* No slave found */
96
- parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
43
+ if (!i2c_bus_busy(bus->bus)) {
97
- for (core = 0; core < ms->smp.cores; core++) {
44
+ return;
98
- if (ms->smp.threads > 1) {
45
+ }
99
- g_queue_push_tail(list,
46
+ }
100
- GUINT_TO_POINTER(table_data->len - pptt_start));
47
+
101
- build_processor_hierarchy_node(
48
+ if (bus->cmd & I2CD_M_TX_CMD) {
102
- table_data,
49
if (i2c_send(bus->bus, bus->buf)) {
103
- (0 << 0), /* not a physical package */
50
bus->intr_status |= (I2CD_INTR_TX_NAK | I2CD_INTR_ABNORMAL);
104
- parent_offset, core, NULL, 0);
51
i2c_end_transfer(bus->bus);
105
- } else {
52
} else {
106
- build_processor_hierarchy_node(
53
bus->intr_status |= I2CD_INTR_TX_ACK;
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;
54
}
123
}
55
+ bus->cmd &= ~I2CD_M_TX_CMD;
124
- }
56
+ }
125
57
126
- length = g_queue_get_length(list);
58
- } else if (bus->cmd & I2CD_M_RX_CMD) {
127
- for (i = 0; i < length; i++) {
59
+ if (bus->cmd & I2CD_M_RX_CMD) {
128
- int thread;
60
int ret = i2c_recv(bus->bus);
129
+ if (ms->smp.threads == 1) {
61
if (ret < 0) {
130
+ build_processor_hierarchy_node(table_data,
62
qemu_log_mask(LOG_GUEST_ERROR, "%s: read failed\n", __func__);
131
+ (1 << 1) | /* ACPI Processor ID valid */
63
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
132
+ (1 << 3), /* Node is a Leaf */
64
bus->intr_status |= I2CD_INTR_RX_DONE;
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);
65
}
154
}
66
bus->buf = (ret & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
67
+ bus->cmd &= ~I2CD_M_RX_CMD;
68
}
155
}
69
156
70
if (bus->cmd & (I2CD_M_STOP_CMD | I2CD_M_S_RX_CMD_LAST)) {
157
- g_queue_free(list);
71
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
158
acpi_table_end(linker, &table);
72
i2c_end_transfer(bus->bus);
73
bus->intr_status |= I2CD_INTR_NORMAL_STOP;
74
}
75
+ bus->cmd &= ~I2CD_M_STOP_CMD;
76
}
77
-
78
- /* command is handled, reset it and check for interrupts */
79
- bus->cmd &= ~0xFFFF;
80
- aspeed_i2c_bus_raise_interrupt(bus);
81
}
159
}
82
160
83
static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
84
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
85
}
86
87
aspeed_i2c_bus_handle_cmd(bus, value);
88
+ aspeed_i2c_bus_raise_interrupt(bus);
89
break;
90
91
default:
92
--
161
--
93
2.7.4
162
2.25.1
94
95
diff view generated by jsdifflib