1
Big pullreq this week, though none of the new features are
1
Hi; here's a target-arm pullreq. Mostly this is RTH's FEAT_RME
2
particularly earthshaking. Most of the bulk is from code cleanup
2
series; there are also a handful of bug fixes including some
3
patches from me or rth.
3
which aren't arm-specific but which it's convenient to include
4
here.
4
5
5
thanks
6
thanks
6
-- PMM
7
-- PMM
7
8
8
The following changes since commit b651b80822fa8cb66ca30087ac7fbc75507ae5d2:
9
The following changes since commit b455ce4c2f300c8ba47cba7232dd03261368a4cb:
9
10
10
Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-5.0-pull-request' into staging (2020-02-20 17:35:42 +0000)
11
Merge tag 'q800-for-8.1-pull-request' of https://github.com/vivier/qemu-m68k into staging (2023-06-22 10:18:32 +0200)
11
12
12
are available in the Git repository at:
13
are available in the Git repository at:
13
14
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200221
15
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230623
15
16
16
for you to fetch changes up to 270a679b3f950d7c4c600f324aab8bff292d0971:
17
for you to fetch changes up to 497fad38979c16b6412388927401e577eba43d26:
17
18
18
target/arm: Add missing checks for fpsp_v2 (2020-02-21 12:54:25 +0000)
19
pc-bios/keymaps: Use the official xkb name for Arabic layout, not the legacy synonym (2023-06-23 11:46:02 +0100)
19
20
20
----------------------------------------------------------------
21
----------------------------------------------------------------
21
target-arm queue:
22
target-arm queue:
22
* aspeed/scu: Implement chip ID register
23
* Add (experimental) support for FEAT_RME
23
* hw/misc/iotkit-secctl: Fix writing to 'PPC Interrupt Clear' register
24
* host-utils: Avoid using __builtin_subcll on buggy versions of Apple Clang
24
* mainstone: Make providing flash images non-mandatory
25
* target/arm: Restructure has_vfp_d32 test
25
* z2: Make providing flash images non-mandatory
26
* hw/arm/sbsa-ref: add ITS support in SBSA GIC
26
* Fix failures to flush SVE high bits after AdvSIMD INS/ZIP/UZP/TRN/TBL/TBX/EXT
27
* target/arm: Fix sve predicate store, 8 <= VQ <= 15
27
* Minor performance improvement: spend less time recalculating hflags values
28
* pc-bios/keymaps: Use the official xkb name for Arabic layout, not the legacy synonym
28
* Code cleanup to isar_feature function tests
29
* Implement ARMv8.1-PMU and ARMv8.4-PMU extensions
30
* Bugfix: correct handling of PMCR_EL0.LC bit
31
* Bugfix: correct definition of PMCRDP
32
* Correctly implement ACTLR2, HACTLR2
33
* allwinner: Wire up USB ports
34
* Vectorize emulation of USHL, SSHL, PMUL*
35
* xilinx_spips: Correct the number of dummy cycles for the FAST_READ_4 cmd
36
* sh4: Fix PCI ISA IO memory subregion
37
* Code cleanup to use more isar_feature tests and fewer ARM_FEATURE_* tests
38
29
39
----------------------------------------------------------------
30
----------------------------------------------------------------
40
Francisco Iglesias (1):
31
Peter Maydell (2):
41
xilinx_spips: Correct the number of dummy cycles for the FAST_READ_4 cmd
32
host-utils: Avoid using __builtin_subcll on buggy versions of Apple Clang
33
pc-bios/keymaps: Use the official xkb name for Arabic layout, not the legacy synonym
42
34
43
Guenter Roeck (6):
35
Richard Henderson (23):
44
mainstone: Make providing flash images non-mandatory
36
target/arm: Add isar_feature_aa64_rme
45
z2: Make providing flash images non-mandatory
37
target/arm: Update SCR and HCR for RME
46
hw: usb: hcd-ohci: Move OHCISysBusState and TYPE_SYSBUS_OHCI to include file
38
target/arm: SCR_EL3.NS may be RES1
47
hcd-ehci: Introduce "companion-enable" sysbus property
39
target/arm: Add RME cpregs
48
arm: allwinner: Wire up USB ports
40
target/arm: Introduce ARMSecuritySpace
49
sh4: Fix PCI ISA IO memory subregion
41
include/exec/memattrs: Add two bits of space to MemTxAttrs
42
target/arm: Adjust the order of Phys and Stage2 ARMMMUIdx
43
target/arm: Introduce ARMMMUIdx_Phys_{Realm,Root}
44
target/arm: Remove __attribute__((nonnull)) from ptw.c
45
target/arm: Pipe ARMSecuritySpace through ptw.c
46
target/arm: NSTable is RES0 for the RME EL3 regime
47
target/arm: Handle Block and Page bits for security space
48
target/arm: Handle no-execute for Realm and Root regimes
49
target/arm: Use get_phys_addr_with_struct in S1_ptw_translate
50
target/arm: Move s1_is_el0 into S1Translate
51
target/arm: Use get_phys_addr_with_struct for stage2
52
target/arm: Add GPC syndrome
53
target/arm: Implement GPC exceptions
54
target/arm: Implement the granule protection check
55
target/arm: Add cpu properties for enabling FEAT_RME
56
docs/system/arm: Document FEAT_RME
57
target/arm: Restructure has_vfp_d32 test
58
target/arm: Fix sve predicate store, 8 <= VQ <= 15
50
59
51
Joel Stanley (2):
60
Shashi Mallela (1):
52
aspeed/scu: Create separate write callbacks
61
hw/arm/sbsa-ref: add ITS support in SBSA GIC
53
aspeed/scu: Implement chip ID register
54
62
55
Peter Maydell (21):
63
docs/system/arm/cpu-features.rst | 23 ++
56
target/arm: Add _aa32_ to isar_feature functions testing 32-bit ID registers
64
docs/system/arm/emulation.rst | 1 +
57
target/arm: Check aa32_pan in take_aarch32_exception(), not aa64_pan
65
docs/system/arm/sbsa.rst | 14 +
58
target/arm: Add isar_feature_any_fp16 and document naming/usage conventions
66
include/exec/memattrs.h | 9 +-
59
target/arm: Define and use any_predinv isar_feature test
67
include/qemu/compiler.h | 13 +
60
target/arm: Factor out PMU register definitions
68
include/qemu/host-utils.h | 2 +-
61
target/arm: Add and use FIELD definitions for ID_AA64DFR0_EL1
69
target/arm/cpu.h | 151 ++++++++---
62
target/arm: Use FIELD macros for clearing ID_DFR0 PERFMON field
70
target/arm/internals.h | 27 ++
63
target/arm: Define an aa32_pmu_8_1 isar feature test function
71
target/arm/syndrome.h | 10 +
64
target/arm: Add _aa64_ and _any_ versions of pmu_8_1 isar checks
72
hw/arm/sbsa-ref.c | 33 ++-
65
target/arm: Stop assuming DBGDIDR always exists
73
target/arm/cpu.c | 32 ++-
66
target/arm: Move DBGDIDR into ARMISARegisters
74
target/arm/helper.c | 162 ++++++++++-
67
target/arm: Read debug-related ID registers from KVM
75
target/arm/ptw.c | 570 +++++++++++++++++++++++++++++++--------
68
target/arm: Implement ARMv8.1-PMU extension
76
target/arm/tcg/cpu64.c | 53 ++++
69
target/arm: Implement ARMv8.4-PMU extension
77
target/arm/tcg/tlb_helper.c | 96 ++++++-
70
target/arm: Provide ARMv8.4-PMU in '-cpu max'
78
target/arm/tcg/translate-sve.c | 2 +-
71
target/arm: Correct definition of PMCRDP
79
pc-bios/keymaps/meson.build | 2 +-
72
target/arm: Correct handling of PMCR_EL0.LC bit
80
17 files changed, 1034 insertions(+), 166 deletions(-)
73
target/arm: Test correct register in aa32_pan and aa32_ats1e1 checks
74
target/arm: Use isar_feature function for testing AA32HPD feature
75
target/arm: Use FIELD_EX32 for testing 32-bit fields
76
target/arm: Correctly implement ACTLR2, HACTLR2
77
78
Philippe Mathieu-Daudé (1):
79
hw/misc/iotkit-secctl: Fix writing to 'PPC Interrupt Clear' register
80
81
Richard Henderson (21):
82
target/arm: Flush high bits of sve register after AdvSIMD EXT
83
target/arm: Flush high bits of sve register after AdvSIMD TBL/TBX
84
target/arm: Flush high bits of sve register after AdvSIMD ZIP/UZP/TRN
85
target/arm: Flush high bits of sve register after AdvSIMD INS
86
target/arm: Use bit 55 explicitly for pauth
87
target/arm: Fix select for aa64_va_parameters_both
88
target/arm: Remove ttbr1_valid check from get_phys_addr_lpae
89
target/arm: Split out aa64_va_parameter_tbi, aa64_va_parameter_tbid
90
target/arm: Vectorize USHL and SSHL
91
target/arm: Convert PMUL.8 to gvec
92
target/arm: Convert PMULL.64 to gvec
93
target/arm: Convert PMULL.8 to gvec
94
target/arm: Rename isar_feature_aa32_simd_r32
95
target/arm: Use isar_feature_aa32_simd_r32 more places
96
target/arm: Set MVFR0.FPSP for ARMv5 cpus
97
target/arm: Add isar_feature_aa32_simd_r16
98
target/arm: Rename isar_feature_aa32_fpdp_v2
99
target/arm: Add isar_feature_aa32_{fpsp_v2, fpsp_v3, fpdp_v3}
100
target/arm: Perform fpdp_v2 check first
101
target/arm: Replace ARM_FEATURE_VFP3 checks with fp{sp, dp}_v3
102
target/arm: Add missing checks for fpsp_v2
103
104
hw/usb/hcd-ohci.h | 16 ++
105
include/hw/arm/allwinner-a10.h | 6 +
106
target/arm/cpu.h | 173 ++++++++++++---
107
target/arm/helper-sve.h | 2 +
108
target/arm/helper.h | 21 +-
109
target/arm/internals.h | 47 +++-
110
target/arm/translate.h | 6 +
111
hw/arm/allwinner-a10.c | 43 ++++
112
hw/arm/mainstone.c | 11 +-
113
hw/arm/z2.c | 6 -
114
hw/intc/armv7m_nvic.c | 30 +--
115
hw/misc/aspeed_scu.c | 93 ++++++--
116
hw/misc/iotkit-secctl.c | 2 +-
117
hw/sh4/sh_pci.c | 11 +-
118
hw/ssi/xilinx_spips.c | 2 +-
119
hw/usb/hcd-ehci-sysbus.c | 2 +
120
hw/usb/hcd-ohci.c | 15 --
121
linux-user/arm/signal.c | 4 +-
122
linux-user/elfload.c | 4 +-
123
target/arm/arch_dump.c | 11 +-
124
target/arm/cpu.c | 175 +++++++--------
125
target/arm/cpu64.c | 58 +++--
126
target/arm/debug_helper.c | 6 +-
127
target/arm/helper.c | 472 +++++++++++++++++++++++------------------
128
target/arm/kvm32.c | 25 +++
129
target/arm/kvm64.c | 46 ++++
130
target/arm/m_helper.c | 11 +-
131
target/arm/machine.c | 3 +-
132
target/arm/neon_helper.c | 117 ----------
133
target/arm/pauth_helper.c | 3 +-
134
target/arm/translate-a64.c | 92 ++++----
135
target/arm/translate-vfp.inc.c | 263 ++++++++++++++---------
136
target/arm/translate.c | 356 ++++++++++++++++++++++++++-----
137
target/arm/vec_helper.c | 211 ++++++++++++++++++
138
target/arm/vfp_helper.c | 2 +-
139
35 files changed, 1564 insertions(+), 781 deletions(-)
140
diff view generated by jsdifflib
Deleted patch
1
From: Joel Stanley <joel@jms.id.au>
2
1
3
This splits the common write callback into separate ast2400 and ast2500
4
implementations. This makes it clearer when implementing differing
5
behaviour.
6
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
8
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
9
Reviewed-by: Cédric Le Goater <clg@kaod.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Message-id: 20200121013302.43839-2-joel@jms.id.au
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/misc/aspeed_scu.c | 80 +++++++++++++++++++++++++++++++-------------
15
1 file changed, 57 insertions(+), 23 deletions(-)
16
17
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/misc/aspeed_scu.c
20
+++ b/hw/misc/aspeed_scu.c
21
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
22
return s->regs[reg];
23
}
24
25
-static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
26
- unsigned size)
27
+static void aspeed_ast2400_scu_write(void *opaque, hwaddr offset,
28
+ uint64_t data, unsigned size)
29
+{
30
+ AspeedSCUState *s = ASPEED_SCU(opaque);
31
+ int reg = TO_REG(offset);
32
+
33
+ if (reg >= ASPEED_SCU_NR_REGS) {
34
+ qemu_log_mask(LOG_GUEST_ERROR,
35
+ "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
36
+ __func__, offset);
37
+ return;
38
+ }
39
+
40
+ if (reg > PROT_KEY && reg < CPU2_BASE_SEG1 &&
41
+ !s->regs[PROT_KEY]) {
42
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: SCU is locked!\n", __func__);
43
+ }
44
+
45
+ trace_aspeed_scu_write(offset, size, data);
46
+
47
+ switch (reg) {
48
+ case PROT_KEY:
49
+ s->regs[reg] = (data == ASPEED_SCU_PROT_KEY) ? 1 : 0;
50
+ return;
51
+ case SILICON_REV:
52
+ case FREQ_CNTR_EVAL:
53
+ case VGA_SCRATCH1 ... VGA_SCRATCH8:
54
+ case RNG_DATA:
55
+ case FREE_CNTR4:
56
+ case FREE_CNTR4_EXT:
57
+ qemu_log_mask(LOG_GUEST_ERROR,
58
+ "%s: Write to read-only offset 0x%" HWADDR_PRIx "\n",
59
+ __func__, offset);
60
+ return;
61
+ }
62
+
63
+ s->regs[reg] = data;
64
+}
65
+
66
+static void aspeed_ast2500_scu_write(void *opaque, hwaddr offset,
67
+ uint64_t data, unsigned size)
68
{
69
AspeedSCUState *s = ASPEED_SCU(opaque);
70
int reg = TO_REG(offset);
71
@@ -XXX,XX +XXX,XX @@ static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
72
case PROT_KEY:
73
s->regs[reg] = (data == ASPEED_SCU_PROT_KEY) ? 1 : 0;
74
return;
75
- case CLK_SEL:
76
- s->regs[reg] = data;
77
- break;
78
case HW_STRAP1:
79
- if (ASPEED_IS_AST2500(s->regs[SILICON_REV])) {
80
- s->regs[HW_STRAP1] |= data;
81
- return;
82
- }
83
- /* Jump to assignment below */
84
- break;
85
+ s->regs[HW_STRAP1] |= data;
86
+ return;
87
case SILICON_REV:
88
- if (ASPEED_IS_AST2500(s->regs[SILICON_REV])) {
89
- s->regs[HW_STRAP1] &= ~data;
90
- } else {
91
- qemu_log_mask(LOG_GUEST_ERROR,
92
- "%s: Write to read-only offset 0x%" HWADDR_PRIx "\n",
93
- __func__, offset);
94
- }
95
- /* Avoid assignment below, we've handled everything */
96
+ s->regs[HW_STRAP1] &= ~data;
97
return;
98
case FREQ_CNTR_EVAL:
99
case VGA_SCRATCH1 ... VGA_SCRATCH8:
100
@@ -XXX,XX +XXX,XX @@ static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
101
s->regs[reg] = data;
102
}
103
104
-static const MemoryRegionOps aspeed_scu_ops = {
105
+static const MemoryRegionOps aspeed_ast2400_scu_ops = {
106
.read = aspeed_scu_read,
107
- .write = aspeed_scu_write,
108
+ .write = aspeed_ast2400_scu_write,
109
+ .endianness = DEVICE_LITTLE_ENDIAN,
110
+ .valid.min_access_size = 4,
111
+ .valid.max_access_size = 4,
112
+ .valid.unaligned = false,
113
+};
114
+
115
+static const MemoryRegionOps aspeed_ast2500_scu_ops = {
116
+ .read = aspeed_scu_read,
117
+ .write = aspeed_ast2500_scu_write,
118
.endianness = DEVICE_LITTLE_ENDIAN,
119
.valid.min_access_size = 4,
120
.valid.max_access_size = 4,
121
@@ -XXX,XX +XXX,XX @@ static void aspeed_2400_scu_class_init(ObjectClass *klass, void *data)
122
asc->calc_hpll = aspeed_2400_scu_calc_hpll;
123
asc->apb_divider = 2;
124
asc->nr_regs = ASPEED_SCU_NR_REGS;
125
- asc->ops = &aspeed_scu_ops;
126
+ asc->ops = &aspeed_ast2400_scu_ops;
127
}
128
129
static const TypeInfo aspeed_2400_scu_info = {
130
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_scu_class_init(ObjectClass *klass, void *data)
131
asc->calc_hpll = aspeed_2500_scu_calc_hpll;
132
asc->apb_divider = 4;
133
asc->nr_regs = ASPEED_SCU_NR_REGS;
134
- asc->ops = &aspeed_scu_ops;
135
+ asc->ops = &aspeed_ast2500_scu_ops;
136
}
137
138
static const TypeInfo aspeed_2500_scu_info = {
139
--
140
2.20.1
141
142
diff view generated by jsdifflib
Deleted patch
1
From: Joel Stanley <joel@jms.id.au>
2
1
3
This returns a fixed but non-zero value for the chip id.
4
5
Signed-off-by: Joel Stanley <joel@jms.id.au>
6
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20200121013302.43839-3-joel@jms.id.au
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/misc/aspeed_scu.c | 13 +++++++++++++
13
1 file changed, 13 insertions(+)
14
15
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/misc/aspeed_scu.c
18
+++ b/hw/misc/aspeed_scu.c
19
@@ -XXX,XX +XXX,XX @@
20
#define CPU2_BASE_SEG4 TO_REG(0x110)
21
#define CPU2_BASE_SEG5 TO_REG(0x114)
22
#define CPU2_CACHE_CTRL TO_REG(0x118)
23
+#define CHIP_ID0 TO_REG(0x150)
24
+#define CHIP_ID1 TO_REG(0x154)
25
#define UART_HPLL_CLK TO_REG(0x160)
26
#define PCIE_CTRL TO_REG(0x180)
27
#define BMC_MMIO_CTRL TO_REG(0x184)
28
@@ -XXX,XX +XXX,XX @@
29
#define AST2600_HW_STRAP2_PROT TO_REG(0x518)
30
#define AST2600_RNG_CTRL TO_REG(0x524)
31
#define AST2600_RNG_DATA TO_REG(0x540)
32
+#define AST2600_CHIP_ID0 TO_REG(0x5B0)
33
+#define AST2600_CHIP_ID1 TO_REG(0x5B4)
34
35
#define AST2600_CLK TO_REG(0x40)
36
37
@@ -XXX,XX +XXX,XX @@ static const uint32_t ast2500_a1_resets[ASPEED_SCU_NR_REGS] = {
38
[CPU2_BASE_SEG1] = 0x80000000U,
39
[CPU2_BASE_SEG4] = 0x1E600000U,
40
[CPU2_BASE_SEG5] = 0xC0000000U,
41
+ [CHIP_ID0] = 0x1234ABCDU,
42
+ [CHIP_ID1] = 0x88884444U,
43
[UART_HPLL_CLK] = 0x00001903U,
44
[PCIE_CTRL] = 0x0000007BU,
45
[BMC_DEV_ID] = 0x00002402U
46
@@ -XXX,XX +XXX,XX @@ static void aspeed_ast2500_scu_write(void *opaque, hwaddr offset,
47
case RNG_DATA:
48
case FREE_CNTR4:
49
case FREE_CNTR4_EXT:
50
+ case CHIP_ID0:
51
+ case CHIP_ID1:
52
qemu_log_mask(LOG_GUEST_ERROR,
53
"%s: Write to read-only offset 0x%" HWADDR_PRIx "\n",
54
__func__, offset);
55
@@ -XXX,XX +XXX,XX @@ static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset,
56
case AST2600_RNG_DATA:
57
case AST2600_SILICON_REV:
58
case AST2600_SILICON_REV2:
59
+ case AST2600_CHIP_ID0:
60
+ case AST2600_CHIP_ID1:
61
/* Add read only registers here */
62
qemu_log_mask(LOG_GUEST_ERROR,
63
"%s: Write to read-only offset 0x%" HWADDR_PRIx "\n",
64
@@ -XXX,XX +XXX,XX @@ static const uint32_t ast2600_a0_resets[ASPEED_AST2600_SCU_NR_REGS] = {
65
[AST2600_CLK_STOP_CTRL2] = 0xFFF0FFF0,
66
[AST2600_SDRAM_HANDSHAKE] = 0x00000040, /* SoC completed DRAM init */
67
[AST2600_HPLL_PARAM] = 0x1000405F,
68
+ [AST2600_CHIP_ID0] = 0x1234ABCD,
69
+ [AST2600_CHIP_ID1] = 0x88884444,
70
+
71
};
72
73
static void aspeed_ast2600_scu_reset(DeviceState *dev)
74
--
75
2.20.1
76
77
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Fix warning reported by Clang static code analyzer:
4
5
CC hw/misc/iotkit-secctl.o
6
hw/misc/iotkit-secctl.c:343:9: warning: Value stored to 'value' is never read
7
value &= 0x00f000f3;
8
^ ~~~~~~~~~~
9
10
Fixes: b3717c23e1c
11
Reported-by: Clang Static Analyzer
12
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20200217132922.24607-1-f4bug@amsat.org
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/misc/iotkit-secctl.c | 2 +-
18
1 file changed, 1 insertion(+), 1 deletion(-)
19
20
diff --git a/hw/misc/iotkit-secctl.c b/hw/misc/iotkit-secctl.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/misc/iotkit-secctl.c
23
+++ b/hw/misc/iotkit-secctl.c
24
@@ -XXX,XX +XXX,XX @@ static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr,
25
qemu_set_irq(s->sec_resp_cfg, s->secrespcfg);
26
break;
27
case A_SECPPCINTCLR:
28
- value &= 0x00f000f3;
29
+ s->secppcintstat &= ~(value & 0x00f000f3);
30
foreach_ppc(s, iotkit_secctl_ppc_update_irq_clear);
31
break;
32
case A_SECPPCINTEN:
33
--
34
2.20.1
35
36
diff view generated by jsdifflib
Deleted patch
1
From: Guenter Roeck <linux@roeck-us.net>
2
1
3
Up to now, the mainstone machine only boots if two flash images are
4
provided. This is not really necessary; the machine can boot from initrd
5
or from SD without it. At the same time, having to provide dummy flash
6
images is a nuisance and does not add any real value. Make it optional.
7
8
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Message-id: 20200217210824.18513-1-linux@roeck-us.net
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/arm/mainstone.c | 11 +----------
14
1 file changed, 1 insertion(+), 10 deletions(-)
15
16
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/mainstone.c
19
+++ b/hw/arm/mainstone.c
20
@@ -XXX,XX +XXX,XX @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
21
/* There are two 32MiB flash devices on the board */
22
for (i = 0; i < 2; i ++) {
23
dinfo = drive_get(IF_PFLASH, 0, i);
24
- if (!dinfo) {
25
- if (qtest_enabled()) {
26
- break;
27
- }
28
- error_report("Two flash images must be given with the "
29
- "'pflash' parameter");
30
- exit(1);
31
- }
32
-
33
if (!pflash_cfi01_register(mainstone_flash_base[i],
34
i ? "mainstone.flash1" : "mainstone.flash0",
35
MAINSTONE_FLASH,
36
- blk_by_legacy_dinfo(dinfo),
37
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
38
sector_len, 4, 0, 0, 0, 0, be)) {
39
error_report("Error registering flash memory");
40
exit(1);
41
--
42
2.20.1
43
44
diff view generated by jsdifflib
Deleted patch
1
From: Guenter Roeck <linux@roeck-us.net>
2
1
3
Up to now, the z2 machine only boots if a flash image is provided.
4
This is not really necessary; the machine can boot from initrd or from
5
SD without it. At the same time, having to provide dummy flash images
6
is a nuisance and does not add any real value. Make it optional.
7
8
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Message-id: 20200217210903.18602-1-linux@roeck-us.net
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/arm/z2.c | 6 ------
14
1 file changed, 6 deletions(-)
15
16
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/z2.c
19
+++ b/hw/arm/z2.c
20
@@ -XXX,XX +XXX,XX @@ static void z2_init(MachineState *machine)
21
be = 0;
22
#endif
23
dinfo = drive_get(IF_PFLASH, 0, 0);
24
- if (!dinfo && !qtest_enabled()) {
25
- error_report("Flash image must be given with the "
26
- "'pflash' parameter");
27
- exit(1);
28
- }
29
-
30
if (!pflash_cfi01_register(Z2_FLASH_BASE, "z2.flash0", Z2_FLASH_SIZE,
31
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
32
sector_len, 4, 0, 0, 0, 0, be)) {
33
--
34
2.20.1
35
36
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Writes to AdvSIMD registers flush the bits above 128.
4
5
Buglink: https://bugs.launchpad.net/bugs/1863247
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200214194643.23317-2-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/translate-a64.c | 1 +
12
1 file changed, 1 insertion(+)
13
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
17
+++ b/target/arm/translate-a64.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_simd_ext(DisasContext *s, uint32_t insn)
19
tcg_temp_free_i64(tcg_resl);
20
write_vec_element(s, tcg_resh, rd, 1, MO_64);
21
tcg_temp_free_i64(tcg_resh);
22
+ clear_vec_high(s, true, rd);
23
}
24
25
/* TBL/TBX
26
--
27
2.20.1
28
29
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Writes to AdvSIMD registers flush the bits above 128.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200214194643.23317-3-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/translate-a64.c | 1 +
11
1 file changed, 1 insertion(+)
12
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
16
+++ b/target/arm/translate-a64.c
17
@@ -XXX,XX +XXX,XX @@ static void disas_simd_tb(DisasContext *s, uint32_t insn)
18
tcg_temp_free_i64(tcg_resl);
19
write_vec_element(s, tcg_resh, rd, 1, MO_64);
20
tcg_temp_free_i64(tcg_resh);
21
+ clear_vec_high(s, true, rd);
22
}
23
24
/* ZIP/UZP/TRN
25
--
26
2.20.1
27
28
diff view generated by jsdifflib
1
Add the 64-bit version of the "is this a v8.1 PMUv3?"
1
From: Richard Henderson <richard.henderson@linaro.org>
2
ID register check function, and the _any_ version that
3
checks for either AArch32 or AArch64 support. We'll use
4
this in a later commit.
5
2
6
We don't (yet) do any isar_feature checks on ID_AA64DFR1_EL1,
3
Add the missing field for ID_AA64PFR0, and the predicate.
7
but we move id_aa64dfr1 into the ARMISARegisters struct with
4
Disable it if EL3 is forced off by the board or command-line.
8
id_aa64dfr0, for consistency.
9
5
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230620124418.805717-2-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20200214175116.9164-10-peter.maydell@linaro.org
14
---
11
---
15
target/arm/cpu.h | 15 +++++++++++++--
12
target/arm/cpu.h | 6 ++++++
16
target/arm/cpu.c | 3 ++-
13
target/arm/cpu.c | 4 ++++
17
target/arm/cpu64.c | 6 +++---
14
2 files changed, 10 insertions(+)
18
target/arm/helper.c | 12 +++++++-----
19
4 files changed, 25 insertions(+), 11 deletions(-)
20
15
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.h
18
--- a/target/arm/cpu.h
24
+++ b/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
25
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
20
@@ -XXX,XX +XXX,XX @@ FIELD(ID_AA64PFR0, SEL2, 36, 4)
26
uint64_t id_aa64mmfr0;
21
FIELD(ID_AA64PFR0, MPAM, 40, 4)
27
uint64_t id_aa64mmfr1;
22
FIELD(ID_AA64PFR0, AMU, 44, 4)
28
uint64_t id_aa64mmfr2;
23
FIELD(ID_AA64PFR0, DIT, 48, 4)
29
+ uint64_t id_aa64dfr0;
24
+FIELD(ID_AA64PFR0, RME, 52, 4)
30
+ uint64_t id_aa64dfr1;
25
FIELD(ID_AA64PFR0, CSV2, 56, 4)
31
} isar;
26
FIELD(ID_AA64PFR0, CSV3, 60, 4)
32
uint32_t midr;
27
33
uint32_t revidr;
28
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_sel2(const ARMISARegisters *id)
34
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
29
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SEL2) != 0;
35
uint32_t id_mmfr2;
36
uint32_t id_mmfr3;
37
uint32_t id_mmfr4;
38
- uint64_t id_aa64dfr0;
39
- uint64_t id_aa64dfr1;
40
uint64_t id_aa64afr0;
41
uint64_t id_aa64afr1;
42
uint32_t dbgdidr;
43
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
44
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
45
}
30
}
46
31
47
+static inline bool isar_feature_aa64_pmu_8_1(const ARMISARegisters *id)
32
+static inline bool isar_feature_aa64_rme(const ARMISARegisters *id)
48
+{
33
+{
49
+ return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 4 &&
34
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RME) != 0;
50
+ FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
51
+}
35
+}
52
+
36
+
53
/*
37
static inline bool isar_feature_aa64_vh(const ARMISARegisters *id)
54
* Feature tests for "does this exist in either 32-bit or 64-bit?"
38
{
55
*/
39
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0;
56
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_predinv(const ARMISARegisters *id)
57
return isar_feature_aa64_predinv(id) || isar_feature_aa32_predinv(id);
58
}
59
60
+static inline bool isar_feature_any_pmu_8_1(const ARMISARegisters *id)
61
+{
62
+ return isar_feature_aa64_pmu_8_1(id) || isar_feature_aa32_pmu_8_1(id);
63
+}
64
+
65
/*
66
* Forward to the above feature tests given an ARMCPU pointer.
67
*/
68
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
40
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
69
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/cpu.c
42
--- a/target/arm/cpu.c
71
+++ b/target/arm/cpu.c
43
+++ b/target/arm/cpu.c
72
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
44
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
73
cpu);
45
cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPSDBG, 0);
74
#endif
46
cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
75
} else {
47
ID_AA64PFR0, EL3, 0);
76
- cpu->id_aa64dfr0 = FIELD_DP64(cpu->id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
48
+
77
+ cpu->isar.id_aa64dfr0 =
49
+ /* Disable the realm management extension, which requires EL3. */
78
+ FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
50
+ cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
79
cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, PERFMON, 0);
51
+ ID_AA64PFR0, RME, 0);
80
cpu->pmceid0 = 0;
81
cpu->pmceid1 = 0;
82
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/target/arm/cpu64.c
85
+++ b/target/arm/cpu64.c
86
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
87
cpu->isar.id_isar5 = 0x00011121;
88
cpu->isar.id_isar6 = 0;
89
cpu->isar.id_aa64pfr0 = 0x00002222;
90
- cpu->id_aa64dfr0 = 0x10305106;
91
+ cpu->isar.id_aa64dfr0 = 0x10305106;
92
cpu->isar.id_aa64isar0 = 0x00011120;
93
cpu->isar.id_aa64mmfr0 = 0x00001124;
94
cpu->dbgdidr = 0x3516d000;
95
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
96
cpu->isar.id_isar5 = 0x00011121;
97
cpu->isar.id_isar6 = 0;
98
cpu->isar.id_aa64pfr0 = 0x00002222;
99
- cpu->id_aa64dfr0 = 0x10305106;
100
+ cpu->isar.id_aa64dfr0 = 0x10305106;
101
cpu->isar.id_aa64isar0 = 0x00011120;
102
cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
103
cpu->dbgdidr = 0x3516d000;
104
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
105
cpu->isar.id_isar4 = 0x00011142;
106
cpu->isar.id_isar5 = 0x00011121;
107
cpu->isar.id_aa64pfr0 = 0x00002222;
108
- cpu->id_aa64dfr0 = 0x10305106;
109
+ cpu->isar.id_aa64dfr0 = 0x10305106;
110
cpu->isar.id_aa64isar0 = 0x00011120;
111
cpu->isar.id_aa64mmfr0 = 0x00001124;
112
cpu->dbgdidr = 0x3516d000;
113
diff --git a/target/arm/helper.c b/target/arm/helper.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/target/arm/helper.c
116
+++ b/target/arm/helper.c
117
@@ -XXX,XX +XXX,XX @@
118
#include "hw/semihosting/semihost.h"
119
#include "sysemu/cpus.h"
120
#include "sysemu/kvm.h"
121
+#include "sysemu/tcg.h"
122
#include "qemu/range.h"
123
#include "qapi/qapi-commands-machine-target.h"
124
#include "qapi/error.h"
125
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
126
* check that if they both exist then they agree.
127
*/
128
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
129
- assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
130
- assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
131
- assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) == ctx_cmps);
132
+ assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
133
+ assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
134
+ assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS)
135
+ == ctx_cmps);
136
}
52
}
137
53
138
define_one_arm_cp_reg(cpu, &dbgdidr);
54
if (!cpu->has_el2) {
139
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
140
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0,
141
.access = PL1_R, .type = ARM_CP_CONST,
142
.accessfn = access_aa64_tid3,
143
- .resetvalue = cpu->id_aa64dfr0 },
144
+ .resetvalue = cpu->isar.id_aa64dfr0 },
145
{ .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64,
146
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1,
147
.access = PL1_R, .type = ARM_CP_CONST,
148
.accessfn = access_aa64_tid3,
149
- .resetvalue = cpu->id_aa64dfr1 },
150
+ .resetvalue = cpu->isar.id_aa64dfr1 },
151
{ .name = "ID_AA64DFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
152
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 2,
153
.access = PL1_R, .type = ARM_CP_CONST,
154
--
55
--
155
2.20.1
56
2.34.1
156
57
157
58
diff view generated by jsdifflib
1
The ACTLR2 and HACTLR2 AArch32 system registers didn't exist in ARMv7
1
From: Richard Henderson <richard.henderson@linaro.org>
2
or the original ARMv8. They were later added as optional registers,
3
whose presence is signaled by the ID_MMFR4.AC2 field. From ARMv8.2
4
they are mandatory (ie ID_MMFR4.AC2 must be non-zero).
5
2
6
We implemented HACTLR2 in commit 0e0456ab8895a5e85, but we
3
Define the missing SCR and HCR bits, allow SCR_NSE and {SCR,HCR}_GPF
7
incorrectly made it exist for all v8 CPUs, and we didn't implement
4
to be set, and invalidate TLBs when NSE changes.
8
ACTLR2 at all.
9
5
10
Sort this out by implementing both registers only when they are
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
supposed to exist, and setting the ID_MMFR4 bit for -cpu max.
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
8
Message-id: 20230620124418.805717-3-richard.henderson@linaro.org
13
Note that this removes HACTLR2 from our Cortex-A53, -A47 and -A72
14
CPU models; this is correct, because those CPUs do not implement
15
this register.
16
17
Fixes: 0e0456ab8895a5e85
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-id: 20200214175116.9164-22-peter.maydell@linaro.org
21
---
10
---
22
target/arm/cpu.h | 5 +++++
11
target/arm/cpu.h | 5 +++--
23
target/arm/cpu.c | 1 +
12
target/arm/helper.c | 10 ++++++++--
24
target/arm/cpu64.c | 4 ++++
13
2 files changed, 11 insertions(+), 4 deletions(-)
25
target/arm/helper.c | 32 +++++++++++++++++++++++---------
26
4 files changed, 33 insertions(+), 9 deletions(-)
27
14
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
29
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
17
--- a/target/arm/cpu.h
31
+++ b/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
32
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_hpd(const ARMISARegisters *id)
19
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
33
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, HPDS) != 0;
20
#define HCR_TERR (1ULL << 36)
34
}
21
#define HCR_TEA (1ULL << 37)
35
22
#define HCR_MIOCNCE (1ULL << 38)
36
+static inline bool isar_feature_aa32_ac2(const ARMISARegisters *id)
23
-/* RES0 bit 39 */
37
+{
24
+#define HCR_TME (1ULL << 39)
38
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, AC2) != 0;
25
#define HCR_APK (1ULL << 40)
39
+}
26
#define HCR_API (1ULL << 41)
40
+
27
#define HCR_NV (1ULL << 42)
41
/*
28
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
42
* 64-bit feature tests via id registers.
29
#define HCR_NV2 (1ULL << 45)
43
*/
30
#define HCR_FWB (1ULL << 46)
44
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
31
#define HCR_FIEN (1ULL << 47)
45
index XXXXXXX..XXXXXXX 100644
32
-/* RES0 bit 48 */
46
--- a/target/arm/cpu.c
33
+#define HCR_GPF (1ULL << 48)
47
+++ b/target/arm/cpu.c
34
#define HCR_TID4 (1ULL << 49)
48
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
35
#define HCR_TICAB (1ULL << 50)
49
36
#define HCR_AMVOFFEN (1ULL << 51)
50
t = cpu->isar.id_mmfr4;
37
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
51
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
38
#define SCR_TRNDR (1ULL << 40)
52
+ t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
39
#define SCR_ENTP2 (1ULL << 41)
53
cpu->isar.id_mmfr4 = t;
40
#define SCR_GPF (1ULL << 48)
54
}
41
+#define SCR_NSE (1ULL << 62)
55
#endif
42
56
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
43
#define HSTR_TTEE (1 << 16)
57
index XXXXXXX..XXXXXXX 100644
44
#define HSTR_TJDBX (1 << 17)
58
--- a/target/arm/cpu64.c
59
+++ b/target/arm/cpu64.c
60
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
61
u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */
62
cpu->isar.id_mmfr3 = u;
63
64
+ u = cpu->isar.id_mmfr4;
65
+ u = FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
66
+ cpu->isar.id_mmfr4 = u;
67
+
68
u = cpu->isar.id_aa64dfr0;
69
u = FIELD_DP64(u, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
70
cpu->isar.id_aa64dfr0 = u;
71
diff --git a/target/arm/helper.c b/target/arm/helper.c
45
diff --git a/target/arm/helper.c b/target/arm/helper.c
72
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/helper.c
47
--- a/target/arm/helper.c
74
+++ b/target/arm/helper.c
48
+++ b/target/arm/helper.c
75
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo ats1cp_reginfo[] = {
49
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
76
};
50
if (cpu_isar_feature(aa64_fgt, cpu)) {
77
#endif
51
valid_mask |= SCR_FGTEN;
78
79
+/*
80
+ * ACTLR2 and HACTLR2 map to ACTLR_EL1[63:32] and
81
+ * ACTLR_EL2[63:32]. They exist only if the ID_MMFR4.AC2 field
82
+ * is non-zero, which is never for ARMv7, optionally in ARMv8
83
+ * and mandatorily for ARMv8.2 and up.
84
+ * ACTLR2 is banked for S and NS if EL3 is AArch32. Since QEMU's
85
+ * implementation is RAZ/WI we can ignore this detail, as we
86
+ * do for ACTLR.
87
+ */
88
+static const ARMCPRegInfo actlr2_hactlr2_reginfo[] = {
89
+ { .name = "ACTLR2", .state = ARM_CP_STATE_AA32,
90
+ .cp = 15, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 3,
91
+ .access = PL1_RW, .type = ARM_CP_CONST,
92
+ .resetvalue = 0 },
93
+ { .name = "HACTLR2", .state = ARM_CP_STATE_AA32,
94
+ .cp = 15, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 3,
95
+ .access = PL2_RW, .type = ARM_CP_CONST,
96
+ .resetvalue = 0 },
97
+ REGINFO_SENTINEL
98
+};
99
+
100
void register_cp_regs_for_features(ARMCPU *cpu)
101
{
102
/* Register all the coprocessor registers based on feature bits */
103
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
104
REGINFO_SENTINEL
105
};
106
define_arm_cp_regs(cpu, auxcr_reginfo);
107
- if (arm_feature(env, ARM_FEATURE_V8)) {
108
- /* HACTLR2 maps to ACTLR_EL2[63:32] and is not in ARMv7 */
109
- ARMCPRegInfo hactlr2_reginfo = {
110
- .name = "HACTLR2", .state = ARM_CP_STATE_AA32,
111
- .cp = 15, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 3,
112
- .access = PL2_RW, .type = ARM_CP_CONST,
113
- .resetvalue = 0
114
- };
115
- define_one_arm_cp_reg(cpu, &hactlr2_reginfo);
116
+ if (cpu_isar_feature(aa32_ac2, cpu)) {
117
+ define_arm_cp_regs(cpu, actlr2_hactlr2_reginfo);
118
}
52
}
53
+ if (cpu_isar_feature(aa64_rme, cpu)) {
54
+ valid_mask |= SCR_NSE | SCR_GPF;
55
+ }
56
} else {
57
valid_mask &= ~(SCR_RW | SCR_ST);
58
if (cpu_isar_feature(aa32_ras, cpu)) {
59
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
60
env->cp15.scr_el3 = value;
61
62
/*
63
- * If SCR_EL3.NS changes, i.e. arm_is_secure_below_el3, then
64
+ * If SCR_EL3.{NS,NSE} changes, i.e. change of security state,
65
* we must invalidate all TLBs below EL3.
66
*/
67
- if (changed & SCR_NS) {
68
+ if (changed & (SCR_NS | SCR_NSE)) {
69
tlb_flush_by_mmuidx(env_cpu(env), (ARMMMUIdxBit_E10_0 |
70
ARMMMUIdxBit_E20_0 |
71
ARMMMUIdxBit_E10_1 |
72
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
73
if (cpu_isar_feature(aa64_fwb, cpu)) {
74
valid_mask |= HCR_FWB;
75
}
76
+ if (cpu_isar_feature(aa64_rme, cpu)) {
77
+ valid_mask |= HCR_GPF;
78
+ }
119
}
79
}
120
80
81
if (cpu_isar_feature(any_evt, cpu)) {
121
--
82
--
122
2.20.1
83
2.34.1
123
124
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Select should always be 0 for a regime with one range.
3
With RME, SEL2 must also be present to support secure state.
4
The NS bit is RES1 if SEL2 is not present.
4
5
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200216194343.21331-3-richard.henderson@linaro.org
8
Message-id: 20230620124418.805717-4-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/helper.c | 46 +++++++++++++++++++++++----------------------
11
target/arm/helper.c | 3 +++
11
1 file changed, 24 insertions(+), 22 deletions(-)
12
1 file changed, 3 insertions(+)
12
13
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
16
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
17
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
18
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
18
bool tbi, tbid, epd, hpd, using16k, using64k;
19
int select, tsz;
20
21
- /*
22
- * Bit 55 is always between the two regions, and is canonical for
23
- * determining if address tagging is enabled.
24
- */
25
- select = extract64(va, 55, 1);
26
-
27
if (!regime_has_2_ranges(mmu_idx)) {
28
+ select = 0;
29
tsz = extract32(tcr, 0, 6);
30
using64k = extract32(tcr, 14, 1);
31
using16k = extract32(tcr, 15, 1);
32
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
33
tbid = extract32(tcr, 29, 1);
34
}
19
}
35
epd = false;
20
if (cpu_isar_feature(aa64_sel2, cpu)) {
36
- } else if (!select) {
21
valid_mask |= SCR_EEL2;
37
- tsz = extract32(tcr, 0, 6);
22
+ } else if (cpu_isar_feature(aa64_rme, cpu)) {
38
- epd = extract32(tcr, 7, 1);
23
+ /* With RME and without SEL2, NS is RES1 (R_GSWWH, I_DJJQJ). */
39
- using64k = extract32(tcr, 14, 1);
24
+ value |= SCR_NS;
40
- using16k = extract32(tcr, 15, 1);
25
}
41
- tbi = extract64(tcr, 37, 1);
26
if (cpu_isar_feature(aa64_mte, cpu)) {
42
- hpd = extract64(tcr, 41, 1);
27
valid_mask |= SCR_ATA;
43
- tbid = extract64(tcr, 51, 1);
44
} else {
45
- int tg = extract32(tcr, 30, 2);
46
- using16k = tg == 1;
47
- using64k = tg == 3;
48
- tsz = extract32(tcr, 16, 6);
49
- epd = extract32(tcr, 23, 1);
50
- tbi = extract64(tcr, 38, 1);
51
- hpd = extract64(tcr, 42, 1);
52
- tbid = extract64(tcr, 52, 1);
53
+ /*
54
+ * Bit 55 is always between the two regions, and is canonical for
55
+ * determining if address tagging is enabled.
56
+ */
57
+ select = extract64(va, 55, 1);
58
+ if (!select) {
59
+ tsz = extract32(tcr, 0, 6);
60
+ epd = extract32(tcr, 7, 1);
61
+ using64k = extract32(tcr, 14, 1);
62
+ using16k = extract32(tcr, 15, 1);
63
+ tbi = extract64(tcr, 37, 1);
64
+ hpd = extract64(tcr, 41, 1);
65
+ tbid = extract64(tcr, 51, 1);
66
+ } else {
67
+ int tg = extract32(tcr, 30, 2);
68
+ using16k = tg == 1;
69
+ using64k = tg == 3;
70
+ tsz = extract32(tcr, 16, 6);
71
+ epd = extract32(tcr, 23, 1);
72
+ tbi = extract64(tcr, 38, 1);
73
+ hpd = extract64(tcr, 42, 1);
74
+ tbid = extract64(tcr, 52, 1);
75
+ }
76
}
77
tsz = MIN(tsz, 39); /* TODO: ARMv8.4-TTST */
78
tsz = MAX(tsz, 16); /* TODO: ARMv8.2-LVA */
79
--
28
--
80
2.20.1
29
2.34.1
81
82
diff view generated by jsdifflib
1
The ARMv8.4-PMU extension adds:
1
From: Richard Henderson <richard.henderson@linaro.org>
2
* one new required event, STALL
3
* one new system register PMMIR_EL1
4
2
5
(There are also some more L1-cache related events, but since
3
This includes GPCCR, GPTBR, MFAR, the TLB flush insns PAALL, PAALLOS,
6
we don't implement any cache we don't provide these, in the
4
RPALOS, RPAOS, and the cache flush insns CIPAPA and CIGDPAPA.
7
same way we don't provide the base-PMUv3 cache events.)
8
5
9
The STALL event "counts every attributable cycle on which no
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
attributable instruction or operation was sent for execution on this
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
PE". QEMU doesn't stall in this sense, so this is another
8
Message-id: 20230620124418.805717-5-richard.henderson@linaro.org
12
always-reads-zero event.
13
14
The PMMIR_EL1 register is a read-only register providing
15
implementation-specific information about the PMU; currently it has
16
only one field, SLOTS, which defines behaviour of the STALL_SLOT PMU
17
event. Since QEMU doesn't implement the STALL_SLOT event, we can
18
validly make the register read zero.
19
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Message-id: 20200214175116.9164-15-peter.maydell@linaro.org
23
---
10
---
24
target/arm/cpu.h | 18 ++++++++++++++++++
11
target/arm/cpu.h | 19 ++++++++++
25
target/arm/helper.c | 22 +++++++++++++++++++++-
12
target/arm/helper.c | 84 +++++++++++++++++++++++++++++++++++++++++++++
26
2 files changed, 39 insertions(+), 1 deletion(-)
13
2 files changed, 103 insertions(+)
27
14
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
29
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
17
--- a/target/arm/cpu.h
31
+++ b/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
32
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_pmu_8_1(const ARMISARegisters *id)
19
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
33
FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
20
uint64_t fgt_read[2]; /* HFGRTR, HDFGRTR */
34
}
21
uint64_t fgt_write[2]; /* HFGWTR, HDFGWTR */
35
22
uint64_t fgt_exec[1]; /* HFGITR */
36
+static inline bool isar_feature_aa32_pmu_8_4(const ARMISARegisters *id)
37
+{
38
+ /* 0xf means "non-standard IMPDEF PMU" */
39
+ return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 5 &&
40
+ FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
41
+}
42
+
23
+
43
/*
24
+ /* RME registers */
44
* 64-bit feature tests via id registers.
25
+ uint64_t gpccr_el3;
45
*/
26
+ uint64_t gptbr_el3;
46
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_pmu_8_1(const ARMISARegisters *id)
27
+ uint64_t mfar_el3;
47
FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
28
} cp15;
48
}
29
49
30
struct {
50
+static inline bool isar_feature_aa64_pmu_8_4(const ARMISARegisters *id)
31
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
51
+{
32
uint64_t reset_cbar;
52
+ return FIELD_EX32(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 5 &&
33
uint32_t reset_auxcr;
53
+ FIELD_EX32(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
34
bool reset_hivecs;
54
+}
35
+ uint8_t reset_l0gptsz;
36
37
/*
38
* Intermediate values used during property parsing.
39
@@ -XXX,XX +XXX,XX @@ FIELD(MVFR1, SIMDFMAC, 28, 4)
40
FIELD(MVFR2, SIMDMISC, 0, 4)
41
FIELD(MVFR2, FPMISC, 4, 4)
42
43
+FIELD(GPCCR, PPS, 0, 3)
44
+FIELD(GPCCR, IRGN, 8, 2)
45
+FIELD(GPCCR, ORGN, 10, 2)
46
+FIELD(GPCCR, SH, 12, 2)
47
+FIELD(GPCCR, PGS, 14, 2)
48
+FIELD(GPCCR, GPC, 16, 1)
49
+FIELD(GPCCR, GPCP, 17, 1)
50
+FIELD(GPCCR, L0GPTSZ, 20, 4)
55
+
51
+
56
/*
52
+FIELD(MFAR, FPA, 12, 40)
57
* Feature tests for "does this exist in either 32-bit or 64-bit?"
53
+FIELD(MFAR, NSE, 62, 1)
58
*/
54
+FIELD(MFAR, NS, 63, 1)
59
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_pmu_8_1(const ARMISARegisters *id)
60
return isar_feature_aa64_pmu_8_1(id) || isar_feature_aa32_pmu_8_1(id);
61
}
62
63
+static inline bool isar_feature_any_pmu_8_4(const ARMISARegisters *id)
64
+{
65
+ return isar_feature_aa64_pmu_8_4(id) || isar_feature_aa32_pmu_8_4(id);
66
+}
67
+
55
+
68
/*
56
QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
69
* Forward to the above feature tests given an ARMCPU pointer.
57
70
*/
58
/* If adding a feature bit which corresponds to a Linux ELF
71
diff --git a/target/arm/helper.c b/target/arm/helper.c
59
diff --git a/target/arm/helper.c b/target/arm/helper.c
72
index XXXXXXX..XXXXXXX 100644
60
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/helper.c
61
--- a/target/arm/helper.c
74
+++ b/target/arm/helper.c
62
+++ b/target/arm/helper.c
75
@@ -XXX,XX +XXX,XX @@ static bool pmu_8_1_events_supported(CPUARMState *env)
63
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo sme_reginfo[] = {
76
return cpu_isar_feature(any_pmu_8_1, env_archcpu(env));
64
.access = PL2_RW, .accessfn = access_esm,
77
}
65
.type = ARM_CP_CONST, .resetvalue = 0 },
78
66
};
79
+static bool pmu_8_4_events_supported(CPUARMState *env)
67
+
68
+static void tlbi_aa64_paall_write(CPUARMState *env, const ARMCPRegInfo *ri,
69
+ uint64_t value)
80
+{
70
+{
81
+ /* For events which are supported in any v8.1 PMU */
71
+ CPUState *cs = env_cpu(env);
82
+ return cpu_isar_feature(any_pmu_8_4, env_archcpu(env));
72
+
73
+ tlb_flush(cs);
83
+}
74
+}
84
+
75
+
85
static uint64_t zero_event_get_count(CPUARMState *env)
76
+static void gpccr_write(CPUARMState *env, const ARMCPRegInfo *ri,
86
{
77
+ uint64_t value)
87
/* For events which on QEMU never fire, so their count is always zero */
78
+{
88
@@ -XXX,XX +XXX,XX @@ static const pm_event pm_events[] = {
79
+ /* L0GPTSZ is RO; other bits not mentioned are RES0. */
89
.get_count = zero_event_get_count,
80
+ uint64_t rw_mask = R_GPCCR_PPS_MASK | R_GPCCR_IRGN_MASK |
90
.ns_per_count = zero_event_ns_per,
81
+ R_GPCCR_ORGN_MASK | R_GPCCR_SH_MASK | R_GPCCR_PGS_MASK |
91
},
82
+ R_GPCCR_GPC_MASK | R_GPCCR_GPCP_MASK;
92
+ { .number = 0x03c, /* STALL */
83
+
93
+ .supported = pmu_8_4_events_supported,
84
+ env->cp15.gpccr_el3 = (value & rw_mask) | (env->cp15.gpccr_el3 & ~rw_mask);
94
+ .get_count = zero_event_get_count,
85
+}
95
+ .ns_per_count = zero_event_ns_per,
86
+
96
+ },
87
+static void gpccr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
97
};
88
+{
98
89
+ env->cp15.gpccr_el3 = FIELD_DP64(0, GPCCR, L0GPTSZ,
99
/*
90
+ env_archcpu(env)->reset_l0gptsz);
100
@@ -XXX,XX +XXX,XX @@ static const pm_event pm_events[] = {
91
+}
101
* should first be updated to something sparse instead of the current
92
+
102
* supported_event_map[] array.
93
+static void tlbi_aa64_paallos_write(CPUARMState *env, const ARMCPRegInfo *ri,
103
*/
94
+ uint64_t value)
104
-#define MAX_EVENT_ID 0x24
95
+{
105
+#define MAX_EVENT_ID 0x3c
96
+ CPUState *cs = env_cpu(env);
106
#define UNSUPPORTED_EVENT UINT16_MAX
97
+
107
static uint16_t supported_event_map[MAX_EVENT_ID + 1];
98
+ tlb_flush_all_cpus_synced(cs);
108
99
+}
109
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
100
+
110
};
101
+static const ARMCPRegInfo rme_reginfo[] = {
111
define_arm_cp_regs(cpu, v81_pmu_regs);
102
+ { .name = "GPCCR_EL3", .state = ARM_CP_STATE_AA64,
103
+ .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 1, .opc2 = 6,
104
+ .access = PL3_RW, .writefn = gpccr_write, .resetfn = gpccr_reset,
105
+ .fieldoffset = offsetof(CPUARMState, cp15.gpccr_el3) },
106
+ { .name = "GPTBR_EL3", .state = ARM_CP_STATE_AA64,
107
+ .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 1, .opc2 = 4,
108
+ .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.gptbr_el3) },
109
+ { .name = "MFAR_EL3", .state = ARM_CP_STATE_AA64,
110
+ .opc0 = 3, .opc1 = 6, .crn = 6, .crm = 0, .opc2 = 5,
111
+ .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.mfar_el3) },
112
+ { .name = "TLBI_PAALL", .state = ARM_CP_STATE_AA64,
113
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 4,
114
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
115
+ .writefn = tlbi_aa64_paall_write },
116
+ { .name = "TLBI_PAALLOS", .state = ARM_CP_STATE_AA64,
117
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 1, .opc2 = 4,
118
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
119
+ .writefn = tlbi_aa64_paallos_write },
120
+ /*
121
+ * QEMU does not have a way to invalidate by physical address, thus
122
+ * invalidating a range of physical addresses is accomplished by
123
+ * flushing all tlb entries in the outer sharable domain,
124
+ * just like PAALLOS.
125
+ */
126
+ { .name = "TLBI_RPALOS", .state = ARM_CP_STATE_AA64,
127
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 4, .opc2 = 7,
128
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
129
+ .writefn = tlbi_aa64_paallos_write },
130
+ { .name = "TLBI_RPAOS", .state = ARM_CP_STATE_AA64,
131
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 4, .opc2 = 3,
132
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
133
+ .writefn = tlbi_aa64_paallos_write },
134
+ { .name = "DC_CIPAPA", .state = ARM_CP_STATE_AA64,
135
+ .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 14, .opc2 = 1,
136
+ .access = PL3_W, .type = ARM_CP_NOP },
137
+};
138
+
139
+static const ARMCPRegInfo rme_mte_reginfo[] = {
140
+ { .name = "DC_CIGDPAPA", .state = ARM_CP_STATE_AA64,
141
+ .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 14, .opc2 = 5,
142
+ .access = PL3_W, .type = ARM_CP_NOP },
143
+};
144
#endif /* TARGET_AARCH64 */
145
146
static void define_pmu_regs(ARMCPU *cpu)
147
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
148
if (cpu_isar_feature(aa64_fgt, cpu)) {
149
define_arm_cp_regs(cpu, fgt_reginfo);
112
}
150
}
113
+ if (cpu_isar_feature(any_pmu_8_4, cpu)) {
151
+
114
+ static const ARMCPRegInfo v84_pmmir = {
152
+ if (cpu_isar_feature(aa64_rme, cpu)) {
115
+ .name = "PMMIR_EL1", .state = ARM_CP_STATE_BOTH,
153
+ define_arm_cp_regs(cpu, rme_reginfo);
116
+ .opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 6,
154
+ if (cpu_isar_feature(aa64_mte, cpu)) {
117
+ .access = PL1_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
155
+ define_arm_cp_regs(cpu, rme_mte_reginfo);
118
+ .resetvalue = 0
156
+ }
119
+ };
120
+ define_one_arm_cp_reg(cpu, &v84_pmmir);
121
+ }
157
+ }
122
}
158
#endif
123
159
124
/* We don't know until after realize whether there's a GICv3
160
if (cpu_isar_feature(any_predinv, cpu)) {
125
--
161
--
126
2.20.1
162
2.34.1
127
128
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Use this in the places that were checking ARM_FEATURE_VFP, and
3
Introduce both the enumeration and functions to retrieve
4
are obviously testing for the existance of the register set
4
the current state, and state outside of EL3.
5
as opposed to testing for some particular instruction extension.
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
Message-id: 20200214181547.21408-6-richard.henderson@linaro.org
8
Message-id: 20230620124418.805717-6-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/cpu.h | 6 ++++++
11
target/arm/cpu.h | 89 ++++++++++++++++++++++++++++++++++-----------
13
hw/intc/armv7m_nvic.c | 20 ++++++++++----------
12
target/arm/helper.c | 60 ++++++++++++++++++++++++++++++
14
linux-user/arm/signal.c | 4 ++--
13
2 files changed, 127 insertions(+), 22 deletions(-)
15
target/arm/arch_dump.c | 11 ++++++-----
16
target/arm/cpu.c | 8 ++++----
17
target/arm/helper.c | 4 ++--
18
target/arm/m_helper.c | 11 ++++++-----
19
target/arm/machine.c | 3 +--
20
8 files changed, 37 insertions(+), 30 deletions(-)
21
14
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
17
--- a/target/arm/cpu.h
25
+++ b/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
26
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
19
@@ -XXX,XX +XXX,XX @@ static inline int arm_feature(CPUARMState *env, int feature)
27
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
20
28
}
21
void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp);
29
22
30
+static inline bool isar_feature_aa32_simd_r16(const ARMISARegisters *id)
23
-#if !defined(CONFIG_USER_ONLY)
31
+{
24
/*
32
+ /* Return true if D0-D15 are implemented */
25
+ * ARM v9 security states.
33
+ return FIELD_EX32(id->mvfr0, MVFR0, SIMDREG) > 0;
26
+ * The ordering of the enumeration corresponds to the low 2 bits
34
+}
27
+ * of the GPI value, and (except for Root) the concat of NSE:NS.
35
+
28
+ */
36
static inline bool isar_feature_aa32_simd_r32(const ARMISARegisters *id)
29
+
37
{
30
+typedef enum ARMSecuritySpace {
38
/* Return true if D16-D31 are implemented */
31
+ ARMSS_Secure = 0,
39
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
32
+ ARMSS_NonSecure = 1,
40
index XXXXXXX..XXXXXXX 100644
33
+ ARMSS_Root = 2,
41
--- a/hw/intc/armv7m_nvic.c
34
+ ARMSS_Realm = 3,
42
+++ b/hw/intc/armv7m_nvic.c
35
+} ARMSecuritySpace;
43
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
36
+
44
case 0xd84: /* CSSELR */
37
+/* Return true if @space is secure, in the pre-v9 sense. */
45
return cpu->env.v7m.csselr[attrs.secure];
38
+static inline bool arm_space_is_secure(ARMSecuritySpace space)
46
case 0xd88: /* CPACR */
39
+{
47
- if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
40
+ return space == ARMSS_Secure || space == ARMSS_Root;
48
+ if (!cpu_isar_feature(aa32_simd_r16, cpu)) {
41
+}
49
return 0;
42
+
50
}
43
+/* Return the ARMSecuritySpace for @secure, assuming !RME or EL[0-2]. */
51
return cpu->env.v7m.cpacr[attrs.secure];
44
+static inline ARMSecuritySpace arm_secure_to_space(bool secure)
52
case 0xd8c: /* NSACR */
45
+{
53
- if (!attrs.secure || !arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
46
+ return secure ? ARMSS_Secure : ARMSS_NonSecure;
54
+ if (!attrs.secure || !cpu_isar_feature(aa32_simd_r16, cpu)) {
47
+}
55
return 0;
48
+
56
}
49
+#if !defined(CONFIG_USER_ONLY)
57
return cpu->env.v7m.nsacr;
50
+/**
58
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
51
+ * arm_security_space_below_el3:
59
}
52
+ * @env: cpu context
60
return cpu->env.v7m.sfar;
53
+ *
61
case 0xf34: /* FPCCR */
54
+ * Return the security space of exception levels below EL3, following
62
- if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
55
+ * an exception return to those levels. Unlike arm_security_space,
63
+ if (!cpu_isar_feature(aa32_simd_r16, cpu)) {
56
+ * this doesn't care about the current EL.
64
return 0;
57
+ */
65
}
58
+ARMSecuritySpace arm_security_space_below_el3(CPUARMState *env);
66
if (attrs.secure) {
59
+
67
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
60
+/**
68
return value;
61
+ * arm_is_secure_below_el3:
69
}
62
+ * @env: cpu context
70
case 0xf38: /* FPCAR */
63
+ *
71
- if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
64
* Return true if exception levels below EL3 are in secure state,
72
+ if (!cpu_isar_feature(aa32_simd_r16, cpu)) {
65
- * or would be following an exception return to that level.
73
return 0;
66
- * Unlike arm_is_secure() (which is always a question about the
74
}
67
- * _current_ state of the CPU) this doesn't care about the current
75
return cpu->env.v7m.fpcar[attrs.secure];
68
- * EL or mode.
76
case 0xf3c: /* FPDSCR */
69
+ * or would be following an exception return to those levels.
77
- if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
70
*/
78
+ if (!cpu_isar_feature(aa32_simd_r16, cpu)) {
71
static inline bool arm_is_secure_below_el3(CPUARMState *env)
79
return 0;
72
{
80
}
73
- assert(!arm_feature(env, ARM_FEATURE_M));
81
return cpu->env.v7m.fpdscr[attrs.secure];
74
- if (arm_feature(env, ARM_FEATURE_EL3)) {
82
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
75
- return !(env->cp15.scr_el3 & SCR_NS);
83
}
76
- } else {
84
break;
77
- /* If EL3 is not supported then the secure state is implementation
85
case 0xd88: /* CPACR */
78
- * defined, in which case QEMU defaults to non-secure.
86
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
79
- */
87
+ if (cpu_isar_feature(aa32_simd_r16, cpu)) {
80
- return false;
88
/* We implement only the Floating Point extension's CP10/CP11 */
81
- }
89
cpu->env.v7m.cpacr[attrs.secure] = value & (0xf << 20);
82
+ ARMSecuritySpace ss = arm_security_space_below_el3(env);
90
}
83
+ return ss == ARMSS_Secure;
91
break;
84
}
92
case 0xd8c: /* NSACR */
85
93
- if (attrs.secure && arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
86
/* Return true if the CPU is AArch64 EL3 or AArch32 Mon */
94
+ if (attrs.secure && cpu_isar_feature(aa32_simd_r16, cpu)) {
87
@@ -XXX,XX +XXX,XX @@ static inline bool arm_is_el3_or_mon(CPUARMState *env)
95
/* We implement only the Floating Point extension's CP10/CP11 */
88
return false;
96
cpu->env.v7m.nsacr = value & (3 << 10);
89
}
97
}
90
98
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
91
-/* Return true if the processor is in secure state */
99
break;
92
+/**
100
}
93
+ * arm_security_space:
101
case 0xf34: /* FPCCR */
94
+ * @env: cpu context
102
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
95
+ *
103
+ if (cpu_isar_feature(aa32_simd_r16, cpu)) {
96
+ * Return the current security space of the cpu.
104
/* Not all bits here are banked. */
97
+ */
105
uint32_t fpccr_s;
98
+ARMSecuritySpace arm_security_space(CPUARMState *env);
106
99
+
107
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
100
+/**
108
}
101
+ * arm_is_secure:
109
break;
102
+ * @env: cpu context
110
case 0xf38: /* FPCAR */
103
+ *
111
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
104
+ * Return true if the processor is in secure state.
112
+ if (cpu_isar_feature(aa32_simd_r16, cpu)) {
105
+ */
113
value &= ~7;
106
static inline bool arm_is_secure(CPUARMState *env)
114
cpu->env.v7m.fpcar[attrs.secure] = value;
107
{
115
}
108
- if (arm_feature(env, ARM_FEATURE_M)) {
116
break;
109
- return env->v7m.secure;
117
case 0xf3c: /* FPDSCR */
110
- }
118
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
111
- if (arm_is_el3_or_mon(env)) {
119
+ if (cpu_isar_feature(aa32_simd_r16, cpu)) {
112
- return true;
120
value &= 0x07c00000;
113
- }
121
cpu->env.v7m.fpdscr[attrs.secure] = value;
114
- return arm_is_secure_below_el3(env);
122
}
115
+ return arm_space_is_secure(arm_security_space(env));
123
diff --git a/linux-user/arm/signal.c b/linux-user/arm/signal.c
116
}
124
index XXXXXXX..XXXXXXX 100644
117
125
--- a/linux-user/arm/signal.c
118
/*
126
+++ b/linux-user/arm/signal.c
119
@@ -XXX,XX +XXX,XX @@ static inline bool arm_is_el2_enabled(CPUARMState *env)
127
@@ -XXX,XX +XXX,XX @@ static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
120
}
128
setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
121
129
/* Save coprocessor signal frame. */
122
#else
130
regspace = uc->tuc_regspace;
123
+static inline ARMSecuritySpace arm_security_space_below_el3(CPUARMState *env)
131
- if (arm_feature(env, ARM_FEATURE_VFP)) {
124
+{
132
+ if (cpu_isar_feature(aa32_simd_r16, env_archcpu(env))) {
125
+ return ARMSS_NonSecure;
133
regspace = setup_sigframe_v2_vfp(regspace, env);
126
+}
134
}
127
+
135
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
128
static inline bool arm_is_secure_below_el3(CPUARMState *env)
136
@@ -XXX,XX +XXX,XX @@ static int do_sigframe_return_v2(CPUARMState *env,
129
{
137
130
return false;
138
/* Restore coprocessor signal frame */
131
}
139
regspace = uc->tuc_regspace;
132
140
- if (arm_feature(env, ARM_FEATURE_VFP)) {
133
+static inline ARMSecuritySpace arm_security_space(CPUARMState *env)
141
+ if (cpu_isar_feature(aa32_simd_r16, env_archcpu(env))) {
134
+{
142
regspace = restore_sigframe_v2_vfp(env, regspace);
135
+ return ARMSS_NonSecure;
143
if (!regspace) {
136
+}
144
return 1;
137
+
145
diff --git a/target/arm/arch_dump.c b/target/arm/arch_dump.c
138
static inline bool arm_is_secure(CPUARMState *env)
146
index XXXXXXX..XXXXXXX 100644
139
{
147
--- a/target/arm/arch_dump.c
140
return false;
148
+++ b/target/arm/arch_dump.c
149
@@ -XXX,XX +XXX,XX @@ int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
150
int cpuid, void *opaque)
151
{
152
struct arm_note note;
153
- CPUARMState *env = &ARM_CPU(cs)->env;
154
+ ARMCPU *cpu = ARM_CPU(cs);
155
+ CPUARMState *env = &cpu->env;
156
DumpState *s = opaque;
157
- int ret, i, fpvalid = !!arm_feature(env, ARM_FEATURE_VFP);
158
+ int ret, i;
159
+ bool fpvalid = cpu_isar_feature(aa32_simd_r16, cpu);
160
161
arm_note_init(&note, s, "CORE", 5, NT_PRSTATUS, sizeof(note.prstatus));
162
163
@@ -XXX,XX +XXX,XX @@ int cpu_get_dump_info(ArchDumpInfo *info,
164
ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
165
{
166
ARMCPU *cpu = ARM_CPU(first_cpu);
167
- CPUARMState *env = &cpu->env;
168
size_t note_size;
169
170
if (class == ELFCLASS64) {
171
@@ -XXX,XX +XXX,XX @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
172
note_size += AARCH64_PRFPREG_NOTE_SIZE;
173
#ifdef TARGET_AARCH64
174
if (cpu_isar_feature(aa64_sve, cpu)) {
175
- note_size += AARCH64_SVE_NOTE_SIZE(env);
176
+ note_size += AARCH64_SVE_NOTE_SIZE(&cpu->env);
177
}
178
#endif
179
} else {
180
note_size = ARM_PRSTATUS_NOTE_SIZE;
181
- if (arm_feature(env, ARM_FEATURE_VFP)) {
182
+ if (cpu_isar_feature(aa32_simd_r16, cpu)) {
183
note_size += ARM_VFP_NOTE_SIZE;
184
}
185
}
186
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
187
index XXXXXXX..XXXXXXX 100644
188
--- a/target/arm/cpu.c
189
+++ b/target/arm/cpu.c
190
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
191
env->v7m.ccr[M_REG_S] |= R_V7M_CCR_UNALIGN_TRP_MASK;
192
}
193
194
- if (arm_feature(env, ARM_FEATURE_VFP)) {
195
+ if (cpu_isar_feature(aa32_simd_r16, cpu)) {
196
env->v7m.fpccr[M_REG_NS] = R_V7M_FPCCR_ASPEN_MASK;
197
env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK |
198
R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK;
199
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_dump_state(CPUState *cs, FILE *f, int flags)
200
int numvfpregs = 0;
201
if (cpu_isar_feature(aa32_simd_r32, cpu)) {
202
numvfpregs = 32;
203
- } else if (arm_feature(env, ARM_FEATURE_VFP)) {
204
+ } else if (cpu_isar_feature(aa32_simd_r16, cpu)) {
205
numvfpregs = 16;
206
}
207
for (i = 0; i < numvfpregs; i++) {
208
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
209
* KVM does not currently allow us to lie to the guest about its
210
* ID/feature registers, so the guest always sees what the host has.
211
*/
212
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
213
+ if (cpu_isar_feature(aa32_simd_r16, cpu)) {
214
cpu->has_vfp = true;
215
if (!kvm_enabled()) {
216
qdev_property_add_static(DEVICE(obj), &arm_cpu_has_vfp_property);
217
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
218
* We rely on no XScale CPU having VFP so we can use the same bits in the
219
* TB flags field for VECSTRIDE and XSCALE_CPAR.
220
*/
221
- assert(!(arm_feature(env, ARM_FEATURE_VFP) &&
222
+ assert(!(cpu_isar_feature(aa32_simd_r16, cpu) &&
223
arm_feature(env, ARM_FEATURE_XSCALE)));
224
225
if (arm_feature(env, ARM_FEATURE_V7) &&
226
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
227
index XXXXXXX..XXXXXXX 100644
142
index XXXXXXX..XXXXXXX 100644
228
--- a/target/arm/helper.c
143
--- a/target/arm/helper.c
229
+++ b/target/arm/helper.c
144
+++ b/target/arm/helper.c
230
@@ -XXX,XX +XXX,XX @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
145
@@ -XXX,XX +XXX,XX @@ void aarch64_sve_change_el(CPUARMState *env, int old_el,
231
* ASEDIS [31] and D32DIS [30] are both UNK/SBZP without VFP.
232
* TRCDIS [28] is RAZ/WI since we do not implement a trace macrocell.
233
*/
234
- if (arm_feature(env, ARM_FEATURE_VFP)) {
235
+ if (cpu_isar_feature(aa32_simd_r16, env_archcpu(env))) {
236
/* VFP coprocessor: cp10 & cp11 [23:20] */
237
mask |= (1 << 31) | (1 << 30) | (0xf << 20);
238
239
@@ -XXX,XX +XXX,XX @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
240
} else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
241
gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
242
35, "arm-vfp3.xml", 0);
243
- } else if (arm_feature(env, ARM_FEATURE_VFP)) {
244
+ } else if (cpu_isar_feature(aa32_simd_r16, cpu)) {
245
gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
246
19, "arm-vfp.xml", 0);
247
}
146
}
248
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
147
}
249
index XXXXXXX..XXXXXXX 100644
148
#endif
250
--- a/target/arm/m_helper.c
149
+
251
+++ b/target/arm/m_helper.c
150
+#ifndef CONFIG_USER_ONLY
252
@@ -XXX,XX +XXX,XX @@ static uint32_t v7m_integrity_sig(CPUARMState *env, uint32_t lr)
151
+ARMSecuritySpace arm_security_space(CPUARMState *env)
253
*/
152
+{
254
uint32_t sig = 0xfefa125a;
153
+ if (arm_feature(env, ARM_FEATURE_M)) {
255
154
+ return arm_secure_to_space(env->v7m.secure);
256
- if (!arm_feature(env, ARM_FEATURE_VFP) || (lr & R_V7M_EXCRET_FTYPE_MASK)) {
155
+ }
257
+ if (!cpu_isar_feature(aa32_simd_r16, env_archcpu(env))
156
+
258
+ || (lr & R_V7M_EXCRET_FTYPE_MASK)) {
157
+ /*
259
sig |= 1;
158
+ * If EL3 is not supported then the secure state is implementation
260
}
159
+ * defined, in which case QEMU defaults to non-secure.
261
return sig;
160
+ */
262
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
161
+ if (!arm_feature(env, ARM_FEATURE_EL3)) {
263
162
+ return ARMSS_NonSecure;
264
if (dotailchain) {
163
+ }
265
/* Sanitize LR FType and PREFIX bits */
164
+
266
- if (!arm_feature(env, ARM_FEATURE_VFP)) {
165
+ /* Check for AArch64 EL3 or AArch32 Mon. */
267
+ if (!cpu_isar_feature(aa32_simd_r16, cpu)) {
166
+ if (is_a64(env)) {
268
lr |= R_V7M_EXCRET_FTYPE_MASK;
167
+ if (extract32(env->pstate, 2, 2) == 3) {
269
}
168
+ if (cpu_isar_feature(aa64_rme, env_archcpu(env))) {
270
lr = deposit32(lr, 24, 8, 0xff);
169
+ return ARMSS_Root;
271
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
170
+ } else {
272
171
+ return ARMSS_Secure;
273
ftype = excret & R_V7M_EXCRET_FTYPE_MASK;
172
+ }
274
173
+ }
275
- if (!arm_feature(env, ARM_FEATURE_VFP) && !ftype) {
174
+ } else {
276
+ if (!ftype && !cpu_isar_feature(aa32_simd_r16, cpu)) {
175
+ if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) {
277
qemu_log_mask(LOG_GUEST_ERROR, "M profile: zero FTYPE in exception "
176
+ return ARMSS_Secure;
278
"exit PC value 0x%" PRIx32 " is UNPREDICTABLE "
177
+ }
279
"if FPU not present\n",
178
+ }
280
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
179
+
281
* SFPA is RAZ/WI from NS. FPCA is RO if NSACR.CP10 == 0,
180
+ return arm_security_space_below_el3(env);
282
* RES0 if the FPU is not present, and is stored in the S bank
181
+}
283
*/
182
+
284
- if (arm_feature(env, ARM_FEATURE_VFP) &&
183
+ARMSecuritySpace arm_security_space_below_el3(CPUARMState *env)
285
+ if (cpu_isar_feature(aa32_simd_r16, env_archcpu(env)) &&
184
+{
286
extract32(env->v7m.nsacr, 10, 1)) {
185
+ assert(!arm_feature(env, ARM_FEATURE_M));
287
env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
186
+
288
env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK;
187
+ /*
289
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
188
+ * If EL3 is not supported then the secure state is implementation
290
env->v7m.control[env->v7m.secure] &= ~R_V7M_CONTROL_NPRIV_MASK;
189
+ * defined, in which case QEMU defaults to non-secure.
291
env->v7m.control[env->v7m.secure] |= val & R_V7M_CONTROL_NPRIV_MASK;
190
+ */
292
}
191
+ if (!arm_feature(env, ARM_FEATURE_EL3)) {
293
- if (arm_feature(env, ARM_FEATURE_VFP)) {
192
+ return ARMSS_NonSecure;
294
+ if (cpu_isar_feature(aa32_simd_r16, env_archcpu(env))) {
193
+ }
295
/*
194
+
296
* SFPA is RAZ/WI from NS or if no FPU.
195
+ /*
297
* FPCA is RO if NSACR.CP10 == 0, RES0 if the FPU is not present.
196
+ * Note NSE cannot be set without RME, and NSE & !NS is Reserved.
298
diff --git a/target/arm/machine.c b/target/arm/machine.c
197
+ * Ignoring NSE when !NS retains consistency without having to
299
index XXXXXXX..XXXXXXX 100644
198
+ * modify other predicates.
300
--- a/target/arm/machine.c
199
+ */
301
+++ b/target/arm/machine.c
200
+ if (!(env->cp15.scr_el3 & SCR_NS)) {
302
@@ -XXX,XX +XXX,XX @@
201
+ return ARMSS_Secure;
303
static bool vfp_needed(void *opaque)
202
+ } else if (env->cp15.scr_el3 & SCR_NSE) {
304
{
203
+ return ARMSS_Realm;
305
ARMCPU *cpu = opaque;
204
+ } else {
306
- CPUARMState *env = &cpu->env;
205
+ return ARMSS_NonSecure;
307
206
+ }
308
- return arm_feature(env, ARM_FEATURE_VFP);
207
+}
309
+ return cpu_isar_feature(aa32_simd_r16, cpu);
208
+#endif /* !CONFIG_USER_ONLY */
310
}
311
312
static int get_fpscr(QEMUFile *f, void *opaque, size_t size,
313
--
209
--
314
2.20.1
210
2.34.1
315
316
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 will eventually remove the early ARM_FEATURE_VFP test,
3
We will need 2 bits to represent ARMSecurityState.
4
so add a proper test for each trans_* that does not already
5
have another ISA test.
6
4
5
Do not attempt to replace or widen secure, even though it
6
logically overlaps the new field -- there are uses within
7
e.g. hw/block/pflash_cfi01.c, which don't know anything
8
specific about ARM.
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200214181547.21408-11-richard.henderson@linaro.org
12
Message-id: 20230620124418.805717-7-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
14
---
12
target/arm/translate-vfp.inc.c | 78 ++++++++++++++++++++++++++++++----
15
include/exec/memattrs.h | 9 ++++++++-
13
1 file changed, 69 insertions(+), 9 deletions(-)
16
1 file changed, 8 insertions(+), 1 deletion(-)
14
17
15
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
18
diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-vfp.inc.c
20
--- a/include/exec/memattrs.h
18
+++ b/target/arm/translate-vfp.inc.c
21
+++ b/include/exec/memattrs.h
19
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
22
@@ -XXX,XX +XXX,XX @@ typedef struct MemTxAttrs {
20
int pass;
23
* "didn't specify" if necessary.
21
uint32_t offset;
24
*/
22
25
unsigned int unspecified:1;
23
+ /* SIZE == 2 is a VFP instruction; otherwise NEON. */
26
- /* ARM/AMBA: TrustZone Secure access
24
+ if (a->size == 2
27
+ /*
25
+ ? !dc_isar_feature(aa32_fpsp_v2, s)
28
+ * ARM/AMBA: TrustZone Secure access
26
+ : !arm_dc_feature(s, ARM_FEATURE_NEON)) {
29
* x86: System Management Mode access
27
+ return false;
30
*/
28
+ }
31
unsigned int secure:1;
29
+
32
+ /*
30
/* UNDEF accesses to D16-D31 if they don't exist */
33
+ * ARM: ArmSecuritySpace. This partially overlaps secure, but it is
31
if (!dc_isar_feature(aa32_simd_r32, s) && (a->vn & 0x10)) {
34
+ * easier to have both fields to assist code that does not understand
32
return false;
35
+ * ARMv9 RME, or no specific knowledge of ARM at all (e.g. pflash).
33
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
36
+ */
34
pass = extract32(offset, 2, 1);
37
+ unsigned int space:2;
35
offset = extract32(offset, 0, 2) * 8;
38
/* Memory access is usermode (unprivileged) */
36
39
unsigned int user:1;
37
- if (a->size != 2 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
38
- return false;
39
- }
40
-
41
if (!vfp_access_check(s)) {
42
return true;
43
}
44
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
45
int pass;
46
uint32_t offset;
47
48
+ /* SIZE == 2 is a VFP instruction; otherwise NEON. */
49
+ if (a->size == 2
50
+ ? !dc_isar_feature(aa32_fpsp_v2, s)
51
+ : !arm_dc_feature(s, ARM_FEATURE_NEON)) {
52
+ return false;
53
+ }
54
+
55
/* UNDEF accesses to D16-D31 if they don't exist */
56
if (!dc_isar_feature(aa32_simd_r32, s) && (a->vn & 0x10)) {
57
return false;
58
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
59
pass = extract32(offset, 2, 1);
60
offset = extract32(offset, 0, 2) * 8;
61
62
- if (a->size != 2 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
63
- return false;
64
- }
65
-
66
if (!vfp_access_check(s)) {
67
return true;
68
}
69
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
70
TCGv_i32 tmp;
71
bool ignore_vfp_enabled = false;
72
73
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
74
+ return false;
75
+ }
76
+
77
if (arm_dc_feature(s, ARM_FEATURE_M)) {
78
/*
79
* The only M-profile VFP vmrs/vmsr sysreg is FPSCR.
80
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_single(DisasContext *s, arg_VMOV_single *a)
81
{
82
TCGv_i32 tmp;
83
84
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
85
+ return false;
86
+ }
87
+
88
if (!vfp_access_check(s)) {
89
return true;
90
}
91
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_sp(DisasContext *s, arg_VMOV_64_sp *a)
92
{
93
TCGv_i32 tmp;
94
95
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
96
+ return false;
97
+ }
98
+
99
/*
40
/*
100
* VMOV between two general-purpose registers and two single precision
101
* floating point registers
102
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a)
103
104
/*
105
* VMOV between two general-purpose registers and one double precision
106
- * floating point register
107
+ * floating point register. Note that this does not require support
108
+ * for double precision arithmetic.
109
*/
110
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
111
+ return false;
112
+ }
113
114
/* UNDEF accesses to D16-D31 if they don't exist */
115
if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
116
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
117
uint32_t offset;
118
TCGv_i32 addr, tmp;
119
120
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
121
+ return false;
122
+ }
123
+
124
if (!vfp_access_check(s)) {
125
return true;
126
}
127
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
128
TCGv_i32 addr;
129
TCGv_i64 tmp;
130
131
+ /* Note that this does not require support for double arithmetic. */
132
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
133
+ return false;
134
+ }
135
+
136
/* UNDEF accesses to D16-D31 if they don't exist */
137
if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
138
return false;
139
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_sp(DisasContext *s, arg_VLDM_VSTM_sp *a)
140
TCGv_i32 addr, tmp;
141
int i, n;
142
143
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
144
+ return false;
145
+ }
146
+
147
n = a->imm;
148
149
if (n == 0 || (a->vd + n) > 32) {
150
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a)
151
TCGv_i64 tmp;
152
int i, n;
153
154
+ /* Note that this does not require support for double arithmetic. */
155
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
156
+ return false;
157
+ }
158
+
159
n = a->imm >> 1;
160
161
if (n == 0 || (a->vd + n) > 32 || n > 16) {
162
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_sp(DisasContext *s, VFPGen3OpSPFn *fn,
163
TCGv_i32 f0, f1, fd;
164
TCGv_ptr fpst;
165
166
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
167
+ return false;
168
+ }
169
+
170
if (!dc_isar_feature(aa32_fpshvec, s) &&
171
(veclen != 0 || s->vec_stride != 0)) {
172
return false;
173
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
174
int veclen = s->vec_len;
175
TCGv_i32 f0, fd;
176
177
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
178
+ return false;
179
+ }
180
+
181
if (!dc_isar_feature(aa32_fpshvec, s) &&
182
(veclen != 0 || s->vec_stride != 0)) {
183
return false;
184
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_sp(DisasContext *s, arg_VCMP_sp *a)
185
{
186
TCGv_i32 vd, vm;
187
188
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
189
+ return false;
190
+ }
191
+
192
/* Vm/M bits must be zero for the Z variant */
193
if (a->z && a->vm != 0) {
194
return false;
195
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_sp(DisasContext *s, arg_VCVT_int_sp *a)
196
TCGv_i32 vm;
197
TCGv_ptr fpst;
198
199
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
200
+ return false;
201
+ }
202
+
203
if (!vfp_access_check(s)) {
204
return true;
205
}
206
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp_int(DisasContext *s, arg_VCVT_sp_int *a)
207
TCGv_i32 vm;
208
TCGv_ptr fpst;
209
210
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
211
+ return false;
212
+ }
213
+
214
if (!vfp_access_check(s)) {
215
return true;
216
}
217
--
41
--
218
2.20.1
42
2.34.1
219
220
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 old name, isar_feature_aa32_fp_d32, does not reflect
3
It will be helpful to have ARMMMUIdx_Phys_* to be in the same
4
the MVFR0 field name, SIMDReg.
4
relative order as ARMSecuritySpace enumerators. This requires
5
the adjustment to the nstable check. While there, check for being
6
in secure state rather than rely on clearing the low bit making
7
no change to non-secure state.
5
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Message-id: 20230620124418.805717-8-richard.henderson@linaro.org
8
Message-id: 20200214181547.21408-3-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
[PMM: wrapped one long line]
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/cpu.h | 2 +-
14
target/arm/cpu.h | 12 ++++++------
14
target/arm/translate-vfp.inc.c | 53 +++++++++++++++++-----------------
15
target/arm/ptw.c | 12 +++++-------
15
2 files changed, 28 insertions(+), 27 deletions(-)
16
2 files changed, 11 insertions(+), 13 deletions(-)
16
17
17
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
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
20
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
22
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
22
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
23
ARMMMUIdx_E2 = 6 | ARM_MMU_IDX_A,
23
}
24
ARMMMUIdx_E3 = 7 | ARM_MMU_IDX_A,
24
25
25
-static inline bool isar_feature_aa32_fp_d32(const ARMISARegisters *id)
26
- /* TLBs with 1-1 mapping to the physical address spaces. */
26
+static inline bool isar_feature_aa32_simd_r32(const ARMISARegisters *id)
27
- ARMMMUIdx_Phys_NS = 8 | ARM_MMU_IDX_A,
27
{
28
- ARMMMUIdx_Phys_S = 9 | ARM_MMU_IDX_A,
28
/* Return true if D16-D31 are implemented */
29
-
29
return FIELD_EX32(id->mvfr0, MVFR0, SIMDREG) >= 2;
30
/*
30
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
31
* Used for second stage of an S12 page table walk, or for descriptor
32
* loads during first stage of an S1 page table walk. Note that both
33
* are in use simultaneously for SecureEL2: the security state for
34
* the S2 ptw is selected by the NS bit from the S1 ptw.
35
*/
36
- ARMMMUIdx_Stage2 = 10 | ARM_MMU_IDX_A,
37
- ARMMMUIdx_Stage2_S = 11 | ARM_MMU_IDX_A,
38
+ ARMMMUIdx_Stage2_S = 8 | ARM_MMU_IDX_A,
39
+ ARMMMUIdx_Stage2 = 9 | ARM_MMU_IDX_A,
40
+
41
+ /* TLBs with 1-1 mapping to the physical address spaces. */
42
+ ARMMMUIdx_Phys_S = 10 | ARM_MMU_IDX_A,
43
+ ARMMMUIdx_Phys_NS = 11 | ARM_MMU_IDX_A,
44
45
/*
46
* These are not allocated TLBs and are used only for AT system
47
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
31
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/translate-vfp.inc.c
49
--- a/target/arm/ptw.c
33
+++ b/target/arm/translate-vfp.inc.c
50
+++ b/target/arm/ptw.c
34
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
51
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
52
descaddr |= (address >> (stride * (4 - level))) & indexmask;
53
descaddr &= ~7ULL;
54
nstable = !regime_is_stage2(mmu_idx) && extract32(tableattrs, 4, 1);
55
- if (nstable) {
56
+ if (nstable && ptw->in_secure) {
57
/*
58
* Stage2_S -> Stage2 or Phys_S -> Phys_NS
59
- * Assert that the non-secure idx are even, and relative order.
60
+ * Assert the relative order of the secure/non-secure indexes.
61
*/
62
- QEMU_BUILD_BUG_ON((ARMMMUIdx_Phys_NS & 1) != 0);
63
- QEMU_BUILD_BUG_ON((ARMMMUIdx_Stage2 & 1) != 0);
64
- QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_NS + 1 != ARMMMUIdx_Phys_S);
65
- QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2 + 1 != ARMMMUIdx_Stage2_S);
66
- ptw->in_ptw_idx &= ~1;
67
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_S + 1 != ARMMMUIdx_Phys_NS);
68
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2_S + 1 != ARMMMUIdx_Stage2);
69
+ ptw->in_ptw_idx += 1;
70
ptw->in_secure = false;
35
}
71
}
36
72
if (!S1_ptw_translate(env, ptw, descaddr, fi)) {
37
/* UNDEF accesses to D16-D31 if they don't exist */
38
- if (dp && !dc_isar_feature(aa32_fp_d32, s) &&
39
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
40
((a->vm | a->vn | a->vd) & 0x10)) {
41
return false;
42
}
43
@@ -XXX,XX +XXX,XX @@ static bool trans_VMINMAXNM(DisasContext *s, arg_VMINMAXNM *a)
44
}
45
46
/* UNDEF accesses to D16-D31 if they don't exist */
47
- if (dp && !dc_isar_feature(aa32_fp_d32, s) &&
48
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
49
((a->vm | a->vn | a->vd) & 0x10)) {
50
return false;
51
}
52
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
53
}
54
55
/* UNDEF accesses to D16-D31 if they don't exist */
56
- if (dp && !dc_isar_feature(aa32_fp_d32, s) &&
57
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
58
((a->vm | a->vd) & 0x10)) {
59
return false;
60
}
61
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
62
}
63
64
/* UNDEF accesses to D16-D31 if they don't exist */
65
- if (dp && !dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
66
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
67
return false;
68
}
69
70
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
71
uint32_t offset;
72
73
/* UNDEF accesses to D16-D31 if they don't exist */
74
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vn & 0x10)) {
75
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vn & 0x10)) {
76
return false;
77
}
78
79
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
80
uint32_t offset;
81
82
/* UNDEF accesses to D16-D31 if they don't exist */
83
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vn & 0x10)) {
84
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vn & 0x10)) {
85
return false;
86
}
87
88
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
89
}
90
91
/* UNDEF accesses to D16-D31 if they don't exist */
92
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vn & 0x10)) {
93
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vn & 0x10)) {
94
return false;
95
}
96
97
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a)
98
*/
99
100
/* UNDEF accesses to D16-D31 if they don't exist */
101
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
102
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
103
return false;
104
}
105
106
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
107
TCGv_i64 tmp;
108
109
/* UNDEF accesses to D16-D31 if they don't exist */
110
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vd & 0x10)) {
111
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
112
return false;
113
}
114
115
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a)
116
}
117
118
/* UNDEF accesses to D16-D31 if they don't exist */
119
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vd + n) > 16) {
120
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd + n) > 16) {
121
return false;
122
}
123
124
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
125
TCGv_ptr fpst;
126
127
/* UNDEF accesses to D16-D31 if they don't exist */
128
- if (!dc_isar_feature(aa32_fp_d32, s) && ((vd | vn | vm) & 0x10)) {
129
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vn | vm) & 0x10)) {
130
return false;
131
}
132
133
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
134
TCGv_i64 f0, fd;
135
136
/* UNDEF accesses to D16-D31 if they don't exist */
137
- if (!dc_isar_feature(aa32_fp_d32, s) && ((vd | vm) & 0x10)) {
138
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vm) & 0x10)) {
139
return false;
140
}
141
142
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
143
}
144
145
/* UNDEF accesses to D16-D31 if they don't exist. */
146
- if (!dc_isar_feature(aa32_fp_d32, s) && ((a->vd | a->vn | a->vm) & 0x10)) {
147
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
148
+ ((a->vd | a->vn | a->vm) & 0x10)) {
149
return false;
150
}
151
152
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
153
vd = a->vd;
154
155
/* UNDEF accesses to D16-D31 if they don't exist. */
156
- if (!dc_isar_feature(aa32_fp_d32, s) && (vd & 0x10)) {
157
+ if (!dc_isar_feature(aa32_simd_r32, s) && (vd & 0x10)) {
158
return false;
159
}
160
161
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
162
}
163
164
/* UNDEF accesses to D16-D31 if they don't exist. */
165
- if (!dc_isar_feature(aa32_fp_d32, s) && ((a->vd | a->vm) & 0x10)) {
166
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((a->vd | a->vm) & 0x10)) {
167
return false;
168
}
169
170
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
171
}
172
173
/* UNDEF accesses to D16-D31 if they don't exist. */
174
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vd & 0x10)) {
175
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
176
return false;
177
}
178
179
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
180
}
181
182
/* UNDEF accesses to D16-D31 if they don't exist. */
183
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
184
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
185
return false;
186
}
187
188
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
189
}
190
191
/* UNDEF accesses to D16-D31 if they don't exist. */
192
- if (!dc_isar_feature(aa32_fp_d32, s) && ((a->vd | a->vm) & 0x10)) {
193
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((a->vd | a->vm) & 0x10)) {
194
return false;
195
}
196
197
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
198
}
199
200
/* UNDEF accesses to D16-D31 if they don't exist. */
201
- if (!dc_isar_feature(aa32_fp_d32, s) && ((a->vd | a->vm) & 0x10)) {
202
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((a->vd | a->vm) & 0x10)) {
203
return false;
204
}
205
206
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
207
}
208
209
/* UNDEF accesses to D16-D31 if they don't exist. */
210
- if (!dc_isar_feature(aa32_fp_d32, s) && ((a->vd | a->vm) & 0x10)) {
211
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((a->vd | a->vm) & 0x10)) {
212
return false;
213
}
214
215
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
216
TCGv_i32 vm;
217
218
/* UNDEF accesses to D16-D31 if they don't exist. */
219
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vd & 0x10)) {
220
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
221
return false;
222
}
223
224
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
225
TCGv_i32 vd;
226
227
/* UNDEF accesses to D16-D31 if they don't exist. */
228
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
229
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
230
return false;
231
}
232
233
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
234
TCGv_ptr fpst;
235
236
/* UNDEF accesses to D16-D31 if they don't exist. */
237
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vd & 0x10)) {
238
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
239
return false;
240
}
241
242
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
243
}
244
245
/* UNDEF accesses to D16-D31 if they don't exist. */
246
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
247
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
248
return false;
249
}
250
251
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
252
}
253
254
/* UNDEF accesses to D16-D31 if they don't exist. */
255
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vd & 0x10)) {
256
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
257
return false;
258
}
259
260
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
261
TCGv_ptr fpst;
262
263
/* UNDEF accesses to D16-D31 if they don't exist. */
264
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
265
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
266
return false;
267
}
268
269
--
73
--
270
2.20.1
74
2.34.1
271
272
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 will shortly use these to test for VFPv2 and VFPv3
3
With FEAT_RME, there are four physical address spaces.
4
in different situations.
4
For now, just define the symbols, and mention them in
5
the same spots as the other Phys indexes in ptw.c.
5
6
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200214181547.21408-8-richard.henderson@linaro.org
10
Message-id: 20230620124418.805717-9-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
target/arm/cpu.h | 18 ++++++++++++++++++
13
target/arm/cpu.h | 23 +++++++++++++++++++++--
12
1 file changed, 18 insertions(+)
14
target/arm/ptw.c | 10 ++++++++--
15
2 files changed, 29 insertions(+), 4 deletions(-)
13
16
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
19
--- a/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fpshvec(const ARMISARegisters *id)
21
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
19
return FIELD_EX32(id->mvfr0, MVFR0, FPSHVEC) > 0;
22
ARMMMUIdx_Stage2 = 9 | ARM_MMU_IDX_A,
20
}
23
21
24
/* TLBs with 1-1 mapping to the physical address spaces. */
22
+static inline bool isar_feature_aa32_fpsp_v2(const ARMISARegisters *id)
25
- ARMMMUIdx_Phys_S = 10 | ARM_MMU_IDX_A,
26
- ARMMMUIdx_Phys_NS = 11 | ARM_MMU_IDX_A,
27
+ ARMMMUIdx_Phys_S = 10 | ARM_MMU_IDX_A,
28
+ ARMMMUIdx_Phys_NS = 11 | ARM_MMU_IDX_A,
29
+ ARMMMUIdx_Phys_Root = 12 | ARM_MMU_IDX_A,
30
+ ARMMMUIdx_Phys_Realm = 13 | ARM_MMU_IDX_A,
31
32
/*
33
* These are not allocated TLBs and are used only for AT system
34
@@ -XXX,XX +XXX,XX @@ typedef enum ARMASIdx {
35
ARMASIdx_TagS = 3,
36
} ARMASIdx;
37
38
+static inline ARMMMUIdx arm_space_to_phys(ARMSecuritySpace space)
23
+{
39
+{
24
+ /* Return true if CPU supports single precision floating point, VFPv2 */
40
+ /* Assert the relative order of the physical mmu indexes. */
25
+ return FIELD_EX32(id->mvfr0, MVFR0, FPSP) > 0;
41
+ QEMU_BUILD_BUG_ON(ARMSS_Secure != 0);
42
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_NS != ARMMMUIdx_Phys_S + ARMSS_NonSecure);
43
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_Root != ARMMMUIdx_Phys_S + ARMSS_Root);
44
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_Realm != ARMMMUIdx_Phys_S + ARMSS_Realm);
45
+
46
+ return ARMMMUIdx_Phys_S + space;
26
+}
47
+}
27
+
48
+
28
+static inline bool isar_feature_aa32_fpsp_v3(const ARMISARegisters *id)
49
+static inline ARMSecuritySpace arm_phys_to_space(ARMMMUIdx idx)
29
+{
50
+{
30
+ /* Return true if CPU supports single precision floating point, VFPv3 */
51
+ assert(idx >= ARMMMUIdx_Phys_S && idx <= ARMMMUIdx_Phys_Realm);
31
+ return FIELD_EX32(id->mvfr0, MVFR0, FPSP) >= 2;
52
+ return idx - ARMMMUIdx_Phys_S;
32
+}
53
+}
33
+
54
+
34
static inline bool isar_feature_aa32_fpdp_v2(const ARMISARegisters *id)
55
static inline bool arm_v7m_csselr_razwi(ARMCPU *cpu)
35
{
56
{
36
/* Return true if CPU supports double precision floating point, VFPv2 */
57
/* If all the CLIDR.Ctypem bits are 0 there are no caches, and
37
return FIELD_EX32(id->mvfr0, MVFR0, FPDP) > 0;
58
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
38
}
59
index XXXXXXX..XXXXXXX 100644
39
60
--- a/target/arm/ptw.c
40
+static inline bool isar_feature_aa32_fpdp_v3(const ARMISARegisters *id)
61
+++ b/target/arm/ptw.c
41
+{
62
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
42
+ /* Return true if CPU supports double precision floating point, VFPv3 */
63
case ARMMMUIdx_E3:
43
+ return FIELD_EX32(id->mvfr0, MVFR0, FPDP) >= 2;
64
break;
44
+}
65
45
+
66
- case ARMMMUIdx_Phys_NS:
46
/*
67
case ARMMMUIdx_Phys_S:
47
* We always set the FP and SIMD FP16 fields to indicate identical
68
+ case ARMMMUIdx_Phys_NS:
48
* levels of support (assuming SIMD is implemented at all), so
69
+ case ARMMMUIdx_Phys_Root:
70
+ case ARMMMUIdx_Phys_Realm:
71
/* No translation for physical address spaces. */
72
return true;
73
74
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
75
switch (mmu_idx) {
76
case ARMMMUIdx_Stage2:
77
case ARMMMUIdx_Stage2_S:
78
- case ARMMMUIdx_Phys_NS:
79
case ARMMMUIdx_Phys_S:
80
+ case ARMMMUIdx_Phys_NS:
81
+ case ARMMMUIdx_Phys_Root:
82
+ case ARMMMUIdx_Phys_Realm:
83
break;
84
85
default:
86
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
87
switch (mmu_idx) {
88
case ARMMMUIdx_Phys_S:
89
case ARMMMUIdx_Phys_NS:
90
+ case ARMMMUIdx_Phys_Root:
91
+ case ARMMMUIdx_Phys_Realm:
92
/* Checking Phys early avoids special casing later vs regime_el. */
93
return get_phys_addr_disabled(env, address, access_type, mmu_idx,
94
is_secure, result, fi);
49
--
95
--
50
2.20.1
96
2.34.1
51
97
52
98
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 are going to convert FEATURE tests to ISAR tests,
3
This was added in 7e98e21c098 as part of a reorg in which
4
so FPSP needs to be set for these cpus, like we have
4
one of the argument had been legally NULL, and this caught
5
already for FPDP.
5
actual instances. Now that the reorg is complete, this
6
serves little purpose.
6
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200214181547.21408-5-richard.henderson@linaro.org
11
Message-id: 20230620124418.805717-10-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
target/arm/cpu.c | 10 ++++++----
14
target/arm/ptw.c | 6 ++----
13
1 file changed, 6 insertions(+), 4 deletions(-)
15
1 file changed, 2 insertions(+), 4 deletions(-)
14
16
15
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
17
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.c
19
--- a/target/arm/ptw.c
18
+++ b/target/arm/cpu.c
20
+++ b/target/arm/ptw.c
19
@@ -XXX,XX +XXX,XX @@ static void arm926_initfn(Object *obj)
21
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
20
*/
22
static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
21
cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1);
23
uint64_t address,
22
/*
24
MMUAccessType access_type, bool s1_is_el0,
23
- * Similarly, we need to set MVFR0 fields to enable double precision
25
- GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
24
- * and short vector support even though ARMv5 doesn't have this register.
26
- __attribute__((nonnull));
25
+ * Similarly, we need to set MVFR0 fields to enable vfp and short vector
27
+ GetPhysAddrResult *result, ARMMMUFaultInfo *fi);
26
+ * support even though ARMv5 doesn't have this register.
28
27
*/
29
static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
28
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
30
target_ulong address,
29
+ cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSP, 1);
31
MMUAccessType access_type,
30
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPDP, 1);
32
GetPhysAddrResult *result,
31
}
33
- ARMMMUFaultInfo *fi)
32
34
- __attribute__((nonnull));
33
@@ -XXX,XX +XXX,XX @@ static void arm1026_initfn(Object *obj)
35
+ ARMMMUFaultInfo *fi);
34
*/
36
35
cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1);
37
/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
36
/*
38
static const uint8_t pamax_map[] = {
37
- * Similarly, we need to set MVFR0 fields to enable double precision
38
- * and short vector support even though ARMv5 doesn't have this register.
39
+ * Similarly, we need to set MVFR0 fields to enable vfp and short vector
40
+ * support even though ARMv5 doesn't have this register.
41
*/
42
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
43
+ cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSP, 1);
44
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPDP, 1);
45
46
{
47
--
39
--
48
2.20.1
40
2.34.1
49
41
50
42
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Writes to AdvSIMD registers flush the bits above 128.
3
Add input and output space members to S1Translate. Set and adjust
4
them in S1_ptw_translate, and the various points at which we drop
5
secure state. Initialize the space in get_phys_addr; for now leave
6
get_phys_addr_with_secure considering only secure vs non-secure spaces.
4
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200214194643.23317-5-richard.henderson@linaro.org
10
Message-id: 20230620124418.805717-11-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
12
---
10
target/arm/translate-a64.c | 6 ++++++
13
target/arm/ptw.c | 86 +++++++++++++++++++++++++++++++++++++++---------
11
1 file changed, 6 insertions(+)
14
1 file changed, 71 insertions(+), 15 deletions(-)
12
15
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
18
--- a/target/arm/ptw.c
16
+++ b/target/arm/translate-a64.c
19
+++ b/target/arm/ptw.c
17
@@ -XXX,XX +XXX,XX @@ static void handle_simd_inse(DisasContext *s, int rd, int rn,
20
@@ -XXX,XX +XXX,XX @@
18
write_vec_element(s, tmp, rd, dst_index, size);
21
typedef struct S1Translate {
19
22
ARMMMUIdx in_mmu_idx;
20
tcg_temp_free_i64(tmp);
23
ARMMMUIdx in_ptw_idx;
24
+ ARMSecuritySpace in_space;
25
bool in_secure;
26
bool in_debug;
27
bool out_secure;
28
bool out_rw;
29
bool out_be;
30
+ ARMSecuritySpace out_space;
31
hwaddr out_virt;
32
hwaddr out_phys;
33
void *out_host;
34
@@ -XXX,XX +XXX,XX @@ static bool S2_attrs_are_device(uint64_t hcr, uint8_t attrs)
35
static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
36
hwaddr addr, ARMMMUFaultInfo *fi)
37
{
38
+ ARMSecuritySpace space = ptw->in_space;
39
bool is_secure = ptw->in_secure;
40
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
41
ARMMMUIdx s2_mmu_idx = ptw->in_ptw_idx;
42
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
43
.in_mmu_idx = s2_mmu_idx,
44
.in_ptw_idx = ptw_idx_for_stage_2(env, s2_mmu_idx),
45
.in_secure = s2_mmu_idx == ARMMMUIdx_Stage2_S,
46
+ .in_space = (s2_mmu_idx == ARMMMUIdx_Stage2_S ? ARMSS_Secure
47
+ : space == ARMSS_Realm ? ARMSS_Realm
48
+ : ARMSS_NonSecure),
49
.in_debug = true,
50
};
51
GetPhysAddrResult s2 = { };
52
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
53
ptw->out_phys = s2.f.phys_addr;
54
pte_attrs = s2.cacheattrs.attrs;
55
ptw->out_secure = s2.f.attrs.secure;
56
+ ptw->out_space = s2.f.attrs.space;
57
} else {
58
/* Regime is physical. */
59
ptw->out_phys = addr;
60
pte_attrs = 0;
61
ptw->out_secure = s2_mmu_idx == ARMMMUIdx_Phys_S;
62
+ ptw->out_space = (s2_mmu_idx == ARMMMUIdx_Phys_S ? ARMSS_Secure
63
+ : space == ARMSS_Realm ? ARMSS_Realm
64
+ : ARMSS_NonSecure);
65
}
66
ptw->out_host = NULL;
67
ptw->out_rw = false;
68
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
69
ptw->out_rw = full->prot & PAGE_WRITE;
70
pte_attrs = full->pte_attrs;
71
ptw->out_secure = full->attrs.secure;
72
+ ptw->out_space = full->attrs.space;
73
#else
74
g_assert_not_reached();
75
#endif
76
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw,
77
}
78
} else {
79
/* Page tables are in MMIO. */
80
- MemTxAttrs attrs = { .secure = ptw->out_secure };
81
+ MemTxAttrs attrs = {
82
+ .secure = ptw->out_secure,
83
+ .space = ptw->out_space,
84
+ };
85
AddressSpace *as = arm_addressspace(cs, attrs);
86
MemTxResult result = MEMTX_OK;
87
88
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw,
89
#endif
90
} else {
91
/* Page tables are in MMIO. */
92
- MemTxAttrs attrs = { .secure = ptw->out_secure };
93
+ MemTxAttrs attrs = {
94
+ .secure = ptw->out_secure,
95
+ .space = ptw->out_space,
96
+ };
97
AddressSpace *as = arm_addressspace(cs, attrs);
98
MemTxResult result = MEMTX_OK;
99
100
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, S1Translate *ptw,
101
* regime, because the attribute will already be non-secure.
102
*/
103
result->f.attrs.secure = false;
104
+ result->f.attrs.space = ARMSS_NonSecure;
105
}
106
result->f.phys_addr = phys_addr;
107
return false;
108
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
109
* regime, because the attribute will already be non-secure.
110
*/
111
result->f.attrs.secure = false;
112
+ result->f.attrs.space = ARMSS_NonSecure;
113
}
114
115
if (regime_is_stage2(mmu_idx)) {
116
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
117
*/
118
if (sattrs.ns) {
119
result->f.attrs.secure = false;
120
+ result->f.attrs.space = ARMSS_NonSecure;
121
} else if (!secure) {
122
/*
123
* NS access to S memory must fault.
124
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
125
bool is_secure = ptw->in_secure;
126
bool ret, ipa_secure;
127
ARMCacheAttrs cacheattrs1;
128
+ ARMSecuritySpace ipa_space;
129
bool is_el0;
130
uint64_t hcr;
131
132
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
133
134
ipa = result->f.phys_addr;
135
ipa_secure = result->f.attrs.secure;
136
+ ipa_space = result->f.attrs.space;
137
138
is_el0 = ptw->in_mmu_idx == ARMMMUIdx_Stage1_E0;
139
ptw->in_mmu_idx = ipa_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
140
ptw->in_secure = ipa_secure;
141
+ ptw->in_space = ipa_space;
142
ptw->in_ptw_idx = ptw_idx_for_stage_2(env, ptw->in_mmu_idx);
143
144
/*
145
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
146
ARMMMUIdx s1_mmu_idx;
147
148
/*
149
- * The page table entries may downgrade secure to non-secure, but
150
- * cannot upgrade an non-secure translation regime's attributes
151
- * to secure.
152
+ * The page table entries may downgrade Secure to NonSecure, but
153
+ * cannot upgrade a NonSecure translation regime's attributes
154
+ * to Secure or Realm.
155
*/
156
result->f.attrs.secure = is_secure;
157
+ result->f.attrs.space = ptw->in_space;
158
159
switch (mmu_idx) {
160
case ARMMMUIdx_Phys_S:
161
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
162
163
default:
164
/* Single stage uses physical for ptw. */
165
- ptw->in_ptw_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
166
+ ptw->in_ptw_idx = arm_space_to_phys(ptw->in_space);
167
break;
168
}
169
170
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
171
S1Translate ptw = {
172
.in_mmu_idx = mmu_idx,
173
.in_secure = is_secure,
174
+ .in_space = arm_secure_to_space(is_secure),
175
};
176
return get_phys_addr_with_struct(env, &ptw, address, access_type,
177
result, fi);
178
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
179
MMUAccessType access_type, ARMMMUIdx mmu_idx,
180
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
181
{
182
- bool is_secure;
183
+ S1Translate ptw = {
184
+ .in_mmu_idx = mmu_idx,
185
+ };
186
+ ARMSecuritySpace ss;
187
188
switch (mmu_idx) {
189
case ARMMMUIdx_E10_0:
190
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
191
case ARMMMUIdx_Stage1_E1:
192
case ARMMMUIdx_Stage1_E1_PAN:
193
case ARMMMUIdx_E2:
194
- is_secure = arm_is_secure_below_el3(env);
195
+ ss = arm_security_space_below_el3(env);
196
break;
197
case ARMMMUIdx_Stage2:
198
+ /*
199
+ * For Secure EL2, we need this index to be NonSecure;
200
+ * otherwise this will already be NonSecure or Realm.
201
+ */
202
+ ss = arm_security_space_below_el3(env);
203
+ if (ss == ARMSS_Secure) {
204
+ ss = ARMSS_NonSecure;
205
+ }
206
+ break;
207
case ARMMMUIdx_Phys_NS:
208
case ARMMMUIdx_MPrivNegPri:
209
case ARMMMUIdx_MUserNegPri:
210
case ARMMMUIdx_MPriv:
211
case ARMMMUIdx_MUser:
212
- is_secure = false;
213
+ ss = ARMSS_NonSecure;
214
break;
215
- case ARMMMUIdx_E3:
216
case ARMMMUIdx_Stage2_S:
217
case ARMMMUIdx_Phys_S:
218
case ARMMMUIdx_MSPrivNegPri:
219
case ARMMMUIdx_MSUserNegPri:
220
case ARMMMUIdx_MSPriv:
221
case ARMMMUIdx_MSUser:
222
- is_secure = true;
223
+ ss = ARMSS_Secure;
224
+ break;
225
+ case ARMMMUIdx_E3:
226
+ if (arm_feature(env, ARM_FEATURE_AARCH64) &&
227
+ cpu_isar_feature(aa64_rme, env_archcpu(env))) {
228
+ ss = ARMSS_Root;
229
+ } else {
230
+ ss = ARMSS_Secure;
231
+ }
232
+ break;
233
+ case ARMMMUIdx_Phys_Root:
234
+ ss = ARMSS_Root;
235
+ break;
236
+ case ARMMMUIdx_Phys_Realm:
237
+ ss = ARMSS_Realm;
238
break;
239
default:
240
g_assert_not_reached();
241
}
242
- return get_phys_addr_with_secure(env, address, access_type, mmu_idx,
243
- is_secure, result, fi);
21
+
244
+
22
+ /* INS is considered a 128-bit write for SVE. */
245
+ ptw.in_space = ss;
23
+ clear_vec_high(s, true, rd);
246
+ ptw.in_secure = arm_space_is_secure(ss);
247
+ return get_phys_addr_with_struct(env, &ptw, address, access_type,
248
+ result, fi);
24
}
249
}
25
250
26
251
hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
27
@@ -XXX,XX +XXX,XX @@ static void handle_simd_insg(DisasContext *s, int rd, int rn, int imm5)
252
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
28
253
{
29
idx = extract32(imm5, 1 + size, 4 - size);
254
ARMCPU *cpu = ARM_CPU(cs);
30
write_vec_element(s, cpu_reg(s, rn), rd, idx, size);
255
CPUARMState *env = &cpu->env;
31
+
256
+ ARMMMUIdx mmu_idx = arm_mmu_idx(env);
32
+ /* INS is considered a 128-bit write for SVE. */
257
+ ARMSecuritySpace ss = arm_security_space(env);
33
+ clear_vec_high(s, true, rd);
258
S1Translate ptw = {
34
}
259
- .in_mmu_idx = arm_mmu_idx(env),
35
260
- .in_secure = arm_is_secure(env),
36
/*
261
+ .in_mmu_idx = mmu_idx,
262
+ .in_space = ss,
263
+ .in_secure = arm_space_is_secure(ss),
264
.in_debug = true,
265
};
266
GetPhysAddrResult res = {};
37
--
267
--
38
2.20.1
268
2.34.1
39
40
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Now that aa64_va_parameters_both sets select based on the number
3
Test in_space instead of in_secure so that we don't
4
of ranges in the regime, the ttbr1_valid check is redundant.
4
switch out of Root space.
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: 20200216194343.21331-4-richard.henderson@linaro.org
8
Message-id: 20230620124418.805717-12-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/helper.c | 6 +-----
11
target/arm/ptw.c | 28 ++++++++++++++--------------
12
1 file changed, 1 insertion(+), 5 deletions(-)
12
1 file changed, 14 insertions(+), 14 deletions(-)
13
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
16
--- a/target/arm/ptw.c
17
+++ b/target/arm/helper.c
17
+++ b/target/arm/ptw.c
18
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
18
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
19
TCR *tcr = regime_tcr(env, mmu_idx);
19
{
20
int ap, ns, xn, pxn;
20
ARMCPU *cpu = env_archcpu(env);
21
uint32_t el = regime_el(env, mmu_idx);
21
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
22
- bool ttbr1_valid;
22
- bool is_secure = ptw->in_secure;
23
int32_t level;
24
ARMVAParameters param;
25
uint64_t ttbr;
26
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
23
uint64_t descaddrmask;
27
uint64_t descaddrmask;
24
bool aarch64 = arm_el_is_aa64(env, el);
28
bool aarch64 = arm_el_is_aa64(env, el);
25
bool guarded = false;
29
uint64_t descriptor, new_descriptor;
26
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
30
- bool nstable;
27
param = aa64_va_parameters(env, address, mmu_idx,
31
28
access_type != MMU_INST_FETCH);
32
/* TODO: This code does not support shareability levels. */
29
level = 0;
33
if (aarch64) {
30
- ttbr1_valid = regime_has_2_ranges(mmu_idx);
34
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
31
addrsize = 64 - 8 * param.tbi;
35
descaddrmask = MAKE_64BIT_MASK(0, 40);
32
inputsize = 64 - param.tsz;
33
} else {
34
param = aa32_va_parameters(env, address, mmu_idx);
35
level = 1;
36
- /* There is no TTBR1 for EL2 */
37
- ttbr1_valid = (el != 2);
38
addrsize = (mmu_idx == ARMMMUIdx_Stage2 ? 40 : 32);
39
inputsize = addrsize - param.tsz;
40
}
36
}
41
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
37
descaddrmask &= ~indexmask_grainsize;
42
if (inputsize < addrsize) {
38
-
43
target_ulong top_bits = sextract64(address, inputsize,
39
- /*
44
addrsize - inputsize);
40
- * Secure stage 1 accesses start with the page table in secure memory and
45
- if (-top_bits != param.select || (param.select && !ttbr1_valid)) {
41
- * can be downgraded to non-secure at any step. Non-secure accesses
46
+ if (-top_bits != param.select) {
42
- * remain non-secure. We implement this by just ORing in the NSTable/NS
47
/* The gap between the two regions is a Translation fault */
43
- * bits at each step.
48
fault_type = ARMFault_Translation;
44
- * Stage 2 never gets this kind of downgrade.
49
goto do_fault;
45
- */
46
- tableattrs = is_secure ? 0 : (1 << 4);
47
+ tableattrs = 0;
48
49
next_level:
50
descaddr |= (address >> (stride * (4 - level))) & indexmask;
51
descaddr &= ~7ULL;
52
- nstable = !regime_is_stage2(mmu_idx) && extract32(tableattrs, 4, 1);
53
- if (nstable && ptw->in_secure) {
54
+
55
+ /*
56
+ * Process the NSTable bit from the previous level. This changes
57
+ * the table address space and the output space from Secure to
58
+ * NonSecure. With RME, the EL3 translation regime does not change
59
+ * from Root to NonSecure.
60
+ */
61
+ if (ptw->in_space == ARMSS_Secure
62
+ && !regime_is_stage2(mmu_idx)
63
+ && extract32(tableattrs, 4, 1)) {
64
/*
65
* Stage2_S -> Stage2 or Phys_S -> Phys_NS
66
* Assert the relative order of the secure/non-secure indexes.
67
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
68
QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2_S + 1 != ARMMMUIdx_Stage2);
69
ptw->in_ptw_idx += 1;
70
ptw->in_secure = false;
71
+ ptw->in_space = ARMSS_NonSecure;
72
}
73
+
74
if (!S1_ptw_translate(env, ptw, descaddr, fi)) {
75
goto do_fault;
76
}
77
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
78
*/
79
attrs = new_descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(50, 14));
80
if (!regime_is_stage2(mmu_idx)) {
81
- attrs |= nstable << 5; /* NS */
82
+ attrs |= !ptw->in_secure << 5; /* NS */
83
if (!param.hpd) {
84
attrs |= extract64(tableattrs, 0, 2) << 53; /* XN, PXN */
85
/*
50
--
86
--
51
2.20.1
87
2.34.1
52
53
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Shuffle the order of the checks so that we test the ISA
3
With Realm security state, bit 55 of a block or page descriptor during
4
before we test anything else, such as the register arguments.
4
the stage2 walk becomes the NS bit; during the stage1 walk the bit 5
5
NS bit is RES0. With Root security state, bit 11 of the block or page
6
descriptor during the stage1 walk becomes the NSE bit.
5
7
8
Rather than collecting an NS bit and applying it later, compute the
9
output pa space from the input pa space and unconditionally assign.
10
This means that we no longer need to adjust the output space earlier
11
for the NSTable bit.
12
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200214181547.21408-9-richard.henderson@linaro.org
15
Message-id: 20230620124418.805717-13-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
17
---
11
target/arm/translate-vfp.inc.c | 144 ++++++++++++++++-----------------
18
target/arm/ptw.c | 89 +++++++++++++++++++++++++++++++++++++++---------
12
1 file changed, 72 insertions(+), 72 deletions(-)
19
1 file changed, 73 insertions(+), 16 deletions(-)
13
20
14
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
21
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-vfp.inc.c
23
--- a/target/arm/ptw.c
17
+++ b/target/arm/translate-vfp.inc.c
24
+++ b/target/arm/ptw.c
18
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
25
@@ -XXX,XX +XXX,XX @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
19
return false;
26
* @mmu_idx: MMU index indicating required translation regime
27
* @is_aa64: TRUE if AArch64
28
* @ap: The 2-bit simple AP (AP[2:1])
29
- * @ns: NS (non-secure) bit
30
* @xn: XN (execute-never) bit
31
* @pxn: PXN (privileged execute-never) bit
32
+ * @in_pa: The original input pa space
33
+ * @out_pa: The output pa space, modified by NSTable, NS, and NSE
34
*/
35
static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
36
- int ap, int ns, int xn, int pxn)
37
+ int ap, int xn, int pxn,
38
+ ARMSecuritySpace in_pa, ARMSecuritySpace out_pa)
39
{
40
ARMCPU *cpu = env_archcpu(env);
41
bool is_user = regime_is_user(env, mmu_idx);
42
@@ -XXX,XX +XXX,XX @@ static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
43
}
20
}
44
}
21
45
22
- /* UNDEF accesses to D16-D31 if they don't exist */
46
- if (ns && arm_is_secure(env) && (env->cp15.scr_el3 & SCR_SIF)) {
23
- if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
47
+ if (out_pa == ARMSS_NonSecure && in_pa == ARMSS_Secure &&
24
- ((a->vm | a->vn | a->vd) & 0x10)) {
48
+ (env->cp15.scr_el3 & SCR_SIF)) {
25
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
49
return prot_rw;
26
return false;
27
}
50
}
28
51
29
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
52
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
30
+ /* UNDEF accesses to D16-D31 if they don't exist */
53
int32_t stride;
31
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
54
int addrsize, inputsize, outputsize;
32
+ ((a->vm | a->vn | a->vd) & 0x10)) {
55
uint64_t tcr = regime_tcr(env, mmu_idx);
33
return false;
56
- int ap, ns, xn, pxn;
57
+ int ap, xn, pxn;
58
uint32_t el = regime_el(env, mmu_idx);
59
uint64_t descaddrmask;
60
bool aarch64 = arm_el_is_aa64(env, el);
61
uint64_t descriptor, new_descriptor;
62
+ ARMSecuritySpace out_space;
63
64
/* TODO: This code does not support shareability levels. */
65
if (aarch64) {
66
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
34
}
67
}
35
68
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VMINMAXNM(DisasContext *s, arg_VMINMAXNM *a)
69
ap = extract32(attrs, 6, 2);
37
return false;
70
+ out_space = ptw->in_space;
71
if (regime_is_stage2(mmu_idx)) {
72
- ns = mmu_idx == ARMMMUIdx_Stage2;
73
+ /*
74
+ * R_GYNXY: For stage2 in Realm security state, bit 55 is NS.
75
+ * The bit remains ignored for other security states.
76
+ */
77
+ if (out_space == ARMSS_Realm && extract64(attrs, 55, 1)) {
78
+ out_space = ARMSS_NonSecure;
79
+ }
80
xn = extract64(attrs, 53, 2);
81
result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
82
} else {
83
- ns = extract32(attrs, 5, 1);
84
+ int nse, ns = extract32(attrs, 5, 1);
85
+ switch (out_space) {
86
+ case ARMSS_Root:
87
+ /*
88
+ * R_GVZML: Bit 11 becomes the NSE field in the EL3 regime.
89
+ * R_XTYPW: NSE and NS together select the output pa space.
90
+ */
91
+ nse = extract32(attrs, 11, 1);
92
+ out_space = (nse << 1) | ns;
93
+ if (out_space == ARMSS_Secure &&
94
+ !cpu_isar_feature(aa64_sel2, cpu)) {
95
+ out_space = ARMSS_NonSecure;
96
+ }
97
+ break;
98
+ case ARMSS_Secure:
99
+ if (ns) {
100
+ out_space = ARMSS_NonSecure;
101
+ }
102
+ break;
103
+ case ARMSS_Realm:
104
+ switch (mmu_idx) {
105
+ case ARMMMUIdx_Stage1_E0:
106
+ case ARMMMUIdx_Stage1_E1:
107
+ case ARMMMUIdx_Stage1_E1_PAN:
108
+ /* I_CZPRF: For Realm EL1&0 stage1, NS bit is RES0. */
109
+ break;
110
+ case ARMMMUIdx_E2:
111
+ case ARMMMUIdx_E20_0:
112
+ case ARMMMUIdx_E20_2:
113
+ case ARMMMUIdx_E20_2_PAN:
114
+ /*
115
+ * R_LYKFZ, R_WGRZN: For Realm EL2 and EL2&1,
116
+ * NS changes the output to non-secure space.
117
+ */
118
+ if (ns) {
119
+ out_space = ARMSS_NonSecure;
120
+ }
121
+ break;
122
+ default:
123
+ g_assert_not_reached();
124
+ }
125
+ break;
126
+ case ARMSS_NonSecure:
127
+ /* R_QRMFF: For NonSecure state, the NS bit is RES0. */
128
+ break;
129
+ default:
130
+ g_assert_not_reached();
131
+ }
132
xn = extract64(attrs, 54, 1);
133
pxn = extract64(attrs, 53, 1);
134
- result->f.prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
135
+
136
+ /*
137
+ * Note that we modified ptw->in_space earlier for NSTable, but
138
+ * result->f.attrs retains a copy of the original security space.
139
+ */
140
+ result->f.prot = get_S1prot(env, mmu_idx, aarch64, ap, xn, pxn,
141
+ result->f.attrs.space, out_space);
38
}
142
}
39
143
40
- /* UNDEF accesses to D16-D31 if they don't exist */
144
if (!(result->f.prot & (1 << access_type))) {
41
- if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
145
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
42
- ((a->vm | a->vn | a->vd) & 0x10)) {
146
}
43
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
44
return false;
45
}
147
}
46
148
47
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
149
- if (ns) {
48
+ /* UNDEF accesses to D16-D31 if they don't exist */
150
- /*
49
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
151
- * The NS bit will (as required by the architecture) have no effect if
50
+ ((a->vm | a->vn | a->vd) & 0x10)) {
152
- * the CPU doesn't support TZ or this is a non-secure translation
51
return false;
153
- * regime, because the attribute will already be non-secure.
52
}
154
- */
53
155
- result->f.attrs.secure = false;
54
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
156
- result->f.attrs.space = ARMSS_NonSecure;
55
return false;
56
}
57
58
- /* UNDEF accesses to D16-D31 if they don't exist */
59
- if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
60
- ((a->vm | a->vd) & 0x10)) {
61
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
62
return false;
63
}
64
65
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
66
+ /* UNDEF accesses to D16-D31 if they don't exist */
67
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
68
+ ((a->vm | a->vd) & 0x10)) {
69
return false;
70
}
71
72
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
73
return false;
74
}
75
76
- /* UNDEF accesses to D16-D31 if they don't exist */
77
- if (dp && !dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
78
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
79
return false;
80
}
81
82
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
83
+ /* UNDEF accesses to D16-D31 if they don't exist */
84
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
85
return false;
86
}
87
88
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
89
TCGv_i64 f0, f1, fd;
90
TCGv_ptr fpst;
91
92
- /* UNDEF accesses to D16-D31 if they don't exist */
93
- if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vn | vm) & 0x10)) {
94
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
95
return false;
96
}
97
98
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
99
+ /* UNDEF accesses to D16-D31 if they don't exist */
100
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vn | vm) & 0x10)) {
101
return false;
102
}
103
104
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
105
int veclen = s->vec_len;
106
TCGv_i64 f0, fd;
107
108
- /* UNDEF accesses to D16-D31 if they don't exist */
109
- if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vm) & 0x10)) {
110
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
111
return false;
112
}
113
114
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
115
+ /* UNDEF accesses to D16-D31 if they don't exist */
116
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vm) & 0x10)) {
117
return false;
118
}
119
120
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
121
return false;
122
}
123
124
- /* UNDEF accesses to D16-D31 if they don't exist. */
125
- if (!dc_isar_feature(aa32_simd_r32, s) &&
126
- ((a->vd | a->vn | a->vm) & 0x10)) {
127
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
128
return false;
129
}
130
131
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
132
+ /* UNDEF accesses to D16-D31 if they don't exist. */
133
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
134
+ ((a->vd | a->vn | a->vm) & 0x10)) {
135
return false;
136
}
137
138
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
139
140
vd = a->vd;
141
142
- /* UNDEF accesses to D16-D31 if they don't exist. */
143
- if (!dc_isar_feature(aa32_simd_r32, s) && (vd & 0x10)) {
144
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
145
return false;
146
}
147
148
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
149
+ /* UNDEF accesses to D16-D31 if they don't exist. */
150
+ if (!dc_isar_feature(aa32_simd_r32, s) && (vd & 0x10)) {
151
return false;
152
}
153
154
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
155
{
156
TCGv_i64 vd, vm;
157
158
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
159
+ return false;
160
+ }
161
+
162
/* Vm/M bits must be zero for the Z variant */
163
if (a->z && a->vm != 0) {
164
return false;
165
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
166
return false;
167
}
168
169
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
170
- return false;
171
- }
157
- }
172
-
158
+ result->f.attrs.space = out_space;
173
if (!vfp_access_check(s)) {
159
+ result->f.attrs.secure = arm_space_is_secure(out_space);
174
return true;
160
175
}
161
if (regime_is_stage2(mmu_idx)) {
176
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
162
result->cacheattrs.is_s2_format = true;
177
TCGv_i32 tmp;
178
TCGv_i64 vd;
179
180
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
181
+ return false;
182
+ }
183
+
184
if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
185
return false;
186
}
187
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
188
return false;
189
}
190
191
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
192
- return false;
193
- }
194
-
195
if (!vfp_access_check(s)) {
196
return true;
197
}
198
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
199
TCGv_i32 tmp;
200
TCGv_i64 vm;
201
202
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
203
+ return false;
204
+ }
205
+
206
if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
207
return false;
208
}
209
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
210
return false;
211
}
212
213
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
214
- return false;
215
- }
216
-
217
if (!vfp_access_check(s)) {
218
return true;
219
}
220
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
221
TCGv_ptr fpst;
222
TCGv_i64 tmp;
223
224
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
225
+ return false;
226
+ }
227
+
228
if (!dc_isar_feature(aa32_vrint, s)) {
229
return false;
230
}
231
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
232
return false;
233
}
234
235
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
236
- return false;
237
- }
238
-
239
if (!vfp_access_check(s)) {
240
return true;
241
}
242
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
243
TCGv_i64 tmp;
244
TCGv_i32 tcg_rmode;
245
246
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
247
+ return false;
248
+ }
249
+
250
if (!dc_isar_feature(aa32_vrint, s)) {
251
return false;
252
}
253
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
254
return false;
255
}
256
257
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
258
- return false;
259
- }
260
-
261
if (!vfp_access_check(s)) {
262
return true;
263
}
264
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
265
TCGv_ptr fpst;
266
TCGv_i64 tmp;
267
268
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
269
+ return false;
270
+ }
271
+
272
if (!dc_isar_feature(aa32_vrint, s)) {
273
return false;
274
}
275
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
276
return false;
277
}
278
279
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
280
- return false;
281
- }
282
-
283
if (!vfp_access_check(s)) {
284
return true;
285
}
286
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
287
TCGv_i64 vd;
288
TCGv_i32 vm;
289
290
- /* UNDEF accesses to D16-D31 if they don't exist. */
291
- if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
292
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
293
return false;
294
}
295
296
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
297
+ /* UNDEF accesses to D16-D31 if they don't exist. */
298
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
299
return false;
300
}
301
302
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
303
TCGv_i64 vm;
304
TCGv_i32 vd;
305
306
- /* UNDEF accesses to D16-D31 if they don't exist. */
307
- if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
308
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
309
return false;
310
}
311
312
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
313
+ /* UNDEF accesses to D16-D31 if they don't exist. */
314
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
315
return false;
316
}
317
318
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
319
TCGv_i64 vd;
320
TCGv_ptr fpst;
321
322
- /* UNDEF accesses to D16-D31 if they don't exist. */
323
- if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
324
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
325
return false;
326
}
327
328
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
329
+ /* UNDEF accesses to D16-D31 if they don't exist. */
330
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
331
return false;
332
}
333
334
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
335
TCGv_i32 vd;
336
TCGv_i64 vm;
337
338
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
339
+ return false;
340
+ }
341
+
342
if (!dc_isar_feature(aa32_jscvt, s)) {
343
return false;
344
}
345
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
346
return false;
347
}
348
349
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
350
- return false;
351
- }
352
-
353
if (!vfp_access_check(s)) {
354
return true;
355
}
356
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
357
TCGv_ptr fpst;
358
int frac_bits;
359
360
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
361
+ return false;
362
+ }
363
+
364
if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
365
return false;
366
}
367
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
368
return false;
369
}
370
371
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
372
- return false;
373
- }
374
-
375
if (!vfp_access_check(s)) {
376
return true;
377
}
378
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
379
TCGv_i64 vm;
380
TCGv_ptr fpst;
381
382
- /* UNDEF accesses to D16-D31 if they don't exist. */
383
- if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
384
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
385
return false;
386
}
387
388
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
389
+ /* UNDEF accesses to D16-D31 if they don't exist. */
390
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
391
return false;
392
}
393
394
--
163
--
395
2.20.1
164
2.34.1
396
397
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 old name, isar_feature_aa32_fpdp, does not reflect
3
While Root and Realm may read and write data from other spaces,
4
that the test includes VFPv2. We will introduce further
4
neither may execute from other pa spaces.
5
feature tests for VFPv3.
6
5
6
This happens for Stage1 EL3, EL2, EL2&0, and Stage2 EL1&0.
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Message-id: 20230620124418.805717-14-richard.henderson@linaro.org
9
Message-id: 20200214181547.21408-7-richard.henderson@linaro.org
10
[PMM: fixed grammar in commit message]
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
12
---
14
target/arm/cpu.h | 4 ++--
13
target/arm/ptw.c | 52 ++++++++++++++++++++++++++++++++++++++++++------
15
target/arm/translate-vfp.inc.c | 40 +++++++++++++++++-----------------
14
1 file changed, 46 insertions(+), 6 deletions(-)
16
2 files changed, 22 insertions(+), 22 deletions(-)
17
15
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
18
--- a/target/arm/ptw.c
21
+++ b/target/arm/cpu.h
19
+++ b/target/arm/ptw.c
22
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fpshvec(const ARMISARegisters *id)
20
@@ -XXX,XX +XXX,XX @@ do_fault:
23
return FIELD_EX32(id->mvfr0, MVFR0, FPSHVEC) > 0;
21
* @xn: XN (execute-never) bits
24
}
22
* @s1_is_el0: true if this is S2 of an S1+2 walk for EL0
25
23
*/
26
-static inline bool isar_feature_aa32_fpdp(const ARMISARegisters *id)
24
-static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
27
+static inline bool isar_feature_aa32_fpdp_v2(const ARMISARegisters *id)
25
+static int get_S2prot_noexecute(int s2ap)
28
{
26
{
29
- /* Return true if CPU supports double precision floating point */
27
int prot = 0;
30
+ /* Return true if CPU supports double precision floating point, VFPv2 */
28
31
return FIELD_EX32(id->mvfr0, MVFR0, FPDP) > 0;
29
@@ -XXX,XX +XXX,XX @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
32
}
30
if (s2ap & 2) {
33
31
prot |= PAGE_WRITE;
34
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-vfp.inc.c
37
+++ b/target/arm/translate-vfp.inc.c
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
39
return false;
40
}
32
}
41
33
+ return prot;
42
- if (dp && !dc_isar_feature(aa32_fpdp, s)) {
34
+}
43
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
35
+
44
return false;
36
+static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
37
+{
38
+ int prot = get_S2prot_noexecute(s2ap);
39
40
if (cpu_isar_feature(any_tts2uxn, env_archcpu(env))) {
41
switch (xn) {
42
@@ -XXX,XX +XXX,XX @@ static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
43
}
45
}
44
}
46
45
47
@@ -XXX,XX +XXX,XX @@ static bool trans_VMINMAXNM(DisasContext *s, arg_VMINMAXNM *a)
46
- if (out_pa == ARMSS_NonSecure && in_pa == ARMSS_Secure &&
48
return false;
47
- (env->cp15.scr_el3 & SCR_SIF)) {
48
- return prot_rw;
49
+ if (in_pa != out_pa) {
50
+ switch (in_pa) {
51
+ case ARMSS_Root:
52
+ /*
53
+ * R_ZWRVD: permission fault for insn fetched from non-Root,
54
+ * I_WWBFB: SIF has no effect in EL3.
55
+ */
56
+ return prot_rw;
57
+ case ARMSS_Realm:
58
+ /*
59
+ * R_PKTDS: permission fault for insn fetched from non-Realm,
60
+ * for Realm EL2 or EL2&0. The corresponding fault for EL1&0
61
+ * happens during any stage2 translation.
62
+ */
63
+ switch (mmu_idx) {
64
+ case ARMMMUIdx_E2:
65
+ case ARMMMUIdx_E20_0:
66
+ case ARMMMUIdx_E20_2:
67
+ case ARMMMUIdx_E20_2_PAN:
68
+ return prot_rw;
69
+ default:
70
+ break;
71
+ }
72
+ break;
73
+ case ARMSS_Secure:
74
+ if (env->cp15.scr_el3 & SCR_SIF) {
75
+ return prot_rw;
76
+ }
77
+ break;
78
+ default:
79
+ /* Input NonSecure must have output NonSecure. */
80
+ g_assert_not_reached();
81
+ }
49
}
82
}
50
83
51
- if (dp && !dc_isar_feature(aa32_fpdp, s)) {
84
/* TODO have_wxn should be replaced with
52
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
85
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
53
return false;
86
/*
54
}
87
* R_GYNXY: For stage2 in Realm security state, bit 55 is NS.
55
88
* The bit remains ignored for other security states.
56
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
89
+ * R_YMCSL: Executing an insn fetched from non-Realm causes
57
return false;
90
+ * a stage2 permission fault.
58
}
91
*/
59
92
if (out_space == ARMSS_Realm && extract64(attrs, 55, 1)) {
60
- if (dp && !dc_isar_feature(aa32_fpdp, s)) {
93
out_space = ARMSS_NonSecure;
61
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
94
+ result->f.prot = get_S2prot_noexecute(ap);
62
return false;
95
+ } else {
63
}
96
+ xn = extract64(attrs, 53, 2);
64
97
+ result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
65
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
98
}
66
return false;
99
- xn = extract64(attrs, 53, 2);
67
}
100
- result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
68
101
} else {
69
- if (dp && !dc_isar_feature(aa32_fpdp, s)) {
102
int nse, ns = extract32(attrs, 5, 1);
70
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
103
switch (out_space) {
71
return false;
72
}
73
74
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
75
return false;
76
}
77
78
- if (!dc_isar_feature(aa32_fpdp, s)) {
79
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
80
return false;
81
}
82
83
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
84
return false;
85
}
86
87
- if (!dc_isar_feature(aa32_fpdp, s)) {
88
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
89
return false;
90
}
91
92
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
93
return false;
94
}
95
96
- if (!dc_isar_feature(aa32_fpdp, s)) {
97
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
98
return false;
99
}
100
101
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
102
return false;
103
}
104
105
- if (!dc_isar_feature(aa32_fpdp, s)) {
106
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
107
return false;
108
}
109
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
111
return false;
112
}
113
114
- if (!dc_isar_feature(aa32_fpdp, s)) {
115
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
116
return false;
117
}
118
119
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
120
return false;
121
}
122
123
- if (!dc_isar_feature(aa32_fpdp, s)) {
124
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
125
return false;
126
}
127
128
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
129
return false;
130
}
131
132
- if (!dc_isar_feature(aa32_fpdp, s)) {
133
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
134
return false;
135
}
136
137
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
138
return false;
139
}
140
141
- if (!dc_isar_feature(aa32_fpdp, s)) {
142
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
143
return false;
144
}
145
146
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
147
return false;
148
}
149
150
- if (!dc_isar_feature(aa32_fpdp, s)) {
151
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
152
return false;
153
}
154
155
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
156
return false;
157
}
158
159
- if (!dc_isar_feature(aa32_fpdp, s)) {
160
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
161
return false;
162
}
163
164
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
165
return false;
166
}
167
168
- if (!dc_isar_feature(aa32_fpdp, s)) {
169
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
170
return false;
171
}
172
173
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
174
return false;
175
}
176
177
- if (!dc_isar_feature(aa32_fpdp, s)) {
178
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
179
return false;
180
}
181
182
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
183
return false;
184
}
185
186
- if (!dc_isar_feature(aa32_fpdp, s)) {
187
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
188
return false;
189
}
190
191
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
192
return false;
193
}
194
195
- if (!dc_isar_feature(aa32_fpdp, s)) {
196
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
197
return false;
198
}
199
200
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
201
return false;
202
}
203
204
- if (!dc_isar_feature(aa32_fpdp, s)) {
205
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
206
return false;
207
}
208
209
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
210
return false;
211
}
212
213
- if (!dc_isar_feature(aa32_fpdp, s)) {
214
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
215
return false;
216
}
217
218
--
104
--
219
2.20.1
105
2.34.1
220
221
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 still need two different helpers, since NEON and SVE2 get the
3
Do not provide a fast-path for physical addresses,
4
inputs from different locations within the source vector. However,
4
as those will need to be validated for GPC.
5
we can convert both to the same internal form for computation.
6
5
7
The sve2 helper is not used yet, but adding it with this patch
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
helps illustrate why the neon changes are helpful.
9
10
Tested-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20200216214232.4230-5-richard.henderson@linaro.org
8
Message-id: 20230620124418.805717-15-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
10
---
16
target/arm/helper-sve.h | 2 ++
11
target/arm/ptw.c | 44 +++++++++++++++++---------------------------
17
target/arm/helper.h | 3 +-
12
1 file changed, 17 insertions(+), 27 deletions(-)
18
target/arm/neon_helper.c | 32 --------------------
19
target/arm/translate-a64.c | 27 +++++++++++------
20
target/arm/translate.c | 26 ++++++++---------
21
target/arm/vec_helper.c | 60 ++++++++++++++++++++++++++++++++++++++
22
6 files changed, 95 insertions(+), 55 deletions(-)
23
13
24
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper-sve.h
16
--- a/target/arm/ptw.c
27
+++ b/target/arm/helper-sve.h
17
+++ b/target/arm/ptw.c
28
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(sve_stdd_le_zd, TCG_CALL_NO_WG,
18
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
29
void, env, ptr, ptr, ptr, tl, i32)
19
* From gdbstub, do not use softmmu so that we don't modify the
30
DEF_HELPER_FLAGS_6(sve_stdd_be_zd, TCG_CALL_NO_WG,
20
* state of the cpu at all, including softmmu tlb contents.
31
void, env, ptr, ptr, ptr, tl, i32)
21
*/
32
+
22
- if (regime_is_stage2(s2_mmu_idx)) {
33
+DEF_HELPER_FLAGS_4(sve2_pmull_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
23
- S1Translate s2ptw = {
34
diff --git a/target/arm/helper.h b/target/arm/helper.h
24
- .in_mmu_idx = s2_mmu_idx,
35
index XXXXXXX..XXXXXXX 100644
25
- .in_ptw_idx = ptw_idx_for_stage_2(env, s2_mmu_idx),
36
--- a/target/arm/helper.h
26
- .in_secure = s2_mmu_idx == ARMMMUIdx_Stage2_S,
37
+++ b/target/arm/helper.h
27
- .in_space = (s2_mmu_idx == ARMMMUIdx_Stage2_S ? ARMSS_Secure
38
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(neon_sub_u8, i32, i32, i32)
28
- : space == ARMSS_Realm ? ARMSS_Realm
39
DEF_HELPER_2(neon_sub_u16, i32, i32, i32)
29
- : ARMSS_NonSecure),
40
DEF_HELPER_2(neon_mul_u8, i32, i32, i32)
30
- .in_debug = true,
41
DEF_HELPER_2(neon_mul_u16, i32, i32, i32)
31
- };
42
-DEF_HELPER_2(neon_mull_p8, i64, i32, i32)
32
- GetPhysAddrResult s2 = { };
43
33
+ S1Translate s2ptw = {
44
DEF_HELPER_2(neon_tst_u8, i32, i32, i32)
34
+ .in_mmu_idx = s2_mmu_idx,
45
DEF_HELPER_2(neon_tst_u16, i32, i32, i32)
35
+ .in_ptw_idx = ptw_idx_for_stage_2(env, s2_mmu_idx),
46
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_ushl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
36
+ .in_secure = s2_mmu_idx == ARMMMUIdx_Stage2_S,
47
DEF_HELPER_FLAGS_4(gvec_pmul_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
37
+ .in_space = (s2_mmu_idx == ARMMMUIdx_Stage2_S ? ARMSS_Secure
48
DEF_HELPER_FLAGS_4(gvec_pmull_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
38
+ : space == ARMSS_Realm ? ARMSS_Realm
49
39
+ : ARMSS_NonSecure),
50
+DEF_HELPER_FLAGS_4(neon_pmull_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
40
+ .in_debug = true,
51
+
41
+ };
52
#ifdef TARGET_AARCH64
42
+ GetPhysAddrResult s2 = { };
53
#include "helper-a64.h"
43
54
#include "helper-sve.h"
44
- if (get_phys_addr_lpae(env, &s2ptw, addr, MMU_DATA_LOAD,
55
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
45
- false, &s2, fi)) {
56
index XXXXXXX..XXXXXXX 100644
46
- goto fail;
57
--- a/target/arm/neon_helper.c
47
- }
58
+++ b/target/arm/neon_helper.c
48
- ptw->out_phys = s2.f.phys_addr;
59
@@ -XXX,XX +XXX,XX @@ NEON_VOP(mul_u8, neon_u8, 4)
49
- pte_attrs = s2.cacheattrs.attrs;
60
NEON_VOP(mul_u16, neon_u16, 2)
50
- ptw->out_secure = s2.f.attrs.secure;
61
#undef NEON_FN
51
- ptw->out_space = s2.f.attrs.space;
62
52
- } else {
63
-/* Polynomial multiplication is like integer multiplication except the
53
- /* Regime is physical. */
64
- partial products are XORed, not added. */
54
- ptw->out_phys = addr;
65
-uint64_t HELPER(neon_mull_p8)(uint32_t op1, uint32_t op2)
55
- pte_attrs = 0;
66
-{
56
- ptw->out_secure = s2_mmu_idx == ARMMMUIdx_Phys_S;
67
- uint64_t result = 0;
57
- ptw->out_space = (s2_mmu_idx == ARMMMUIdx_Phys_S ? ARMSS_Secure
68
- uint64_t mask;
58
- : space == ARMSS_Realm ? ARMSS_Realm
69
- uint64_t op2ex = op2;
59
- : ARMSS_NonSecure);
70
- op2ex = (op2ex & 0xff) |
60
+ if (get_phys_addr_with_struct(env, &s2ptw, addr,
71
- ((op2ex & 0xff00) << 8) |
61
+ MMU_DATA_LOAD, &s2, fi)) {
72
- ((op2ex & 0xff0000) << 16) |
62
+ goto fail;
73
- ((op2ex & 0xff000000) << 24);
74
- while (op1) {
75
- mask = 0;
76
- if (op1 & 1) {
77
- mask |= 0xffff;
78
- }
79
- if (op1 & (1 << 8)) {
80
- mask |= (0xffffU << 16);
81
- }
82
- if (op1 & (1 << 16)) {
83
- mask |= (0xffffULL << 32);
84
- }
85
- if (op1 & (1 << 24)) {
86
- mask |= (0xffffULL << 48);
87
- }
88
- result ^= op2ex & mask;
89
- op1 = (op1 >> 1) & 0x7f7f7f7f;
90
- op2ex <<= 1;
91
- }
92
- return result;
93
-}
94
-
95
#define NEON_FN(dest, src1, src2) dest = (src1 & src2) ? -1 : 0
96
NEON_VOP(tst_u8, neon_u8, 4)
97
NEON_VOP(tst_u16, neon_u16, 2)
98
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/translate-a64.c
101
+++ b/target/arm/translate-a64.c
102
@@ -XXX,XX +XXX,XX @@ static void handle_3rd_widening(DisasContext *s, int is_q, int is_u, int size,
103
gen_helper_neon_addl_saturate_s32(tcg_passres, cpu_env,
104
tcg_passres, tcg_passres);
105
break;
106
- case 14: /* PMULL */
107
- assert(size == 0);
108
- gen_helper_neon_mull_p8(tcg_passres, tcg_op1, tcg_op2);
109
- break;
110
default:
111
g_assert_not_reached();
112
}
113
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn)
114
handle_3rd_narrowing(s, is_q, is_u, size, opcode, rd, rn, rm);
115
break;
116
case 14: /* PMULL, PMULL2 */
117
- if (is_u || size == 1 || size == 2) {
118
+ if (is_u) {
119
unallocated_encoding(s);
120
return;
121
}
63
}
122
- if (size == 3) {
64
+ ptw->out_phys = s2.f.phys_addr;
123
+ switch (size) {
65
+ pte_attrs = s2.cacheattrs.attrs;
124
+ case 0: /* PMULL.P8 */
66
ptw->out_host = NULL;
125
+ if (!fp_access_check(s)) {
67
ptw->out_rw = false;
126
+ return;
68
+ ptw->out_secure = s2.f.attrs.secure;
127
+ }
69
+ ptw->out_space = s2.f.attrs.space;
128
+ /* The Q field specifies lo/hi half input for this insn. */
70
} else {
129
+ gen_gvec_op3_ool(s, true, rd, rn, rm, is_q,
71
#ifdef CONFIG_TCG
130
+ gen_helper_neon_pmull_h);
72
CPUTLBEntryFull *full;
131
+ break;
132
+
133
+ case 3: /* PMULL.P64 */
134
if (!dc_isar_feature(aa64_pmull, s)) {
135
unallocated_encoding(s);
136
return;
137
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn)
138
/* The Q field specifies lo/hi half input for this insn. */
139
gen_gvec_op3_ool(s, true, rd, rn, rm, is_q,
140
gen_helper_gvec_pmull_q);
141
- return;
142
+ break;
143
+
144
+ default:
145
+ unallocated_encoding(s);
146
+ break;
147
}
148
- goto is_widening;
149
+ return;
150
case 9: /* SQDMLAL, SQDMLAL2 */
151
case 11: /* SQDMLSL, SQDMLSL2 */
152
case 13: /* SQDMULL, SQDMULL2 */
153
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn)
154
unallocated_encoding(s);
155
return;
156
}
157
- is_widening:
158
if (!fp_access_check(s)) {
159
return;
160
}
161
diff --git a/target/arm/translate.c b/target/arm/translate.c
162
index XXXXXXX..XXXXXXX 100644
163
--- a/target/arm/translate.c
164
+++ b/target/arm/translate.c
165
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
166
return 1;
167
}
168
169
- /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
170
- * outside the loop below as it only performs a single pass.
171
- */
172
- if (op == 14 && size == 2) {
173
- if (!dc_isar_feature(aa32_pmull, s)) {
174
- return 1;
175
+ /* Handle polynomial VMULL in a single pass. */
176
+ if (op == 14) {
177
+ if (size == 0) {
178
+ /* VMULL.P8 */
179
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, 16, 16,
180
+ 0, gen_helper_neon_pmull_h);
181
+ } else {
182
+ /* VMULL.P64 */
183
+ if (!dc_isar_feature(aa32_pmull, s)) {
184
+ return 1;
185
+ }
186
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, 16, 16,
187
+ 0, gen_helper_gvec_pmull_q);
188
}
189
- tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, 16, 16,
190
- 0, gen_helper_gvec_pmull_q);
191
return 0;
192
}
193
194
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
195
/* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
196
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
197
break;
198
- case 14: /* Polynomial VMULL */
199
- gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
200
- tcg_temp_free_i32(tmp2);
201
- tcg_temp_free_i32(tmp);
202
- break;
203
default: /* 15 is RESERVED: caught earlier */
204
abort();
205
}
206
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
207
index XXXXXXX..XXXXXXX 100644
208
--- a/target/arm/vec_helper.c
209
+++ b/target/arm/vec_helper.c
210
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_pmull_q)(void *vd, void *vn, void *vm, uint32_t desc)
211
}
212
clear_tail(d, opr_sz, simd_maxsz(desc));
213
}
214
+
215
+/*
216
+ * 8x8->16 polynomial multiply.
217
+ *
218
+ * The byte inputs are expanded to (or extracted from) half-words.
219
+ * Note that neon and sve2 get the inputs from different positions.
220
+ * This allows 4 bytes to be processed in parallel with uint64_t.
221
+ */
222
+
223
+static uint64_t expand_byte_to_half(uint64_t x)
224
+{
225
+ return (x & 0x000000ff)
226
+ | ((x & 0x0000ff00) << 8)
227
+ | ((x & 0x00ff0000) << 16)
228
+ | ((x & 0xff000000) << 24);
229
+}
230
+
231
+static uint64_t pmull_h(uint64_t op1, uint64_t op2)
232
+{
233
+ uint64_t result = 0;
234
+ int i;
235
+
236
+ for (i = 0; i < 8; ++i) {
237
+ uint64_t mask = (op1 & 0x0001000100010001ull) * 0xffff;
238
+ result ^= op2 & mask;
239
+ op1 >>= 1;
240
+ op2 <<= 1;
241
+ }
242
+ return result;
243
+}
244
+
245
+void HELPER(neon_pmull_h)(void *vd, void *vn, void *vm, uint32_t desc)
246
+{
247
+ int hi = simd_data(desc);
248
+ uint64_t *d = vd, *n = vn, *m = vm;
249
+ uint64_t nn = n[hi], mm = m[hi];
250
+
251
+ d[0] = pmull_h(expand_byte_to_half(nn), expand_byte_to_half(mm));
252
+ nn >>= 32;
253
+ mm >>= 32;
254
+ d[1] = pmull_h(expand_byte_to_half(nn), expand_byte_to_half(mm));
255
+
256
+ clear_tail(d, 16, simd_maxsz(desc));
257
+}
258
+
259
+#ifdef TARGET_AARCH64
260
+void HELPER(sve2_pmull_h)(void *vd, void *vn, void *vm, uint32_t desc)
261
+{
262
+ int shift = simd_data(desc) * 8;
263
+ intptr_t i, opr_sz = simd_oprsz(desc);
264
+ uint64_t *d = vd, *n = vn, *m = vm;
265
+
266
+ for (i = 0; i < opr_sz / 8; ++i) {
267
+ uint64_t nn = (n[i] >> shift) & 0x00ff00ff00ff00ffull;
268
+ uint64_t mm = (m[i] >> shift) & 0x00ff00ff00ff00ffull;
269
+
270
+ d[i] = pmull_h(nn, mm);
271
+ }
272
+}
273
+#endif
274
--
73
--
275
2.20.1
74
2.34.1
276
277
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Sort this check to the start of a trans_* function.
3
Instead of passing this to get_phys_addr_lpae, stash it
4
Merge this with any existing test for fpdp_v2.
4
in the S1Translate structure.
5
5
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200214181547.21408-10-richard.henderson@linaro.org
9
Message-id: 20230620124418.805717-16-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/translate-vfp.inc.c | 24 ++++++++----------------
12
target/arm/ptw.c | 27 ++++++++++++---------------
12
1 file changed, 8 insertions(+), 16 deletions(-)
13
1 file changed, 12 insertions(+), 15 deletions(-)
13
14
14
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
15
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-vfp.inc.c
17
--- a/target/arm/ptw.c
17
+++ b/target/arm/translate-vfp.inc.c
18
+++ b/target/arm/ptw.c
18
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
19
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
19
* VFPv2 allows access to FPSID from userspace; VFPv3 restricts
20
ARMSecuritySpace in_space;
20
* all ID registers to privileged access only.
21
bool in_secure;
21
*/
22
bool in_debug;
22
- if (IS_USER(s) && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
23
+ /*
23
+ if (IS_USER(s) && dc_isar_feature(aa32_fpsp_v3, s)) {
24
+ * If this is stage 2 of a stage 1+2 page table walk, then this must
24
return false;
25
+ * be true if stage 1 is an EL0 access; otherwise this is ignored.
26
+ * Stage 2 is indicated by in_mmu_idx set to ARMMMUIdx_Stage2{,_S}.
27
+ */
28
+ bool in_s1_is_el0;
29
bool out_secure;
30
bool out_rw;
31
bool out_be;
32
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
33
} S1Translate;
34
35
static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
36
- uint64_t address,
37
- MMUAccessType access_type, bool s1_is_el0,
38
+ uint64_t address, MMUAccessType access_type,
39
GetPhysAddrResult *result, ARMMMUFaultInfo *fi);
40
41
static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
42
@@ -XXX,XX +XXX,XX @@ static int check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, uint64_t tcr,
43
* @ptw: Current and next stage parameters for the walk.
44
* @address: virtual address to get physical address for
45
* @access_type: MMU_DATA_LOAD, MMU_DATA_STORE or MMU_INST_FETCH
46
- * @s1_is_el0: if @ptw->in_mmu_idx is ARMMMUIdx_Stage2
47
- * (so this is a stage 2 page table walk),
48
- * must be true if this is stage 2 of a stage 1+2
49
- * walk for an EL0 access. If @mmu_idx is anything else,
50
- * @s1_is_el0 is ignored.
51
* @result: set on translation success,
52
* @fi: set to fault info if the translation fails
53
*/
54
static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
55
uint64_t address,
56
- MMUAccessType access_type, bool s1_is_el0,
57
+ MMUAccessType access_type,
58
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
59
{
60
ARMCPU *cpu = env_archcpu(env);
61
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
62
result->f.prot = get_S2prot_noexecute(ap);
63
} else {
64
xn = extract64(attrs, 53, 2);
65
- result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
66
+ result->f.prot = get_S2prot(env, ap, xn, ptw->in_s1_is_el0);
25
}
67
}
26
ignore_vfp_enabled = true;
68
} else {
27
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
69
int nse, ns = extract32(attrs, 5, 1);
28
case ARM_VFP_FPINST:
70
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
29
case ARM_VFP_FPINST2:
71
bool ret, ipa_secure;
30
/* Not present in VFPv3 */
72
ARMCacheAttrs cacheattrs1;
31
- if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
73
ARMSecuritySpace ipa_space;
32
+ if (IS_USER(s) || dc_isar_feature(aa32_fpsp_v3, s)) {
74
- bool is_el0;
33
return false;
75
uint64_t hcr;
34
}
76
35
break;
77
ret = get_phys_addr_with_struct(env, ptw, address, access_type, result, fi);
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
78
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
37
79
ipa_secure = result->f.attrs.secure;
38
vd = a->vd;
80
ipa_space = result->f.attrs.space;
39
81
40
- if (!dc_isar_feature(aa32_fpshvec, s) &&
82
- is_el0 = ptw->in_mmu_idx == ARMMMUIdx_Stage1_E0;
41
- (veclen != 0 || s->vec_stride != 0)) {
83
+ ptw->in_s1_is_el0 = ptw->in_mmu_idx == ARMMMUIdx_Stage1_E0;
42
+ if (!dc_isar_feature(aa32_fpsp_v3, s)) {
84
ptw->in_mmu_idx = ipa_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
43
return false;
85
ptw->in_secure = ipa_secure;
86
ptw->in_space = ipa_space;
87
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
88
ret = get_phys_addr_pmsav8(env, ipa, access_type,
89
ptw->in_mmu_idx, is_secure, result, fi);
90
} else {
91
- ret = get_phys_addr_lpae(env, ptw, ipa, access_type,
92
- is_el0, result, fi);
93
+ ret = get_phys_addr_lpae(env, ptw, ipa, access_type, result, fi);
44
}
94
}
45
95
fi->s2addr = ipa;
46
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
96
47
+ if (!dc_isar_feature(aa32_fpshvec, s) &&
97
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
48
+ (veclen != 0 || s->vec_stride != 0)) {
49
return false;
50
}
98
}
51
99
52
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
100
if (regime_using_lpae_format(env, mmu_idx)) {
53
101
- return get_phys_addr_lpae(env, ptw, address, access_type, false,
54
vd = a->vd;
102
- result, fi);
55
103
+ return get_phys_addr_lpae(env, ptw, address, access_type, result, fi);
56
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
104
} else if (arm_feature(env, ARM_FEATURE_V7) ||
57
+ if (!dc_isar_feature(aa32_fpdp_v3, s)) {
105
regime_sctlr(env, mmu_idx) & SCTLR_XP) {
58
return false;
106
return get_phys_addr_v6(env, ptw, address, access_type, result, fi);
59
}
60
61
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
62
return false;
63
}
64
65
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
66
- return false;
67
- }
68
-
69
if (!vfp_access_check(s)) {
70
return true;
71
}
72
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
73
TCGv_ptr fpst;
74
int frac_bits;
75
76
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
77
+ if (!dc_isar_feature(aa32_fpsp_v3, s)) {
78
return false;
79
}
80
81
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
82
TCGv_ptr fpst;
83
int frac_bits;
84
85
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
86
- return false;
87
- }
88
-
89
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
90
+ if (!dc_isar_feature(aa32_fpdp_v3, s)) {
91
return false;
92
}
93
94
--
107
--
95
2.20.1
108
2.34.1
96
109
97
110
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 gvec form will be needed for implementing SVE2.
3
This fixes a bug in which we failed to initialize
4
the result attributes properly after the memset.
4
5
5
Tested-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200216214232.4230-4-richard.henderson@linaro.org
9
Message-id: 20230620124418.805717-17-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/helper.h | 4 +---
12
target/arm/ptw.c | 11 +----------
12
target/arm/neon_helper.c | 30 ------------------------------
13
1 file changed, 1 insertion(+), 10 deletions(-)
13
target/arm/translate-a64.c | 28 +++-------------------------
14
target/arm/translate.c | 16 ++--------------
15
target/arm/vec_helper.c | 33 +++++++++++++++++++++++++++++++++
16
5 files changed, 39 insertions(+), 72 deletions(-)
17
14
18
diff --git a/target/arm/helper.h b/target/arm/helper.h
15
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.h
17
--- a/target/arm/ptw.c
21
+++ b/target/arm/helper.h
18
+++ b/target/arm/ptw.c
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
19
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
23
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
20
void *out_host;
24
DEF_HELPER_2(dc_zva, void, env, i64)
21
} S1Translate;
25
22
26
-DEF_HELPER_FLAGS_2(neon_pmull_64_lo, TCG_CALL_NO_RWG_SE, i64, i64, i64)
23
-static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
27
-DEF_HELPER_FLAGS_2(neon_pmull_64_hi, TCG_CALL_NO_RWG_SE, i64, i64, i64)
24
- uint64_t address, MMUAccessType access_type,
25
- GetPhysAddrResult *result, ARMMMUFaultInfo *fi);
28
-
26
-
29
DEF_HELPER_FLAGS_5(gvec_qrdmlah_s16, TCG_CALL_NO_RWG,
27
static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
30
void, ptr, ptr, ptr, ptr, i32)
28
target_ulong address,
31
DEF_HELPER_FLAGS_5(gvec_qrdmlsh_s16, TCG_CALL_NO_RWG,
29
MMUAccessType access_type,
32
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_ushl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
30
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
33
DEF_HELPER_FLAGS_4(gvec_ushl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
31
cacheattrs1 = result->cacheattrs;
34
32
memset(result, 0, sizeof(*result));
35
DEF_HELPER_FLAGS_4(gvec_pmul_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
36
+DEF_HELPER_FLAGS_4(gvec_pmull_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
34
- if (arm_feature(env, ARM_FEATURE_PMSA)) {
37
35
- ret = get_phys_addr_pmsav8(env, ipa, access_type,
38
#ifdef TARGET_AARCH64
36
- ptw->in_mmu_idx, is_secure, result, fi);
39
#include "helper-a64.h"
37
- } else {
40
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
38
- ret = get_phys_addr_lpae(env, ptw, ipa, access_type, result, fi);
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/neon_helper.c
43
+++ b/target/arm/neon_helper.c
44
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_zip16)(void *vd, void *vm)
45
rm[0] = m0;
46
rd[0] = d0;
47
}
48
-
49
-/* Helper function for 64 bit polynomial multiply case:
50
- * perform PolynomialMult(op1, op2) and return either the top or
51
- * bottom half of the 128 bit result.
52
- */
53
-uint64_t HELPER(neon_pmull_64_lo)(uint64_t op1, uint64_t op2)
54
-{
55
- int bitnum;
56
- uint64_t res = 0;
57
-
58
- for (bitnum = 0; bitnum < 64; bitnum++) {
59
- if (op1 & (1ULL << bitnum)) {
60
- res ^= op2 << bitnum;
61
- }
62
- }
39
- }
63
- return res;
40
+ ret = get_phys_addr_with_struct(env, ptw, ipa, access_type, result, fi);
64
-}
41
fi->s2addr = ipa;
65
-uint64_t HELPER(neon_pmull_64_hi)(uint64_t op1, uint64_t op2)
42
66
-{
43
/* Combine the S1 and S2 perms. */
67
- int bitnum;
68
- uint64_t res = 0;
69
-
70
- /* bit 0 of op1 can't influence the high 64 bits at all */
71
- for (bitnum = 1; bitnum < 64; bitnum++) {
72
- if (op1 & (1ULL << bitnum)) {
73
- res ^= op2 >> (64 - bitnum);
74
- }
75
- }
76
- return res;
77
-}
78
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/target/arm/translate-a64.c
81
+++ b/target/arm/translate-a64.c
82
@@ -XXX,XX +XXX,XX @@ static void handle_3rd_narrowing(DisasContext *s, int is_q, int is_u, int size,
83
clear_vec_high(s, is_q, rd);
84
}
85
86
-static void handle_pmull_64(DisasContext *s, int is_q, int rd, int rn, int rm)
87
-{
88
- /* PMULL of 64 x 64 -> 128 is an odd special case because it
89
- * is the only three-reg-diff instruction which produces a
90
- * 128-bit wide result from a single operation. However since
91
- * it's possible to calculate the two halves more or less
92
- * separately we just use two helper calls.
93
- */
94
- TCGv_i64 tcg_op1 = tcg_temp_new_i64();
95
- TCGv_i64 tcg_op2 = tcg_temp_new_i64();
96
- TCGv_i64 tcg_res = tcg_temp_new_i64();
97
-
98
- read_vec_element(s, tcg_op1, rn, is_q, MO_64);
99
- read_vec_element(s, tcg_op2, rm, is_q, MO_64);
100
- gen_helper_neon_pmull_64_lo(tcg_res, tcg_op1, tcg_op2);
101
- write_vec_element(s, tcg_res, rd, 0, MO_64);
102
- gen_helper_neon_pmull_64_hi(tcg_res, tcg_op1, tcg_op2);
103
- write_vec_element(s, tcg_res, rd, 1, MO_64);
104
-
105
- tcg_temp_free_i64(tcg_op1);
106
- tcg_temp_free_i64(tcg_op2);
107
- tcg_temp_free_i64(tcg_res);
108
-}
109
-
110
/* AdvSIMD three different
111
* 31 30 29 28 24 23 22 21 20 16 15 12 11 10 9 5 4 0
112
* +---+---+---+-----------+------+---+------+--------+-----+------+------+
113
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn)
114
if (!fp_access_check(s)) {
115
return;
116
}
117
- handle_pmull_64(s, is_q, rd, rn, rm);
118
+ /* The Q field specifies lo/hi half input for this insn. */
119
+ gen_gvec_op3_ool(s, true, rd, rn, rm, is_q,
120
+ gen_helper_gvec_pmull_q);
121
return;
122
}
123
goto is_widening;
124
diff --git a/target/arm/translate.c b/target/arm/translate.c
125
index XXXXXXX..XXXXXXX 100644
126
--- a/target/arm/translate.c
127
+++ b/target/arm/translate.c
128
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
129
* outside the loop below as it only performs a single pass.
130
*/
131
if (op == 14 && size == 2) {
132
- TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
133
-
134
if (!dc_isar_feature(aa32_pmull, s)) {
135
return 1;
136
}
137
- tcg_rn = tcg_temp_new_i64();
138
- tcg_rm = tcg_temp_new_i64();
139
- tcg_rd = tcg_temp_new_i64();
140
- neon_load_reg64(tcg_rn, rn);
141
- neon_load_reg64(tcg_rm, rm);
142
- gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
143
- neon_store_reg64(tcg_rd, rd);
144
- gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
145
- neon_store_reg64(tcg_rd, rd + 1);
146
- tcg_temp_free_i64(tcg_rn);
147
- tcg_temp_free_i64(tcg_rm);
148
- tcg_temp_free_i64(tcg_rd);
149
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, 16, 16,
150
+ 0, gen_helper_gvec_pmull_q);
151
return 0;
152
}
153
154
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
155
index XXXXXXX..XXXXXXX 100644
156
--- a/target/arm/vec_helper.c
157
+++ b/target/arm/vec_helper.c
158
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_pmul_b)(void *vd, void *vn, void *vm, uint32_t desc)
159
}
160
clear_tail(d, opr_sz, simd_maxsz(desc));
161
}
162
+
163
+/*
164
+ * 64x64->128 polynomial multiply.
165
+ * Because of the lanes are not accessed in strict columns,
166
+ * this probably cannot be turned into a generic helper.
167
+ */
168
+void HELPER(gvec_pmull_q)(void *vd, void *vn, void *vm, uint32_t desc)
169
+{
170
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
171
+ intptr_t hi = simd_data(desc);
172
+ uint64_t *d = vd, *n = vn, *m = vm;
173
+
174
+ for (i = 0; i < opr_sz / 8; i += 2) {
175
+ uint64_t nn = n[i + hi];
176
+ uint64_t mm = m[i + hi];
177
+ uint64_t rhi = 0;
178
+ uint64_t rlo = 0;
179
+
180
+ /* Bit 0 can only influence the low 64-bit result. */
181
+ if (nn & 1) {
182
+ rlo = mm;
183
+ }
184
+
185
+ for (j = 1; j < 64; ++j) {
186
+ uint64_t mask = -((nn >> j) & 1);
187
+ rlo ^= (mm << j) & mask;
188
+ rhi ^= (mm >> (64 - j)) & mask;
189
+ }
190
+ d[i] = rlo;
191
+ d[i + 1] = rhi;
192
+ }
193
+ clear_tail(d, opr_sz, simd_maxsz(desc));
194
+}
195
--
44
--
196
2.20.1
45
2.34.1
197
46
198
47
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Writes to AdvSIMD registers flush the bits above 128.
3
The function takes the fields as filled in by
4
the Arm ARM pseudocode for TakeGPCException.
4
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200214194643.23317-4-richard.henderson@linaro.org
8
Message-id: 20230620124418.805717-18-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/translate-a64.c | 1 +
11
target/arm/syndrome.h | 10 ++++++++++
11
1 file changed, 1 insertion(+)
12
1 file changed, 10 insertions(+)
12
13
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
16
--- a/target/arm/syndrome.h
16
+++ b/target/arm/translate-a64.c
17
+++ b/target/arm/syndrome.h
17
@@ -XXX,XX +XXX,XX @@ static void disas_simd_zip_trn(DisasContext *s, uint32_t insn)
18
@@ -XXX,XX +XXX,XX @@ enum arm_exception_class {
18
tcg_temp_free_i64(tcg_resl);
19
EC_SVEACCESSTRAP = 0x19,
19
write_vec_element(s, tcg_resh, rd, 1, MO_64);
20
EC_ERETTRAP = 0x1a,
20
tcg_temp_free_i64(tcg_resh);
21
EC_SMETRAP = 0x1d,
21
+ clear_vec_high(s, true, rd);
22
+ EC_GPC = 0x1e,
23
EC_INSNABORT = 0x20,
24
EC_INSNABORT_SAME_EL = 0x21,
25
EC_PCALIGNMENT = 0x22,
26
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_bxjtrap(int cv, int cond, int rm)
27
(cv << 24) | (cond << 20) | rm;
22
}
28
}
23
29
24
/*
30
+static inline uint32_t syn_gpc(int s2ptw, int ind, int gpcsc,
31
+ int cm, int s1ptw, int wnr, int fsc)
32
+{
33
+ /* TODO: FEAT_NV2 adds VNCR */
34
+ return (EC_GPC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (s2ptw << 21)
35
+ | (ind << 20) | (gpcsc << 14) | (cm << 8) | (s1ptw << 7)
36
+ | (wnr << 6) | fsc;
37
+}
38
+
39
static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
40
{
41
return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
25
--
42
--
26
2.20.1
43
2.34.1
27
28
diff view generated by jsdifflib
1
The AArch32 DBGDIDR defines properties like the number of
1
From: Richard Henderson <richard.henderson@linaro.org>
2
breakpoints, watchpoints and context-matching comparators. On an
3
AArch64 CPU, the register may not even exist if AArch32 is not
4
supported at EL1.
5
2
6
Currently we hard-code use of DBGDIDR to identify the number of
3
Handle GPC Fault types in arm_deliver_fault, reporting as
7
breakpoints etc; this works for all our TCG CPUs, but will break if
4
either a GPC exception at EL3, or falling through to insn
8
we ever add an AArch64-only CPU. We also have an assert() that the
5
or data aborts at various exception levels.
9
AArch32 and AArch64 registers match, which currently works only by
10
luck for KVM because we don't populate either of these ID registers
11
from the KVM vCPU and so they are both zero.
12
6
13
Clean this up so we have functions for finding the number
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
of breakpoints, watchpoints and context comparators which look
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
in the appropriate ID register.
9
Message-id: 20230620124418.805717-19-richard.henderson@linaro.org
16
17
This allows us to drop the "check that AArch64 and AArch32 agree
18
on the number of breakpoints etc" asserts:
19
* we no longer look at the AArch32 versions unless that's the
20
right place to be looking
21
* it's valid to have a CPU (eg AArch64-only) where they don't match
22
* we shouldn't have been asserting the validity of ID registers
23
in a codepath used with KVM anyway
24
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Message-id: 20200214175116.9164-11-peter.maydell@linaro.org
28
---
11
---
29
target/arm/cpu.h | 7 +++++++
12
target/arm/cpu.h | 1 +
30
target/arm/internals.h | 42 +++++++++++++++++++++++++++++++++++++++
13
target/arm/internals.h | 27 +++++++++++
31
target/arm/debug_helper.c | 6 +++---
14
target/arm/helper.c | 5 ++
32
target/arm/helper.c | 21 +++++---------------
15
target/arm/tcg/tlb_helper.c | 96 +++++++++++++++++++++++++++++++++++--
33
4 files changed, 57 insertions(+), 19 deletions(-)
16
4 files changed, 126 insertions(+), 3 deletions(-)
34
17
35
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
36
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/cpu.h
20
--- a/target/arm/cpu.h
38
+++ b/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
39
@@ -XXX,XX +XXX,XX @@ FIELD(ID_DFR0, MPROFDBG, 20, 4)
22
@@ -XXX,XX +XXX,XX @@
40
FIELD(ID_DFR0, PERFMON, 24, 4)
23
#define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */
41
FIELD(ID_DFR0, TRACEFILT, 28, 4)
24
#define EXCP_DIVBYZERO 23 /* v7M DIVBYZERO UsageFault */
42
25
#define EXCP_VSERR 24
43
+FIELD(DBGDIDR, SE_IMP, 12, 1)
26
+#define EXCP_GPC 25 /* v9 Granule Protection Check Fault */
44
+FIELD(DBGDIDR, NSUHD_IMP, 14, 1)
27
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
45
+FIELD(DBGDIDR, VERSION, 16, 4)
28
46
+FIELD(DBGDIDR, CTX_CMPS, 20, 4)
29
#define ARMV7M_EXCP_RESET 1
47
+FIELD(DBGDIDR, BRPS, 24, 4)
48
+FIELD(DBGDIDR, WRPS, 28, 4)
49
+
50
FIELD(MVFR0, SIMDREG, 0, 4)
51
FIELD(MVFR0, FPSP, 4, 4)
52
FIELD(MVFR0, FPDP, 8, 4)
53
diff --git a/target/arm/internals.h b/target/arm/internals.h
30
diff --git a/target/arm/internals.h b/target/arm/internals.h
54
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/internals.h
32
--- a/target/arm/internals.h
56
+++ b/target/arm/internals.h
33
+++ b/target/arm/internals.h
57
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_debug_exception_fsr(CPUARMState *env)
34
@@ -XXX,XX +XXX,XX @@ typedef enum ARMFaultType {
35
ARMFault_ICacheMaint,
36
ARMFault_QEMU_NSCExec, /* v8M: NS executing in S&NSC memory */
37
ARMFault_QEMU_SFault, /* v8M: SecureFault INVTRAN, INVEP or AUVIOL */
38
+ ARMFault_GPCFOnWalk,
39
+ ARMFault_GPCFOnOutput,
40
} ARMFaultType;
41
42
+typedef enum ARMGPCF {
43
+ GPCF_None,
44
+ GPCF_AddressSize,
45
+ GPCF_Walk,
46
+ GPCF_EABT,
47
+ GPCF_Fail,
48
+} ARMGPCF;
49
+
50
/**
51
* ARMMMUFaultInfo: Information describing an ARM MMU Fault
52
* @type: Type of fault
53
+ * @gpcf: Subtype of ARMFault_GPCFOn{Walk,Output}.
54
* @level: Table walk level (for translation, access flag and permission faults)
55
* @domain: Domain of the fault address (for non-LPAE CPUs only)
56
* @s2addr: Address that caused a fault at stage 2
57
+ * @paddr: physical address that caused a fault for gpc
58
+ * @paddr_space: physical address space that caused a fault for gpc
59
* @stage2: True if we faulted at stage 2
60
* @s1ptw: True if we faulted at stage 2 while doing a stage 1 page-table walk
61
* @s1ns: True if we faulted on a non-secure IPA while in secure state
62
@@ -XXX,XX +XXX,XX @@ typedef enum ARMFaultType {
63
typedef struct ARMMMUFaultInfo ARMMMUFaultInfo;
64
struct ARMMMUFaultInfo {
65
ARMFaultType type;
66
+ ARMGPCF gpcf;
67
target_ulong s2addr;
68
+ target_ulong paddr;
69
+ ARMSecuritySpace paddr_space;
70
int level;
71
int domain;
72
bool stage2;
73
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
74
case ARMFault_Exclusive:
75
fsc = 0x35;
76
break;
77
+ case ARMFault_GPCFOnWalk:
78
+ assert(fi->level >= -1 && fi->level <= 3);
79
+ if (fi->level < 0) {
80
+ fsc = 0b100011;
81
+ } else {
82
+ fsc = 0b100100 | fi->level;
83
+ }
84
+ break;
85
+ case ARMFault_GPCFOnOutput:
86
+ fsc = 0b101000;
87
+ break;
88
default:
89
/* Other faults can't occur in a context that requires a
90
* long-format status code.
91
diff --git a/target/arm/helper.c b/target/arm/helper.c
92
index XXXXXXX..XXXXXXX 100644
93
--- a/target/arm/helper.c
94
+++ b/target/arm/helper.c
95
@@ -XXX,XX +XXX,XX @@ void arm_log_exception(CPUState *cs)
96
[EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
97
[EXCP_DIVBYZERO] = "v7M DIVBYZERO UsageFault",
98
[EXCP_VSERR] = "Virtual SERR",
99
+ [EXCP_GPC] = "Granule Protection Check",
100
};
101
102
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
103
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
58
}
104
}
105
106
switch (cs->exception_index) {
107
+ case EXCP_GPC:
108
+ qemu_log_mask(CPU_LOG_INT, "...with MFAR 0x%" PRIx64 "\n",
109
+ env->cp15.mfar_el3);
110
+ /* fall through */
111
case EXCP_PREFETCH_ABORT:
112
case EXCP_DATA_ABORT:
113
/*
114
diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/target/arm/tcg/tlb_helper.c
117
+++ b/target/arm/tcg/tlb_helper.c
118
@@ -XXX,XX +XXX,XX @@ static uint32_t compute_fsr_fsc(CPUARMState *env, ARMMMUFaultInfo *fi,
119
return fsr;
59
}
120
}
60
121
61
+/**
122
+static bool report_as_gpc_exception(ARMCPU *cpu, int current_el,
62
+ * arm_num_brps: Return number of implemented breakpoints.
123
+ ARMMMUFaultInfo *fi)
63
+ * Note that the ID register BRPS field is "number of bps - 1",
64
+ * and we return the actual number of breakpoints.
65
+ */
66
+static inline int arm_num_brps(ARMCPU *cpu)
67
+{
124
+{
68
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
125
+ bool ret;
69
+ return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) + 1;
126
+
127
+ switch (fi->gpcf) {
128
+ case GPCF_None:
129
+ return false;
130
+ case GPCF_AddressSize:
131
+ case GPCF_Walk:
132
+ case GPCF_EABT:
133
+ /* R_PYTGX: GPT faults are reported as GPC. */
134
+ ret = true;
135
+ break;
136
+ case GPCF_Fail:
137
+ /*
138
+ * R_BLYPM: A GPF at EL3 is reported as insn or data abort.
139
+ * R_VBZMW, R_LXHQR: A GPF at EL[0-2] is reported as a GPC
140
+ * if SCR_EL3.GPF is set, otherwise an insn or data abort.
141
+ */
142
+ ret = (cpu->env.cp15.scr_el3 & SCR_GPF) && current_el != 3;
143
+ break;
144
+ default:
145
+ g_assert_not_reached();
146
+ }
147
+
148
+ assert(cpu_isar_feature(aa64_rme, cpu));
149
+ assert(fi->type == ARMFault_GPCFOnWalk ||
150
+ fi->type == ARMFault_GPCFOnOutput);
151
+ if (fi->gpcf == GPCF_AddressSize) {
152
+ assert(fi->level == 0);
70
+ } else {
153
+ } else {
71
+ return FIELD_EX32(cpu->dbgdidr, DBGDIDR, BRPS) + 1;
154
+ assert(fi->level >= 0 && fi->level <= 1);
72
+ }
155
+ }
156
+
157
+ return ret;
73
+}
158
+}
74
+
159
+
75
+/**
160
+static unsigned encode_gpcsc(ARMMMUFaultInfo *fi)
76
+ * arm_num_wrps: Return number of implemented watchpoints.
77
+ * Note that the ID register WRPS field is "number of wps - 1",
78
+ * and we return the actual number of watchpoints.
79
+ */
80
+static inline int arm_num_wrps(ARMCPU *cpu)
81
+{
161
+{
82
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
162
+ static uint8_t const gpcsc[] = {
83
+ return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) + 1;
163
+ [GPCF_AddressSize] = 0b000000,
84
+ } else {
164
+ [GPCF_Walk] = 0b000100,
85
+ return FIELD_EX32(cpu->dbgdidr, DBGDIDR, WRPS) + 1;
165
+ [GPCF_Fail] = 0b001100,
86
+ }
166
+ [GPCF_EABT] = 0b010100,
167
+ };
168
+
169
+ /* Note that we've validated fi->gpcf and fi->level above. */
170
+ return gpcsc[fi->gpcf] | fi->level;
87
+}
171
+}
88
+
172
+
89
+/**
173
static G_NORETURN
90
+ * arm_num_ctx_cmps: Return number of implemented context comparators.
174
void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
91
+ * Note that the ID register CTX_CMPS field is "number of cmps - 1",
175
MMUAccessType access_type,
92
+ * and we return the actual number of comparators.
176
int mmu_idx, ARMMMUFaultInfo *fi)
93
+ */
94
+static inline int arm_num_ctx_cmps(ARMCPU *cpu)
95
+{
96
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
97
+ return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) + 1;
98
+ } else {
99
+ return FIELD_EX32(cpu->dbgdidr, DBGDIDR, CTX_CMPS) + 1;
100
+ }
101
+}
102
+
103
/* Note make_memop_idx reserves 4 bits for mmu_idx, and MO_BSWAP is bit 3.
104
* Thus a TCGMemOpIdx, without any MO_ALIGN bits, fits in 8 bits.
105
*/
106
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/debug_helper.c
109
+++ b/target/arm/debug_helper.c
110
@@ -XXX,XX +XXX,XX @@ static bool linked_bp_matches(ARMCPU *cpu, int lbn)
111
{
177
{
112
CPUARMState *env = &cpu->env;
178
CPUARMState *env = &cpu->env;
113
uint64_t bcr = env->cp15.dbgbcr[lbn];
179
- int target_el;
114
- int brps = extract32(cpu->dbgdidr, 24, 4);
180
+ int target_el = exception_target_el(env);
115
- int ctx_cmps = extract32(cpu->dbgdidr, 20, 4);
181
+ int current_el = arm_current_el(env);
116
+ int brps = arm_num_brps(cpu);
182
bool same_el;
117
+ int ctx_cmps = arm_num_ctx_cmps(cpu);
183
uint32_t syn, exc, fsr, fsc;
118
int bt;
184
119
uint32_t contextidr;
185
- target_el = exception_target_el(env);
120
uint64_t hcr_el2;
186
+ if (report_as_gpc_exception(cpu, current_el, fi)) {
121
@@ -XXX,XX +XXX,XX @@ static bool linked_bp_matches(ARMCPU *cpu, int lbn)
187
+ target_el = 3;
122
* case DBGWCR<n>_EL1.LBN must indicate that breakpoint).
188
+
123
* We choose the former.
189
+ fsr = compute_fsr_fsc(env, fi, target_el, mmu_idx, &fsc);
124
*/
190
+
125
- if (lbn > brps || lbn < (brps - ctx_cmps)) {
191
+ syn = syn_gpc(fi->stage2 && fi->type == ARMFault_GPCFOnWalk,
126
+ if (lbn >= brps || lbn < (brps - ctx_cmps)) {
192
+ access_type == MMU_INST_FETCH,
127
return false;
193
+ encode_gpcsc(fi), 0, fi->s1ptw,
194
+ access_type == MMU_DATA_STORE, fsc);
195
+
196
+ env->cp15.mfar_el3 = fi->paddr;
197
+ switch (fi->paddr_space) {
198
+ case ARMSS_Secure:
199
+ break;
200
+ case ARMSS_NonSecure:
201
+ env->cp15.mfar_el3 |= R_MFAR_NS_MASK;
202
+ break;
203
+ case ARMSS_Root:
204
+ env->cp15.mfar_el3 |= R_MFAR_NSE_MASK;
205
+ break;
206
+ case ARMSS_Realm:
207
+ env->cp15.mfar_el3 |= R_MFAR_NSE_MASK | R_MFAR_NS_MASK;
208
+ break;
209
+ default:
210
+ g_assert_not_reached();
211
+ }
212
+
213
+ exc = EXCP_GPC;
214
+ goto do_raise;
215
+ }
216
+
217
+ /* If SCR_EL3.GPF is unset, GPF may still be routed to EL2. */
218
+ if (fi->gpcf == GPCF_Fail && target_el < 2) {
219
+ if (arm_hcr_el2_eff(env) & HCR_GPF) {
220
+ target_el = 2;
221
+ }
222
+ }
223
+
224
if (fi->stage2) {
225
target_el = 2;
226
env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
227
@@ -XXX,XX +XXX,XX @@ void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
228
env->cp15.hpfar_el2 |= HPFAR_NS;
229
}
128
}
230
}
129
231
- same_el = (arm_current_el(env) == target_el);
130
diff --git a/target/arm/helper.c b/target/arm/helper.c
232
131
index XXXXXXX..XXXXXXX 100644
233
+ same_el = current_el == target_el;
132
--- a/target/arm/helper.c
234
fsr = compute_fsr_fsc(env, fi, target_el, mmu_idx, &fsc);
133
+++ b/target/arm/helper.c
235
134
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
236
if (access_type == MMU_INST_FETCH) {
135
};
237
@@ -XXX,XX +XXX,XX @@ void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
136
238
exc = EXCP_DATA_ABORT;
137
/* Note that all these register fields hold "number of Xs minus 1". */
138
- brps = extract32(cpu->dbgdidr, 24, 4);
139
- wrps = extract32(cpu->dbgdidr, 28, 4);
140
- ctx_cmps = extract32(cpu->dbgdidr, 20, 4);
141
+ brps = arm_num_brps(cpu);
142
+ wrps = arm_num_wrps(cpu);
143
+ ctx_cmps = arm_num_ctx_cmps(cpu);
144
145
assert(ctx_cmps <= brps);
146
147
- /* The DBGDIDR and ID_AA64DFR0_EL1 define various properties
148
- * of the debug registers such as number of breakpoints;
149
- * check that if they both exist then they agree.
150
- */
151
- if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
152
- assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
153
- assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
154
- assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS)
155
- == ctx_cmps);
156
- }
157
-
158
define_one_arm_cp_reg(cpu, &dbgdidr);
159
define_arm_cp_regs(cpu, debug_cp_reginfo);
160
161
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
162
define_arm_cp_regs(cpu, debug_lpae_cp_reginfo);
163
}
239
}
164
240
165
- for (i = 0; i < brps + 1; i++) {
241
+ do_raise:
166
+ for (i = 0; i < brps; i++) {
242
env->exception.vaddress = addr;
167
ARMCPRegInfo dbgregs[] = {
243
env->exception.fsr = fsr;
168
{ .name = "DBGBVR", .state = ARM_CP_STATE_BOTH,
244
raise_exception(env, exc, syn, target_el);
169
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,
170
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
171
define_arm_cp_regs(cpu, dbgregs);
172
}
173
174
- for (i = 0; i < wrps + 1; i++) {
175
+ for (i = 0; i < wrps; i++) {
176
ARMCPRegInfo dbgregs[] = {
177
{ .name = "DBGWVR", .state = ARM_CP_STATE_BOTH,
178
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,
179
--
245
--
180
2.20.1
246
2.34.1
181
182
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
For the purpose of rebuild_hflags_a64, we do not need to compute
3
Place the check at the end of get_phys_addr_with_struct,
4
all of the va parameters, only tbi. Moreover, we can compute them
4
so that we check all physical results.
5
in a form that is more useful to storing in hflags.
6
7
This eliminates the need for aa64_va_parameter_both, so fold that
8
in to aa64_va_parameter. The remaining calls to aa64_va_parameter
9
are in get_phys_addr_lpae and in pauth_helper.c.
10
11
This reduces the total cpu consumption of aa64_va_parameter in a
12
kernel boot plus a kvm guest kernel boot from 3% to 0.5%.
13
5
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20200216194343.21331-5-richard.henderson@linaro.org
8
Message-id: 20230620124418.805717-20-richard.henderson@linaro.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
10
---
19
target/arm/internals.h | 3 --
11
target/arm/ptw.c | 249 +++++++++++++++++++++++++++++++++++++++++++----
20
target/arm/helper.c | 68 +++++++++++++++++++++++-------------------
12
1 file changed, 232 insertions(+), 17 deletions(-)
21
2 files changed, 37 insertions(+), 34 deletions(-)
22
13
23
diff --git a/target/arm/internals.h b/target/arm/internals.h
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
24
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/internals.h
16
--- a/target/arm/ptw.c
26
+++ b/target/arm/internals.h
17
+++ b/target/arm/ptw.c
27
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
18
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
28
unsigned tsz : 8;
19
void *out_host;
29
unsigned select : 1;
20
} S1Translate;
30
bool tbi : 1;
21
31
- bool tbid : 1;
22
-static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
32
bool epd : 1;
23
- target_ulong address,
33
bool hpd : 1;
24
- MMUAccessType access_type,
34
bool using16k : 1;
25
- GetPhysAddrResult *result,
35
bool using64k : 1;
26
- ARMMMUFaultInfo *fi);
36
} ARMVAParameters;
27
+static bool get_phys_addr_nogpc(CPUARMState *env, S1Translate *ptw,
37
28
+ target_ulong address,
38
-ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
29
+ MMUAccessType access_type,
39
- ARMMMUIdx mmu_idx);
30
+ GetPhysAddrResult *result,
40
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
31
+ ARMMMUFaultInfo *fi);
41
ARMMMUIdx mmu_idx, bool data);
32
+
42
33
+static bool get_phys_addr_gpc(CPUARMState *env, S1Translate *ptw,
43
diff --git a/target/arm/helper.c b/target/arm/helper.c
34
+ target_ulong address,
44
index XXXXXXX..XXXXXXX 100644
35
+ MMUAccessType access_type,
45
--- a/target/arm/helper.c
36
+ GetPhysAddrResult *result,
46
+++ b/target/arm/helper.c
37
+ ARMMMUFaultInfo *fi);
47
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
38
48
}
39
/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
49
#endif /* !CONFIG_USER_ONLY */
40
static const uint8_t pamax_map[] = {
50
41
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
51
-ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
42
return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0;
52
- ARMMMUIdx mmu_idx)
43
}
53
+static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx)
44
45
+static bool granule_protection_check(CPUARMState *env, uint64_t paddress,
46
+ ARMSecuritySpace pspace,
47
+ ARMMMUFaultInfo *fi)
54
+{
48
+{
55
+ if (regime_has_2_ranges(mmu_idx)) {
49
+ MemTxAttrs attrs = {
56
+ return extract64(tcr, 37, 2);
50
+ .secure = true,
57
+ } else if (mmu_idx == ARMMMUIdx_Stage2) {
51
+ .space = ARMSS_Root,
58
+ return 0; /* VTCR_EL2 */
52
+ };
59
+ } else {
53
+ ARMCPU *cpu = env_archcpu(env);
60
+ return extract32(tcr, 20, 1);
54
+ uint64_t gpccr = env->cp15.gpccr_el3;
61
+ }
55
+ unsigned pps, pgs, l0gptsz, level = 0;
56
+ uint64_t tableaddr, pps_mask, align, entry, index;
57
+ AddressSpace *as;
58
+ MemTxResult result;
59
+ int gpi;
60
+
61
+ if (!FIELD_EX64(gpccr, GPCCR, GPC)) {
62
+ return true;
63
+ }
64
+
65
+ /*
66
+ * GPC Priority 1 (R_GMGRR):
67
+ * R_JWCSM: If the configuration of GPCCR_EL3 is invalid,
68
+ * the access fails as GPT walk fault at level 0.
69
+ */
70
+
71
+ /*
72
+ * Configuration of PPS to a value exceeding the implemented
73
+ * physical address size is invalid.
74
+ */
75
+ pps = FIELD_EX64(gpccr, GPCCR, PPS);
76
+ if (pps > FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE)) {
77
+ goto fault_walk;
78
+ }
79
+ pps = pamax_map[pps];
80
+ pps_mask = MAKE_64BIT_MASK(0, pps);
81
+
82
+ switch (FIELD_EX64(gpccr, GPCCR, SH)) {
83
+ case 0b10: /* outer shareable */
84
+ break;
85
+ case 0b00: /* non-shareable */
86
+ case 0b11: /* inner shareable */
87
+ /* Inner and Outer non-cacheable requires Outer shareable. */
88
+ if (FIELD_EX64(gpccr, GPCCR, ORGN) == 0 &&
89
+ FIELD_EX64(gpccr, GPCCR, IRGN) == 0) {
90
+ goto fault_walk;
91
+ }
92
+ break;
93
+ default: /* reserved */
94
+ goto fault_walk;
95
+ }
96
+
97
+ switch (FIELD_EX64(gpccr, GPCCR, PGS)) {
98
+ case 0b00: /* 4KB */
99
+ pgs = 12;
100
+ break;
101
+ case 0b01: /* 64KB */
102
+ pgs = 16;
103
+ break;
104
+ case 0b10: /* 16KB */
105
+ pgs = 14;
106
+ break;
107
+ default: /* reserved */
108
+ goto fault_walk;
109
+ }
110
+
111
+ /* Note this field is read-only and fixed at reset. */
112
+ l0gptsz = 30 + FIELD_EX64(gpccr, GPCCR, L0GPTSZ);
113
+
114
+ /*
115
+ * GPC Priority 2: Secure, Realm or Root address exceeds PPS.
116
+ * R_CPDSB: A NonSecure physical address input exceeding PPS
117
+ * does not experience any fault.
118
+ */
119
+ if (paddress & ~pps_mask) {
120
+ if (pspace == ARMSS_NonSecure) {
121
+ return true;
122
+ }
123
+ goto fault_size;
124
+ }
125
+
126
+ /* GPC Priority 3: the base address of GPTBR_EL3 exceeds PPS. */
127
+ tableaddr = env->cp15.gptbr_el3 << 12;
128
+ if (tableaddr & ~pps_mask) {
129
+ goto fault_size;
130
+ }
131
+
132
+ /*
133
+ * BADDR is aligned per a function of PPS and L0GPTSZ.
134
+ * These bits of GPTBR_EL3 are RES0, but are not a configuration error,
135
+ * unlike the RES0 bits of the GPT entries (R_XNKFZ).
136
+ */
137
+ align = MAX(pps - l0gptsz + 3, 12);
138
+ align = MAKE_64BIT_MASK(0, align);
139
+ tableaddr &= ~align;
140
+
141
+ as = arm_addressspace(env_cpu(env), attrs);
142
+
143
+ /* Level 0 lookup. */
144
+ index = extract64(paddress, l0gptsz, pps - l0gptsz);
145
+ tableaddr += index * 8;
146
+ entry = address_space_ldq_le(as, tableaddr, attrs, &result);
147
+ if (result != MEMTX_OK) {
148
+ goto fault_eabt;
149
+ }
150
+
151
+ switch (extract32(entry, 0, 4)) {
152
+ case 1: /* block descriptor */
153
+ if (entry >> 8) {
154
+ goto fault_walk; /* RES0 bits not 0 */
155
+ }
156
+ gpi = extract32(entry, 4, 4);
157
+ goto found;
158
+ case 3: /* table descriptor */
159
+ tableaddr = entry & ~0xf;
160
+ align = MAX(l0gptsz - pgs - 1, 12);
161
+ align = MAKE_64BIT_MASK(0, align);
162
+ if (tableaddr & (~pps_mask | align)) {
163
+ goto fault_walk; /* RES0 bits not 0 */
164
+ }
165
+ break;
166
+ default: /* invalid */
167
+ goto fault_walk;
168
+ }
169
+
170
+ /* Level 1 lookup */
171
+ level = 1;
172
+ index = extract64(paddress, pgs + 4, l0gptsz - pgs - 4);
173
+ tableaddr += index * 8;
174
+ entry = address_space_ldq_le(as, tableaddr, attrs, &result);
175
+ if (result != MEMTX_OK) {
176
+ goto fault_eabt;
177
+ }
178
+
179
+ switch (extract32(entry, 0, 4)) {
180
+ case 1: /* contiguous descriptor */
181
+ if (entry >> 10) {
182
+ goto fault_walk; /* RES0 bits not 0 */
183
+ }
184
+ /*
185
+ * Because the softmmu tlb only works on units of TARGET_PAGE_SIZE,
186
+ * and because we cannot invalidate by pa, and thus will always
187
+ * flush entire tlbs, we don't actually care about the range here
188
+ * and can simply extract the GPI as the result.
189
+ */
190
+ if (extract32(entry, 8, 2) == 0) {
191
+ goto fault_walk; /* reserved contig */
192
+ }
193
+ gpi = extract32(entry, 4, 4);
194
+ break;
195
+ default:
196
+ index = extract64(paddress, pgs, 4);
197
+ gpi = extract64(entry, index * 4, 4);
198
+ break;
199
+ }
200
+
201
+ found:
202
+ switch (gpi) {
203
+ case 0b0000: /* no access */
204
+ break;
205
+ case 0b1111: /* all access */
206
+ return true;
207
+ case 0b1000:
208
+ case 0b1001:
209
+ case 0b1010:
210
+ case 0b1011:
211
+ if (pspace == (gpi & 3)) {
212
+ return true;
213
+ }
214
+ break;
215
+ default:
216
+ goto fault_walk; /* reserved */
217
+ }
218
+
219
+ fi->gpcf = GPCF_Fail;
220
+ goto fault_common;
221
+ fault_eabt:
222
+ fi->gpcf = GPCF_EABT;
223
+ goto fault_common;
224
+ fault_size:
225
+ fi->gpcf = GPCF_AddressSize;
226
+ goto fault_common;
227
+ fault_walk:
228
+ fi->gpcf = GPCF_Walk;
229
+ fault_common:
230
+ fi->level = level;
231
+ fi->paddr = paddress;
232
+ fi->paddr_space = pspace;
233
+ return false;
62
+}
234
+}
63
+
235
+
64
+static int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx)
236
static bool S2_attrs_are_device(uint64_t hcr, uint8_t attrs)
237
{
238
/*
239
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
240
};
241
GetPhysAddrResult s2 = { };
242
243
- if (get_phys_addr_with_struct(env, &s2ptw, addr,
244
- MMU_DATA_LOAD, &s2, fi)) {
245
+ if (get_phys_addr_gpc(env, &s2ptw, addr, MMU_DATA_LOAD, &s2, fi)) {
246
goto fail;
247
}
248
+
249
ptw->out_phys = s2.f.phys_addr;
250
pte_attrs = s2.cacheattrs.attrs;
251
ptw->out_host = NULL;
252
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
253
254
fail:
255
assert(fi->type != ARMFault_None);
256
+ if (fi->type == ARMFault_GPCFOnOutput) {
257
+ fi->type = ARMFault_GPCFOnWalk;
258
+ }
259
fi->s2addr = addr;
260
fi->stage2 = true;
261
fi->s1ptw = true;
262
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
263
ARMMMUFaultInfo *fi)
264
{
265
uint8_t memattr = 0x00; /* Device nGnRnE */
266
- uint8_t shareability = 0; /* non-sharable */
267
+ uint8_t shareability = 0; /* non-shareable */
268
int r_el;
269
270
switch (mmu_idx) {
271
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
272
} else {
273
memattr = 0x44; /* Normal, NC, No */
274
}
275
- shareability = 2; /* outer sharable */
276
+ shareability = 2; /* outer shareable */
277
}
278
result->cacheattrs.is_s2_format = false;
279
break;
280
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
281
ARMSecuritySpace ipa_space;
282
uint64_t hcr;
283
284
- ret = get_phys_addr_with_struct(env, ptw, address, access_type, result, fi);
285
+ ret = get_phys_addr_nogpc(env, ptw, address, access_type, result, fi);
286
287
/* If S1 fails, return early. */
288
if (ret) {
289
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
290
cacheattrs1 = result->cacheattrs;
291
memset(result, 0, sizeof(*result));
292
293
- ret = get_phys_addr_with_struct(env, ptw, ipa, access_type, result, fi);
294
+ ret = get_phys_addr_nogpc(env, ptw, ipa, access_type, result, fi);
295
fi->s2addr = ipa;
296
297
/* Combine the S1 and S2 perms. */
298
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
299
return false;
300
}
301
302
-static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
303
+static bool get_phys_addr_nogpc(CPUARMState *env, S1Translate *ptw,
304
target_ulong address,
305
MMUAccessType access_type,
306
GetPhysAddrResult *result,
307
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
308
}
309
}
310
311
+static bool get_phys_addr_gpc(CPUARMState *env, S1Translate *ptw,
312
+ target_ulong address,
313
+ MMUAccessType access_type,
314
+ GetPhysAddrResult *result,
315
+ ARMMMUFaultInfo *fi)
65
+{
316
+{
66
+ if (regime_has_2_ranges(mmu_idx)) {
317
+ if (get_phys_addr_nogpc(env, ptw, address, access_type, result, fi)) {
67
+ return extract64(tcr, 51, 2);
318
+ return true;
68
+ } else if (mmu_idx == ARMMMUIdx_Stage2) {
319
+ }
69
+ return 0; /* VTCR_EL2 */
320
+ if (!granule_protection_check(env, result->f.phys_addr,
70
+ } else {
321
+ result->f.attrs.space, fi)) {
71
+ return extract32(tcr, 29, 1);
322
+ fi->type = ARMFault_GPCFOnOutput;
72
+ }
323
+ return true;
324
+ }
325
+ return false;
73
+}
326
+}
74
+
327
+
75
+ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
328
bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
76
+ ARMMMUIdx mmu_idx, bool data)
329
MMUAccessType access_type, ARMMMUIdx mmu_idx,
77
{
330
bool is_secure, GetPhysAddrResult *result,
78
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
331
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
79
- bool tbi, tbid, epd, hpd, using16k, using64k;
332
.in_secure = is_secure,
80
- int select, tsz;
333
.in_space = arm_secure_to_space(is_secure),
81
+ bool epd, hpd, using16k, using64k;
82
+ int select, tsz, tbi;
83
84
if (!regime_has_2_ranges(mmu_idx)) {
85
select = 0;
86
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
87
using16k = extract32(tcr, 15, 1);
88
if (mmu_idx == ARMMMUIdx_Stage2) {
89
/* VTCR_EL2 */
90
- tbi = tbid = hpd = false;
91
+ hpd = false;
92
} else {
93
- tbi = extract32(tcr, 20, 1);
94
hpd = extract32(tcr, 24, 1);
95
- tbid = extract32(tcr, 29, 1);
96
}
97
epd = false;
98
} else {
99
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
100
epd = extract32(tcr, 7, 1);
101
using64k = extract32(tcr, 14, 1);
102
using16k = extract32(tcr, 15, 1);
103
- tbi = extract64(tcr, 37, 1);
104
hpd = extract64(tcr, 41, 1);
105
- tbid = extract64(tcr, 51, 1);
106
} else {
107
int tg = extract32(tcr, 30, 2);
108
using16k = tg == 1;
109
using64k = tg == 3;
110
tsz = extract32(tcr, 16, 6);
111
epd = extract32(tcr, 23, 1);
112
- tbi = extract64(tcr, 38, 1);
113
hpd = extract64(tcr, 42, 1);
114
- tbid = extract64(tcr, 52, 1);
115
}
116
}
117
tsz = MIN(tsz, 39); /* TODO: ARMv8.4-TTST */
118
tsz = MAX(tsz, 16); /* TODO: ARMv8.2-LVA */
119
120
+ /* Present TBI as a composite with TBID. */
121
+ tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
122
+ if (!data) {
123
+ tbi &= ~aa64_va_parameter_tbid(tcr, mmu_idx);
124
+ }
125
+ tbi = (tbi >> select) & 1;
126
+
127
return (ARMVAParameters) {
128
.tsz = tsz,
129
.select = select,
130
.tbi = tbi,
131
- .tbid = tbid,
132
.epd = epd,
133
.hpd = hpd,
134
.using16k = using16k,
135
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
136
};
334
};
137
}
335
- return get_phys_addr_with_struct(env, &ptw, address, access_type,
138
336
- result, fi);
139
-ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
337
+ return get_phys_addr_gpc(env, &ptw, address, access_type, result, fi);
140
- ARMMMUIdx mmu_idx, bool data)
338
}
141
-{
339
142
- ARMVAParameters ret = aa64_va_parameters_both(env, va, mmu_idx);
340
bool get_phys_addr(CPUARMState *env, target_ulong address,
143
-
341
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
144
- /* Present TBI as a composite with TBID. */
342
145
- ret.tbi &= (data || !ret.tbid);
343
ptw.in_space = ss;
146
- return ret;
344
ptw.in_secure = arm_space_is_secure(ss);
147
-}
345
- return get_phys_addr_with_struct(env, &ptw, address, access_type,
148
-
346
- result, fi);
149
#ifndef CONFIG_USER_ONLY
347
+ return get_phys_addr_gpc(env, &ptw, address, access_type, result, fi);
150
static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
348
}
151
ARMMMUIdx mmu_idx)
349
152
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
350
hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
153
{
351
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
154
uint32_t flags = rebuild_hflags_aprofile(env);
352
ARMMMUFaultInfo fi = {};
155
ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
353
bool ret;
156
- ARMVAParameters p0 = aa64_va_parameters_both(env, 0, stage1);
354
157
+ uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
355
- ret = get_phys_addr_with_struct(env, &ptw, addr, MMU_DATA_LOAD, &res, &fi);
158
uint64_t sctlr;
356
+ ret = get_phys_addr_gpc(env, &ptw, addr, MMU_DATA_LOAD, &res, &fi);
159
int tbii, tbid;
357
*attrs = res.f.attrs;
160
358
161
flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
359
if (ret) {
162
163
/* Get control bits for tagged addresses. */
164
- if (regime_has_2_ranges(mmu_idx)) {
165
- ARMVAParameters p1 = aa64_va_parameters_both(env, -1, stage1);
166
- tbid = (p1.tbi << 1) | p0.tbi;
167
- tbii = tbid & ~((p1.tbid << 1) | p0.tbid);
168
- } else {
169
- tbid = p0.tbi;
170
- tbii = tbid & !p0.tbid;
171
- }
172
+ tbid = aa64_va_parameter_tbi(tcr, mmu_idx);
173
+ tbii = tbid & ~aa64_va_parameter_tbid(tcr, mmu_idx);
174
175
flags = FIELD_DP32(flags, TBFLAG_A64, TBII, tbii);
176
flags = FIELD_DP32(flags, TBFLAG_A64, TBID, tbid);
177
--
360
--
178
2.20.1
361
2.34.1
179
180
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
These instructions shift left or right depending on the sign
3
Add an x-rme cpu property to enable FEAT_RME.
4
of the input, and 7 bits are significant to the shift. This
4
Add an x-l0gptsz property to set GPCCR_EL3.L0GPTSZ,
5
requires several masks and selects in addition to the actual
5
for testing various possible configurations.
6
shifts to form the complete answer.
7
6
8
That said, the operation is still a small improvement even for
7
We're not currently completely sure whether FEAT_RME will
9
two 64-bit elements -- 13 vector operations instead of 2 * 7
8
be OK to enable purely as a CPU-level property, or if it will
10
integer operations.
9
need board co-operation, so we're making these experimental
10
x- properties, so that the people developing the system
11
level software for RME can try to start using this and let
12
us know how it goes. The command line syntax for enabling
13
this will change in future, without backwards-compatibility.
11
14
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20200216214232.4230-2-richard.henderson@linaro.org
16
Message-id: 20230620124418.805717-21-richard.henderson@linaro.org
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
19
---
17
target/arm/helper.h | 11 +-
20
target/arm/tcg/cpu64.c | 53 ++++++++++++++++++++++++++++++++++++++++++
18
target/arm/translate.h | 6 +
21
1 file changed, 53 insertions(+)
19
target/arm/neon_helper.c | 33 ----
20
target/arm/translate-a64.c | 18 +--
21
target/arm/translate.c | 299 +++++++++++++++++++++++++++++++++++--
22
target/arm/vec_helper.c | 88 +++++++++++
23
6 files changed, 389 insertions(+), 66 deletions(-)
24
22
25
diff --git a/target/arm/helper.h b/target/arm/helper.h
23
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
26
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/helper.h
25
--- a/target/arm/tcg/cpu64.c
28
+++ b/target/arm/helper.h
26
+++ b/target/arm/tcg/cpu64.c
29
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(neon_abd_s16, i32, i32, i32)
27
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
30
DEF_HELPER_2(neon_abd_u32, i32, i32, i32)
28
cpu->sve_max_vq = max_vq;
31
DEF_HELPER_2(neon_abd_s32, i32, i32, i32)
29
}
32
30
33
-DEF_HELPER_2(neon_shl_u8, i32, i32, i32)
31
+static bool cpu_arm_get_rme(Object *obj, Error **errp)
34
-DEF_HELPER_2(neon_shl_s8, i32, i32, i32)
35
DEF_HELPER_2(neon_shl_u16, i32, i32, i32)
36
DEF_HELPER_2(neon_shl_s16, i32, i32, i32)
37
-DEF_HELPER_2(neon_shl_u32, i32, i32, i32)
38
-DEF_HELPER_2(neon_shl_s32, i32, i32, i32)
39
-DEF_HELPER_2(neon_shl_u64, i64, i64, i64)
40
-DEF_HELPER_2(neon_shl_s64, i64, i64, i64)
41
DEF_HELPER_2(neon_rshl_u8, i32, i32, i32)
42
DEF_HELPER_2(neon_rshl_s8, i32, i32, i32)
43
DEF_HELPER_2(neon_rshl_u16, i32, i32, i32)
44
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(frint64_s, TCG_CALL_NO_RWG, f32, f32, ptr)
45
DEF_HELPER_FLAGS_2(frint32_d, TCG_CALL_NO_RWG, f64, f64, ptr)
46
DEF_HELPER_FLAGS_2(frint64_d, TCG_CALL_NO_RWG, f64, f64, ptr)
47
48
+DEF_HELPER_FLAGS_4(gvec_sshl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
49
+DEF_HELPER_FLAGS_4(gvec_sshl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
50
+DEF_HELPER_FLAGS_4(gvec_ushl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
51
+DEF_HELPER_FLAGS_4(gvec_ushl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
52
+
53
#ifdef TARGET_AARCH64
54
#include "helper-a64.h"
55
#include "helper-sve.h"
56
diff --git a/target/arm/translate.h b/target/arm/translate.h
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/translate.h
59
+++ b/target/arm/translate.h
60
@@ -XXX,XX +XXX,XX @@ uint64_t vfp_expand_imm(int size, uint8_t imm8);
61
extern const GVecGen3 mla_op[4];
62
extern const GVecGen3 mls_op[4];
63
extern const GVecGen3 cmtst_op[4];
64
+extern const GVecGen3 sshl_op[4];
65
+extern const GVecGen3 ushl_op[4];
66
extern const GVecGen2i ssra_op[4];
67
extern const GVecGen2i usra_op[4];
68
extern const GVecGen2i sri_op[4];
69
@@ -XXX,XX +XXX,XX @@ extern const GVecGen4 sqadd_op[4];
70
extern const GVecGen4 uqsub_op[4];
71
extern const GVecGen4 sqsub_op[4];
72
void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
73
+void gen_ushl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
74
+void gen_sshl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
75
+void gen_ushl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
76
+void gen_sshl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
77
78
/*
79
* Forward to the isar_feature_* tests given a DisasContext pointer.
80
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/neon_helper.c
83
+++ b/target/arm/neon_helper.c
84
@@ -XXX,XX +XXX,XX @@ NEON_VOP(abd_u32, neon_u32, 1)
85
} else { \
86
dest = src1 << tmp; \
87
}} while (0)
88
-NEON_VOP(shl_u8, neon_u8, 4)
89
NEON_VOP(shl_u16, neon_u16, 2)
90
-NEON_VOP(shl_u32, neon_u32, 1)
91
#undef NEON_FN
92
93
-uint64_t HELPER(neon_shl_u64)(uint64_t val, uint64_t shiftop)
94
-{
95
- int8_t shift = (int8_t)shiftop;
96
- if (shift >= 64 || shift <= -64) {
97
- val = 0;
98
- } else if (shift < 0) {
99
- val >>= -shift;
100
- } else {
101
- val <<= shift;
102
- }
103
- return val;
104
-}
105
-
106
#define NEON_FN(dest, src1, src2) do { \
107
int8_t tmp; \
108
tmp = (int8_t)src2; \
109
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_shl_u64)(uint64_t val, uint64_t shiftop)
110
} else { \
111
dest = src1 << tmp; \
112
}} while (0)
113
-NEON_VOP(shl_s8, neon_s8, 4)
114
NEON_VOP(shl_s16, neon_s16, 2)
115
-NEON_VOP(shl_s32, neon_s32, 1)
116
#undef NEON_FN
117
118
-uint64_t HELPER(neon_shl_s64)(uint64_t valop, uint64_t shiftop)
119
-{
120
- int8_t shift = (int8_t)shiftop;
121
- int64_t val = valop;
122
- if (shift >= 64) {
123
- val = 0;
124
- } else if (shift <= -64) {
125
- val >>= 63;
126
- } else if (shift < 0) {
127
- val >>= -shift;
128
- } else {
129
- val <<= shift;
130
- }
131
- return val;
132
-}
133
-
134
#define NEON_FN(dest, src1, src2) do { \
135
int8_t tmp; \
136
tmp = (int8_t)src2; \
137
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
138
index XXXXXXX..XXXXXXX 100644
139
--- a/target/arm/translate-a64.c
140
+++ b/target/arm/translate-a64.c
141
@@ -XXX,XX +XXX,XX @@ static void handle_3same_64(DisasContext *s, int opcode, bool u,
142
break;
143
case 0x8: /* SSHL, USHL */
144
if (u) {
145
- gen_helper_neon_shl_u64(tcg_rd, tcg_rn, tcg_rm);
146
+ gen_ushl_i64(tcg_rd, tcg_rn, tcg_rm);
147
} else {
148
- gen_helper_neon_shl_s64(tcg_rd, tcg_rn, tcg_rm);
149
+ gen_sshl_i64(tcg_rd, tcg_rn, tcg_rm);
150
}
151
break;
152
case 0x9: /* SQSHL, UQSHL */
153
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
154
is_q ? 16 : 8, vec_full_reg_size(s),
155
(u ? uqsub_op : sqsub_op) + size);
156
return;
157
+ case 0x08: /* SSHL, USHL */
158
+ gen_gvec_op3(s, is_q, rd, rn, rm,
159
+ u ? &ushl_op[size] : &sshl_op[size]);
160
+ return;
161
case 0x0c: /* SMAX, UMAX */
162
if (u) {
163
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_umax, size);
164
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
165
genfn = fns[size][u];
166
break;
167
}
168
- case 0x8: /* SSHL, USHL */
169
- {
170
- static NeonGenTwoOpFn * const fns[3][2] = {
171
- { gen_helper_neon_shl_s8, gen_helper_neon_shl_u8 },
172
- { gen_helper_neon_shl_s16, gen_helper_neon_shl_u16 },
173
- { gen_helper_neon_shl_s32, gen_helper_neon_shl_u32 },
174
- };
175
- genfn = fns[size][u];
176
- break;
177
- }
178
case 0x9: /* SQSHL, UQSHL */
179
{
180
static NeonGenTwoOpEnvFn * const fns[3][2] = {
181
diff --git a/target/arm/translate.c b/target/arm/translate.c
182
index XXXXXXX..XXXXXXX 100644
183
--- a/target/arm/translate.c
184
+++ b/target/arm/translate.c
185
@@ -XXX,XX +XXX,XX @@ static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
186
if (u) {
187
switch (size) {
188
case 1: gen_helper_neon_shl_u16(var, var, shift); break;
189
- case 2: gen_helper_neon_shl_u32(var, var, shift); break;
190
+ case 2: gen_ushl_i32(var, var, shift); break;
191
default: abort();
192
}
193
} else {
194
switch (size) {
195
case 1: gen_helper_neon_shl_s16(var, var, shift); break;
196
- case 2: gen_helper_neon_shl_s32(var, var, shift); break;
197
+ case 2: gen_sshl_i32(var, var, shift); break;
198
default: abort();
199
}
200
}
201
@@ -XXX,XX +XXX,XX @@ const GVecGen3 cmtst_op[4] = {
202
.vece = MO_64 },
203
};
204
205
+void gen_ushl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
206
+{
32
+{
207
+ TCGv_i32 lval = tcg_temp_new_i32();
33
+ ARMCPU *cpu = ARM_CPU(obj);
208
+ TCGv_i32 rval = tcg_temp_new_i32();
34
+ return cpu_isar_feature(aa64_rme, cpu);
209
+ TCGv_i32 lsh = tcg_temp_new_i32();
210
+ TCGv_i32 rsh = tcg_temp_new_i32();
211
+ TCGv_i32 zero = tcg_const_i32(0);
212
+ TCGv_i32 max = tcg_const_i32(32);
213
+
214
+ /*
215
+ * Rely on the TCG guarantee that out of range shifts produce
216
+ * unspecified results, not undefined behaviour (i.e. no trap).
217
+ * Discard out-of-range results after the fact.
218
+ */
219
+ tcg_gen_ext8s_i32(lsh, shift);
220
+ tcg_gen_neg_i32(rsh, lsh);
221
+ tcg_gen_shl_i32(lval, src, lsh);
222
+ tcg_gen_shr_i32(rval, src, rsh);
223
+ tcg_gen_movcond_i32(TCG_COND_LTU, dst, lsh, max, lval, zero);
224
+ tcg_gen_movcond_i32(TCG_COND_LTU, dst, rsh, max, rval, dst);
225
+
226
+ tcg_temp_free_i32(lval);
227
+ tcg_temp_free_i32(rval);
228
+ tcg_temp_free_i32(lsh);
229
+ tcg_temp_free_i32(rsh);
230
+ tcg_temp_free_i32(zero);
231
+ tcg_temp_free_i32(max);
232
+}
35
+}
233
+
36
+
234
+void gen_ushl_i64(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 shift)
37
+static void cpu_arm_set_rme(Object *obj, bool value, Error **errp)
235
+{
38
+{
236
+ TCGv_i64 lval = tcg_temp_new_i64();
39
+ ARMCPU *cpu = ARM_CPU(obj);
237
+ TCGv_i64 rval = tcg_temp_new_i64();
40
+ uint64_t t;
238
+ TCGv_i64 lsh = tcg_temp_new_i64();
239
+ TCGv_i64 rsh = tcg_temp_new_i64();
240
+ TCGv_i64 zero = tcg_const_i64(0);
241
+ TCGv_i64 max = tcg_const_i64(64);
242
+
41
+
243
+ /*
42
+ t = cpu->isar.id_aa64pfr0;
244
+ * Rely on the TCG guarantee that out of range shifts produce
43
+ t = FIELD_DP64(t, ID_AA64PFR0, RME, value);
245
+ * unspecified results, not undefined behaviour (i.e. no trap).
44
+ cpu->isar.id_aa64pfr0 = t;
246
+ * Discard out-of-range results after the fact.
247
+ */
248
+ tcg_gen_ext8s_i64(lsh, shift);
249
+ tcg_gen_neg_i64(rsh, lsh);
250
+ tcg_gen_shl_i64(lval, src, lsh);
251
+ tcg_gen_shr_i64(rval, src, rsh);
252
+ tcg_gen_movcond_i64(TCG_COND_LTU, dst, lsh, max, lval, zero);
253
+ tcg_gen_movcond_i64(TCG_COND_LTU, dst, rsh, max, rval, dst);
254
+
255
+ tcg_temp_free_i64(lval);
256
+ tcg_temp_free_i64(rval);
257
+ tcg_temp_free_i64(lsh);
258
+ tcg_temp_free_i64(rsh);
259
+ tcg_temp_free_i64(zero);
260
+ tcg_temp_free_i64(max);
261
+}
45
+}
262
+
46
+
263
+static void gen_ushl_vec(unsigned vece, TCGv_vec dst,
47
+static void cpu_max_set_l0gptsz(Object *obj, Visitor *v, const char *name,
264
+ TCGv_vec src, TCGv_vec shift)
48
+ void *opaque, Error **errp)
265
+{
49
+{
266
+ TCGv_vec lval = tcg_temp_new_vec_matching(dst);
50
+ ARMCPU *cpu = ARM_CPU(obj);
267
+ TCGv_vec rval = tcg_temp_new_vec_matching(dst);
51
+ uint32_t value;
268
+ TCGv_vec lsh = tcg_temp_new_vec_matching(dst);
269
+ TCGv_vec rsh = tcg_temp_new_vec_matching(dst);
270
+ TCGv_vec msk, max;
271
+
52
+
272
+ tcg_gen_neg_vec(vece, rsh, shift);
53
+ if (!visit_type_uint32(v, name, &value, errp)) {
273
+ if (vece == MO_8) {
54
+ return;
274
+ tcg_gen_mov_vec(lsh, shift);
275
+ } else {
276
+ msk = tcg_temp_new_vec_matching(dst);
277
+ tcg_gen_dupi_vec(vece, msk, 0xff);
278
+ tcg_gen_and_vec(vece, lsh, shift, msk);
279
+ tcg_gen_and_vec(vece, rsh, rsh, msk);
280
+ tcg_temp_free_vec(msk);
281
+ }
55
+ }
282
+
56
+
283
+ /*
57
+ /* Encode the value for the GPCCR_EL3 field. */
284
+ * Rely on the TCG guarantee that out of range shifts produce
58
+ switch (value) {
285
+ * unspecified results, not undefined behaviour (i.e. no trap).
59
+ case 30:
286
+ * Discard out-of-range results after the fact.
60
+ case 34:
287
+ */
61
+ case 36:
288
+ tcg_gen_shlv_vec(vece, lval, src, lsh);
62
+ case 39:
289
+ tcg_gen_shrv_vec(vece, rval, src, rsh);
63
+ cpu->reset_l0gptsz = value - 30;
290
+
64
+ break;
291
+ max = tcg_temp_new_vec_matching(dst);
65
+ default:
292
+ tcg_gen_dupi_vec(vece, max, 8 << vece);
66
+ error_setg(errp, "invalid value for l0gptsz");
293
+
67
+ error_append_hint(errp, "valid values are 30, 34, 36, 39\n");
294
+ /*
68
+ break;
295
+ * The choice of LT (signed) and GEU (unsigned) are biased toward
296
+ * the instructions of the x86_64 host. For MO_8, the whole byte
297
+ * is significant so we must use an unsigned compare; otherwise we
298
+ * have already masked to a byte and so a signed compare works.
299
+ * Other tcg hosts have a full set of comparisons and do not care.
300
+ */
301
+ if (vece == MO_8) {
302
+ tcg_gen_cmp_vec(TCG_COND_GEU, vece, lsh, lsh, max);
303
+ tcg_gen_cmp_vec(TCG_COND_GEU, vece, rsh, rsh, max);
304
+ tcg_gen_andc_vec(vece, lval, lval, lsh);
305
+ tcg_gen_andc_vec(vece, rval, rval, rsh);
306
+ } else {
307
+ tcg_gen_cmp_vec(TCG_COND_LT, vece, lsh, lsh, max);
308
+ tcg_gen_cmp_vec(TCG_COND_LT, vece, rsh, rsh, max);
309
+ tcg_gen_and_vec(vece, lval, lval, lsh);
310
+ tcg_gen_and_vec(vece, rval, rval, rsh);
311
+ }
69
+ }
312
+ tcg_gen_or_vec(vece, dst, lval, rval);
313
+
314
+ tcg_temp_free_vec(max);
315
+ tcg_temp_free_vec(lval);
316
+ tcg_temp_free_vec(rval);
317
+ tcg_temp_free_vec(lsh);
318
+ tcg_temp_free_vec(rsh);
319
+}
70
+}
320
+
71
+
321
+static const TCGOpcode ushl_list[] = {
72
+static void cpu_max_get_l0gptsz(Object *obj, Visitor *v, const char *name,
322
+ INDEX_op_neg_vec, INDEX_op_shlv_vec,
73
+ void *opaque, Error **errp)
323
+ INDEX_op_shrv_vec, INDEX_op_cmp_vec, 0
74
+{
324
+};
75
+ ARMCPU *cpu = ARM_CPU(obj);
76
+ uint32_t value = cpu->reset_l0gptsz + 30;
325
+
77
+
326
+const GVecGen3 ushl_op[4] = {
78
+ visit_type_uint32(v, name, &value, errp);
327
+ { .fniv = gen_ushl_vec,
328
+ .fno = gen_helper_gvec_ushl_b,
329
+ .opt_opc = ushl_list,
330
+ .vece = MO_8 },
331
+ { .fniv = gen_ushl_vec,
332
+ .fno = gen_helper_gvec_ushl_h,
333
+ .opt_opc = ushl_list,
334
+ .vece = MO_16 },
335
+ { .fni4 = gen_ushl_i32,
336
+ .fniv = gen_ushl_vec,
337
+ .opt_opc = ushl_list,
338
+ .vece = MO_32 },
339
+ { .fni8 = gen_ushl_i64,
340
+ .fniv = gen_ushl_vec,
341
+ .opt_opc = ushl_list,
342
+ .vece = MO_64 },
343
+};
344
+
345
+void gen_sshl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
346
+{
347
+ TCGv_i32 lval = tcg_temp_new_i32();
348
+ TCGv_i32 rval = tcg_temp_new_i32();
349
+ TCGv_i32 lsh = tcg_temp_new_i32();
350
+ TCGv_i32 rsh = tcg_temp_new_i32();
351
+ TCGv_i32 zero = tcg_const_i32(0);
352
+ TCGv_i32 max = tcg_const_i32(31);
353
+
354
+ /*
355
+ * Rely on the TCG guarantee that out of range shifts produce
356
+ * unspecified results, not undefined behaviour (i.e. no trap).
357
+ * Discard out-of-range results after the fact.
358
+ */
359
+ tcg_gen_ext8s_i32(lsh, shift);
360
+ tcg_gen_neg_i32(rsh, lsh);
361
+ tcg_gen_shl_i32(lval, src, lsh);
362
+ tcg_gen_umin_i32(rsh, rsh, max);
363
+ tcg_gen_sar_i32(rval, src, rsh);
364
+ tcg_gen_movcond_i32(TCG_COND_LEU, lval, lsh, max, lval, zero);
365
+ tcg_gen_movcond_i32(TCG_COND_LT, dst, lsh, zero, rval, lval);
366
+
367
+ tcg_temp_free_i32(lval);
368
+ tcg_temp_free_i32(rval);
369
+ tcg_temp_free_i32(lsh);
370
+ tcg_temp_free_i32(rsh);
371
+ tcg_temp_free_i32(zero);
372
+ tcg_temp_free_i32(max);
373
+}
79
+}
374
+
80
+
375
+void gen_sshl_i64(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 shift)
81
static Property arm_cpu_lpa2_property =
376
+{
82
DEFINE_PROP_BOOL("lpa2", ARMCPU, prop_lpa2, true);
377
+ TCGv_i64 lval = tcg_temp_new_i64();
83
378
+ TCGv_i64 rval = tcg_temp_new_i64();
84
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
379
+ TCGv_i64 lsh = tcg_temp_new_i64();
85
aarch64_add_sme_properties(obj);
380
+ TCGv_i64 rsh = tcg_temp_new_i64();
86
object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
381
+ TCGv_i64 zero = tcg_const_i64(0);
87
cpu_max_set_sve_max_vq, NULL, NULL);
382
+ TCGv_i64 max = tcg_const_i64(63);
88
+ object_property_add_bool(obj, "x-rme", cpu_arm_get_rme, cpu_arm_set_rme);
383
+
89
+ object_property_add(obj, "x-l0gptsz", "uint32", cpu_max_get_l0gptsz,
384
+ /*
90
+ cpu_max_set_l0gptsz, NULL, NULL);
385
+ * Rely on the TCG guarantee that out of range shifts produce
91
qdev_property_add_static(DEVICE(obj), &arm_cpu_lpa2_property);
386
+ * unspecified results, not undefined behaviour (i.e. no trap).
387
+ * Discard out-of-range results after the fact.
388
+ */
389
+ tcg_gen_ext8s_i64(lsh, shift);
390
+ tcg_gen_neg_i64(rsh, lsh);
391
+ tcg_gen_shl_i64(lval, src, lsh);
392
+ tcg_gen_umin_i64(rsh, rsh, max);
393
+ tcg_gen_sar_i64(rval, src, rsh);
394
+ tcg_gen_movcond_i64(TCG_COND_LEU, lval, lsh, max, lval, zero);
395
+ tcg_gen_movcond_i64(TCG_COND_LT, dst, lsh, zero, rval, lval);
396
+
397
+ tcg_temp_free_i64(lval);
398
+ tcg_temp_free_i64(rval);
399
+ tcg_temp_free_i64(lsh);
400
+ tcg_temp_free_i64(rsh);
401
+ tcg_temp_free_i64(zero);
402
+ tcg_temp_free_i64(max);
403
+}
404
+
405
+static void gen_sshl_vec(unsigned vece, TCGv_vec dst,
406
+ TCGv_vec src, TCGv_vec shift)
407
+{
408
+ TCGv_vec lval = tcg_temp_new_vec_matching(dst);
409
+ TCGv_vec rval = tcg_temp_new_vec_matching(dst);
410
+ TCGv_vec lsh = tcg_temp_new_vec_matching(dst);
411
+ TCGv_vec rsh = tcg_temp_new_vec_matching(dst);
412
+ TCGv_vec tmp = tcg_temp_new_vec_matching(dst);
413
+
414
+ /*
415
+ * Rely on the TCG guarantee that out of range shifts produce
416
+ * unspecified results, not undefined behaviour (i.e. no trap).
417
+ * Discard out-of-range results after the fact.
418
+ */
419
+ tcg_gen_neg_vec(vece, rsh, shift);
420
+ if (vece == MO_8) {
421
+ tcg_gen_mov_vec(lsh, shift);
422
+ } else {
423
+ tcg_gen_dupi_vec(vece, tmp, 0xff);
424
+ tcg_gen_and_vec(vece, lsh, shift, tmp);
425
+ tcg_gen_and_vec(vece, rsh, rsh, tmp);
426
+ }
427
+
428
+ /* Bound rsh so out of bound right shift gets -1. */
429
+ tcg_gen_dupi_vec(vece, tmp, (8 << vece) - 1);
430
+ tcg_gen_umin_vec(vece, rsh, rsh, tmp);
431
+ tcg_gen_cmp_vec(TCG_COND_GT, vece, tmp, lsh, tmp);
432
+
433
+ tcg_gen_shlv_vec(vece, lval, src, lsh);
434
+ tcg_gen_sarv_vec(vece, rval, src, rsh);
435
+
436
+ /* Select in-bound left shift. */
437
+ tcg_gen_andc_vec(vece, lval, lval, tmp);
438
+
439
+ /* Select between left and right shift. */
440
+ if (vece == MO_8) {
441
+ tcg_gen_dupi_vec(vece, tmp, 0);
442
+ tcg_gen_cmpsel_vec(TCG_COND_LT, vece, dst, lsh, tmp, rval, lval);
443
+ } else {
444
+ tcg_gen_dupi_vec(vece, tmp, 0x80);
445
+ tcg_gen_cmpsel_vec(TCG_COND_LT, vece, dst, lsh, tmp, lval, rval);
446
+ }
447
+
448
+ tcg_temp_free_vec(lval);
449
+ tcg_temp_free_vec(rval);
450
+ tcg_temp_free_vec(lsh);
451
+ tcg_temp_free_vec(rsh);
452
+ tcg_temp_free_vec(tmp);
453
+}
454
+
455
+static const TCGOpcode sshl_list[] = {
456
+ INDEX_op_neg_vec, INDEX_op_umin_vec, INDEX_op_shlv_vec,
457
+ INDEX_op_sarv_vec, INDEX_op_cmp_vec, INDEX_op_cmpsel_vec, 0
458
+};
459
+
460
+const GVecGen3 sshl_op[4] = {
461
+ { .fniv = gen_sshl_vec,
462
+ .fno = gen_helper_gvec_sshl_b,
463
+ .opt_opc = sshl_list,
464
+ .vece = MO_8 },
465
+ { .fniv = gen_sshl_vec,
466
+ .fno = gen_helper_gvec_sshl_h,
467
+ .opt_opc = sshl_list,
468
+ .vece = MO_16 },
469
+ { .fni4 = gen_sshl_i32,
470
+ .fniv = gen_sshl_vec,
471
+ .opt_opc = sshl_list,
472
+ .vece = MO_32 },
473
+ { .fni8 = gen_sshl_i64,
474
+ .fniv = gen_sshl_vec,
475
+ .opt_opc = sshl_list,
476
+ .vece = MO_64 },
477
+};
478
+
479
static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
480
TCGv_vec a, TCGv_vec b)
481
{
482
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
483
vec_size, vec_size);
484
}
485
return 0;
486
+
487
+ case NEON_3R_VSHL:
488
+ /* Note the operation is vshl vd,vm,vn */
489
+ tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
490
+ u ? &ushl_op[size] : &sshl_op[size]);
491
+ return 0;
492
}
493
494
if (size == 3) {
495
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
496
neon_load_reg64(cpu_V0, rn + pass);
497
neon_load_reg64(cpu_V1, rm + pass);
498
switch (op) {
499
- case NEON_3R_VSHL:
500
- if (u) {
501
- gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
502
- } else {
503
- gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
504
- }
505
- break;
506
case NEON_3R_VQSHL:
507
if (u) {
508
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
509
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
510
}
511
pairwise = 0;
512
switch (op) {
513
- case NEON_3R_VSHL:
514
case NEON_3R_VQSHL:
515
case NEON_3R_VRSHL:
516
case NEON_3R_VQRSHL:
517
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
518
case NEON_3R_VHSUB:
519
GEN_NEON_INTEGER_OP(hsub);
520
break;
521
- case NEON_3R_VSHL:
522
- GEN_NEON_INTEGER_OP(shl);
523
- break;
524
case NEON_3R_VQSHL:
525
GEN_NEON_INTEGER_OP_ENV(qshl);
526
break;
527
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
528
}
529
} else {
530
if (input_unsigned) {
531
- gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
532
+ gen_ushl_i64(cpu_V0, in, tmp64);
533
} else {
534
- gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
535
+ gen_sshl_i64(cpu_V0, in, tmp64);
536
}
537
}
538
tmp = tcg_temp_new_i32();
539
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
540
index XXXXXXX..XXXXXXX 100644
541
--- a/target/arm/vec_helper.c
542
+++ b/target/arm/vec_helper.c
543
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fmlal_idx_a64)(void *vd, void *vn, void *vm,
544
do_fmlal_idx(vd, vn, vm, &env->vfp.fp_status, desc,
545
get_flush_inputs_to_zero(&env->vfp.fp_status_f16));
546
}
92
}
547
+
93
548
+void HELPER(gvec_sshl_b)(void *vd, void *vn, void *vm, uint32_t desc)
549
+{
550
+ intptr_t i, opr_sz = simd_oprsz(desc);
551
+ int8_t *d = vd, *n = vn, *m = vm;
552
+
553
+ for (i = 0; i < opr_sz; ++i) {
554
+ int8_t mm = m[i];
555
+ int8_t nn = n[i];
556
+ int8_t res = 0;
557
+ if (mm >= 0) {
558
+ if (mm < 8) {
559
+ res = nn << mm;
560
+ }
561
+ } else {
562
+ res = nn >> (mm > -8 ? -mm : 7);
563
+ }
564
+ d[i] = res;
565
+ }
566
+ clear_tail(d, opr_sz, simd_maxsz(desc));
567
+}
568
+
569
+void HELPER(gvec_sshl_h)(void *vd, void *vn, void *vm, uint32_t desc)
570
+{
571
+ intptr_t i, opr_sz = simd_oprsz(desc);
572
+ int16_t *d = vd, *n = vn, *m = vm;
573
+
574
+ for (i = 0; i < opr_sz / 2; ++i) {
575
+ int8_t mm = m[i]; /* only 8 bits of shift are significant */
576
+ int16_t nn = n[i];
577
+ int16_t res = 0;
578
+ if (mm >= 0) {
579
+ if (mm < 16) {
580
+ res = nn << mm;
581
+ }
582
+ } else {
583
+ res = nn >> (mm > -16 ? -mm : 15);
584
+ }
585
+ d[i] = res;
586
+ }
587
+ clear_tail(d, opr_sz, simd_maxsz(desc));
588
+}
589
+
590
+void HELPER(gvec_ushl_b)(void *vd, void *vn, void *vm, uint32_t desc)
591
+{
592
+ intptr_t i, opr_sz = simd_oprsz(desc);
593
+ uint8_t *d = vd, *n = vn, *m = vm;
594
+
595
+ for (i = 0; i < opr_sz; ++i) {
596
+ int8_t mm = m[i];
597
+ uint8_t nn = n[i];
598
+ uint8_t res = 0;
599
+ if (mm >= 0) {
600
+ if (mm < 8) {
601
+ res = nn << mm;
602
+ }
603
+ } else {
604
+ if (mm > -8) {
605
+ res = nn >> -mm;
606
+ }
607
+ }
608
+ d[i] = res;
609
+ }
610
+ clear_tail(d, opr_sz, simd_maxsz(desc));
611
+}
612
+
613
+void HELPER(gvec_ushl_h)(void *vd, void *vn, void *vm, uint32_t desc)
614
+{
615
+ intptr_t i, opr_sz = simd_oprsz(desc);
616
+ uint16_t *d = vd, *n = vn, *m = vm;
617
+
618
+ for (i = 0; i < opr_sz / 2; ++i) {
619
+ int8_t mm = m[i]; /* only 8 bits of shift are significant */
620
+ uint16_t nn = n[i];
621
+ uint16_t res = 0;
622
+ if (mm >= 0) {
623
+ if (mm < 16) {
624
+ res = nn << mm;
625
+ }
626
+ } else {
627
+ if (mm > -16) {
628
+ res = nn >> -mm;
629
+ }
630
+ }
631
+ d[i] = res;
632
+ }
633
+ clear_tail(d, opr_sz, simd_maxsz(desc));
634
+}
635
--
94
--
636
2.20.1
95
2.34.1
637
638
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 gvec form will be needed for implementing SVE2.
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
5
Extend the implementation to operate on uint64_t instead of uint32_t.
6
Use a counted inner loop instead of terminating when op1 goes to zero,
7
looking toward the required implementation for ARMv8.4-DIT.
8
9
Tested-by: Alex Bennée <alex.bennee@linaro.org>
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20230622143046.1578160-1-richard.henderson@linaro.org
12
Message-id: 20200216214232.4230-3-richard.henderson@linaro.org
6
[PMM: fixed typo; note experimental status in emulation.rst too]
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
8
---
15
target/arm/helper.h | 3 ++-
9
docs/system/arm/cpu-features.rst | 23 +++++++++++++++++++++++
16
target/arm/neon_helper.c | 22 ----------------------
10
docs/system/arm/emulation.rst | 1 +
17
target/arm/translate-a64.c | 10 +++-------
11
2 files changed, 24 insertions(+)
18
target/arm/translate.c | 11 ++++-------
19
target/arm/vec_helper.c | 30 ++++++++++++++++++++++++++++++
20
5 files changed, 39 insertions(+), 37 deletions(-)
21
12
22
diff --git a/target/arm/helper.h b/target/arm/helper.h
13
diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
23
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/helper.h
15
--- a/docs/system/arm/cpu-features.rst
25
+++ b/target/arm/helper.h
16
+++ b/docs/system/arm/cpu-features.rst
26
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(neon_sub_u8, i32, i32, i32)
17
@@ -XXX,XX +XXX,XX @@ As with ``sve-default-vector-length``, if the default length is larger
27
DEF_HELPER_2(neon_sub_u16, i32, i32, i32)
18
than the maximum vector length enabled, the actual vector length will
28
DEF_HELPER_2(neon_mul_u8, i32, i32, i32)
19
be reduced. If this property is set to ``-1`` then the default vector
29
DEF_HELPER_2(neon_mul_u16, i32, i32, i32)
20
length is set to the maximum possible length.
30
-DEF_HELPER_2(neon_mul_p8, i32, i32, i32)
31
DEF_HELPER_2(neon_mull_p8, i64, i32, i32)
32
33
DEF_HELPER_2(neon_tst_u8, i32, i32, i32)
34
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_sshl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
35
DEF_HELPER_FLAGS_4(gvec_ushl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
36
DEF_HELPER_FLAGS_4(gvec_ushl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
37
38
+DEF_HELPER_FLAGS_4(gvec_pmul_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
39
+
21
+
40
#ifdef TARGET_AARCH64
22
+RME CPU Properties
41
#include "helper-a64.h"
23
+==================
42
#include "helper-sve.h"
24
+
43
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
25
+The status of RME support with QEMU is experimental. At this time we
26
+only support RME within the CPU proper, not within the SMMU or GIC.
27
+The feature is enabled by the CPU property ``x-rme``, with the ``x-``
28
+prefix present as a reminder of the experimental status, and defaults off.
29
+
30
+The method for enabling RME will change in some future QEMU release
31
+without notice or backward compatibility.
32
+
33
+RME Level 0 GPT Size Property
34
+-----------------------------
35
+
36
+To aid firmware developers in testing different possible CPU
37
+configurations, ``x-l0gptsz=S`` may be used to specify the value
38
+to encode into ``GPCCR_EL3.L0GPTSZ``, a read-only field that
39
+specifies the size of the Level 0 Granule Protection Table.
40
+Legal values for ``S`` are 30, 34, 36, and 39; the default is 30.
41
+
42
+As with ``x-rme``, the ``x-l0gptsz`` property may be renamed or
43
+removed in some future QEMU release.
44
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
44
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/neon_helper.c
46
--- a/docs/system/arm/emulation.rst
46
+++ b/target/arm/neon_helper.c
47
+++ b/docs/system/arm/emulation.rst
47
@@ -XXX,XX +XXX,XX @@ NEON_VOP(mul_u16, neon_u16, 2)
48
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
48
49
- FEAT_RAS (Reliability, availability, and serviceability)
49
/* Polynomial multiplication is like integer multiplication except the
50
- FEAT_RASv1p1 (RAS Extension v1.1)
50
partial products are XORed, not added. */
51
- FEAT_RDM (Advanced SIMD rounding double multiply accumulate instructions)
51
-uint32_t HELPER(neon_mul_p8)(uint32_t op1, uint32_t op2)
52
+- FEAT_RME (Realm Management Extension) (NB: support status in QEMU is experimental)
52
-{
53
- FEAT_RNG (Random number generator)
53
- uint32_t mask;
54
- FEAT_S2FWB (Stage 2 forced Write-Back)
54
- uint32_t result;
55
- FEAT_SB (Speculation Barrier)
55
- result = 0;
56
- while (op1) {
57
- mask = 0;
58
- if (op1 & 1)
59
- mask |= 0xff;
60
- if (op1 & (1 << 8))
61
- mask |= (0xff << 8);
62
- if (op1 & (1 << 16))
63
- mask |= (0xff << 16);
64
- if (op1 & (1 << 24))
65
- mask |= (0xff << 24);
66
- result ^= op2 & mask;
67
- op1 = (op1 >> 1) & 0x7f7f7f7f;
68
- op2 = (op2 << 1) & 0xfefefefe;
69
- }
70
- return result;
71
-}
72
-
73
uint64_t HELPER(neon_mull_p8)(uint32_t op1, uint32_t op2)
74
{
75
uint64_t result = 0;
76
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/translate-a64.c
79
+++ b/target/arm/translate-a64.c
80
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
81
case 0x13: /* MUL, PMUL */
82
if (!u) { /* MUL */
83
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_mul, size);
84
- return;
85
+ } else { /* PMUL */
86
+ gen_gvec_op3_ool(s, is_q, rd, rn, rm, 0, gen_helper_gvec_pmul_b);
87
}
88
- break;
89
+ return;
90
case 0x12: /* MLA, MLS */
91
if (u) {
92
gen_gvec_op3(s, is_q, rd, rn, rm, &mls_op[size]);
93
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
94
genfn = fns[size][u];
95
break;
96
}
97
- case 0x13: /* MUL, PMUL */
98
- assert(u); /* PMUL */
99
- assert(size == 0);
100
- genfn = gen_helper_neon_mul_p8;
101
- break;
102
case 0x16: /* SQDMULH, SQRDMULH */
103
{
104
static NeonGenTwoOpEnvFn * const fns[2][2] = {
105
diff --git a/target/arm/translate.c b/target/arm/translate.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/arm/translate.c
108
+++ b/target/arm/translate.c
109
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
110
111
case NEON_3R_VMUL: /* VMUL */
112
if (u) {
113
- /* Polynomial case allows only P8 and is handled below. */
114
+ /* Polynomial case allows only P8. */
115
if (size != 0) {
116
return 1;
117
}
118
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
119
+ 0, gen_helper_gvec_pmul_b);
120
} else {
121
tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
122
vec_size, vec_size);
123
- return 0;
124
}
125
- break;
126
+ return 0;
127
128
case NEON_3R_VML: /* VMLA, VMLS */
129
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
130
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
131
tmp2 = neon_load_reg(rd, pass);
132
gen_neon_add(size, tmp, tmp2);
133
break;
134
- case NEON_3R_VMUL:
135
- /* VMUL.P8; other cases already eliminated. */
136
- gen_helper_neon_mul_p8(tmp, tmp, tmp2);
137
- break;
138
case NEON_3R_VPMAX:
139
GEN_NEON_INTEGER_OP(pmax);
140
break;
141
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
142
index XXXXXXX..XXXXXXX 100644
143
--- a/target/arm/vec_helper.c
144
+++ b/target/arm/vec_helper.c
145
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_ushl_h)(void *vd, void *vn, void *vm, uint32_t desc)
146
}
147
clear_tail(d, opr_sz, simd_maxsz(desc));
148
}
149
+
150
+/*
151
+ * 8x8->8 polynomial multiply.
152
+ *
153
+ * Polynomial multiplication is like integer multiplication except the
154
+ * partial products are XORed, not added.
155
+ *
156
+ * TODO: expose this as a generic vector operation, as it is a common
157
+ * crypto building block.
158
+ */
159
+void HELPER(gvec_pmul_b)(void *vd, void *vn, void *vm, uint32_t desc)
160
+{
161
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
162
+ uint64_t *d = vd, *n = vn, *m = vm;
163
+
164
+ for (i = 0; i < opr_sz / 8; ++i) {
165
+ uint64_t nn = n[i];
166
+ uint64_t mm = m[i];
167
+ uint64_t rr = 0;
168
+
169
+ for (j = 0; j < 8; ++j) {
170
+ uint64_t mask = (nn & 0x0101010101010101ull) * 0xff;
171
+ rr ^= mm & mask;
172
+ mm = (mm << 1) & 0xfefefefefefefefeull;
173
+ nn >>= 1;
174
+ }
175
+ d[i] = rr;
176
+ }
177
+ clear_tail(d, opr_sz, simd_maxsz(desc));
178
+}
179
--
56
--
180
2.20.1
57
2.34.1
181
58
182
59
diff view generated by jsdifflib
1
Cut-and-paste errors mean we're using FIELD_EX64() to extract fields from
1
We use __builtin_subcll() to do a 64-bit subtract with borrow-in and
2
some 32-bit ID register fields. Use FIELD_EX32() instead. (This makes
2
borrow-out when the host compiler supports it. Unfortunately some
3
no difference in behaviour, it's just more consistent.)
3
versions of Apple Clang have a bug in their implementation of this
4
intrinsic which means it returns the wrong value. The effect is that
5
a QEMU built with the affected compiler will hang when emulating x86
6
or m68k float80 division.
4
7
8
The upstream LLVM issue is:
9
https://github.com/llvm/llvm-project/issues/55253
10
11
The commit that introduced the bug apparently never made it into an
12
upstream LLVM release without the subsequent fix
13
https://github.com/llvm/llvm-project/commit/fffb6e6afdbaba563189c1f715058ed401fbc88d
14
but unfortunately it did make it into Apple Clang 14.0, as shipped
15
in Xcode 14.3 (14.2 is reported to be OK). The Apple bug number is
16
FB12210478.
17
18
Add ifdefs to avoid use of __builtin_subcll() on Apple Clang version
19
14 or greater. There is not currently a version of Apple Clang which
20
has the bug fix -- when one appears we should be able to add an upper
21
bound to the ifdef condition so we can start using the builtin again.
22
We make the lower bound a conservative "any Apple clang with major
23
version 14 or greater" because the consequences of incorrectly
24
disabling the builtin when it would work are pretty small and the
25
consequences of not disabling it when we should are pretty bad.
26
27
Many thanks to those users who both reported this bug and also
28
did a lot of work in identifying the root cause; in particular
29
to Daniel Bertalan and osy.
30
31
Cc: qemu-stable@nongnu.org
32
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1631
33
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1659
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
35
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200214175116.9164-21-peter.maydell@linaro.org
36
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
37
Tested-by: Daniel Bertalan <dani@danielbertalan.dev>
38
Tested-by: Tested-By: Solra Bizna <solra@bizna.name>
39
Message-id: 20230622130823.1631719-1-peter.maydell@linaro.org
8
---
40
---
9
target/arm/cpu.h | 18 +++++++++---------
41
include/qemu/compiler.h | 13 +++++++++++++
10
1 file changed, 9 insertions(+), 9 deletions(-)
42
include/qemu/host-utils.h | 2 +-
43
2 files changed, 14 insertions(+), 1 deletion(-)
11
44
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
45
diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h
13
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.h
47
--- a/include/qemu/compiler.h
15
+++ b/target/arm/cpu.h
48
+++ b/include/qemu/compiler.h
16
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
49
@@ -XXX,XX +XXX,XX @@
17
static inline bool isar_feature_aa32_fp_d32(const ARMISARegisters *id)
50
#define QEMU_DISABLE_CFI
51
#endif
52
53
+/*
54
+ * Apple clang version 14 has a bug in its __builtin_subcll(); define
55
+ * BUILTIN_SUBCLL_BROKEN for the offending versions so we can avoid it.
56
+ * When a version of Apple clang which has this bug fixed is released
57
+ * we can add an upper bound to this check.
58
+ * See https://gitlab.com/qemu-project/qemu/-/issues/1631
59
+ * and https://gitlab.com/qemu-project/qemu/-/issues/1659 for details.
60
+ * The bug never made it into any upstream LLVM releases, only Apple ones.
61
+ */
62
+#if defined(__apple_build_version__) && __clang_major__ >= 14
63
+#define BUILTIN_SUBCLL_BROKEN
64
+#endif
65
+
66
#endif /* COMPILER_H */
67
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
68
index XXXXXXX..XXXXXXX 100644
69
--- a/include/qemu/host-utils.h
70
+++ b/include/qemu/host-utils.h
71
@@ -XXX,XX +XXX,XX @@ static inline uint64_t uadd64_carry(uint64_t x, uint64_t y, bool *pcarry)
72
*/
73
static inline uint64_t usub64_borrow(uint64_t x, uint64_t y, bool *pborrow)
18
{
74
{
19
/* Return true if D16-D31 are implemented */
75
-#if __has_builtin(__builtin_subcll)
20
- return FIELD_EX64(id->mvfr0, MVFR0, SIMDREG) >= 2;
76
+#if __has_builtin(__builtin_subcll) && !defined(BUILTIN_SUBCLL_BROKEN)
21
+ return FIELD_EX32(id->mvfr0, MVFR0, SIMDREG) >= 2;
77
unsigned long long b = *pborrow;
22
}
78
x = __builtin_subcll(x, y, b, &b);
23
79
*pborrow = b & 1;
24
static inline bool isar_feature_aa32_fpshvec(const ARMISARegisters *id)
25
{
26
- return FIELD_EX64(id->mvfr0, MVFR0, FPSHVEC) > 0;
27
+ return FIELD_EX32(id->mvfr0, MVFR0, FPSHVEC) > 0;
28
}
29
30
static inline bool isar_feature_aa32_fpdp(const ARMISARegisters *id)
31
{
32
/* Return true if CPU supports double precision floating point */
33
- return FIELD_EX64(id->mvfr0, MVFR0, FPDP) > 0;
34
+ return FIELD_EX32(id->mvfr0, MVFR0, FPDP) > 0;
35
}
36
37
/*
38
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fpdp(const ARMISARegisters *id)
39
*/
40
static inline bool isar_feature_aa32_fp16_spconv(const ARMISARegisters *id)
41
{
42
- return FIELD_EX64(id->mvfr1, MVFR1, FPHP) > 0;
43
+ return FIELD_EX32(id->mvfr1, MVFR1, FPHP) > 0;
44
}
45
46
static inline bool isar_feature_aa32_fp16_dpconv(const ARMISARegisters *id)
47
{
48
- return FIELD_EX64(id->mvfr1, MVFR1, FPHP) > 1;
49
+ return FIELD_EX32(id->mvfr1, MVFR1, FPHP) > 1;
50
}
51
52
static inline bool isar_feature_aa32_vsel(const ARMISARegisters *id)
53
{
54
- return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 1;
55
+ return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 1;
56
}
57
58
static inline bool isar_feature_aa32_vcvt_dr(const ARMISARegisters *id)
59
{
60
- return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 2;
61
+ return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 2;
62
}
63
64
static inline bool isar_feature_aa32_vrint(const ARMISARegisters *id)
65
{
66
- return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 3;
67
+ return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 3;
68
}
69
70
static inline bool isar_feature_aa32_vminmaxnm(const ARMISARegisters *id)
71
{
72
- return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 4;
73
+ return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 4;
74
}
75
76
static inline bool isar_feature_aa32_pan(const ARMISARegisters *id)
77
--
80
--
78
2.20.1
81
2.34.1
79
82
80
83
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Many uses of ARM_FEATURE_VFP3 are testing for the number of simd
3
One cannot test for feature aa32_simd_r32 without first
4
registers implemented. Use the proper test vs MVFR0.SIMDReg.
4
testing if AArch32 mode is supported at all. This leads to
5
5
6
qemu-system-aarch64: ARM CPUs must have both VFP-D32 and Neon or neither
7
8
for Apple M1 cpus.
9
10
We already have a check for ARMv8-A never setting vfp-d32 true,
11
so restructure the code so that AArch64 avoids the test entirely.
12
13
Reported-by: Mads Ynddal <mads@ynddal.dk>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200214181547.21408-4-richard.henderson@linaro.org
15
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
[PMM: fix typo in commit message]
16
Tested-by: Mads Ynddal <m.ynddal@samsung.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
18
Reviewed-by: Cédric Le Goater <clg@kaod.org>
19
Reviewed-by: Mads Ynddal <m.ynddal@samsung.com>
20
Message-id: 20230619140216.402530-1-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
22
---
12
target/arm/cpu.c | 9 ++++-----
23
target/arm/cpu.c | 28 +++++++++++++++-------------
13
target/arm/helper.c | 13 ++++++-------
24
1 file changed, 15 insertions(+), 13 deletions(-)
14
target/arm/translate.c | 2 +-
15
3 files changed, 11 insertions(+), 13 deletions(-)
16
25
17
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
26
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
18
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.c
28
--- a/target/arm/cpu.c
20
+++ b/target/arm/cpu.c
29
+++ b/target/arm/cpu.c
21
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_dump_state(CPUState *cs, FILE *f, int flags)
30
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
22
31
* KVM does not currently allow us to lie to the guest about its
23
if (flags & CPU_DUMP_FPU) {
32
* ID/feature registers, so the guest always sees what the host has.
24
int numvfpregs = 0;
33
*/
25
- if (arm_feature(env, ARM_FEATURE_VFP)) {
34
- if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)
26
- numvfpregs += 16;
35
- ? cpu_isar_feature(aa64_fp_simd, cpu)
27
- }
36
- : cpu_isar_feature(aa32_vfp, cpu)) {
28
- if (arm_feature(env, ARM_FEATURE_VFP3)) {
37
- cpu->has_vfp = true;
29
- numvfpregs += 16;
38
- if (!kvm_enabled()) {
39
- qdev_property_add_static(DEVICE(obj), &arm_cpu_has_vfp_property);
40
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
41
+ if (cpu_isar_feature(aa64_fp_simd, cpu)) {
42
+ cpu->has_vfp = true;
43
+ cpu->has_vfp_d32 = true;
44
+ if (tcg_enabled() || qtest_enabled()) {
45
+ qdev_property_add_static(DEVICE(obj),
46
+ &arm_cpu_has_vfp_property);
47
+ }
48
}
49
- }
50
-
51
- if (cpu->has_vfp && cpu_isar_feature(aa32_simd_r32, cpu)) {
52
- cpu->has_vfp_d32 = true;
53
- if (!kvm_enabled()) {
54
+ } else if (cpu_isar_feature(aa32_vfp, cpu)) {
55
+ cpu->has_vfp = true;
30
+ if (cpu_isar_feature(aa32_simd_r32, cpu)) {
56
+ if (cpu_isar_feature(aa32_simd_r32, cpu)) {
31
+ numvfpregs = 32;
57
+ cpu->has_vfp_d32 = true;
32
+ } else if (arm_feature(env, ARM_FEATURE_VFP)) {
58
/*
33
+ numvfpregs = 16;
59
* The permitted values of the SIMDReg bits [3:0] on
34
}
60
* Armv8-A are either 0b0000 and 0b0010. On such CPUs,
35
for (i = 0; i < numvfpregs; i++) {
61
* make sure that has_vfp_d32 can not be set to false.
36
uint64_t v = *aa32_vfp_dreg(env, i);
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/helper.c
40
+++ b/target/arm/helper.c
41
@@ -XXX,XX +XXX,XX @@ static void switch_mode(CPUARMState *env, int mode);
42
43
static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
44
{
45
- int nregs;
46
+ ARMCPU *cpu = env_archcpu(env);
47
+ int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16;
48
49
/* VFP data registers are always little-endian. */
50
- nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
51
if (reg < nregs) {
52
stq_le_p(buf, *aa32_vfp_dreg(env, reg));
53
return 8;
54
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
55
56
static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
57
{
58
- int nregs;
59
+ ARMCPU *cpu = env_archcpu(env);
60
+ int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16;
61
62
- nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
63
if (reg < nregs) {
64
*aa32_vfp_dreg(env, reg) = ldq_le_p(buf);
65
return 8;
66
@@ -XXX,XX +XXX,XX @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
67
/* VFPv3 and upwards with NEON implement 32 double precision
68
* registers (D0-D31).
69
*/
62
*/
70
- if (!arm_feature(env, ARM_FEATURE_NEON) ||
63
- if (!(arm_feature(&cpu->env, ARM_FEATURE_V8) &&
71
- !arm_feature(env, ARM_FEATURE_VFP3)) {
64
- !arm_feature(&cpu->env, ARM_FEATURE_M))) {
72
+ if (!cpu_isar_feature(aa32_simd_r32, env_archcpu(env))) {
65
+ if ((tcg_enabled() || qtest_enabled())
73
/* D32DIS [30] is RAO/WI if D16-31 are not implemented. */
66
+ && !(arm_feature(&cpu->env, ARM_FEATURE_V8)
74
value |= (1 << 30);
67
+ && !arm_feature(&cpu->env, ARM_FEATURE_M))) {
68
qdev_property_add_static(DEVICE(obj),
69
&arm_cpu_has_vfp_d32_property);
75
}
70
}
76
@@ -XXX,XX +XXX,XX @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
77
} else if (arm_feature(env, ARM_FEATURE_NEON)) {
78
gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
79
51, "arm-neon.xml", 0);
80
- } else if (arm_feature(env, ARM_FEATURE_VFP3)) {
81
+ } else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
82
gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
83
35, "arm-vfp3.xml", 0);
84
} else if (arm_feature(env, ARM_FEATURE_VFP)) {
85
diff --git a/target/arm/translate.c b/target/arm/translate.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/target/arm/translate.c
88
+++ b/target/arm/translate.c
89
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
90
#define VFP_SREG(insn, bigbit, smallbit) \
91
((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
92
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
93
- if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
94
+ if (dc_isar_feature(aa32_simd_r32, s)) { \
95
reg = (((insn) >> (bigbit)) & 0x0f) \
96
| (((insn) >> ((smallbit) - 4)) & 0x10); \
97
} else { \
98
--
71
--
99
2.20.1
72
2.34.1
100
73
101
74
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
From: Shashi Mallela <shashi.mallela@linaro.org>
2
2
3
Instantiate EHCI and OHCI controllers on Allwinner A10. OHCI ports are
3
Create ITS as part of SBSA platform GIC initialization.
4
modeled as companions of the respective EHCI ports.
5
4
6
With this patch applied, USB controllers are discovered and instantiated
5
GIC ITS information is in DeviceTree so TF-A can pass it to EDK2.
7
when booting the cubieboard machine with a recent Linux kernel.
8
6
9
ehci-platform 1c14000.usb: EHCI Host Controller
7
Bumping platform version to 0.2 as this is important hardware change.
10
ehci-platform 1c14000.usb: new USB bus registered, assigned bus number 1
11
ehci-platform 1c14000.usb: irq 26, io mem 0x01c14000
12
ehci-platform 1c14000.usb: USB 2.0 started, EHCI 1.00
13
ehci-platform 1c1c000.usb: EHCI Host Controller
14
ehci-platform 1c1c000.usb: new USB bus registered, assigned bus number 2
15
ehci-platform 1c1c000.usb: irq 31, io mem 0x01c1c000
16
ehci-platform 1c1c000.usb: USB 2.0 started, EHCI 1.00
17
ohci-platform 1c14400.usb: Generic Platform OHCI controller
18
ohci-platform 1c14400.usb: new USB bus registered, assigned bus number 3
19
ohci-platform 1c14400.usb: irq 27, io mem 0x01c14400
20
ohci-platform 1c1c400.usb: Generic Platform OHCI controller
21
ohci-platform 1c1c400.usb: new USB bus registered, assigned bus number 4
22
ohci-platform 1c1c400.usb: irq 32, io mem 0x01c1c400
23
usb 2-1: new high-speed USB device number 2 using ehci-platform
24
usb-storage 2-1:1.0: USB Mass Storage device detected
25
scsi host1: usb-storage 2-1:1.0
26
usb 3-1: new full-speed USB device number 2 using ohci-platform
27
input: QEMU QEMU USB Mouse as /devices/platform/soc/1c14400.usb/usb3/3-1/3-1:1.0/0003:0627:0001.0001/input/input0
28
8
29
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
9
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
30
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
10
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
31
Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com>
11
Message-id: 20230619170913.517373-2-marcin.juszkiewicz@linaro.org
32
Message-id: 20200217204812.9857-4-linux@roeck-us.net
12
Co-authored-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
13
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
33
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
---
16
---
35
include/hw/arm/allwinner-a10.h | 6 +++++
17
docs/system/arm/sbsa.rst | 14 ++++++++++++++
36
hw/arm/allwinner-a10.c | 43 ++++++++++++++++++++++++++++++++++
18
hw/arm/sbsa-ref.c | 33 ++++++++++++++++++++++++++++++---
37
2 files changed, 49 insertions(+)
19
2 files changed, 44 insertions(+), 3 deletions(-)
38
20
39
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
21
diff --git a/docs/system/arm/sbsa.rst b/docs/system/arm/sbsa.rst
40
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
41
--- a/include/hw/arm/allwinner-a10.h
23
--- a/docs/system/arm/sbsa.rst
42
+++ b/include/hw/arm/allwinner-a10.h
24
+++ b/docs/system/arm/sbsa.rst
43
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ to be a complete compliant DT. It currently reports:
44
#include "hw/intc/allwinner-a10-pic.h"
26
- platform version
45
#include "hw/net/allwinner_emac.h"
27
- GIC addresses
46
#include "hw/ide/ahci.h"
28
47
+#include "hw/usb/hcd-ohci.h"
29
+Platform version
48
+#include "hw/usb/hcd-ehci.h"
30
+''''''''''''''''
49
50
#include "target/arm/cpu.h"
51
52
53
#define AW_A10_SDRAM_BASE 0x40000000
54
55
+#define AW_A10_NUM_USB 2
56
+
31
+
57
#define TYPE_AW_A10 "allwinner-a10"
32
The platform version is only for informing platform firmware about
58
#define AW_A10(obj) OBJECT_CHECK(AwA10State, (obj), TYPE_AW_A10)
33
what kind of ``sbsa-ref`` board it is running on. It is neither
59
34
a QEMU versioned machine type nor a reflection of the level of the
60
@@ -XXX,XX +XXX,XX @@ typedef struct AwA10State {
35
@@ -XXX,XX +XXX,XX @@ SBSA/SystemReady SR support provided.
61
AwEmacState emac;
36
The ``machine-version-major`` value is updated when changes breaking
62
AllwinnerAHCIState sata;
37
fw compatibility are introduced. The ``machine-version-minor`` value
63
MemoryRegion sram_a;
38
is updated when features are added that don't break fw compatibility.
64
+ EHCISysBusState ehci[AW_A10_NUM_USB];
39
+
65
+ OHCISysBusState ohci[AW_A10_NUM_USB];
40
+Platform version changes:
66
} AwA10State;
41
+
67
42
+0.0
68
#endif
43
+ Devicetree holds information about CPUs, memory and platform version.
69
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
44
+
45
+0.1
46
+ GIC information is present in devicetree.
47
+
48
+0.2
49
+ GIC ITS information is present in devicetree.
50
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
70
index XXXXXXX..XXXXXXX 100644
51
index XXXXXXX..XXXXXXX 100644
71
--- a/hw/arm/allwinner-a10.c
52
--- a/hw/arm/sbsa-ref.c
72
+++ b/hw/arm/allwinner-a10.c
53
+++ b/hw/arm/sbsa-ref.c
73
@@ -XXX,XX +XXX,XX @@
54
@@ -XXX,XX +XXX,XX @@ enum {
74
#include "hw/arm/allwinner-a10.h"
55
SBSA_CPUPERIPHS,
75
#include "hw/misc/unimp.h"
56
SBSA_GIC_DIST,
76
#include "sysemu/sysemu.h"
57
SBSA_GIC_REDIST,
77
+#include "hw/boards.h"
58
+ SBSA_GIC_ITS,
78
+#include "hw/usb/hcd-ohci.h"
59
SBSA_SECURE_EC,
79
60
SBSA_GWDT_WS0,
80
#define AW_A10_PIC_REG_BASE 0x01c20400
61
SBSA_GWDT_REFRESH,
81
#define AW_A10_PIT_REG_BASE 0x01c20c00
62
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry sbsa_ref_memmap[] = {
82
#define AW_A10_UART0_REG_BASE 0x01c28000
63
[SBSA_CPUPERIPHS] = { 0x40000000, 0x00040000 },
83
#define AW_A10_EMAC_BASE 0x01c0b000
64
[SBSA_GIC_DIST] = { 0x40060000, 0x00010000 },
84
+#define AW_A10_EHCI_BASE 0x01c14000
65
[SBSA_GIC_REDIST] = { 0x40080000, 0x04000000 },
85
+#define AW_A10_OHCI_BASE 0x01c14400
66
+ [SBSA_GIC_ITS] = { 0x44081000, 0x00020000 },
86
#define AW_A10_SATA_BASE 0x01c18000
67
[SBSA_SECURE_EC] = { 0x50000000, 0x00001000 },
87
68
[SBSA_GWDT_REFRESH] = { 0x50010000, 0x00001000 },
88
static void aw_a10_init(Object *obj)
69
[SBSA_GWDT_CONTROL] = { 0x50011000, 0x00001000 },
89
@@ -XXX,XX +XXX,XX @@ static void aw_a10_init(Object *obj)
70
@@ -XXX,XX +XXX,XX @@ static void sbsa_fdt_add_gic_node(SBSAMachineState *sms)
90
71
2, sbsa_ref_memmap[SBSA_GIC_REDIST].base,
91
sysbus_init_child_obj(obj, "sata", &s->sata, sizeof(s->sata),
72
2, sbsa_ref_memmap[SBSA_GIC_REDIST].size);
92
TYPE_ALLWINNER_AHCI);
73
74
+ nodename = g_strdup_printf("/intc/its");
75
+ qemu_fdt_add_subnode(sms->fdt, nodename);
76
+ qemu_fdt_setprop_sized_cells(sms->fdt, nodename, "reg",
77
+ 2, sbsa_ref_memmap[SBSA_GIC_ITS].base,
78
+ 2, sbsa_ref_memmap[SBSA_GIC_ITS].size);
93
+
79
+
94
+ if (machine_usb(current_machine)) {
80
g_free(nodename);
95
+ int i;
81
}
96
+
82
+
97
+ for (i = 0; i < AW_A10_NUM_USB; i++) {
83
/*
98
+ sysbus_init_child_obj(obj, "ehci[*]", OBJECT(&s->ehci[i]),
84
* Firmware on this machine only uses ACPI table to load OS, these limited
99
+ sizeof(s->ehci[i]), TYPE_PLATFORM_EHCI);
85
* device tree nodes are just to let firmware know the info which varies from
100
+ sysbus_init_child_obj(obj, "ohci[*]", OBJECT(&s->ohci[i]),
86
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SBSAMachineState *sms)
101
+ sizeof(s->ohci[i]), TYPE_SYSBUS_OHCI);
87
* fw compatibility.
102
+ }
88
*/
103
+ }
89
qemu_fdt_setprop_cell(fdt, "/", "machine-version-major", 0);
90
- qemu_fdt_setprop_cell(fdt, "/", "machine-version-minor", 1);
91
+ qemu_fdt_setprop_cell(fdt, "/", "machine-version-minor", 2);
92
93
if (ms->numa_state->have_numa_distance) {
94
int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
95
@@ -XXX,XX +XXX,XX @@ static void create_secure_ram(SBSAMachineState *sms,
96
memory_region_add_subregion(secure_sysmem, base, secram);
104
}
97
}
105
98
106
static void aw_a10_realize(DeviceState *dev, Error **errp)
99
-static void create_gic(SBSAMachineState *sms)
107
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
100
+static void create_its(SBSAMachineState *sms)
108
serial_mm_init(get_system_memory(), AW_A10_UART0_REG_BASE, 2,
101
+{
109
qdev_get_gpio_in(dev, 1),
102
+ const char *itsclass = its_class_name();
110
115200, serial_hd(0), DEVICE_NATIVE_ENDIAN);
103
+ DeviceState *dev;
111
+
104
+
112
+ if (machine_usb(current_machine)) {
105
+ dev = qdev_new(itsclass);
113
+ int i;
114
+
106
+
115
+ for (i = 0; i < AW_A10_NUM_USB; i++) {
107
+ object_property_set_link(OBJECT(dev), "parent-gicv3", OBJECT(sms->gic),
116
+ char bus[16];
108
+ &error_abort);
109
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
110
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, sbsa_ref_memmap[SBSA_GIC_ITS].base);
111
+}
117
+
112
+
118
+ sprintf(bus, "usb-bus.%d", i);
113
+static void create_gic(SBSAMachineState *sms, MemoryRegion *mem)
114
{
115
unsigned int smp_cpus = MACHINE(sms)->smp.cpus;
116
SysBusDevice *gicbusdev;
117
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms)
118
qdev_prop_set_uint32(sms->gic, "len-redist-region-count", 1);
119
qdev_prop_set_uint32(sms->gic, "redist-region-count[0]", redist0_count);
120
121
+ object_property_set_link(OBJECT(sms->gic), "sysmem",
122
+ OBJECT(mem), &error_fatal);
123
+ qdev_prop_set_bit(sms->gic, "has-lpi", true);
119
+
124
+
120
+ object_property_set_bool(OBJECT(&s->ehci[i]), true,
125
gicbusdev = SYS_BUS_DEVICE(sms->gic);
121
+ "companion-enable", &error_fatal);
126
sysbus_realize_and_unref(gicbusdev, &error_fatal);
122
+ object_property_set_bool(OBJECT(&s->ehci[i]), true, "realized",
127
sysbus_mmio_map(gicbusdev, 0, sbsa_ref_memmap[SBSA_GIC_DIST].base);
123
+ &error_fatal);
128
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms)
124
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci[i]), 0,
129
sysbus_connect_irq(gicbusdev, i + 3 * smp_cpus,
125
+ AW_A10_EHCI_BASE + i * 0x8000);
130
qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
126
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0,
131
}
127
+ qdev_get_gpio_in(dev, 39 + i));
132
+ create_its(sms);
128
+
129
+ object_property_set_str(OBJECT(&s->ohci[i]), bus, "masterbus",
130
+ &error_fatal);
131
+ object_property_set_bool(OBJECT(&s->ohci[i]), true, "realized",
132
+ &error_fatal);
133
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ohci[i]), 0,
134
+ AW_A10_OHCI_BASE + i * 0x8000);
135
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->ohci[i]), 0,
136
+ qdev_get_gpio_in(dev, 64 + i));
137
+ }
138
+ }
139
}
133
}
140
134
141
static void aw_a10_class_init(ObjectClass *oc, void *data)
135
static void create_uart(const SBSAMachineState *sms, int uart,
136
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
137
138
create_secure_ram(sms, secure_sysmem);
139
140
- create_gic(sms);
141
+ create_gic(sms, sysmem);
142
143
create_uart(sms, SBSA_UART, sysmem, serial_hd(0));
144
create_uart(sms, SBSA_SECURE_UART, secure_sysmem, serial_hd(1));
142
--
145
--
143
2.20.1
146
2.34.1
144
145
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 psuedocode in aarch64/functions/pac/auth/Auth and
3
Brown bag time: store instead of load results in uninitialized temp.
4
aarch64/functions/pac/strip/Strip always uses bit 55 for
5
extfield and do not consider if the current regime has 2 ranges.
6
4
7
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
5
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1704
7
Reported-by: Mark Rutland <mark.rutland@arm.com>
8
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20230620134659.817559-1-richard.henderson@linaro.org
11
Fixes: e6dd5e782be ("target/arm: Use tcg_gen_qemu_{ld, st}_i128 in gen_sve_{ld, st}r")
12
Tested-by: Alex Bennée <alex.bennee@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20200216194343.21331-2-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
16
---
13
target/arm/pauth_helper.c | 3 ++-
17
target/arm/tcg/translate-sve.c | 2 +-
14
1 file changed, 2 insertions(+), 1 deletion(-)
18
1 file changed, 1 insertion(+), 1 deletion(-)
15
19
16
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
20
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/pauth_helper.c
22
--- a/target/arm/tcg/translate-sve.c
19
+++ b/target/arm/pauth_helper.c
23
+++ b/target/arm/tcg/translate-sve.c
20
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
24
@@ -XXX,XX +XXX,XX @@ void gen_sve_str(DisasContext *s, TCGv_ptr base, int vofs,
21
25
/* Predicate register stores can be any multiple of 2. */
22
static uint64_t pauth_original_ptr(uint64_t ptr, ARMVAParameters param)
26
if (len_remain >= 8) {
23
{
27
t0 = tcg_temp_new_i64();
24
- uint64_t extfield = -param.select;
28
- tcg_gen_st_i64(t0, base, vofs + len_align);
25
+ /* Note that bit 55 is used whether or not the regime has 2 ranges. */
29
+ tcg_gen_ld_i64(t0, base, vofs + len_align);
26
+ uint64_t extfield = sextract64(ptr, 55, 1);
30
tcg_gen_qemu_st_i64(t0, clean_addr, midx, MO_LEUQ | MO_ATOM_NONE);
27
int bot_pac_bit = 64 - param.tsz;
31
len_remain -= 8;
28
int top_pac_bit = 64 - 8 * param.tbi;
32
len_align += 8;
29
30
--
33
--
31
2.20.1
34
2.34.1
32
35
33
36
diff view generated by jsdifflib
Deleted patch
1
Enforce a convention that an isar_feature function that tests a
2
32-bit ID register always has _aa32_ in its name, and one that
3
tests a 64-bit ID register always has _aa64_ in its name.
4
We already follow this except for three cases: thumb_div,
5
arm_div and jazelle, which all need _aa32_ adding.
6
1
7
(As noted in the comment, isar_feature_aa32_fp16_arith()
8
is an exception in that it currently tests ID_AA64PFR0_EL1,
9
but will switch to MVFR1 once we've properly implemented
10
FP16 for AArch32.)
11
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Message-id: 20200214175116.9164-2-peter.maydell@linaro.org
16
---
17
target/arm/cpu.h | 13 ++++++++++---
18
target/arm/internals.h | 2 +-
19
linux-user/elfload.c | 4 ++--
20
target/arm/cpu.c | 6 ++++--
21
target/arm/helper.c | 2 +-
22
target/arm/translate.c | 6 +++---
23
6 files changed, 21 insertions(+), 12 deletions(-)
24
25
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/cpu.h
28
+++ b/target/arm/cpu.h
29
@@ -XXX,XX +XXX,XX @@ static inline uint64_t *aa64_vfp_qreg(CPUARMState *env, unsigned regno)
30
/* Shared between translate-sve.c and sve_helper.c. */
31
extern const uint64_t pred_esz_masks[4];
32
33
+/*
34
+ * Naming convention for isar_feature functions:
35
+ * Functions which test 32-bit ID registers should have _aa32_ in
36
+ * their name. Functions which test 64-bit ID registers should have
37
+ * _aa64_ in their name.
38
+ */
39
+
40
/*
41
* 32-bit feature tests via id registers.
42
*/
43
-static inline bool isar_feature_thumb_div(const ARMISARegisters *id)
44
+static inline bool isar_feature_aa32_thumb_div(const ARMISARegisters *id)
45
{
46
return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) != 0;
47
}
48
49
-static inline bool isar_feature_arm_div(const ARMISARegisters *id)
50
+static inline bool isar_feature_aa32_arm_div(const ARMISARegisters *id)
51
{
52
return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) > 1;
53
}
54
55
-static inline bool isar_feature_jazelle(const ARMISARegisters *id)
56
+static inline bool isar_feature_aa32_jazelle(const ARMISARegisters *id)
57
{
58
return FIELD_EX32(id->id_isar1, ID_ISAR1, JAZELLE) != 0;
59
}
60
diff --git a/target/arm/internals.h b/target/arm/internals.h
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/internals.h
63
+++ b/target/arm/internals.h
64
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features,
65
if ((features >> ARM_FEATURE_THUMB2) & 1) {
66
valid |= CPSR_IT;
67
}
68
- if (isar_feature_jazelle(id)) {
69
+ if (isar_feature_aa32_jazelle(id)) {
70
valid |= CPSR_J;
71
}
72
if (isar_feature_aa32_pan(id)) {
73
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/linux-user/elfload.c
76
+++ b/linux-user/elfload.c
77
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
78
GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPv3);
79
GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
80
GET_FEATURE(ARM_FEATURE_VFP4, ARM_HWCAP_ARM_VFPv4);
81
- GET_FEATURE_ID(arm_div, ARM_HWCAP_ARM_IDIVA);
82
- GET_FEATURE_ID(thumb_div, ARM_HWCAP_ARM_IDIVT);
83
+ GET_FEATURE_ID(aa32_arm_div, ARM_HWCAP_ARM_IDIVA);
84
+ GET_FEATURE_ID(aa32_thumb_div, ARM_HWCAP_ARM_IDIVT);
85
/* All QEMU's VFPv3 CPUs have 32 registers, see VFP_DREG in translate.c.
86
* Note that the ARM_HWCAP_ARM_VFPv3D16 bit is always the inverse of
87
* ARM_HWCAP_ARM_VFPD32 (and so always clear for QEMU); it is unrelated
88
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/cpu.c
91
+++ b/target/arm/cpu.c
92
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
93
* Presence of EL2 itself is ARM_FEATURE_EL2, and of the
94
* Security Extensions is ARM_FEATURE_EL3.
95
*/
96
- assert(!tcg_enabled() || no_aa32 || cpu_isar_feature(arm_div, cpu));
97
+ assert(!tcg_enabled() || no_aa32 ||
98
+ cpu_isar_feature(aa32_arm_div, cpu));
99
set_feature(env, ARM_FEATURE_LPAE);
100
set_feature(env, ARM_FEATURE_V7);
101
}
102
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
103
if (arm_feature(env, ARM_FEATURE_V6)) {
104
set_feature(env, ARM_FEATURE_V5);
105
if (!arm_feature(env, ARM_FEATURE_M)) {
106
- assert(!tcg_enabled() || no_aa32 || cpu_isar_feature(jazelle, cpu));
107
+ assert(!tcg_enabled() || no_aa32 ||
108
+ cpu_isar_feature(aa32_jazelle, cpu));
109
set_feature(env, ARM_FEATURE_AUXCR);
110
}
111
}
112
diff --git a/target/arm/helper.c b/target/arm/helper.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/helper.c
115
+++ b/target/arm/helper.c
116
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
117
if (arm_feature(env, ARM_FEATURE_LPAE)) {
118
define_arm_cp_regs(cpu, lpae_cp_reginfo);
119
}
120
- if (cpu_isar_feature(jazelle, cpu)) {
121
+ if (cpu_isar_feature(aa32_jazelle, cpu)) {
122
define_arm_cp_regs(cpu, jazelle_regs);
123
}
124
/* Slightly awkwardly, the OMAP and StrongARM cores need all of
125
diff --git a/target/arm/translate.c b/target/arm/translate.c
126
index XXXXXXX..XXXXXXX 100644
127
--- a/target/arm/translate.c
128
+++ b/target/arm/translate.c
129
@@ -XXX,XX +XXX,XX @@
130
#define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
131
/* currently all emulated v5 cores are also v5TE, so don't bother */
132
#define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
133
-#define ENABLE_ARCH_5J dc_isar_feature(jazelle, s)
134
+#define ENABLE_ARCH_5J dc_isar_feature(aa32_jazelle, s)
135
#define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
136
#define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
137
#define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
138
@@ -XXX,XX +XXX,XX @@ static bool op_div(DisasContext *s, arg_rrr *a, bool u)
139
TCGv_i32 t1, t2;
140
141
if (s->thumb
142
- ? !dc_isar_feature(thumb_div, s)
143
- : !dc_isar_feature(arm_div, s)) {
144
+ ? !dc_isar_feature(aa32_thumb_div, s)
145
+ : !dc_isar_feature(aa32_arm_div, s)) {
146
return false;
147
}
148
149
--
150
2.20.1
151
152
diff view generated by jsdifflib
1
In take_aarch32_exception(), we know we are dealing with a CPU that
1
The xkb official name for the Arabic keyboard layout is 'ara'.
2
has AArch32, so the right isar_feature test is aa32_pan, not aa64_pan.
2
However xkb has for at least the past 15 years also permitted it to
3
be named via the legacy synonym 'ar'. In xkeyboard-config 2.39 this
4
synoynm was removed, which breaks compilation of QEMU:
3
5
6
FAILED: pc-bios/keymaps/ar
7
/home/fred/qemu-git/src/qemu/build-full/qemu-keymap -f pc-bios/keymaps/ar -l ar
8
xkbcommon: ERROR: Couldn't find file "symbols/ar" in include paths
9
xkbcommon: ERROR: 1 include paths searched:
10
xkbcommon: ERROR:     /usr/share/X11/xkb
11
xkbcommon: ERROR: 3 include paths could not be added:
12
xkbcommon: ERROR:     /home/fred/.config/xkb
13
xkbcommon: ERROR:     /home/fred/.xkb
14
xkbcommon: ERROR:     /etc/xkb
15
xkbcommon: ERROR: Abandoning symbols file "(unnamed)"
16
xkbcommon: ERROR: Failed to compile xkb_symbols
17
xkbcommon: ERROR: Failed to compile keymap
18
19
The upstream xkeyboard-config change removing the compat
20
mapping is:
21
https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/commit/470ad2cd8fea84d7210377161d86b31999bb5ea6
22
23
Make QEMU always ask for the 'ara' xkb layout, which should work on
24
both older and newer xkeyboard-config. We leave the QEMU name for
25
this keyboard layout as 'ar'; it is not the only one where our name
26
for it deviates from the xkb standard name.
27
28
Cc: qemu-stable@nongnu.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
30
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200214175116.9164-3-peter.maydell@linaro.org
31
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
32
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
33
Message-id: 20230620162024.1132013-1-peter.maydell@linaro.org
34
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1709
7
---
35
---
8
target/arm/helper.c | 2 +-
36
pc-bios/keymaps/meson.build | 2 +-
9
1 file changed, 1 insertion(+), 1 deletion(-)
37
1 file changed, 1 insertion(+), 1 deletion(-)
10
38
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
39
diff --git a/pc-bios/keymaps/meson.build b/pc-bios/keymaps/meson.build
12
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
41
--- a/pc-bios/keymaps/meson.build
14
+++ b/target/arm/helper.c
42
+++ b/pc-bios/keymaps/meson.build
15
@@ -XXX,XX +XXX,XX @@ static void take_aarch32_exception(CPUARMState *env, int new_mode,
43
@@ -XXX,XX +XXX,XX @@
16
env->elr_el[2] = env->regs[15];
44
keymaps = {
17
} else {
45
- 'ar': '-l ar',
18
/* CPSR.PAN is normally preserved preserved unless... */
46
+ 'ar': '-l ara',
19
- if (cpu_isar_feature(aa64_pan, env_archcpu(env))) {
47
'bepo': '-l fr -v dvorak',
20
+ if (cpu_isar_feature(aa32_pan, env_archcpu(env))) {
48
'cz': '-l cz',
21
switch (new_el) {
49
'da': '-l dk',
22
case 3:
23
if (!arm_is_secure_below_el3(env)) {
24
--
50
--
25
2.20.1
51
2.34.1
26
52
27
53
diff view generated by jsdifflib
Deleted patch
1
Our current usage of the isar_feature feature tests almost always
2
uses an _aa32_ test when the code path is known to be AArch32
3
specific and an _aa64_ test when the code path is known to be
4
AArch64 specific. There is just one exception: in the vfp_set_fpscr
5
helper we check aa64_fp16 to determine whether the FZ16 bit in
6
the FP(S)CR exists, but this code is also used for AArch32.
7
There are other places in future where we're likely to want
8
a general "does this feature exist for either AArch32 or
9
AArch64" check (typically where architecturally the feature exists
10
for both CPU states if it exists at all, but the CPU might be
11
AArch32-only or AArch64-only, and so only have one set of ID
12
registers).
13
1
14
Introduce a new category of isar_feature_* functions:
15
isar_feature_any_foo() should be tested when what we want to
16
know is "does this feature exist for either AArch32 or AArch64",
17
and always returns the logical OR of isar_feature_aa32_foo()
18
and isar_feature_aa64_foo().
19
20
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Message-id: 20200214175116.9164-4-peter.maydell@linaro.org
24
---
25
target/arm/cpu.h | 19 ++++++++++++++++++-
26
target/arm/vfp_helper.c | 2 +-
27
2 files changed, 19 insertions(+), 2 deletions(-)
28
29
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/cpu.h
32
+++ b/target/arm/cpu.h
33
@@ -XXX,XX +XXX,XX @@ extern const uint64_t pred_esz_masks[4];
34
* Naming convention for isar_feature functions:
35
* Functions which test 32-bit ID registers should have _aa32_ in
36
* their name. Functions which test 64-bit ID registers should have
37
- * _aa64_ in their name.
38
+ * _aa64_ in their name. These must only be used in code where we
39
+ * know for certain that the CPU has AArch32 or AArch64 respectively
40
+ * or where the correct answer for a CPU which doesn't implement that
41
+ * CPU state is "false" (eg when generating A32 or A64 code, if adding
42
+ * system registers that are specific to that CPU state, for "should
43
+ * we let this system register bit be set" tests where the 32-bit
44
+ * flavour of the register doesn't have the bit, and so on).
45
+ * Functions which simply ask "does this feature exist at all" have
46
+ * _any_ in their name, and always return the logical OR of the _aa64_
47
+ * and the _aa32_ function.
48
*/
49
50
/*
51
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
52
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
53
}
54
55
+/*
56
+ * Feature tests for "does this exist in either 32-bit or 64-bit?"
57
+ */
58
+static inline bool isar_feature_any_fp16(const ARMISARegisters *id)
59
+{
60
+ return isar_feature_aa64_fp16(id) || isar_feature_aa32_fp16_arith(id);
61
+}
62
+
63
/*
64
* Forward to the above feature tests given an ARMCPU pointer.
65
*/
66
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/vfp_helper.c
69
+++ b/target/arm/vfp_helper.c
70
@@ -XXX,XX +XXX,XX @@ uint32_t vfp_get_fpscr(CPUARMState *env)
71
void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
72
{
73
/* When ARMv8.2-FP16 is not supported, FZ16 is RES0. */
74
- if (!cpu_isar_feature(aa64_fp16, env_archcpu(env))) {
75
+ if (!cpu_isar_feature(any_fp16, env_archcpu(env))) {
76
val &= ~FPCR_FZ16;
77
}
78
79
--
80
2.20.1
81
82
diff view generated by jsdifflib
Deleted patch
1
Instead of open-coding "ARM_FEATURE_AARCH64 ? aa64_predinv: aa32_predinv",
2
define and use an any_predinv isar_feature test function.
3
1
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20200214175116.9164-5-peter.maydell@linaro.org
8
---
9
target/arm/cpu.h | 5 +++++
10
target/arm/helper.c | 9 +--------
11
2 files changed, 6 insertions(+), 8 deletions(-)
12
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
16
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_fp16(const ARMISARegisters *id)
18
return isar_feature_aa64_fp16(id) || isar_feature_aa32_fp16_arith(id);
19
}
20
21
+static inline bool isar_feature_any_predinv(const ARMISARegisters *id)
22
+{
23
+ return isar_feature_aa64_predinv(id) || isar_feature_aa32_predinv(id);
24
+}
25
+
26
/*
27
* Forward to the above feature tests given an ARMCPU pointer.
28
*/
29
diff --git a/target/arm/helper.c b/target/arm/helper.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/helper.c
32
+++ b/target/arm/helper.c
33
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
34
#endif /*CONFIG_USER_ONLY*/
35
#endif
36
37
- /*
38
- * While all v8.0 cpus support aarch64, QEMU does have configurations
39
- * that do not set ID_AA64ISAR1, e.g. user-only qemu-arm -cpu max,
40
- * which will set ID_ISAR6.
41
- */
42
- if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)
43
- ? cpu_isar_feature(aa64_predinv, cpu)
44
- : cpu_isar_feature(aa32_predinv, cpu)) {
45
+ if (cpu_isar_feature(any_predinv, cpu)) {
46
define_arm_cp_regs(cpu, predinv_reginfo);
47
}
48
49
--
50
2.20.1
51
52
diff view generated by jsdifflib
Deleted patch
1
Pull the code that defines the various PMU registers out
2
into its own function, matching the pattern we have
3
already for the debug registers.
4
1
5
Apart from one style fix to a multi-line comment, this
6
is purely movement of code with no changes to it.
7
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20200214175116.9164-6-peter.maydell@linaro.org
12
---
13
target/arm/helper.c | 158 +++++++++++++++++++++++---------------------
14
1 file changed, 82 insertions(+), 76 deletions(-)
15
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
19
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
21
}
22
}
23
24
+static void define_pmu_regs(ARMCPU *cpu)
25
+{
26
+ /*
27
+ * v7 performance monitor control register: same implementor
28
+ * field as main ID register, and we implement four counters in
29
+ * addition to the cycle count register.
30
+ */
31
+ unsigned int i, pmcrn = 4;
32
+ ARMCPRegInfo pmcr = {
33
+ .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
34
+ .access = PL0_RW,
35
+ .type = ARM_CP_IO | ARM_CP_ALIAS,
36
+ .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),
37
+ .accessfn = pmreg_access, .writefn = pmcr_write,
38
+ .raw_writefn = raw_write,
39
+ };
40
+ ARMCPRegInfo pmcr64 = {
41
+ .name = "PMCR_EL0", .state = ARM_CP_STATE_AA64,
42
+ .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 0,
43
+ .access = PL0_RW, .accessfn = pmreg_access,
44
+ .type = ARM_CP_IO,
45
+ .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
46
+ .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT),
47
+ .writefn = pmcr_write, .raw_writefn = raw_write,
48
+ };
49
+ define_one_arm_cp_reg(cpu, &pmcr);
50
+ define_one_arm_cp_reg(cpu, &pmcr64);
51
+ for (i = 0; i < pmcrn; i++) {
52
+ char *pmevcntr_name = g_strdup_printf("PMEVCNTR%d", i);
53
+ char *pmevcntr_el0_name = g_strdup_printf("PMEVCNTR%d_EL0", i);
54
+ char *pmevtyper_name = g_strdup_printf("PMEVTYPER%d", i);
55
+ char *pmevtyper_el0_name = g_strdup_printf("PMEVTYPER%d_EL0", i);
56
+ ARMCPRegInfo pmev_regs[] = {
57
+ { .name = pmevcntr_name, .cp = 15, .crn = 14,
58
+ .crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
59
+ .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
60
+ .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
61
+ .accessfn = pmreg_access },
62
+ { .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
63
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 8 | (3 & (i >> 3)),
64
+ .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
65
+ .type = ARM_CP_IO,
66
+ .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
67
+ .raw_readfn = pmevcntr_rawread,
68
+ .raw_writefn = pmevcntr_rawwrite },
69
+ { .name = pmevtyper_name, .cp = 15, .crn = 14,
70
+ .crm = 12 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
71
+ .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
72
+ .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
73
+ .accessfn = pmreg_access },
74
+ { .name = pmevtyper_el0_name, .state = ARM_CP_STATE_AA64,
75
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 12 | (3 & (i >> 3)),
76
+ .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
77
+ .type = ARM_CP_IO,
78
+ .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
79
+ .raw_writefn = pmevtyper_rawwrite },
80
+ REGINFO_SENTINEL
81
+ };
82
+ define_arm_cp_regs(cpu, pmev_regs);
83
+ g_free(pmevcntr_name);
84
+ g_free(pmevcntr_el0_name);
85
+ g_free(pmevtyper_name);
86
+ g_free(pmevtyper_el0_name);
87
+ }
88
+ if (FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
89
+ FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) != 0xf) {
90
+ ARMCPRegInfo v81_pmu_regs[] = {
91
+ { .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
92
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
93
+ .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
94
+ .resetvalue = extract64(cpu->pmceid0, 32, 32) },
95
+ { .name = "PMCEID3", .state = ARM_CP_STATE_AA32,
96
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5,
97
+ .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
98
+ .resetvalue = extract64(cpu->pmceid1, 32, 32) },
99
+ REGINFO_SENTINEL
100
+ };
101
+ define_arm_cp_regs(cpu, v81_pmu_regs);
102
+ }
103
+}
104
+
105
/* We don't know until after realize whether there's a GICv3
106
* attached, and that is what registers the gicv3 sysregs.
107
* So we have to fill in the GIC fields in ID_PFR/ID_PFR1_EL1/ID_AA64PFR0_EL1
108
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
109
define_arm_cp_regs(cpu, pmovsset_cp_reginfo);
110
}
111
if (arm_feature(env, ARM_FEATURE_V7)) {
112
- /* v7 performance monitor control register: same implementor
113
- * field as main ID register, and we implement four counters in
114
- * addition to the cycle count register.
115
- */
116
- unsigned int i, pmcrn = 4;
117
- ARMCPRegInfo pmcr = {
118
- .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
119
- .access = PL0_RW,
120
- .type = ARM_CP_IO | ARM_CP_ALIAS,
121
- .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),
122
- .accessfn = pmreg_access, .writefn = pmcr_write,
123
- .raw_writefn = raw_write,
124
- };
125
- ARMCPRegInfo pmcr64 = {
126
- .name = "PMCR_EL0", .state = ARM_CP_STATE_AA64,
127
- .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 0,
128
- .access = PL0_RW, .accessfn = pmreg_access,
129
- .type = ARM_CP_IO,
130
- .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
131
- .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT),
132
- .writefn = pmcr_write, .raw_writefn = raw_write,
133
- };
134
- define_one_arm_cp_reg(cpu, &pmcr);
135
- define_one_arm_cp_reg(cpu, &pmcr64);
136
- for (i = 0; i < pmcrn; i++) {
137
- char *pmevcntr_name = g_strdup_printf("PMEVCNTR%d", i);
138
- char *pmevcntr_el0_name = g_strdup_printf("PMEVCNTR%d_EL0", i);
139
- char *pmevtyper_name = g_strdup_printf("PMEVTYPER%d", i);
140
- char *pmevtyper_el0_name = g_strdup_printf("PMEVTYPER%d_EL0", i);
141
- ARMCPRegInfo pmev_regs[] = {
142
- { .name = pmevcntr_name, .cp = 15, .crn = 14,
143
- .crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
144
- .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
145
- .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
146
- .accessfn = pmreg_access },
147
- { .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
148
- .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 8 | (3 & (i >> 3)),
149
- .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
150
- .type = ARM_CP_IO,
151
- .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
152
- .raw_readfn = pmevcntr_rawread,
153
- .raw_writefn = pmevcntr_rawwrite },
154
- { .name = pmevtyper_name, .cp = 15, .crn = 14,
155
- .crm = 12 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
156
- .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
157
- .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
158
- .accessfn = pmreg_access },
159
- { .name = pmevtyper_el0_name, .state = ARM_CP_STATE_AA64,
160
- .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 12 | (3 & (i >> 3)),
161
- .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
162
- .type = ARM_CP_IO,
163
- .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
164
- .raw_writefn = pmevtyper_rawwrite },
165
- REGINFO_SENTINEL
166
- };
167
- define_arm_cp_regs(cpu, pmev_regs);
168
- g_free(pmevcntr_name);
169
- g_free(pmevcntr_el0_name);
170
- g_free(pmevtyper_name);
171
- g_free(pmevtyper_el0_name);
172
- }
173
ARMCPRegInfo clidr = {
174
.name = "CLIDR", .state = ARM_CP_STATE_BOTH,
175
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
176
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
177
define_one_arm_cp_reg(cpu, &clidr);
178
define_arm_cp_regs(cpu, v7_cp_reginfo);
179
define_debug_regs(cpu);
180
+ define_pmu_regs(cpu);
181
} else {
182
define_arm_cp_regs(cpu, not_v7_cp_reginfo);
183
}
184
- if (FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
185
- FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) != 0xf) {
186
- ARMCPRegInfo v81_pmu_regs[] = {
187
- { .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
188
- .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
189
- .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
190
- .resetvalue = extract64(cpu->pmceid0, 32, 32) },
191
- { .name = "PMCEID3", .state = ARM_CP_STATE_AA32,
192
- .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5,
193
- .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
194
- .resetvalue = extract64(cpu->pmceid1, 32, 32) },
195
- REGINFO_SENTINEL
196
- };
197
- define_arm_cp_regs(cpu, v81_pmu_regs);
198
- }
199
if (arm_feature(env, ARM_FEATURE_V8)) {
200
/* AArch64 ID registers, which all have impdef reset values.
201
* Note that within the ID register ranges the unused slots
202
--
203
2.20.1
204
205
diff view generated by jsdifflib
Deleted patch
1
Add FIELD() definitions for the ID_AA64DFR0_EL1 and use them
2
where we currently have hard-coded bit values.
3
1
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20200214175116.9164-7-peter.maydell@linaro.org
8
---
9
target/arm/cpu.h | 10 ++++++++++
10
target/arm/cpu.c | 2 +-
11
target/arm/helper.c | 6 +++---
12
3 files changed, 14 insertions(+), 4 deletions(-)
13
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 @@ FIELD(ID_AA64MMFR2, BBM, 52, 4)
19
FIELD(ID_AA64MMFR2, EVT, 56, 4)
20
FIELD(ID_AA64MMFR2, E0PD, 60, 4)
21
22
+FIELD(ID_AA64DFR0, DEBUGVER, 0, 4)
23
+FIELD(ID_AA64DFR0, TRACEVER, 4, 4)
24
+FIELD(ID_AA64DFR0, PMUVER, 8, 4)
25
+FIELD(ID_AA64DFR0, BRPS, 12, 4)
26
+FIELD(ID_AA64DFR0, WRPS, 20, 4)
27
+FIELD(ID_AA64DFR0, CTX_CMPS, 28, 4)
28
+FIELD(ID_AA64DFR0, PMSVER, 32, 4)
29
+FIELD(ID_AA64DFR0, DOUBLELOCK, 36, 4)
30
+FIELD(ID_AA64DFR0, TRACEFILT, 40, 4)
31
+
32
FIELD(ID_DFR0, COPDBG, 0, 4)
33
FIELD(ID_DFR0, COPSDBG, 4, 4)
34
FIELD(ID_DFR0, MMAPDBG, 8, 4)
35
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/cpu.c
38
+++ b/target/arm/cpu.c
39
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
40
cpu);
41
#endif
42
} else {
43
- cpu->id_aa64dfr0 &= ~0xf00;
44
+ cpu->id_aa64dfr0 = FIELD_DP64(cpu->id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
45
cpu->id_dfr0 &= ~(0xf << 24);
46
cpu->pmceid0 = 0;
47
cpu->pmceid1 = 0;
48
diff --git a/target/arm/helper.c b/target/arm/helper.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/helper.c
51
+++ b/target/arm/helper.c
52
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
53
* check that if they both exist then they agree.
54
*/
55
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
56
- assert(extract32(cpu->id_aa64dfr0, 12, 4) == brps);
57
- assert(extract32(cpu->id_aa64dfr0, 20, 4) == wrps);
58
- assert(extract32(cpu->id_aa64dfr0, 28, 4) == ctx_cmps);
59
+ assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
60
+ assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
61
+ assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) == ctx_cmps);
62
}
63
64
define_one_arm_cp_reg(cpu, &dbgdidr);
65
--
66
2.20.1
67
68
diff view generated by jsdifflib
Deleted patch
1
We already define FIELD macros for ID_DFR0, so use them in the
2
one place where we're doing direct bit value manipulation.
3
1
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20200214175116.9164-8-peter.maydell@linaro.org
8
---
9
target/arm/cpu.c | 2 +-
10
1 file changed, 1 insertion(+), 1 deletion(-)
11
12
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.c
15
+++ b/target/arm/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
17
#endif
18
} else {
19
cpu->id_aa64dfr0 = FIELD_DP64(cpu->id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
20
- cpu->id_dfr0 &= ~(0xf << 24);
21
+ cpu->id_dfr0 = FIELD_DP32(cpu->id_dfr0, ID_DFR0, PERFMON, 0);
22
cpu->pmceid0 = 0;
23
cpu->pmceid1 = 0;
24
}
25
--
26
2.20.1
27
28
diff view generated by jsdifflib
Deleted patch
1
Instead of open-coding a check on the ID_DFR0 PerfMon ID register
2
field, create a standardly-named isar_feature for "does AArch32 have
3
a v8.1 PMUv3" and use it.
4
1
5
This entails moving the id_dfr0 field into the ARMISARegisters struct.
6
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20200214175116.9164-9-peter.maydell@linaro.org
10
---
11
target/arm/cpu.h | 9 ++++++++-
12
hw/intc/armv7m_nvic.c | 2 +-
13
target/arm/cpu.c | 28 ++++++++++++++--------------
14
target/arm/cpu64.c | 6 +++---
15
target/arm/helper.c | 5 ++---
16
5 files changed, 28 insertions(+), 22 deletions(-)
17
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
23
uint32_t mvfr0;
24
uint32_t mvfr1;
25
uint32_t mvfr2;
26
+ uint32_t id_dfr0;
27
uint64_t id_aa64isar0;
28
uint64_t id_aa64isar1;
29
uint64_t id_aa64pfr0;
30
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
31
uint32_t reset_sctlr;
32
uint32_t id_pfr0;
33
uint32_t id_pfr1;
34
- uint32_t id_dfr0;
35
uint64_t pmceid0;
36
uint64_t pmceid1;
37
uint32_t id_afr0;
38
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_ats1e1(const ARMISARegisters *id)
39
return FIELD_EX64(id->mvfr0, ID_MMFR3, PAN) >= 2;
40
}
41
42
+static inline bool isar_feature_aa32_pmu_8_1(const ARMISARegisters *id)
43
+{
44
+ /* 0xf means "non-standard IMPDEF PMU" */
45
+ return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
46
+ FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
47
+}
48
+
49
/*
50
* 64-bit feature tests via id registers.
51
*/
52
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/intc/armv7m_nvic.c
55
+++ b/hw/intc/armv7m_nvic.c
56
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
57
case 0xd44: /* PFR1. */
58
return cpu->id_pfr1;
59
case 0xd48: /* DFR0. */
60
- return cpu->id_dfr0;
61
+ return cpu->isar.id_dfr0;
62
case 0xd4c: /* AFR0. */
63
return cpu->id_afr0;
64
case 0xd50: /* MMFR0. */
65
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/cpu.c
68
+++ b/target/arm/cpu.c
69
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
70
#endif
71
} else {
72
cpu->id_aa64dfr0 = FIELD_DP64(cpu->id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
73
- cpu->id_dfr0 = FIELD_DP32(cpu->id_dfr0, ID_DFR0, PERFMON, 0);
74
+ cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, PERFMON, 0);
75
cpu->pmceid0 = 0;
76
cpu->pmceid1 = 0;
77
}
78
@@ -XXX,XX +XXX,XX @@ static void arm1136_r2_initfn(Object *obj)
79
cpu->reset_sctlr = 0x00050078;
80
cpu->id_pfr0 = 0x111;
81
cpu->id_pfr1 = 0x1;
82
- cpu->id_dfr0 = 0x2;
83
+ cpu->isar.id_dfr0 = 0x2;
84
cpu->id_afr0 = 0x3;
85
cpu->id_mmfr0 = 0x01130003;
86
cpu->id_mmfr1 = 0x10030302;
87
@@ -XXX,XX +XXX,XX @@ static void arm1136_initfn(Object *obj)
88
cpu->reset_sctlr = 0x00050078;
89
cpu->id_pfr0 = 0x111;
90
cpu->id_pfr1 = 0x1;
91
- cpu->id_dfr0 = 0x2;
92
+ cpu->isar.id_dfr0 = 0x2;
93
cpu->id_afr0 = 0x3;
94
cpu->id_mmfr0 = 0x01130003;
95
cpu->id_mmfr1 = 0x10030302;
96
@@ -XXX,XX +XXX,XX @@ static void arm1176_initfn(Object *obj)
97
cpu->reset_sctlr = 0x00050078;
98
cpu->id_pfr0 = 0x111;
99
cpu->id_pfr1 = 0x11;
100
- cpu->id_dfr0 = 0x33;
101
+ cpu->isar.id_dfr0 = 0x33;
102
cpu->id_afr0 = 0;
103
cpu->id_mmfr0 = 0x01130003;
104
cpu->id_mmfr1 = 0x10030302;
105
@@ -XXX,XX +XXX,XX @@ static void arm11mpcore_initfn(Object *obj)
106
cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */
107
cpu->id_pfr0 = 0x111;
108
cpu->id_pfr1 = 0x1;
109
- cpu->id_dfr0 = 0;
110
+ cpu->isar.id_dfr0 = 0;
111
cpu->id_afr0 = 0x2;
112
cpu->id_mmfr0 = 0x01100103;
113
cpu->id_mmfr1 = 0x10020302;
114
@@ -XXX,XX +XXX,XX @@ static void cortex_m3_initfn(Object *obj)
115
cpu->pmsav7_dregion = 8;
116
cpu->id_pfr0 = 0x00000030;
117
cpu->id_pfr1 = 0x00000200;
118
- cpu->id_dfr0 = 0x00100000;
119
+ cpu->isar.id_dfr0 = 0x00100000;
120
cpu->id_afr0 = 0x00000000;
121
cpu->id_mmfr0 = 0x00000030;
122
cpu->id_mmfr1 = 0x00000000;
123
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
124
cpu->isar.mvfr2 = 0x00000000;
125
cpu->id_pfr0 = 0x00000030;
126
cpu->id_pfr1 = 0x00000200;
127
- cpu->id_dfr0 = 0x00100000;
128
+ cpu->isar.id_dfr0 = 0x00100000;
129
cpu->id_afr0 = 0x00000000;
130
cpu->id_mmfr0 = 0x00000030;
131
cpu->id_mmfr1 = 0x00000000;
132
@@ -XXX,XX +XXX,XX @@ static void cortex_m7_initfn(Object *obj)
133
cpu->isar.mvfr2 = 0x00000040;
134
cpu->id_pfr0 = 0x00000030;
135
cpu->id_pfr1 = 0x00000200;
136
- cpu->id_dfr0 = 0x00100000;
137
+ cpu->isar.id_dfr0 = 0x00100000;
138
cpu->id_afr0 = 0x00000000;
139
cpu->id_mmfr0 = 0x00100030;
140
cpu->id_mmfr1 = 0x00000000;
141
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
142
cpu->isar.mvfr2 = 0x00000040;
143
cpu->id_pfr0 = 0x00000030;
144
cpu->id_pfr1 = 0x00000210;
145
- cpu->id_dfr0 = 0x00200000;
146
+ cpu->isar.id_dfr0 = 0x00200000;
147
cpu->id_afr0 = 0x00000000;
148
cpu->id_mmfr0 = 0x00101F40;
149
cpu->id_mmfr1 = 0x00000000;
150
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
151
cpu->midr = 0x411fc153; /* r1p3 */
152
cpu->id_pfr0 = 0x0131;
153
cpu->id_pfr1 = 0x001;
154
- cpu->id_dfr0 = 0x010400;
155
+ cpu->isar.id_dfr0 = 0x010400;
156
cpu->id_afr0 = 0x0;
157
cpu->id_mmfr0 = 0x0210030;
158
cpu->id_mmfr1 = 0x00000000;
159
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
160
cpu->reset_sctlr = 0x00c50078;
161
cpu->id_pfr0 = 0x1031;
162
cpu->id_pfr1 = 0x11;
163
- cpu->id_dfr0 = 0x400;
164
+ cpu->isar.id_dfr0 = 0x400;
165
cpu->id_afr0 = 0;
166
cpu->id_mmfr0 = 0x31100003;
167
cpu->id_mmfr1 = 0x20000000;
168
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
169
cpu->reset_sctlr = 0x00c50078;
170
cpu->id_pfr0 = 0x1031;
171
cpu->id_pfr1 = 0x11;
172
- cpu->id_dfr0 = 0x000;
173
+ cpu->isar.id_dfr0 = 0x000;
174
cpu->id_afr0 = 0;
175
cpu->id_mmfr0 = 0x00100103;
176
cpu->id_mmfr1 = 0x20000000;
177
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
178
cpu->reset_sctlr = 0x00c50078;
179
cpu->id_pfr0 = 0x00001131;
180
cpu->id_pfr1 = 0x00011011;
181
- cpu->id_dfr0 = 0x02010555;
182
+ cpu->isar.id_dfr0 = 0x02010555;
183
cpu->id_afr0 = 0x00000000;
184
cpu->id_mmfr0 = 0x10101105;
185
cpu->id_mmfr1 = 0x40000000;
186
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
187
cpu->reset_sctlr = 0x00c50078;
188
cpu->id_pfr0 = 0x00001131;
189
cpu->id_pfr1 = 0x00011011;
190
- cpu->id_dfr0 = 0x02010555;
191
+ cpu->isar.id_dfr0 = 0x02010555;
192
cpu->id_afr0 = 0x00000000;
193
cpu->id_mmfr0 = 0x10201105;
194
cpu->id_mmfr1 = 0x20000000;
195
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
196
index XXXXXXX..XXXXXXX 100644
197
--- a/target/arm/cpu64.c
198
+++ b/target/arm/cpu64.c
199
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
200
cpu->reset_sctlr = 0x00c50838;
201
cpu->id_pfr0 = 0x00000131;
202
cpu->id_pfr1 = 0x00011011;
203
- cpu->id_dfr0 = 0x03010066;
204
+ cpu->isar.id_dfr0 = 0x03010066;
205
cpu->id_afr0 = 0x00000000;
206
cpu->id_mmfr0 = 0x10101105;
207
cpu->id_mmfr1 = 0x40000000;
208
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
209
cpu->reset_sctlr = 0x00c50838;
210
cpu->id_pfr0 = 0x00000131;
211
cpu->id_pfr1 = 0x00011011;
212
- cpu->id_dfr0 = 0x03010066;
213
+ cpu->isar.id_dfr0 = 0x03010066;
214
cpu->id_afr0 = 0x00000000;
215
cpu->id_mmfr0 = 0x10101105;
216
cpu->id_mmfr1 = 0x40000000;
217
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
218
cpu->reset_sctlr = 0x00c50838;
219
cpu->id_pfr0 = 0x00000131;
220
cpu->id_pfr1 = 0x00011011;
221
- cpu->id_dfr0 = 0x03010066;
222
+ cpu->isar.id_dfr0 = 0x03010066;
223
cpu->id_afr0 = 0x00000000;
224
cpu->id_mmfr0 = 0x10201105;
225
cpu->id_mmfr1 = 0x40000000;
226
diff --git a/target/arm/helper.c b/target/arm/helper.c
227
index XXXXXXX..XXXXXXX 100644
228
--- a/target/arm/helper.c
229
+++ b/target/arm/helper.c
230
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
231
g_free(pmevtyper_name);
232
g_free(pmevtyper_el0_name);
233
}
234
- if (FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
235
- FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) != 0xf) {
236
+ if (cpu_isar_feature(aa32_pmu_8_1, cpu)) {
237
ARMCPRegInfo v81_pmu_regs[] = {
238
{ .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
239
.cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
240
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
241
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2,
242
.access = PL1_R, .type = ARM_CP_CONST,
243
.accessfn = access_aa32_tid3,
244
- .resetvalue = cpu->id_dfr0 },
245
+ .resetvalue = cpu->isar.id_dfr0 },
246
{ .name = "ID_AFR0", .state = ARM_CP_STATE_BOTH,
247
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 3,
248
.access = PL1_R, .type = ARM_CP_CONST,
249
--
250
2.20.1
251
252
diff view generated by jsdifflib
Deleted patch
1
We're going to want to read the DBGDIDR register from KVM in
2
a subsequent commit, which means it needs to be in the
3
ARMISARegisters sub-struct. Move it.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200214175116.9164-12-peter.maydell@linaro.org
8
---
9
target/arm/cpu.h | 2 +-
10
target/arm/internals.h | 6 +++---
11
target/arm/cpu.c | 8 ++++----
12
target/arm/cpu64.c | 6 +++---
13
target/arm/helper.c | 2 +-
14
5 files changed, 12 insertions(+), 12 deletions(-)
15
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
21
uint32_t mvfr1;
22
uint32_t mvfr2;
23
uint32_t id_dfr0;
24
+ uint32_t dbgdidr;
25
uint64_t id_aa64isar0;
26
uint64_t id_aa64isar1;
27
uint64_t id_aa64pfr0;
28
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
29
uint32_t id_mmfr4;
30
uint64_t id_aa64afr0;
31
uint64_t id_aa64afr1;
32
- uint32_t dbgdidr;
33
uint32_t clidr;
34
uint64_t mp_affinity; /* MP ID without feature bits */
35
/* The elements of this array are the CCSIDR values for each cache,
36
diff --git a/target/arm/internals.h b/target/arm/internals.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/internals.h
39
+++ b/target/arm/internals.h
40
@@ -XXX,XX +XXX,XX @@ static inline int arm_num_brps(ARMCPU *cpu)
41
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
42
return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) + 1;
43
} else {
44
- return FIELD_EX32(cpu->dbgdidr, DBGDIDR, BRPS) + 1;
45
+ return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, BRPS) + 1;
46
}
47
}
48
49
@@ -XXX,XX +XXX,XX @@ static inline int arm_num_wrps(ARMCPU *cpu)
50
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
51
return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) + 1;
52
} else {
53
- return FIELD_EX32(cpu->dbgdidr, DBGDIDR, WRPS) + 1;
54
+ return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, WRPS) + 1;
55
}
56
}
57
58
@@ -XXX,XX +XXX,XX @@ static inline int arm_num_ctx_cmps(ARMCPU *cpu)
59
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
60
return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) + 1;
61
} else {
62
- return FIELD_EX32(cpu->dbgdidr, DBGDIDR, CTX_CMPS) + 1;
63
+ return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, CTX_CMPS) + 1;
64
}
65
}
66
67
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/arm/cpu.c
70
+++ b/target/arm/cpu.c
71
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
72
cpu->isar.id_isar2 = 0x21232031;
73
cpu->isar.id_isar3 = 0x11112131;
74
cpu->isar.id_isar4 = 0x00111142;
75
- cpu->dbgdidr = 0x15141000;
76
+ cpu->isar.dbgdidr = 0x15141000;
77
cpu->clidr = (1 << 27) | (2 << 24) | 3;
78
cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */
79
cpu->ccsidr[1] = 0x2007e01a; /* 16k L1 icache. */
80
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
81
cpu->isar.id_isar2 = 0x21232041;
82
cpu->isar.id_isar3 = 0x11112131;
83
cpu->isar.id_isar4 = 0x00111142;
84
- cpu->dbgdidr = 0x35141000;
85
+ cpu->isar.dbgdidr = 0x35141000;
86
cpu->clidr = (1 << 27) | (1 << 24) | 3;
87
cpu->ccsidr[0] = 0xe00fe019; /* 16k L1 dcache. */
88
cpu->ccsidr[1] = 0x200fe019; /* 16k L1 icache. */
89
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
90
cpu->isar.id_isar2 = 0x21232041;
91
cpu->isar.id_isar3 = 0x11112131;
92
cpu->isar.id_isar4 = 0x10011142;
93
- cpu->dbgdidr = 0x3515f005;
94
+ cpu->isar.dbgdidr = 0x3515f005;
95
cpu->clidr = 0x0a200023;
96
cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
97
cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
98
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
99
cpu->isar.id_isar2 = 0x21232041;
100
cpu->isar.id_isar3 = 0x11112131;
101
cpu->isar.id_isar4 = 0x10011142;
102
- cpu->dbgdidr = 0x3515f021;
103
+ cpu->isar.dbgdidr = 0x3515f021;
104
cpu->clidr = 0x0a200023;
105
cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
106
cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
107
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/target/arm/cpu64.c
110
+++ b/target/arm/cpu64.c
111
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
112
cpu->isar.id_aa64dfr0 = 0x10305106;
113
cpu->isar.id_aa64isar0 = 0x00011120;
114
cpu->isar.id_aa64mmfr0 = 0x00001124;
115
- cpu->dbgdidr = 0x3516d000;
116
+ cpu->isar.dbgdidr = 0x3516d000;
117
cpu->clidr = 0x0a200023;
118
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
119
cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */
120
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
121
cpu->isar.id_aa64dfr0 = 0x10305106;
122
cpu->isar.id_aa64isar0 = 0x00011120;
123
cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
124
- cpu->dbgdidr = 0x3516d000;
125
+ cpu->isar.dbgdidr = 0x3516d000;
126
cpu->clidr = 0x0a200023;
127
cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
128
cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */
129
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
130
cpu->isar.id_aa64dfr0 = 0x10305106;
131
cpu->isar.id_aa64isar0 = 0x00011120;
132
cpu->isar.id_aa64mmfr0 = 0x00001124;
133
- cpu->dbgdidr = 0x3516d000;
134
+ cpu->isar.dbgdidr = 0x3516d000;
135
cpu->clidr = 0x0a200023;
136
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
137
cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */
138
diff --git a/target/arm/helper.c b/target/arm/helper.c
139
index XXXXXXX..XXXXXXX 100644
140
--- a/target/arm/helper.c
141
+++ b/target/arm/helper.c
142
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
143
ARMCPRegInfo dbgdidr = {
144
.name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0,
145
.access = PL0_R, .accessfn = access_tda,
146
- .type = ARM_CP_CONST, .resetvalue = cpu->dbgdidr,
147
+ .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdidr,
148
};
149
150
/* Note that all these register fields hold "number of Xs minus 1". */
151
--
152
2.20.1
153
154
diff view generated by jsdifflib
Deleted patch
1
Now we have isar_feature test functions that look at fields in the
2
ID_AA64DFR0_EL1 and ID_DFR0 ID registers, add the code that reads
3
these register values from KVM so that the checks behave correctly
4
when we're using KVM.
5
1
6
No isar_feature function tests ID_AA64DFR1_EL1 or DBGDIDR yet, but we
7
add it to maintain the invariant that every field in the
8
ARMISARegisters struct is populated for a KVM CPU and can be relied
9
on. This requirement isn't actually written down yet, so add a note
10
to the relevant comment.
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20200214175116.9164-13-peter.maydell@linaro.org
15
---
16
target/arm/cpu.h | 5 +++++
17
target/arm/kvm32.c | 8 ++++++++
18
target/arm/kvm64.c | 36 ++++++++++++++++++++++++++++++++++++
19
3 files changed, 49 insertions(+)
20
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.h
24
+++ b/target/arm/cpu.h
25
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
26
* prefix means a constant register.
27
* Some of these registers are split out into a substructure that
28
* is shared with the translators to control the ISA.
29
+ *
30
+ * Note that if you add an ID register to the ARMISARegisters struct
31
+ * you need to also update the 32-bit and 64-bit versions of the
32
+ * kvm_arm_get_host_cpu_features() function to correctly populate the
33
+ * field by reading the value from the KVM vCPU.
34
*/
35
struct ARMISARegisters {
36
uint32_t id_isar0;
37
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/kvm32.c
40
+++ b/target/arm/kvm32.c
41
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
42
ahcf->isar.id_isar6 = 0;
43
}
44
45
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0,
46
+ ARM_CP15_REG32(0, 0, 1, 2));
47
+
48
err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr0,
49
KVM_REG_ARM | KVM_REG_SIZE_U32 |
50
KVM_REG_ARM_VFP | KVM_REG_ARM_VFP_MVFR0);
51
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
52
* Fortunately there is not yet anything in there that affects migration.
53
*/
54
55
+ /*
56
+ * There is no way to read DBGDIDR, because currently 32-bit KVM
57
+ * doesn't implement debug at all. Leave it at zero.
58
+ */
59
+
60
kvm_arm_destroy_scratch_host_vcpu(fdarray);
61
62
if (err < 0) {
63
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/kvm64.c
66
+++ b/target/arm/kvm64.c
67
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
68
} else {
69
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64pfr1,
70
ARM64_SYS_REG(3, 0, 0, 4, 1));
71
+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr0,
72
+ ARM64_SYS_REG(3, 0, 0, 5, 0));
73
+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr1,
74
+ ARM64_SYS_REG(3, 0, 0, 5, 1));
75
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar0,
76
ARM64_SYS_REG(3, 0, 0, 6, 0));
77
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar1,
78
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
79
* than skipping the reads and leaving 0, as we must avoid
80
* considering the values in every case.
81
*/
82
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0,
83
+ ARM64_SYS_REG(3, 0, 0, 1, 2));
84
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar0,
85
ARM64_SYS_REG(3, 0, 0, 2, 0));
86
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar1,
87
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
88
ARM64_SYS_REG(3, 0, 0, 3, 1));
89
err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr2,
90
ARM64_SYS_REG(3, 0, 0, 3, 2));
91
+
92
+ /*
93
+ * DBGDIDR is a bit complicated because the kernel doesn't
94
+ * provide an accessor for it in 64-bit mode, which is what this
95
+ * scratch VM is in, and there's no architected "64-bit sysreg
96
+ * which reads the same as the 32-bit register" the way there is
97
+ * for other ID registers. Instead we synthesize a value from the
98
+ * AArch64 ID_AA64DFR0, the same way the kernel code in
99
+ * arch/arm64/kvm/sys_regs.c:trap_dbgidr() does.
100
+ * We only do this if the CPU supports AArch32 at EL1.
101
+ */
102
+ if (FIELD_EX32(ahcf->isar.id_aa64pfr0, ID_AA64PFR0, EL1) >= 2) {
103
+ int wrps = FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, WRPS);
104
+ int brps = FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, BRPS);
105
+ int ctx_cmps =
106
+ FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS);
107
+ int version = 6; /* ARMv8 debug architecture */
108
+ bool has_el3 =
109
+ !!FIELD_EX32(ahcf->isar.id_aa64pfr0, ID_AA64PFR0, EL3);
110
+ uint32_t dbgdidr = 0;
111
+
112
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, WRPS, wrps);
113
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, BRPS, brps);
114
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, CTX_CMPS, ctx_cmps);
115
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, VERSION, version);
116
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, NSUHD_IMP, has_el3);
117
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, SE_IMP, has_el3);
118
+ dbgdidr |= (1 << 15); /* RES1 bit */
119
+ ahcf->isar.dbgdidr = dbgdidr;
120
+ }
121
}
122
123
sve_supported = ioctl(fdarray[0], KVM_CHECK_EXTENSION, KVM_CAP_ARM_SVE) > 0;
124
--
125
2.20.1
126
127
diff view generated by jsdifflib
Deleted patch
1
The ARMv8.1-PMU extension requires:
2
* the evtCount field in PMETYPER<n>_EL0 is 16 bits, not 10
3
* MDCR_EL2.HPMD allows event counting to be disabled at EL2
4
* two new required events, STALL_FRONTEND and STALL_BACKEND
5
* ID register bits in ID_AA64DFR0_EL1 and ID_DFR0
6
1
7
We already implement the 16-bit evtCount field and the
8
HPMD bit, so all that is missing is the two new events:
9
STALL_FRONTEND
10
"counts every cycle counted by the CPU_CYCLES event on which no
11
operation was issued because there are no operations available
12
to issue to this PE from the frontend"
13
STALL_BACKEND
14
"counts every cycle counted by the CPU_CYCLES event on which no
15
operation was issued because the backend is unable to accept
16
any available operations from the frontend"
17
18
QEMU never stalls in this sense, so our implementation is trivial:
19
always return a zero count.
20
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Message-id: 20200214175116.9164-14-peter.maydell@linaro.org
24
---
25
target/arm/helper.c | 32 ++++++++++++++++++++++++++++++--
26
1 file changed, 30 insertions(+), 2 deletions(-)
27
28
diff --git a/target/arm/helper.c b/target/arm/helper.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/helper.c
31
+++ b/target/arm/helper.c
32
@@ -XXX,XX +XXX,XX @@ static int64_t instructions_ns_per(uint64_t icount)
33
}
34
#endif
35
36
+static bool pmu_8_1_events_supported(CPUARMState *env)
37
+{
38
+ /* For events which are supported in any v8.1 PMU */
39
+ return cpu_isar_feature(any_pmu_8_1, env_archcpu(env));
40
+}
41
+
42
+static uint64_t zero_event_get_count(CPUARMState *env)
43
+{
44
+ /* For events which on QEMU never fire, so their count is always zero */
45
+ return 0;
46
+}
47
+
48
+static int64_t zero_event_ns_per(uint64_t cycles)
49
+{
50
+ /* An event which never fires can never overflow */
51
+ return -1;
52
+}
53
+
54
static const pm_event pm_events[] = {
55
{ .number = 0x000, /* SW_INCR */
56
.supported = event_always_supported,
57
@@ -XXX,XX +XXX,XX @@ static const pm_event pm_events[] = {
58
.supported = event_always_supported,
59
.get_count = cycles_get_count,
60
.ns_per_count = cycles_ns_per,
61
- }
62
+ },
63
#endif
64
+ { .number = 0x023, /* STALL_FRONTEND */
65
+ .supported = pmu_8_1_events_supported,
66
+ .get_count = zero_event_get_count,
67
+ .ns_per_count = zero_event_ns_per,
68
+ },
69
+ { .number = 0x024, /* STALL_BACKEND */
70
+ .supported = pmu_8_1_events_supported,
71
+ .get_count = zero_event_get_count,
72
+ .ns_per_count = zero_event_ns_per,
73
+ },
74
};
75
76
/*
77
@@ -XXX,XX +XXX,XX @@ static const pm_event pm_events[] = {
78
* should first be updated to something sparse instead of the current
79
* supported_event_map[] array.
80
*/
81
-#define MAX_EVENT_ID 0x11
82
+#define MAX_EVENT_ID 0x24
83
#define UNSUPPORTED_EVENT UINT16_MAX
84
static uint16_t supported_event_map[MAX_EVENT_ID + 1];
85
86
--
87
2.20.1
88
89
diff view generated by jsdifflib
Deleted patch
1
Set the ID register bits to provide ARMv8.4-PMU (and implicitly
2
also ARMv8.1-PMU) in the 'max' CPU.
3
1
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Message-id: 20200214175116.9164-16-peter.maydell@linaro.org
7
---
8
target/arm/cpu64.c | 8 ++++++++
9
1 file changed, 8 insertions(+)
10
11
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu64.c
14
+++ b/target/arm/cpu64.c
15
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
16
u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */
17
cpu->id_mmfr3 = u;
18
19
+ u = cpu->isar.id_aa64dfr0;
20
+ u = FIELD_DP64(u, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
21
+ cpu->isar.id_aa64dfr0 = u;
22
+
23
+ u = cpu->isar.id_dfr0;
24
+ u = FIELD_DP32(u, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
25
+ cpu->isar.id_dfr0 = u;
26
+
27
/*
28
* FIXME: We do not yet support ARMv8.2-fp16 for AArch32 yet,
29
* so do not set MVFR1.FPHP. Strictly speaking this is not legal,
30
--
31
2.20.1
32
33
diff view generated by jsdifflib
Deleted patch
1
The PMCR_EL0.DP bit is bit 5, which is 0x20, not 0x10. 0x10 is 'X'.
2
Correct our #define of PMCRDP and add the missing PMCRX.
3
1
4
We do have the correct behaviour for handling the DP bit being
5
set, so this fixes a guest-visible bug.
6
7
Fixes: 033614c47de
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20200214175116.9164-17-peter.maydell@linaro.org
12
---
13
target/arm/helper.c | 3 ++-
14
1 file changed, 2 insertions(+), 1 deletion(-)
15
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
19
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
21
#define PMCRN_MASK 0xf800
22
#define PMCRN_SHIFT 11
23
#define PMCRLC 0x40
24
-#define PMCRDP 0x10
25
+#define PMCRDP 0x20
26
+#define PMCRX 0x10
27
#define PMCRD 0x8
28
#define PMCRC 0x4
29
#define PMCRP 0x2
30
--
31
2.20.1
32
33
diff view generated by jsdifflib
Deleted patch
1
The LC bit in the PMCR_EL0 register is supposed to be:
2
* read/write
3
* RES1 on an AArch64-only implementation
4
* an architecturally UNKNOWN value on reset
5
(and use of LC==0 by software is deprecated).
6
1
7
We were implementing it incorrectly as read-only always zero,
8
though we do have all the code needed to test it and behave
9
accordingly.
10
11
Instead make it a read-write bit which resets to 1 always, which
12
satisfies all the architectural requirements above.
13
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Message-id: 20200214175116.9164-18-peter.maydell@linaro.org
18
---
19
target/arm/helper.c | 13 +++++++++----
20
1 file changed, 9 insertions(+), 4 deletions(-)
21
22
diff --git a/target/arm/helper.c b/target/arm/helper.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/helper.c
25
+++ b/target/arm/helper.c
26
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
27
#define PMCRC 0x4
28
#define PMCRP 0x2
29
#define PMCRE 0x1
30
+/*
31
+ * Mask of PMCR bits writeable by guest (not including WO bits like C, P,
32
+ * which can be written as 1 to trigger behaviour but which stay RAZ).
33
+ */
34
+#define PMCR_WRITEABLE_MASK (PMCRLC | PMCRDP | PMCRX | PMCRD | PMCRE)
35
36
#define PMXEVTYPER_P 0x80000000
37
#define PMXEVTYPER_U 0x40000000
38
@@ -XXX,XX +XXX,XX @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
39
}
40
}
41
42
- /* only the DP, X, D and E bits are writable */
43
- env->cp15.c9_pmcr &= ~0x39;
44
- env->cp15.c9_pmcr |= (value & 0x39);
45
+ env->cp15.c9_pmcr &= ~PMCR_WRITEABLE_MASK;
46
+ env->cp15.c9_pmcr |= (value & PMCR_WRITEABLE_MASK);
47
48
pmu_op_finish(env);
49
}
50
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
51
.access = PL0_RW, .accessfn = pmreg_access,
52
.type = ARM_CP_IO,
53
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
54
- .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT),
55
+ .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT) |
56
+ PMCRLC,
57
.writefn = pmcr_write, .raw_writefn = raw_write,
58
};
59
define_one_arm_cp_reg(cpu, &pmcr);
60
--
61
2.20.1
62
63
diff view generated by jsdifflib
Deleted patch
1
The isar_feature_aa32_pan and isar_feature_aa32_ats1e1 functions
2
are supposed to be testing fields in ID_MMFR3; but a cut-and-paste
3
error meant we were looking at MVFR0 instead.
4
1
5
Fix the functions to look at the right register; this requires
6
us to move at least id_mmfr3 to the ARMISARegisters struct; we
7
choose to move all the ID_MMFRn registers for consistency.
8
9
Fixes: 3d6ad6bb466f
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200214175116.9164-19-peter.maydell@linaro.org
13
---
14
target/arm/cpu.h | 14 +++---
15
hw/intc/armv7m_nvic.c | 8 ++--
16
target/arm/cpu.c | 104 +++++++++++++++++++++---------------------
17
target/arm/cpu64.c | 28 ++++++------
18
target/arm/helper.c | 12 ++---
19
target/arm/kvm32.c | 17 +++++++
20
target/arm/kvm64.c | 10 ++++
21
7 files changed, 110 insertions(+), 83 deletions(-)
22
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/cpu.h
26
+++ b/target/arm/cpu.h
27
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
28
uint32_t id_isar4;
29
uint32_t id_isar5;
30
uint32_t id_isar6;
31
+ uint32_t id_mmfr0;
32
+ uint32_t id_mmfr1;
33
+ uint32_t id_mmfr2;
34
+ uint32_t id_mmfr3;
35
+ uint32_t id_mmfr4;
36
uint32_t mvfr0;
37
uint32_t mvfr1;
38
uint32_t mvfr2;
39
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
40
uint64_t pmceid0;
41
uint64_t pmceid1;
42
uint32_t id_afr0;
43
- uint32_t id_mmfr0;
44
- uint32_t id_mmfr1;
45
- uint32_t id_mmfr2;
46
- uint32_t id_mmfr3;
47
- uint32_t id_mmfr4;
48
uint64_t id_aa64afr0;
49
uint64_t id_aa64afr1;
50
uint32_t clidr;
51
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_vminmaxnm(const ARMISARegisters *id)
52
53
static inline bool isar_feature_aa32_pan(const ARMISARegisters *id)
54
{
55
- return FIELD_EX64(id->mvfr0, ID_MMFR3, PAN) != 0;
56
+ return FIELD_EX32(id->id_mmfr3, ID_MMFR3, PAN) != 0;
57
}
58
59
static inline bool isar_feature_aa32_ats1e1(const ARMISARegisters *id)
60
{
61
- return FIELD_EX64(id->mvfr0, ID_MMFR3, PAN) >= 2;
62
+ return FIELD_EX32(id->id_mmfr3, ID_MMFR3, PAN) >= 2;
63
}
64
65
static inline bool isar_feature_aa32_pmu_8_1(const ARMISARegisters *id)
66
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/intc/armv7m_nvic.c
69
+++ b/hw/intc/armv7m_nvic.c
70
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
71
case 0xd4c: /* AFR0. */
72
return cpu->id_afr0;
73
case 0xd50: /* MMFR0. */
74
- return cpu->id_mmfr0;
75
+ return cpu->isar.id_mmfr0;
76
case 0xd54: /* MMFR1. */
77
- return cpu->id_mmfr1;
78
+ return cpu->isar.id_mmfr1;
79
case 0xd58: /* MMFR2. */
80
- return cpu->id_mmfr2;
81
+ return cpu->isar.id_mmfr2;
82
case 0xd5c: /* MMFR3. */
83
- return cpu->id_mmfr3;
84
+ return cpu->isar.id_mmfr3;
85
case 0xd60: /* ISAR0. */
86
return cpu->isar.id_isar0;
87
case 0xd64: /* ISAR1. */
88
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/cpu.c
91
+++ b/target/arm/cpu.c
92
@@ -XXX,XX +XXX,XX @@ static void arm1136_r2_initfn(Object *obj)
93
cpu->id_pfr1 = 0x1;
94
cpu->isar.id_dfr0 = 0x2;
95
cpu->id_afr0 = 0x3;
96
- cpu->id_mmfr0 = 0x01130003;
97
- cpu->id_mmfr1 = 0x10030302;
98
- cpu->id_mmfr2 = 0x01222110;
99
+ cpu->isar.id_mmfr0 = 0x01130003;
100
+ cpu->isar.id_mmfr1 = 0x10030302;
101
+ cpu->isar.id_mmfr2 = 0x01222110;
102
cpu->isar.id_isar0 = 0x00140011;
103
cpu->isar.id_isar1 = 0x12002111;
104
cpu->isar.id_isar2 = 0x11231111;
105
@@ -XXX,XX +XXX,XX @@ static void arm1136_initfn(Object *obj)
106
cpu->id_pfr1 = 0x1;
107
cpu->isar.id_dfr0 = 0x2;
108
cpu->id_afr0 = 0x3;
109
- cpu->id_mmfr0 = 0x01130003;
110
- cpu->id_mmfr1 = 0x10030302;
111
- cpu->id_mmfr2 = 0x01222110;
112
+ cpu->isar.id_mmfr0 = 0x01130003;
113
+ cpu->isar.id_mmfr1 = 0x10030302;
114
+ cpu->isar.id_mmfr2 = 0x01222110;
115
cpu->isar.id_isar0 = 0x00140011;
116
cpu->isar.id_isar1 = 0x12002111;
117
cpu->isar.id_isar2 = 0x11231111;
118
@@ -XXX,XX +XXX,XX @@ static void arm1176_initfn(Object *obj)
119
cpu->id_pfr1 = 0x11;
120
cpu->isar.id_dfr0 = 0x33;
121
cpu->id_afr0 = 0;
122
- cpu->id_mmfr0 = 0x01130003;
123
- cpu->id_mmfr1 = 0x10030302;
124
- cpu->id_mmfr2 = 0x01222100;
125
+ cpu->isar.id_mmfr0 = 0x01130003;
126
+ cpu->isar.id_mmfr1 = 0x10030302;
127
+ cpu->isar.id_mmfr2 = 0x01222100;
128
cpu->isar.id_isar0 = 0x0140011;
129
cpu->isar.id_isar1 = 0x12002111;
130
cpu->isar.id_isar2 = 0x11231121;
131
@@ -XXX,XX +XXX,XX @@ static void arm11mpcore_initfn(Object *obj)
132
cpu->id_pfr1 = 0x1;
133
cpu->isar.id_dfr0 = 0;
134
cpu->id_afr0 = 0x2;
135
- cpu->id_mmfr0 = 0x01100103;
136
- cpu->id_mmfr1 = 0x10020302;
137
- cpu->id_mmfr2 = 0x01222000;
138
+ cpu->isar.id_mmfr0 = 0x01100103;
139
+ cpu->isar.id_mmfr1 = 0x10020302;
140
+ cpu->isar.id_mmfr2 = 0x01222000;
141
cpu->isar.id_isar0 = 0x00100011;
142
cpu->isar.id_isar1 = 0x12002111;
143
cpu->isar.id_isar2 = 0x11221011;
144
@@ -XXX,XX +XXX,XX @@ static void cortex_m3_initfn(Object *obj)
145
cpu->id_pfr1 = 0x00000200;
146
cpu->isar.id_dfr0 = 0x00100000;
147
cpu->id_afr0 = 0x00000000;
148
- cpu->id_mmfr0 = 0x00000030;
149
- cpu->id_mmfr1 = 0x00000000;
150
- cpu->id_mmfr2 = 0x00000000;
151
- cpu->id_mmfr3 = 0x00000000;
152
+ cpu->isar.id_mmfr0 = 0x00000030;
153
+ cpu->isar.id_mmfr1 = 0x00000000;
154
+ cpu->isar.id_mmfr2 = 0x00000000;
155
+ cpu->isar.id_mmfr3 = 0x00000000;
156
cpu->isar.id_isar0 = 0x01141110;
157
cpu->isar.id_isar1 = 0x02111000;
158
cpu->isar.id_isar2 = 0x21112231;
159
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
160
cpu->id_pfr1 = 0x00000200;
161
cpu->isar.id_dfr0 = 0x00100000;
162
cpu->id_afr0 = 0x00000000;
163
- cpu->id_mmfr0 = 0x00000030;
164
- cpu->id_mmfr1 = 0x00000000;
165
- cpu->id_mmfr2 = 0x00000000;
166
- cpu->id_mmfr3 = 0x00000000;
167
+ cpu->isar.id_mmfr0 = 0x00000030;
168
+ cpu->isar.id_mmfr1 = 0x00000000;
169
+ cpu->isar.id_mmfr2 = 0x00000000;
170
+ cpu->isar.id_mmfr3 = 0x00000000;
171
cpu->isar.id_isar0 = 0x01141110;
172
cpu->isar.id_isar1 = 0x02111000;
173
cpu->isar.id_isar2 = 0x21112231;
174
@@ -XXX,XX +XXX,XX @@ static void cortex_m7_initfn(Object *obj)
175
cpu->id_pfr1 = 0x00000200;
176
cpu->isar.id_dfr0 = 0x00100000;
177
cpu->id_afr0 = 0x00000000;
178
- cpu->id_mmfr0 = 0x00100030;
179
- cpu->id_mmfr1 = 0x00000000;
180
- cpu->id_mmfr2 = 0x01000000;
181
- cpu->id_mmfr3 = 0x00000000;
182
+ cpu->isar.id_mmfr0 = 0x00100030;
183
+ cpu->isar.id_mmfr1 = 0x00000000;
184
+ cpu->isar.id_mmfr2 = 0x01000000;
185
+ cpu->isar.id_mmfr3 = 0x00000000;
186
cpu->isar.id_isar0 = 0x01101110;
187
cpu->isar.id_isar1 = 0x02112000;
188
cpu->isar.id_isar2 = 0x20232231;
189
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
190
cpu->id_pfr1 = 0x00000210;
191
cpu->isar.id_dfr0 = 0x00200000;
192
cpu->id_afr0 = 0x00000000;
193
- cpu->id_mmfr0 = 0x00101F40;
194
- cpu->id_mmfr1 = 0x00000000;
195
- cpu->id_mmfr2 = 0x01000000;
196
- cpu->id_mmfr3 = 0x00000000;
197
+ cpu->isar.id_mmfr0 = 0x00101F40;
198
+ cpu->isar.id_mmfr1 = 0x00000000;
199
+ cpu->isar.id_mmfr2 = 0x01000000;
200
+ cpu->isar.id_mmfr3 = 0x00000000;
201
cpu->isar.id_isar0 = 0x01101110;
202
cpu->isar.id_isar1 = 0x02212000;
203
cpu->isar.id_isar2 = 0x20232232;
204
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
205
cpu->id_pfr1 = 0x001;
206
cpu->isar.id_dfr0 = 0x010400;
207
cpu->id_afr0 = 0x0;
208
- cpu->id_mmfr0 = 0x0210030;
209
- cpu->id_mmfr1 = 0x00000000;
210
- cpu->id_mmfr2 = 0x01200000;
211
- cpu->id_mmfr3 = 0x0211;
212
+ cpu->isar.id_mmfr0 = 0x0210030;
213
+ cpu->isar.id_mmfr1 = 0x00000000;
214
+ cpu->isar.id_mmfr2 = 0x01200000;
215
+ cpu->isar.id_mmfr3 = 0x0211;
216
cpu->isar.id_isar0 = 0x02101111;
217
cpu->isar.id_isar1 = 0x13112111;
218
cpu->isar.id_isar2 = 0x21232141;
219
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
220
cpu->id_pfr1 = 0x11;
221
cpu->isar.id_dfr0 = 0x400;
222
cpu->id_afr0 = 0;
223
- cpu->id_mmfr0 = 0x31100003;
224
- cpu->id_mmfr1 = 0x20000000;
225
- cpu->id_mmfr2 = 0x01202000;
226
- cpu->id_mmfr3 = 0x11;
227
+ cpu->isar.id_mmfr0 = 0x31100003;
228
+ cpu->isar.id_mmfr1 = 0x20000000;
229
+ cpu->isar.id_mmfr2 = 0x01202000;
230
+ cpu->isar.id_mmfr3 = 0x11;
231
cpu->isar.id_isar0 = 0x00101111;
232
cpu->isar.id_isar1 = 0x12112111;
233
cpu->isar.id_isar2 = 0x21232031;
234
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
235
cpu->id_pfr1 = 0x11;
236
cpu->isar.id_dfr0 = 0x000;
237
cpu->id_afr0 = 0;
238
- cpu->id_mmfr0 = 0x00100103;
239
- cpu->id_mmfr1 = 0x20000000;
240
- cpu->id_mmfr2 = 0x01230000;
241
- cpu->id_mmfr3 = 0x00002111;
242
+ cpu->isar.id_mmfr0 = 0x00100103;
243
+ cpu->isar.id_mmfr1 = 0x20000000;
244
+ cpu->isar.id_mmfr2 = 0x01230000;
245
+ cpu->isar.id_mmfr3 = 0x00002111;
246
cpu->isar.id_isar0 = 0x00101111;
247
cpu->isar.id_isar1 = 0x13112111;
248
cpu->isar.id_isar2 = 0x21232041;
249
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
250
cpu->id_pfr1 = 0x00011011;
251
cpu->isar.id_dfr0 = 0x02010555;
252
cpu->id_afr0 = 0x00000000;
253
- cpu->id_mmfr0 = 0x10101105;
254
- cpu->id_mmfr1 = 0x40000000;
255
- cpu->id_mmfr2 = 0x01240000;
256
- cpu->id_mmfr3 = 0x02102211;
257
+ cpu->isar.id_mmfr0 = 0x10101105;
258
+ cpu->isar.id_mmfr1 = 0x40000000;
259
+ cpu->isar.id_mmfr2 = 0x01240000;
260
+ cpu->isar.id_mmfr3 = 0x02102211;
261
/* a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
262
* table 4-41 gives 0x02101110, which includes the arm div insns.
263
*/
264
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
265
cpu->id_pfr1 = 0x00011011;
266
cpu->isar.id_dfr0 = 0x02010555;
267
cpu->id_afr0 = 0x00000000;
268
- cpu->id_mmfr0 = 0x10201105;
269
- cpu->id_mmfr1 = 0x20000000;
270
- cpu->id_mmfr2 = 0x01240000;
271
- cpu->id_mmfr3 = 0x02102211;
272
+ cpu->isar.id_mmfr0 = 0x10201105;
273
+ cpu->isar.id_mmfr1 = 0x20000000;
274
+ cpu->isar.id_mmfr2 = 0x01240000;
275
+ cpu->isar.id_mmfr3 = 0x02102211;
276
cpu->isar.id_isar0 = 0x02101110;
277
cpu->isar.id_isar1 = 0x13112111;
278
cpu->isar.id_isar2 = 0x21232041;
279
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
280
t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
281
cpu->isar.mvfr2 = t;
282
283
- t = cpu->id_mmfr3;
284
+ t = cpu->isar.id_mmfr3;
285
t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
286
- cpu->id_mmfr3 = t;
287
+ cpu->isar.id_mmfr3 = t;
288
289
- t = cpu->id_mmfr4;
290
+ t = cpu->isar.id_mmfr4;
291
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
292
- cpu->id_mmfr4 = t;
293
+ cpu->isar.id_mmfr4 = t;
294
}
295
#endif
296
}
297
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
298
index XXXXXXX..XXXXXXX 100644
299
--- a/target/arm/cpu64.c
300
+++ b/target/arm/cpu64.c
301
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
302
cpu->id_pfr1 = 0x00011011;
303
cpu->isar.id_dfr0 = 0x03010066;
304
cpu->id_afr0 = 0x00000000;
305
- cpu->id_mmfr0 = 0x10101105;
306
- cpu->id_mmfr1 = 0x40000000;
307
- cpu->id_mmfr2 = 0x01260000;
308
- cpu->id_mmfr3 = 0x02102211;
309
+ cpu->isar.id_mmfr0 = 0x10101105;
310
+ cpu->isar.id_mmfr1 = 0x40000000;
311
+ cpu->isar.id_mmfr2 = 0x01260000;
312
+ cpu->isar.id_mmfr3 = 0x02102211;
313
cpu->isar.id_isar0 = 0x02101110;
314
cpu->isar.id_isar1 = 0x13112111;
315
cpu->isar.id_isar2 = 0x21232042;
316
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
317
cpu->id_pfr1 = 0x00011011;
318
cpu->isar.id_dfr0 = 0x03010066;
319
cpu->id_afr0 = 0x00000000;
320
- cpu->id_mmfr0 = 0x10101105;
321
- cpu->id_mmfr1 = 0x40000000;
322
- cpu->id_mmfr2 = 0x01260000;
323
- cpu->id_mmfr3 = 0x02102211;
324
+ cpu->isar.id_mmfr0 = 0x10101105;
325
+ cpu->isar.id_mmfr1 = 0x40000000;
326
+ cpu->isar.id_mmfr2 = 0x01260000;
327
+ cpu->isar.id_mmfr3 = 0x02102211;
328
cpu->isar.id_isar0 = 0x02101110;
329
cpu->isar.id_isar1 = 0x13112111;
330
cpu->isar.id_isar2 = 0x21232042;
331
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
332
cpu->id_pfr1 = 0x00011011;
333
cpu->isar.id_dfr0 = 0x03010066;
334
cpu->id_afr0 = 0x00000000;
335
- cpu->id_mmfr0 = 0x10201105;
336
- cpu->id_mmfr1 = 0x40000000;
337
- cpu->id_mmfr2 = 0x01260000;
338
- cpu->id_mmfr3 = 0x02102211;
339
+ cpu->isar.id_mmfr0 = 0x10201105;
340
+ cpu->isar.id_mmfr1 = 0x40000000;
341
+ cpu->isar.id_mmfr2 = 0x01260000;
342
+ cpu->isar.id_mmfr3 = 0x02102211;
343
cpu->isar.id_isar0 = 0x02101110;
344
cpu->isar.id_isar1 = 0x13112111;
345
cpu->isar.id_isar2 = 0x21232042;
346
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
347
u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1);
348
cpu->isar.id_isar6 = u;
349
350
- u = cpu->id_mmfr3;
351
+ u = cpu->isar.id_mmfr3;
352
u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */
353
- cpu->id_mmfr3 = u;
354
+ cpu->isar.id_mmfr3 = u;
355
356
u = cpu->isar.id_aa64dfr0;
357
u = FIELD_DP64(u, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
358
diff --git a/target/arm/helper.c b/target/arm/helper.c
359
index XXXXXXX..XXXXXXX 100644
360
--- a/target/arm/helper.c
361
+++ b/target/arm/helper.c
362
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
363
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 4,
364
.access = PL1_R, .type = ARM_CP_CONST,
365
.accessfn = access_aa32_tid3,
366
- .resetvalue = cpu->id_mmfr0 },
367
+ .resetvalue = cpu->isar.id_mmfr0 },
368
{ .name = "ID_MMFR1", .state = ARM_CP_STATE_BOTH,
369
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 5,
370
.access = PL1_R, .type = ARM_CP_CONST,
371
.accessfn = access_aa32_tid3,
372
- .resetvalue = cpu->id_mmfr1 },
373
+ .resetvalue = cpu->isar.id_mmfr1 },
374
{ .name = "ID_MMFR2", .state = ARM_CP_STATE_BOTH,
375
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 6,
376
.access = PL1_R, .type = ARM_CP_CONST,
377
.accessfn = access_aa32_tid3,
378
- .resetvalue = cpu->id_mmfr2 },
379
+ .resetvalue = cpu->isar.id_mmfr2 },
380
{ .name = "ID_MMFR3", .state = ARM_CP_STATE_BOTH,
381
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 7,
382
.access = PL1_R, .type = ARM_CP_CONST,
383
.accessfn = access_aa32_tid3,
384
- .resetvalue = cpu->id_mmfr3 },
385
+ .resetvalue = cpu->isar.id_mmfr3 },
386
{ .name = "ID_ISAR0", .state = ARM_CP_STATE_BOTH,
387
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
388
.access = PL1_R, .type = ARM_CP_CONST,
389
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
390
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6,
391
.access = PL1_R, .type = ARM_CP_CONST,
392
.accessfn = access_aa32_tid3,
393
- .resetvalue = cpu->id_mmfr4 },
394
+ .resetvalue = cpu->isar.id_mmfr4 },
395
{ .name = "ID_ISAR6", .state = ARM_CP_STATE_BOTH,
396
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7,
397
.access = PL1_R, .type = ARM_CP_CONST,
398
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
399
define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo);
400
define_arm_cp_regs(cpu, vmsa_cp_reginfo);
401
/* TTCBR2 is introduced with ARMv8.2-A32HPD. */
402
- if (FIELD_EX32(cpu->id_mmfr4, ID_MMFR4, HPDS) != 0) {
403
+ if (FIELD_EX32(cpu->isar.id_mmfr4, ID_MMFR4, HPDS) != 0) {
404
define_one_arm_cp_reg(cpu, &ttbcr2_reginfo);
405
}
406
}
407
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
408
index XXXXXXX..XXXXXXX 100644
409
--- a/target/arm/kvm32.c
410
+++ b/target/arm/kvm32.c
411
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
412
* Fortunately there is not yet anything in there that affects migration.
413
*/
414
415
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0,
416
+ ARM_CP15_REG32(0, 0, 1, 4));
417
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr1,
418
+ ARM_CP15_REG32(0, 0, 1, 5));
419
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr2,
420
+ ARM_CP15_REG32(0, 0, 1, 6));
421
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr3,
422
+ ARM_CP15_REG32(0, 0, 1, 7));
423
+ if (read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr4,
424
+ ARM_CP15_REG32(0, 0, 2, 6))) {
425
+ /*
426
+ * Older kernels don't support reading ID_MMFR4 (a new in v8
427
+ * register); assume it's zero.
428
+ */
429
+ ahcf->isar.id_mmfr4 = 0;
430
+ }
431
+
432
/*
433
* There is no way to read DBGDIDR, because currently 32-bit KVM
434
* doesn't implement debug at all. Leave it at zero.
435
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
436
index XXXXXXX..XXXXXXX 100644
437
--- a/target/arm/kvm64.c
438
+++ b/target/arm/kvm64.c
439
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
440
*/
441
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0,
442
ARM64_SYS_REG(3, 0, 0, 1, 2));
443
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0,
444
+ ARM64_SYS_REG(3, 0, 0, 1, 4));
445
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr1,
446
+ ARM64_SYS_REG(3, 0, 0, 1, 5));
447
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr2,
448
+ ARM64_SYS_REG(3, 0, 0, 1, 6));
449
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr3,
450
+ ARM64_SYS_REG(3, 0, 0, 1, 7));
451
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar0,
452
ARM64_SYS_REG(3, 0, 0, 2, 0));
453
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar1,
454
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
455
ARM64_SYS_REG(3, 0, 0, 2, 4));
456
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar5,
457
ARM64_SYS_REG(3, 0, 0, 2, 5));
458
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr4,
459
+ ARM64_SYS_REG(3, 0, 0, 2, 6));
460
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar6,
461
ARM64_SYS_REG(3, 0, 0, 2, 7));
462
463
--
464
2.20.1
465
466
diff view generated by jsdifflib
Deleted patch
1
Now we have moved ID_MMFR4 into the ARMISARegisters struct, we
2
can define and use an isar_feature for the presence of the
3
ARMv8.2-AA32HPD feature, rather than open-coding the test.
4
1
5
While we're here, correct a comment typo which missed an 'A'
6
from the feature name.
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20200214175116.9164-20-peter.maydell@linaro.org
11
---
12
target/arm/cpu.h | 5 +++++
13
target/arm/helper.c | 4 ++--
14
2 files changed, 7 insertions(+), 2 deletions(-)
15
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_pmu_8_4(const ARMISARegisters *id)
21
FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
22
}
23
24
+static inline bool isar_feature_aa32_hpd(const ARMISARegisters *id)
25
+{
26
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, HPDS) != 0;
27
+}
28
+
29
/*
30
* 64-bit feature tests via id registers.
31
*/
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/helper.c
35
+++ b/target/arm/helper.c
36
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
37
} else {
38
define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo);
39
define_arm_cp_regs(cpu, vmsa_cp_reginfo);
40
- /* TTCBR2 is introduced with ARMv8.2-A32HPD. */
41
- if (FIELD_EX32(cpu->isar.id_mmfr4, ID_MMFR4, HPDS) != 0) {
42
+ /* TTCBR2 is introduced with ARMv8.2-AA32HPD. */
43
+ if (cpu_isar_feature(aa32_hpd, cpu)) {
44
define_one_arm_cp_reg(cpu, &ttbcr2_reginfo);
45
}
46
}
47
--
48
2.20.1
49
50
diff view generated by jsdifflib
Deleted patch
1
From: Guenter Roeck <linux@roeck-us.net>
2
1
3
We need to be able to use OHCISysBusState outside hcd-ohci.c, so move it
4
to its include file.
5
6
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
7
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
8
Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com>
9
Message-id: 20200217204812.9857-2-linux@roeck-us.net
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/usb/hcd-ohci.h | 16 ++++++++++++++++
13
hw/usb/hcd-ohci.c | 15 ---------------
14
2 files changed, 16 insertions(+), 15 deletions(-)
15
16
diff --git a/hw/usb/hcd-ohci.h b/hw/usb/hcd-ohci.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/usb/hcd-ohci.h
19
+++ b/hw/usb/hcd-ohci.h
20
@@ -XXX,XX +XXX,XX @@
21
#define HCD_OHCI_H
22
23
#include "sysemu/dma.h"
24
+#include "hw/usb.h"
25
26
/* Number of Downstream Ports on the root hub: */
27
#define OHCI_MAX_PORTS 15
28
@@ -XXX,XX +XXX,XX @@ typedef struct OHCIState {
29
void (*ohci_die)(struct OHCIState *ohci);
30
} OHCIState;
31
32
+#define TYPE_SYSBUS_OHCI "sysbus-ohci"
33
+#define SYSBUS_OHCI(obj) OBJECT_CHECK(OHCISysBusState, (obj), TYPE_SYSBUS_OHCI)
34
+
35
+typedef struct {
36
+ /*< private >*/
37
+ SysBusDevice parent_obj;
38
+ /*< public >*/
39
+
40
+ OHCIState ohci;
41
+ char *masterbus;
42
+ uint32_t num_ports;
43
+ uint32_t firstport;
44
+ dma_addr_t dma_offset;
45
+} OHCISysBusState;
46
+
47
extern const VMStateDescription vmstate_ohci_state;
48
49
void usb_ohci_init(OHCIState *ohci, DeviceState *dev, uint32_t num_ports,
50
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/usb/hcd-ohci.c
53
+++ b/hw/usb/hcd-ohci.c
54
@@ -XXX,XX +XXX,XX @@ void ohci_sysbus_die(struct OHCIState *ohci)
55
ohci_bus_stop(ohci);
56
}
57
58
-#define TYPE_SYSBUS_OHCI "sysbus-ohci"
59
-#define SYSBUS_OHCI(obj) OBJECT_CHECK(OHCISysBusState, (obj), TYPE_SYSBUS_OHCI)
60
-
61
-typedef struct {
62
- /*< private >*/
63
- SysBusDevice parent_obj;
64
- /*< public >*/
65
-
66
- OHCIState ohci;
67
- char *masterbus;
68
- uint32_t num_ports;
69
- uint32_t firstport;
70
- dma_addr_t dma_offset;
71
-} OHCISysBusState;
72
-
73
static void ohci_realize_pxa(DeviceState *dev, Error **errp)
74
{
75
OHCISysBusState *s = SYSBUS_OHCI(dev);
76
--
77
2.20.1
78
79
diff view generated by jsdifflib
Deleted patch
1
From: Guenter Roeck <linux@roeck-us.net>
2
1
3
We'll use this property in a follow-up patch to insantiate an EHCI
4
bus with companion support.
5
6
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
7
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
8
Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com>
9
Message-id: 20200217204812.9857-3-linux@roeck-us.net
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/usb/hcd-ehci-sysbus.c | 2 ++
13
1 file changed, 2 insertions(+)
14
15
diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/usb/hcd-ehci-sysbus.c
18
+++ b/hw/usb/hcd-ehci-sysbus.c
19
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_ehci_sysbus = {
20
21
static Property ehci_sysbus_properties[] = {
22
DEFINE_PROP_UINT32("maxframes", EHCISysBusState, ehci.maxframes, 128),
23
+ DEFINE_PROP_BOOL("companion-enable", EHCISysBusState, ehci.companion_enable,
24
+ false),
25
DEFINE_PROP_END_OF_LIST(),
26
};
27
28
--
29
2.20.1
30
31
diff view generated by jsdifflib
Deleted patch
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
2
1
3
Correct the number of dummy cycles required by the FAST_READ_4 command (to
4
be eight, one dummy byte).
5
6
Fixes: ef06ca3946 ("xilinx_spips: Add support for RX discard and RX drain")
7
Suggested-by: Cédric Le Goater <clg@kaod.org>
8
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
9
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Message-id: 20200218113350.6090-1-frasse.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/ssi/xilinx_spips.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/ssi/xilinx_spips.c
19
+++ b/hw/ssi/xilinx_spips.c
20
@@ -XXX,XX +XXX,XX @@ static int xilinx_spips_num_dummies(XilinxQSPIPS *qs, uint8_t command)
21
case FAST_READ:
22
case DOR:
23
case QOR:
24
+ case FAST_READ_4:
25
case DOR_4:
26
case QOR_4:
27
return 1;
28
case DIOR:
29
- case FAST_READ_4:
30
case DIOR_4:
31
return 2;
32
case QIOR:
33
--
34
2.20.1
35
36
diff view generated by jsdifflib
Deleted patch
1
From: Guenter Roeck <linux@roeck-us.net>
2
1
3
Booting the r2d machine from flash fails because flash is not discovered.
4
Looking at the flattened memory tree, we see the following.
5
6
FlatView #1
7
AS "memory", root: system
8
AS "cpu-memory-0", root: system
9
AS "sh_pci_host", root: bus master container
10
Root memory region: system
11
0000000000000000-000000000000ffff (prio 0, i/o): io
12
0000000000010000-0000000000ffffff (prio 0, i/o): r2d.flash @0000000000010000
13
14
The overlapping memory region is sh_pci.isa, ie the ISA I/O region bridge.
15
This region is initially assigned to address 0xfe240000, but overwritten
16
with a write into the PCIIOBR register. This write is expected to adjust
17
the PCI memory window, but not to change the region's base adddress.
18
19
Peter Maydell provided the following detailed explanation.
20
21
"Section 22.3.7 and in particular figure 22.3 (of "SSH7751R user's manual:
22
hardware") are clear about how this is supposed to work: there is a window
23
at 0xfe240000 in the system register space for PCI I/O space. When the CPU
24
makes an access into that area, the PCI controller calculates the PCI
25
address to use by combining bits 0..17 of the system address with the
26
bits 31..18 value that the guest has put into the PCIIOBR. That is, writing
27
to the PCIIOBR changes which section of the IO address space is visible in
28
the 0xfe240000 window. Instead what QEMU's implementation does is move the
29
window to whatever value the guest writes to the PCIIOBR register -- so if
30
the guest writes 0 we put the window at 0 in system address space."
31
32
Fix the problem by calling memory_region_set_alias_offset() instead of
33
removing and re-adding the PCI ISA subregion on writes into PCIIOBR.
34
At the same time, in sh_pci_device_realize(), don't set iobr since
35
it is overwritten later anyway. Instead, pass the base address to
36
memory_region_add_subregion() directly.
37
38
Many thanks to Peter Maydell for the detailed problem analysis, and for
39
providing suggestions on how to fix the problem.
40
41
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
42
Message-id: 20200218201050.15273-1-linux@roeck-us.net
43
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
44
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
45
---
46
hw/sh4/sh_pci.c | 11 +++--------
47
1 file changed, 3 insertions(+), 8 deletions(-)
48
49
diff --git a/hw/sh4/sh_pci.c b/hw/sh4/sh_pci.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/sh4/sh_pci.c
52
+++ b/hw/sh4/sh_pci.c
53
@@ -XXX,XX +XXX,XX @@ static void sh_pci_reg_write (void *p, hwaddr addr, uint64_t val,
54
pcic->mbr = val & 0xff000001;
55
break;
56
case 0x1c8:
57
- if ((val & 0xfffc0000) != (pcic->iobr & 0xfffc0000)) {
58
- memory_region_del_subregion(get_system_memory(), &pcic->isa);
59
- pcic->iobr = val & 0xfffc0001;
60
- memory_region_add_subregion(get_system_memory(),
61
- pcic->iobr & 0xfffc0000, &pcic->isa);
62
- }
63
+ pcic->iobr = val & 0xfffc0001;
64
+ memory_region_set_alias_offset(&pcic->isa, val & 0xfffc0000);
65
break;
66
case 0x220:
67
pci_data_write(phb->bus, pcic->par, val, 4);
68
@@ -XXX,XX +XXX,XX @@ static void sh_pci_device_realize(DeviceState *dev, Error **errp)
69
get_system_io(), 0, 0x40000);
70
sysbus_init_mmio(sbd, &s->memconfig_p4);
71
sysbus_init_mmio(sbd, &s->memconfig_a7);
72
- s->iobr = 0xfe240000;
73
- memory_region_add_subregion(get_system_memory(), s->iobr, &s->isa);
74
+ memory_region_add_subregion(get_system_memory(), 0xfe240000, &s->isa);
75
76
s->dev = pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "sh_pci_host");
77
}
78
--
79
2.20.1
80
81
diff view generated by jsdifflib