1
target-arm queue for softfreeze:
1
target-arm queue: the big stuff here is the final part of
2
This has all the big stuff I want to get in for softfreeze;
2
rth's patches for Cortex-A76 and Neoverse-N1 support;
3
there may be one or two smaller patches I pick up later in
3
also present are Gavin's NUMA series and a few other things.
4
the week.
5
4
6
thanks
5
thanks
7
-- PMM
6
-- PMM
8
7
9
The following changes since commit 0984a157c1c053394adbf64ed7de97f1aebe6a2d:
8
The following changes since commit 554623226f800acf48a2ed568900c1c968ec9a8b:
10
9
11
Merge remote-tracking branch 'remotes/jasowang/tags/net-pull-request' into staging (2019-03-05 09:33:20 +0000)
10
Merge tag 'qemu-sparc-20220508' of https://github.com/mcayland/qemu into staging (2022-05-08 17:03:26 -0500)
12
11
13
are available in the Git repository at:
12
are available in the Git repository at:
14
13
15
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190305
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220509
16
15
17
for you to fetch changes up to 566528f823d1a2e9eb2d7b2ed839547cb31bfc34:
16
for you to fetch changes up to ae9141d4a3265553503bf07d3574b40f84615a34:
18
17
19
hw/arm/stellaris: Implement watchdog timer (2019-03-05 15:55:09 +0000)
18
hw/acpi/aml-build: Use existing CPU topology to build PPTT table (2022-05-09 11:47:55 +0100)
20
19
21
----------------------------------------------------------------
20
----------------------------------------------------------------
22
target-arm queue:
21
target-arm queue:
23
* Fix PC test for LDM (exception return)
22
* MAINTAINERS/.mailmap: update email for Leif Lindholm
24
* Implement ARMv8.0-SB
23
* hw/arm: add version information to sbsa-ref machine DT
25
* Implement ARMv8.0-PredInv
24
* Enable new features for -cpu max:
26
* Implement ARMv8.4-CondM
25
FEAT_Debugv8p2, FEAT_Debugv8p4, FEAT_RAS (minimal version only),
27
* Implement ARMv8.5-CondM
26
FEAT_IESB, FEAT_CSV2, FEAT_CSV2_2, FEAT_CSV3, FEAT_DGH
28
* Implement ARMv8.5-FRINT
27
* Emulate Cortex-A76
29
* hw/arm/stellaris: Implement watchdog timer
28
* Emulate Neoverse-N1
30
* virt: support more than 255GB of RAM
29
* Fix the virt board default NUMA topology
31
30
32
----------------------------------------------------------------
31
----------------------------------------------------------------
33
Eric Auger (9):
32
Gavin Shan (6):
34
hw/arm/virt: Rename highmem IO regions
33
qapi/machine.json: Add cluster-id
35
hw/arm/virt: Split the memory map description
34
qtest/numa-test: Specify CPU topology in aarch64_numa_cpu()
36
hw/boards: Add a MachineState parameter to kvm_type callback
35
hw/arm/virt: Consider SMP configuration in CPU topology
37
kvm: add kvm_arm_get_max_vm_ipa_size
36
qtest/numa-test: Correct CPU and NUMA association in aarch64_numa_cpu()
38
vl: Set machine ram_size, maxram_size and ram_slots earlier
37
hw/arm/virt: Fix CPU's default NUMA node ID
39
hw/arm/virt: Dynamic memory map depending on RAM requirements
38
hw/acpi/aml-build: Use existing CPU topology to build PPTT table
40
hw/arm/virt: Implement kvm_type function for 4.0 machine
41
hw/arm/virt: Check the VCPU PA range in TCG mode
42
hw/arm/virt: Bump the 255GB initial RAM limit
43
39
44
Michel Heily (1):
40
Leif Lindholm (2):
45
hw/arm/stellaris: Implement watchdog timer
41
MAINTAINERS/.mailmap: update email for Leif Lindholm
42
hw/arm: add versioning to sbsa-ref machine DT
46
43
47
Richard Henderson (11):
44
Richard Henderson (24):
48
target/arm: Fix PC test for LDM (exception return)
45
target/arm: Handle cpreg registration for missing EL
49
target/arm: Split out arm_sctlr
46
target/arm: Drop EL3 no EL2 fallbacks
50
target/arm: Implement ARMv8.0-SB
47
target/arm: Merge zcr reginfo
51
target/arm: Implement ARMv8.0-PredInv
48
target/arm: Adjust definition of CONTEXTIDR_EL2
52
target/arm: Split helper_msr_i_pstate into 3
49
target/arm: Move cortex impdef sysregs to cpu_tcg.c
53
target/arm: Add set/clear_pstate_bits, share gen_ss_advance
50
target/arm: Update qemu-system-arm -cpu max to cortex-a57
54
target/arm: Rearrange disas_data_proc_reg
51
target/arm: Set ID_DFR0.PerfMon for qemu-system-arm -cpu max
55
target/arm: Implement ARMv8.4-CondM
52
target/arm: Split out aa32_max_features
56
target/arm: Implement ARMv8.5-CondM
53
target/arm: Annotate arm_max_initfn with FEAT identifiers
57
target/arm: Restructure handle_fp_1src_{single, double}
54
target/arm: Use field names for manipulating EL2 and EL3 modes
58
target/arm: Implement ARMv8.5-FRINT
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
59
69
60
Shameer Kolothum (1):
70
docs/system/arm/emulation.rst | 10 +
61
hw/arm/boot: introduce fdt_add_memory_node helper
71
docs/system/arm/virt.rst | 2 +
62
72
qapi/machine.json | 6 +-
63
include/hw/arm/virt.h | 16 +-
73
target/arm/cpregs.h | 11 +
64
include/hw/boards.h | 5 +-
74
target/arm/cpu.h | 23 ++
65
include/hw/watchdog/cmsdk-apb-watchdog.h | 8 +
75
target/arm/helper.h | 1 +
66
target/arm/cpu.h | 64 ++++-
76
target/arm/internals.h | 16 ++
67
target/arm/helper-a64.h | 3 +
77
target/arm/syndrome.h | 5 +
68
target/arm/helper.h | 8 +-
78
target/arm/a32.decode | 16 +-
69
target/arm/internals.h | 15 +
79
target/arm/t32.decode | 18 +-
70
target/arm/kvm_arm.h | 13 +
80
hw/acpi/aml-build.c | 111 ++++----
71
target/arm/translate.h | 34 +++
81
hw/arm/sbsa-ref.c | 16 ++
72
accel/kvm/kvm-all.c | 2 +-
82
hw/arm/virt.c | 21 +-
73
hw/arm/boot.c | 54 ++--
83
hw/core/machine-hmp-cmds.c | 4 +
74
hw/arm/stellaris.c | 22 +-
84
hw/core/machine.c | 16 ++
75
hw/arm/virt-acpi-build.c | 10 +-
85
target/arm/cpu.c | 66 ++++-
76
hw/arm/virt.c | 196 ++++++++++---
86
target/arm/cpu64.c | 353 ++++++++++++++-----------
77
hw/ppc/mac_newworld.c | 3 +-
87
target/arm/cpu_tcg.c | 227 +++++++++++-----
78
hw/ppc/mac_oldworld.c | 2 +-
88
target/arm/helper.c | 600 +++++++++++++++++++++++++-----------------
79
hw/ppc/spapr.c | 2 +-
89
target/arm/op_helper.c | 43 +++
80
hw/watchdog/cmsdk-apb-watchdog.c | 74 ++++-
90
target/arm/translate-a64.c | 18 ++
81
linux-user/elfload.c | 2 +
91
target/arm/translate.c | 23 ++
82
target/arm/cpu.c | 2 +
92
tests/qtest/numa-test.c | 19 +-
83
target/arm/cpu64.c | 6 +
93
.mailmap | 3 +-
84
target/arm/helper-a64.c | 30 ++
94
MAINTAINERS | 2 +-
85
target/arm/helper.c | 63 +++-
95
25 files changed, 1068 insertions(+), 562 deletions(-)
86
target/arm/kvm.c | 10 +
87
target/arm/op_helper.c | 47 ---
88
target/arm/translate-a64.c | 478 +++++++++++++++++++++++--------
89
target/arm/translate.c | 35 ++-
90
target/arm/vfp_helper.c | 96 +++++++
91
vl.c | 6 +-
92
29 files changed, 1032 insertions(+), 274 deletions(-)
93
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
2
3
On ARM, the kvm_type will be resolved by querying the KVMState.
3
NUVIA was acquired by Qualcomm in March 2021, but kept functioning on
4
Let's add the MachineState handle to the callback so that we
4
separate infrastructure for a transitional period. We've now switched
5
can retrieve the KVMState handle. in kvm_init, when the callback
5
over to contributing as Qualcomm Innovation Center (quicinc), so update
6
is called, the kvm_state variable is not yet set.
6
my email address to reflect this.
7
7
8
Signed-off-by: Eric Auger <eric.auger@redhat.com>
8
Signed-off-by: Leif Lindholm <quic_llindhol@quicinc.com>
9
Acked-by: David Gibson <david@gibson.dropbear.id.au>
9
Message-id: 20220505113740.75565-1-quic_llindhol@quicinc.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Cc: Leif Lindholm <leif@nuviainc.com>
11
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
11
Cc: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20190304101339.25970-5-eric.auger@redhat.com
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
[ppc parts]
13
[Fixed commit message typo]
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
15
---
18
include/hw/boards.h | 5 ++++-
16
.mailmap | 3 ++-
19
accel/kvm/kvm-all.c | 2 +-
17
MAINTAINERS | 2 +-
20
hw/ppc/mac_newworld.c | 3 +--
18
2 files changed, 3 insertions(+), 2 deletions(-)
21
hw/ppc/mac_oldworld.c | 2 +-
22
hw/ppc/spapr.c | 2 +-
23
5 files changed, 8 insertions(+), 6 deletions(-)
24
19
25
diff --git a/include/hw/boards.h b/include/hw/boards.h
20
diff --git a/.mailmap b/.mailmap
26
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/boards.h
22
--- a/.mailmap
28
+++ b/include/hw/boards.h
23
+++ b/.mailmap
29
@@ -XXX,XX +XXX,XX @@ typedef struct {
24
@@ -XXX,XX +XXX,XX @@ Greg Kurz <groug@kaod.org> <gkurz@linux.vnet.ibm.com>
30
* should instead use "unimplemented-device" for all memory ranges where
25
Huacai Chen <chenhuacai@kernel.org> <chenhc@lemote.com>
31
* the guest will attempt to probe for a device that QEMU doesn't
26
Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
32
* implement and a stub device is required.
27
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
33
+ * @kvm_type:
28
-Leif Lindholm <leif@nuviainc.com> <leif.lindholm@linaro.org>
34
+ * Return the type of KVM corresponding to the kvm-type string option or
29
+Leif Lindholm <quic_llindhol@quicinc.com> <leif.lindholm@linaro.org>
35
+ * computed based on other criteria such as the host kernel capabilities.
30
+Leif Lindholm <quic_llindhol@quicinc.com> <leif@nuviainc.com>
36
*/
31
Radoslaw Biernacki <rad@semihalf.com> <radoslaw.biernacki@linaro.org>
37
struct MachineClass {
32
Paul Burton <paulburton@kernel.org> <paul.burton@mips.com>
38
/*< private >*/
33
Paul Burton <paulburton@kernel.org> <paul.burton@imgtec.com>
39
@@ -XXX,XX +XXX,XX @@ struct MachineClass {
34
diff --git a/MAINTAINERS b/MAINTAINERS
40
void (*init)(MachineState *state);
41
void (*reset)(void);
42
void (*hot_add_cpu)(const int64_t id, Error **errp);
43
- int (*kvm_type)(const char *arg);
44
+ int (*kvm_type)(MachineState *machine, const char *arg);
45
46
BlockInterfaceType block_default_type;
47
int units_per_default_bus;
48
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
49
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
50
--- a/accel/kvm/kvm-all.c
36
--- a/MAINTAINERS
51
+++ b/accel/kvm/kvm-all.c
37
+++ b/MAINTAINERS
52
@@ -XXX,XX +XXX,XX @@ static int kvm_init(MachineState *ms)
38
@@ -XXX,XX +XXX,XX @@ F: include/hw/ssi/imx_spi.h
53
39
SBSA-REF
54
kvm_type = qemu_opt_get(qemu_get_machine_opts(), "kvm-type");
40
M: Radoslaw Biernacki <rad@semihalf.com>
55
if (mc->kvm_type) {
41
M: Peter Maydell <peter.maydell@linaro.org>
56
- type = mc->kvm_type(kvm_type);
42
-R: Leif Lindholm <leif@nuviainc.com>
57
+ type = mc->kvm_type(ms, kvm_type);
43
+R: Leif Lindholm <quic_llindhol@quicinc.com>
58
} else if (kvm_type) {
44
L: qemu-arm@nongnu.org
59
ret = -EINVAL;
45
S: Maintained
60
fprintf(stderr, "Invalid argument kvm-type=%s\n", kvm_type);
46
F: hw/arm/sbsa-ref.c
61
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/ppc/mac_newworld.c
64
+++ b/hw/ppc/mac_newworld.c
65
@@ -XXX,XX +XXX,XX @@ static char *core99_fw_dev_path(FWPathProvider *p, BusState *bus,
66
67
return NULL;
68
}
69
-
70
-static int core99_kvm_type(const char *arg)
71
+static int core99_kvm_type(MachineState *machine, const char *arg)
72
{
73
/* Always force PR KVM */
74
return 2;
75
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/hw/ppc/mac_oldworld.c
78
+++ b/hw/ppc/mac_oldworld.c
79
@@ -XXX,XX +XXX,XX @@ static char *heathrow_fw_dev_path(FWPathProvider *p, BusState *bus,
80
return NULL;
81
}
82
83
-static int heathrow_kvm_type(const char *arg)
84
+static int heathrow_kvm_type(MachineState *machine, const char *arg)
85
{
86
/* Always force PR KVM */
87
return 2;
88
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/hw/ppc/spapr.c
91
+++ b/hw/ppc/spapr.c
92
@@ -XXX,XX +XXX,XX @@ static void spapr_machine_init(MachineState *machine)
93
}
94
}
95
96
-static int spapr_kvm_type(const char *vm_type)
97
+static int spapr_kvm_type(MachineState *machine, const char *vm_type)
98
{
99
if (!vm_type) {
100
return 0;
101
--
47
--
102
2.20.1
48
2.25.1
103
49
104
50
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Up to now the memory map has been static and the high IO region
3
More gracefully handle cpregs when EL2 and/or EL3 are missing.
4
base has always been 256GiB.
4
If the reg is entirely inaccessible, do not register it at all.
5
5
If the reg is for EL2, and EL3 is present but EL2 is not,
6
This patch modifies the virt_set_memmap() function, which freezes
6
either discard, squash to res0, const, or keep unchanged.
7
the memory map, so that the high IO range base becomes floating,
7
8
located after the initial RAM and the device memory.
8
Per rule RJFFP, mark the 4 aarch32 hypervisor access registers
9
9
with ARM_CP_EL3_NO_EL2_KEEP, and mark all of the EL2 address
10
The function computes
10
translation and tlb invalidation "regs" ARM_CP_EL3_NO_EL2_UNDEF.
11
- the base of the device memory,
11
Mark the 2 virtualization processor id regs ARM_CP_EL3_NO_EL2_C_NZ.
12
- the size of the device memory,
12
13
- the high IO region base
13
This will simplify cpreg registration for conditional arm features.
14
- the highest GPA used in the memory map.
14
15
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Entries of the high IO region are assigned a base address. The
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
device memory is initialized.
17
Message-id: 20220506180242.216785-2-richard.henderson@linaro.org
18
19
The highest GPA used in the memory map will be used at VM creation
20
to choose the requested IPA size.
21
22
Setting all the existing highmem IO regions beyond the RAM
23
allows to have a single contiguous RAM region (initial RAM and
24
possible hotpluggable device memory). That way we do not need
25
to do invasive changes in the EDK2 FW to support a dynamic
26
RAM base.
27
28
Still the user cannot request an initial RAM size greater than 255GB.
29
30
Signed-off-by: Eric Auger <eric.auger@redhat.com>
31
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
32
Message-id: 20190304101339.25970-8-eric.auger@redhat.com
33
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
---
19
---
35
include/hw/arm/virt.h | 1 +
20
target/arm/cpregs.h | 11 +++
36
hw/arm/virt.c | 52 ++++++++++++++++++++++++++++++++++++++-----
21
target/arm/helper.c | 178 ++++++++++++++++++++++++++++++--------------
37
2 files changed, 47 insertions(+), 6 deletions(-)
22
2 files changed, 133 insertions(+), 56 deletions(-)
38
23
39
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
24
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
40
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
41
--- a/include/hw/arm/virt.h
26
--- a/target/arm/cpregs.h
42
+++ b/include/hw/arm/virt.h
27
+++ b/target/arm/cpregs.h
43
@@ -XXX,XX +XXX,XX @@ typedef struct {
28
@@ -XXX,XX +XXX,XX @@ enum {
44
uint32_t msi_phandle;
29
ARM_CP_SVE = 1 << 14,
45
uint32_t iommu_phandle;
30
/* Flag: Do not expose in gdb sysreg xml. */
46
int psci_conduit;
31
ARM_CP_NO_GDB = 1 << 15,
47
+ hwaddr highest_gpa;
32
+ /*
48
} VirtMachineState;
33
+ * Flags: If EL3 but not EL2...
49
34
+ * - UNDEF: discard the cpreg,
50
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
35
+ * - KEEP: retain the cpreg as is,
51
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
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
/*
46
diff --git a/target/arm/helper.c b/target/arm/helper.c
52
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
53
--- a/hw/arm/virt.c
48
--- a/target/arm/helper.c
54
+++ b/hw/arm/virt.c
49
+++ b/target/arm/helper.c
55
@@ -XXX,XX +XXX,XX @@
50
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
56
#include "qapi/visitor.h"
51
.access = PL1_RW, .readfn = spsel_read, .writefn = spsel_write },
57
#include "standard-headers/linux/input.h"
52
{ .name = "FPEXC32_EL2", .state = ARM_CP_STATE_AA64,
58
#include "hw/arm/smmuv3.h"
53
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 3, .opc2 = 0,
59
+#include "hw/acpi/acpi.h"
54
- .access = PL2_RW, .type = ARM_CP_ALIAS | ARM_CP_FPU,
60
55
+ .access = PL2_RW,
61
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
56
+ .type = ARM_CP_ALIAS | ARM_CP_FPU | ARM_CP_EL3_NO_EL2_KEEP,
62
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
57
.fieldoffset = offsetof(CPUARMState, vfp.xregs[ARM_VFP_FPEXC]) },
63
@@ -XXX,XX +XXX,XX @@
58
{ .name = "DACR32_EL2", .state = ARM_CP_STATE_AA64,
64
* of a terabyte of RAM will be doing it on a host with more than a
59
.opc0 = 3, .opc1 = 4, .crn = 3, .crm = 0, .opc2 = 0,
65
* terabyte of physical address space.)
60
- .access = PL2_RW, .resetvalue = 0,
66
*/
61
+ .access = PL2_RW, .resetvalue = 0, .type = ARM_CP_EL3_NO_EL2_KEEP,
67
-#define RAMLIMIT_GB 255
62
.writefn = dacr_write, .raw_writefn = raw_write,
68
-#define RAMLIMIT_BYTES (RAMLIMIT_GB * 1024ULL * 1024 * 1024)
63
.fieldoffset = offsetof(CPUARMState, cp15.dacr32_el2) },
69
+#define LEGACY_RAMLIMIT_GB 255
64
{ .name = "IFSR32_EL2", .state = ARM_CP_STATE_AA64,
70
+#define LEGACY_RAMLIMIT_BYTES (LEGACY_RAMLIMIT_GB * GiB)
65
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 0, .opc2 = 1,
71
66
- .access = PL2_RW, .resetvalue = 0,
72
/* Addresses and sizes of our components.
67
+ .access = PL2_RW, .resetvalue = 0, .type = ARM_CP_EL3_NO_EL2_KEEP,
73
* 0..128MB is space for a flash device so we can run bootrom code such as UEFI.
68
.fieldoffset = offsetof(CPUARMState, cp15.ifsr32_el2) },
74
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry base_memmap[] = {
69
{ .name = "SPSR_IRQ", .state = ARM_CP_STATE_AA64,
75
[VIRT_PCIE_MMIO] = { 0x10000000, 0x2eff0000 },
70
.type = ARM_CP_ALIAS,
76
[VIRT_PCIE_PIO] = { 0x3eff0000, 0x00010000 },
71
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
77
[VIRT_PCIE_ECAM] = { 0x3f000000, 0x01000000 },
72
.writefn = tlbimva_hyp_is_write },
78
- [VIRT_MEM] = { 0x40000000, RAMLIMIT_BYTES },
73
{ .name = "TLBI_ALLE2", .state = ARM_CP_STATE_AA64,
79
+ /* Actual RAM size depends on initial RAM and device memory settings */
74
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0,
80
+ [VIRT_MEM] = { GiB, LEGACY_RAMLIMIT_BYTES },
75
- .type = ARM_CP_NO_RAW, .access = PL2_W,
81
};
76
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
82
77
.writefn = tlbi_aa64_alle2_write },
83
/*
78
{ .name = "TLBI_VAE2", .state = ARM_CP_STATE_AA64,
84
@@ -XXX,XX +XXX,XX @@ static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx)
79
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1,
85
80
- .type = ARM_CP_NO_RAW, .access = PL2_W,
86
static void virt_set_memmap(VirtMachineState *vms)
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)
87
{
223
{
88
- hwaddr base;
224
+ CPUARMState *env = &cpu->env;
89
+ MachineState *ms = MACHINE(vms);
225
uint32_t key;
90
+ hwaddr base, device_memory_base, device_memory_size;
226
ARMCPRegInfo *r2;
91
int i;
227
bool is64 = r->type & ARM_CP_64BIT;
92
228
bool ns = secstate & ARM_CP_SECSTATE_NS;
93
vms->memmap = extended_memmap;
229
int cp = r->cp;
94
@@ -XXX,XX +XXX,XX @@ static void virt_set_memmap(VirtMachineState *vms)
230
- bool isbanked;
95
vms->memmap[i] = base_memmap[i];
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
}
96
}
238
}
97
239
98
- base = 256 * GiB; /* Top of the legacy initial RAM region */
240
+ /*
99
+ if (ms->ram_slots > ACPI_MAX_RAM_SLOTS) {
241
+ * Eliminate registers that are not present because the EL is missing.
100
+ error_report("unsupported number of memory slots: %"PRIu64,
242
+ * Doing this here makes it easier to put all registers for a given
101
+ ms->ram_slots);
243
+ * feature into the same ARMCPRegInfo array and define them all at once.
102
+ exit(EXIT_FAILURE);
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
+ }
103
+ }
264
+ }
104
+
265
+
105
+ /*
266
/* Combine cpreg and name into one allocation. */
106
+ * We compute the base of the high IO region depending on the
267
name_len = strlen(name) + 1;
107
+ * amount of initial and device memory. The device memory start/size
268
r2 = g_malloc(sizeof(*r2) + name_len);
108
+ * is aligned on 1GiB. We never put the high IO region below 256GiB
269
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
109
+ * so that if maxram_size is < 255GiB we keep the legacy memory map.
270
r2->opaque = opaque;
110
+ * The device region size assumes 1GiB page max alignment per slot.
111
+ */
112
+ device_memory_base =
113
+ ROUND_UP(vms->memmap[VIRT_MEM].base + ms->ram_size, GiB);
114
+ device_memory_size = ms->maxram_size - ms->ram_size + ms->ram_slots * GiB;
115
+
116
+ /* Base address of the high IO region */
117
+ base = device_memory_base + ROUND_UP(device_memory_size, GiB);
118
+ if (base < device_memory_base) {
119
+ error_report("maxmem/slots too huge");
120
+ exit(EXIT_FAILURE);
121
+ }
122
+ if (base < vms->memmap[VIRT_MEM].base + LEGACY_RAMLIMIT_BYTES) {
123
+ base = vms->memmap[VIRT_MEM].base + LEGACY_RAMLIMIT_BYTES;
124
+ }
125
126
for (i = VIRT_LOWMEMMAP_LAST; i < ARRAY_SIZE(extended_memmap); i++) {
127
hwaddr size = extended_memmap[i].size;
128
@@ -XXX,XX +XXX,XX @@ static void virt_set_memmap(VirtMachineState *vms)
129
vms->memmap[i].size = size;
130
base += size;
131
}
271
}
132
+ vms->highest_gpa = base - 1;
272
133
+ if (device_memory_size > 0) {
273
- isbanked = r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1];
134
+ ms->device_memory = g_malloc0(sizeof(*ms->device_memory));
274
- if (isbanked) {
135
+ ms->device_memory->base = device_memory_base;
275
+ if (make_const) {
136
+ memory_region_init(&ms->device_memory->mr, OBJECT(vms),
276
+ /* This should not have been a very special register to begin. */
137
+ "device-memory", device_memory_size);
277
+ int old_special = r2->type & ARM_CP_SPECIAL_MASK;
138
+ }
278
+ assert(old_special == 0 || old_special == ARM_CP_NOP);
139
}
279
/*
140
280
- * Register is banked (using both entries in array).
141
static void machvirt_init(MachineState *machine)
281
- * Overwriting fieldoffset as the array is only used to define
142
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
282
- * banked registers but later only fieldoffset is used.
143
vms->smp_cpus = smp_cpus;
283
+ * Set the special function to CONST, retaining the other flags.
144
284
+ * This is important for e.g. ARM_CP_SVE so that we still
145
if (machine->ram_size > vms->memmap[VIRT_MEM].size) {
285
+ * take the SVE trap if CPTR_EL3.EZ == 0.
146
- error_report("mach-virt: cannot model more than %dGB RAM", RAMLIMIT_GB);
286
*/
147
+ error_report("mach-virt: cannot model more than %dGB RAM",
287
- r2->fieldoffset = r->bank_fieldoffsets[ns];
148
+ LEGACY_RAMLIMIT_GB);
288
- }
149
exit(1);
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
}
150
}
374
}
151
375
152
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
376
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
153
memory_region_allocate_system_memory(ram, NULL, "mach-virt.ram",
377
* multiple times. Special registers (ie NOP/WFI) are
154
machine->ram_size);
378
* never migratable and not even raw-accessible.
155
memory_region_add_subregion(sysmem, vms->memmap[VIRT_MEM].base, ram);
379
*/
156
+ if (machine->device_memory) {
380
- if (r->type & ARM_CP_SPECIAL_MASK) {
157
+ memory_region_add_subregion(sysmem, machine->device_memory->base,
381
+ if (r2->type & ARM_CP_SPECIAL_MASK) {
158
+ &machine->device_memory->mr);
382
r2->type |= ARM_CP_NO_RAW;
159
+ }
383
}
160
384
if (((r->crm == CP_ANY) && crm != 0) ||
161
create_flash(vms, sysmem, secure_sysmem ? secure_sysmem : sysmem);
162
163
--
385
--
164
2.20.1
386
2.25.1
165
166
diff view generated by jsdifflib
New patch
1
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
Drop el3_no_el2_cp_reginfo, el3_no_el2_v8_cp_reginfo, and the local
4
vpidr_regs definition, and rely on the squashing to ARM_CP_CONST
5
while registering for v8.
6
7
This is a behavior change for v7 cpus with Security Extensions and
8
without Virtualization Extensions, in that the virtualization cpregs
9
are now correctly not present. This would be a migration compatibility
10
break, except that we have an existing bug in which migration of 32-bit
11
cpus with Security Extensions enabled does not work.
12
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220506180242.216785-3-richard.henderson@linaro.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
target/arm/helper.c | 158 ++++----------------------------------------
19
1 file changed, 13 insertions(+), 145 deletions(-)
20
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/helper.c
24
+++ b/target/arm/helper.c
25
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
26
.fieldoffset = offsetoflow32(CPUARMState, cp15.mdcr_el3) },
27
};
28
29
-/* Used to describe the behaviour of EL2 regs when EL2 does not exist. */
30
-static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
31
- { .name = "VBAR_EL2", .state = ARM_CP_STATE_BOTH,
32
- .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
33
- .access = PL2_RW,
34
- .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore },
35
- { .name = "HCR_EL2", .state = ARM_CP_STATE_BOTH,
36
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
37
- .access = PL2_RW,
38
- .type = ARM_CP_CONST, .resetvalue = 0 },
39
- { .name = "HACR_EL2", .state = ARM_CP_STATE_BOTH,
40
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 7,
41
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
42
- { .name = "ESR_EL2", .state = ARM_CP_STATE_BOTH,
43
- .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
44
- .access = PL2_RW,
45
- .type = ARM_CP_CONST, .resetvalue = 0 },
46
- { .name = "CPTR_EL2", .state = ARM_CP_STATE_BOTH,
47
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 2,
48
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
49
- { .name = "MAIR_EL2", .state = ARM_CP_STATE_BOTH,
50
- .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 0,
51
- .access = PL2_RW, .type = ARM_CP_CONST,
52
- .resetvalue = 0 },
53
- { .name = "HMAIR1", .state = ARM_CP_STATE_AA32,
54
- .cp = 15, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1,
55
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
56
- { .name = "AMAIR_EL2", .state = ARM_CP_STATE_BOTH,
57
- .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 0,
58
- .access = PL2_RW, .type = ARM_CP_CONST,
59
- .resetvalue = 0 },
60
- { .name = "HAMAIR1", .state = ARM_CP_STATE_AA32,
61
- .cp = 15, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1,
62
- .access = PL2_RW, .type = ARM_CP_CONST,
63
- .resetvalue = 0 },
64
- { .name = "AFSR0_EL2", .state = ARM_CP_STATE_BOTH,
65
- .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 0,
66
- .access = PL2_RW, .type = ARM_CP_CONST,
67
- .resetvalue = 0 },
68
- { .name = "AFSR1_EL2", .state = ARM_CP_STATE_BOTH,
69
- .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 1,
70
- .access = PL2_RW, .type = ARM_CP_CONST,
71
- .resetvalue = 0 },
72
- { .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH,
73
- .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2,
74
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
75
- { .name = "VTCR_EL2", .state = ARM_CP_STATE_BOTH,
76
- .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2,
77
- .access = PL2_RW, .accessfn = access_el3_aa32ns,
78
- .type = ARM_CP_CONST, .resetvalue = 0 },
79
- { .name = "VTTBR", .state = ARM_CP_STATE_AA32,
80
- .cp = 15, .opc1 = 6, .crm = 2,
81
- .access = PL2_RW, .accessfn = access_el3_aa32ns,
82
- .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
83
- { .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64,
84
- .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0,
85
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
86
- { .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH,
87
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0,
88
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
89
- { .name = "TPIDR_EL2", .state = ARM_CP_STATE_BOTH,
90
- .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 2,
91
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
92
- { .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64,
93
- .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0,
94
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
95
- { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2,
96
- .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST,
97
- .resetvalue = 0 },
98
- { .name = "CNTHCTL_EL2", .state = ARM_CP_STATE_BOTH,
99
- .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 1, .opc2 = 0,
100
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
101
- { .name = "CNTVOFF_EL2", .state = ARM_CP_STATE_AA64,
102
- .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 0, .opc2 = 3,
103
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
104
- { .name = "CNTVOFF", .cp = 15, .opc1 = 4, .crm = 14,
105
- .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST,
106
- .resetvalue = 0 },
107
- { .name = "CNTHP_CVAL_EL2", .state = ARM_CP_STATE_AA64,
108
- .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 2,
109
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
110
- { .name = "CNTHP_CVAL", .cp = 15, .opc1 = 6, .crm = 14,
111
- .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST,
112
- .resetvalue = 0 },
113
- { .name = "CNTHP_TVAL_EL2", .state = ARM_CP_STATE_BOTH,
114
- .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 0,
115
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
116
- { .name = "CNTHP_CTL_EL2", .state = ARM_CP_STATE_BOTH,
117
- .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 1,
118
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
119
- { .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH,
120
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1,
121
- .access = PL2_RW, .accessfn = access_tda,
122
- .type = ARM_CP_CONST, .resetvalue = 0 },
123
- { .name = "HPFAR_EL2", .state = ARM_CP_STATE_BOTH,
124
- .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4,
125
- .access = PL2_RW, .accessfn = access_el3_aa32ns,
126
- .type = ARM_CP_CONST, .resetvalue = 0 },
127
- { .name = "HSTR_EL2", .state = ARM_CP_STATE_BOTH,
128
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 3,
129
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
130
- { .name = "FAR_EL2", .state = ARM_CP_STATE_BOTH,
131
- .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
132
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
133
- { .name = "HIFAR", .state = ARM_CP_STATE_AA32,
134
- .type = ARM_CP_CONST,
135
- .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 2,
136
- .access = PL2_RW, .resetvalue = 0 },
137
-};
138
-
139
-/* Ditto, but for registers which exist in ARMv8 but not v7 */
140
-static const ARMCPRegInfo el3_no_el2_v8_cp_reginfo[] = {
141
- { .name = "HCR2", .state = ARM_CP_STATE_AA32,
142
- .cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4,
143
- .access = PL2_RW,
144
- .type = ARM_CP_CONST, .resetvalue = 0 },
145
-};
146
-
147
static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
148
{
149
ARMCPU *cpu = env_archcpu(env);
150
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
151
define_arm_cp_regs(cpu, v8_idregs);
152
define_arm_cp_regs(cpu, v8_cp_reginfo);
153
}
154
- if (arm_feature(env, ARM_FEATURE_EL2)) {
155
+
156
+ /*
157
+ * Register the base EL2 cpregs.
158
+ * Pre v8, these registers are implemented only as part of the
159
+ * Virtualization Extensions (EL2 present). Beginning with v8,
160
+ * if EL2 is missing but EL3 is enabled, mostly these become
161
+ * RES0 from EL3, with some specific exceptions.
162
+ */
163
+ if (arm_feature(env, ARM_FEATURE_EL2)
164
+ || (arm_feature(env, ARM_FEATURE_EL3)
165
+ && arm_feature(env, ARM_FEATURE_V8))) {
166
uint64_t vmpidr_def = mpidr_read_val(env);
167
ARMCPRegInfo vpidr_regs[] = {
168
{ .name = "VPIDR", .state = ARM_CP_STATE_AA32,
169
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
170
};
171
define_one_arm_cp_reg(cpu, &rvbar);
172
}
173
- } else {
174
- /* If EL2 is missing but higher ELs are enabled, we need to
175
- * register the no_el2 reginfos.
176
- */
177
- if (arm_feature(env, ARM_FEATURE_EL3)) {
178
- /* When EL3 exists but not EL2, VPIDR and VMPIDR take the value
179
- * of MIDR_EL1 and MPIDR_EL1.
180
- */
181
- ARMCPRegInfo vpidr_regs[] = {
182
- { .name = "VPIDR_EL2", .state = ARM_CP_STATE_BOTH,
183
- .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,
184
- .access = PL2_RW, .accessfn = access_el3_aa32ns,
185
- .type = ARM_CP_CONST, .resetvalue = cpu->midr,
186
- .fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) },
187
- { .name = "VMPIDR_EL2", .state = ARM_CP_STATE_BOTH,
188
- .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,
189
- .access = PL2_RW, .accessfn = access_el3_aa32ns,
190
- .type = ARM_CP_NO_RAW,
191
- .writefn = arm_cp_write_ignore, .readfn = mpidr_read },
192
- };
193
- define_arm_cp_regs(cpu, vpidr_regs);
194
- define_arm_cp_regs(cpu, el3_no_el2_cp_reginfo);
195
- if (arm_feature(env, ARM_FEATURE_V8)) {
196
- define_arm_cp_regs(cpu, el3_no_el2_v8_cp_reginfo);
197
- }
198
- }
199
}
200
+
201
+ /* Register the base EL3 cpregs. */
202
if (arm_feature(env, ARM_FEATURE_EL3)) {
203
define_arm_cp_regs(cpu, el3_cp_reginfo);
204
ARMCPRegInfo el3_regs[] = {
205
--
206
2.25.1
diff view generated by jsdifflib
1
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
We introduce an helper to create a memory node.
3
Drop zcr_no_el2_reginfo and merge the 3 registers into one array,
4
now that ZCR_EL2 can be squashed to RES0 and ZCR_EL3 dropped
5
while registering.
4
6
5
Signed-off-by: Eric Auger <eric.auger@redhat.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
9
Message-id: 20220506180242.216785-4-richard.henderson@linaro.org
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190304101339.25970-2-eric.auger@redhat.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
hw/arm/boot.c | 54 ++++++++++++++++++++++++++++++++-------------------
12
target/arm/helper.c | 55 ++++++++++++++-------------------------------
13
1 file changed, 34 insertions(+), 20 deletions(-)
13
1 file changed, 17 insertions(+), 38 deletions(-)
14
14
15
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/boot.c
17
--- a/target/arm/helper.c
18
+++ b/hw/arm/boot.c
18
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ static void set_kernel_args_old(const struct arm_boot_info *info,
19
@@ -XXX,XX +XXX,XX @@ static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
20
}
20
}
21
}
21
}
22
22
23
+static int fdt_add_memory_node(void *fdt, uint32_t acells, hwaddr mem_base,
23
-static const ARMCPRegInfo zcr_el1_reginfo = {
24
+ uint32_t scells, hwaddr mem_len,
24
- .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
25
+ int numa_node_id)
25
- .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
26
+{
26
- .access = PL1_RW, .type = ARM_CP_SVE,
27
+ char *nodename;
27
- .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
28
+ int ret;
28
- .writefn = zcr_write, .raw_writefn = raw_write
29
+
29
-};
30
+ nodename = g_strdup_printf("/memory@%" PRIx64, mem_base);
31
+ qemu_fdt_add_subnode(fdt, nodename);
32
+ qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
33
+ ret = qemu_fdt_setprop_sized_cells(fdt, nodename, "reg", acells, mem_base,
34
+ scells, mem_len);
35
+ if (ret < 0) {
36
+ goto out;
37
+ }
38
+
39
+ /* only set the NUMA ID if it is specified */
40
+ if (numa_node_id >= 0) {
41
+ ret = qemu_fdt_setprop_cell(fdt, nodename,
42
+ "numa-node-id", numa_node_id);
43
+ }
44
+out:
45
+ g_free(nodename);
46
+ return ret;
47
+}
48
+
49
static void fdt_add_psci_node(void *fdt)
50
{
51
uint32_t cpu_suspend_fn;
52
@@ -XXX,XX +XXX,XX @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
53
void *fdt = NULL;
54
int size, rc, n = 0;
55
uint32_t acells, scells;
56
- char *nodename;
57
unsigned int i;
58
hwaddr mem_base, mem_len;
59
char **node_path;
60
@@ -XXX,XX +XXX,XX @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
61
mem_base = binfo->loader_start;
62
for (i = 0; i < nb_numa_nodes; i++) {
63
mem_len = numa_info[i].node_mem;
64
- nodename = g_strdup_printf("/memory@%" PRIx64, mem_base);
65
- qemu_fdt_add_subnode(fdt, nodename);
66
- qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
67
- rc = qemu_fdt_setprop_sized_cells(fdt, nodename, "reg",
68
- acells, mem_base,
69
- scells, mem_len);
70
+ rc = fdt_add_memory_node(fdt, acells, mem_base,
71
+ scells, mem_len, i);
72
if (rc < 0) {
73
- fprintf(stderr, "couldn't set %s/reg for node %d\n", nodename,
74
- i);
75
+ fprintf(stderr, "couldn't add /memory@%"PRIx64" node\n",
76
+ mem_base);
77
goto fail;
78
}
79
80
- qemu_fdt_setprop_cell(fdt, nodename, "numa-node-id", i);
81
mem_base += mem_len;
82
- g_free(nodename);
83
}
84
} else {
85
- nodename = g_strdup_printf("/memory@%" PRIx64, binfo->loader_start);
86
- qemu_fdt_add_subnode(fdt, nodename);
87
- qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
88
-
30
-
89
- rc = qemu_fdt_setprop_sized_cells(fdt, nodename, "reg",
31
-static const ARMCPRegInfo zcr_el2_reginfo = {
90
- acells, binfo->loader_start,
32
- .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
91
- scells, binfo->ram_size);
33
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
92
+ rc = fdt_add_memory_node(fdt, acells, binfo->loader_start,
34
- .access = PL2_RW, .type = ARM_CP_SVE,
93
+ scells, binfo->ram_size, -1);
35
- .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
94
if (rc < 0) {
36
- .writefn = zcr_write, .raw_writefn = raw_write
95
- fprintf(stderr, "couldn't set %s reg\n", nodename);
37
-};
96
+ fprintf(stderr, "couldn't add /memory@%"PRIx64" node\n",
38
-
97
+ binfo->loader_start);
39
-static const ARMCPRegInfo zcr_no_el2_reginfo = {
98
goto fail;
40
- .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
99
}
41
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
100
- g_free(nodename);
42
- .access = PL2_RW, .type = ARM_CP_SVE,
43
- .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore
44
-};
45
-
46
-static const ARMCPRegInfo zcr_el3_reginfo = {
47
- .name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
48
- .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
49
- .access = PL3_RW, .type = ARM_CP_SVE,
50
- .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
51
- .writefn = zcr_write, .raw_writefn = raw_write
52
+static const ARMCPRegInfo zcr_reginfo[] = {
53
+ { .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
54
+ .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
55
+ .access = PL1_RW, .type = ARM_CP_SVE,
56
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
57
+ .writefn = zcr_write, .raw_writefn = raw_write },
58
+ { .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
59
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
60
+ .access = PL2_RW, .type = ARM_CP_SVE,
61
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
62
+ .writefn = zcr_write, .raw_writefn = raw_write },
63
+ { .name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
64
+ .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
65
+ .access = PL3_RW, .type = ARM_CP_SVE,
66
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
67
+ .writefn = zcr_write, .raw_writefn = raw_write },
68
};
69
70
void hw_watchpoint_update(ARMCPU *cpu, int n)
71
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
101
}
72
}
102
73
103
rc = fdt_path_offset(fdt, "/chosen");
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
104
--
88
--
105
2.20.1
89
2.25.1
106
107
diff view generated by jsdifflib
1
From: Michel Heily <michelheily@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Implement the watchdog timer for the stellaris boards.
3
This register is present for either VHE or Debugv8p2.
4
This device is a close variant of the CMSDK APB watchdog
5
device, so we can model it by subclassing that device and
6
tweaking the behaviour of some of its registers.
7
4
8
Signed-off-by: Michel Heily <michelheily@gmail.com>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <petser.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
[PMM: rewrote commit message, fixed a few checkpatch nits,
7
Message-id: 20220506180242.216785-5-richard.henderson@linaro.org
11
added comment giving the URL of the spec for the Stellaris
12
variant of the watchdog device]
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
9
---
15
include/hw/watchdog/cmsdk-apb-watchdog.h | 8 +++
10
target/arm/helper.c | 15 +++++++++++----
16
hw/arm/stellaris.c | 22 ++++++-
11
1 file changed, 11 insertions(+), 4 deletions(-)
17
hw/watchdog/cmsdk-apb-watchdog.c | 74 +++++++++++++++++++++++-
18
3 files changed, 100 insertions(+), 4 deletions(-)
19
12
20
diff --git a/include/hw/watchdog/cmsdk-apb-watchdog.h b/include/hw/watchdog/cmsdk-apb-watchdog.h
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/watchdog/cmsdk-apb-watchdog.h
15
--- a/target/arm/helper.c
23
+++ b/include/hw/watchdog/cmsdk-apb-watchdog.h
16
+++ b/target/arm/helper.c
24
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo jazelle_regs[] = {
25
#define CMSDK_APB_WATCHDOG(obj) OBJECT_CHECK(CMSDKAPBWatchdog, (obj), \
18
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
26
TYPE_CMSDK_APB_WATCHDOG)
27
28
+/*
29
+ * This shares the same struct (and cast macro) as the base
30
+ * cmsdk-apb-watchdog device.
31
+ */
32
+#define TYPE_LUMINARY_WATCHDOG "luminary-watchdog"
33
+
34
typedef struct CMSDKAPBWatchdog {
35
/*< private >*/
36
SysBusDevice parent_obj;
37
@@ -XXX,XX +XXX,XX @@ typedef struct CMSDKAPBWatchdog {
38
MemoryRegion iomem;
39
qemu_irq wdogint;
40
uint32_t wdogclk_frq;
41
+ bool is_luminary;
42
struct ptimer_state *timer;
43
44
uint32_t control;
45
@@ -XXX,XX +XXX,XX @@ typedef struct CMSDKAPBWatchdog {
46
uint32_t itcr;
47
uint32_t itop;
48
uint32_t resetstatus;
49
+ const uint32_t *id;
50
} CMSDKAPBWatchdog;
51
52
#endif
53
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/arm/stellaris.c
56
+++ b/hw/arm/stellaris.c
57
@@ -XXX,XX +XXX,XX @@
58
#include "sysemu/sysemu.h"
59
#include "hw/arm/armv7m.h"
60
#include "hw/char/pl011.h"
61
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
62
#include "hw/misc/unimp.h"
63
#include "cpu.h"
64
65
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
66
* Stellaris LM3S6965 Microcontroller Data Sheet (rev I)
67
* http://www.ti.com/lit/ds/symlink/lm3s6965.pdf
68
*
69
- * 40000000 wdtimer (unimplemented)
70
+ * 40000000 wdtimer
71
* 40002000 i2c (unimplemented)
72
* 40004000 GPIO
73
* 40005000 GPIO
74
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
75
stellaris_sys_init(0x400fe000, qdev_get_gpio_in(nvic, 28),
76
board, nd_table[0].macaddr.a);
77
78
+
79
+ if (board->dc1 & (1 << 3)) { /* watchdog present */
80
+ dev = qdev_create(NULL, TYPE_LUMINARY_WATCHDOG);
81
+
82
+ /* system_clock_scale is valid now */
83
+ uint32_t mainclk = NANOSECONDS_PER_SECOND / system_clock_scale;
84
+ qdev_prop_set_uint32(dev, "wdogclk-frq", mainclk);
85
+
86
+ qdev_init_nofail(dev);
87
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev),
88
+ 0,
89
+ 0x40000000u);
90
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev),
91
+ 0,
92
+ qdev_get_gpio_in(nvic, 18));
93
+ }
94
+
95
+
96
for (i = 0; i < 7; i++) {
97
if (board->dc4 & (1 << i)) {
98
gpio_dev[i] = sysbus_create_simple("pl061_luminary", gpio_addr[i],
99
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
100
/* Add dummy regions for the devices we don't implement yet,
101
* so guest accesses don't cause unlogged crashes.
102
*/
103
- create_unimplemented_device("wdtimer", 0x40000000, 0x1000);
104
create_unimplemented_device("i2c-0", 0x40002000, 0x1000);
105
create_unimplemented_device("i2c-2", 0x40021000, 0x1000);
106
create_unimplemented_device("PWM", 0x40028000, 0x1000);
107
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/hw/watchdog/cmsdk-apb-watchdog.c
110
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
111
@@ -XXX,XX +XXX,XX @@
112
* System Design Kit (CMSDK) and documented in the Cortex-M System
113
* Design Kit Technical Reference Manual (ARM DDI0479C):
114
* https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
115
+ *
116
+ * We also support the variant of this device found in the TI
117
+ * Stellaris/Luminary boards and documented in:
118
+ * http://www.ti.com/lit/ds/symlink/lm3s6965.pdf
119
*/
120
121
#include "qemu/osdep.h"
122
@@ -XXX,XX +XXX,XX @@ REG32(WDOGINTCLR, 0xc)
123
REG32(WDOGRIS, 0x10)
124
FIELD(WDOGRIS, INT, 0, 1)
125
REG32(WDOGMIS, 0x14)
126
+REG32(WDOGTEST, 0x418) /* only in Stellaris/Luminary version of the device */
127
REG32(WDOGLOCK, 0xc00)
128
#define WDOG_UNLOCK_VALUE 0x1ACCE551
129
REG32(WDOGITCR, 0xf00)
130
@@ -XXX,XX +XXX,XX @@ REG32(CID2, 0xff8)
131
REG32(CID3, 0xffc)
132
133
/* PID/CID values */
134
-static const int watchdog_id[] = {
135
+static const uint32_t cmsdk_apb_watchdog_id[] = {
136
0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
137
0x24, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
138
0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
139
};
19
};
140
20
141
+static const uint32_t luminary_watchdog_id[] = {
21
+static const ARMCPRegInfo contextidr_el2 = {
142
+ 0x00, 0x00, 0x00, 0x00, /* PID4..PID7 */
22
+ .name = "CONTEXTIDR_EL2", .state = ARM_CP_STATE_AA64,
143
+ 0x05, 0x18, 0x18, 0x01, /* PID0..PID3 */
23
+ .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 1,
144
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
24
+ .access = PL2_RW,
25
+ .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[2])
145
+};
26
+};
146
+
27
+
147
static bool cmsdk_apb_watchdog_intstatus(CMSDKAPBWatchdog *s)
28
static const ARMCPRegInfo vhe_reginfo[] = {
148
{
29
- { .name = "CONTEXTIDR_EL2", .state = ARM_CP_STATE_AA64,
149
/* Return masked interrupt status */
30
- .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 1,
150
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_update(CMSDKAPBWatchdog *s)
31
- .access = PL2_RW,
151
bool wdogres;
32
- .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[2]) },
152
33
{ .name = "TTBR1_EL2", .state = ARM_CP_STATE_AA64,
153
if (s->itcr) {
34
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 1,
154
+ /*
35
.access = PL2_RW, .writefn = vmsa_tcr_ttbr_el2_write,
155
+ * Not checking that !s->is_luminary since s->itcr can't be written
36
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
156
+ * when s->is_luminary in the first place.
37
define_one_arm_cp_reg(cpu, &ssbs_reginfo);
157
+ */
38
}
158
wdogint = s->itop & R_WDOGITOP_WDOGINT_MASK;
39
159
wdogres = s->itop & R_WDOGITOP_WDOGRES_MASK;
40
+ if (cpu_isar_feature(aa64_vh, cpu) ||
160
} else {
41
+ cpu_isar_feature(aa64_debugv8p2, cpu)) {
161
@@ -XXX,XX +XXX,XX @@ static uint64_t cmsdk_apb_watchdog_read(void *opaque, hwaddr offset,
42
+ define_one_arm_cp_reg(cpu, &contextidr_el2);
162
r = s->lock;
43
+ }
163
break;
44
if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
164
case A_WDOGITCR:
45
define_arm_cp_regs(cpu, vhe_reginfo);
165
+ if (s->is_luminary) {
46
}
166
+ goto bad_offset;
167
+ }
168
r = s->itcr;
169
break;
170
case A_PID4 ... A_CID3:
171
- r = watchdog_id[(offset - A_PID4) / 4];
172
+ r = s->id[(offset - A_PID4) / 4];
173
break;
174
case A_WDOGINTCLR:
175
case A_WDOGITOP:
176
+ if (s->is_luminary) {
177
+ goto bad_offset;
178
+ }
179
qemu_log_mask(LOG_GUEST_ERROR,
180
"CMSDK APB watchdog read: read of WO offset %x\n",
181
(int)offset);
182
r = 0;
183
break;
184
+ case A_WDOGTEST:
185
+ if (!s->is_luminary) {
186
+ goto bad_offset;
187
+ }
188
+ qemu_log_mask(LOG_UNIMP,
189
+ "Luminary watchdog read: stall not implemented\n");
190
+ r = 0;
191
+ break;
192
default:
193
+bad_offset:
194
qemu_log_mask(LOG_GUEST_ERROR,
195
"CMSDK APB watchdog read: bad offset %x\n", (int)offset);
196
r = 0;
197
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset,
198
ptimer_run(s->timer, 0);
199
break;
200
case A_WDOGCONTROL:
201
+ if (s->is_luminary && 0 != (R_WDOGCONTROL_INTEN_MASK & s->control)) {
202
+ /*
203
+ * The Luminary version of this device ignores writes to
204
+ * this register after the guest has enabled interrupts
205
+ * (so they can only be disabled again via reset).
206
+ */
207
+ break;
208
+ }
209
s->control = value & R_WDOGCONTROL_VALID_MASK;
210
cmsdk_apb_watchdog_update(s);
211
break;
212
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset,
213
s->lock = (value != WDOG_UNLOCK_VALUE);
214
break;
215
case A_WDOGITCR:
216
+ if (s->is_luminary) {
217
+ goto bad_offset;
218
+ }
219
s->itcr = value & R_WDOGITCR_VALID_MASK;
220
cmsdk_apb_watchdog_update(s);
221
break;
222
case A_WDOGITOP:
223
+ if (s->is_luminary) {
224
+ goto bad_offset;
225
+ }
226
s->itop = value & R_WDOGITOP_VALID_MASK;
227
cmsdk_apb_watchdog_update(s);
228
break;
229
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset,
230
"CMSDK APB watchdog write: write to RO offset 0x%x\n",
231
(int)offset);
232
break;
233
+ case A_WDOGTEST:
234
+ if (!s->is_luminary) {
235
+ goto bad_offset;
236
+ }
237
+ qemu_log_mask(LOG_UNIMP,
238
+ "Luminary watchdog write: stall not implemented\n");
239
+ break;
240
default:
241
+bad_offset:
242
qemu_log_mask(LOG_GUEST_ERROR,
243
"CMSDK APB watchdog write: bad offset 0x%x\n",
244
(int)offset);
245
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_init(Object *obj)
246
s, "cmsdk-apb-watchdog", 0x1000);
247
sysbus_init_mmio(sbd, &s->iomem);
248
sysbus_init_irq(sbd, &s->wdogint);
249
+
250
+ s->is_luminary = false;
251
+ s->id = cmsdk_apb_watchdog_id;
252
}
253
254
static void cmsdk_apb_watchdog_realize(DeviceState *dev, Error **errp)
255
@@ -XXX,XX +XXX,XX @@ static const TypeInfo cmsdk_apb_watchdog_info = {
256
.class_init = cmsdk_apb_watchdog_class_init,
257
};
258
259
+static void luminary_watchdog_init(Object *obj)
260
+{
261
+ CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(obj);
262
+
263
+ s->is_luminary = true;
264
+ s->id = luminary_watchdog_id;
265
+}
266
+
267
+static const TypeInfo luminary_watchdog_info = {
268
+ .name = TYPE_LUMINARY_WATCHDOG,
269
+ .parent = TYPE_CMSDK_APB_WATCHDOG,
270
+ .instance_init = luminary_watchdog_init
271
+};
272
+
273
static void cmsdk_apb_watchdog_register_types(void)
274
{
275
type_register_static(&cmsdk_apb_watchdog_info);
276
+ type_register_static(&luminary_watchdog_info);
277
}
278
279
type_init(cmsdk_apb_watchdog_register_types);
280
--
47
--
281
2.20.1
48
2.25.1
282
283
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This decoding more closely matches the ARMv8.4 Table C4-6,
3
Previously we were defining some of these in user-only mode,
4
Encoding table for Data Processing - Register Group.
4
but none of them are accessible from user-only, therefore
5
5
define them only in system mode.
6
In particular, op2 == 0 is now more than just Add/sub (with carry).
6
7
7
This will shortly be used from cpu_tcg.c also.
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190301200501.16533-7-richard.henderson@linaro.org
11
Message-id: 20220506180242.216785-6-richard.henderson@linaro.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
---
13
target/arm/translate-a64.c | 98 ++++++++++++++++++++++----------------
14
target/arm/internals.h | 6 ++++
14
1 file changed, 57 insertions(+), 41 deletions(-)
15
target/arm/cpu64.c | 64 +++---------------------------------------
15
16
target/arm/cpu_tcg.c | 59 ++++++++++++++++++++++++++++++++++++++
16
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
3 files changed, 69 insertions(+), 60 deletions(-)
18
19
diff --git a/target/arm/internals.h b/target/arm/internals.h
17
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a64.c
21
--- a/target/arm/internals.h
19
+++ b/target/arm/translate-a64.c
22
+++ b/target/arm/internals.h
20
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_3src(DisasContext *s, uint32_t insn)
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)
103
{
104
ARMCPU *cpu = ARM_CPU(obj);
105
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
106
cpu->gic_num_lrs = 4;
107
cpu->gic_vpribits = 5;
108
cpu->gic_vprebits = 5;
109
- define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
110
+ define_cortex_a72_a57_a53_cp_reginfo(cpu);
21
}
111
}
22
112
23
/* Add/subtract (with carry)
113
static void aarch64_a53_initfn(Object *obj)
24
- * 31 30 29 28 27 26 25 24 23 22 21 20 16 15 10 9 5 4 0
114
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
25
- * +--+--+--+------------------------+------+---------+------+-----+
115
cpu->gic_num_lrs = 4;
26
- * |sf|op| S| 1 1 0 1 0 0 0 0 | rm | opcode2 | Rn | Rd |
116
cpu->gic_vpribits = 5;
27
- * +--+--+--+------------------------+------+---------+------+-----+
117
cpu->gic_vprebits = 5;
28
- * [000000]
118
- define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
29
+ * 31 30 29 28 27 26 25 24 23 22 21 20 16 15 10 9 5 4 0
119
+ define_cortex_a72_a57_a53_cp_reginfo(cpu);
30
+ * +--+--+--+------------------------+------+-------------+------+-----+
31
+ * |sf|op| S| 1 1 0 1 0 0 0 0 | rm | 0 0 0 0 0 0 | Rn | Rd |
32
+ * +--+--+--+------------------------+------+-------------+------+-----+
33
*/
34
35
static void disas_adc_sbc(DisasContext *s, uint32_t insn)
36
@@ -XXX,XX +XXX,XX @@ static void disas_adc_sbc(DisasContext *s, uint32_t insn)
37
unsigned int sf, op, setflags, rm, rn, rd;
38
TCGv_i64 tcg_y, tcg_rn, tcg_rd;
39
40
- if (extract32(insn, 10, 6) != 0) {
41
- unallocated_encoding(s);
42
- return;
43
- }
44
-
45
sf = extract32(insn, 31, 1);
46
op = extract32(insn, 30, 1);
47
setflags = extract32(insn, 29, 1);
48
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
49
}
50
}
120
}
51
121
52
-/* Data processing - register */
122
static void aarch64_a72_initfn(Object *obj)
53
+/*
123
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
54
+ * Data processing - register
124
cpu->gic_num_lrs = 4;
55
+ * 31 30 29 28 25 21 20 16 10 0
125
cpu->gic_vpribits = 5;
56
+ * +--+---+--+---+-------+-----+-------+-------+---------+
126
cpu->gic_vprebits = 5;
57
+ * | |op0| |op1| 1 0 1 | op2 | | op3 | |
127
- define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
58
+ * +--+---+--+---+-------+-----+-------+-------+---------+
128
+ define_cortex_a72_a57_a53_cp_reginfo(cpu);
59
+ */
129
}
60
static void disas_data_proc_reg(DisasContext *s, uint32_t insn)
130
61
{
131
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
62
- switch (extract32(insn, 24, 5)) {
132
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
63
- case 0x0a: /* Logical (shifted register) */
133
index XXXXXXX..XXXXXXX 100644
64
- disas_logic_reg(s, insn);
134
--- a/target/arm/cpu_tcg.c
65
- break;
135
+++ b/target/arm/cpu_tcg.c
66
- case 0x0b: /* Add/subtract */
136
@@ -XXX,XX +XXX,XX @@
67
- if (insn & (1 << 21)) { /* (extended register) */
137
#endif
68
- disas_add_sub_ext_reg(s, insn);
138
#include "cpregs.h"
69
+ int op0 = extract32(insn, 30, 1);
139
70
+ int op1 = extract32(insn, 28, 1);
140
+#ifndef CONFIG_USER_ONLY
71
+ int op2 = extract32(insn, 21, 4);
141
+static uint64_t l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
72
+ int op3 = extract32(insn, 10, 6);
142
+{
73
+
143
+ ARMCPU *cpu = env_archcpu(env);
74
+ if (!op1) {
144
+
75
+ if (op2 & 8) {
145
+ /* Number of cores is in [25:24]; otherwise we RAZ */
76
+ if (op2 & 1) {
146
+ return (cpu->core_count - 1) << 24;
77
+ /* Add/sub (extended register) */
147
+}
78
+ disas_add_sub_ext_reg(s, insn);
148
+
79
+ } else {
149
+static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = {
80
+ /* Add/sub (shifted register) */
150
+ { .name = "L2CTLR_EL1", .state = ARM_CP_STATE_AA64,
81
+ disas_add_sub_reg(s, insn);
151
+ .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 2,
82
+ }
152
+ .access = PL1_RW, .readfn = l2ctlr_read,
83
} else {
153
+ .writefn = arm_cp_write_ignore },
84
- disas_add_sub_reg(s, insn);
154
+ { .name = "L2CTLR",
85
+ /* Logical (shifted register) */
155
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 2,
86
+ disas_logic_reg(s, insn);
156
+ .access = PL1_RW, .readfn = l2ctlr_read,
87
}
157
+ .writefn = arm_cp_write_ignore },
88
- break;
158
+ { .name = "L2ECTLR_EL1", .state = ARM_CP_STATE_AA64,
89
- case 0x1b: /* Data-processing (3 source) */
159
+ .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 3,
90
- disas_data_proc_3src(s, insn);
160
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
91
- break;
161
+ { .name = "L2ECTLR",
92
- case 0x1a:
162
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 3,
93
- switch (extract32(insn, 21, 3)) {
163
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
94
- case 0x0: /* Add/subtract (with carry) */
164
+ { .name = "L2ACTLR", .state = ARM_CP_STATE_BOTH,
95
+ return;
165
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 0, .opc2 = 0,
96
+ }
166
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
97
+
167
+ { .name = "CPUACTLR_EL1", .state = ARM_CP_STATE_AA64,
98
+ switch (op2) {
168
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 0,
99
+ case 0x0:
169
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
100
+ switch (op3) {
170
+ { .name = "CPUACTLR",
101
+ case 0x00: /* Add/subtract (with carry) */
171
+ .cp = 15, .opc1 = 0, .crm = 15,
102
disas_adc_sbc(s, insn);
172
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
103
break;
173
+ { .name = "CPUECTLR_EL1", .state = ARM_CP_STATE_AA64,
104
- case 0x2: /* Conditional compare */
174
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 1,
105
- disas_cc(s, insn); /* both imm and reg forms */
175
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
106
- break;
176
+ { .name = "CPUECTLR",
107
- case 0x4: /* Conditional select */
177
+ .cp = 15, .opc1 = 1, .crm = 15,
108
- disas_cond_select(s, insn);
178
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
109
- break;
179
+ { .name = "CPUMERRSR_EL1", .state = ARM_CP_STATE_AA64,
110
- case 0x6: /* Data-processing */
180
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 2,
111
- if (insn & (1 << 30)) { /* (1 source) */
181
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
112
- disas_data_proc_1src(s, insn);
182
+ { .name = "CPUMERRSR",
113
- } else { /* (2 source) */
183
+ .cp = 15, .opc1 = 2, .crm = 15,
114
- disas_data_proc_2src(s, insn);
184
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
115
- }
185
+ { .name = "L2MERRSR_EL1", .state = ARM_CP_STATE_AA64,
116
- break;
186
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 3,
117
+
187
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
118
default:
188
+ { .name = "L2MERRSR",
119
- unallocated_encoding(s);
189
+ .cp = 15, .opc1 = 3, .crm = 15,
120
- break;
190
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
121
+ goto do_unallocated;
191
+};
122
}
192
+
123
break;
193
+void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu)
124
+
194
+{
125
+ case 0x2: /* Conditional compare */
195
+ define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
126
+ disas_cc(s, insn); /* both imm and reg forms */
196
+}
127
+ break;
197
+#endif /* !CONFIG_USER_ONLY */
128
+
198
+
129
+ case 0x4: /* Conditional select */
199
/* CPU models. These are not needed for the AArch64 linux-user build. */
130
+ disas_cond_select(s, insn);
200
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
131
+ break;
201
132
+
133
+ case 0x6: /* Data-processing */
134
+ if (op0) { /* (1 source) */
135
+ disas_data_proc_1src(s, insn);
136
+ } else { /* (2 source) */
137
+ disas_data_proc_2src(s, insn);
138
+ }
139
+ break;
140
+ case 0x8 ... 0xf: /* (3 source) */
141
+ disas_data_proc_3src(s, insn);
142
+ break;
143
+
144
default:
145
+ do_unallocated:
146
unallocated_encoding(s);
147
break;
148
}
149
--
202
--
150
2.20.1
203
2.25.1
151
152
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Instead of starting with cortex-a15 and adding v8 features to
4
a v7 cpu, begin with a v8 cpu stripped of its aarch64 features.
5
This fixes the long-standing to-do where we only enabled v8
6
features for user-only.
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20220506180242.216785-7-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/cpu_tcg.c | 151 ++++++++++++++++++++++++++-----------------
14
1 file changed, 92 insertions(+), 59 deletions(-)
15
16
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu_tcg.c
19
+++ b/target/arm/cpu_tcg.c
20
@@ -XXX,XX +XXX,XX @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
21
static void arm_max_initfn(Object *obj)
22
{
23
ARMCPU *cpu = ARM_CPU(obj);
24
+ uint32_t t;
25
26
- cortex_a15_initfn(obj);
27
+ /* aarch64_a57_initfn, advertising none of the aarch64 features */
28
+ cpu->dtb_compatible = "arm,cortex-a57";
29
+ set_feature(&cpu->env, ARM_FEATURE_V8);
30
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
31
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
32
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
33
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
34
+ set_feature(&cpu->env, ARM_FEATURE_EL3);
35
+ set_feature(&cpu->env, ARM_FEATURE_PMU);
36
+ cpu->midr = 0x411fd070;
37
+ cpu->revidr = 0x00000000;
38
+ cpu->reset_fpsid = 0x41034070;
39
+ cpu->isar.mvfr0 = 0x10110222;
40
+ cpu->isar.mvfr1 = 0x12111111;
41
+ cpu->isar.mvfr2 = 0x00000043;
42
+ cpu->ctr = 0x8444c004;
43
+ cpu->reset_sctlr = 0x00c50838;
44
+ cpu->isar.id_pfr0 = 0x00000131;
45
+ cpu->isar.id_pfr1 = 0x00011011;
46
+ cpu->isar.id_dfr0 = 0x03010066;
47
+ cpu->id_afr0 = 0x00000000;
48
+ cpu->isar.id_mmfr0 = 0x10101105;
49
+ cpu->isar.id_mmfr1 = 0x40000000;
50
+ cpu->isar.id_mmfr2 = 0x01260000;
51
+ cpu->isar.id_mmfr3 = 0x02102211;
52
+ cpu->isar.id_isar0 = 0x02101110;
53
+ cpu->isar.id_isar1 = 0x13112111;
54
+ cpu->isar.id_isar2 = 0x21232042;
55
+ cpu->isar.id_isar3 = 0x01112131;
56
+ cpu->isar.id_isar4 = 0x00011142;
57
+ cpu->isar.id_isar5 = 0x00011121;
58
+ cpu->isar.id_isar6 = 0;
59
+ cpu->isar.dbgdidr = 0x3516d000;
60
+ cpu->clidr = 0x0a200023;
61
+ cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
62
+ cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */
63
+ cpu->ccsidr[2] = 0x70ffe07a; /* 2048KB L2 cache */
64
+ define_cortex_a72_a57_a53_cp_reginfo(cpu);
65
66
- /* old-style VFP short-vector support */
67
- cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
68
+ /* Add additional features supported by QEMU */
69
+ t = cpu->isar.id_isar5;
70
+ t = FIELD_DP32(t, ID_ISAR5, AES, 2);
71
+ t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
72
+ t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
73
+ t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
74
+ t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
75
+ t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
76
+ cpu->isar.id_isar5 = t;
77
+
78
+ t = cpu->isar.id_isar6;
79
+ t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
80
+ t = FIELD_DP32(t, ID_ISAR6, DP, 1);
81
+ t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
82
+ t = FIELD_DP32(t, ID_ISAR6, SB, 1);
83
+ t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
84
+ t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
85
+ t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
86
+ cpu->isar.id_isar6 = t;
87
+
88
+ t = cpu->isar.mvfr1;
89
+ t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */
90
+ t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
91
+ cpu->isar.mvfr1 = t;
92
+
93
+ t = cpu->isar.mvfr2;
94
+ t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
95
+ t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
96
+ cpu->isar.mvfr2 = t;
97
+
98
+ t = cpu->isar.id_mmfr3;
99
+ t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
100
+ cpu->isar.id_mmfr3 = t;
101
+
102
+ t = cpu->isar.id_mmfr4;
103
+ t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
104
+ t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
105
+ t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
106
+ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
107
+ cpu->isar.id_mmfr4 = t;
108
+
109
+ t = cpu->isar.id_pfr0;
110
+ t = FIELD_DP32(t, ID_PFR0, DIT, 1);
111
+ cpu->isar.id_pfr0 = t;
112
+
113
+ t = cpu->isar.id_pfr2;
114
+ t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
115
+ cpu->isar.id_pfr2 = t;
116
117
#ifdef CONFIG_USER_ONLY
118
/*
119
- * We don't set these in system emulation mode for the moment,
120
- * since we don't correctly set (all of) the ID registers to
121
- * advertise them.
122
+ * Break with true ARMv8 and add back old-style VFP short-vector support.
123
+ * Only do this for user-mode, where -cpu max is the default, so that
124
+ * older v6 and v7 programs are more likely to work without adjustment.
125
*/
126
- set_feature(&cpu->env, ARM_FEATURE_V8);
127
- {
128
- uint32_t t;
129
-
130
- t = cpu->isar.id_isar5;
131
- t = FIELD_DP32(t, ID_ISAR5, AES, 2);
132
- t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
133
- t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
134
- t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
135
- t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
136
- t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
137
- cpu->isar.id_isar5 = t;
138
-
139
- t = cpu->isar.id_isar6;
140
- t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
141
- t = FIELD_DP32(t, ID_ISAR6, DP, 1);
142
- t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
143
- t = FIELD_DP32(t, ID_ISAR6, SB, 1);
144
- t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
145
- t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
146
- t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
147
- cpu->isar.id_isar6 = t;
148
-
149
- t = cpu->isar.mvfr1;
150
- t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */
151
- t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
152
- cpu->isar.mvfr1 = t;
153
-
154
- t = cpu->isar.mvfr2;
155
- t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
156
- t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
157
- cpu->isar.mvfr2 = t;
158
-
159
- t = cpu->isar.id_mmfr3;
160
- t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
161
- cpu->isar.id_mmfr3 = t;
162
-
163
- t = cpu->isar.id_mmfr4;
164
- t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
165
- t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
166
- t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
167
- t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
168
- cpu->isar.id_mmfr4 = t;
169
-
170
- t = cpu->isar.id_pfr0;
171
- t = FIELD_DP32(t, ID_PFR0, DIT, 1);
172
- cpu->isar.id_pfr0 = t;
173
-
174
- t = cpu->isar.id_pfr2;
175
- t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
176
- cpu->isar.id_pfr2 = t;
177
- }
178
-#endif /* CONFIG_USER_ONLY */
179
+ cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
180
+#endif
181
}
182
#endif /* !TARGET_AARCH64 */
183
184
--
185
2.25.1
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
We set this for qemu-system-aarch64, but failed to do so
4
for the strictly 32-bit emulation.
5
6
Fixes: 3bec78447a9 ("target/arm: Provide ARMv8.4-PMU in '-cpu max'")
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220506180242.216785-8-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu_tcg.c | 4 ++++
13
1 file changed, 4 insertions(+)
14
15
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu_tcg.c
18
+++ b/target/arm/cpu_tcg.c
19
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
20
t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
21
cpu->isar.id_pfr2 = t;
22
23
+ t = cpu->isar.id_dfr0;
24
+ t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
25
+ cpu->isar.id_dfr0 = t;
26
+
27
#ifdef CONFIG_USER_ONLY
28
/*
29
* Break with true ARMv8 and add back old-style VFP short-vector support.
30
--
31
2.25.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The EL0+UMA check is unique to DAIF. While SPSel had avoided the
3
Share the code to set AArch32 max features so that we no
4
check by nature of already checking EL >= 1, the other post v8.0
4
longer have code drift between qemu{-system,}-{arm,aarch64}.
5
extensions to MSR (imm) allow EL0 and do not require UMA. Avoid
6
the unconditional write to pc and use raise_exception_ra to unwind.
7
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190301200501.16533-5-richard.henderson@linaro.org
8
Message-id: 20220506180242.216785-9-richard.henderson@linaro.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
target/arm/helper-a64.h | 3 +++
11
target/arm/internals.h | 2 +
14
target/arm/helper.h | 1 -
12
target/arm/cpu64.c | 50 +-----------------
15
target/arm/internals.h | 15 ++++++++++++++
13
target/arm/cpu_tcg.c | 114 ++++++++++++++++++++++-------------------
16
target/arm/helper-a64.c | 30 +++++++++++++++++++++++++++
14
3 files changed, 65 insertions(+), 101 deletions(-)
17
target/arm/op_helper.c | 42 --------------------------------------
18
target/arm/translate-a64.c | 41 ++++++++++++++++++++++---------------
19
6 files changed, 73 insertions(+), 59 deletions(-)
20
15
21
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/helper-a64.h
24
+++ b/target/arm/helper-a64.h
25
@@ -XXX,XX +XXX,XX @@
26
DEF_HELPER_FLAGS_2(udiv64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
27
DEF_HELPER_FLAGS_2(sdiv64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
28
DEF_HELPER_FLAGS_1(rbit64, TCG_CALL_NO_RWG_SE, i64, i64)
29
+DEF_HELPER_2(msr_i_spsel, void, env, i32)
30
+DEF_HELPER_2(msr_i_daifset, void, env, i32)
31
+DEF_HELPER_2(msr_i_daifclear, void, env, i32)
32
DEF_HELPER_3(vfp_cmph_a64, i64, f16, f16, ptr)
33
DEF_HELPER_3(vfp_cmpeh_a64, i64, f16, f16, ptr)
34
DEF_HELPER_3(vfp_cmps_a64, i64, f32, f32, ptr)
35
diff --git a/target/arm/helper.h b/target/arm/helper.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper.h
38
+++ b/target/arm/helper.h
39
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(get_cp_reg, i32, env, ptr)
40
DEF_HELPER_3(set_cp_reg64, void, env, ptr, i64)
41
DEF_HELPER_2(get_cp_reg64, i64, env, ptr)
42
43
-DEF_HELPER_3(msr_i_pstate, void, env, i32, i32)
44
DEF_HELPER_1(clear_pstate_ss, void, env)
45
46
DEF_HELPER_2(get_r13_banked, i32, env, i32)
47
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
48
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/internals.h
18
--- a/target/arm/internals.h
50
+++ b/target/arm/internals.h
19
+++ b/target/arm/internals.h
51
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
20
@@ -XXX,XX +XXX,XX @@ static inline void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu) { }
52
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
21
void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu);
53
ARMMMUIdx mmu_idx, bool data);
22
#endif
54
23
55
+static inline int exception_target_el(CPUARMState *env)
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
103
@@ -XXX,XX +XXX,XX @@
104
#endif
105
#include "cpregs.h"
106
107
+
108
+/* Share AArch32 -cpu max features with AArch64. */
109
+void aa32_max_features(ARMCPU *cpu)
56
+{
110
+{
57
+ int target_el = MAX(1, arm_current_el(env));
111
+ uint32_t t;
58
+
112
+
59
+ /*
113
+ /* Add additional features supported by QEMU */
60
+ * No such thing as secure EL1 if EL3 is aarch32,
114
+ t = cpu->isar.id_isar5;
61
+ * so update the target EL to EL3 in this case.
115
+ t = FIELD_DP32(t, ID_ISAR5, AES, 2);
62
+ */
116
+ t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
63
+ if (arm_is_secure(env) && !arm_el_is_aa64(env, 3) && target_el == 1) {
117
+ t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
64
+ target_el = 3;
118
+ t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
65
+ }
119
+ t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
66
+
120
+ t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
67
+ return target_el;
121
+ cpu->isar.id_isar5 = t;
122
+
123
+ t = cpu->isar.id_isar6;
124
+ t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
125
+ t = FIELD_DP32(t, ID_ISAR6, DP, 1);
126
+ t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
127
+ t = FIELD_DP32(t, ID_ISAR6, SB, 1);
128
+ t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
129
+ t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
130
+ t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
131
+ cpu->isar.id_isar6 = t;
132
+
133
+ t = cpu->isar.mvfr1;
134
+ t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */
135
+ t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
136
+ cpu->isar.mvfr1 = t;
137
+
138
+ t = cpu->isar.mvfr2;
139
+ t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
140
+ t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
141
+ cpu->isar.mvfr2 = t;
142
+
143
+ t = cpu->isar.id_mmfr3;
144
+ t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
145
+ cpu->isar.id_mmfr3 = t;
146
+
147
+ t = cpu->isar.id_mmfr4;
148
+ t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
149
+ t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
150
+ t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
151
+ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
152
+ cpu->isar.id_mmfr4 = t;
153
+
154
+ t = cpu->isar.id_pfr0;
155
+ t = FIELD_DP32(t, ID_PFR0, DIT, 1);
156
+ cpu->isar.id_pfr0 = t;
157
+
158
+ t = cpu->isar.id_pfr2;
159
+ t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
160
+ cpu->isar.id_pfr2 = t;
161
+
162
+ t = cpu->isar.id_dfr0;
163
+ t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
164
+ cpu->isar.id_dfr0 = t;
68
+}
165
+}
69
+
166
+
70
#endif
167
#ifndef CONFIG_USER_ONLY
71
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
168
static uint64_t l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/helper-a64.c
74
+++ b/target/arm/helper-a64.c
75
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(rbit64)(uint64_t x)
76
return revbit64(x);
77
}
78
79
+void HELPER(msr_i_spsel)(CPUARMState *env, uint32_t imm)
80
+{
81
+ update_spsel(env, imm);
82
+}
83
+
84
+static void daif_check(CPUARMState *env, uint32_t op,
85
+ uint32_t imm, uintptr_t ra)
86
+{
87
+ /* DAIF update to PSTATE. This is OK from EL0 only if UMA is set. */
88
+ if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UMA)) {
89
+ raise_exception_ra(env, EXCP_UDEF,
90
+ syn_aa64_sysregtrap(0, extract32(op, 0, 3),
91
+ extract32(op, 3, 3), 4,
92
+ imm, 0x1f, 0),
93
+ exception_target_el(env), ra);
94
+ }
95
+}
96
+
97
+void HELPER(msr_i_daifset)(CPUARMState *env, uint32_t imm)
98
+{
99
+ daif_check(env, 0x1e, imm, GETPC());
100
+ env->daif |= (imm << 6) & PSTATE_DAIF;
101
+}
102
+
103
+void HELPER(msr_i_daifclear)(CPUARMState *env, uint32_t imm)
104
+{
105
+ daif_check(env, 0x1f, imm, GETPC());
106
+ env->daif &= ~((imm << 6) & PSTATE_DAIF);
107
+}
108
+
109
/* Convert a softfloat float_relation_ (as returned by
110
* the float*_compare functions) to the correct ARM
111
* NZCV flag state.
112
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/op_helper.c
115
+++ b/target/arm/op_helper.c
116
@@ -XXX,XX +XXX,XX @@ void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome,
117
cpu_loop_exit_restore(cs, ra);
118
}
119
120
-static int exception_target_el(CPUARMState *env)
121
-{
122
- int target_el = MAX(1, arm_current_el(env));
123
-
124
- /* No such thing as secure EL1 if EL3 is aarch32, so update the target EL
125
- * to EL3 in this case.
126
- */
127
- if (arm_is_secure(env) && !arm_el_is_aa64(env, 3) && target_el == 1) {
128
- target_el = 3;
129
- }
130
-
131
- return target_el;
132
-}
133
-
134
uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def, void *vn,
135
uint32_t maxindex)
136
{
169
{
137
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
170
@@ -XXX,XX +XXX,XX @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
138
return res;
171
static void arm_max_initfn(Object *obj)
139
}
140
141
-void HELPER(msr_i_pstate)(CPUARMState *env, uint32_t op, uint32_t imm)
142
-{
143
- /* MSR_i to update PSTATE. This is OK from EL0 only if UMA is set.
144
- * Note that SPSel is never OK from EL0; we rely on handle_msr_i()
145
- * to catch that case at translate time.
146
- */
147
- if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UMA)) {
148
- uint32_t syndrome = syn_aa64_sysregtrap(0, extract32(op, 0, 3),
149
- extract32(op, 3, 3), 4,
150
- imm, 0x1f, 0);
151
- raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env));
152
- }
153
-
154
- switch (op) {
155
- case 0x05: /* SPSel */
156
- update_spsel(env, imm);
157
- break;
158
- case 0x1e: /* DAIFSet */
159
- env->daif |= (imm << 6) & PSTATE_DAIF;
160
- break;
161
- case 0x1f: /* DAIFClear */
162
- env->daif &= ~((imm << 6) & PSTATE_DAIF);
163
- break;
164
- default:
165
- g_assert_not_reached();
166
- }
167
-}
168
-
169
void HELPER(clear_pstate_ss)(CPUARMState *env)
170
{
172
{
171
env->pstate &= ~PSTATE_SS;
173
ARMCPU *cpu = ARM_CPU(obj);
172
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
174
- uint32_t t;
173
index XXXXXXX..XXXXXXX 100644
175
174
--- a/target/arm/translate-a64.c
176
/* aarch64_a57_initfn, advertising none of the aarch64 features */
175
+++ b/target/arm/translate-a64.c
177
cpu->dtb_compatible = "arm,cortex-a57";
176
@@ -XXX,XX +XXX,XX @@ static void handle_sync(DisasContext *s, uint32_t insn,
178
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
177
static void handle_msr_i(DisasContext *s, uint32_t insn,
179
cpu->ccsidr[2] = 0x70ffe07a; /* 2048KB L2 cache */
178
unsigned int op1, unsigned int op2, unsigned int crm)
180
define_cortex_a72_a57_a53_cp_reginfo(cpu);
179
{
181
180
+ TCGv_i32 t1;
182
- /* Add additional features supported by QEMU */
181
int op = op1 << 3 | op2;
183
- t = cpu->isar.id_isar5;
182
+
184
- t = FIELD_DP32(t, ID_ISAR5, AES, 2);
183
+ /* End the TB by default, chaining is ok. */
185
- t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
184
+ s->base.is_jmp = DISAS_TOO_MANY;
186
- t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
185
+
187
- t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
186
switch (op) {
188
- t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
187
case 0x05: /* SPSel */
189
- t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
188
if (s->current_el == 0) {
190
- cpu->isar.id_isar5 = t;
189
- unallocated_encoding(s);
191
-
190
- return;
192
- t = cpu->isar.id_isar6;
191
+ goto do_unallocated;
193
- t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
192
}
194
- t = FIELD_DP32(t, ID_ISAR6, DP, 1);
193
- /* fall through */
195
- t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
194
- case 0x1e: /* DAIFSet */
196
- t = FIELD_DP32(t, ID_ISAR6, SB, 1);
195
- case 0x1f: /* DAIFClear */
197
- t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
196
- {
198
- t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
197
- TCGv_i32 tcg_imm = tcg_const_i32(crm);
199
- t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
198
- TCGv_i32 tcg_op = tcg_const_i32(op);
200
- cpu->isar.id_isar6 = t;
199
- gen_a64_set_pc_im(s->pc - 4);
201
-
200
- gen_helper_msr_i_pstate(cpu_env, tcg_op, tcg_imm);
202
- t = cpu->isar.mvfr1;
201
- tcg_temp_free_i32(tcg_imm);
203
- t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */
202
- tcg_temp_free_i32(tcg_op);
204
- t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
203
- /* For DAIFClear, exit the cpu loop to re-evaluate pending IRQs. */
205
- cpu->isar.mvfr1 = t;
204
- gen_a64_set_pc_im(s->pc);
206
-
205
- s->base.is_jmp = (op == 0x1f ? DISAS_EXIT : DISAS_JUMP);
207
- t = cpu->isar.mvfr2;
206
+ t1 = tcg_const_i32(crm & PSTATE_SP);
208
- t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
207
+ gen_helper_msr_i_spsel(cpu_env, t1);
209
- t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
208
+ tcg_temp_free_i32(t1);
210
- cpu->isar.mvfr2 = t;
209
break;
211
-
210
- }
212
- t = cpu->isar.id_mmfr3;
211
+
213
- t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
212
+ case 0x1e: /* DAIFSet */
214
- cpu->isar.id_mmfr3 = t;
213
+ t1 = tcg_const_i32(crm);
215
-
214
+ gen_helper_msr_i_daifset(cpu_env, t1);
216
- t = cpu->isar.id_mmfr4;
215
+ tcg_temp_free_i32(t1);
217
- t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
216
+ break;
218
- t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
217
+
219
- t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
218
+ case 0x1f: /* DAIFClear */
220
- t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
219
+ t1 = tcg_const_i32(crm);
221
- cpu->isar.id_mmfr4 = t;
220
+ gen_helper_msr_i_daifclear(cpu_env, t1);
222
-
221
+ tcg_temp_free_i32(t1);
223
- t = cpu->isar.id_pfr0;
222
+ /* For DAIFClear, exit the cpu loop to re-evaluate pending IRQs. */
224
- t = FIELD_DP32(t, ID_PFR0, DIT, 1);
223
+ s->base.is_jmp = DISAS_UPDATE;
225
- cpu->isar.id_pfr0 = t;
224
+ break;
226
-
225
+
227
- t = cpu->isar.id_pfr2;
226
default:
228
- t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
227
+ do_unallocated:
229
- cpu->isar.id_pfr2 = t;
228
unallocated_encoding(s);
230
-
229
return;
231
- t = cpu->isar.id_dfr0;
230
}
232
- t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
233
- cpu->isar.id_dfr0 = t;
234
+ aa32_max_features(cpu);
235
236
#ifdef CONFIG_USER_ONLY
237
/*
231
--
238
--
232
2.20.1
239
2.25.1
233
234
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
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>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190301200501.16533-9-richard.henderson@linaro.org
9
Message-id: 20220506180242.216785-10-richard.henderson@linaro.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
11
---
9
target/arm/cpu.h | 5 ++++
12
target/arm/cpu64.c | 100 +++++++++++++++++++++----------------------
10
target/arm/cpu64.c | 2 +-
13
target/arm/cpu_tcg.c | 48 ++++++++++-----------
11
target/arm/translate-a64.c | 58 ++++++++++++++++++++++++++++++++++++++
14
2 files changed, 74 insertions(+), 74 deletions(-)
12
3 files changed, 64 insertions(+), 1 deletion(-)
13
15
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_condm_4(const ARMISARegisters *id)
19
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) != 0;
20
}
21
22
+static inline bool isar_feature_aa64_condm_5(const ARMISARegisters *id)
23
+{
24
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) >= 2;
25
+}
26
+
27
static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id)
28
{
29
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0;
30
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
16
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
31
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/cpu64.c
18
--- a/target/arm/cpu64.c
33
+++ b/target/arm/cpu64.c
19
+++ b/target/arm/cpu64.c
34
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
20
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
35
t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 1);
21
cpu->midr = t;
36
t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
22
37
t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1);
23
t = cpu->isar.id_aa64isar0;
38
- t = FIELD_DP64(t, ID_AA64ISAR0, TS, 1);
24
- t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* AES + PMULL */
39
+ t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* v8.5-CondM */
25
- t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1);
40
cpu->isar.id_aa64isar0 = t;
26
- t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* SHA512 */
41
27
+ t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* FEAT_PMULL */
42
t = cpu->isar.id_aa64isar1;
28
+ t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1); /* FEAT_SHA1 */
43
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
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
44
index XXXXXXX..XXXXXXX 100644
161
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/translate-a64.c
162
--- a/target/arm/cpu_tcg.c
46
+++ b/target/arm/translate-a64.c
163
+++ b/target/arm/cpu_tcg.c
47
@@ -XXX,XX +XXX,XX @@ static void handle_sync(DisasContext *s, uint32_t insn,
164
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
48
}
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;
49
}
242
}
50
243
51
+static void gen_xaflag(void)
52
+{
53
+ TCGv_i32 z = tcg_temp_new_i32();
54
+
55
+ tcg_gen_setcondi_i32(TCG_COND_EQ, z, cpu_ZF, 0);
56
+
57
+ /*
58
+ * (!C & !Z) << 31
59
+ * (!(C | Z)) << 31
60
+ * ~((C | Z) << 31)
61
+ * ~-(C | Z)
62
+ * (C | Z) - 1
63
+ */
64
+ tcg_gen_or_i32(cpu_NF, cpu_CF, z);
65
+ tcg_gen_subi_i32(cpu_NF, cpu_NF, 1);
66
+
67
+ /* !(Z & C) */
68
+ tcg_gen_and_i32(cpu_ZF, z, cpu_CF);
69
+ tcg_gen_xori_i32(cpu_ZF, cpu_ZF, 1);
70
+
71
+ /* (!C & Z) << 31 -> -(Z & ~C) */
72
+ tcg_gen_andc_i32(cpu_VF, z, cpu_CF);
73
+ tcg_gen_neg_i32(cpu_VF, cpu_VF);
74
+
75
+ /* C | Z */
76
+ tcg_gen_or_i32(cpu_CF, cpu_CF, z);
77
+
78
+ tcg_temp_free_i32(z);
79
+}
80
+
81
+static void gen_axflag(void)
82
+{
83
+ tcg_gen_sari_i32(cpu_VF, cpu_VF, 31); /* V ? -1 : 0 */
84
+ tcg_gen_andc_i32(cpu_CF, cpu_CF, cpu_VF); /* C & !V */
85
+
86
+ /* !(Z | V) -> !(!ZF | V) -> ZF & !V -> ZF & ~VF */
87
+ tcg_gen_andc_i32(cpu_ZF, cpu_ZF, cpu_VF);
88
+
89
+ tcg_gen_movi_i32(cpu_NF, 0);
90
+ tcg_gen_movi_i32(cpu_VF, 0);
91
+}
92
+
93
/* MSR (immediate) - move immediate to processor state field */
94
static void handle_msr_i(DisasContext *s, uint32_t insn,
95
unsigned int op1, unsigned int op2, unsigned int crm)
96
@@ -XXX,XX +XXX,XX @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
97
s->base.is_jmp = DISAS_NEXT;
98
break;
99
100
+ case 0x01: /* XAFlag */
101
+ if (crm != 0 || !dc_isar_feature(aa64_condm_5, s)) {
102
+ goto do_unallocated;
103
+ }
104
+ gen_xaflag();
105
+ s->base.is_jmp = DISAS_NEXT;
106
+ break;
107
+
108
+ case 0x02: /* AXFlag */
109
+ if (crm != 0 || !dc_isar_feature(aa64_condm_5, s)) {
110
+ goto do_unallocated;
111
+ }
112
+ gen_axflag();
113
+ s->base.is_jmp = DISAS_NEXT;
114
+ break;
115
+
116
case 0x05: /* SPSel */
117
if (s->current_el == 0) {
118
goto do_unallocated;
119
--
244
--
120
2.20.1
245
2.25.1
121
122
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This will allow sharing code that adjusts rmode beyond
3
Use FIELD_DP{32,64} to manipulate id_pfr1 and id_aa64pfr0
4
the existing users.
4
during arm_cpu_realizefn.
5
5
6
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190301200501.16533-10-richard.henderson@linaro.org
8
Message-id: 20220506180242.216785-11-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
target/arm/translate-a64.c | 90 +++++++++++++++++++++-----------------
11
target/arm/cpu.c | 22 +++++++++++++---------
13
1 file changed, 49 insertions(+), 41 deletions(-)
12
1 file changed, 13 insertions(+), 9 deletions(-)
14
13
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
16
--- a/target/arm/cpu.c
18
+++ b/target/arm/translate-a64.c
17
+++ b/target/arm/cpu.c
19
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn)
18
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
20
/* Floating-point data-processing (1 source) - single precision */
19
*/
21
static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
20
unset_feature(env, ARM_FEATURE_EL3);
22
{
21
23
+ void (*gen_fpst)(TCGv_i32, TCGv_i32, TCGv_ptr);
22
- /* Disable the security extension feature bits in the processor feature
24
+ TCGv_i32 tcg_op, tcg_res;
23
- * registers as well. These are id_pfr1[7:4] and id_aa64pfr0[15:12].
25
TCGv_ptr fpst;
24
+ /*
26
- TCGv_i32 tcg_op;
25
+ * Disable the security extension feature bits in the processor
27
- TCGv_i32 tcg_res;
26
+ * feature registers as well.
28
+ int rmode = -1;
27
*/
29
28
- cpu->isar.id_pfr1 &= ~0xf0;
30
- fpst = get_fpstatus_ptr(false);
29
- cpu->isar.id_aa64pfr0 &= ~0xf000;
31
tcg_op = read_fp_sreg(s, rn);
30
+ cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1, ID_PFR1, SECURITY, 0);
32
tcg_res = tcg_temp_new_i32();
31
+ cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
33
32
+ ID_AA64PFR0, EL3, 0);
34
switch (opcode) {
35
case 0x0: /* FMOV */
36
tcg_gen_mov_i32(tcg_res, tcg_op);
37
- break;
38
+ goto done;
39
case 0x1: /* FABS */
40
gen_helper_vfp_abss(tcg_res, tcg_op);
41
- break;
42
+ goto done;
43
case 0x2: /* FNEG */
44
gen_helper_vfp_negs(tcg_res, tcg_op);
45
- break;
46
+ goto done;
47
case 0x3: /* FSQRT */
48
gen_helper_vfp_sqrts(tcg_res, tcg_op, cpu_env);
49
- break;
50
+ goto done;
51
case 0x8: /* FRINTN */
52
case 0x9: /* FRINTP */
53
case 0xa: /* FRINTM */
54
case 0xb: /* FRINTZ */
55
case 0xc: /* FRINTA */
56
- {
57
- TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(opcode & 7));
58
-
59
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
60
- gen_helper_rints(tcg_res, tcg_op, fpst);
61
-
62
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
63
- tcg_temp_free_i32(tcg_rmode);
64
+ rmode = arm_rmode_to_sf(opcode & 7);
65
+ gen_fpst = gen_helper_rints;
66
break;
67
- }
68
case 0xe: /* FRINTX */
69
- gen_helper_rints_exact(tcg_res, tcg_op, fpst);
70
+ gen_fpst = gen_helper_rints_exact;
71
break;
72
case 0xf: /* FRINTI */
73
- gen_helper_rints(tcg_res, tcg_op, fpst);
74
+ gen_fpst = gen_helper_rints;
75
break;
76
default:
77
- abort();
78
+ g_assert_not_reached();
79
}
33
}
80
34
81
- write_fp_sreg(s, rd, tcg_res);
35
if (!cpu->has_el2) {
82
-
36
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
83
+ fpst = get_fpstatus_ptr(false);
84
+ if (rmode >= 0) {
85
+ TCGv_i32 tcg_rmode = tcg_const_i32(rmode);
86
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
87
+ gen_fpst(tcg_res, tcg_op, fpst);
88
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
89
+ tcg_temp_free_i32(tcg_rmode);
90
+ } else {
91
+ gen_fpst(tcg_res, tcg_op, fpst);
92
+ }
93
tcg_temp_free_ptr(fpst);
94
+
95
+ done:
96
+ write_fp_sreg(s, rd, tcg_res);
97
tcg_temp_free_i32(tcg_op);
98
tcg_temp_free_i32(tcg_res);
99
}
100
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
101
/* Floating-point data-processing (1 source) - double precision */
102
static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn)
103
{
104
+ void (*gen_fpst)(TCGv_i64, TCGv_i64, TCGv_ptr);
105
+ TCGv_i64 tcg_op, tcg_res;
106
TCGv_ptr fpst;
107
- TCGv_i64 tcg_op;
108
- TCGv_i64 tcg_res;
109
+ int rmode = -1;
110
111
switch (opcode) {
112
case 0x0: /* FMOV */
113
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn)
114
return;
115
}
37
}
116
38
117
- fpst = get_fpstatus_ptr(false);
39
if (!arm_feature(env, ARM_FEATURE_EL2)) {
118
tcg_op = read_fp_dreg(s, rn);
40
- /* Disable the hypervisor feature bits in the processor feature
119
tcg_res = tcg_temp_new_i64();
41
- * registers if we don't have EL2. These are id_pfr1[15:12] and
120
42
- * id_aa64pfr0_el1[11:8].
121
switch (opcode) {
43
+ /*
122
case 0x1: /* FABS */
44
+ * Disable the hypervisor feature bits in the processor feature
123
gen_helper_vfp_absd(tcg_res, tcg_op);
45
+ * registers if we don't have EL2.
124
- break;
46
*/
125
+ goto done;
47
- cpu->isar.id_aa64pfr0 &= ~0xf00;
126
case 0x2: /* FNEG */
48
- cpu->isar.id_pfr1 &= ~0xf000;
127
gen_helper_vfp_negd(tcg_res, tcg_op);
49
+ cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
128
- break;
50
+ ID_AA64PFR0, EL2, 0);
129
+ goto done;
51
+ cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1,
130
case 0x3: /* FSQRT */
52
+ ID_PFR1, VIRTUALIZATION, 0);
131
gen_helper_vfp_sqrtd(tcg_res, tcg_op, cpu_env);
132
- break;
133
+ goto done;
134
case 0x8: /* FRINTN */
135
case 0x9: /* FRINTP */
136
case 0xa: /* FRINTM */
137
case 0xb: /* FRINTZ */
138
case 0xc: /* FRINTA */
139
- {
140
- TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(opcode & 7));
141
-
142
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
143
- gen_helper_rintd(tcg_res, tcg_op, fpst);
144
-
145
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
146
- tcg_temp_free_i32(tcg_rmode);
147
+ rmode = arm_rmode_to_sf(opcode & 7);
148
+ gen_fpst = gen_helper_rintd;
149
break;
150
- }
151
case 0xe: /* FRINTX */
152
- gen_helper_rintd_exact(tcg_res, tcg_op, fpst);
153
+ gen_fpst = gen_helper_rintd_exact;
154
break;
155
case 0xf: /* FRINTI */
156
- gen_helper_rintd(tcg_res, tcg_op, fpst);
157
+ gen_fpst = gen_helper_rintd;
158
break;
159
default:
160
- abort();
161
+ g_assert_not_reached();
162
}
53
}
163
54
164
- write_fp_dreg(s, rd, tcg_res);
55
#ifndef CONFIG_USER_ONLY
165
-
166
+ fpst = get_fpstatus_ptr(false);
167
+ if (rmode >= 0) {
168
+ TCGv_i32 tcg_rmode = tcg_const_i32(rmode);
169
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
170
+ gen_fpst(tcg_res, tcg_op, fpst);
171
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
172
+ tcg_temp_free_i32(tcg_rmode);
173
+ } else {
174
+ gen_fpst(tcg_res, tcg_op, fpst);
175
+ }
176
tcg_temp_free_ptr(fpst);
177
+
178
+ done:
179
+ write_fp_dreg(s, rd, tcg_res);
180
tcg_temp_free_i64(tcg_op);
181
tcg_temp_free_i64(tcg_res);
182
}
183
--
56
--
184
2.20.1
57
2.25.1
185
186
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The only portion of FEAT_Debugv8p2 that is relevant to QEMU
4
is CONTEXTIDR_EL2, which is also conditionally implemented
5
with FEAT_VHE. The rest of the debug extension concerns the
6
External debug interface, which is outside the scope of QEMU.
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20190301200501.16533-3-richard.henderson@linaro.org
10
Message-id: 20220506180242.216785-12-richard.henderson@linaro.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
12
---
8
target/arm/cpu.h | 10 ++++++++++
13
docs/system/arm/emulation.rst | 1 +
9
linux-user/elfload.c | 1 +
14
target/arm/cpu.c | 1 +
10
target/arm/cpu.c | 1 +
15
target/arm/cpu64.c | 1 +
11
target/arm/cpu64.c | 2 ++
16
target/arm/cpu_tcg.c | 2 ++
12
target/arm/translate-a64.c | 14 ++++++++++++++
17
4 files changed, 5 insertions(+)
13
target/arm/translate.c | 22 ++++++++++++++++++++++
14
6 files changed, 50 insertions(+)
15
18
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
17
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
21
--- a/docs/system/arm/emulation.rst
19
+++ b/target/arm/cpu.h
22
+++ b/docs/system/arm/emulation.rst
20
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fhm(const ARMISARegisters *id)
23
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
21
return FIELD_EX32(id->id_isar6, ID_ISAR6, FHM) != 0;
24
- FEAT_BTI (Branch Target Identification)
22
}
25
- FEAT_DIT (Data Independent Timing instructions)
23
26
- FEAT_DPB (DC CVAP instruction)
24
+static inline bool isar_feature_aa32_sb(const ARMISARegisters *id)
27
+- FEAT_Debugv8p2 (Debug changes for v8.2)
25
+{
28
- FEAT_DotProd (Advanced SIMD dot product instructions)
26
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, SB) != 0;
29
- FEAT_FCMA (Floating-point complex number instructions)
27
+}
30
- FEAT_FHM (Floating-point half-precision multiplication instructions)
28
+
29
static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
30
{
31
/*
32
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_pauth(const ARMISARegisters *id)
33
FIELD_DP64(0, ID_AA64ISAR1, GPI, 0xf))) != 0;
34
}
35
36
+static inline bool isar_feature_aa64_sb(const ARMISARegisters *id)
37
+{
38
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SB) != 0;
39
+}
40
+
41
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
42
{
43
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
44
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/linux-user/elfload.c
47
+++ b/linux-user/elfload.c
48
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
49
GET_FEATURE_ID(aa64_pauth, ARM_HWCAP_A64_PACA | ARM_HWCAP_A64_PACG);
50
GET_FEATURE_ID(aa64_fhm, ARM_HWCAP_A64_ASIMDFHM);
51
GET_FEATURE_ID(aa64_jscvt, ARM_HWCAP_A64_JSCVT);
52
+ GET_FEATURE_ID(aa64_sb, ARM_HWCAP_A64_SB);
53
54
#undef GET_FEATURE_ID
55
56
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
57
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/cpu.c
33
--- a/target/arm/cpu.c
59
+++ b/target/arm/cpu.c
34
+++ b/target/arm/cpu.c
60
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
35
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
61
t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
36
* feature registers as well.
62
t = FIELD_DP32(t, ID_ISAR6, DP, 1);
37
*/
63
t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
38
cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1, ID_PFR1, SECURITY, 0);
64
+ t = FIELD_DP32(t, ID_ISAR6, SB, 1);
39
+ cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPSDBG, 0);
65
cpu->isar.id_isar6 = t;
40
cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
66
41
ID_AA64PFR0, EL3, 0);
67
t = cpu->id_mmfr4;
42
}
68
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
43
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
69
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/cpu64.c
45
--- a/target/arm/cpu64.c
71
+++ b/target/arm/cpu64.c
46
+++ b/target/arm/cpu64.c
72
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
47
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
73
t = FIELD_DP64(t, ID_AA64ISAR1, API, 0);
48
cpu->isar.id_aa64zfr0 = t;
74
t = FIELD_DP64(t, ID_AA64ISAR1, GPA, 1);
49
75
t = FIELD_DP64(t, ID_AA64ISAR1, GPI, 0);
50
t = cpu->isar.id_aa64dfr0;
76
+ t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
51
+ t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 8); /* FEAT_Debugv8p2 */
77
cpu->isar.id_aa64isar1 = t;
52
t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* FEAT_PMUv3p4 */
78
53
cpu->isar.id_aa64dfr0 = t;
79
t = cpu->isar.id_aa64pfr0;
54
80
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
55
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
81
u = FIELD_DP32(u, ID_ISAR6, JSCVT, 1);
82
u = FIELD_DP32(u, ID_ISAR6, DP, 1);
83
u = FIELD_DP32(u, ID_ISAR6, FHM, 1);
84
+ u = FIELD_DP32(u, ID_ISAR6, SB, 1);
85
cpu->isar.id_isar6 = u;
86
87
/*
88
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
89
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/translate-a64.c
57
--- a/target/arm/cpu_tcg.c
91
+++ b/target/arm/translate-a64.c
58
+++ b/target/arm/cpu_tcg.c
92
@@ -XXX,XX +XXX,XX @@ static void handle_sync(DisasContext *s, uint32_t insn,
59
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
93
reset_btype(s);
60
cpu->isar.id_pfr2 = t;
94
gen_goto_tb(s, 0, s->pc);
61
95
return;
62
t = cpu->isar.id_dfr0;
96
+
63
+ t = FIELD_DP32(t, ID_DFR0, COPDBG, 8); /* FEAT_Debugv8p2 */
97
+ case 7: /* SB */
64
+ t = FIELD_DP32(t, ID_DFR0, COPSDBG, 8); /* FEAT_Debugv8p2 */
98
+ if (crm != 0 || !dc_isar_feature(aa64_sb, s)) {
65
t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* FEAT_PMUv3p4 */
99
+ goto do_unallocated;
66
cpu->isar.id_dfr0 = t;
100
+ }
67
}
101
+ /*
102
+ * TODO: There is no speculation barrier opcode for TCG;
103
+ * MB and end the TB instead.
104
+ */
105
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
106
+ gen_goto_tb(s, 0, s->pc);
107
+ return;
108
+
109
default:
110
+ do_unallocated:
111
unallocated_encoding(s);
112
return;
113
}
114
diff --git a/target/arm/translate.c b/target/arm/translate.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/target/arm/translate.c
117
+++ b/target/arm/translate.c
118
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
119
*/
120
gen_goto_tb(s, 0, s->pc & ~1);
121
return;
122
+ case 7: /* sb */
123
+ if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
124
+ goto illegal_op;
125
+ }
126
+ /*
127
+ * TODO: There is no speculation barrier opcode
128
+ * for TCG; MB and end the TB instead.
129
+ */
130
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
131
+ gen_goto_tb(s, 0, s->pc & ~1);
132
+ return;
133
default:
134
goto illegal_op;
135
}
136
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
137
*/
138
gen_goto_tb(s, 0, s->pc & ~1);
139
break;
140
+ case 7: /* sb */
141
+ if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
142
+ goto illegal_op;
143
+ }
144
+ /*
145
+ * TODO: There is no speculation barrier opcode
146
+ * for TCG; MB and end the TB instead.
147
+ */
148
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
149
+ gen_goto_tb(s, 0, s->pc & ~1);
150
+ break;
151
default:
152
goto illegal_op;
153
}
154
--
68
--
155
2.20.1
69
2.25.1
156
157
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
This extension concerns changes to the External Debug interface,
4
with Secure and Non-secure access to the debug registers, and all
5
of it is outside the scope of QEMU. Indicating support for this
6
is mandatory with FEAT_SEL2, which we do implement.
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20220506180242.216785-13-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
docs/system/arm/emulation.rst | 1 +
14
target/arm/cpu64.c | 2 +-
15
target/arm/cpu_tcg.c | 4 ++--
16
3 files changed, 4 insertions(+), 3 deletions(-)
17
18
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
19
index XXXXXXX..XXXXXXX 100644
20
--- a/docs/system/arm/emulation.rst
21
+++ b/docs/system/arm/emulation.rst
22
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
23
- FEAT_DIT (Data Independent Timing instructions)
24
- FEAT_DPB (DC CVAP instruction)
25
- FEAT_Debugv8p2 (Debug changes for v8.2)
26
+- FEAT_Debugv8p4 (Debug changes for v8.4)
27
- FEAT_DotProd (Advanced SIMD dot product instructions)
28
- FEAT_FCMA (Floating-point complex number instructions)
29
- FEAT_FHM (Floating-point half-precision multiplication instructions)
30
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/cpu64.c
33
+++ b/target/arm/cpu64.c
34
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
35
cpu->isar.id_aa64zfr0 = t;
36
37
t = cpu->isar.id_aa64dfr0;
38
- t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 8); /* FEAT_Debugv8p2 */
39
+ t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 9); /* FEAT_Debugv8p4 */
40
t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* FEAT_PMUv3p4 */
41
cpu->isar.id_aa64dfr0 = t;
42
43
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/cpu_tcg.c
46
+++ b/target/arm/cpu_tcg.c
47
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
48
cpu->isar.id_pfr2 = t;
49
50
t = cpu->isar.id_dfr0;
51
- t = FIELD_DP32(t, ID_DFR0, COPDBG, 8); /* FEAT_Debugv8p2 */
52
- t = FIELD_DP32(t, ID_DFR0, COPSDBG, 8); /* FEAT_Debugv8p2 */
53
+ t = FIELD_DP32(t, ID_DFR0, COPDBG, 9); /* FEAT_Debugv8p4 */
54
+ t = FIELD_DP32(t, ID_DFR0, COPSDBG, 9); /* FEAT_Debugv8p4 */
55
t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* FEAT_PMUv3p4 */
56
cpu->isar.id_dfr0 = t;
57
}
58
--
59
2.25.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
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>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190301200501.16533-8-richard.henderson@linaro.org
12
Message-id: 20220506180242.216785-14-richard.henderson@linaro.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
[PMM: fixed up block comment style]
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
14
---
10
target/arm/cpu.h | 5 ++
15
target/arm/cpu.h | 5 +++
11
linux-user/elfload.c | 1 +
16
target/arm/helper.c | 84 +++++++++++++++++++++++++++++++++++++++++++++
12
target/arm/cpu64.c | 1 +
17
2 files changed, 89 insertions(+)
13
target/arm/translate-a64.c | 99 +++++++++++++++++++++++++++++++++++++-
14
4 files changed, 105 insertions(+), 1 deletion(-)
15
18
16
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
17
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
21
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_fhm(const ARMISARegisters *id)
23
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
21
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, FHM) != 0;
24
uint64_t tfsr_el[4]; /* tfsre0_el1 is index 0. */
22
}
25
uint64_t gcr_el1;
23
26
uint64_t rgsr_el1;
24
+static inline bool isar_feature_aa64_condm_4(const ARMISARegisters *id)
27
+
28
+ /* Minimal RAS registers */
29
+ uint64_t disr_el1;
30
+ uint64_t vdisr_el2;
31
+ uint64_t vsesr_el2;
32
} cp15;
33
34
struct {
35
diff --git a/target/arm/helper.c b/target/arm/helper.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper.c
38
+++ b/target/arm/helper.c
39
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
40
.access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
41
};
42
43
+/*
44
+ * Check for traps to RAS registers, which are controlled
45
+ * by HCR_EL2.TERR and SCR_EL3.TERR.
46
+ */
47
+static CPAccessResult access_terr(CPUARMState *env, const ARMCPRegInfo *ri,
48
+ bool isread)
25
+{
49
+{
26
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) != 0;
50
+ int el = arm_current_el(env);
51
+
52
+ if (el < 2 && (arm_hcr_el2_eff(env) & HCR_TERR)) {
53
+ return CP_ACCESS_TRAP_EL2;
54
+ }
55
+ if (el < 3 && (env->cp15.scr_el3 & SCR_TERR)) {
56
+ return CP_ACCESS_TRAP_EL3;
57
+ }
58
+ return CP_ACCESS_OK;
27
+}
59
+}
28
+
60
+
29
static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id)
61
+static uint64_t disr_read(CPUARMState *env, const ARMCPRegInfo *ri)
30
{
62
+{
31
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0;
63
+ int el = arm_current_el(env);
32
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/linux-user/elfload.c
35
+++ b/linux-user/elfload.c
36
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
37
GET_FEATURE_ID(aa64_fhm, ARM_HWCAP_A64_ASIMDFHM);
38
GET_FEATURE_ID(aa64_jscvt, ARM_HWCAP_A64_JSCVT);
39
GET_FEATURE_ID(aa64_sb, ARM_HWCAP_A64_SB);
40
+ GET_FEATURE_ID(aa64_condm_4, ARM_HWCAP_A64_FLAGM);
41
42
#undef GET_FEATURE_ID
43
44
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/cpu64.c
47
+++ b/target/arm/cpu64.c
48
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
49
t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 1);
50
t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
51
t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1);
52
+ t = FIELD_DP64(t, ID_AA64ISAR0, TS, 1);
53
cpu->isar.id_aa64isar0 = t;
54
55
t = cpu->isar.id_aa64isar1;
56
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/translate-a64.c
59
+++ b/target/arm/translate-a64.c
60
@@ -XXX,XX +XXX,XX @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
61
s->base.is_jmp = DISAS_TOO_MANY;
62
63
switch (op) {
64
+ case 0x00: /* CFINV */
65
+ if (crm != 0 || !dc_isar_feature(aa64_condm_4, s)) {
66
+ goto do_unallocated;
67
+ }
68
+ tcg_gen_xori_i32(cpu_CF, cpu_CF, 1);
69
+ s->base.is_jmp = DISAS_NEXT;
70
+ break;
71
+
64
+
72
case 0x05: /* SPSel */
65
+ if (el < 2 && (arm_hcr_el2_eff(env) & HCR_AMO)) {
73
if (s->current_el == 0) {
66
+ return env->cp15.vdisr_el2;
74
goto do_unallocated;
67
+ }
75
@@ -XXX,XX +XXX,XX @@ static void gen_get_nzcv(TCGv_i64 tcg_rt)
68
+ if (el < 3 && (env->cp15.scr_el3 & SCR_EA)) {
76
}
69
+ return 0; /* RAZ/WI */
77
70
+ }
78
static void gen_set_nzcv(TCGv_i64 tcg_rt)
71
+ return env->cp15.disr_el1;
79
-
72
+}
80
{
73
+
81
TCGv_i32 nzcv = tcg_temp_new_i32();
74
+static void disr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t val)
82
83
@@ -XXX,XX +XXX,XX @@ static void disas_adc_sbc(DisasContext *s, uint32_t insn)
84
}
85
}
86
87
+/*
88
+ * Rotate right into flags
89
+ * 31 30 29 21 15 10 5 4 0
90
+ * +--+--+--+-----------------+--------+-----------+------+--+------+
91
+ * |sf|op| S| 1 1 0 1 0 0 0 0 | imm6 | 0 0 0 0 1 | Rn |o2| mask |
92
+ * +--+--+--+-----------------+--------+-----------+------+--+------+
93
+ */
94
+static void disas_rotate_right_into_flags(DisasContext *s, uint32_t insn)
95
+{
75
+{
96
+ int mask = extract32(insn, 0, 4);
76
+ int el = arm_current_el(env);
97
+ int o2 = extract32(insn, 4, 1);
98
+ int rn = extract32(insn, 5, 5);
99
+ int imm6 = extract32(insn, 15, 6);
100
+ int sf_op_s = extract32(insn, 29, 3);
101
+ TCGv_i64 tcg_rn;
102
+ TCGv_i32 nzcv;
103
+
77
+
104
+ if (sf_op_s != 5 || o2 != 0 || !dc_isar_feature(aa64_condm_4, s)) {
78
+ if (el < 2 && (arm_hcr_el2_eff(env) & HCR_AMO)) {
105
+ unallocated_encoding(s);
79
+ env->cp15.vdisr_el2 = val;
106
+ return;
80
+ return;
107
+ }
81
+ }
108
+
82
+ if (el < 3 && (env->cp15.scr_el3 & SCR_EA)) {
109
+ tcg_rn = read_cpu_reg(s, rn, 1);
83
+ return; /* RAZ/WI */
110
+ tcg_gen_rotri_i64(tcg_rn, tcg_rn, imm6);
111
+
112
+ nzcv = tcg_temp_new_i32();
113
+ tcg_gen_extrl_i64_i32(nzcv, tcg_rn);
114
+
115
+ if (mask & 8) { /* N */
116
+ tcg_gen_shli_i32(cpu_NF, nzcv, 31 - 3);
117
+ }
84
+ }
118
+ if (mask & 4) { /* Z */
85
+ env->cp15.disr_el1 = val;
119
+ tcg_gen_not_i32(cpu_ZF, nzcv);
120
+ tcg_gen_andi_i32(cpu_ZF, cpu_ZF, 4);
121
+ }
122
+ if (mask & 2) { /* C */
123
+ tcg_gen_extract_i32(cpu_CF, nzcv, 1, 1);
124
+ }
125
+ if (mask & 1) { /* V */
126
+ tcg_gen_shli_i32(cpu_VF, nzcv, 31 - 0);
127
+ }
128
+
129
+ tcg_temp_free_i32(nzcv);
130
+}
86
+}
131
+
87
+
132
+/*
88
+/*
133
+ * Evaluate into flags
89
+ * Minimal RAS implementation with no Error Records.
134
+ * 31 30 29 21 15 14 10 5 4 0
90
+ * Which means that all of the Error Record registers:
135
+ * +--+--+--+-----------------+---------+----+---------+------+--+------+
91
+ * ERXADDR_EL1
136
+ * |sf|op| S| 1 1 0 1 0 0 0 0 | opcode2 | sz | 0 0 1 0 | Rn |o3| mask |
92
+ * ERXCTLR_EL1
137
+ * +--+--+--+-----------------+---------+----+---------+------+--+------+
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.
138
+ */
106
+ */
139
+static void disas_evaluate_into_flags(DisasContext *s, uint32_t insn)
107
+static const ARMCPRegInfo minimal_ras_reginfo[] = {
140
+{
108
+ { .name = "DISR_EL1", .state = ARM_CP_STATE_BOTH,
141
+ int o3_mask = extract32(insn, 0, 5);
109
+ .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 1, .opc2 = 1,
142
+ int rn = extract32(insn, 5, 5);
110
+ .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.disr_el1),
143
+ int o2 = extract32(insn, 15, 6);
111
+ .readfn = disr_read, .writefn = disr_write, .raw_writefn = raw_write },
144
+ int sz = extract32(insn, 14, 1);
112
+ { .name = "ERRIDR_EL1", .state = ARM_CP_STATE_BOTH,
145
+ int sf_op_s = extract32(insn, 29, 3);
113
+ .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 3, .opc2 = 0,
146
+ TCGv_i32 tmp;
114
+ .access = PL1_R, .accessfn = access_terr,
147
+ int shift;
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
+};
148
+
123
+
149
+ if (sf_op_s != 1 || o2 != 0 || o3_mask != 0xd ||
124
/* Return the exception level to which exceptions should be taken
150
+ !dc_isar_feature(aa64_condm_4, s)) {
125
* via SVEAccessTrap. If an exception should be routed through
151
+ unallocated_encoding(s);
126
* AArch64.AdvSIMDFPAccessTrap, return 0; fp_exception_el should
152
+ return;
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);
153
+ }
133
+ }
154
+ shift = sz ? 16 : 24; /* SETF16 or SETF8 */
134
155
+
135
if (cpu_isar_feature(aa64_vh, cpu) ||
156
+ tmp = tcg_temp_new_i32();
136
cpu_isar_feature(aa64_debugv8p2, cpu)) {
157
+ tcg_gen_extrl_i64_i32(tmp, cpu_reg(s, rn));
158
+ tcg_gen_shli_i32(cpu_NF, tmp, shift);
159
+ tcg_gen_shli_i32(cpu_VF, tmp, shift - 1);
160
+ tcg_gen_mov_i32(cpu_ZF, cpu_NF);
161
+ tcg_gen_xor_i32(cpu_VF, cpu_VF, cpu_NF);
162
+ tcg_temp_free_i32(tmp);
163
+}
164
+
165
/* Conditional compare (immediate / register)
166
* 31 30 29 28 27 26 25 24 23 22 21 20 16 15 12 11 10 9 5 4 3 0
167
* +--+--+--+------------------------+--------+------+----+--+------+--+-----+
168
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn)
169
disas_adc_sbc(s, insn);
170
break;
171
172
+ case 0x01: /* Rotate right into flags */
173
+ case 0x21:
174
+ disas_rotate_right_into_flags(s, insn);
175
+ break;
176
+
177
+ case 0x02: /* Evaluate into flags */
178
+ case 0x12:
179
+ case 0x22:
180
+ case 0x32:
181
+ disas_evaluate_into_flags(s, insn);
182
+ break;
183
+
184
default:
185
goto do_unallocated;
186
}
187
--
137
--
188
2.20.1
138
2.25.1
189
190
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Enable writes to the TERR and TEA bits when RAS is enabled.
4
These bits are otherwise RES0.
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-15-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/helper.c | 9 +++++++++
12
1 file changed, 9 insertions(+)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
19
}
20
valid_mask &= ~SCR_NET;
21
22
+ if (cpu_isar_feature(aa64_ras, cpu)) {
23
+ valid_mask |= SCR_TERR;
24
+ }
25
if (cpu_isar_feature(aa64_lor, cpu)) {
26
valid_mask |= SCR_TLOR;
27
}
28
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
29
}
30
} else {
31
valid_mask &= ~(SCR_RW | SCR_ST);
32
+ if (cpu_isar_feature(aa32_ras, cpu)) {
33
+ valid_mask |= SCR_TERR;
34
+ }
35
}
36
37
if (!arm_feature(env, ARM_FEATURE_EL2)) {
38
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
39
if (cpu_isar_feature(aa64_vh, cpu)) {
40
valid_mask |= HCR_E2H;
41
}
42
+ if (cpu_isar_feature(aa64_ras, cpu)) {
43
+ valid_mask |= HCR_TERR | HCR_TEA;
44
+ }
45
if (cpu_isar_feature(aa64_lor, cpu)) {
46
valid_mask |= HCR_TLOR;
47
}
48
--
49
2.25.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Minimize the number of places that will need updating when
3
Virtual SError exceptions are raised by setting HCR_EL2.VSE,
4
the virtual host extensions are added.
4
and are routed to EL1 just like other virtual exceptions.
5
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190301200501.16533-2-richard.henderson@linaro.org
8
Message-id: 20220506180242.216785-16-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
target/arm/cpu.h | 26 ++++++++++++++++----------
11
target/arm/cpu.h | 2 ++
12
target/arm/helper.c | 8 ++------
12
target/arm/internals.h | 8 ++++++++
13
2 files changed, 18 insertions(+), 16 deletions(-)
13
target/arm/syndrome.h | 5 +++++
14
target/arm/cpu.c | 38 +++++++++++++++++++++++++++++++++++++-
15
target/arm/helper.c | 40 +++++++++++++++++++++++++++++++++++++++-
16
5 files changed, 91 insertions(+), 2 deletions(-)
14
17
15
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
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
20
--- a/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ static inline bool arm_sctlr_b(CPUARMState *env)
22
@@ -XXX,XX +XXX,XX @@
20
(env->cp15.sctlr_el[1] & SCTLR_B) != 0;
23
#define EXCP_LSERR 21 /* v8M LSERR SecureFault */
21
}
24
#define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */
22
25
#define EXCP_DIVBYZERO 23 /* v7M DIVBYZERO UsageFault */
23
+static inline uint64_t arm_sctlr(CPUARMState *env, int el)
26
+#define EXCP_VSERR 24
27
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
28
29
#define ARMV7M_EXCP_RESET 1
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)
24
+{
66
+{
25
+ if (el == 0) {
67
+ return (EC_SERROR << ARM_EL_EC_SHIFT) | ARM_EL_IL | extra;
26
+ /* FIXME: ARMv8.1-VHE S2 translation regime. */
68
+}
27
+ return env->cp15.sctlr_el[1];
69
+
28
+ } else {
70
#endif /* TARGET_ARM_SYNDROME_H */
29
+ return env->cp15.sctlr_el[el];
71
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/cpu.c
74
+++ b/target/arm/cpu.c
75
@@ -XXX,XX +XXX,XX @@ static bool arm_cpu_has_work(CPUState *cs)
76
return (cpu->power_state != PSCI_OFF)
77
&& cs->interrupt_request &
78
(CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD
79
- | CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ
80
+ | CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ | CPU_INTERRUPT_VSERR
81
| CPU_INTERRUPT_EXITTB);
82
}
83
84
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
85
return false;
86
}
87
return !(env->daif & PSTATE_I);
88
+ case EXCP_VSERR:
89
+ if (!(hcr_el2 & HCR_AMO) || (hcr_el2 & HCR_TGE)) {
90
+ /* VIRQs are only taken when hypervized. */
91
+ return false;
92
+ }
93
+ return !(env->daif & PSTATE_A);
94
default:
95
g_assert_not_reached();
96
}
97
@@ -XXX,XX +XXX,XX @@ static bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
98
goto found;
99
}
100
}
101
+ if (interrupt_request & CPU_INTERRUPT_VSERR) {
102
+ excp_idx = EXCP_VSERR;
103
+ target_el = 1;
104
+ if (arm_excp_unmasked(cs, excp_idx, target_el,
105
+ cur_el, secure, hcr_el2)) {
106
+ /* Taking a virtual abort clears HCR_EL2.VSE */
107
+ env->cp15.hcr_el2 &= ~HCR_VSE;
108
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_VSERR);
109
+ goto found;
110
+ }
111
+ }
112
return false;
113
114
found:
115
@@ -XXX,XX +XXX,XX @@ void arm_cpu_update_vfiq(ARMCPU *cpu)
116
}
117
}
118
119
+void arm_cpu_update_vserr(ARMCPU *cpu)
120
+{
121
+ /*
122
+ * Update the interrupt level for VSERR, which is the HCR_EL2.VSE bit.
123
+ */
124
+ CPUARMState *env = &cpu->env;
125
+ CPUState *cs = CPU(cpu);
126
+
127
+ bool new_state = env->cp15.hcr_el2 & HCR_VSE;
128
+
129
+ if (new_state != ((cs->interrupt_request & CPU_INTERRUPT_VSERR) != 0)) {
130
+ if (new_state) {
131
+ cpu_interrupt(cs, CPU_INTERRUPT_VSERR);
132
+ } else {
133
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_VSERR);
134
+ }
30
+ }
135
+ }
31
+}
136
+}
32
+
137
+
33
+
138
#ifndef CONFIG_USER_ONLY
34
/* Return true if the processor is in big-endian mode. */
139
static void arm_cpu_set_irq(void *opaque, int irq, int level)
35
static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
36
{
140
{
37
- int cur_el;
38
-
39
/* In 32bit endianness is determined by looking at CPSR's E bit */
40
if (!is_a64(env)) {
41
return
42
@@ -XXX,XX +XXX,XX @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
43
arm_sctlr_b(env) ||
44
#endif
45
((env->uncached_cpsr & CPSR_E) ? 1 : 0);
46
+ } else {
47
+ int cur_el = arm_current_el(env);
48
+ uint64_t sctlr = arm_sctlr(env, cur_el);
49
+
50
+ return (sctlr & (cur_el ? SCTLR_EE : SCTLR_E0E)) != 0;
51
}
52
-
53
- cur_el = arm_current_el(env);
54
-
55
- if (cur_el == 0) {
56
- return (env->cp15.sctlr_el[1] & SCTLR_E0E) != 0;
57
- }
58
-
59
- return (env->cp15.sctlr_el[cur_el] & SCTLR_EE) != 0;
60
}
61
62
#include "exec/cpu-all.h"
63
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
64
index XXXXXXX..XXXXXXX 100644
142
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/helper.c
143
--- a/target/arm/helper.c
66
+++ b/target/arm/helper.c
144
+++ b/target/arm/helper.c
67
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
145
@@ -XXX,XX +XXX,XX @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
68
flags = FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len);
69
}
146
}
70
147
}
71
- if (current_el == 0) {
148
72
- /* FIXME: ARMv8.1-VHE S2 translation regime. */
149
- /* External aborts are not possible in QEMU so A bit is always clear */
73
- sctlr = env->cp15.sctlr_el[1];
150
+ if (hcr_el2 & HCR_AMO) {
74
- } else {
151
+ if (cs->interrupt_request & CPU_INTERRUPT_VSERR) {
75
- sctlr = env->cp15.sctlr_el[current_el];
152
+ ret |= CPSR_A;
76
- }
153
+ }
77
+ sctlr = arm_sctlr(env, current_el);
154
+ }
78
+
155
+
79
if (cpu_isar_feature(aa64_pauth, cpu)) {
156
return ret;
80
/*
157
}
81
* In order to save space in flags, we record only whether
158
159
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
160
g_assert(qemu_mutex_iothread_locked());
161
arm_cpu_update_virq(cpu);
162
arm_cpu_update_vfiq(cpu);
163
+ arm_cpu_update_vserr(cpu);
164
}
165
166
static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
167
@@ -XXX,XX +XXX,XX @@ void arm_log_exception(CPUState *cs)
168
[EXCP_LSERR] = "v8M LSERR UsageFault",
169
[EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
170
[EXCP_DIVBYZERO] = "v7M DIVBYZERO UsageFault",
171
+ [EXCP_VSERR] = "Virtual SERR",
172
};
173
174
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
175
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
176
mask = CPSR_A | CPSR_I | CPSR_F;
177
offset = 4;
178
break;
179
+ case EXCP_VSERR:
180
+ {
181
+ /*
182
+ * Note that this is reported as a data abort, but the DFAR
183
+ * has an UNKNOWN value. Construct the SError syndrome from
184
+ * AET and ExT fields.
185
+ */
186
+ ARMMMUFaultInfo fi = { .type = ARMFault_AsyncExternal, };
187
+
188
+ if (extended_addresses_enabled(env)) {
189
+ env->exception.fsr = arm_fi_to_lfsc(&fi);
190
+ } else {
191
+ env->exception.fsr = arm_fi_to_sfsc(&fi);
192
+ }
193
+ env->exception.fsr |= env->cp15.vsesr_el2 & 0xd000;
194
+ A32_BANKED_CURRENT_REG_SET(env, dfsr, env->exception.fsr);
195
+ qemu_log_mask(CPU_LOG_INT, "...with IFSR 0x%x\n",
196
+ env->exception.fsr);
197
+
198
+ new_mode = ARM_CPU_MODE_ABT;
199
+ addr = 0x10;
200
+ mask = CPSR_A | CPSR_I;
201
+ offset = 8;
202
+ }
203
+ break;
204
case EXCP_SMC:
205
new_mode = ARM_CPU_MODE_MON;
206
addr = 0x08;
207
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
208
case EXCP_VFIQ:
209
addr += 0x100;
210
break;
211
+ case EXCP_VSERR:
212
+ addr += 0x180;
213
+ /* Construct the SError syndrome from IDS and ISS fields. */
214
+ env->exception.syndrome = syn_serror(env->cp15.vsesr_el2 & 0x1ffffff);
215
+ env->cp15.esr_el[new_el] = env->exception.syndrome;
216
+ break;
217
default:
218
cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
219
}
82
--
220
--
83
2.20.1
221
2.25.1
84
85
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
We do not need an out-of-line helper for manipulating bits in pstate.
3
Check for and defer any pending virtual SError.
4
While changing things, share the implementation of gen_ss_advance.
5
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190301200501.16533-6-richard.henderson@linaro.org
7
Message-id: 20220506180242.216785-17-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
target/arm/helper.h | 2 --
10
target/arm/helper.h | 1 +
12
target/arm/translate.h | 34 ++++++++++++++++++++++++++++++++++
11
target/arm/a32.decode | 16 ++++++++------
13
target/arm/op_helper.c | 5 -----
12
target/arm/t32.decode | 18 ++++++++--------
14
target/arm/translate-a64.c | 11 -----------
13
target/arm/op_helper.c | 43 ++++++++++++++++++++++++++++++++++++++
15
target/arm/translate.c | 11 -----------
14
target/arm/translate-a64.c | 17 +++++++++++++++
16
5 files changed, 34 insertions(+), 29 deletions(-)
15
target/arm/translate.c | 23 ++++++++++++++++++++
16
6 files changed, 103 insertions(+), 15 deletions(-)
17
17
18
diff --git a/target/arm/helper.h b/target/arm/helper.h
18
diff --git a/target/arm/helper.h b/target/arm/helper.h
19
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.h
20
--- a/target/arm/helper.h
21
+++ b/target/arm/helper.h
21
+++ b/target/arm/helper.h
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(get_cp_reg, i32, env, ptr)
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(wfe, void, env)
23
DEF_HELPER_3(set_cp_reg64, void, env, ptr, i64)
23
DEF_HELPER_1(yield, void, env)
24
DEF_HELPER_2(get_cp_reg64, i64, env, ptr)
24
DEF_HELPER_1(pre_hvc, void, env)
25
25
DEF_HELPER_2(pre_smc, void, env, i32)
26
-DEF_HELPER_1(clear_pstate_ss, void, env)
26
+DEF_HELPER_1(vesb, void, env)
27
-
27
28
DEF_HELPER_2(get_r13_banked, i32, env, i32)
28
DEF_HELPER_3(cpsr_write, void, env, i32, i32)
29
DEF_HELPER_3(set_r13_banked, void, env, i32, i32)
29
DEF_HELPER_2(cpsr_write_eret, void, env, i32)
30
30
diff --git a/target/arm/a32.decode b/target/arm/a32.decode
31
diff --git a/target/arm/translate.h b/target/arm/translate.h
31
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/a32.decode
33
--- a/target/arm/translate.h
33
+++ b/target/arm/a32.decode
34
+++ b/target/arm/translate.h
34
@@ -XXX,XX +XXX,XX @@ SMULTT .... 0001 0110 .... 0000 .... 1110 .... @rd0mn
35
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 get_ahp_flag(void)
35
36
return ret;
36
{
37
{
38
- YIELD ---- 0011 0010 0000 1111 ---- 0000 0001
39
- WFE ---- 0011 0010 0000 1111 ---- 0000 0010
40
- WFI ---- 0011 0010 0000 1111 ---- 0000 0011
41
+ [
42
+ YIELD ---- 0011 0010 0000 1111 ---- 0000 0001
43
+ WFE ---- 0011 0010 0000 1111 ---- 0000 0010
44
+ WFI ---- 0011 0010 0000 1111 ---- 0000 0011
45
46
- # TODO: Implement SEV, SEVL; may help SMP performance.
47
- # SEV ---- 0011 0010 0000 1111 ---- 0000 0100
48
- # SEVL ---- 0011 0010 0000 1111 ---- 0000 0101
49
+ # TODO: Implement SEV, SEVL; may help SMP performance.
50
+ # SEV ---- 0011 0010 0000 1111 ---- 0000 0100
51
+ # SEVL ---- 0011 0010 0000 1111 ---- 0000 0101
52
+
53
+ ESB ---- 0011 0010 0000 1111 ---- 0001 0000
54
+ ]
55
56
# The canonical nop ends in 00000000, but the whole of the
57
# rest of the space executes as nop if otherwise unsupported.
58
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/t32.decode
61
+++ b/target/arm/t32.decode
62
@@ -XXX,XX +XXX,XX @@ CLZ 1111 1010 1011 ---- 1111 .... 1000 .... @rdm
63
[
64
# Hints, and CPS
65
{
66
- YIELD 1111 0011 1010 1111 1000 0000 0000 0001
67
- WFE 1111 0011 1010 1111 1000 0000 0000 0010
68
- WFI 1111 0011 1010 1111 1000 0000 0000 0011
69
+ [
70
+ YIELD 1111 0011 1010 1111 1000 0000 0000 0001
71
+ WFE 1111 0011 1010 1111 1000 0000 0000 0010
72
+ WFI 1111 0011 1010 1111 1000 0000 0000 0011
73
74
- # TODO: Implement SEV, SEVL; may help SMP performance.
75
- # SEV 1111 0011 1010 1111 1000 0000 0000 0100
76
- # SEVL 1111 0011 1010 1111 1000 0000 0000 0101
77
+ # TODO: Implement SEV, SEVL; may help SMP performance.
78
+ # SEV 1111 0011 1010 1111 1000 0000 0000 0100
79
+ # SEVL 1111 0011 1010 1111 1000 0000 0000 0101
80
81
- # For M-profile minimal-RAS ESB can be a NOP, which is the
82
- # default behaviour since it is in the hint space.
83
- # ESB 1111 0011 1010 1111 1000 0000 0001 0000
84
+ ESB 1111 0011 1010 1111 1000 0000 0001 0000
85
+ ]
86
87
# The canonical nop ends in 0000 0000, but the whole rest
88
# of the space is "reserved hint, behaves as nop".
89
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/target/arm/op_helper.c
92
+++ b/target/arm/op_helper.c
93
@@ -XXX,XX +XXX,XX @@ void HELPER(probe_access)(CPUARMState *env, target_ulong ptr,
94
access_type, mmu_idx, ra);
95
}
37
}
96
}
38
97
+
39
+/* Set bits within PSTATE. */
98
+/*
40
+static inline void set_pstate_bits(uint32_t bits)
99
+ * This function corresponds to AArch64.vESBOperation().
100
+ * Note that the AArch32 version is not functionally different.
101
+ */
102
+void HELPER(vesb)(CPUARMState *env)
41
+{
103
+{
42
+ TCGv_i32 p = tcg_temp_new_i32();
104
+ /*
43
+
105
+ * The EL2Enabled() check is done inside arm_hcr_el2_eff,
44
+ tcg_debug_assert(!(bits & CACHED_PSTATE_BITS));
106
+ * and will return HCR_EL2.VSE == 0, so nothing happens.
45
+
107
+ */
46
+ tcg_gen_ld_i32(p, cpu_env, offsetof(CPUARMState, pstate));
108
+ uint64_t hcr = arm_hcr_el2_eff(env);
47
+ tcg_gen_ori_i32(p, p, bits);
109
+ bool enabled = !(hcr & HCR_TGE) && (hcr & HCR_AMO);
48
+ tcg_gen_st_i32(p, cpu_env, offsetof(CPUARMState, pstate));
110
+ bool pending = enabled && (hcr & HCR_VSE);
49
+ tcg_temp_free_i32(p);
111
+ bool masked = (env->daif & PSTATE_A);
50
+}
112
+
51
+
113
+ /* If VSE pending and masked, defer the exception. */
52
+/* Clear bits within PSTATE. */
114
+ if (pending && masked) {
53
+static inline void clear_pstate_bits(uint32_t bits)
115
+ uint32_t syndrome;
54
+{
116
+
55
+ TCGv_i32 p = tcg_temp_new_i32();
117
+ if (arm_el_is_aa64(env, 1)) {
56
+
118
+ /* Copy across IDS and ISS from VSESR. */
57
+ tcg_debug_assert(!(bits & CACHED_PSTATE_BITS));
119
+ syndrome = env->cp15.vsesr_el2 & 0x1ffffff;
58
+
120
+ } else {
59
+ tcg_gen_ld_i32(p, cpu_env, offsetof(CPUARMState, pstate));
121
+ ARMMMUFaultInfo fi = { .type = ARMFault_AsyncExternal };
60
+ tcg_gen_andi_i32(p, p, ~bits);
122
+
61
+ tcg_gen_st_i32(p, cpu_env, offsetof(CPUARMState, pstate));
123
+ if (extended_addresses_enabled(env)) {
62
+ tcg_temp_free_i32(p);
124
+ syndrome = arm_fi_to_lfsc(&fi);
63
+}
125
+ } else {
64
+
126
+ syndrome = arm_fi_to_sfsc(&fi);
65
+/* If the singlestep state is Active-not-pending, advance to Active-pending. */
127
+ }
66
+static inline void gen_ss_advance(DisasContext *s)
128
+ /* Copy across AET and ExT from VSESR. */
67
+{
129
+ syndrome |= env->cp15.vsesr_el2 & 0xd000;
68
+ if (s->ss_active) {
130
+ }
69
+ s->pstate_ss = 0;
131
+
70
+ clear_pstate_bits(PSTATE_SS);
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);
71
+ }
138
+ }
72
+}
139
+}
73
74
/* Vector operations shared between ARM and AArch64. */
75
extern const GVecGen3 bsl_op;
76
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/op_helper.c
79
+++ b/target/arm/op_helper.c
80
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
81
return res;
82
}
83
84
-void HELPER(clear_pstate_ss)(CPUARMState *env)
85
-{
86
- env->pstate &= ~PSTATE_SS;
87
-}
88
-
89
void HELPER(pre_hvc)(CPUARMState *env)
90
{
91
ARMCPU *cpu = arm_env_get_cpu(env);
92
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
93
index XXXXXXX..XXXXXXX 100644
141
index XXXXXXX..XXXXXXX 100644
94
--- a/target/arm/translate-a64.c
142
--- a/target/arm/translate-a64.c
95
+++ b/target/arm/translate-a64.c
143
+++ b/target/arm/translate-a64.c
96
@@ -XXX,XX +XXX,XX @@ static void gen_exception_bkpt_insn(DisasContext *s, int offset,
144
@@ -XXX,XX +XXX,XX @@ static void handle_hint(DisasContext *s, uint32_t insn,
97
s->base.is_jmp = DISAS_NORETURN;
145
gen_helper_autib(cpu_X[17], cpu_env, cpu_X[17], cpu_X[16]);
98
}
146
}
99
147
break;
100
-static void gen_ss_advance(DisasContext *s)
148
+ case 0b10000: /* ESB */
101
-{
149
+ /* Without RAS, we must implement this as NOP. */
102
- /* If the singlestep state is Active-not-pending, advance to
150
+ if (dc_isar_feature(aa64_ras, s)) {
103
- * Active-pending.
151
+ /*
104
- */
152
+ * QEMU does not have a source of physical SErrors,
105
- if (s->ss_active) {
153
+ * so we are only concerned with virtual SErrors.
106
- s->pstate_ss = 0;
154
+ * The pseudocode in the ARM for this case is
107
- gen_helper_clear_pstate_ss(cpu_env);
155
+ * if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then
108
- }
156
+ * AArch64.vESBOperation();
109
-}
157
+ * Most of the condition can be evaluated at translation time.
110
-
158
+ * Test for EL2 present, and defer test for SEL2 to runtime.
111
static void gen_step_complete_exception(DisasContext *s)
159
+ */
112
{
160
+ if (s->current_el <= 1 && arm_dc_feature(s, ARM_FEATURE_EL2)) {
113
/* We just completed step of an insn. Move from Active-not-pending
161
+ gen_helper_vesb(cpu_env);
162
+ }
163
+ }
164
+ break;
165
case 0b11000: /* PACIAZ */
166
if (s->pauth_active) {
167
gen_helper_pacia(cpu_X[30], cpu_env, cpu_X[30],
114
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
115
index XXXXXXX..XXXXXXX 100644
169
index XXXXXXX..XXXXXXX 100644
116
--- a/target/arm/translate.c
170
--- a/target/arm/translate.c
117
+++ b/target/arm/translate.c
171
+++ b/target/arm/translate.c
118
@@ -XXX,XX +XXX,XX @@ static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
172
@@ -XXX,XX +XXX,XX @@ static bool trans_WFI(DisasContext *s, arg_WFI *a)
119
tcg_temp_free_i32(tcg_excp);
173
return true;
120
}
174
}
121
175
122
-static void gen_ss_advance(DisasContext *s)
176
+static bool trans_ESB(DisasContext *s, arg_ESB *a)
123
-{
177
+{
124
- /* If the singlestep state is Active-not-pending, advance to
178
+ /*
125
- * Active-pending.
179
+ * For M-profile, minimal-RAS ESB can be a NOP.
126
- */
180
+ * Without RAS, we must implement this as NOP.
127
- if (s->ss_active) {
181
+ */
128
- s->pstate_ss = 0;
182
+ if (!arm_dc_feature(s, ARM_FEATURE_M) && dc_isar_feature(aa32_ras, s)) {
129
- gen_helper_clear_pstate_ss(cpu_env);
183
+ /*
130
- }
184
+ * QEMU does not have a source of physical SErrors,
131
-}
185
+ * so we are only concerned with virtual SErrors.
132
-
186
+ * The pseudocode in the ARM for this case is
133
static void gen_step_complete_exception(DisasContext *s)
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)
134
{
200
{
135
/* We just completed step of an insn. Move from Active-not-pending
201
return true;
136
--
202
--
137
2.20.1
203
2.25.1
138
139
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
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
There is no branch prediction in TCG, therefore there is no
4
need to actually include the context number into the predictor.
5
Therefore all we need to do is add the state for SCXTNUM_ELx.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20190301200501.16533-4-richard.henderson@linaro.org
9
Message-id: 20220506180242.216785-21-richard.henderson@linaro.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
target/arm/cpu.h | 13 ++++++++++-
12
docs/system/arm/emulation.rst | 3 ++
9
target/arm/cpu.c | 1 +
13
target/arm/cpu.h | 16 +++++++++
10
target/arm/cpu64.c | 2 ++
14
target/arm/cpu.c | 5 +++
11
target/arm/helper.c | 55 +++++++++++++++++++++++++++++++++++++++++++++
15
target/arm/cpu64.c | 3 +-
12
4 files changed, 70 insertions(+), 1 deletion(-)
16
target/arm/helper.c | 61 ++++++++++++++++++++++++++++++++++-
17
5 files changed, 86 insertions(+), 2 deletions(-)
13
18
19
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
20
index XXXXXXX..XXXXXXX 100644
21
--- a/docs/system/arm/emulation.rst
22
+++ b/docs/system/arm/emulation.rst
23
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
24
- FEAT_BF16 (AArch64 BFloat16 instructions)
25
- FEAT_BTI (Branch Target Identification)
26
- FEAT_CSV2 (Cache speculation variant 2)
27
+- FEAT_CSV2_1p1 (Cache speculation variant 2, version 1.1)
28
+- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
29
+- FEAT_CSV2_2 (Cache speculation variant 2, version 2)
30
- FEAT_DIT (Data Independent Timing instructions)
31
- FEAT_DPB (DC CVAP instruction)
32
- FEAT_Debugv8p2 (Debug changes for v8.2)
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
33
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
35
--- a/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
36
+++ b/target/arm/cpu.h
37
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
38
ARMPACKey apdb;
39
ARMPACKey apga;
40
} keys;
41
+
42
+ uint64_t scxtnum_el[4];
43
#endif
44
45
#if defined(CONFIG_USER_ONLY)
18
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
46
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
19
#define SCTLR_R (1U << 9) /* up to v6; RAZ in v7 */
47
#define SCTLR_WXN (1U << 19)
20
#define SCTLR_UMA (1U << 9) /* v8 onward, AArch64 only */
48
#define SCTLR_ST (1U << 20) /* up to ??, RAZ in v6 */
21
#define SCTLR_F (1U << 10) /* up to v6 */
49
#define SCTLR_UWXN (1U << 20) /* v7 onward, AArch32 only */
22
-#define SCTLR_SW (1U << 10) /* v7, RES0 in v8 */
50
+#define SCTLR_TSCXT (1U << 20) /* FEAT_CSV2_1p2, AArch64 only */
23
+#define SCTLR_SW (1U << 10) /* v7 */
51
#define SCTLR_FI (1U << 21) /* up to v7, v8 RES0 */
24
+#define SCTLR_EnRCTX (1U << 10) /* in v8.0-PredInv */
52
#define SCTLR_IESB (1U << 21) /* v8.2-IESB, AArch64 only */
25
#define SCTLR_Z (1U << 11) /* in v7, RES1 in v8 */
53
#define SCTLR_U (1U << 22) /* up to v6, RAO in v7 */
26
#define SCTLR_EOS (1U << 11) /* v8.5-ExS */
54
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_dit(const ARMISARegisters *id)
27
#define SCTLR_I (1U << 12)
55
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0;
28
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_sb(const ARMISARegisters *id)
29
return FIELD_EX32(id->id_isar6, ID_ISAR6, SB) != 0;
30
}
56
}
31
57
32
+static inline bool isar_feature_aa32_predinv(const ARMISARegisters *id)
58
+static inline bool isar_feature_aa64_scxtnum(const ARMISARegisters *id)
33
+{
59
+{
34
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, SPECRES) != 0;
60
+ int key = FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, CSV2);
61
+ if (key >= 2) {
62
+ return true; /* FEAT_CSV2_2 */
63
+ }
64
+ if (key == 1) {
65
+ key = FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, CSV2_FRAC);
66
+ return key >= 2; /* FEAT_CSV2_1p2 */
67
+ }
68
+ return false;
35
+}
69
+}
36
+
70
+
37
static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
71
static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id)
38
{
72
{
39
/*
73
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SSBS) != 0;
40
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_sb(const ARMISARegisters *id)
41
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SB) != 0;
42
}
43
44
+static inline bool isar_feature_aa64_predinv(const ARMISARegisters *id)
45
+{
46
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SPECRES) != 0;
47
+}
48
+
49
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
50
{
51
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
52
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
74
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
53
index XXXXXXX..XXXXXXX 100644
75
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/cpu.c
76
--- a/target/arm/cpu.c
55
+++ b/target/arm/cpu.c
77
+++ b/target/arm/cpu.c
56
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
78
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
57
t = FIELD_DP32(t, ID_ISAR6, DP, 1);
79
*/
58
t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
80
env->cp15.gcr_el1 = 0x1ffff;
59
t = FIELD_DP32(t, ID_ISAR6, SB, 1);
81
}
60
+ t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
82
+ /*
61
cpu->isar.id_isar6 = t;
83
+ * Disable access to SCXTNUM_EL0 from CSV2_1p2.
62
84
+ * This is not yet exposed from the Linux kernel in any way.
63
t = cpu->id_mmfr4;
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)) {
64
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
90
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
65
index XXXXXXX..XXXXXXX 100644
91
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/cpu64.c
92
--- a/target/arm/cpu64.c
67
+++ b/target/arm/cpu64.c
93
+++ b/target/arm/cpu64.c
68
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
94
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
69
t = FIELD_DP64(t, ID_AA64ISAR1, GPA, 1);
95
t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
70
t = FIELD_DP64(t, ID_AA64ISAR1, GPI, 0);
96
t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); /* FEAT_SEL2 */
71
t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
97
t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
72
+ t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
98
- t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 1); /* FEAT_CSV2 */
73
cpu->isar.id_aa64isar1 = t;
99
+ t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 2); /* FEAT_CSV2_2 */
74
100
cpu->isar.id_aa64pfr0 = t;
75
t = cpu->isar.id_aa64pfr0;
101
102
t = cpu->isar.id_aa64pfr1;
76
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
103
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
77
u = FIELD_DP32(u, ID_ISAR6, DP, 1);
104
* we do for EL2 with the virtualization=on property.
78
u = FIELD_DP32(u, ID_ISAR6, FHM, 1);
105
*/
79
u = FIELD_DP32(u, ID_ISAR6, SB, 1);
106
t = FIELD_DP64(t, ID_AA64PFR1, MTE, 3); /* FEAT_MTE3 */
80
+ u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1);
107
+ t = FIELD_DP64(t, ID_AA64PFR1, CSV2_FRAC, 0); /* FEAT_CSV2_2 */
81
cpu->isar.id_isar6 = u;
108
cpu->isar.id_aa64pfr1 = t;
82
109
83
/*
110
t = cpu->isar.id_aa64mmfr0;
84
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
85
index XXXXXXX..XXXXXXX 100644
112
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/helper.c
113
--- a/target/arm/helper.c
87
+++ b/target/arm/helper.c
114
+++ b/target/arm/helper.c
88
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pauth_reginfo[] = {
115
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
116
if (cpu_isar_feature(aa64_mte, cpu)) {
117
valid_mask |= SCR_ATA;
118
}
119
+ if (cpu_isar_feature(aa64_scxtnum, cpu)) {
120
+ valid_mask |= SCR_ENSCXT;
121
+ }
122
} else {
123
valid_mask &= ~(SCR_RW | SCR_ST);
124
if (cpu_isar_feature(aa32_ras, cpu)) {
125
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
126
if (cpu_isar_feature(aa64_mte, cpu)) {
127
valid_mask |= HCR_ATA | HCR_DCT | HCR_TID5;
128
}
129
+ if (cpu_isar_feature(aa64_scxtnum, cpu)) {
130
+ valid_mask |= HCR_ENSCXT;
131
+ }
132
}
133
134
/* Clear RES0 bits. */
135
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
136
{ K(3, 0, 5, 6, 0), K(3, 4, 5, 6, 0), K(3, 5, 5, 6, 0),
137
"TFSR_EL1", "TFSR_EL2", "TFSR_EL12", isar_feature_aa64_mte },
138
139
+ { K(3, 0, 13, 0, 7), K(3, 4, 13, 0, 7), K(3, 5, 13, 0, 7),
140
+ "SCXTNUM_EL1", "SCXTNUM_EL2", "SCXTNUM_EL12",
141
+ isar_feature_aa64_scxtnum },
142
+
143
/* TODO: ARMv8.2-SPE -- PMSCR_EL2 */
144
/* TODO: ARMv8.4-Trace -- TRFCR_EL2 */
145
};
146
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_el0_cacheop_reginfo[] = {
147
},
89
};
148
};
90
#endif
149
91
150
-#endif
92
+static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
151
+static CPAccessResult access_scxtnum(CPUARMState *env, const ARMCPRegInfo *ri,
93
+ bool isread)
152
+ bool isread)
94
+{
153
+{
154
+ uint64_t hcr = arm_hcr_el2_eff(env);
95
+ int el = arm_current_el(env);
155
+ int el = arm_current_el(env);
96
+
156
+
97
+ if (el == 0) {
157
+ if (el == 0 && !((hcr & HCR_E2H) && (hcr & HCR_TGE))) {
98
+ uint64_t sctlr = arm_sctlr(env, el);
158
+ if (env->cp15.sctlr_el[1] & SCTLR_TSCXT) {
99
+ if (!(sctlr & SCTLR_EnRCTX)) {
159
+ if (hcr & HCR_TGE) {
160
+ return CP_ACCESS_TRAP_EL2;
161
+ }
100
+ return CP_ACCESS_TRAP;
162
+ return CP_ACCESS_TRAP;
101
+ }
163
+ }
102
+ } else if (el == 1) {
164
+ } else if (el < 2 && (env->cp15.sctlr_el[2] & SCTLR_TSCXT)) {
103
+ uint64_t hcr = arm_hcr_el2_eff(env);
165
+ return CP_ACCESS_TRAP_EL2;
104
+ if (hcr & HCR_NV) {
166
+ }
105
+ return CP_ACCESS_TRAP_EL2;
167
+ if (el < 2 && arm_is_el2_enabled(env) && !(hcr & HCR_ENSCXT)) {
106
+ }
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;
107
+ }
174
+ }
108
+ return CP_ACCESS_OK;
175
+ return CP_ACCESS_OK;
109
+}
176
+}
110
+
177
+
111
+static const ARMCPRegInfo predinv_reginfo[] = {
178
+static const ARMCPRegInfo scxtnum_reginfo[] = {
112
+ { .name = "CFP_RCTX", .state = ARM_CP_STATE_AA64,
179
+ { .name = "SCXTNUM_EL0", .state = ARM_CP_STATE_AA64,
113
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 4,
180
+ .opc0 = 3, .opc1 = 3, .crn = 13, .crm = 0, .opc2 = 7,
114
+ .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
181
+ .access = PL0_RW, .accessfn = access_scxtnum,
115
+ { .name = "DVP_RCTX", .state = ARM_CP_STATE_AA64,
182
+ .fieldoffset = offsetof(CPUARMState, scxtnum_el[0]) },
116
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 5,
183
+ { .name = "SCXTNUM_EL1", .state = ARM_CP_STATE_AA64,
117
+ .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
184
+ .opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 7,
118
+ { .name = "CPP_RCTX", .state = ARM_CP_STATE_AA64,
185
+ .access = PL1_RW, .accessfn = access_scxtnum,
119
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 7,
186
+ .fieldoffset = offsetof(CPUARMState, scxtnum_el[1]) },
120
+ .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
187
+ { .name = "SCXTNUM_EL2", .state = ARM_CP_STATE_AA64,
121
+ /*
188
+ .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 7,
122
+ * Note the AArch32 opcodes have a different OPC1.
189
+ .access = PL2_RW, .accessfn = access_scxtnum,
123
+ */
190
+ .fieldoffset = offsetof(CPUARMState, scxtnum_el[2]) },
124
+ { .name = "CFPRCTX", .state = ARM_CP_STATE_AA32,
191
+ { .name = "SCXTNUM_EL3", .state = ARM_CP_STATE_AA64,
125
+ .cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 4,
192
+ .opc0 = 3, .opc1 = 6, .crn = 13, .crm = 0, .opc2 = 7,
126
+ .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
193
+ .access = PL3_RW,
127
+ { .name = "DVPRCTX", .state = ARM_CP_STATE_AA32,
194
+ .fieldoffset = offsetof(CPUARMState, scxtnum_el[3]) },
128
+ .cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 5,
129
+ .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
130
+ { .name = "CPPRCTX", .state = ARM_CP_STATE_AA32,
131
+ .cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 7,
132
+ .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
133
+ REGINFO_SENTINEL
134
+};
195
+};
135
+
196
+#endif /* TARGET_AARCH64 */
136
void register_cp_regs_for_features(ARMCPU *cpu)
197
137
{
198
static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
138
/* Register all the coprocessor registers based on feature bits */
199
bool isread)
139
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
200
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
140
define_arm_cp_regs(cpu, pauth_reginfo);
201
define_arm_cp_regs(cpu, mte_tco_ro_reginfo);
202
define_arm_cp_regs(cpu, mte_el0_cacheop_reginfo);
141
}
203
}
204
+
205
+ if (cpu_isar_feature(aa64_scxtnum, cpu)) {
206
+ define_arm_cp_regs(cpu, scxtnum_reginfo);
207
+ }
142
#endif
208
#endif
143
+
209
144
+ /*
210
if (cpu_isar_feature(any_predinv, cpu)) {
145
+ * While all v8.0 cpus support aarch64, QEMU does have configurations
146
+ * that do not set ID_AA64ISAR1, e.g. user-only qemu-arm -cpu max,
147
+ * which will set ID_ISAR6.
148
+ */
149
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)
150
+ ? cpu_isar_feature(aa64_predinv, cpu)
151
+ : cpu_isar_feature(aa32_predinv, cpu)) {
152
+ define_arm_cp_regs(cpu, predinv_reginfo);
153
+ }
154
}
155
156
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
157
--
211
--
158
2.20.1
212
2.25.1
159
160
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Found by inspection: Rn is the base register against which the
3
This extension concerns cache speculation, which TCG does
4
load began; I is the register within the mask being processed.
4
not implement. Thus we can trivially enable this feature.
5
The exception return should of course be processed from the loaded PC.
6
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20220506180242.216785-22-richard.henderson@linaro.org
9
Message-id: 20190301202921.21209-1-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
target/arm/translate.c | 2 +-
11
docs/system/arm/emulation.rst | 1 +
13
1 file changed, 1 insertion(+), 1 deletion(-)
12
target/arm/cpu64.c | 1 +
13
target/arm/cpu_tcg.c | 1 +
14
3 files changed, 3 insertions(+)
14
15
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.c
18
--- a/docs/system/arm/emulation.rst
18
+++ b/target/arm/translate.c
19
+++ b/docs/system/arm/emulation.rst
19
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
20
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
20
} else if (i == rn) {
21
- FEAT_CSV2_1p1 (Cache speculation variant 2, version 1.1)
21
loaded_var = tmp;
22
- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
22
loaded_base = 1;
23
- FEAT_CSV2_2 (Cache speculation variant 2, version 2)
23
- } else if (rn == 15 && exc_return) {
24
+- FEAT_CSV3 (Cache speculation variant 3)
24
+ } else if (i == 15 && exc_return) {
25
- FEAT_DIT (Data Independent Timing instructions)
25
store_pc_exc_ret(s, tmp);
26
- FEAT_DPB (DC CVAP instruction)
26
} else {
27
- FEAT_Debugv8p2 (Debug changes for v8.2)
27
store_reg_from_load(s, i, tmp);
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
28
--
52
--
29
2.20.1
53
2.25.1
30
31
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
3
This extension concerns not merging memory access, which TCG does
4
not implement. Thus we can trivially enable this feature.
5
Add a comment to handle_hint for the DGH instruction, but no code.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190301200501.16533-11-richard.henderson@linaro.org
9
Message-id: 20220506180242.216785-23-richard.henderson@linaro.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
11
---
9
target/arm/cpu.h | 5 ++
12
docs/system/arm/emulation.rst | 1 +
10
target/arm/helper.h | 5 ++
13
target/arm/cpu64.c | 1 +
11
target/arm/cpu64.c | 1 +
14
target/arm/translate-a64.c | 1 +
12
target/arm/translate-a64.c | 71 ++++++++++++++++++++++++++--
15
3 files changed, 3 insertions(+)
13
target/arm/vfp_helper.c | 96 ++++++++++++++++++++++++++++++++++++++
14
5 files changed, 173 insertions(+), 5 deletions(-)
15
16
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
--- a/docs/system/arm/emulation.rst
19
+++ b/target/arm/cpu.h
20
+++ b/docs/system/arm/emulation.rst
20
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_predinv(const ARMISARegisters *id)
21
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
21
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SPECRES) != 0;
22
- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
22
}
23
- FEAT_CSV2_2 (Cache speculation variant 2, version 2)
23
24
- FEAT_CSV3 (Cache speculation variant 3)
24
+static inline bool isar_feature_aa64_frint(const ARMISARegisters *id)
25
+- FEAT_DGH (Data gathering hint)
25
+{
26
- FEAT_DIT (Data Independent Timing instructions)
26
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FRINTTS) != 0;
27
- FEAT_DPB (DC CVAP instruction)
27
+}
28
- FEAT_Debugv8p2 (Debug changes for v8.2)
28
+
29
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
30
{
31
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
32
diff --git a/target/arm/helper.h b/target/arm/helper.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/helper.h
35
+++ b/target/arm/helper.h
36
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_fmlal_idx_a32, TCG_CALL_NO_RWG,
37
DEF_HELPER_FLAGS_5(gvec_fmlal_idx_a64, TCG_CALL_NO_RWG,
38
void, ptr, ptr, ptr, ptr, i32)
39
40
+DEF_HELPER_FLAGS_2(frint32_s, TCG_CALL_NO_RWG, f32, f32, ptr)
41
+DEF_HELPER_FLAGS_2(frint64_s, TCG_CALL_NO_RWG, f32, f32, ptr)
42
+DEF_HELPER_FLAGS_2(frint32_d, TCG_CALL_NO_RWG, f64, f64, ptr)
43
+DEF_HELPER_FLAGS_2(frint64_d, TCG_CALL_NO_RWG, f64, f64, ptr)
44
+
45
#ifdef TARGET_AARCH64
46
#include "helper-a64.h"
47
#include "helper-sve.h"
48
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
29
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
49
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/cpu64.c
31
--- a/target/arm/cpu64.c
51
+++ b/target/arm/cpu64.c
32
+++ b/target/arm/cpu64.c
52
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
33
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
53
t = FIELD_DP64(t, ID_AA64ISAR1, GPI, 0);
34
t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1); /* FEAT_SB */
54
t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
35
t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1); /* FEAT_SPECRES */
55
t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
36
t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 1); /* FEAT_BF16 */
56
+ t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1);
37
+ t = FIELD_DP64(t, ID_AA64ISAR1, DGH, 1); /* FEAT_DGH */
57
cpu->isar.id_aa64isar1 = t;
38
t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1); /* FEAT_I8MM */
58
39
cpu->isar.id_aa64isar1 = t;
59
t = cpu->isar.id_aa64pfr0;
40
60
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
41
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
61
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/translate-a64.c
43
--- a/target/arm/translate-a64.c
63
+++ b/target/arm/translate-a64.c
44
+++ b/target/arm/translate-a64.c
64
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
45
@@ -XXX,XX +XXX,XX @@ static void handle_hint(DisasContext *s, uint32_t insn,
65
case 0xf: /* FRINTI */
66
gen_fpst = gen_helper_rints;
67
break;
46
break;
68
+ case 0x10: /* FRINT32Z */
47
case 0b00100: /* SEV */
69
+ rmode = float_round_to_zero;
48
case 0b00101: /* SEVL */
70
+ gen_fpst = gen_helper_frint32_s;
49
+ case 0b00110: /* DGH */
71
+ break;
50
/* we treat all as NOP at least for now */
72
+ case 0x11: /* FRINT32X */
73
+ gen_fpst = gen_helper_frint32_s;
74
+ break;
75
+ case 0x12: /* FRINT64Z */
76
+ rmode = float_round_to_zero;
77
+ gen_fpst = gen_helper_frint64_s;
78
+ break;
79
+ case 0x13: /* FRINT64X */
80
+ gen_fpst = gen_helper_frint64_s;
81
+ break;
82
default:
83
g_assert_not_reached();
84
}
85
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn)
86
case 0xf: /* FRINTI */
87
gen_fpst = gen_helper_rintd;
88
break;
51
break;
89
+ case 0x10: /* FRINT32Z */
52
case 0b00111: /* XPACLRI */
90
+ rmode = float_round_to_zero;
91
+ gen_fpst = gen_helper_frint32_d;
92
+ break;
93
+ case 0x11: /* FRINT32X */
94
+ gen_fpst = gen_helper_frint32_d;
95
+ break;
96
+ case 0x12: /* FRINT64Z */
97
+ rmode = float_round_to_zero;
98
+ gen_fpst = gen_helper_frint64_d;
99
+ break;
100
+ case 0x13: /* FRINT64X */
101
+ gen_fpst = gen_helper_frint64_d;
102
+ break;
103
default:
104
g_assert_not_reached();
105
}
106
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
107
handle_fp_fcvt(s, opcode, rd, rn, dtype, type);
108
break;
109
}
110
+
111
+ case 0x10 ... 0x13: /* FRINT{32,64}{X,Z} */
112
+ if (type > 1 || !dc_isar_feature(aa64_frint, s)) {
113
+ unallocated_encoding(s);
114
+ return;
115
+ }
116
+ /* fall through */
117
case 0x0 ... 0x3:
118
case 0x8 ... 0xc:
119
case 0xe ... 0xf:
120
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
121
if (!fp_access_check(s)) {
122
return;
123
}
124
-
125
handle_fp_1src_single(s, opcode, rd, rn);
126
break;
127
case 1:
128
if (!fp_access_check(s)) {
129
return;
130
}
131
-
132
handle_fp_1src_double(s, opcode, rd, rn);
133
break;
134
case 3:
135
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
136
if (!fp_access_check(s)) {
137
return;
138
}
139
-
140
handle_fp_1src_half(s, opcode, rd, rn);
141
break;
142
default:
143
unallocated_encoding(s);
144
}
145
break;
146
+
147
default:
148
unallocated_encoding(s);
149
break;
150
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u,
151
case 0x59: /* FRINTX */
152
gen_helper_rintd_exact(tcg_rd, tcg_rn, tcg_fpstatus);
153
break;
154
+ case 0x1e: /* FRINT32Z */
155
+ case 0x5e: /* FRINT32X */
156
+ gen_helper_frint32_d(tcg_rd, tcg_rn, tcg_fpstatus);
157
+ break;
158
+ case 0x1f: /* FRINT64Z */
159
+ case 0x5f: /* FRINT64X */
160
+ gen_helper_frint64_d(tcg_rd, tcg_rn, tcg_fpstatus);
161
+ break;
162
default:
163
g_assert_not_reached();
164
}
165
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
166
}
167
break;
168
case 0xc ... 0xf:
169
- case 0x16 ... 0x1d:
170
- case 0x1f:
171
+ case 0x16 ... 0x1f:
172
{
173
/* Floating point: U, size[1] and opcode indicate operation;
174
* size[0] indicates single or double precision.
175
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
176
}
177
need_fpstatus = true;
178
break;
179
+ case 0x1e: /* FRINT32Z */
180
+ case 0x1f: /* FRINT64Z */
181
+ need_rmode = true;
182
+ rmode = FPROUNDING_ZERO;
183
+ /* fall through */
184
+ case 0x5e: /* FRINT32X */
185
+ case 0x5f: /* FRINT64X */
186
+ need_fpstatus = true;
187
+ if ((size == 3 && !is_q) || !dc_isar_feature(aa64_frint, s)) {
188
+ unallocated_encoding(s);
189
+ return;
190
+ }
191
+ break;
192
default:
193
unallocated_encoding(s);
194
return;
195
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
196
case 0x7c: /* URSQRTE */
197
gen_helper_rsqrte_u32(tcg_res, tcg_op, tcg_fpstatus);
198
break;
199
+ case 0x1e: /* FRINT32Z */
200
+ case 0x5e: /* FRINT32X */
201
+ gen_helper_frint32_s(tcg_res, tcg_op, tcg_fpstatus);
202
+ break;
203
+ case 0x1f: /* FRINT64Z */
204
+ case 0x5f: /* FRINT64X */
205
+ gen_helper_frint64_s(tcg_res, tcg_op, tcg_fpstatus);
206
+ break;
207
default:
208
g_assert_not_reached();
209
}
210
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
211
index XXXXXXX..XXXXXXX 100644
212
--- a/target/arm/vfp_helper.c
213
+++ b/target/arm/vfp_helper.c
214
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(vjcvt)(float64 value, CPUARMState *env)
215
216
return result;
217
}
218
+
219
+/* Round a float32 to an integer that fits in int32_t or int64_t. */
220
+static float32 frint_s(float32 f, float_status *fpst, int intsize)
221
+{
222
+ int old_flags = get_float_exception_flags(fpst);
223
+ uint32_t exp = extract32(f, 23, 8);
224
+
225
+ if (unlikely(exp == 0xff)) {
226
+ /* NaN or Inf. */
227
+ goto overflow;
228
+ }
229
+
230
+ /* Round and re-extract the exponent. */
231
+ f = float32_round_to_int(f, fpst);
232
+ exp = extract32(f, 23, 8);
233
+
234
+ /* Validate the range of the result. */
235
+ if (exp < 126 + intsize) {
236
+ /* abs(F) <= INT{N}_MAX */
237
+ return f;
238
+ }
239
+ if (exp == 126 + intsize) {
240
+ uint32_t sign = extract32(f, 31, 1);
241
+ uint32_t frac = extract32(f, 0, 23);
242
+ if (sign && frac == 0) {
243
+ /* F == INT{N}_MIN */
244
+ return f;
245
+ }
246
+ }
247
+
248
+ overflow:
249
+ /*
250
+ * Raise Invalid and return INT{N}_MIN as a float. Revert any
251
+ * inexact exception float32_round_to_int may have raised.
252
+ */
253
+ set_float_exception_flags(old_flags | float_flag_invalid, fpst);
254
+ return (0x100u + 126u + intsize) << 23;
255
+}
256
+
257
+float32 HELPER(frint32_s)(float32 f, void *fpst)
258
+{
259
+ return frint_s(f, fpst, 32);
260
+}
261
+
262
+float32 HELPER(frint64_s)(float32 f, void *fpst)
263
+{
264
+ return frint_s(f, fpst, 64);
265
+}
266
+
267
+/* Round a float64 to an integer that fits in int32_t or int64_t. */
268
+static float64 frint_d(float64 f, float_status *fpst, int intsize)
269
+{
270
+ int old_flags = get_float_exception_flags(fpst);
271
+ uint32_t exp = extract64(f, 52, 11);
272
+
273
+ if (unlikely(exp == 0x7ff)) {
274
+ /* NaN or Inf. */
275
+ goto overflow;
276
+ }
277
+
278
+ /* Round and re-extract the exponent. */
279
+ f = float64_round_to_int(f, fpst);
280
+ exp = extract64(f, 52, 11);
281
+
282
+ /* Validate the range of the result. */
283
+ if (exp < 1022 + intsize) {
284
+ /* abs(F) <= INT{N}_MAX */
285
+ return f;
286
+ }
287
+ if (exp == 1022 + intsize) {
288
+ uint64_t sign = extract64(f, 63, 1);
289
+ uint64_t frac = extract64(f, 0, 52);
290
+ if (sign && frac == 0) {
291
+ /* F == INT{N}_MIN */
292
+ return f;
293
+ }
294
+ }
295
+
296
+ overflow:
297
+ /*
298
+ * Raise Invalid and return INT{N}_MIN as a float. Revert any
299
+ * inexact exception float64_round_to_int may have raised.
300
+ */
301
+ set_float_exception_flags(old_flags | float_flag_invalid, fpst);
302
+ return (uint64_t)(0x800 + 1022 + intsize) << 52;
303
+}
304
+
305
+float64 HELPER(frint32_d)(float64 f, void *fpst)
306
+{
307
+ return frint_d(f, fpst, 32);
308
+}
309
+
310
+float64 HELPER(frint64_d)(float64 f, void *fpst)
311
+{
312
+ return frint_d(f, fpst, 64);
313
+}
314
--
53
--
315
2.20.1
54
2.25.1
316
317
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This patch implements the machine class kvm_type() callback.
3
Enable the a76 for virt and sbsa board use.
4
It returns the number of bits requested to implement the whole GPA
5
range including the RAM and IO regions located beyond.
6
The returned value is passed though the KVM_CREATE_VM ioctl and
7
this allows KVM to set the stage2 tables dynamically.
8
4
9
To compute the highest GPA used in the memory map, kvm_type()
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
must freeze the memory map by calling virt_set_memmap().
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
7
Message-id: 20220506180242.216785-24-richard.henderson@linaro.org
12
Signed-off-by: Eric Auger <eric.auger@redhat.com>
13
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
14
Message-id: 20190304101339.25970-9-eric.auger@redhat.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
9
---
17
hw/arm/virt.c | 39 ++++++++++++++++++++++++++++++++++++++-
10
docs/system/arm/virt.rst | 1 +
18
1 file changed, 38 insertions(+), 1 deletion(-)
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
16
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
17
index XXXXXXX..XXXXXXX 100644
18
--- a/docs/system/arm/virt.rst
19
+++ b/docs/system/arm/virt.rst
20
@@ -XXX,XX +XXX,XX @@ Supported guest CPU types:
21
- ``cortex-a53`` (64-bit)
22
- ``cortex-a57`` (64-bit)
23
- ``cortex-a72`` (64-bit)
24
+- ``cortex-a76`` (64-bit)
25
- ``a64fx`` (64-bit)
26
- ``host`` (with KVM only)
27
- ``max`` (same as ``host`` for KVM; best possible emulation with TCG)
28
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/sbsa-ref.c
31
+++ b/hw/arm/sbsa-ref.c
32
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
33
static const char * const valid_cpus[] = {
34
ARM_CPU_TYPE_NAME("cortex-a57"),
35
ARM_CPU_TYPE_NAME("cortex-a72"),
36
+ ARM_CPU_TYPE_NAME("cortex-a76"),
37
ARM_CPU_TYPE_NAME("max"),
38
};
39
20
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
40
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
21
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/virt.c
42
--- a/hw/arm/virt.c
23
+++ b/hw/arm/virt.c
43
+++ b/hw/arm/virt.c
24
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
44
@@ -XXX,XX +XXX,XX @@ static const char *valid_cpus[] = {
25
bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
45
ARM_CPU_TYPE_NAME("cortex-a53"),
26
bool aarch64 = true;
46
ARM_CPU_TYPE_NAME("cortex-a57"),
27
47
ARM_CPU_TYPE_NAME("cortex-a72"),
28
- virt_set_memmap(vms);
48
+ ARM_CPU_TYPE_NAME("cortex-a76"),
29
+ /*
49
ARM_CPU_TYPE_NAME("a64fx"),
30
+ * In accelerated mode, the memory map is computed earlier in kvm_type()
50
ARM_CPU_TYPE_NAME("host"),
31
+ * to create a VM with the right number of IPA bits.
51
ARM_CPU_TYPE_NAME("max"),
32
+ */
52
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
33
+ if (!vms->memmap) {
53
index XXXXXXX..XXXXXXX 100644
34
+ virt_set_memmap(vms);
54
--- a/target/arm/cpu64.c
35
+ }
55
+++ b/target/arm/cpu64.c
36
56
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
37
/* We can probe only here because during property set
57
define_cortex_a72_a57_a53_cp_reginfo(cpu);
38
* KVM is not available yet
39
@@ -XXX,XX +XXX,XX @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
40
return NULL;
41
}
58
}
42
59
43
+/*
60
+static void aarch64_a76_initfn(Object *obj)
44
+ * for arm64 kvm_type [7-0] encodes the requested number of bits
45
+ * in the IPA address space
46
+ */
47
+static int virt_kvm_type(MachineState *ms, const char *type_str)
48
+{
61
+{
49
+ VirtMachineState *vms = VIRT_MACHINE(ms);
62
+ ARMCPU *cpu = ARM_CPU(obj);
50
+ int max_vm_pa_size = kvm_arm_get_max_vm_ipa_size(ms);
51
+ int requested_pa_size;
52
+
63
+
53
+ /* we freeze the memory map to compute the highest gpa */
64
+ cpu->dtb_compatible = "arm,cortex-a76";
54
+ virt_set_memmap(vms);
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);
55
+
73
+
56
+ requested_pa_size = 64 - clz64(vms->highest_gpa);
74
+ /* Ordered by B2.4 AArch64 registers by functional group */
75
+ cpu->clidr = 0x82000023;
76
+ cpu->ctr = 0x8444C004;
77
+ cpu->dcz_blocksize = 4;
78
+ cpu->isar.id_aa64dfr0 = 0x0000000010305408ull;
79
+ cpu->isar.id_aa64isar0 = 0x0000100010211120ull;
80
+ cpu->isar.id_aa64isar1 = 0x0000000000100001ull;
81
+ cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull;
82
+ cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
83
+ cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull;
84
+ cpu->isar.id_aa64pfr0 = 0x1100000010111112ull; /* GIC filled in later */
85
+ cpu->isar.id_aa64pfr1 = 0x0000000000000010ull;
86
+ cpu->id_afr0 = 0x00000000;
87
+ cpu->isar.id_dfr0 = 0x04010088;
88
+ cpu->isar.id_isar0 = 0x02101110;
89
+ cpu->isar.id_isar1 = 0x13112111;
90
+ cpu->isar.id_isar2 = 0x21232042;
91
+ cpu->isar.id_isar3 = 0x01112131;
92
+ cpu->isar.id_isar4 = 0x00010142;
93
+ cpu->isar.id_isar5 = 0x01011121;
94
+ cpu->isar.id_isar6 = 0x00000010;
95
+ cpu->isar.id_mmfr0 = 0x10201105;
96
+ cpu->isar.id_mmfr1 = 0x40000000;
97
+ cpu->isar.id_mmfr2 = 0x01260000;
98
+ cpu->isar.id_mmfr3 = 0x02122211;
99
+ cpu->isar.id_mmfr4 = 0x00021110;
100
+ cpu->isar.id_pfr0 = 0x10010131;
101
+ cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */
102
+ cpu->isar.id_pfr2 = 0x00000011;
103
+ cpu->midr = 0x414fd0b1; /* r4p1 */
104
+ cpu->revidr = 0;
57
+
105
+
58
+ if (requested_pa_size > max_vm_pa_size) {
106
+ /* From B2.18 CCSIDR_EL1 */
59
+ error_report("-m and ,maxmem option values "
107
+ cpu->ccsidr[0] = 0x701fe01a; /* 64KB L1 dcache */
60
+ "require an IPA range (%d bits) larger than "
108
+ cpu->ccsidr[1] = 0x201fe01a; /* 64KB L1 icache */
61
+ "the one supported by the host (%d bits)",
109
+ cpu->ccsidr[2] = 0x707fe03a; /* 512KB L2 cache */
62
+ requested_pa_size, max_vm_pa_size);
110
+
63
+ exit(1);
111
+ /* From B2.93 SCTLR_EL3 */
64
+ }
112
+ cpu->reset_sctlr = 0x30c50838;
65
+ /*
113
+
66
+ * By default we return 0 which corresponds to an implicit legacy
114
+ /* From B4.23 ICH_VTR_EL2 */
67
+ * 40b IPA setting. Otherwise we return the actual requested PA
115
+ cpu->gic_num_lrs = 4;
68
+ * logsize
116
+ cpu->gic_vpribits = 5;
69
+ */
117
+ cpu->gic_vprebits = 5;
70
+ return requested_pa_size > 40 ? requested_pa_size : 0;
118
+
119
+ /* From B5.1 AdvSIMD AArch64 register summary */
120
+ cpu->isar.mvfr0 = 0x10110222;
121
+ cpu->isar.mvfr1 = 0x13211111;
122
+ cpu->isar.mvfr2 = 0x00000043;
71
+}
123
+}
72
+
124
+
73
static void virt_machine_class_init(ObjectClass *oc, void *data)
125
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
74
{
126
{
75
MachineClass *mc = MACHINE_CLASS(oc);
127
/*
76
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
128
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo aarch64_cpus[] = {
77
mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
129
{ .name = "cortex-a57", .initfn = aarch64_a57_initfn },
78
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
130
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
79
mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
131
{ .name = "cortex-a72", .initfn = aarch64_a72_initfn },
80
+ mc->kvm_type = virt_kvm_type;
132
+ { .name = "cortex-a76", .initfn = aarch64_a76_initfn },
81
assert(!mc->get_hotplug_handler);
133
{ .name = "a64fx", .initfn = aarch64_a64fx_initfn },
82
mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
134
{ .name = "max", .initfn = aarch64_max_initfn },
83
hc->plug = virt_machine_device_plug_cb;
135
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
84
--
136
--
85
2.20.1
137
2.25.1
86
87
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
In the prospect to introduce an extended memory map supporting more
3
Enable the n1 for virt and sbsa board use.
4
RAM, let's split the memory map array into two parts:
5
4
6
- the former a15memmap, renamed base_memmap, contains regions below
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
and including the RAM. MemMapEntries initialized in this array
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
have a static size and base address.
7
Message-id: 20220506180242.216785-25-richard.henderson@linaro.org
9
- extended_memmap, only initialized with entries located after the
10
RAM. MemMapEntries initialized in this array only get their size
11
initialized. Their base address is dynamically computed depending
12
on the the top of the RAM, with same alignment as their size.
13
14
Eventually base_memmap entries are copied into the extended_memmap
15
array. Using two separate arrays however clarifies which entries
16
are statically allocated and those which are dynamically allocated.
17
18
This new split will allow to grow the RAM size without changing the
19
description of the high IO entries.
20
21
We introduce a new virt_set_memmap() helper function which
22
"freezes" the memory map. We call it in machvirt_init as
23
memory attributes of the machine are not yet set when
24
virt_instance_init() gets called.
25
26
The memory map is unchanged (the top of the initial RAM still is
27
256GiB). Then come the high IO regions with same layout as before.
28
29
Signed-off-by: Eric Auger <eric.auger@redhat.com>
30
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
31
Message-id: 20190304101339.25970-4-eric.auger@redhat.com
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
---
9
---
34
include/hw/arm/virt.h | 13 +++++++----
10
docs/system/arm/virt.rst | 1 +
35
hw/arm/virt.c | 50 +++++++++++++++++++++++++++++++++++++------
11
hw/arm/sbsa-ref.c | 1 +
36
2 files changed, 53 insertions(+), 10 deletions(-)
12
hw/arm/virt.c | 1 +
13
target/arm/cpu64.c | 66 ++++++++++++++++++++++++++++++++++++++++
14
4 files changed, 69 insertions(+)
37
15
38
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
16
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
39
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
40
--- a/include/hw/arm/virt.h
18
--- a/docs/system/arm/virt.rst
41
+++ b/include/hw/arm/virt.h
19
+++ b/docs/system/arm/virt.rst
42
@@ -XXX,XX +XXX,XX @@ enum {
20
@@ -XXX,XX +XXX,XX @@ Supported guest CPU types:
43
VIRT_GIC_VCPU,
21
- ``cortex-a76`` (64-bit)
44
VIRT_GIC_ITS,
22
- ``a64fx`` (64-bit)
45
VIRT_GIC_REDIST,
23
- ``host`` (with KVM only)
46
- VIRT_HIGH_GIC_REDIST2,
24
+- ``neoverse-n1`` (64-bit)
47
VIRT_SMMU,
25
- ``max`` (same as ``host`` for KVM; best possible emulation with TCG)
48
VIRT_UART,
26
49
VIRT_MMIO,
27
Note that the default is ``cortex-a15``, so for an AArch64 guest you must
50
@@ -XXX,XX +XXX,XX @@ enum {
28
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
51
VIRT_PCIE_MMIO,
29
index XXXXXXX..XXXXXXX 100644
52
VIRT_PCIE_PIO,
30
--- a/hw/arm/sbsa-ref.c
53
VIRT_PCIE_ECAM,
31
+++ b/hw/arm/sbsa-ref.c
54
- VIRT_HIGH_PCIE_ECAM,
32
@@ -XXX,XX +XXX,XX @@ static const char * const valid_cpus[] = {
55
VIRT_PLATFORM_BUS,
33
ARM_CPU_TYPE_NAME("cortex-a57"),
56
- VIRT_HIGH_PCIE_MMIO,
34
ARM_CPU_TYPE_NAME("cortex-a72"),
57
VIRT_GPIO,
35
ARM_CPU_TYPE_NAME("cortex-a76"),
58
VIRT_SECURE_UART,
36
+ ARM_CPU_TYPE_NAME("neoverse-n1"),
59
VIRT_SECURE_MEM,
37
ARM_CPU_TYPE_NAME("max"),
60
+ VIRT_LOWMEMMAP_LAST,
61
+};
62
+
63
+/* indices of IO regions located after the RAM */
64
+enum {
65
+ VIRT_HIGH_GIC_REDIST2 = VIRT_LOWMEMMAP_LAST,
66
+ VIRT_HIGH_PCIE_ECAM,
67
+ VIRT_HIGH_PCIE_MMIO,
68
};
38
};
69
39
70
typedef enum VirtIOMMUType {
71
@@ -XXX,XX +XXX,XX @@ typedef struct {
72
int32_t gic_version;
73
VirtIOMMUType iommu;
74
struct arm_boot_info bootinfo;
75
- const MemMapEntry *memmap;
76
+ MemMapEntry *memmap;
77
const int *irqmap;
78
int smp_cpus;
79
void *fdt;
80
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
40
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
81
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
82
--- a/hw/arm/virt.c
42
--- a/hw/arm/virt.c
83
+++ b/hw/arm/virt.c
43
+++ b/hw/arm/virt.c
84
@@ -XXX,XX +XXX,XX @@
44
@@ -XXX,XX +XXX,XX @@ static const char *valid_cpus[] = {
85
*/
45
ARM_CPU_TYPE_NAME("cortex-a72"),
86
46
ARM_CPU_TYPE_NAME("cortex-a76"),
87
#include "qemu/osdep.h"
47
ARM_CPU_TYPE_NAME("a64fx"),
88
+#include "qemu/units.h"
48
+ ARM_CPU_TYPE_NAME("neoverse-n1"),
89
#include "qapi/error.h"
49
ARM_CPU_TYPE_NAME("host"),
90
#include "hw/sysbus.h"
50
ARM_CPU_TYPE_NAME("max"),
91
#include "hw/arm/arm.h"
51
};
92
@@ -XXX,XX +XXX,XX @@
52
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
93
* Note that devices should generally be placed at multiples of 0x10000,
53
index XXXXXXX..XXXXXXX 100644
94
* to accommodate guests using 64K pages.
54
--- a/target/arm/cpu64.c
95
*/
55
+++ b/target/arm/cpu64.c
96
-static const MemMapEntry a15memmap[] = {
56
@@ -XXX,XX +XXX,XX @@ static void aarch64_a76_initfn(Object *obj)
97
+static const MemMapEntry base_memmap[] = {
57
cpu->isar.mvfr2 = 0x00000043;
98
/* Space up to 0x8000000 is reserved for a boot ROM */
58
}
99
[VIRT_FLASH] = { 0, 0x08000000 },
59
100
[VIRT_CPUPERIPHS] = { 0x08000000, 0x00020000 },
60
+static void aarch64_neoverse_n1_initfn(Object *obj)
101
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry a15memmap[] = {
61
+{
102
[VIRT_PCIE_PIO] = { 0x3eff0000, 0x00010000 },
62
+ ARMCPU *cpu = ARM_CPU(obj);
103
[VIRT_PCIE_ECAM] = { 0x3f000000, 0x01000000 },
104
[VIRT_MEM] = { 0x40000000, RAMLIMIT_BYTES },
105
+};
106
+
63
+
107
+/*
64
+ cpu->dtb_compatible = "arm,neoverse-n1";
108
+ * Highmem IO Regions: This memory map is floating, located after the RAM.
65
+ set_feature(&cpu->env, ARM_FEATURE_V8);
109
+ * Each MemMapEntry base (GPA) will be dynamically computed, depending on the
66
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
110
+ * top of the RAM, so that its base get the same alignment as the size,
67
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
111
+ * ie. a 512GiB entry will be aligned on a 512GiB boundary. If there is
68
+ set_feature(&cpu->env, ARM_FEATURE_AARCH64);
112
+ * less than 256GiB of RAM, the floating area starts at the 256GiB mark.
69
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
113
+ * Note the extended_memmap is sized so that it eventually also includes the
70
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
114
+ * base_memmap entries (VIRT_HIGH_GIC_REDIST2 index is greater than the last
71
+ set_feature(&cpu->env, ARM_FEATURE_EL3);
115
+ * index of base_memmap).
72
+ set_feature(&cpu->env, ARM_FEATURE_PMU);
116
+ */
117
+static MemMapEntry extended_memmap[] = {
118
/* Additional 64 MB redist region (can contain up to 512 redistributors) */
119
- [VIRT_HIGH_GIC_REDIST2] = { 0x4000000000ULL, 0x4000000 },
120
- [VIRT_HIGH_PCIE_ECAM] = { 0x4010000000ULL, 0x10000000 },
121
- /* Second PCIe window, 512GB wide at the 512GB boundary */
122
- [VIRT_HIGH_PCIE_MMIO] = { 0x8000000000ULL, 0x8000000000ULL },
123
+ [VIRT_HIGH_GIC_REDIST2] = { 0x0, 64 * MiB },
124
+ [VIRT_HIGH_PCIE_ECAM] = { 0x0, 256 * MiB },
125
+ /* Second PCIe window */
126
+ [VIRT_HIGH_PCIE_MMIO] = { 0x0, 512 * GiB },
127
};
128
129
static const int a15irqmap[] = {
130
@@ -XXX,XX +XXX,XX @@ static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx)
131
return arm_cpu_mp_affinity(idx, clustersz);
132
}
133
134
+static void virt_set_memmap(VirtMachineState *vms)
135
+{
136
+ hwaddr base;
137
+ int i;
138
+
73
+
139
+ vms->memmap = extended_memmap;
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;
140
+
105
+
141
+ for (i = 0; i < ARRAY_SIZE(base_memmap); i++) {
106
+ /* From B2.23 CCSIDR_EL1 */
142
+ vms->memmap[i] = base_memmap[i];
107
+ cpu->ccsidr[0] = 0x701fe01a; /* 64KB L1 dcache */
143
+ }
108
+ cpu->ccsidr[1] = 0x201fe01a; /* 64KB L1 icache */
109
+ cpu->ccsidr[2] = 0x70ffe03a; /* 1MB L2 cache */
144
+
110
+
145
+ base = 256 * GiB; /* Top of the legacy initial RAM region */
111
+ /* From B2.98 SCTLR_EL3 */
112
+ cpu->reset_sctlr = 0x30c50838;
146
+
113
+
147
+ for (i = VIRT_LOWMEMMAP_LAST; i < ARRAY_SIZE(extended_memmap); i++) {
114
+ /* From B4.23 ICH_VTR_EL2 */
148
+ hwaddr size = extended_memmap[i].size;
115
+ cpu->gic_num_lrs = 4;
116
+ cpu->gic_vpribits = 5;
117
+ cpu->gic_vprebits = 5;
149
+
118
+
150
+ base = ROUND_UP(base, size);
119
+ /* From B5.1 AdvSIMD AArch64 register summary */
151
+ vms->memmap[i].base = base;
120
+ cpu->isar.mvfr0 = 0x10110222;
152
+ vms->memmap[i].size = size;
121
+ cpu->isar.mvfr1 = 0x13211111;
153
+ base += size;
122
+ cpu->isar.mvfr2 = 0x00000043;
154
+ }
155
+}
123
+}
156
+
124
+
157
static void machvirt_init(MachineState *machine)
125
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
158
{
126
{
159
VirtMachineState *vms = VIRT_MACHINE(machine);
127
/*
160
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
128
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo aarch64_cpus[] = {
161
bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
129
{ .name = "cortex-a72", .initfn = aarch64_a72_initfn },
162
bool aarch64 = true;
130
{ .name = "cortex-a76", .initfn = aarch64_a76_initfn },
163
131
{ .name = "a64fx", .initfn = aarch64_a64fx_initfn },
164
+ virt_set_memmap(vms);
132
+ { .name = "neoverse-n1", .initfn = aarch64_neoverse_n1_initfn },
165
+
133
{ .name = "max", .initfn = aarch64_max_initfn },
166
/* We can probe only here because during property set
134
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
167
* KVM is not available yet
135
{ .name = "host", .initfn = aarch64_host_initfn },
168
*/
169
@@ -XXX,XX +XXX,XX @@ static void virt_instance_init(Object *obj)
170
"Valid values are none and smmuv3",
171
NULL);
172
173
- vms->memmap = a15memmap;
174
vms->irqmap = a15irqmap;
175
}
176
177
--
136
--
178
2.20.1
137
2.25.1
179
180
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
2
3
The machine RAM attributes will need to be analyzed during the
3
The sbsa-ref machine is continuously evolving. Some of the changes we
4
configure_accelerator() process. especially kvm_type() arm64
4
want to make in the near future, to align with real components (e.g.
5
machine callback will use them to know how many IPA/GPA bits are
5
the GIC-700), will break compatibility for existing firmware.
6
needed to model the whole RAM range. So let's assign those machine
7
state fields before calling configure_accelerator.
8
6
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
7
Introduce two new properties to the DT generated on machine generation:
8
- machine-version-major
9
To be incremented when a platform change makes the machine
10
incompatible with existing firmware.
11
- machine-version-minor
12
To be incremented when functionality is added to the machine
13
without causing incompatibility with existing firmware.
14
to be reset to 0 when machine-version-major is incremented.
15
16
This versioning scheme is *neither*:
17
- A QEMU versioned machine type; a given version of QEMU will emulate
18
a given version of the platform.
19
- A reflection of level of SBSA (now SystemReady SR) support provided.
20
21
The version will increment on guest-visible functional changes only,
22
akin to a revision ID register found on a physical platform.
23
24
These properties are both introduced with the value 0.
25
(Hence, a machine where the DT is lacking these nodes is equivalent
26
to version 0.0.)
27
28
Signed-off-by: Leif Lindholm <quic_llindhol@quicinc.com>
29
Message-id: 20220505113947.75714-1-quic_llindhol@quicinc.com
30
Cc: Peter Maydell <peter.maydell@linaro.org>
31
Cc: Radoslaw Biernacki <rad@semihalf.com>
32
Cc: Cédric Le Goater <clg@kaod.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
33
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
12
Message-id: 20190304101339.25970-7-eric.auger@redhat.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
35
---
15
vl.c | 6 +++---
36
hw/arm/sbsa-ref.c | 14 ++++++++++++++
16
1 file changed, 3 insertions(+), 3 deletions(-)
37
1 file changed, 14 insertions(+)
17
38
18
diff --git a/vl.c b/vl.c
39
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
19
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
20
--- a/vl.c
41
--- a/hw/arm/sbsa-ref.c
21
+++ b/vl.c
42
+++ b/hw/arm/sbsa-ref.c
22
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
43
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SBSAMachineState *sms)
23
machine_opts = qemu_get_machine_opts();
44
qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
24
qemu_opt_foreach(machine_opts, machine_set_property, current_machine,
45
qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
25
&error_fatal);
46
26
+ current_machine->ram_size = ram_size;
47
+ /*
27
+ current_machine->maxram_size = maxram_size;
48
+ * This versioning scheme is for informing platform fw only. It is neither:
28
+ current_machine->ram_slots = ram_slots;
49
+ * - A QEMU versioned machine type; a given version of QEMU will emulate
29
50
+ * a given version of the platform.
30
configure_accelerator(current_machine, argv[0]);
51
+ * - A reflection of level of SBSA (now SystemReady SR) support provided.
31
52
+ *
32
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
53
+ * machine-version-major: updated when changes breaking fw compatibility
33
replay_checkpoint(CHECKPOINT_INIT);
54
+ * are introduced.
34
qdev_machine_init();
55
+ * machine-version-minor: updated when features are added that don't break
35
56
+ * fw compatibility.
36
- current_machine->ram_size = ram_size;
57
+ */
37
- current_machine->maxram_size = maxram_size;
58
+ qemu_fdt_setprop_cell(fdt, "/", "machine-version-major", 0);
38
- current_machine->ram_slots = ram_slots;
59
+ qemu_fdt_setprop_cell(fdt, "/", "machine-version-minor", 0);
39
current_machine->boot_order = boot_order;
60
+
40
61
if (ms->numa_state->have_numa_distance) {
41
/* parse features once if machine provides default cpu_type */
62
int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
63
uint32_t *matrix = g_malloc0(size);
42
--
64
--
43
2.20.1
65
2.25.1
44
66
45
67
diff view generated by jsdifflib
New patch
1
From: Gavin Shan <gshan@redhat.com>
1
2
3
This adds cluster-id in CPU instance properties, which will be used
4
by arm/virt machine. Besides, the cluster-id is also verified or
5
dumped in various spots:
6
7
* hw/core/machine.c::machine_set_cpu_numa_node() to associate
8
CPU with its NUMA node.
9
10
* hw/core/machine.c::machine_numa_finish_cpu_init() to record
11
CPU slots with no NUMA mapping set.
12
13
* hw/core/machine-hmp-cmds.c::hmp_hotpluggable_cpus() to dump
14
cluster-id.
15
16
Signed-off-by: Gavin Shan <gshan@redhat.com>
17
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
18
Acked-by: Igor Mammedov <imammedo@redhat.com>
19
Message-id: 20220503140304.855514-2-gshan@redhat.com
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
22
qapi/machine.json | 6 ++++--
23
hw/core/machine-hmp-cmds.c | 4 ++++
24
hw/core/machine.c | 16 ++++++++++++++++
25
3 files changed, 24 insertions(+), 2 deletions(-)
26
27
diff --git a/qapi/machine.json b/qapi/machine.json
28
index XXXXXXX..XXXXXXX 100644
29
--- a/qapi/machine.json
30
+++ b/qapi/machine.json
31
@@ -XXX,XX +XXX,XX @@
32
# @node-id: NUMA node ID the CPU belongs to
33
# @socket-id: socket number within node/board the CPU belongs to
34
# @die-id: die number within socket the CPU belongs to (since 4.1)
35
-# @core-id: core number within die the CPU belongs to
36
+# @cluster-id: cluster number within die the CPU belongs to (since 7.1)
37
+# @core-id: core number within cluster the CPU belongs to
38
# @thread-id: thread number within core the CPU belongs to
39
#
40
-# Note: currently there are 5 properties that could be present
41
+# Note: currently there are 6 properties that could be present
42
# but management should be prepared to pass through other
43
# properties with device_add command to allow for future
44
# interface extension. This also requires the filed names to be kept in
45
@@ -XXX,XX +XXX,XX @@
46
'data': { '*node-id': 'int',
47
'*socket-id': 'int',
48
'*die-id': 'int',
49
+ '*cluster-id': 'int',
50
'*core-id': 'int',
51
'*thread-id': 'int'
52
}
53
diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/core/machine-hmp-cmds.c
56
+++ b/hw/core/machine-hmp-cmds.c
57
@@ -XXX,XX +XXX,XX @@ void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict)
58
if (c->has_die_id) {
59
monitor_printf(mon, " die-id: \"%" PRIu64 "\"\n", c->die_id);
60
}
61
+ if (c->has_cluster_id) {
62
+ monitor_printf(mon, " cluster-id: \"%" PRIu64 "\"\n",
63
+ c->cluster_id);
64
+ }
65
if (c->has_core_id) {
66
monitor_printf(mon, " core-id: \"%" PRIu64 "\"\n", c->core_id);
67
}
68
diff --git a/hw/core/machine.c b/hw/core/machine.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/core/machine.c
71
+++ b/hw/core/machine.c
72
@@ -XXX,XX +XXX,XX @@ void machine_set_cpu_numa_node(MachineState *machine,
73
return;
74
}
75
76
+ if (props->has_cluster_id && !slot->props.has_cluster_id) {
77
+ error_setg(errp, "cluster-id is not supported");
78
+ return;
79
+ }
80
+
81
if (props->has_socket_id && !slot->props.has_socket_id) {
82
error_setg(errp, "socket-id is not supported");
83
return;
84
@@ -XXX,XX +XXX,XX @@ void machine_set_cpu_numa_node(MachineState *machine,
85
continue;
86
}
87
88
+ if (props->has_cluster_id &&
89
+ props->cluster_id != slot->props.cluster_id) {
90
+ continue;
91
+ }
92
+
93
if (props->has_die_id && props->die_id != slot->props.die_id) {
94
continue;
95
}
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);
105
+ }
106
if (cpu->props.has_core_id) {
107
if (s->len) {
108
g_string_append_printf(s, ", ");
109
--
110
2.25.1
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Gavin Shan <gshan@redhat.com>
2
2
3
In preparation for a split of the memory map into a static
3
The CPU topology isn't enabled on arm/virt machine yet, but we're
4
part and a dynamic part floating after the RAM, let's rename the
4
going to do it in next patch. After the CPU topology is enabled by
5
regions located after the RAM
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:
6
9
7
Signed-off-by: Eric Auger <eric.auger@redhat.com>
10
[14/21 qemu:qtest+qtest-aarch64 / qtest-aarch64/numa-test ERROR
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
1.48s killed by signal 6 SIGABRT
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
12
>>> G_TEST_DBUS_DAEMON=/home/gavin/sandbox/qemu.main/tests/dbus-vmstate-daemon.sh \
10
Message-id: 20190304101339.25970-3-eric.auger@redhat.com
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
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
29
---
13
include/hw/arm/virt.h | 8 ++++----
30
tests/qtest/numa-test.c | 3 ++-
14
hw/arm/virt-acpi-build.c | 10 ++++++----
31
1 file changed, 2 insertions(+), 1 deletion(-)
15
hw/arm/virt.c | 33 ++++++++++++++++++---------------
16
3 files changed, 28 insertions(+), 23 deletions(-)
17
32
18
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
33
diff --git a/tests/qtest/numa-test.c b/tests/qtest/numa-test.c
19
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/virt.h
35
--- a/tests/qtest/numa-test.c
21
+++ b/include/hw/arm/virt.h
36
+++ b/tests/qtest/numa-test.c
22
@@ -XXX,XX +XXX,XX @@ enum {
37
@@ -XXX,XX +XXX,XX @@ static void aarch64_numa_cpu(const void *data)
23
VIRT_GIC_VCPU,
38
QTestState *qts;
24
VIRT_GIC_ITS,
39
g_autofree char *cli = NULL;
25
VIRT_GIC_REDIST,
40
26
- VIRT_GIC_REDIST2,
41
- cli = make_cli(data, "-machine smp.cpus=2 "
27
+ VIRT_HIGH_GIC_REDIST2,
42
+ cli = make_cli(data, "-machine "
28
VIRT_SMMU,
43
+ "smp.cpus=2,smp.sockets=1,smp.clusters=1,smp.cores=1,smp.threads=2 "
29
VIRT_UART,
44
"-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 "
30
VIRT_MMIO,
45
"-numa cpu,node-id=1,thread-id=0 "
31
@@ -XXX,XX +XXX,XX @@ enum {
46
"-numa cpu,node-id=0,thread-id=1");
32
VIRT_PCIE_MMIO,
33
VIRT_PCIE_PIO,
34
VIRT_PCIE_ECAM,
35
- VIRT_PCIE_ECAM_HIGH,
36
+ VIRT_HIGH_PCIE_ECAM,
37
VIRT_PLATFORM_BUS,
38
- VIRT_PCIE_MMIO_HIGH,
39
+ VIRT_HIGH_PCIE_MMIO,
40
VIRT_GPIO,
41
VIRT_SECURE_UART,
42
VIRT_SECURE_MEM,
43
@@ -XXX,XX +XXX,XX @@ typedef struct {
44
int psci_conduit;
45
} VirtMachineState;
46
47
-#define VIRT_ECAM_ID(high) (high ? VIRT_PCIE_ECAM_HIGH : VIRT_PCIE_ECAM)
48
+#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
49
50
#define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
51
#define VIRT_MACHINE(obj) \
52
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/arm/virt-acpi-build.c
55
+++ b/hw/arm/virt-acpi-build.c
56
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
57
size_pio));
58
59
if (use_highmem) {
60
- hwaddr base_mmio_high = memmap[VIRT_PCIE_MMIO_HIGH].base;
61
- hwaddr size_mmio_high = memmap[VIRT_PCIE_MMIO_HIGH].size;
62
+ hwaddr base_mmio_high = memmap[VIRT_HIGH_PCIE_MMIO].base;
63
+ hwaddr size_mmio_high = memmap[VIRT_HIGH_PCIE_MMIO].size;
64
65
aml_append(rbuf,
66
aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
67
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
68
gicr = acpi_data_push(table_data, sizeof(*gicr));
69
gicr->type = ACPI_APIC_GENERIC_REDISTRIBUTOR;
70
gicr->length = sizeof(*gicr);
71
- gicr->base_address = cpu_to_le64(memmap[VIRT_GIC_REDIST2].base);
72
- gicr->range_length = cpu_to_le32(memmap[VIRT_GIC_REDIST2].size);
73
+ gicr->base_address =
74
+ cpu_to_le64(memmap[VIRT_HIGH_GIC_REDIST2].base);
75
+ gicr->range_length =
76
+ cpu_to_le32(memmap[VIRT_HIGH_GIC_REDIST2].size);
77
}
78
79
if (its_class_name() && !vmc->no_its) {
80
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/hw/arm/virt.c
83
+++ b/hw/arm/virt.c
84
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry a15memmap[] = {
85
[VIRT_PCIE_ECAM] = { 0x3f000000, 0x01000000 },
86
[VIRT_MEM] = { 0x40000000, RAMLIMIT_BYTES },
87
/* Additional 64 MB redist region (can contain up to 512 redistributors) */
88
- [VIRT_GIC_REDIST2] = { 0x4000000000ULL, 0x4000000 },
89
- [VIRT_PCIE_ECAM_HIGH] = { 0x4010000000ULL, 0x10000000 },
90
+ [VIRT_HIGH_GIC_REDIST2] = { 0x4000000000ULL, 0x4000000 },
91
+ [VIRT_HIGH_PCIE_ECAM] = { 0x4010000000ULL, 0x10000000 },
92
/* Second PCIe window, 512GB wide at the 512GB boundary */
93
- [VIRT_PCIE_MMIO_HIGH] = { 0x8000000000ULL, 0x8000000000ULL },
94
+ [VIRT_HIGH_PCIE_MMIO] = { 0x8000000000ULL, 0x8000000000ULL },
95
};
96
97
static const int a15irqmap[] = {
98
@@ -XXX,XX +XXX,XX @@ static void fdt_add_gic_node(VirtMachineState *vms)
99
2, vms->memmap[VIRT_GIC_REDIST].size);
100
} else {
101
qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
102
- 2, vms->memmap[VIRT_GIC_DIST].base,
103
- 2, vms->memmap[VIRT_GIC_DIST].size,
104
- 2, vms->memmap[VIRT_GIC_REDIST].base,
105
- 2, vms->memmap[VIRT_GIC_REDIST].size,
106
- 2, vms->memmap[VIRT_GIC_REDIST2].base,
107
- 2, vms->memmap[VIRT_GIC_REDIST2].size);
108
+ 2, vms->memmap[VIRT_GIC_DIST].base,
109
+ 2, vms->memmap[VIRT_GIC_DIST].size,
110
+ 2, vms->memmap[VIRT_GIC_REDIST].base,
111
+ 2, vms->memmap[VIRT_GIC_REDIST].size,
112
+ 2, vms->memmap[VIRT_HIGH_GIC_REDIST2].base,
113
+ 2, vms->memmap[VIRT_HIGH_GIC_REDIST2].size);
114
}
115
116
if (vms->virt) {
117
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
118
119
if (nb_redist_regions == 2) {
120
uint32_t redist1_capacity =
121
- vms->memmap[VIRT_GIC_REDIST2].size / GICV3_REDIST_SIZE;
122
+ vms->memmap[VIRT_HIGH_GIC_REDIST2].size / GICV3_REDIST_SIZE;
123
124
qdev_prop_set_uint32(gicdev, "redist-region-count[1]",
125
MIN(smp_cpus - redist0_count, redist1_capacity));
126
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
127
if (type == 3) {
128
sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_REDIST].base);
129
if (nb_redist_regions == 2) {
130
- sysbus_mmio_map(gicbusdev, 2, vms->memmap[VIRT_GIC_REDIST2].base);
131
+ sysbus_mmio_map(gicbusdev, 2,
132
+ vms->memmap[VIRT_HIGH_GIC_REDIST2].base);
133
}
134
} else {
135
sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_CPU].base);
136
@@ -XXX,XX +XXX,XX @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
137
{
138
hwaddr base_mmio = vms->memmap[VIRT_PCIE_MMIO].base;
139
hwaddr size_mmio = vms->memmap[VIRT_PCIE_MMIO].size;
140
- hwaddr base_mmio_high = vms->memmap[VIRT_PCIE_MMIO_HIGH].base;
141
- hwaddr size_mmio_high = vms->memmap[VIRT_PCIE_MMIO_HIGH].size;
142
+ hwaddr base_mmio_high = vms->memmap[VIRT_HIGH_PCIE_MMIO].base;
143
+ hwaddr size_mmio_high = vms->memmap[VIRT_HIGH_PCIE_MMIO].size;
144
hwaddr base_pio = vms->memmap[VIRT_PCIE_PIO].base;
145
hwaddr size_pio = vms->memmap[VIRT_PCIE_PIO].size;
146
hwaddr base_ecam, size_ecam;
147
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
148
* many redistributors we can fit into the memory map.
149
*/
150
if (vms->gic_version == 3) {
151
- virt_max_cpus = vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
152
- virt_max_cpus += vms->memmap[VIRT_GIC_REDIST2].size / GICV3_REDIST_SIZE;
153
+ virt_max_cpus =
154
+ vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
155
+ virt_max_cpus +=
156
+ vms->memmap[VIRT_HIGH_GIC_REDIST2].size / GICV3_REDIST_SIZE;
157
} else {
158
virt_max_cpus = GIC_NCPU;
159
}
160
--
47
--
161
2.20.1
48
2.25.1
162
49
163
50
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Gavin Shan <gshan@redhat.com>
2
2
3
Now we have the extended memory map (high IO regions beyond the
3
Currently, the SMP configuration isn't considered when the CPU
4
scalable RAM) and dynamic IPA range support at KVM/ARM level
4
topology is populated. In this case, it's impossible to provide
5
we can bump the legacy 255GB initial RAM limit. The actual maximum
5
the default CPU-to-NUMA mapping or association based on the socket
6
RAM size now depends on the physical CPU and host kernel, in
6
ID of the given CPU.
7
accelerated mode. In TCG mode, it depends on the VCPU
8
AA64MMFR0.PARANGE.
9
7
10
Signed-off-by: Eric Auger <eric.auger@redhat.com>
8
This takes account of SMP configuration when the CPU topology
11
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
9
is populated. The die ID for the given CPU isn't assigned since
12
Message-id: 20190304101339.25970-11-eric.auger@redhat.com
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
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
19
---
15
hw/arm/virt.c | 21 +--------------------
20
hw/arm/virt.c | 15 ++++++++++++++-
16
1 file changed, 1 insertion(+), 20 deletions(-)
21
1 file changed, 14 insertions(+), 1 deletion(-)
17
22
18
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
23
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
19
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/virt.c
25
--- a/hw/arm/virt.c
21
+++ b/hw/arm/virt.c
26
+++ b/hw/arm/virt.c
22
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
23
28
int n;
24
#define PLATFORM_BUS_NUM_IRQS 64
29
unsigned int max_cpus = ms->smp.max_cpus;
25
30
VirtMachineState *vms = VIRT_MACHINE(ms);
26
-/* RAM limit in GB. Since VIRT_MEM starts at the 1GB mark, this means
31
+ MachineClass *mc = MACHINE_GET_CLASS(vms);
27
- * RAM can go up to the 256GB mark, leaving 256GB of the physical
32
28
- * address space unallocated and free for future use between 256G and 512G.
33
if (ms->possible_cpus) {
29
- * If we need to provide more RAM to VMs in the future then we need to:
34
assert(ms->possible_cpus->len == max_cpus);
30
- * * allocate a second bank of RAM starting at 2TB and working up
35
@@ -XXX,XX +XXX,XX @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
31
- * * fix the DT and ACPI table generation code in QEMU to correctly
36
ms->possible_cpus->cpus[n].type = ms->cpu_type;
32
- * report two split lumps of RAM to the guest
37
ms->possible_cpus->cpus[n].arch_id =
33
- * * fix KVM in the host kernel to allow guests with >40 bit address spaces
38
virt_cpu_mp_affinity(vms, n);
34
- * (We don't want to fill all the way up to 512GB with RAM because
39
+
35
- * we might want it for non-RAM purposes later. Conversely it seems
40
+ assert(!mc->smp_props.dies_supported);
36
- * reasonable to assume that anybody configuring a VM with a quarter
41
+ ms->possible_cpus->cpus[n].props.has_socket_id = true;
37
- * of a terabyte of RAM will be doing it on a host with more than a
42
+ ms->possible_cpus->cpus[n].props.socket_id =
38
- * terabyte of physical address space.)
43
+ n / (ms->smp.clusters * ms->smp.cores * ms->smp.threads);
39
- */
44
+ ms->possible_cpus->cpus[n].props.has_cluster_id = true;
40
+/* Legacy RAM limit in GB (< version 4.0) */
45
+ ms->possible_cpus->cpus[n].props.cluster_id =
41
#define LEGACY_RAMLIMIT_GB 255
46
+ (n / (ms->smp.cores * ms->smp.threads)) % ms->smp.clusters;
42
#define LEGACY_RAMLIMIT_BYTES (LEGACY_RAMLIMIT_GB * GiB)
47
+ ms->possible_cpus->cpus[n].props.has_core_id = true;
43
48
+ ms->possible_cpus->cpus[n].props.core_id =
44
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
49
+ (n / ms->smp.threads) % ms->smp.cores;
45
50
ms->possible_cpus->cpus[n].props.has_thread_id = true;
46
vms->smp_cpus = smp_cpus;
51
- ms->possible_cpus->cpus[n].props.thread_id = n;
47
52
+ ms->possible_cpus->cpus[n].props.thread_id =
48
- if (machine->ram_size > vms->memmap[VIRT_MEM].size) {
53
+ n % ms->smp.threads;
49
- error_report("mach-virt: cannot model more than %dGB RAM",
54
}
50
- LEGACY_RAMLIMIT_GB);
55
return ms->possible_cpus;
51
- exit(1);
56
}
52
- }
53
-
54
if (vms->virt && kvm_enabled()) {
55
error_report("mach-virt: KVM does not support providing "
56
"Virtualization extensions to the guest CPU");
57
--
57
--
58
2.20.1
58
2.25.1
59
60
diff view generated by jsdifflib
New patch
1
From: Gavin Shan <gshan@redhat.com>
1
2
3
In aarch64_numa_cpu(), the CPU and NUMA association is something
4
like below. Two threads in the same core/cluster/socket are
5
associated with two individual NUMA nodes, which is unreal as
6
Igor Mammedov mentioned. We don't expect the association to break
7
NUMA-to-socket boundary, which matches with the real world.
8
9
NUMA-node socket cluster core thread
10
------------------------------------------
11
0 0 0 0 0
12
1 0 0 0 1
13
14
This corrects the topology for CPUs and their association with
15
NUMA nodes. After this patch is applied, the CPU and NUMA
16
association becomes something like below, which looks real.
17
Besides, socket/cluster/core/thread IDs are all checked when
18
the NUMA node IDs are verified. It helps to check if the CPU
19
topology is properly populated or not.
20
21
NUMA-node socket cluster core thread
22
------------------------------------------
23
0 1 0 0 0
24
1 0 0 0 0
25
26
Suggested-by: Igor Mammedov <imammedo@redhat.com>
27
Signed-off-by: Gavin Shan <gshan@redhat.com>
28
Acked-by: Igor Mammedov <imammedo@redhat.com>
29
Message-id: 20220503140304.855514-5-gshan@redhat.com
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
---
32
tests/qtest/numa-test.c | 18 ++++++++++++------
33
1 file changed, 12 insertions(+), 6 deletions(-)
34
35
diff --git a/tests/qtest/numa-test.c b/tests/qtest/numa-test.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/tests/qtest/numa-test.c
38
+++ b/tests/qtest/numa-test.c
39
@@ -XXX,XX +XXX,XX @@ static void aarch64_numa_cpu(const void *data)
40
g_autofree char *cli = NULL;
41
42
cli = make_cli(data, "-machine "
43
- "smp.cpus=2,smp.sockets=1,smp.clusters=1,smp.cores=1,smp.threads=2 "
44
+ "smp.cpus=2,smp.sockets=2,smp.clusters=1,smp.cores=1,smp.threads=1 "
45
"-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 "
46
- "-numa cpu,node-id=1,thread-id=0 "
47
- "-numa cpu,node-id=0,thread-id=1");
48
+ "-numa cpu,node-id=0,socket-id=1,cluster-id=0,core-id=0,thread-id=0 "
49
+ "-numa cpu,node-id=1,socket-id=0,cluster-id=0,core-id=0,thread-id=0");
50
qts = qtest_init(cli);
51
cpus = get_cpus(qts, &resp);
52
g_assert(cpus);
53
54
while ((e = qlist_pop(cpus))) {
55
QDict *cpu, *props;
56
- int64_t thread, node;
57
+ int64_t socket, cluster, core, thread, node;
58
59
cpu = qobject_to(QDict, e);
60
g_assert(qdict_haskey(cpu, "props"));
61
@@ -XXX,XX +XXX,XX @@ static void aarch64_numa_cpu(const void *data)
62
63
g_assert(qdict_haskey(props, "node-id"));
64
node = qdict_get_int(props, "node-id");
65
+ g_assert(qdict_haskey(props, "socket-id"));
66
+ socket = qdict_get_int(props, "socket-id");
67
+ g_assert(qdict_haskey(props, "cluster-id"));
68
+ cluster = qdict_get_int(props, "cluster-id");
69
+ g_assert(qdict_haskey(props, "core-id"));
70
+ core = qdict_get_int(props, "core-id");
71
g_assert(qdict_haskey(props, "thread-id"));
72
thread = qdict_get_int(props, "thread-id");
73
74
- if (thread == 0) {
75
+ if (socket == 0 && cluster == 0 && core == 0 && thread == 0) {
76
g_assert_cmpint(node, ==, 1);
77
- } else if (thread == 1) {
78
+ } else if (socket == 1 && cluster == 0 && core == 0 && thread == 0) {
79
g_assert_cmpint(node, ==, 0);
80
} else {
81
g_assert(false);
82
--
83
2.25.1
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Gavin Shan <gshan@redhat.com>
2
2
3
We are about to allow the memory map to grow beyond 1TB and
3
When CPU-to-NUMA association isn't explicitly provided by users,
4
potentially overshoot the VCPU AA64MMFR0.PARANGE.
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.
5
7
6
In aarch64 mode and when highmem is set, let's check the VCPU
8
For example, the following warning messages are observed when the
7
PA range is sufficient to address the highest GPA of the memory
9
Linux guest is booted with the following command lines.
8
map.
9
10
10
Signed-off-by: Eric Auger <eric.auger@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>
11
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
48
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
12
Message-id: 20190304101339.25970-10-eric.auger@redhat.com
49
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
50
Message-id: 20220503140304.855514-6-gshan@redhat.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
51
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
52
---
15
hw/arm/virt.c | 17 +++++++++++++++++
53
hw/arm/virt.c | 4 +++-
16
1 file changed, 17 insertions(+)
54
1 file changed, 3 insertions(+), 1 deletion(-)
17
55
18
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
19
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/virt.c
58
--- a/hw/arm/virt.c
21
+++ b/hw/arm/virt.c
59
+++ b/hw/arm/virt.c
22
@@ -XXX,XX +XXX,XX @@
60
@@ -XXX,XX +XXX,XX @@ virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
23
#include "standard-headers/linux/input.h"
61
24
#include "hw/arm/smmuv3.h"
62
static int64_t virt_get_default_cpu_node_id(const MachineState *ms, int idx)
25
#include "hw/acpi/acpi.h"
63
{
26
+#include "target/arm/internals.h"
64
- return idx % ms->numa_state->num_nodes;
27
65
+ int64_t socket_id = ms->possible_cpus->cpus[idx].props.socket_id;
28
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
29
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
30
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
31
fdt_add_timer_nodes(vms);
32
fdt_add_cpu_nodes(vms);
33
34
+ if (!kvm_enabled()) {
35
+ ARMCPU *cpu = ARM_CPU(first_cpu);
36
+ bool aarch64 = object_property_get_bool(OBJECT(cpu), "aarch64", NULL);
37
+
66
+
38
+ if (aarch64 && vms->highmem) {
67
+ return socket_id % ms->numa_state->num_nodes;
39
+ int requested_pa_size, pamax = arm_pamax(cpu);
68
}
40
+
69
41
+ requested_pa_size = 64 - clz64(vms->highest_gpa);
70
static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
42
+ if (pamax < requested_pa_size) {
43
+ error_report("VCPU supports less PA bits (%d) than requested "
44
+ "by the memory map (%d)", pamax, requested_pa_size);
45
+ exit(1);
46
+ }
47
+ }
48
+ }
49
+
50
memory_region_allocate_system_memory(ram, NULL, "mach-virt.ram",
51
machine->ram_size);
52
memory_region_add_subregion(sysmem, vms->memmap[VIRT_MEM].base, ram);
53
--
71
--
54
2.20.1
72
2.25.1
55
56
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Gavin Shan <gshan@redhat.com>
2
2
3
Add the kvm_arm_get_max_vm_ipa_size() helper that returns the
3
When the PPTT table is built, the CPU topology is re-calculated, but
4
number of bits in the IPA address space supported by KVM.
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
This capability needs to be known to create the VM with a
7
This reworks build_pptt() to avoid by reusing the existing IDs in
7
specific IPA max size (kvm_type passed along KVM_CREATE_VM ioctl.
8
ms->possible_cpus. Currently, the only user of build_pptt() is
9
arm/virt machine.
8
10
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
11
Signed-off-by: Gavin Shan <gshan@redhat.com>
10
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
12
Tested-by: Yanan Wang <wangyanan55@huawei.com>
11
Message-id: 20190304101339.25970-6-eric.auger@redhat.com
13
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
14
Acked-by: Igor Mammedov <imammedo@redhat.com>
15
Acked-by: Michael S. Tsirkin <mst@redhat.com>
16
Message-id: 20220503140304.855514-7-gshan@redhat.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
18
---
14
target/arm/kvm_arm.h | 13 +++++++++++++
19
hw/acpi/aml-build.c | 111 +++++++++++++++++++-------------------------
15
target/arm/kvm.c | 10 ++++++++++
20
1 file changed, 48 insertions(+), 63 deletions(-)
16
2 files changed, 23 insertions(+)
17
21
18
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
22
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
19
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/kvm_arm.h
24
--- a/hw/acpi/aml-build.c
21
+++ b/target/arm/kvm_arm.h
25
+++ b/hw/acpi/aml-build.c
22
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf);
26
@@ -XXX,XX +XXX,XX @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
23
*/
27
const char *oem_id, const char *oem_table_id)
24
void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
28
{
25
29
MachineClass *mc = MACHINE_GET_CLASS(ms);
26
+/**
30
- GQueue *list = g_queue_new();
27
+ * kvm_arm_get_max_vm_ipa_size - Returns the number of bits in the
31
- guint pptt_start = table_data->len;
28
+ * IPA address space supported by KVM
32
- guint parent_offset;
29
+ *
33
- guint length, i;
30
+ * @ms: Machine state handle
34
- int uid = 0;
31
+ */
35
- int socket;
32
+int kvm_arm_get_max_vm_ipa_size(MachineState *ms);
36
+ CPUArchIdList *cpus = ms->possible_cpus;
33
+
37
+ int64_t socket_id = -1, cluster_id = -1, core_id = -1;
34
/**
38
+ uint32_t socket_offset = 0, cluster_offset = 0, core_offset = 0;
35
* kvm_arm_sync_mpstate_to_kvm
39
+ uint32_t pptt_start = table_data->len;
36
* @cpu: ARMCPU
40
+ int n;
37
@@ -XXX,XX +XXX,XX @@ static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
41
AcpiTable table = { .sig = "PPTT", .rev = 2,
38
cpu->host_cpu_probe_failed = true;
42
.oem_id = oem_id, .oem_table_id = oem_table_id };
43
44
acpi_table_begin(&table, table_data);
45
46
- for (socket = 0; socket < ms->smp.sockets; socket++) {
47
- g_queue_push_tail(list,
48
- GUINT_TO_POINTER(table_data->len - pptt_start));
49
- build_processor_hierarchy_node(
50
- table_data,
51
- /*
52
- * Physical package - represents the boundary
53
- * of a physical package
54
- */
55
- (1 << 0),
56
- 0, socket, NULL, 0);
57
- }
58
-
59
- if (mc->smp_props.clusters_supported) {
60
- length = g_queue_get_length(list);
61
- for (i = 0; i < length; i++) {
62
- int cluster;
63
-
64
- parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
65
- for (cluster = 0; cluster < ms->smp.clusters; cluster++) {
66
- g_queue_push_tail(list,
67
- GUINT_TO_POINTER(table_data->len - pptt_start));
68
- build_processor_hierarchy_node(
69
- table_data,
70
- (0 << 0), /* not a physical package */
71
- parent_offset, cluster, NULL, 0);
72
- }
73
+ /*
74
+ * This works with the assumption that cpus[n].props.*_id has been
75
+ * sorted from top to down levels in mc->possible_cpu_arch_ids().
76
+ * Otherwise, the unexpected and duplicated containers will be
77
+ * created.
78
+ */
79
+ for (n = 0; n < cpus->len; n++) {
80
+ if (cpus->cpus[n].props.socket_id != socket_id) {
81
+ assert(cpus->cpus[n].props.socket_id > socket_id);
82
+ socket_id = cpus->cpus[n].props.socket_id;
83
+ cluster_id = -1;
84
+ core_id = -1;
85
+ socket_offset = table_data->len - pptt_start;
86
+ build_processor_hierarchy_node(table_data,
87
+ (1 << 0), /* Physical package */
88
+ 0, socket_id, NULL, 0);
89
}
90
- }
91
92
- length = g_queue_get_length(list);
93
- for (i = 0; i < length; i++) {
94
- int core;
95
-
96
- parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
97
- for (core = 0; core < ms->smp.cores; core++) {
98
- if (ms->smp.threads > 1) {
99
- g_queue_push_tail(list,
100
- GUINT_TO_POINTER(table_data->len - pptt_start));
101
- build_processor_hierarchy_node(
102
- table_data,
103
- (0 << 0), /* not a physical package */
104
- parent_offset, core, NULL, 0);
105
- } else {
106
- build_processor_hierarchy_node(
107
- table_data,
108
- (1 << 1) | /* ACPI Processor ID valid */
109
- (1 << 3), /* Node is a Leaf */
110
- parent_offset, uid++, NULL, 0);
111
+ if (mc->smp_props.clusters_supported) {
112
+ if (cpus->cpus[n].props.cluster_id != cluster_id) {
113
+ assert(cpus->cpus[n].props.cluster_id > cluster_id);
114
+ cluster_id = cpus->cpus[n].props.cluster_id;
115
+ core_id = -1;
116
+ cluster_offset = table_data->len - pptt_start;
117
+ build_processor_hierarchy_node(table_data,
118
+ (0 << 0), /* Not a physical package */
119
+ socket_offset, cluster_id, NULL, 0);
120
}
121
+ } else {
122
+ cluster_offset = socket_offset;
123
}
124
- }
125
126
- length = g_queue_get_length(list);
127
- for (i = 0; i < length; i++) {
128
- int thread;
129
+ if (ms->smp.threads == 1) {
130
+ build_processor_hierarchy_node(table_data,
131
+ (1 << 1) | /* ACPI Processor ID valid */
132
+ (1 << 3), /* Node is a Leaf */
133
+ cluster_offset, n, NULL, 0);
134
+ } else {
135
+ if (cpus->cpus[n].props.core_id != core_id) {
136
+ assert(cpus->cpus[n].props.core_id > core_id);
137
+ core_id = cpus->cpus[n].props.core_id;
138
+ core_offset = table_data->len - pptt_start;
139
+ build_processor_hierarchy_node(table_data,
140
+ (0 << 0), /* Not a physical package */
141
+ cluster_offset, core_id, NULL, 0);
142
+ }
143
144
- parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
145
- for (thread = 0; thread < ms->smp.threads; thread++) {
146
- build_processor_hierarchy_node(
147
- table_data,
148
+ build_processor_hierarchy_node(table_data,
149
(1 << 1) | /* ACPI Processor ID valid */
150
(1 << 2) | /* Processor is a Thread */
151
(1 << 3), /* Node is a Leaf */
152
- parent_offset, uid++, NULL, 0);
153
+ core_offset, n, NULL, 0);
154
}
155
}
156
157
- g_queue_free(list);
158
acpi_table_end(linker, &table);
39
}
159
}
40
160
41
+static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
42
+{
43
+ return -ENOENT;
44
+}
45
+
46
static inline int kvm_arm_vgic_probe(void)
47
{
48
return 0;
49
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/kvm.c
52
+++ b/target/arm/kvm.c
53
@@ -XXX,XX +XXX,XX @@
54
#include "qemu/error-report.h"
55
#include "sysemu/sysemu.h"
56
#include "sysemu/kvm.h"
57
+#include "sysemu/kvm_int.h"
58
#include "kvm_arm.h"
59
#include "cpu.h"
60
#include "trace.h"
61
@@ -XXX,XX +XXX,XX @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
62
env->features = arm_host_cpu_features.features;
63
}
64
65
+int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
66
+{
67
+ KVMState *s = KVM_STATE(ms->accelerator);
68
+ int ret;
69
+
70
+ ret = kvm_check_extension(s, KVM_CAP_ARM_VM_IPA_SIZE);
71
+ return ret > 0 ? ret : 40;
72
+}
73
+
74
int kvm_arch_init(MachineState *ms, KVMState *s)
75
{
76
/* For ARM interrupt delivery is always asynchronous,
77
--
161
--
78
2.20.1
162
2.25.1
79
80
diff view generated by jsdifflib