1
Mostly my FEAT_NV/NV2 stuff, but some other smaller series too.
1
This one's almost all docs fixes.
2
2
3
thanks
3
-- PMM
4
-- PMM
4
5
5
The following changes since commit 9468484fe904ab4691de6d9c34616667f377ceac:
6
The following changes since commit ba54a7e6b86884e43bed2d2f5a79c719059652a8:
6
7
7
Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into staging (2024-01-09 10:32:23 +0000)
8
Merge tag 'net-pull-request' of https://github.com/jasowang/qemu into staging (2024-11-26 14:06:40 +0000)
8
9
9
are available in the Git repository at:
10
are available in the Git repository at:
10
11
11
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240111
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20241126
12
13
13
for you to fetch changes up to e2862554c257e908a3833265e38365e794abd362:
14
for you to fetch changes up to d8790ead55a2ef1e65332ebec63ae3c5db598942:
14
15
15
target/arm: Add FEAT_NV2 to max, neoverse-n2, neoverse-v1 CPUs (2024-01-09 14:44:45 +0000)
16
docs/system/arm/aspeed: add missing model supermicrox11spi-bmc (2024-11-26 16:22:38 +0000)
16
17
17
----------------------------------------------------------------
18
----------------------------------------------------------------
18
target-arm queue:
19
target-arm queue:
19
* Emulate FEAT_NV, FEAT_NV2
20
* target/arm/tcg/cpu32.c: swap ATCM and BTCM register names
20
* add cache controller for Freescale i.MX6
21
* docs/system/arm: Fix broken links and missing feature names
21
* Add minimal support for the B-L475E-IOT01A board
22
* Allow SoC models to configure M-profile CPUs with correct number
23
of NVIC priority bits
24
* Add missing QOM parent for v7-M SoCs
25
* Set CTR_EL0.{IDC,DIC} for the 'max' CPU
26
* hw/intc/arm_gicv3_cpuif: handle LPIs in in the list registers
27
22
28
----------------------------------------------------------------
23
----------------------------------------------------------------
29
Inès Varhol (2):
24
Michael Tokarev (1):
30
hw/arm: Add minimal support for the STM32L4x5 SoC
25
target/arm/tcg/cpu32.c: swap ATCM and BTCM register names
31
hw/arm: Add minimal support for the B-L475E-IOT01A board
32
26
33
Nikita Ostrenkov (1):
27
Pierrick Bouvier (8):
34
hw/arm: add cache controller for Freescale i.MX6
28
docs/system/arm/emulation: mention armv9
29
docs/system/arm/emulation: fix typo in feature name
30
docs/system/arm/emulation: add FEAT_SSBS2
31
target/arm/tcg/: fix typo in FEAT name
32
docs/system/arm/: add FEAT_MTE_ASYNC
33
docs/system/arm/: add FEAT_DoubleLock
34
docs/system/arm/fby35: update link to product page
35
docs/system/arm/aspeed: add missing model supermicrox11spi-bmc
35
36
36
Peter Maydell (34):
37
docs/system/arm/aspeed.rst | 7 ++++---
37
target/arm: Set CTR_EL0.{IDC,DIC} for the 'max' CPU
38
docs/system/arm/emulation.rst | 11 +++++++----
38
hw/intc/arm_gicv3_cpuif: handle LPIs in in the list registers
39
docs/system/arm/fby35.rst | 2 +-
39
target/arm: Handle HCR_EL2 accesses for bits introduced with FEAT_NV
40
target/arm/tcg/cpu32.c | 6 +++---
40
target/arm: Implement HCR_EL2.AT handling
41
4 files changed, 15 insertions(+), 11 deletions(-)
41
target/arm: Enable trapping of ERET for FEAT_NV
42
target/arm: Always honour HCR_EL2.TSC when HCR_EL2.NV is set
43
target/arm: Allow use of upper 32 bits of TBFLAG_A64
44
target/arm: Record correct opcode fields in cpreg for E2H aliases
45
target/arm: *_EL12 registers should UNDEF when HCR_EL2.E2H is 0
46
target/arm: Make EL2 cpreg accessfns safe for FEAT_NV EL1 accesses
47
target/arm: Move FPU/SVE/SME access checks up above ARM_CP_SPECIAL_MASK check
48
target/arm: Trap sysreg accesses for FEAT_NV
49
target/arm: Make NV reads of CurrentEL return EL2
50
target/arm: Set SPSR_EL1.M correctly when nested virt is enabled
51
target/arm: Trap registers when HCR_EL2.{NV, NV1} == {1, 1}
52
target/arm: Always use arm_pan_enabled() when checking if PAN is enabled
53
target/arm: Don't honour PSTATE.PAN when HCR_EL2.{NV, NV1} == {1, 1}
54
target/arm: Treat LDTR* and STTR* as LDR/STR when NV, NV1 is 1, 1
55
target/arm: Handle FEAT_NV page table attribute changes
56
target/arm: Add FEAT_NV to max, neoverse-n2, neoverse-v1 CPUs
57
target/arm: Handle HCR_EL2 accesses for FEAT_NV2 bits
58
target/arm: Implement VNCR_EL2 register
59
target/arm: Handle FEAT_NV2 changes to when SPSR_EL1.M reports EL2
60
target/arm: Handle FEAT_NV2 redirection of SPSR_EL2, ELR_EL2, ESR_EL2, FAR_EL2
61
target/arm: Implement FEAT_NV2 redirection of sysregs to RAM
62
target/arm: Report VNCR_EL2 based faults correctly
63
target/arm: Mark up VNCR offsets (offsets 0x0..0xff)
64
target/arm: Mark up VNCR offsets (offsets 0x100..0x160)
65
target/arm: Mark up VNCR offsets (offsets 0x168..0x1f8)
66
target/arm: Mark up VNCR offsets (offsets >= 0x200, except GIC)
67
hw/intc/arm_gicv3_cpuif: Mark up VNCR offsets for GIC CPU registers
68
target/arm: Report HCR_EL2.{NV,NV1,NV2} in cpu dumps
69
target/arm: Enhance CPU_LOG_INT to show SPSR on AArch64 exception-entry
70
target/arm: Add FEAT_NV2 to max, neoverse-n2, neoverse-v1 CPUs
71
72
Philippe Mathieu-Daudé (1):
73
hw/arm: Add missing QOM parent for v7-M SoCs
74
75
Samuel Tardieu (3):
76
hw/intc/armv7m_nvic: add "num-prio-bits" property
77
hw/arm/armv7m: alias the NVIC "num-prio-bits" property
78
hw/arm/socs: configure priority bits for existing SOCs
79
80
MAINTAINERS | 15 ++
81
docs/system/arm/b-l475e-iot01a.rst | 46 +++++
82
docs/system/arm/emulation.rst | 2 +
83
docs/system/arm/stm32.rst | 6 +-
84
docs/system/target-arm.rst | 1 +
85
configs/devices/arm-softmmu/default.mak | 1 +
86
include/hw/arm/armv7m.h | 1 +
87
include/hw/arm/stm32l4x5_soc.h | 57 ++++++
88
target/arm/cpregs.h | 54 +++++-
89
target/arm/cpu-features.h | 10 +
90
target/arm/cpu.h | 24 ++-
91
target/arm/syndrome.h | 20 +-
92
target/arm/tcg/translate.h | 16 +-
93
hw/arm/armv7m.c | 2 +
94
hw/arm/b-l475e-iot01a.c | 72 +++++++
95
hw/arm/fsl-imx6.c | 3 +
96
hw/arm/msf2-som.c | 1 +
97
hw/arm/netduino2.c | 1 +
98
hw/arm/netduinoplus2.c | 1 +
99
hw/arm/olimex-stm32-h405.c | 1 +
100
hw/arm/stellaris.c | 2 +
101
hw/arm/stm32f100_soc.c | 1 +
102
hw/arm/stm32f205_soc.c | 1 +
103
hw/arm/stm32f405_soc.c | 1 +
104
hw/arm/stm32l4x5_soc.c | 266 ++++++++++++++++++++++++++
105
hw/arm/stm32vldiscovery.c | 1 +
106
hw/intc/arm_gicv3_cpuif.c | 28 ++-
107
hw/intc/armv7m_nvic.c | 23 ++-
108
target/arm/cpu.c | 8 +-
109
target/arm/debug_helper.c | 13 +-
110
target/arm/helper.c | 326 +++++++++++++++++++++++++++++---
111
target/arm/ptw.c | 21 ++
112
target/arm/tcg/cpu64.c | 11 ++
113
target/arm/tcg/hflags.c | 30 ++-
114
target/arm/tcg/op_helper.c | 16 +-
115
target/arm/tcg/tlb_helper.c | 27 ++-
116
target/arm/tcg/translate-a64.c | 160 ++++++++++++++--
117
hw/arm/Kconfig | 12 ++
118
hw/arm/meson.build | 2 +
119
39 files changed, 1203 insertions(+), 80 deletions(-)
120
create mode 100644 docs/system/arm/b-l475e-iot01a.rst
121
create mode 100644 include/hw/arm/stm32l4x5_soc.h
122
create mode 100644 hw/arm/b-l475e-iot01a.c
123
create mode 100644 hw/arm/stm32l4x5_soc.c
124
diff view generated by jsdifflib
Deleted patch
1
From: Nikita Ostrenkov <n.ostrenkov@gmail.com>
2
1
3
Signed-off-by: Nikita Ostrenkov <n.ostrenkov@gmail.com>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-id: 20231219105510.4907-1-n.ostrenkov@gmail.com
6
[PMM: fixed stray whitespace]
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
hw/arm/fsl-imx6.c | 3 +++
10
hw/arm/Kconfig | 1 +
11
2 files changed, 4 insertions(+)
12
13
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/fsl-imx6.c
16
+++ b/hw/arm/fsl-imx6.c
17
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
18
qdev_get_gpio_in(DEVICE(&s->cpu[i]), ARM_CPU_FIQ));
19
}
20
21
+ /* L2 cache controller */
22
+ sysbus_create_simple("l2x0", FSL_IMX6_PL310_ADDR, NULL);
23
+
24
if (!sysbus_realize(SYS_BUS_DEVICE(&s->ccm), errp)) {
25
return;
26
}
27
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/Kconfig
30
+++ b/hw/arm/Kconfig
31
@@ -XXX,XX +XXX,XX @@ config FSL_IMX6
32
select IMX_I2C
33
select IMX_USBPHY
34
select WDT_IMX2
35
+ select PL310 # cache controller
36
select SDHCI
37
38
config ASPEED_SOC
39
--
40
2.34.1
41
42
diff view generated by jsdifflib
Deleted patch
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
1
3
This patch adds a new STM32L4x5 SoC, it is necessary to add support for
4
the B-L475E-IOT01A board.
5
The implementation is derived from the STM32F405 SoC.
6
The implementation contains no peripherals, only memory regions are
7
implemented.
8
9
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Acked-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
13
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
14
Message-id: 20240108135849.351719-2-ines.varhol@telecom-paris.fr
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
MAINTAINERS | 8 +
18
include/hw/arm/stm32l4x5_soc.h | 57 +++++++
19
hw/arm/stm32l4x5_soc.c | 265 +++++++++++++++++++++++++++++++++
20
hw/arm/Kconfig | 5 +
21
hw/arm/meson.build | 1 +
22
5 files changed, 336 insertions(+)
23
create mode 100644 include/hw/arm/stm32l4x5_soc.h
24
create mode 100644 hw/arm/stm32l4x5_soc.c
25
26
diff --git a/MAINTAINERS b/MAINTAINERS
27
index XXXXXXX..XXXXXXX 100644
28
--- a/MAINTAINERS
29
+++ b/MAINTAINERS
30
@@ -XXX,XX +XXX,XX @@ L: qemu-arm@nongnu.org
31
S: Maintained
32
F: hw/arm/olimex-stm32-h405.c
33
34
+STM32L4x5 SoC Family
35
+M: Arnaud Minier <arnaud.minier@telecom-paris.fr>
36
+M: Inès Varhol <ines.varhol@telecom-paris.fr>
37
+L: qemu-arm@nongnu.org
38
+S: Maintained
39
+F: hw/arm/stm32l4x5_soc.c
40
+F: include/hw/arm/stm32l4x5_soc.h
41
+
42
SmartFusion2
43
M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
44
M: Peter Maydell <peter.maydell@linaro.org>
45
diff --git a/include/hw/arm/stm32l4x5_soc.h b/include/hw/arm/stm32l4x5_soc.h
46
new file mode 100644
47
index XXXXXXX..XXXXXXX
48
--- /dev/null
49
+++ b/include/hw/arm/stm32l4x5_soc.h
50
@@ -XXX,XX +XXX,XX @@
51
+/*
52
+ * STM32L4x5 SoC family
53
+ *
54
+ * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
55
+ * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
56
+ *
57
+ * SPDX-License-Identifier: GPL-2.0-or-later
58
+ *
59
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
60
+ * See the COPYING file in the top-level directory.
61
+ *
62
+ * This work is heavily inspired by the stm32f405_soc by Alistair Francis.
63
+ * Original code is licensed under the MIT License:
64
+ *
65
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
66
+ */
67
+
68
+/*
69
+ * The reference used is the STMicroElectronics RM0351 Reference manual
70
+ * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
71
+ * https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html
72
+ */
73
+
74
+#ifndef HW_ARM_STM32L4x5_SOC_H
75
+#define HW_ARM_STM32L4x5_SOC_H
76
+
77
+#include "exec/memory.h"
78
+#include "hw/arm/armv7m.h"
79
+#include "qom/object.h"
80
+
81
+#define TYPE_STM32L4X5_SOC "stm32l4x5-soc"
82
+#define TYPE_STM32L4X5XC_SOC "stm32l4x5xc-soc"
83
+#define TYPE_STM32L4X5XE_SOC "stm32l4x5xe-soc"
84
+#define TYPE_STM32L4X5XG_SOC "stm32l4x5xg-soc"
85
+OBJECT_DECLARE_TYPE(Stm32l4x5SocState, Stm32l4x5SocClass, STM32L4X5_SOC)
86
+
87
+struct Stm32l4x5SocState {
88
+ SysBusDevice parent_obj;
89
+
90
+ ARMv7MState armv7m;
91
+
92
+ MemoryRegion sram1;
93
+ MemoryRegion sram2;
94
+ MemoryRegion flash;
95
+ MemoryRegion flash_alias;
96
+
97
+ Clock *sysclk;
98
+ Clock *refclk;
99
+};
100
+
101
+struct Stm32l4x5SocClass {
102
+ SysBusDeviceClass parent_class;
103
+
104
+ size_t flash_size;
105
+};
106
+
107
+#endif
108
diff --git a/hw/arm/stm32l4x5_soc.c b/hw/arm/stm32l4x5_soc.c
109
new file mode 100644
110
index XXXXXXX..XXXXXXX
111
--- /dev/null
112
+++ b/hw/arm/stm32l4x5_soc.c
113
@@ -XXX,XX +XXX,XX @@
114
+/*
115
+ * STM32L4x5 SoC family
116
+ *
117
+ * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
118
+ * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
119
+ *
120
+ * SPDX-License-Identifier: GPL-2.0-or-later
121
+ *
122
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
123
+ * See the COPYING file in the top-level directory.
124
+ *
125
+ * This work is heavily inspired by the stm32f405_soc by Alistair Francis.
126
+ * Original code is licensed under the MIT License:
127
+ *
128
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
129
+ */
130
+
131
+/*
132
+ * The reference used is the STMicroElectronics RM0351 Reference manual
133
+ * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
134
+ * https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html
135
+ */
136
+
137
+#include "qemu/osdep.h"
138
+#include "qemu/units.h"
139
+#include "qapi/error.h"
140
+#include "exec/address-spaces.h"
141
+#include "sysemu/sysemu.h"
142
+#include "hw/arm/stm32l4x5_soc.h"
143
+#include "hw/qdev-clock.h"
144
+#include "hw/misc/unimp.h"
145
+
146
+#define FLASH_BASE_ADDRESS 0x08000000
147
+#define SRAM1_BASE_ADDRESS 0x20000000
148
+#define SRAM1_SIZE (96 * KiB)
149
+#define SRAM2_BASE_ADDRESS 0x10000000
150
+#define SRAM2_SIZE (32 * KiB)
151
+
152
+static void stm32l4x5_soc_initfn(Object *obj)
153
+{
154
+ Stm32l4x5SocState *s = STM32L4X5_SOC(obj);
155
+
156
+ s->sysclk = qdev_init_clock_in(DEVICE(s), "sysclk", NULL, NULL, 0);
157
+ s->refclk = qdev_init_clock_in(DEVICE(s), "refclk", NULL, NULL, 0);
158
+}
159
+
160
+static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
161
+{
162
+ ERRP_GUARD();
163
+ Stm32l4x5SocState *s = STM32L4X5_SOC(dev_soc);
164
+ const Stm32l4x5SocClass *sc = STM32L4X5_SOC_GET_CLASS(dev_soc);
165
+ MemoryRegion *system_memory = get_system_memory();
166
+ DeviceState *armv7m;
167
+
168
+ /*
169
+ * We use s->refclk internally and only define it with qdev_init_clock_in()
170
+ * so it is correctly parented and not leaked on an init/deinit; it is not
171
+ * intended as an externally exposed clock.
172
+ */
173
+ if (clock_has_source(s->refclk)) {
174
+ error_setg(errp, "refclk clock must not be wired up by the board code");
175
+ return;
176
+ }
177
+
178
+ if (!clock_has_source(s->sysclk)) {
179
+ error_setg(errp, "sysclk clock must be wired up by the board code");
180
+ return;
181
+ }
182
+
183
+ /*
184
+ * TODO: ideally we should model the SoC RCC and its ability to
185
+ * change the sysclk frequency and define different sysclk sources.
186
+ */
187
+
188
+ /* The refclk always runs at frequency HCLK / 8 */
189
+ clock_set_mul_div(s->refclk, 8, 1);
190
+ clock_set_source(s->refclk, s->sysclk);
191
+
192
+ if (!memory_region_init_rom(&s->flash, OBJECT(dev_soc), "flash",
193
+ sc->flash_size, errp)) {
194
+ return;
195
+ }
196
+ memory_region_init_alias(&s->flash_alias, OBJECT(dev_soc),
197
+ "flash_boot_alias", &s->flash, 0,
198
+ sc->flash_size);
199
+
200
+ memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, &s->flash);
201
+ memory_region_add_subregion(system_memory, 0, &s->flash_alias);
202
+
203
+ if (!memory_region_init_ram(&s->sram1, OBJECT(dev_soc), "SRAM1", SRAM1_SIZE,
204
+ errp)) {
205
+ return;
206
+ }
207
+ memory_region_add_subregion(system_memory, SRAM1_BASE_ADDRESS, &s->sram1);
208
+
209
+ if (!memory_region_init_ram(&s->sram2, OBJECT(dev_soc), "SRAM2", SRAM2_SIZE,
210
+ errp)) {
211
+ return;
212
+ }
213
+ memory_region_add_subregion(system_memory, SRAM2_BASE_ADDRESS, &s->sram2);
214
+
215
+ object_initialize_child(OBJECT(dev_soc), "armv7m", &s->armv7m, TYPE_ARMV7M);
216
+ armv7m = DEVICE(&s->armv7m);
217
+ qdev_prop_set_uint32(armv7m, "num-irq", 96);
218
+ qdev_prop_set_string(armv7m, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
219
+ qdev_prop_set_bit(armv7m, "enable-bitband", true);
220
+ qdev_connect_clock_in(armv7m, "cpuclk", s->sysclk);
221
+ qdev_connect_clock_in(armv7m, "refclk", s->refclk);
222
+ object_property_set_link(OBJECT(&s->armv7m), "memory",
223
+ OBJECT(system_memory), &error_abort);
224
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->armv7m), errp)) {
225
+ return;
226
+ }
227
+
228
+ /* APB1 BUS */
229
+ create_unimplemented_device("TIM2", 0x40000000, 0x400);
230
+ create_unimplemented_device("TIM3", 0x40000400, 0x400);
231
+ create_unimplemented_device("TIM4", 0x40000800, 0x400);
232
+ create_unimplemented_device("TIM5", 0x40000C00, 0x400);
233
+ create_unimplemented_device("TIM6", 0x40001000, 0x400);
234
+ create_unimplemented_device("TIM7", 0x40001400, 0x400);
235
+ /* RESERVED: 0x40001800, 0x1000 */
236
+ create_unimplemented_device("RTC", 0x40002800, 0x400);
237
+ create_unimplemented_device("WWDG", 0x40002C00, 0x400);
238
+ create_unimplemented_device("IWDG", 0x40003000, 0x400);
239
+ /* RESERVED: 0x40001800, 0x400 */
240
+ create_unimplemented_device("SPI2", 0x40003800, 0x400);
241
+ create_unimplemented_device("SPI3", 0x40003C00, 0x400);
242
+ /* RESERVED: 0x40004000, 0x400 */
243
+ create_unimplemented_device("USART2", 0x40004400, 0x400);
244
+ create_unimplemented_device("USART3", 0x40004800, 0x400);
245
+ create_unimplemented_device("UART4", 0x40004C00, 0x400);
246
+ create_unimplemented_device("UART5", 0x40005000, 0x400);
247
+ create_unimplemented_device("I2C1", 0x40005400, 0x400);
248
+ create_unimplemented_device("I2C2", 0x40005800, 0x400);
249
+ create_unimplemented_device("I2C3", 0x40005C00, 0x400);
250
+ /* RESERVED: 0x40006000, 0x400 */
251
+ create_unimplemented_device("CAN1", 0x40006400, 0x400);
252
+ /* RESERVED: 0x40006800, 0x400 */
253
+ create_unimplemented_device("PWR", 0x40007000, 0x400);
254
+ create_unimplemented_device("DAC1", 0x40007400, 0x400);
255
+ create_unimplemented_device("OPAMP", 0x40007800, 0x400);
256
+ create_unimplemented_device("LPTIM1", 0x40007C00, 0x400);
257
+ create_unimplemented_device("LPUART1", 0x40008000, 0x400);
258
+ /* RESERVED: 0x40008400, 0x400 */
259
+ create_unimplemented_device("SWPMI1", 0x40008800, 0x400);
260
+ /* RESERVED: 0x40008C00, 0x800 */
261
+ create_unimplemented_device("LPTIM2", 0x40009400, 0x400);
262
+ /* RESERVED: 0x40009800, 0x6800 */
263
+
264
+ /* APB2 BUS */
265
+ create_unimplemented_device("SYSCFG", 0x40010000, 0x30);
266
+ create_unimplemented_device("VREFBUF", 0x40010030, 0x1D0);
267
+ create_unimplemented_device("COMP", 0x40010200, 0x200);
268
+ create_unimplemented_device("EXTI", 0x40010400, 0x400);
269
+ /* RESERVED: 0x40010800, 0x1400 */
270
+ create_unimplemented_device("FIREWALL", 0x40011C00, 0x400);
271
+ /* RESERVED: 0x40012000, 0x800 */
272
+ create_unimplemented_device("SDMMC1", 0x40012800, 0x400);
273
+ create_unimplemented_device("TIM1", 0x40012C00, 0x400);
274
+ create_unimplemented_device("SPI1", 0x40013000, 0x400);
275
+ create_unimplemented_device("TIM8", 0x40013400, 0x400);
276
+ create_unimplemented_device("USART1", 0x40013800, 0x400);
277
+ /* RESERVED: 0x40013C00, 0x400 */
278
+ create_unimplemented_device("TIM15", 0x40014000, 0x400);
279
+ create_unimplemented_device("TIM16", 0x40014400, 0x400);
280
+ create_unimplemented_device("TIM17", 0x40014800, 0x400);
281
+ /* RESERVED: 0x40014C00, 0x800 */
282
+ create_unimplemented_device("SAI1", 0x40015400, 0x400);
283
+ create_unimplemented_device("SAI2", 0x40015800, 0x400);
284
+ /* RESERVED: 0x40015C00, 0x400 */
285
+ create_unimplemented_device("DFSDM1", 0x40016000, 0x400);
286
+ /* RESERVED: 0x40016400, 0x9C00 */
287
+
288
+ /* AHB1 BUS */
289
+ create_unimplemented_device("DMA1", 0x40020000, 0x400);
290
+ create_unimplemented_device("DMA2", 0x40020400, 0x400);
291
+ /* RESERVED: 0x40020800, 0x800 */
292
+ create_unimplemented_device("RCC", 0x40021000, 0x400);
293
+ /* RESERVED: 0x40021400, 0xC00 */
294
+ create_unimplemented_device("FLASH", 0x40022000, 0x400);
295
+ /* RESERVED: 0x40022400, 0xC00 */
296
+ create_unimplemented_device("CRC", 0x40023000, 0x400);
297
+ /* RESERVED: 0x40023400, 0x400 */
298
+ create_unimplemented_device("TSC", 0x40024000, 0x400);
299
+
300
+ /* RESERVED: 0x40024400, 0x7FDBC00 */
301
+
302
+ /* AHB2 BUS */
303
+ create_unimplemented_device("GPIOA", 0x48000000, 0x400);
304
+ create_unimplemented_device("GPIOB", 0x48000400, 0x400);
305
+ create_unimplemented_device("GPIOC", 0x48000800, 0x400);
306
+ create_unimplemented_device("GPIOD", 0x48000C00, 0x400);
307
+ create_unimplemented_device("GPIOE", 0x48001000, 0x400);
308
+ create_unimplemented_device("GPIOF", 0x48001400, 0x400);
309
+ create_unimplemented_device("GPIOG", 0x48001800, 0x400);
310
+ create_unimplemented_device("GPIOH", 0x48001C00, 0x400);
311
+ /* RESERVED: 0x48002000, 0x7FDBC00 */
312
+ create_unimplemented_device("OTG_FS", 0x50000000, 0x40000);
313
+ create_unimplemented_device("ADC", 0x50040000, 0x400);
314
+ /* RESERVED: 0x50040400, 0x20400 */
315
+ create_unimplemented_device("RNG", 0x50060800, 0x400);
316
+
317
+ /* AHB3 BUS */
318
+ create_unimplemented_device("FMC", 0xA0000000, 0x1000);
319
+ create_unimplemented_device("QUADSPI", 0xA0001000, 0x400);
320
+}
321
+
322
+static void stm32l4x5_soc_class_init(ObjectClass *klass, void *data)
323
+{
324
+
325
+ DeviceClass *dc = DEVICE_CLASS(klass);
326
+
327
+ dc->realize = stm32l4x5_soc_realize;
328
+ /* Reason: Mapped at fixed location on the system bus */
329
+ dc->user_creatable = false;
330
+ /* No vmstate or reset required: device has no internal state */
331
+}
332
+
333
+static void stm32l4x5xc_soc_class_init(ObjectClass *oc, void *data)
334
+{
335
+ Stm32l4x5SocClass *ssc = STM32L4X5_SOC_CLASS(oc);
336
+
337
+ ssc->flash_size = 256 * KiB;
338
+}
339
+
340
+static void stm32l4x5xe_soc_class_init(ObjectClass *oc, void *data)
341
+{
342
+ Stm32l4x5SocClass *ssc = STM32L4X5_SOC_CLASS(oc);
343
+
344
+ ssc->flash_size = 512 * KiB;
345
+}
346
+
347
+static void stm32l4x5xg_soc_class_init(ObjectClass *oc, void *data)
348
+{
349
+ Stm32l4x5SocClass *ssc = STM32L4X5_SOC_CLASS(oc);
350
+
351
+ ssc->flash_size = 1 * MiB;
352
+}
353
+
354
+static const TypeInfo stm32l4x5_soc_types[] = {
355
+ {
356
+ .name = TYPE_STM32L4X5XC_SOC,
357
+ .parent = TYPE_STM32L4X5_SOC,
358
+ .class_init = stm32l4x5xc_soc_class_init,
359
+ }, {
360
+ .name = TYPE_STM32L4X5XE_SOC,
361
+ .parent = TYPE_STM32L4X5_SOC,
362
+ .class_init = stm32l4x5xe_soc_class_init,
363
+ }, {
364
+ .name = TYPE_STM32L4X5XG_SOC,
365
+ .parent = TYPE_STM32L4X5_SOC,
366
+ .class_init = stm32l4x5xg_soc_class_init,
367
+ }, {
368
+ .name = TYPE_STM32L4X5_SOC,
369
+ .parent = TYPE_SYS_BUS_DEVICE,
370
+ .instance_size = sizeof(Stm32l4x5SocState),
371
+ .instance_init = stm32l4x5_soc_initfn,
372
+ .class_size = sizeof(Stm32l4x5SocClass),
373
+ .class_init = stm32l4x5_soc_class_init,
374
+ .abstract = true,
375
+ }
376
+};
377
+
378
+DEFINE_TYPES(stm32l4x5_soc_types)
379
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
380
index XXXXXXX..XXXXXXX 100644
381
--- a/hw/arm/Kconfig
382
+++ b/hw/arm/Kconfig
383
@@ -XXX,XX +XXX,XX @@ config STM32F405_SOC
384
select STM32F4XX_SYSCFG
385
select STM32F4XX_EXTI
386
387
+config STM32L4X5_SOC
388
+ bool
389
+ select ARM_V7M
390
+ select OR_IRQ
391
+
392
config XLNX_ZYNQMP_ARM
393
bool
394
default y if PIXMAN
395
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
396
index XXXXXXX..XXXXXXX 100644
397
--- a/hw/arm/meson.build
398
+++ b/hw/arm/meson.build
399
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2836.c', 'raspi.c'))
400
arm_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_soc.c'))
401
arm_ss.add(when: 'CONFIG_STM32F205_SOC', if_true: files('stm32f205_soc.c'))
402
arm_ss.add(when: 'CONFIG_STM32F405_SOC', if_true: files('stm32f405_soc.c'))
403
+arm_ss.add(when: 'CONFIG_STM32L4X5_SOC', if_true: files('stm32l4x5_soc.c'))
404
arm_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp.c', 'xlnx-zcu102.c'))
405
arm_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal.c', 'xlnx-versal-virt.c'))
406
arm_ss.add(when: 'CONFIG_FSL_IMX25', if_true: files('fsl-imx25.c', 'imx25_pdk.c'))
407
--
408
2.34.1
409
410
diff view generated by jsdifflib
1
When interpreting CPU dumps where FEAT_NV and FEAT_NV2 are in use,
1
From: Michael Tokarev <mjt@tls.msk.ru>
2
it's helpful to include the values of HCR_EL2.{NV,NV1,NV2} in the CPU
3
dump format, as a way of distinguishing when we are in EL1 as part of
4
executing guest-EL2 and when we are just in normal EL1.
5
2
6
Add the bits to the end of the log line that shows PSTATE and similar
3
According to Cortex-R5 r1p2 manual, register with opcode2=0 is
7
information:
4
BTCM and with opcode2=1 is ATCM, - exactly the opposite from how
5
qemu labels them. Just swap the labels to avoid confusion, -
6
both registers are implemented as always-zero.
8
7
9
PSTATE=000003c9 ---- EL2h BTYPE=0 NV NV2
8
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20241121171602.3273252-1-mjt@tls.msk.ru
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/tcg/cpu32.c | 4 ++--
14
1 file changed, 2 insertions(+), 2 deletions(-)
10
15
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Tested-by: Miguel Luis <miguel.luis@oracle.com>
14
---
15
target/arm/cpu.c | 5 +++++
16
1 file changed, 5 insertions(+)
17
18
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.c
18
--- a/target/arm/tcg/cpu32.c
21
+++ b/target/arm/cpu.c
19
+++ b/target/arm/tcg/cpu32.c
22
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
20
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
23
uint32_t psr = pstate_read(env);
21
24
int i, j;
22
static const ARMCPRegInfo cortexr5_cp_reginfo[] = {
25
int el = arm_current_el(env);
23
/* Dummy the TCM region regs for the moment */
26
+ uint64_t hcr = arm_hcr_el2_eff(env);
24
- { .name = "ATCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
27
const char *ns_status;
25
+ { .name = "BTCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
28
bool sve;
26
.access = PL1_RW, .type = ARM_CP_CONST },
29
27
- { .name = "BTCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1,
30
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
28
+ { .name = "ATCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1,
31
if (cpu_isar_feature(aa64_bti, cpu)) {
29
.access = PL1_RW, .type = ARM_CP_CONST },
32
qemu_fprintf(f, " BTYPE=%d", (psr & PSTATE_BTYPE) >> 10);
30
{ .name = "DCACHE_INVAL", .cp = 15, .opc1 = 0, .crn = 15, .crm = 5,
33
}
31
.opc2 = 0, .access = PL1_W, .type = ARM_CP_NOP },
34
+ qemu_fprintf(f, "%s%s%s",
35
+ (hcr & HCR_NV) ? " NV" : "",
36
+ (hcr & HCR_NV1) ? " NV1" : "",
37
+ (hcr & HCR_NV2) ? " NV2" : "");
38
if (!(flags & CPU_DUMP_FPU)) {
39
qemu_fprintf(f, "\n");
40
return;
41
--
32
--
42
2.34.1
33
2.34.1
diff view generated by jsdifflib
1
From: Samuel Tardieu <sam@rfc1149.net>
1
From: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
2
3
Update the number of priority bits for a number of existing
3
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
SoCs according to their technical documentation:
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
5
Message-id: 20241122225049.1617774-2-pierrick.bouvier@linaro.org
6
- STM32F100/F205/F405/L4x5: 4 bits
7
- Stellaris (Sandstorm/Fury): 3 bits
8
9
Signed-off-by: Samuel Tardieu <sam@rfc1149.net>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20240106181503.1746200-4-sam@rfc1149.net
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
7
---
14
hw/arm/stellaris.c | 2 ++
8
docs/system/arm/emulation.rst | 6 +++---
15
hw/arm/stm32f100_soc.c | 1 +
9
1 file changed, 3 insertions(+), 3 deletions(-)
16
hw/arm/stm32f205_soc.c | 1 +
17
hw/arm/stm32f405_soc.c | 1 +
18
hw/arm/stm32l4x5_soc.c | 1 +
19
5 files changed, 6 insertions(+)
20
10
21
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
11
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
22
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/stellaris.c
13
--- a/docs/system/arm/emulation.rst
24
+++ b/hw/arm/stellaris.c
14
+++ b/docs/system/arm/emulation.rst
25
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@
26
#define BP_GAMEPAD 0x04
16
A-profile CPU architecture support
27
17
==================================
28
#define NUM_IRQ_LINES 64
18
29
+#define NUM_PRIO_BITS 3
19
-QEMU's TCG emulation includes support for the Armv5, Armv6, Armv7 and
30
20
-Armv8 versions of the A-profile architecture. It also has support for
31
typedef const struct {
21
+QEMU's TCG emulation includes support for the Armv5, Armv6, Armv7,
32
const char *name;
22
+Armv8 and Armv9 versions of the A-profile architecture. It also has support for
33
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
23
the following architecture extensions:
34
24
35
nvic = qdev_new(TYPE_ARMV7M);
25
- FEAT_AA32BF16 (AArch32 BFloat16 instructions)
36
qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES);
26
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
37
+ qdev_prop_set_uint8(nvic, "num-prio-bits", NUM_PRIO_BITS);
27
- FEAT_XNX (Translation table stage 2 Unprivileged Execute-never)
38
qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type);
28
39
qdev_prop_set_bit(nvic, "enable-bitband", true);
29
For information on the specifics of these extensions, please refer
40
qdev_connect_clock_in(nvic, "cpuclk",
30
-to the `Armv8-A Arm Architecture Reference Manual
41
diff --git a/hw/arm/stm32f100_soc.c b/hw/arm/stm32f100_soc.c
31
+to the `Arm Architecture Reference Manual for A-profile architecture
42
index XXXXXXX..XXXXXXX 100644
32
<https://developer.arm.com/documentation/ddi0487/latest>`_.
43
--- a/hw/arm/stm32f100_soc.c
33
44
+++ b/hw/arm/stm32f100_soc.c
34
When a specific named CPU is being emulated, only those features which
45
@@ -XXX,XX +XXX,XX @@ static void stm32f100_soc_realize(DeviceState *dev_soc, Error **errp)
46
/* Init ARMv7m */
47
armv7m = DEVICE(&s->armv7m);
48
qdev_prop_set_uint32(armv7m, "num-irq", 61);
49
+ qdev_prop_set_uint8(armv7m, "num-prio-bits", 4);
50
qdev_prop_set_string(armv7m, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m3"));
51
qdev_prop_set_bit(armv7m, "enable-bitband", true);
52
qdev_connect_clock_in(armv7m, "cpuclk", s->sysclk);
53
diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/arm/stm32f205_soc.c
56
+++ b/hw/arm/stm32f205_soc.c
57
@@ -XXX,XX +XXX,XX @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
58
59
armv7m = DEVICE(&s->armv7m);
60
qdev_prop_set_uint32(armv7m, "num-irq", 96);
61
+ qdev_prop_set_uint8(armv7m, "num-prio-bits", 4);
62
qdev_prop_set_string(armv7m, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m3"));
63
qdev_prop_set_bit(armv7m, "enable-bitband", true);
64
qdev_connect_clock_in(armv7m, "cpuclk", s->sysclk);
65
diff --git a/hw/arm/stm32f405_soc.c b/hw/arm/stm32f405_soc.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/arm/stm32f405_soc.c
68
+++ b/hw/arm/stm32f405_soc.c
69
@@ -XXX,XX +XXX,XX @@ static void stm32f405_soc_realize(DeviceState *dev_soc, Error **errp)
70
71
armv7m = DEVICE(&s->armv7m);
72
qdev_prop_set_uint32(armv7m, "num-irq", 96);
73
+ qdev_prop_set_uint8(armv7m, "num-prio-bits", 4);
74
qdev_prop_set_string(armv7m, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
75
qdev_prop_set_bit(armv7m, "enable-bitband", true);
76
qdev_connect_clock_in(armv7m, "cpuclk", s->sysclk);
77
diff --git a/hw/arm/stm32l4x5_soc.c b/hw/arm/stm32l4x5_soc.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/arm/stm32l4x5_soc.c
80
+++ b/hw/arm/stm32l4x5_soc.c
81
@@ -XXX,XX +XXX,XX @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
82
object_initialize_child(OBJECT(dev_soc), "armv7m", &s->armv7m, TYPE_ARMV7M);
83
armv7m = DEVICE(&s->armv7m);
84
qdev_prop_set_uint32(armv7m, "num-irq", 96);
85
+ qdev_prop_set_uint32(armv7m, "num-prio-bits", 4);
86
qdev_prop_set_string(armv7m, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
87
qdev_prop_set_bit(armv7m, "enable-bitband", true);
88
qdev_connect_clock_in(armv7m, "cpuclk", s->sysclk);
89
--
35
--
90
2.34.1
36
2.34.1
diff view generated by jsdifflib
1
Enable FEAT_NV on the 'max' CPU, and stop filtering it out for the
1
From: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
Neoverse N2 and Neoverse V1 CPUs. We continue to downgrade FEAT_NV2
3
support to FEAT_NV for the latter two CPU types.
4
2
3
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241122225049.1617774-3-pierrick.bouvier@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Miguel Luis <miguel.luis@oracle.com>
8
---
7
---
9
docs/system/arm/emulation.rst | 1 +
8
docs/system/arm/emulation.rst | 2 +-
10
target/arm/cpu.c | 8 +++++---
9
1 file changed, 1 insertion(+), 1 deletion(-)
11
target/arm/tcg/cpu64.c | 1 +
12
3 files changed, 7 insertions(+), 3 deletions(-)
13
10
14
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
11
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
15
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/emulation.rst
13
--- a/docs/system/arm/emulation.rst
17
+++ b/docs/system/arm/emulation.rst
14
+++ b/docs/system/arm/emulation.rst
18
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
15
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
16
- FEAT_LSE2 (Large System Extensions v2)
17
- FEAT_LVA (Large Virtual Address space)
18
- FEAT_MixedEnd (Mixed-endian support)
19
-- FEAT_MixdEndEL0 (Mixed-endian support at EL0)
20
+- FEAT_MixedEndEL0 (Mixed-endian support at EL0)
21
- FEAT_MOPS (Standardization of memory operations)
19
- FEAT_MTE (Memory Tagging Extension)
22
- FEAT_MTE (Memory Tagging Extension)
20
- FEAT_MTE2 (Memory Tagging Extension)
23
- FEAT_MTE2 (Memory Tagging Extension)
21
- FEAT_MTE3 (MTE Asymmetric Fault Handling)
22
+- FEAT_NV (Nested Virtualization)
23
- FEAT_PACIMP (Pointer authentication - IMPLEMENTATION DEFINED algorithm)
24
- FEAT_PACQARMA3 (Pointer authentication - QARMA3 algorithm)
25
- FEAT_PACQARMA5 (Pointer authentication - QARMA5 algorithm)
26
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/cpu.c
29
+++ b/target/arm/cpu.c
30
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
31
/* FEAT_MPAM (Memory Partitioning and Monitoring Extension) */
32
cpu->isar.id_aa64pfr0 =
33
FIELD_DP64(cpu->isar.id_aa64pfr0, ID_AA64PFR0, MPAM, 0);
34
- /* FEAT_NV (Nested Virtualization) */
35
- cpu->isar.id_aa64mmfr2 =
36
- FIELD_DP64(cpu->isar.id_aa64mmfr2, ID_AA64MMFR2, NV, 0);
37
+ /* FEAT_NV2 (Enhanced Nested Virtualization support) */
38
+ if (FIELD_EX64(cpu->isar.id_aa64mmfr2, ID_AA64MMFR2, NV) > 1) {
39
+ cpu->isar.id_aa64mmfr2 =
40
+ FIELD_DP64(cpu->isar.id_aa64mmfr2, ID_AA64MMFR2, NV, 1);
41
+ }
42
}
43
44
/* MPU can be configured out of a PMSA CPU either by setting has-mpu
45
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/tcg/cpu64.c
48
+++ b/target/arm/tcg/cpu64.c
49
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
50
t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1); /* FEAT_UAO */
51
t = FIELD_DP64(t, ID_AA64MMFR2, IESB, 1); /* FEAT_IESB */
52
t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1); /* FEAT_LVA */
53
+ t = FIELD_DP64(t, ID_AA64MMFR2, NV, 1); /* FEAT_NV */
54
t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* FEAT_TTST */
55
t = FIELD_DP64(t, ID_AA64MMFR2, AT, 1); /* FEAT_LSE2 */
56
t = FIELD_DP64(t, ID_AA64MMFR2, IDS, 1); /* FEAT_IDST */
57
--
24
--
58
2.34.1
25
2.34.1
diff view generated by jsdifflib
1
We already print various lines of information when we take an
1
From: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
exception, including the ELR and (if relevant) the FAR. Now
3
that FEAT_NV means that we might report something other than
4
the old PSTATE to the guest as the SPSR, it's worth logging
5
this as well.
6
2
3
We implemented this at the same times as FEAT_SSBS, but forgot
4
to list it in the documentation.
5
6
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241122225049.1617774-4-pierrick.bouvier@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
[PMM: improve commit message]
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Miguel Luis <miguel.luis@oracle.com>
10
---
12
---
11
target/arm/helper.c | 1 +
13
docs/system/arm/emulation.rst | 1 +
12
1 file changed, 1 insertion(+)
14
1 file changed, 1 insertion(+)
13
15
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
18
--- a/docs/system/arm/emulation.rst
17
+++ b/target/arm/helper.c
19
+++ b/docs/system/arm/emulation.rst
18
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
20
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
19
}
21
- FEAT_SVE2 (Scalable Vector Extension version 2)
20
env->banked_spsr[aarch64_banked_spsr_index(new_el)] = old_mode;
22
- FEAT_SPECRES (Speculation restriction instructions)
21
23
- FEAT_SSBS (Speculative Store Bypass Safe)
22
+ qemu_log_mask(CPU_LOG_INT, "...with SPSR 0x%x\n", old_mode);
24
+- FEAT_SSBS2 (MRS and MSR instructions for SSBS version 2)
23
qemu_log_mask(CPU_LOG_INT, "...with ELR 0x%" PRIx64 "\n",
25
- FEAT_TGran16K (Support for 16KB memory translation granule size at stage 1)
24
env->elr_el[new_el]);
26
- FEAT_TGran4K (Support for 4KB memory translation granule size at stage 1)
25
27
- FEAT_TGran64K (Support for 64KB memory translation granule size at stage 1)
26
--
28
--
27
2.34.1
29
2.34.1
diff view generated by jsdifflib
1
From: Samuel Tardieu <sam@rfc1149.net>
1
From: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
2
3
A SoC will not have a direct access to the NVIC embedded in its ARM
3
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
core. By aliasing the "num-prio-bits" property similarly to what is
5
done for the "num-irq" one, a SoC can easily configure it on its
6
armv7m instance.
7
8
Signed-off-by: Samuel Tardieu <sam@rfc1149.net>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20240106181503.1746200-3-sam@rfc1149.net
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241122225049.1617774-5-pierrick.bouvier@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
8
---
14
include/hw/arm/armv7m.h | 1 +
9
target/arm/tcg/cpu32.c | 2 +-
15
hw/arm/armv7m.c | 2 ++
10
1 file changed, 1 insertion(+), 1 deletion(-)
16
2 files changed, 3 insertions(+)
17
11
18
diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
12
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
19
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/armv7m.h
14
--- a/target/arm/tcg/cpu32.c
21
+++ b/include/hw/arm/armv7m.h
15
+++ b/target/arm/tcg/cpu32.c
22
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(ARMv7MState, ARMV7M)
16
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
23
* a qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET).
17
cpu->isar.id_mmfr5 = t;
24
* + Property "cpu-type": CPU type to instantiate
18
25
* + Property "num-irq": number of external IRQ lines
19
t = cpu->isar.id_pfr0;
26
+ * + Property "num-prio-bits": number of priority bits in the NVIC
20
- t = FIELD_DP32(t, ID_PFR0, CSV2, 2); /* FEAT_CVS2 */
27
* + Property "memory": MemoryRegion defining the physical address space
21
+ t = FIELD_DP32(t, ID_PFR0, CSV2, 2); /* FEAT_CSV2 */
28
* that CPU accesses see. (The NVIC, bitbanding and other CPU-internal
22
t = FIELD_DP32(t, ID_PFR0, DIT, 1); /* FEAT_DIT */
29
* devices will be automatically layered on top of this view.)
23
t = FIELD_DP32(t, ID_PFR0, RAS, 1); /* FEAT_RAS */
30
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
24
cpu->isar.id_pfr0 = t;
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/arm/armv7m.c
33
+++ b/hw/arm/armv7m.c
34
@@ -XXX,XX +XXX,XX @@ static void armv7m_instance_init(Object *obj)
35
object_initialize_child(obj, "nvic", &s->nvic, TYPE_NVIC);
36
object_property_add_alias(obj, "num-irq",
37
OBJECT(&s->nvic), "num-irq");
38
+ object_property_add_alias(obj, "num-prio-bits",
39
+ OBJECT(&s->nvic), "num-prio-bits");
40
41
object_initialize_child(obj, "systick-reg-ns", &s->systick[M_REG_NS],
42
TYPE_SYSTICK);
43
--
25
--
44
2.34.1
26
2.34.1
45
27
46
28
diff view generated by jsdifflib
1
Enable FEAT_NV2 on the 'max' CPU, and stop filtering it out for
1
From: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
the Neoverse N2 and Neoverse V1 CPUs.
3
2
3
We already implement FEAT_MTE_ASYNC; we just forgot to list it
4
in the documentation.
5
6
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241122225049.1617774-6-pierrick.bouvier@linaro.org
9
[PMM: expand commit message]
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Miguel Luis <miguel.luis@oracle.com>
7
---
11
---
8
docs/system/arm/emulation.rst | 1 +
12
docs/system/arm/emulation.rst | 1 +
9
target/arm/cpu.c | 5 -----
13
1 file changed, 1 insertion(+)
10
target/arm/tcg/cpu64.c | 2 +-
11
3 files changed, 2 insertions(+), 6 deletions(-)
12
14
13
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
15
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/docs/system/arm/emulation.rst
17
--- a/docs/system/arm/emulation.rst
16
+++ b/docs/system/arm/emulation.rst
18
+++ b/docs/system/arm/emulation.rst
17
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
19
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
18
- FEAT_MTE2 (Memory Tagging Extension)
20
- FEAT_MTE2 (Memory Tagging Extension)
19
- FEAT_MTE3 (MTE Asymmetric Fault Handling)
21
- FEAT_MTE3 (MTE Asymmetric Fault Handling)
22
- FEAT_MTE_ASYM_FAULT (Memory tagging asymmetric faults)
23
+- FEAT_MTE_ASYNC (Asynchronous reporting of Tag Check Fault)
24
- FEAT_NMI (Non-maskable Interrupt)
20
- FEAT_NV (Nested Virtualization)
25
- FEAT_NV (Nested Virtualization)
21
+- FEAT_NV2 (Enhanced nested virtualization support)
26
- FEAT_NV2 (Enhanced nested virtualization support)
22
- FEAT_PACIMP (Pointer authentication - IMPLEMENTATION DEFINED algorithm)
23
- FEAT_PACQARMA3 (Pointer authentication - QARMA3 algorithm)
24
- FEAT_PACQARMA5 (Pointer authentication - QARMA5 algorithm)
25
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/cpu.c
28
+++ b/target/arm/cpu.c
29
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
30
/* FEAT_MPAM (Memory Partitioning and Monitoring Extension) */
31
cpu->isar.id_aa64pfr0 =
32
FIELD_DP64(cpu->isar.id_aa64pfr0, ID_AA64PFR0, MPAM, 0);
33
- /* FEAT_NV2 (Enhanced Nested Virtualization support) */
34
- if (FIELD_EX64(cpu->isar.id_aa64mmfr2, ID_AA64MMFR2, NV) > 1) {
35
- cpu->isar.id_aa64mmfr2 =
36
- FIELD_DP64(cpu->isar.id_aa64mmfr2, ID_AA64MMFR2, NV, 1);
37
- }
38
}
39
40
/* MPU can be configured out of a PMSA CPU either by setting has-mpu
41
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/tcg/cpu64.c
44
+++ b/target/arm/tcg/cpu64.c
45
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
46
t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1); /* FEAT_UAO */
47
t = FIELD_DP64(t, ID_AA64MMFR2, IESB, 1); /* FEAT_IESB */
48
t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1); /* FEAT_LVA */
49
- t = FIELD_DP64(t, ID_AA64MMFR2, NV, 1); /* FEAT_NV */
50
+ t = FIELD_DP64(t, ID_AA64MMFR2, NV, 2); /* FEAT_NV2 */
51
t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* FEAT_TTST */
52
t = FIELD_DP64(t, ID_AA64MMFR2, AT, 1); /* FEAT_LSE2 */
53
t = FIELD_DP64(t, ID_AA64MMFR2, IDS, 1); /* FEAT_IDST */
54
--
27
--
55
2.34.1
28
2.34.1
diff view generated by jsdifflib
1
From: Samuel Tardieu <sam@rfc1149.net>
1
From: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
2
3
Cortex-M NVIC can have a different number of priority bits.
3
We already implement FEAT_DoubleLock (see commit f94a6df5dd6a7) when
4
Cortex-M0/M0+/M1 devices must use 2 or more bits, while devices based
4
the ID registers call for it. This feature is actually one that must
5
on ARMv7m and up must use 3 or more bits.
5
*not* be implemented in v9.0, but since our documentation lists
6
everything we can emulate, we should include FEAT_DoubleLock in the
7
list.
6
8
7
This adds a "num-prio-bits" property which will get sensible default
9
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
8
values if unset (2 or 8 depending on the device). Unless a SOC
10
Message-id: 20241122225049.1617774-7-pierrick.bouvier@linaro.org
9
specifies the number of bits to use, the previous behavior is
10
maintained for backward compatibility.
11
12
Signed-off-by: Samuel Tardieu <sam@rfc1149.net>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 20240106181503.1746200-2-sam@rfc1149.net
12
[PMM: expand commit message]
15
Suggested-by: Anton Kochkov <anton.kochkov@proton.me>
16
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1122
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
14
---
20
hw/intc/armv7m_nvic.c | 23 ++++++++++++++++++++++-
15
docs/system/arm/emulation.rst | 1 +
21
1 file changed, 22 insertions(+), 1 deletion(-)
16
1 file changed, 1 insertion(+)
22
17
23
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
18
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
24
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/intc/armv7m_nvic.c
20
--- a/docs/system/arm/emulation.rst
26
+++ b/hw/intc/armv7m_nvic.c
21
+++ b/docs/system/arm/emulation.rst
27
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_nvic = {
22
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
28
static Property props_nvic[] = {
23
- FEAT_CSV3 (Cache speculation variant 3)
29
/* Number of external IRQ lines (so excluding the 16 internal exceptions) */
24
- FEAT_DGH (Data gathering hint)
30
DEFINE_PROP_UINT32("num-irq", NVICState, num_irq, 64),
25
- FEAT_DIT (Data Independent Timing instructions)
31
+ /*
26
+- FEAT_DoubleLock (Double Lock)
32
+ * Number of the maximum priority bits that can be used. 0 means
27
- FEAT_DPB (DC CVAP instruction)
33
+ * to use a reasonable default.
28
- FEAT_DPB2 (DC CVADP instruction)
34
+ */
29
- FEAT_Debugv8p1 (Debug with VHE)
35
+ DEFINE_PROP_UINT8("num-prio-bits", NVICState, num_prio_bits, 0),
36
DEFINE_PROP_END_OF_LIST()
37
};
38
39
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
40
/* include space for internal exception vectors */
41
s->num_irq += NVIC_FIRST_IRQ;
42
43
- s->num_prio_bits = arm_feature(&s->cpu->env, ARM_FEATURE_V7) ? 8 : 2;
44
+ if (s->num_prio_bits == 0) {
45
+ /*
46
+ * If left unspecified, use 2 bits by default on Cortex-M0/M0+/M1
47
+ * and 8 bits otherwise.
48
+ */
49
+ s->num_prio_bits = arm_feature(&s->cpu->env, ARM_FEATURE_V7) ? 8 : 2;
50
+ } else {
51
+ uint8_t min_prio_bits =
52
+ arm_feature(&s->cpu->env, ARM_FEATURE_V7) ? 3 : 2;
53
+ if (s->num_prio_bits < min_prio_bits || s->num_prio_bits > 8) {
54
+ error_setg(errp,
55
+ "num-prio-bits %d is outside "
56
+ "NVIC acceptable range [%d-8]",
57
+ s->num_prio_bits, min_prio_bits);
58
+ return;
59
+ }
60
+ }
61
62
/*
63
* This device provides a single memory region which covers the
64
--
30
--
65
2.34.1
31
2.34.1
diff view generated by jsdifflib
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
1
From: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
2
3
This commit adds a new B-L475E-IOT01A board using the STM32L475VG SoC
3
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
as well as a dedicated documentation file.
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
The implementation is derived from the Netduino Plus 2 machine.
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
There are no peripherals implemented yet, only memory regions.
7
8
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20241122225049.1617774-8-pierrick.bouvier@linaro.org
10
Acked-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
12
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
13
Message-id: 20240108135849.351719-3-ines.varhol@telecom-paris.fr
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
9
---
16
MAINTAINERS | 7 +++
10
docs/system/arm/fby35.rst | 2 +-
17
docs/system/arm/b-l475e-iot01a.rst | 46 ++++++++++++++++
11
1 file changed, 1 insertion(+), 1 deletion(-)
18
docs/system/arm/stm32.rst | 6 ++-
19
docs/system/target-arm.rst | 1 +
20
configs/devices/arm-softmmu/default.mak | 1 +
21
hw/arm/b-l475e-iot01a.c | 72 +++++++++++++++++++++++++
22
hw/arm/Kconfig | 6 +++
23
hw/arm/meson.build | 1 +
24
8 files changed, 138 insertions(+), 2 deletions(-)
25
create mode 100644 docs/system/arm/b-l475e-iot01a.rst
26
create mode 100644 hw/arm/b-l475e-iot01a.c
27
12
28
diff --git a/MAINTAINERS b/MAINTAINERS
13
diff --git a/docs/system/arm/fby35.rst b/docs/system/arm/fby35.rst
29
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
30
--- a/MAINTAINERS
15
--- a/docs/system/arm/fby35.rst
31
+++ b/MAINTAINERS
16
+++ b/docs/system/arm/fby35.rst
32
@@ -XXX,XX +XXX,XX @@ S: Maintained
17
@@ -XXX,XX +XXX,XX @@ include various compute accelerators (video, inferencing, etc). At the moment,
33
F: hw/arm/stm32l4x5_soc.c
18
only the first server slot's BIC is included.
34
F: include/hw/arm/stm32l4x5_soc.h
19
35
20
Yosemite v3.5 is itself a sled which fits into a 40U chassis, and 3 sleds
36
+B-L475E-IOT01A IoT Node
21
-can be fit into a chassis. See `here <https://www.opencompute.org/products/423/wiwynn-yosemite-v3-server>`__
37
+M: Arnaud Minier <arnaud.minier@telecom-paris.fr>
22
+can be fit into a chassis. See `here <https://www.opencompute.org/products-chiplets/237/wiwynn-yosemite-v3-server>`__
38
+M: Inès Varhol <ines.varhol@telecom-paris.fr>
23
for an example.
39
+L: qemu-arm@nongnu.org
24
40
+S: Maintained
25
In this generation, the BMC is an AST2600 and each BIC is an AST1030. The BMC
41
+F: hw/arm/b-l475e-iot01a.c
42
+
43
SmartFusion2
44
M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
45
M: Peter Maydell <peter.maydell@linaro.org>
46
diff --git a/docs/system/arm/b-l475e-iot01a.rst b/docs/system/arm/b-l475e-iot01a.rst
47
new file mode 100644
48
index XXXXXXX..XXXXXXX
49
--- /dev/null
50
+++ b/docs/system/arm/b-l475e-iot01a.rst
51
@@ -XXX,XX +XXX,XX @@
52
+B-L475E-IOT01A IoT Node (``b-l475e-iot01a``)
53
+============================================
54
+
55
+The B-L475E-IOT01A IoT Node uses the STM32L475VG SoC which is based on
56
+ARM Cortex-M4F core. It is part of STMicroelectronics
57
+:doc:`STM32 boards </system/arm/stm32>` and more specifically the STM32L4
58
+ultra-low power series. The STM32L4x5 chip runs at up to 80 MHz and
59
+integrates 128 KiB of SRAM and up to 1MiB of Flash. The B-L475E-IOT01A board
60
+namely features 64 Mibit QSPI Flash, BT, WiFi and RF connectivity,
61
+USART, I2C, SPI, CAN and USB OTG, as well as a variety of sensors.
62
+
63
+Supported devices
64
+"""""""""""""""""
65
+
66
+Currently, B-L475E-IOT01A machine's implementation is minimal,
67
+it only supports the following device:
68
+
69
+- Cortex-M4F based STM32L4x5 SoC
70
+
71
+Missing devices
72
+"""""""""""""""
73
+
74
+The B-L475E-IOT01A does *not* support the following devices:
75
+
76
+- Extended interrupts and events controller (EXTI)
77
+- Reset and clock control (RCC)
78
+- Serial ports (UART)
79
+- System configuration controller (SYSCFG)
80
+- General-purpose I/Os (GPIO)
81
+- Analog to Digital Converter (ADC)
82
+- SPI controller
83
+- Timer controller (TIMER)
84
+
85
+See the complete list of unimplemented peripheral devices
86
+in the STM32L4x5 module : ``./hw/arm/stm32l4x5_soc.c``
87
+
88
+Boot options
89
+""""""""""""
90
+
91
+The B-L475E-IOT01A machine can be started using the ``-kernel``
92
+option to load a firmware. Example:
93
+
94
+.. code-block:: bash
95
+
96
+ $ qemu-system-arm -M b-l475e-iot01a -kernel firmware.bin
97
+
98
diff --git a/docs/system/arm/stm32.rst b/docs/system/arm/stm32.rst
99
index XXXXXXX..XXXXXXX 100644
100
--- a/docs/system/arm/stm32.rst
101
+++ b/docs/system/arm/stm32.rst
102
@@ -XXX,XX +XXX,XX @@ based on this chip :
103
104
- ``netduino2`` Netduino 2 board with STM32F205RFT6 microcontroller
105
106
-The STM32F4 series is based on ARM Cortex-M4F core. This series is pin-to-pin
107
-compatible with STM32F2 series. The following machines are based on this chip :
108
+The STM32F4 series is based on ARM Cortex-M4F core, as well as the STM32L4
109
+ultra-low-power series. The STM32F4 series is pin-to-pin compatible with STM32F2 series.
110
+The following machines are based on this ARM Cortex-M4F chip :
111
112
- ``netduinoplus2`` Netduino Plus 2 board with STM32F405RGT6 microcontroller
113
- ``olimex-stm32-h405`` Olimex STM32 H405 board with STM32F405RGT6 microcontroller
114
+- ``b-l475e-iot01a`` :doc:`B-L475E-IOT01A IoT Node </system/arm/b-l475e-iot01a>` board with STM32L475VG microcontroller
115
116
There are many other STM32 series that are currently not supported by QEMU.
117
118
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
119
index XXXXXXX..XXXXXXX 100644
120
--- a/docs/system/target-arm.rst
121
+++ b/docs/system/target-arm.rst
122
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
123
arm/vexpress
124
arm/aspeed
125
arm/bananapi_m2u.rst
126
+ arm/b-l475e-iot01a.rst
127
arm/sabrelite
128
arm/digic
129
arm/cubieboard
130
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
131
index XXXXXXX..XXXXXXX 100644
132
--- a/configs/devices/arm-softmmu/default.mak
133
+++ b/configs/devices/arm-softmmu/default.mak
134
@@ -XXX,XX +XXX,XX @@ CONFIG_ARM_VIRT=y
135
# CONFIG_NSERIES=n
136
# CONFIG_STELLARIS=n
137
# CONFIG_STM32VLDISCOVERY=n
138
+# CONFIG_B_L475E_IOT01A=n
139
# CONFIG_REALVIEW=n
140
# CONFIG_VERSATILE=n
141
# CONFIG_VEXPRESS=n
142
diff --git a/hw/arm/b-l475e-iot01a.c b/hw/arm/b-l475e-iot01a.c
143
new file mode 100644
144
index XXXXXXX..XXXXXXX
145
--- /dev/null
146
+++ b/hw/arm/b-l475e-iot01a.c
147
@@ -XXX,XX +XXX,XX @@
148
+/*
149
+ * B-L475E-IOT01A Discovery Kit machine
150
+ * (B-L475E-IOT01A IoT Node)
151
+ *
152
+ * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
153
+ * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
154
+ *
155
+ * SPDX-License-Identifier: GPL-2.0-or-later
156
+ *
157
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
158
+ * See the COPYING file in the top-level directory.
159
+ *
160
+ * This work is heavily inspired by the netduinoplus2 by Alistair Francis.
161
+ * Original code is licensed under the MIT License:
162
+ *
163
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
164
+ */
165
+
166
+/*
167
+ * The reference used is the STMicroElectronics UM2153 User manual
168
+ * Discovery kit for IoT node, multi-channel communication with STM32L4.
169
+ * https://www.st.com/en/evaluation-tools/b-l475e-iot01a.html#documentation
170
+ */
171
+
172
+#include "qemu/osdep.h"
173
+#include "qapi/error.h"
174
+#include "hw/boards.h"
175
+#include "hw/qdev-properties.h"
176
+#include "hw/qdev-clock.h"
177
+#include "qemu/error-report.h"
178
+#include "hw/arm/stm32l4x5_soc.h"
179
+#include "hw/arm/boot.h"
180
+
181
+/* Main SYSCLK frequency in Hz (80MHz) */
182
+#define MAIN_SYSCLK_FREQ_HZ 80000000ULL
183
+
184
+static void b_l475e_iot01a_init(MachineState *machine)
185
+{
186
+ const Stm32l4x5SocClass *sc;
187
+ DeviceState *dev;
188
+ Clock *sysclk;
189
+
190
+ /* This clock doesn't need migration because it is fixed-frequency */
191
+ sysclk = clock_new(OBJECT(machine), "SYSCLK");
192
+ clock_set_hz(sysclk, MAIN_SYSCLK_FREQ_HZ);
193
+
194
+ dev = qdev_new(TYPE_STM32L4X5XG_SOC);
195
+ object_property_add_child(OBJECT(machine), "soc", OBJECT(dev));
196
+ qdev_connect_clock_in(dev, "sysclk", sysclk);
197
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
198
+
199
+ sc = STM32L4X5_SOC_GET_CLASS(dev);
200
+ armv7m_load_kernel(ARM_CPU(first_cpu),
201
+ machine->kernel_filename,
202
+ 0, sc->flash_size);
203
+}
204
+
205
+static void b_l475e_iot01a_machine_init(MachineClass *mc)
206
+{
207
+ static const char *machine_valid_cpu_types[] = {
208
+ ARM_CPU_TYPE_NAME("cortex-m4"),
209
+ NULL
210
+ };
211
+ mc->desc = "B-L475E-IOT01A Discovery Kit (Cortex-M4)";
212
+ mc->init = b_l475e_iot01a_init;
213
+ mc->valid_cpu_types = machine_valid_cpu_types;
214
+
215
+ /* SRAM pre-allocated as part of the SoC instantiation */
216
+ mc->default_ram_size = 0;
217
+}
218
+
219
+DEFINE_MACHINE("b-l475e-iot01a", b_l475e_iot01a_machine_init)
220
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
221
index XXXXXXX..XXXXXXX 100644
222
--- a/hw/arm/Kconfig
223
+++ b/hw/arm/Kconfig
224
@@ -XXX,XX +XXX,XX @@ config STM32F405_SOC
225
select STM32F4XX_SYSCFG
226
select STM32F4XX_EXTI
227
228
+config B_L475E_IOT01A
229
+ bool
230
+ default y
231
+ depends on TCG && ARM
232
+ select STM32L4X5_SOC
233
+
234
config STM32L4X5_SOC
235
bool
236
select ARM_V7M
237
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
238
index XXXXXXX..XXXXXXX 100644
239
--- a/hw/arm/meson.build
240
+++ b/hw/arm/meson.build
241
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2836.c', 'raspi.c'))
242
arm_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_soc.c'))
243
arm_ss.add(when: 'CONFIG_STM32F205_SOC', if_true: files('stm32f205_soc.c'))
244
arm_ss.add(when: 'CONFIG_STM32F405_SOC', if_true: files('stm32f405_soc.c'))
245
+arm_ss.add(when: 'CONFIG_B_L475E_IOT01A', if_true: files('b-l475e-iot01a.c'))
246
arm_ss.add(when: 'CONFIG_STM32L4X5_SOC', if_true: files('stm32l4x5_soc.c'))
247
arm_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp.c', 'xlnx-zcu102.c'))
248
arm_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal.c', 'xlnx-versal-virt.c'))
249
--
26
--
250
2.34.1
27
2.34.1
251
28
252
29
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
2
3
QDev objects created with qdev_new() need to manually add
3
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
their parent relationship with object_property_add_child().
4
Reviewed-by: Andrew Jeffery <andrew@codeconstruct.com.au>
5
5
Message-id: 20241122225049.1617774-13-pierrick.bouvier@linaro.org
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20240104141159.53883-1-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
7
---
11
hw/arm/msf2-som.c | 1 +
8
docs/system/arm/aspeed.rst | 7 ++++---
12
hw/arm/netduino2.c | 1 +
9
1 file changed, 4 insertions(+), 3 deletions(-)
13
hw/arm/netduinoplus2.c | 1 +
14
hw/arm/olimex-stm32-h405.c | 1 +
15
hw/arm/stm32vldiscovery.c | 1 +
16
5 files changed, 5 insertions(+)
17
10
18
diff --git a/hw/arm/msf2-som.c b/hw/arm/msf2-som.c
11
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
19
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/msf2-som.c
13
--- a/docs/system/arm/aspeed.rst
21
+++ b/hw/arm/msf2-som.c
14
+++ b/docs/system/arm/aspeed.rst
22
@@ -XXX,XX +XXX,XX @@ static void emcraft_sf2_s2s010_init(MachineState *machine)
15
@@ -XXX,XX +XXX,XX @@
23
memory_region_add_subregion(sysmem, DDR_BASE_ADDRESS, ddr);
16
-Aspeed family boards (``ast2500-evb``, ``ast2600-evb``, ``ast2700-evb``, ``bletchley-bmc``, ``fuji-bmc``, ``fby35-bmc``, ``fp5280g2-bmc``, ``g220a-bmc``, ``palmetto-bmc``, ``qcom-dc-scm-v1-bmc``, ``qcom-firework-bmc``, ``quanta-q71l-bmc``, ``rainier-bmc``, ``romulus-bmc``, ``sonorapass-bmc``, ``supermicrox11-bmc``, ``tiogapass-bmc``, ``tacoma-bmc``, ``witherspoon-bmc``, ``yosemitev2-bmc``)
24
17
-========================================================================================================================================================================================================================================================================================================================================================================================================
25
dev = qdev_new(TYPE_MSF2_SOC);
18
+Aspeed family boards (``ast2500-evb``, ``ast2600-evb``, ``ast2700-evb``, ``bletchley-bmc``, ``fuji-bmc``, ``fby35-bmc``, ``fp5280g2-bmc``, ``g220a-bmc``, ``palmetto-bmc``, ``qcom-dc-scm-v1-bmc``, ``qcom-firework-bmc``, ``quanta-q71l-bmc``, ``rainier-bmc``, ``romulus-bmc``, ``sonorapass-bmc``, ``supermicrox11-bmc``, ``supermicrox11spi-bmc``, ``tiogapass-bmc``, ``tacoma-bmc``, ``witherspoon-bmc``, ``yosemitev2-bmc``)
26
+ object_property_add_child(OBJECT(machine), "soc", OBJECT(dev));
19
+==================================================================================================================================================================================================================================================================================================================================================================================================================================
27
qdev_prop_set_string(dev, "part-name", "M2S010");
20
28
qdev_prop_set_string(dev, "cpu-type", mc->default_cpu_type);
21
The QEMU Aspeed machines model BMCs of various OpenPOWER systems and
29
22
Aspeed evaluation boards. They are based on different releases of the
30
diff --git a/hw/arm/netduino2.c b/hw/arm/netduino2.c
23
@@ -XXX,XX +XXX,XX @@ AST2400 SoC based machines :
31
index XXXXXXX..XXXXXXX 100644
24
32
--- a/hw/arm/netduino2.c
25
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
33
+++ b/hw/arm/netduino2.c
26
- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
34
@@ -XXX,XX +XXX,XX @@ static void netduino2_init(MachineState *machine)
27
-- ``supermicrox11-bmc`` Supermicro X11 BMC
35
clock_set_hz(sysclk, SYSCLK_FRQ);
28
+- ``supermicrox11-bmc`` Supermicro X11 BMC (ARM926EJ-S)
36
29
+- ``supermicrox11spi-bmc`` Supermicro X11 SPI BMC (ARM1176)
37
dev = qdev_new(TYPE_STM32F205_SOC);
30
38
+ object_property_add_child(OBJECT(machine), "soc", OBJECT(dev));
31
AST2500 SoC based machines :
39
qdev_connect_clock_in(dev, "sysclk", sysclk);
40
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
41
42
diff --git a/hw/arm/netduinoplus2.c b/hw/arm/netduinoplus2.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/arm/netduinoplus2.c
45
+++ b/hw/arm/netduinoplus2.c
46
@@ -XXX,XX +XXX,XX @@ static void netduinoplus2_init(MachineState *machine)
47
clock_set_hz(sysclk, SYSCLK_FRQ);
48
49
dev = qdev_new(TYPE_STM32F405_SOC);
50
+ object_property_add_child(OBJECT(machine), "soc", OBJECT(dev));
51
qdev_connect_clock_in(dev, "sysclk", sysclk);
52
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
53
54
diff --git a/hw/arm/olimex-stm32-h405.c b/hw/arm/olimex-stm32-h405.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/arm/olimex-stm32-h405.c
57
+++ b/hw/arm/olimex-stm32-h405.c
58
@@ -XXX,XX +XXX,XX @@ static void olimex_stm32_h405_init(MachineState *machine)
59
clock_set_hz(sysclk, SYSCLK_FRQ);
60
61
dev = qdev_new(TYPE_STM32F405_SOC);
62
+ object_property_add_child(OBJECT(machine), "soc", OBJECT(dev));
63
qdev_connect_clock_in(dev, "sysclk", sysclk);
64
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
65
66
diff --git a/hw/arm/stm32vldiscovery.c b/hw/arm/stm32vldiscovery.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/arm/stm32vldiscovery.c
69
+++ b/hw/arm/stm32vldiscovery.c
70
@@ -XXX,XX +XXX,XX @@ static void stm32vldiscovery_init(MachineState *machine)
71
clock_set_hz(sysclk, SYSCLK_FRQ);
72
73
dev = qdev_new(TYPE_STM32F100_SOC);
74
+ object_property_add_child(OBJECT(machine), "soc", OBJECT(dev));
75
qdev_connect_clock_in(dev, "sysclk", sysclk);
76
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
77
32
78
--
33
--
79
2.34.1
34
2.34.1
80
81
diff view generated by jsdifflib
Deleted patch
1
The CTR_EL0 register has some bits which allow the implementation to
2
tell the guest that it does not need to do cache maintenance for
3
data-to-instruction coherence and instruction-to-data coherence.
4
QEMU doesn't emulate caches and so our cache maintenance insns are
5
all NOPs.
6
1
7
We already have some models of specific CPUs where we set these bits
8
(e.g. the Neoverse V1), but the 'max' CPU still uses the settings it
9
inherits from Cortex-A57. Set the bits for 'max' as well, so the
10
guest doesn't need to do unnecessary work.
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Tested-by: Miguel Luis <miguel.luis@oracle.com>
15
---
16
target/arm/tcg/cpu64.c | 10 ++++++++++
17
1 file changed, 10 insertions(+)
18
19
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/tcg/cpu64.c
22
+++ b/target/arm/tcg/cpu64.c
23
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
24
u = FIELD_DP32(u, CLIDR_EL1, LOUU, 0);
25
cpu->clidr = u;
26
27
+ /*
28
+ * Set CTR_EL0.DIC and IDC to tell the guest it doesnt' need to
29
+ * do any cache maintenance for data-to-instruction or
30
+ * instruction-to-guest coherence. (Our cache ops are nops.)
31
+ */
32
+ t = cpu->ctr;
33
+ t = FIELD_DP64(t, CTR_EL0, IDC, 1);
34
+ t = FIELD_DP64(t, CTR_EL0, DIC, 1);
35
+ cpu->ctr = t;
36
+
37
t = cpu->isar.id_aa64isar0;
38
t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* FEAT_PMULL */
39
t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1); /* FEAT_SHA1 */
40
--
41
2.34.1
diff view generated by jsdifflib
Deleted patch
1
The hypervisor can deliver (virtual) LPIs to a guest by setting up a
2
list register to have an intid which is an LPI. The GIC has to treat
3
these a little differently to standard interrupt IDs, because LPIs
4
have no Active state, and so the guest will only EOI them, it will
5
not also deactivate them. So icv_eoir_write() must do two things:
6
1
7
* if the LPI ID is not in any list register, we drop the
8
priority but do not increment the EOI count
9
* if the LPI ID is in a list register, we immediately deactivate
10
it, regardless of the split-drop-and-deactivate control
11
12
This can be seen in the VirtualWriteEOIR0() and VirtualWriteEOIR1()
13
pseudocode in the GICv3 architecture specification.
14
15
Without this fix, potentially a hypervisor guest might stall because
16
LPIs get stuck in a bogus Active+Pending state.
17
18
Cc: qemu-stable@nongnu.org
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Tested-by: Miguel Luis <miguel.luis@oracle.com>
22
---
23
hw/intc/arm_gicv3_cpuif.c | 17 +++++++++++++----
24
1 file changed, 13 insertions(+), 4 deletions(-)
25
26
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/intc/arm_gicv3_cpuif.c
29
+++ b/hw/intc/arm_gicv3_cpuif.c
30
@@ -XXX,XX +XXX,XX @@ static void icv_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri,
31
idx = icv_find_active(cs, irq);
32
33
if (idx < 0) {
34
- /* No valid list register corresponding to EOI ID */
35
- icv_increment_eoicount(cs);
36
+ /*
37
+ * No valid list register corresponding to EOI ID; if this is a vLPI
38
+ * not in the list regs then do nothing; otherwise increment EOI count
39
+ */
40
+ if (irq < GICV3_LPI_INTID_START) {
41
+ icv_increment_eoicount(cs);
42
+ }
43
} else {
44
uint64_t lr = cs->ich_lr_el2[idx];
45
int thisgrp = (lr & ICH_LR_EL2_GROUP) ? GICV3_G1NS : GICV3_G0;
46
int lr_gprio = ich_lr_prio(lr) & icv_gprio_mask(cs, grp);
47
48
if (thisgrp == grp && lr_gprio == dropprio) {
49
- if (!icv_eoi_split(env, cs)) {
50
- /* Priority drop and deactivate not split: deactivate irq now */
51
+ if (!icv_eoi_split(env, cs) || irq >= GICV3_LPI_INTID_START) {
52
+ /*
53
+ * Priority drop and deactivate not split: deactivate irq now.
54
+ * LPIs always get their active state cleared immediately
55
+ * because no separate deactivate is expected.
56
+ */
57
icv_deactivate_irq(cs, idx);
58
}
59
}
60
--
61
2.34.1
diff view generated by jsdifflib
Deleted patch
1
FEAT_NV defines three new bits in HCR_EL2: NV, NV1 and AT. When the
2
feature is enabled, allow these bits to be written, and flush the
3
TLBs for the bits which affect page table interpretation.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Miguel Luis <miguel.luis@oracle.com>
8
---
9
target/arm/cpu-features.h | 5 +++++
10
target/arm/helper.c | 6 +++++-
11
2 files changed, 10 insertions(+), 1 deletion(-)
12
13
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu-features.h
16
+++ b/target/arm/cpu-features.h
17
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_e0pd(const ARMISARegisters *id)
18
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, E0PD) != 0;
19
}
20
21
+static inline bool isar_feature_aa64_nv(const ARMISARegisters *id)
22
+{
23
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, NV) != 0;
24
+}
25
+
26
static inline bool isar_feature_aa64_pmuv3p1(const ARMISARegisters *id)
27
{
28
return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 4 &&
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 @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
34
if (cpu_isar_feature(aa64_rme, cpu)) {
35
valid_mask |= HCR_GPF;
36
}
37
+ if (cpu_isar_feature(aa64_nv, cpu)) {
38
+ valid_mask |= HCR_NV | HCR_NV1 | HCR_AT;
39
+ }
40
}
41
42
if (cpu_isar_feature(any_evt, cpu)) {
43
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
44
* HCR_DC disables stage1 and enables stage2 translation
45
* HCR_DCT enables tagging on (disabled) stage1 translation
46
* HCR_FWB changes the interpretation of stage2 descriptor bits
47
+ * HCR_NV and HCR_NV1 affect interpretation of descriptor bits
48
*/
49
if ((env->cp15.hcr_el2 ^ value) &
50
- (HCR_VM | HCR_PTW | HCR_DC | HCR_DCT | HCR_FWB)) {
51
+ (HCR_VM | HCR_PTW | HCR_DC | HCR_DCT | HCR_FWB | HCR_NV | HCR_NV1)) {
52
tlb_flush(CPU(cpu));
53
}
54
env->cp15.hcr_el2 = value;
55
--
56
2.34.1
diff view generated by jsdifflib
Deleted patch
1
The FEAT_NV HCR_EL2.AT bit enables trapping of some address
2
translation instructions from EL1 to EL2. Implement this behaviour.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Miguel Luis <miguel.luis@oracle.com>
7
---
8
target/arm/helper.c | 21 +++++++++++++++------
9
1 file changed, 15 insertions(+), 6 deletions(-)
10
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
14
+++ b/target/arm/helper.c
15
@@ -XXX,XX +XXX,XX @@ static CPAccessResult at_s1e2_access(CPUARMState *env, const ARMCPRegInfo *ri,
16
return at_e012_access(env, ri, isread);
17
}
18
19
+static CPAccessResult at_s1e01_access(CPUARMState *env, const ARMCPRegInfo *ri,
20
+ bool isread)
21
+{
22
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_AT)) {
23
+ return CP_ACCESS_TRAP_EL2;
24
+ }
25
+ return at_e012_access(env, ri, isread);
26
+}
27
+
28
static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
29
uint64_t value)
30
{
31
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
32
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 0,
33
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
34
.fgt = FGT_ATS1E1R,
35
- .accessfn = at_e012_access, .writefn = ats_write64 },
36
+ .accessfn = at_s1e01_access, .writefn = ats_write64 },
37
{ .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64,
38
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 1,
39
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
40
.fgt = FGT_ATS1E1W,
41
- .accessfn = at_e012_access, .writefn = ats_write64 },
42
+ .accessfn = at_s1e01_access, .writefn = ats_write64 },
43
{ .name = "AT_S1E0R", .state = ARM_CP_STATE_AA64,
44
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 2,
45
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
46
.fgt = FGT_ATS1E0R,
47
- .accessfn = at_e012_access, .writefn = ats_write64 },
48
+ .accessfn = at_s1e01_access, .writefn = ats_write64 },
49
{ .name = "AT_S1E0W", .state = ARM_CP_STATE_AA64,
50
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 3,
51
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
52
.fgt = FGT_ATS1E0W,
53
- .accessfn = at_e012_access, .writefn = ats_write64 },
54
+ .accessfn = at_s1e01_access, .writefn = ats_write64 },
55
{ .name = "AT_S12E1R", .state = ARM_CP_STATE_AA64,
56
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 4,
57
.access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
58
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo ats1e1_reginfo[] = {
59
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 0,
60
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
61
.fgt = FGT_ATS1E1RP,
62
- .accessfn = at_e012_access, .writefn = ats_write64 },
63
+ .accessfn = at_s1e01_access, .writefn = ats_write64 },
64
{ .name = "AT_S1E1WP", .state = ARM_CP_STATE_AA64,
65
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1,
66
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
67
.fgt = FGT_ATS1E1WP,
68
- .accessfn = at_e012_access, .writefn = ats_write64 },
69
+ .accessfn = at_s1e01_access, .writefn = ats_write64 },
70
};
71
72
static const ARMCPRegInfo ats1cp_reginfo[] = {
73
--
74
2.34.1
diff view generated by jsdifflib
Deleted patch
1
When FEAT_NV is turned on via the HCR_EL2.NV bit, ERET instructions
2
are trapped, with the same syndrome information as for the existing
3
FEAT_FGT fine-grained trap (in the pseudocode this is handled in
4
AArch64.CheckForEretTrap()).
5
1
6
Rename the DisasContext and tbflag bits to reflect that they are
7
no longer exclusively for FGT traps, and set the tbflag bit when
8
FEAT_NV is enabled as well as when the FGT is enabled.
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Tested-by: Miguel Luis <miguel.luis@oracle.com>
13
---
14
target/arm/cpu.h | 2 +-
15
target/arm/tcg/translate.h | 4 ++--
16
target/arm/tcg/hflags.c | 11 ++++++++++-
17
target/arm/tcg/translate-a64.c | 6 +++---
18
4 files changed, 16 insertions(+), 7 deletions(-)
19
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
23
+++ b/target/arm/cpu.h
24
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, PSTATE_ZA, 23, 1)
25
FIELD(TBFLAG_A64, SVL, 24, 4)
26
/* Indicates that SME Streaming mode is active, and SMCR_ELx.FA64 is not. */
27
FIELD(TBFLAG_A64, SME_TRAP_NONSTREAMING, 28, 1)
28
-FIELD(TBFLAG_A64, FGT_ERET, 29, 1)
29
+FIELD(TBFLAG_A64, TRAP_ERET, 29, 1)
30
FIELD(TBFLAG_A64, NAA, 30, 1)
31
FIELD(TBFLAG_A64, ATA0, 31, 1)
32
33
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/tcg/translate.h
36
+++ b/target/arm/tcg/translate.h
37
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
38
bool mve_no_pred;
39
/* True if fine-grained traps are active */
40
bool fgt_active;
41
- /* True if fine-grained trap on ERET is enabled */
42
- bool fgt_eret;
43
/* True if fine-grained trap on SVC is enabled */
44
bool fgt_svc;
45
+ /* True if a trap on ERET is enabled (FGT or NV) */
46
+ bool trap_eret;
47
/* True if FEAT_LSE2 SCTLR_ELx.nAA is set */
48
bool naa;
49
/*
50
diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/tcg/hflags.c
53
+++ b/target/arm/tcg/hflags.c
54
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
55
CPUARMTBFlags flags = {};
56
ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
57
uint64_t tcr = regime_tcr(env, mmu_idx);
58
+ uint64_t hcr = arm_hcr_el2_eff(env);
59
uint64_t sctlr;
60
int tbii, tbid;
61
62
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
63
if (arm_fgt_active(env, el)) {
64
DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1);
65
if (FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, ERET)) {
66
- DP_TBFLAG_A64(flags, FGT_ERET, 1);
67
+ DP_TBFLAG_A64(flags, TRAP_ERET, 1);
68
}
69
if (fgt_svc(env, el)) {
70
DP_TBFLAG_ANY(flags, FGT_SVC, 1);
71
}
72
}
73
74
+ /*
75
+ * ERET can also be trapped for FEAT_NV. arm_hcr_el2_eff() takes care
76
+ * of "is EL2 enabled" and the NV bit can only be set if FEAT_NV is present.
77
+ */
78
+ if (el == 1 && (hcr & HCR_NV)) {
79
+ DP_TBFLAG_A64(flags, TRAP_ERET, 1);
80
+ }
81
+
82
if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
83
/*
84
* Set MTE_ACTIVE if any access may be Checked, and leave clear
85
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/target/arm/tcg/translate-a64.c
88
+++ b/target/arm/tcg/translate-a64.c
89
@@ -XXX,XX +XXX,XX @@ static bool trans_ERET(DisasContext *s, arg_ERET *a)
90
if (s->current_el == 0) {
91
return false;
92
}
93
- if (s->fgt_eret) {
94
+ if (s->trap_eret) {
95
gen_exception_insn_el(s, 0, EXCP_UDEF, syn_erettrap(0), 2);
96
return true;
97
}
98
@@ -XXX,XX +XXX,XX @@ static bool trans_ERETA(DisasContext *s, arg_reta *a)
99
return false;
100
}
101
/* The FGT trap takes precedence over an auth trap. */
102
- if (s->fgt_eret) {
103
+ if (s->trap_eret) {
104
gen_exception_insn_el(s, 0, EXCP_UDEF, syn_erettrap(a->m ? 3 : 2), 2);
105
return true;
106
}
107
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
108
dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
109
dc->fgt_active = EX_TBFLAG_ANY(tb_flags, FGT_ACTIVE);
110
dc->fgt_svc = EX_TBFLAG_ANY(tb_flags, FGT_SVC);
111
- dc->fgt_eret = EX_TBFLAG_A64(tb_flags, FGT_ERET);
112
+ dc->trap_eret = EX_TBFLAG_A64(tb_flags, TRAP_ERET);
113
dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
114
dc->sme_excp_el = EX_TBFLAG_A64(tb_flags, SMEEXC_EL);
115
dc->vl = (EX_TBFLAG_A64(tb_flags, VL) + 1) * 16;
116
--
117
2.34.1
diff view generated by jsdifflib
Deleted patch
1
The HCR_EL2.TSC trap for trapping EL1 execution of SMC instructions
2
has a behaviour change for FEAT_NV when EL3 is not implemented:
3
1
4
* in older architecture versions TSC was required to have no
5
effect (i.e. the SMC insn UNDEFs)
6
* with FEAT_NV, when HCR_EL2.NV == 1 the trap must apply
7
(i.e. SMC traps to EL2, as it already does in all cases when
8
EL3 is implemented)
9
* in newer architecture versions, the behaviour either without
10
FEAT_NV or with FEAT_NV and HCR_EL2.NV == 0 is relaxed to
11
an IMPDEF choice between UNDEF and trap-to-EL2 (i.e. it is
12
permitted to always honour HCR_EL2.TSC) for AArch64 only
13
14
Add the condition to honour the trap bit when HCR_EL2.NV == 1. We
15
leave the HCR_EL2.NV == 0 case with the existing (UNDEF) behaviour,
16
as our IMPDEF choice (both because it avoids a behaviour change
17
for older CPU models and because we'd have to distinguish AArch32
18
from AArch64 if we opted to trap to EL2).
19
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Tested-by: Miguel Luis <miguel.luis@oracle.com>
23
---
24
target/arm/tcg/op_helper.c | 16 +++++++++++++---
25
1 file changed, 13 insertions(+), 3 deletions(-)
26
27
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/tcg/op_helper.c
30
+++ b/target/arm/tcg/op_helper.c
31
@@ -XXX,XX +XXX,XX @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
32
*
33
* Conduit SMC, valid call Trap to EL2 PSCI Call
34
* Conduit SMC, inval call Trap to EL2 Undef insn
35
- * Conduit not SMC Undef insn Undef insn
36
+ * Conduit not SMC Undef or trap[1] Undef insn
37
+ *
38
+ * [1] In this case:
39
+ * - if HCR_EL2.NV == 1 we must trap to EL2
40
+ * - if HCR_EL2.NV == 0 then newer architecture revisions permit
41
+ * AArch64 (but not AArch32) to trap to EL2 as an IMPDEF choice
42
+ * - otherwise we must UNDEF
43
+ * We take the IMPDEF choice to always UNDEF if HCR_EL2.NV == 0.
44
*/
45
46
/* On ARMv8 with EL3 AArch64, SMD applies to both S and NS state.
47
@@ -XXX,XX +XXX,XX @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
48
: smd_flag && !secure;
49
50
if (!arm_feature(env, ARM_FEATURE_EL3) &&
51
+ !(arm_hcr_el2_eff(env) & HCR_NV) &&
52
cpu->psci_conduit != QEMU_PSCI_CONDUIT_SMC) {
53
- /* If we have no EL3 then SMC always UNDEFs and can't be
54
- * trapped to EL2. PSCI-via-SMC is a sort of ersatz EL3
55
+ /*
56
+ * If we have no EL3 then traditionally SMC always UNDEFs and can't be
57
+ * trapped to EL2. For nested virtualization, SMC can be trapped to
58
+ * the outer hypervisor. PSCI-via-SMC is a sort of ersatz EL3
59
* firmware within QEMU, and we want an EL2 guest to be able
60
* to forbid its EL1 from making PSCI calls into QEMU's
61
* "firmware" via HCR.TSC, so for these purposes treat
62
--
63
2.34.1
diff view generated by jsdifflib
Deleted patch
1
The TBFLAG_A64 TB flag bits go in flags2, which for AArch64 guests
2
we know is 64 bits. However at the moment we use FIELD_EX32() and
3
FIELD_DP32() to read and write these bits, which only works for
4
bits 0 to 31. Since we're about to add a flag that uses bit 32,
5
switch to FIELD_EX64() and FIELD_DP64() so that this will work.
6
1
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Miguel Luis <miguel.luis@oracle.com>
10
---
11
target/arm/cpu.h | 8 +++++---
12
1 file changed, 5 insertions(+), 3 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(TBFLAG_A64, NAA, 30, 1)
19
FIELD(TBFLAG_A64, ATA0, 31, 1)
20
21
/*
22
- * Helpers for using the above.
23
+ * Helpers for using the above. Note that only the A64 accessors use
24
+ * FIELD_DP64() and FIELD_EX64(), because in the other cases the flags
25
+ * word either is or might be 32 bits only.
26
*/
27
#define DP_TBFLAG_ANY(DST, WHICH, VAL) \
28
(DST.flags = FIELD_DP32(DST.flags, TBFLAG_ANY, WHICH, VAL))
29
#define DP_TBFLAG_A64(DST, WHICH, VAL) \
30
- (DST.flags2 = FIELD_DP32(DST.flags2, TBFLAG_A64, WHICH, VAL))
31
+ (DST.flags2 = FIELD_DP64(DST.flags2, TBFLAG_A64, WHICH, VAL))
32
#define DP_TBFLAG_A32(DST, WHICH, VAL) \
33
(DST.flags2 = FIELD_DP32(DST.flags2, TBFLAG_A32, WHICH, VAL))
34
#define DP_TBFLAG_M32(DST, WHICH, VAL) \
35
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, ATA0, 31, 1)
36
(DST.flags2 = FIELD_DP32(DST.flags2, TBFLAG_AM32, WHICH, VAL))
37
38
#define EX_TBFLAG_ANY(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_ANY, WHICH)
39
-#define EX_TBFLAG_A64(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_A64, WHICH)
40
+#define EX_TBFLAG_A64(IN, WHICH) FIELD_EX64(IN.flags2, TBFLAG_A64, WHICH)
41
#define EX_TBFLAG_A32(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_A32, WHICH)
42
#define EX_TBFLAG_M32(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_M32, WHICH)
43
#define EX_TBFLAG_AM32(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_AM32, WHICH)
44
--
45
2.34.1
diff view generated by jsdifflib
Deleted patch
1
For FEAT_VHE, we define a set of register aliases, so that for instance:
2
* the SCTLR_EL1 either accesses the real SCTLR_EL1, or (if E2H is 1)
3
SCTLR_EL2
4
* a new SCTLR_EL12 register accesses SCTLR_EL1 if E2H is 1
5
1
6
However when we create the 'new_reg' cpreg struct for the SCTLR_EL12
7
register, we duplicate the information in the SCTLR_EL1 cpreg, which
8
means the opcode fields are those of SCTLR_EL1, not SCTLR_EL12. This
9
is a problem for code which looks at the cpreg opcode fields to
10
determine behaviour (e.g. in access_check_cp_reg()). In practice
11
the current checks we do there don't intersect with the *_EL12
12
registers, but for FEAT_NV this will become a problem.
13
14
Write the correct values from the encoding into the new_reg struct.
15
This restores the invariant that the cpreg that you get back
16
from the hashtable has opcode fields that match the key you used
17
to retrieve it.
18
19
When we call the readfn or writefn for the target register, we
20
pass it the cpreg struct for that target register, not the one
21
for the alias, in case the readfn/writefn want to look at the
22
opcode fields to determine behaviour. This means we need to
23
interpose custom read/writefns for the e12 aliases.
24
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Tested-by: Miguel Luis <miguel.luis@oracle.com>
28
---
29
target/arm/helper.c | 35 +++++++++++++++++++++++++++++++++++
30
1 file changed, 35 insertions(+)
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 @@ static void el2_e2h_write(CPUARMState *env, const ARMCPRegInfo *ri,
37
writefn(env, ri, value);
38
}
39
40
+static uint64_t el2_e2h_e12_read(CPUARMState *env, const ARMCPRegInfo *ri)
41
+{
42
+ /* Pass the EL1 register accessor its ri, not the EL12 alias ri */
43
+ return ri->orig_readfn(env, ri->opaque);
44
+}
45
+
46
+static void el2_e2h_e12_write(CPUARMState *env, const ARMCPRegInfo *ri,
47
+ uint64_t value)
48
+{
49
+ /* Pass the EL1 register accessor its ri, not the EL12 alias ri */
50
+ return ri->orig_writefn(env, ri->opaque, value);
51
+}
52
+
53
static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
54
{
55
struct E2HAlias {
56
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
57
new_reg->type |= ARM_CP_ALIAS;
58
/* Remove PL1/PL0 access, leaving PL2/PL3 R/W in place. */
59
new_reg->access &= PL2_RW | PL3_RW;
60
+ /* The new_reg op fields are as per new_key, not the target reg */
61
+ new_reg->crn = (a->new_key & CP_REG_ARM64_SYSREG_CRN_MASK)
62
+ >> CP_REG_ARM64_SYSREG_CRN_SHIFT;
63
+ new_reg->crm = (a->new_key & CP_REG_ARM64_SYSREG_CRM_MASK)
64
+ >> CP_REG_ARM64_SYSREG_CRM_SHIFT;
65
+ new_reg->opc0 = (a->new_key & CP_REG_ARM64_SYSREG_OP0_MASK)
66
+ >> CP_REG_ARM64_SYSREG_OP0_SHIFT;
67
+ new_reg->opc1 = (a->new_key & CP_REG_ARM64_SYSREG_OP1_MASK)
68
+ >> CP_REG_ARM64_SYSREG_OP1_SHIFT;
69
+ new_reg->opc2 = (a->new_key & CP_REG_ARM64_SYSREG_OP2_MASK)
70
+ >> CP_REG_ARM64_SYSREG_OP2_SHIFT;
71
+ new_reg->opaque = src_reg;
72
+ new_reg->orig_readfn = src_reg->readfn ?: raw_read;
73
+ new_reg->orig_writefn = src_reg->writefn ?: raw_write;
74
+ if (!new_reg->raw_readfn) {
75
+ new_reg->raw_readfn = raw_read;
76
+ }
77
+ if (!new_reg->raw_writefn) {
78
+ new_reg->raw_writefn = raw_write;
79
+ }
80
+ new_reg->readfn = el2_e2h_e12_read;
81
+ new_reg->writefn = el2_e2h_e12_write;
82
83
ok = g_hash_table_insert(cpu->cp_regs,
84
(gpointer)(uintptr_t)a->new_key, new_reg);
85
--
86
2.34.1
diff view generated by jsdifflib
Deleted patch
1
The alias registers like SCTLR_EL12 only exist when HCR_EL2.E2H
2
is 1; they should UNDEF otherwise. We weren't implementing this.
3
Add an intercept of the accessfn for these aliases, and implement
4
the UNDEF check.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Miguel Luis <miguel.luis@oracle.com>
9
---
10
target/arm/cpregs.h | 3 ++-
11
target/arm/helper.c | 16 ++++++++++++++++
12
2 files changed, 18 insertions(+), 1 deletion(-)
13
14
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpregs.h
17
+++ b/target/arm/cpregs.h
18
@@ -XXX,XX +XXX,XX @@ struct ARMCPRegInfo {
19
CPResetFn *resetfn;
20
21
/*
22
- * "Original" writefn and readfn.
23
+ * "Original" readfn, writefn, accessfn.
24
* For ARMv8.1-VHE register aliases, we overwrite the read/write
25
* accessor functions of various EL1/EL0 to perform the runtime
26
* check for which sysreg should actually be modified, and then
27
@@ -XXX,XX +XXX,XX @@ struct ARMCPRegInfo {
28
*/
29
CPReadFn *orig_readfn;
30
CPWriteFn *orig_writefn;
31
+ CPAccessFn *orig_accessfn;
32
};
33
34
/*
35
diff --git a/target/arm/helper.c b/target/arm/helper.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper.c
38
+++ b/target/arm/helper.c
39
@@ -XXX,XX +XXX,XX @@ static void el2_e2h_e12_write(CPUARMState *env, const ARMCPRegInfo *ri,
40
return ri->orig_writefn(env, ri->opaque, value);
41
}
42
43
+static CPAccessResult el2_e2h_e12_access(CPUARMState *env,
44
+ const ARMCPRegInfo *ri,
45
+ bool isread)
46
+{
47
+ /* FOO_EL12 aliases only exist when E2H is 1; otherwise they UNDEF */
48
+ if (!(arm_hcr_el2_eff(env) & HCR_E2H)) {
49
+ return CP_ACCESS_TRAP_UNCATEGORIZED;
50
+ }
51
+ if (ri->orig_accessfn) {
52
+ return ri->orig_accessfn(env, ri->opaque, isread);
53
+ }
54
+ return CP_ACCESS_OK;
55
+}
56
+
57
static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
58
{
59
struct E2HAlias {
60
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
61
new_reg->opaque = src_reg;
62
new_reg->orig_readfn = src_reg->readfn ?: raw_read;
63
new_reg->orig_writefn = src_reg->writefn ?: raw_write;
64
+ new_reg->orig_accessfn = src_reg->accessfn;
65
if (!new_reg->raw_readfn) {
66
new_reg->raw_readfn = raw_read;
67
}
68
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
69
}
70
new_reg->readfn = el2_e2h_e12_read;
71
new_reg->writefn = el2_e2h_e12_write;
72
+ new_reg->accessfn = el2_e2h_e12_access;
73
74
ok = g_hash_table_insert(cpu->cp_regs,
75
(gpointer)(uintptr_t)a->new_key, new_reg);
76
--
77
2.34.1
diff view generated by jsdifflib
Deleted patch
1
FEAT_NV and FEAT_NV2 will allow EL1 to attempt to access cpregs that
2
only exist at EL2. This means we're going to want to run their
3
accessfns when the CPU is at EL1. In almost all cases, the behaviour
4
we want is "the accessfn returns OK if at EL1".
5
1
6
Mostly the accessfn already does the right thing; in a few cases we
7
need to explicitly check that the EL is not 1 before applying various
8
trap controls, or split out an accessfn used both for an _EL1 and an
9
_EL2 register into two so we can handle the FEAT_NV case correctly
10
for the _EL2 register.
11
12
There are two registers where we want the accessfn to trap for
13
a FEAT_NV EL1 access: VSTTBR_EL2 and VSTCR_EL2 should UNDEF
14
an access from NonSecure EL1, not trap to EL2 under FEAT_NV.
15
The way we have written sel2_access() already results in this
16
behaviour.
17
18
We can identify the registers we care about here because they
19
all have opc1 == 4 or 5.
20
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Tested-by: Miguel Luis <miguel.luis@oracle.com>
24
---
25
target/arm/debug_helper.c | 12 +++++++-
26
target/arm/helper.c | 65 ++++++++++++++++++++++++++++++++++-----
27
2 files changed, 69 insertions(+), 8 deletions(-)
28
29
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/debug_helper.c
32
+++ b/target/arm/debug_helper.c
33
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tda(CPUARMState *env, const ARMCPRegInfo *ri,
34
return CP_ACCESS_OK;
35
}
36
37
+static CPAccessResult access_dbgvcr32(CPUARMState *env, const ARMCPRegInfo *ri,
38
+ bool isread)
39
+{
40
+ /* MCDR_EL3.TDMA doesn't apply for FEAT_NV traps */
41
+ if (arm_current_el(env) == 2 && (env->cp15.mdcr_el3 & MDCR_TDA)) {
42
+ return CP_ACCESS_TRAP_EL3;
43
+ }
44
+ return CP_ACCESS_OK;
45
+}
46
+
47
/*
48
* Check for traps to Debug Comms Channel registers. If FEAT_FGT
49
* is implemented then these are controlled by MDCR_EL2.TDCC for
50
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_aa32_el1_reginfo[] = {
51
*/
52
{ .name = "DBGVCR32_EL2", .state = ARM_CP_STATE_AA64,
53
.opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0,
54
- .access = PL2_RW, .accessfn = access_tda,
55
+ .access = PL2_RW, .accessfn = access_dbgvcr32,
56
.type = ARM_CP_NOP | ARM_CP_EL3_NO_EL2_KEEP },
57
};
58
59
diff --git a/target/arm/helper.c b/target/arm/helper.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/target/arm/helper.c
62
+++ b/target/arm/helper.c
63
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
64
static CPAccessResult e2h_access(CPUARMState *env, const ARMCPRegInfo *ri,
65
bool isread)
66
{
67
+ if (arm_current_el(env) == 1) {
68
+ /* This must be a FEAT_NV access */
69
+ /* TODO: FEAT_ECV will need to check CNTHCTL_EL2 here */
70
+ return CP_ACCESS_OK;
71
+ }
72
if (!(arm_hcr_el2_eff(env) & HCR_E2H)) {
73
return CP_ACCESS_TRAP;
74
}
75
@@ -XXX,XX +XXX,XX @@ static void hcrx_write(CPUARMState *env, const ARMCPRegInfo *ri,
76
static CPAccessResult access_hxen(CPUARMState *env, const ARMCPRegInfo *ri,
77
bool isread)
78
{
79
- if (arm_current_el(env) < 3
80
+ if (arm_current_el(env) == 2
81
&& arm_feature(env, ARM_FEATURE_EL3)
82
&& !(env->cp15.scr_el3 & SCR_HXEN)) {
83
return CP_ACCESS_TRAP_EL3;
84
@@ -XXX,XX +XXX,XX @@ static CPAccessResult el2_e2h_e12_access(CPUARMState *env,
85
const ARMCPRegInfo *ri,
86
bool isread)
87
{
88
+ if (arm_current_el(env) == 1) {
89
+ /*
90
+ * This must be a FEAT_NV access (will either trap or redirect
91
+ * to memory). None of the registers with _EL12 aliases want to
92
+ * apply their trap controls for this kind of access, so don't
93
+ * call the orig_accessfn or do the "UNDEF when E2H is 0" check.
94
+ */
95
+ return CP_ACCESS_OK;
96
+ }
97
/* FOO_EL12 aliases only exist when E2H is 1; otherwise they UNDEF */
98
if (!(arm_hcr_el2_eff(env) & HCR_E2H)) {
99
return CP_ACCESS_TRAP_UNCATEGORIZED;
100
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tpidr2(CPUARMState *env, const ARMCPRegInfo *ri,
101
return CP_ACCESS_OK;
102
}
103
104
-static CPAccessResult access_esm(CPUARMState *env, const ARMCPRegInfo *ri,
105
- bool isread)
106
+static CPAccessResult access_smprimap(CPUARMState *env, const ARMCPRegInfo *ri,
107
+ bool isread)
108
+{
109
+ /* If EL1 this is a FEAT_NV access and CPTR_EL3.ESM doesn't apply */
110
+ if (arm_current_el(env) == 2
111
+ && arm_feature(env, ARM_FEATURE_EL3)
112
+ && !FIELD_EX64(env->cp15.cptr_el[3], CPTR_EL3, ESM)) {
113
+ return CP_ACCESS_TRAP_EL3;
114
+ }
115
+ return CP_ACCESS_OK;
116
+}
117
+
118
+static CPAccessResult access_smpri(CPUARMState *env, const ARMCPRegInfo *ri,
119
+ bool isread)
120
{
121
- /* TODO: FEAT_FGT for SMPRI_EL1 but not SMPRIMAP_EL2 */
122
if (arm_current_el(env) < 3
123
&& arm_feature(env, ARM_FEATURE_EL3)
124
&& !FIELD_EX64(env->cp15.cptr_el[3], CPTR_EL3, ESM)) {
125
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo sme_reginfo[] = {
126
*/
127
{ .name = "SMPRI_EL1", .state = ARM_CP_STATE_AA64,
128
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 4,
129
- .access = PL1_RW, .accessfn = access_esm,
130
+ .access = PL1_RW, .accessfn = access_smpri,
131
.fgt = FGT_NSMPRI_EL1,
132
.type = ARM_CP_CONST, .resetvalue = 0 },
133
{ .name = "SMPRIMAP_EL2", .state = ARM_CP_STATE_AA64,
134
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 5,
135
- .access = PL2_RW, .accessfn = access_esm,
136
+ .access = PL2_RW, .accessfn = access_smprimap,
137
.type = ARM_CP_CONST, .resetvalue = 0 },
138
};
139
140
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_mte(CPUARMState *env, const ARMCPRegInfo *ri,
141
bool isread)
142
{
143
int el = arm_current_el(env);
144
+ if (el < 2 && arm_is_el2_enabled(env)) {
145
+ uint64_t hcr = arm_hcr_el2_eff(env);
146
+ if (!(hcr & HCR_ATA) && (!(hcr & HCR_E2H) || !(hcr & HCR_TGE))) {
147
+ return CP_ACCESS_TRAP_EL2;
148
+ }
149
+ }
150
+ if (el < 3 &&
151
+ arm_feature(env, ARM_FEATURE_EL3) &&
152
+ !(env->cp15.scr_el3 & SCR_ATA)) {
153
+ return CP_ACCESS_TRAP_EL3;
154
+ }
155
+ return CP_ACCESS_OK;
156
+}
157
158
+static CPAccessResult access_tfsr_el2(CPUARMState *env, const ARMCPRegInfo *ri,
159
+ bool isread)
160
+{
161
+ /*
162
+ * TFSR_EL2: similar to generic access_mte(), but we need to
163
+ * account for FEAT_NV. At EL1 this must be a FEAT_NV access;
164
+ * we will trap to EL2 and the HCR/SCR traps do not apply.
165
+ */
166
+ int el = arm_current_el(env);
167
+
168
+ if (el == 1) {
169
+ return CP_ACCESS_OK;
170
+ }
171
if (el < 2 && arm_is_el2_enabled(env)) {
172
uint64_t hcr = arm_hcr_el2_eff(env);
173
if (!(hcr & HCR_ATA) && (!(hcr & HCR_E2H) || !(hcr & HCR_TGE))) {
174
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_reginfo[] = {
175
.fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[1]) },
176
{ .name = "TFSR_EL2", .state = ARM_CP_STATE_AA64,
177
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 6, .opc2 = 0,
178
- .access = PL2_RW, .accessfn = access_mte,
179
+ .access = PL2_RW, .accessfn = access_tfsr_el2,
180
.fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[2]) },
181
{ .name = "TFSR_EL3", .state = ARM_CP_STATE_AA64,
182
.opc0 = 3, .opc1 = 6, .crn = 5, .crm = 6, .opc2 = 0,
183
--
184
2.34.1
diff view generated by jsdifflib
Deleted patch
1
In handle_sys() we don't do the check for whether the register is
2
marked as needing an FPU/SVE/SME access check until after we've
3
handled the special cases covered by ARM_CP_SPECIAL_MASK. This is
4
conceptually the wrong way around, because if for example we happen
5
to implement an FPU-access-checked register as ARM_CP_NOP, we should
6
do the access check first.
7
1
8
Move the access checks up so they are with all the other access
9
checks, not sandwiched between the special-case read/write handling
10
and the normal-case read/write handling. This doesn't change
11
behaviour at the moment, because we happen not to define any
12
cpregs with both ARM_CPU_{FPU,SVE,SME} and one of the cases
13
dealt with by ARM_CP_SPECIAL_MASK.
14
15
Moving this code also means we have the correct place to put the
16
FEAT_NV/FEAT_NV2 access handling, which should come after the access
17
checks and before we try to do any read/write action.
18
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Tested-by: Miguel Luis <miguel.luis@oracle.com>
22
---
23
target/arm/tcg/translate-a64.c | 15 ++++++++-------
24
1 file changed, 8 insertions(+), 7 deletions(-)
25
26
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/tcg/translate-a64.c
29
+++ b/target/arm/tcg/translate-a64.c
30
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
31
gen_a64_update_pc(s, 0);
32
}
33
34
+ if ((ri->type & ARM_CP_FPU) && !fp_access_check_only(s)) {
35
+ return;
36
+ } else if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
37
+ return;
38
+ } else if ((ri->type & ARM_CP_SME) && !sme_access_check(s)) {
39
+ return;
40
+ }
41
+
42
/* Handle special cases first */
43
switch (ri->type & ARM_CP_SPECIAL_MASK) {
44
case 0:
45
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
46
default:
47
g_assert_not_reached();
48
}
49
- if ((ri->type & ARM_CP_FPU) && !fp_access_check_only(s)) {
50
- return;
51
- } else if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
52
- return;
53
- } else if ((ri->type & ARM_CP_SME) && !sme_access_check(s)) {
54
- return;
55
- }
56
57
if (ri->type & ARM_CP_IO) {
58
/* I/O operations must end the TB here (whether read or write) */
59
--
60
2.34.1
diff view generated by jsdifflib
Deleted patch
1
For FEAT_NV, accesses to system registers and instructions from EL1
2
which would normally UNDEF there but which work in EL2 need to
3
instead be trapped to EL2. Detect this both for "we know this will
4
UNDEF at translate time" and "we found this UNDEFs at runtime", and
5
make the affected registers trap to EL2 instead.
6
1
7
The Arm ARM defines the set of registers that should trap in terms
8
of their names; for our implementation this would be both awkward
9
and inefficent as a test, so we instead trap based on the opc1
10
field of the sysreg. The regularity of the architectural choice
11
of encodings for sysregs means that in practice this captures
12
exactly the correct set of registers.
13
14
Regardless of how we try to define the registers this trapping
15
applies to, there's going to be a certain possibility of breakage
16
if new architectural features introduce new registers that don't
17
follow the current rules (FEAT_MEC is one example already visible
18
in the released sysreg XML, though not yet in the Arm ARM). This
19
approach seems to me to be straightforward and likely to require
20
a minimum of manual overrides.
21
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Tested-by: Miguel Luis <miguel.luis@oracle.com>
25
---
26
target/arm/cpregs.h | 34 +++++++++++++++++++++++
27
target/arm/cpu.h | 1 +
28
target/arm/tcg/translate.h | 2 ++
29
target/arm/tcg/hflags.c | 1 +
30
target/arm/tcg/translate-a64.c | 49 +++++++++++++++++++++++++++-------
31
5 files changed, 77 insertions(+), 10 deletions(-)
32
33
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/cpregs.h
36
+++ b/target/arm/cpregs.h
37
@@ -XXX,XX +XXX,XX @@ void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu);
38
39
CPAccessResult access_tvm_trvm(CPUARMState *, const ARMCPRegInfo *, bool);
40
41
+/**
42
+ * arm_cpreg_trap_in_nv: Return true if cpreg traps in nested virtualization
43
+ *
44
+ * Return true if this cpreg is one which should be trapped to EL2 if
45
+ * it is executed at EL1 when nested virtualization is enabled via HCR_EL2.NV.
46
+ */
47
+static inline bool arm_cpreg_traps_in_nv(const ARMCPRegInfo *ri)
48
+{
49
+ /*
50
+ * The Arm ARM defines the registers to be trapped in terms of
51
+ * their names (I_TZTZL). However the underlying principle is "if
52
+ * it would UNDEF at EL1 but work at EL2 then it should trap", and
53
+ * the way the encoding of sysregs and system instructions is done
54
+ * means that the right set of registers is exactly those where
55
+ * the opc1 field is 4 or 5. (You can see this also in the assert
56
+ * we do that the opc1 field and the permissions mask line up in
57
+ * define_one_arm_cp_reg_with_opaque().)
58
+ * Checking the opc1 field is easier for us and avoids the problem
59
+ * that we do not consistently use the right architectural names
60
+ * for all sysregs, since we treat the name field as largely for debug.
61
+ *
62
+ * However we do this check, it is going to be at least potentially
63
+ * fragile to future new sysregs, but this seems the least likely
64
+ * to break.
65
+ *
66
+ * In particular, note that the released sysreg XML defines that
67
+ * the FEAT_MEC sysregs and instructions do not follow this FEAT_NV
68
+ * trapping rule, so we will need to add an ARM_CP_* flag to indicate
69
+ * "register does not trap on NV" to handle those if/when we implement
70
+ * FEAT_MEC.
71
+ */
72
+ return ri->opc1 == 4 || ri->opc1 == 5;
73
+}
74
+
75
#endif /* TARGET_ARM_CPREGS_H */
76
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/cpu.h
79
+++ b/target/arm/cpu.h
80
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, SME_TRAP_NONSTREAMING, 28, 1)
81
FIELD(TBFLAG_A64, TRAP_ERET, 29, 1)
82
FIELD(TBFLAG_A64, NAA, 30, 1)
83
FIELD(TBFLAG_A64, ATA0, 31, 1)
84
+FIELD(TBFLAG_A64, NV, 32, 1)
85
86
/*
87
* Helpers for using the above. Note that only the A64 accessors use
88
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/tcg/translate.h
91
+++ b/target/arm/tcg/translate.h
92
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
93
bool trap_eret;
94
/* True if FEAT_LSE2 SCTLR_ELx.nAA is set */
95
bool naa;
96
+ /* True if FEAT_NV HCR_EL2.NV is enabled */
97
+ bool nv;
98
/*
99
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
100
* < 0, set by the current instruction.
101
diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c
102
index XXXXXXX..XXXXXXX 100644
103
--- a/target/arm/tcg/hflags.c
104
+++ b/target/arm/tcg/hflags.c
105
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
106
*/
107
if (el == 1 && (hcr & HCR_NV)) {
108
DP_TBFLAG_A64(flags, TRAP_ERET, 1);
109
+ DP_TBFLAG_A64(flags, NV, 1);
110
}
111
112
if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
113
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/target/arm/tcg/translate-a64.c
116
+++ b/target/arm/tcg/translate-a64.c
117
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
118
crn, crm, op0, op1, op2);
119
const ARMCPRegInfo *ri = get_arm_cp_reginfo(s->cp_regs, key);
120
bool need_exit_tb = false;
121
+ bool nv_trap_to_el2 = false;
122
+ bool skip_fp_access_checks = false;
123
TCGv_ptr tcg_ri = NULL;
124
TCGv_i64 tcg_rt;
125
- uint32_t syndrome;
126
+ uint32_t syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
127
128
if (crn == 11 || crn == 15) {
129
/*
130
* Check for TIDCP trap, which must take precedence over
131
* the UNDEF for "no such register" etc.
132
*/
133
- syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
134
switch (s->current_el) {
135
case 0:
136
if (dc_isar_feature(aa64_tidcp1, s)) {
137
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
138
139
/* Check access permissions */
140
if (!cp_access_ok(s->current_el, ri, isread)) {
141
- gen_sysreg_undef(s, isread, op0, op1, op2, crn, crm, rt);
142
- return;
143
+ /*
144
+ * FEAT_NV/NV2 handling does not do the usual FP access checks
145
+ * for registers only accessible at EL2 (though it *does* do them
146
+ * for registers accessible at EL1).
147
+ */
148
+ skip_fp_access_checks = true;
149
+ if (s->nv && arm_cpreg_traps_in_nv(ri)) {
150
+ /*
151
+ * This register / instruction exists and is an EL2 register, so
152
+ * we must trap to EL2 if accessed in nested virtualization EL1
153
+ * instead of UNDEFing. We'll do that after the usual access checks.
154
+ * (This makes a difference only for a couple of registers like
155
+ * VSTTBR_EL2 where the "UNDEF if NonSecure" should take priority
156
+ * over the trap-to-EL2. Most trapped-by-FEAT_NV registers have
157
+ * an accessfn which does nothing when called from EL1, because
158
+ * the trap-to-EL3 controls which would apply to that register
159
+ * at EL2 don't take priority over the FEAT_NV trap-to-EL2.)
160
+ */
161
+ nv_trap_to_el2 = true;
162
+ } else {
163
+ gen_sysreg_undef(s, isread, op0, op1, op2, crn, crm, rt);
164
+ return;
165
+ }
166
}
167
168
if (ri->accessfn || (ri->fgt && s->fgt_active)) {
169
/* Emit code to perform further access permissions checks at
170
* runtime; this may result in an exception.
171
*/
172
- syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
173
gen_a64_update_pc(s, 0);
174
tcg_ri = tcg_temp_new_ptr();
175
gen_helper_access_check_cp_reg(tcg_ri, tcg_env,
176
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
177
gen_a64_update_pc(s, 0);
178
}
179
180
- if ((ri->type & ARM_CP_FPU) && !fp_access_check_only(s)) {
181
- return;
182
- } else if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
183
- return;
184
- } else if ((ri->type & ARM_CP_SME) && !sme_access_check(s)) {
185
+ if (!skip_fp_access_checks) {
186
+ if ((ri->type & ARM_CP_FPU) && !fp_access_check_only(s)) {
187
+ return;
188
+ } else if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
189
+ return;
190
+ } else if ((ri->type & ARM_CP_SME) && !sme_access_check(s)) {
191
+ return;
192
+ }
193
+ }
194
+
195
+ if (nv_trap_to_el2) {
196
+ gen_exception_insn_el(s, 0, EXCP_UDEF, syndrome, 2);
197
return;
198
}
199
200
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
201
dc->pstate_za = EX_TBFLAG_A64(tb_flags, PSTATE_ZA);
202
dc->sme_trap_nonstreaming = EX_TBFLAG_A64(tb_flags, SME_TRAP_NONSTREAMING);
203
dc->naa = EX_TBFLAG_A64(tb_flags, NAA);
204
+ dc->nv = EX_TBFLAG_A64(tb_flags, NV);
205
dc->vec_len = 0;
206
dc->vec_stride = 0;
207
dc->cp_regs = arm_cpu->cp_regs;
208
--
209
2.34.1
diff view generated by jsdifflib
Deleted patch
1
FEAT_NV requires that when HCR_EL2.NV is set reads of the CurrentEL
2
register from EL1 always report EL2 rather than the real EL.
3
Implement this.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Miguel Luis <miguel.luis@oracle.com>
8
---
9
target/arm/tcg/translate-a64.c | 9 +++++++--
10
1 file changed, 7 insertions(+), 2 deletions(-)
11
12
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/tcg/translate-a64.c
15
+++ b/target/arm/tcg/translate-a64.c
16
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
17
}
18
return;
19
case ARM_CP_CURRENTEL:
20
- /* Reads as current EL value from pstate, which is
21
+ {
22
+ /*
23
+ * Reads as current EL value from pstate, which is
24
* guaranteed to be constant by the tb flags.
25
+ * For nested virt we should report EL2.
26
*/
27
+ int el = s->nv ? 2 : s->current_el;
28
tcg_rt = cpu_reg(s, rt);
29
- tcg_gen_movi_i64(tcg_rt, s->current_el << 2);
30
+ tcg_gen_movi_i64(tcg_rt, el << 2);
31
return;
32
+ }
33
case ARM_CP_DC_ZVA:
34
/* Writes clear the aligned block of memory which rt points into. */
35
if (s->mte_active[0]) {
36
--
37
2.34.1
diff view generated by jsdifflib
Deleted patch
1
FEAT_NV requires that when HCR_EL2.{NV,NV1} == {1,0} and an exception
2
is taken from EL1 to EL1 then the reported EL in SPSR_EL1.M should be
3
EL2, not EL1. Implement this behaviour.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Miguel Luis <miguel.luis@oracle.com>
8
---
9
target/arm/helper.c | 6 ++++++
10
1 file changed, 6 insertions(+)
11
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
15
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
17
old_mode = pstate_read(env);
18
aarch64_save_sp(env, arm_current_el(env));
19
env->elr_el[new_el] = env->pc;
20
+
21
+ if (cur_el == 1 && new_el == 1 &&
22
+ ((arm_hcr_el2_eff(env) & (HCR_NV | HCR_NV1)) == HCR_NV)) {
23
+ /* I_ZJRNN: report EL2 in the SPSR by setting M[3:2] to 0b10 */
24
+ old_mode = deposit32(old_mode, 2, 2, 2);
25
+ }
26
} else {
27
old_mode = cpsr_read_for_spsr_elx(env);
28
env->elr_el[new_el] = env->regs[15];
29
--
30
2.34.1
diff view generated by jsdifflib
Deleted patch
1
When HCR_EL2.{NV,NV1} is {1,1} we must trap five extra registers to
2
EL2: VBAR_EL1, ELR_EL1, SPSR_EL1, SCXTNUM_EL1 and TFSR_EL1.
3
Implement these traps.
4
1
5
This trap does not apply when FEAT_NV2 is implemented and enabled;
6
include the check that HCR_EL2.NV2 is 0 here, to save us having
7
to come back and add it later.
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Tested-by: Miguel Luis <miguel.luis@oracle.com>
12
---
13
target/arm/helper.c | 45 +++++++++++++++++++++++++++++++++++++++++----
14
1 file changed, 41 insertions(+), 4 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 mdcr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
21
}
22
}
23
24
+static CPAccessResult access_nv1(CPUARMState *env, const ARMCPRegInfo *ri,
25
+ bool isread)
26
+{
27
+ if (arm_current_el(env) == 1) {
28
+ uint64_t hcr_nv = arm_hcr_el2_eff(env) & (HCR_NV | HCR_NV1 | HCR_NV2);
29
+
30
+ if (hcr_nv == (HCR_NV | HCR_NV1)) {
31
+ return CP_ACCESS_TRAP_EL2;
32
+ }
33
+ }
34
+ return CP_ACCESS_OK;
35
+}
36
+
37
#ifdef CONFIG_USER_ONLY
38
/*
39
* `IC IVAU` is handled to improve compatibility with JITs that dual-map their
40
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
41
{ .name = "ELR_EL1", .state = ARM_CP_STATE_AA64,
42
.type = ARM_CP_ALIAS,
43
.opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 1,
44
- .access = PL1_RW,
45
+ .access = PL1_RW, .accessfn = access_nv1,
46
.fieldoffset = offsetof(CPUARMState, elr_el[1]) },
47
{ .name = "SPSR_EL1", .state = ARM_CP_STATE_AA64,
48
.type = ARM_CP_ALIAS,
49
.opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 0,
50
- .access = PL1_RW,
51
+ .access = PL1_RW, .accessfn = access_nv1,
52
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_SVC]) },
53
/*
54
* We rely on the access checks not allowing the guest to write to the
55
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_mte(CPUARMState *env, const ARMCPRegInfo *ri,
56
return CP_ACCESS_OK;
57
}
58
59
+static CPAccessResult access_tfsr_el1(CPUARMState *env, const ARMCPRegInfo *ri,
60
+ bool isread)
61
+{
62
+ CPAccessResult nv1 = access_nv1(env, ri, isread);
63
+
64
+ if (nv1 != CP_ACCESS_OK) {
65
+ return nv1;
66
+ }
67
+ return access_mte(env, ri, isread);
68
+}
69
+
70
static CPAccessResult access_tfsr_el2(CPUARMState *env, const ARMCPRegInfo *ri,
71
bool isread)
72
{
73
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_reginfo[] = {
74
.fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[0]) },
75
{ .name = "TFSR_EL1", .state = ARM_CP_STATE_AA64,
76
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 6, .opc2 = 0,
77
- .access = PL1_RW, .accessfn = access_mte,
78
+ .access = PL1_RW, .accessfn = access_tfsr_el1,
79
.fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[1]) },
80
{ .name = "TFSR_EL2", .state = ARM_CP_STATE_AA64,
81
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 6, .opc2 = 0,
82
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_scxtnum(CPUARMState *env, const ARMCPRegInfo *ri,
83
return CP_ACCESS_OK;
84
}
85
86
+static CPAccessResult access_scxtnum_el1(CPUARMState *env,
87
+ const ARMCPRegInfo *ri,
88
+ bool isread)
89
+{
90
+ CPAccessResult nv1 = access_nv1(env, ri, isread);
91
+
92
+ if (nv1 != CP_ACCESS_OK) {
93
+ return nv1;
94
+ }
95
+ return access_scxtnum(env, ri, isread);
96
+}
97
+
98
static const ARMCPRegInfo scxtnum_reginfo[] = {
99
{ .name = "SCXTNUM_EL0", .state = ARM_CP_STATE_AA64,
100
.opc0 = 3, .opc1 = 3, .crn = 13, .crm = 0, .opc2 = 7,
101
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo scxtnum_reginfo[] = {
102
.fieldoffset = offsetof(CPUARMState, scxtnum_el[0]) },
103
{ .name = "SCXTNUM_EL1", .state = ARM_CP_STATE_AA64,
104
.opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 7,
105
- .access = PL1_RW, .accessfn = access_scxtnum,
106
+ .access = PL1_RW, .accessfn = access_scxtnum_el1,
107
.fgt = FGT_SCXTNUM_EL1,
108
.fieldoffset = offsetof(CPUARMState, scxtnum_el[1]) },
109
{ .name = "SCXTNUM_EL2", .state = ARM_CP_STATE_AA64,
110
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
111
{ .name = "VBAR", .state = ARM_CP_STATE_BOTH,
112
.opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
113
.access = PL1_RW, .writefn = vbar_write,
114
+ .accessfn = access_nv1,
115
.fgt = FGT_VBAR_EL1,
116
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s),
117
offsetof(CPUARMState, cp15.vbar_ns) },
118
--
119
2.34.1
diff view generated by jsdifflib
Deleted patch
1
Currently the code in target/arm/helper.c mostly checks the PAN bits
2
in env->pstate or env->uncached_cpsr directly when it wants to know
3
if PAN is enabled, because in most callsites we know whether we are
4
in AArch64 or AArch32. We do have an arm_pan_enabled() function, but
5
we only use it in a few places where the code might run in either an
6
AArch32 or AArch64 context.
7
1
8
For FEAT_NV, when HCR_EL2.{NV,NV1} is {1,1} PAN is always disabled
9
even when the PSTATE.PAN bit is set, the "is PAN enabled" test
10
becomes more complicated. Make all places that check for PAN use
11
arm_pan_enabled(), so we have a place to put the FEAT_NV test.
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Tested-by: Miguel Luis <miguel.luis@oracle.com>
16
---
17
target/arm/helper.c | 22 +++++++++++-----------
18
1 file changed, 11 insertions(+), 11 deletions(-)
19
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
23
+++ b/target/arm/helper.c
24
@@ -XXX,XX +XXX,XX @@ void init_cpreg_list(ARMCPU *cpu)
25
g_list_free(keys);
26
}
27
28
+static bool arm_pan_enabled(CPUARMState *env)
29
+{
30
+ if (is_a64(env)) {
31
+ return env->pstate & PSTATE_PAN;
32
+ } else {
33
+ return env->uncached_cpsr & CPSR_PAN;
34
+ }
35
+}
36
+
37
/*
38
* Some registers are not accessible from AArch32 EL3 if SCR.NS == 0.
39
*/
40
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
41
g_assert(ss != ARMSS_Secure); /* ARMv8.4-SecEL2 is 64-bit only */
42
/* fall through */
43
case 1:
44
- if (ri->crm == 9 && (env->uncached_cpsr & CPSR_PAN)) {
45
+ if (ri->crm == 9 && arm_pan_enabled(env)) {
46
mmu_idx = ARMMMUIdx_Stage1_E1_PAN;
47
} else {
48
mmu_idx = ARMMMUIdx_Stage1_E1;
49
@@ -XXX,XX +XXX,XX @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
50
case 0:
51
switch (ri->opc1) {
52
case 0: /* AT S1E1R, AT S1E1W, AT S1E1RP, AT S1E1WP */
53
- if (ri->crm == 9 && (env->pstate & PSTATE_PAN)) {
54
+ if (ri->crm == 9 && arm_pan_enabled(env)) {
55
mmu_idx = regime_e20 ?
56
ARMMMUIdx_E20_2_PAN : ARMMMUIdx_Stage1_E1_PAN;
57
} else {
58
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
59
}
60
#endif
61
62
-static bool arm_pan_enabled(CPUARMState *env)
63
-{
64
- if (is_a64(env)) {
65
- return env->pstate & PSTATE_PAN;
66
- } else {
67
- return env->uncached_cpsr & CPSR_PAN;
68
- }
69
-}
70
-
71
ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el)
72
{
73
ARMMMUIdx idx;
74
--
75
2.34.1
diff view generated by jsdifflib
Deleted patch
1
For FEAT_NV, when HCR_EL2.{NV,NV1} is {1,1} PAN is always disabled
2
even when the PSTATE.PAN bit is set. Implement this by having
3
arm_pan_enabled() return false in this situation.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Miguel Luis <miguel.luis@oracle.com>
8
---
9
target/arm/helper.c | 3 +++
10
1 file changed, 3 insertions(+)
11
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
15
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ void init_cpreg_list(ARMCPU *cpu)
17
static bool arm_pan_enabled(CPUARMState *env)
18
{
19
if (is_a64(env)) {
20
+ if ((arm_hcr_el2_eff(env) & (HCR_NV | HCR_NV1)) == (HCR_NV | HCR_NV1)) {
21
+ return false;
22
+ }
23
return env->pstate & PSTATE_PAN;
24
} else {
25
return env->uncached_cpsr & CPSR_PAN;
26
--
27
2.34.1
diff view generated by jsdifflib
Deleted patch
1
FEAT_NV requires (per I_JKLJK) that when HCR_EL2.{NV,NV1} is {1,1} the
2
unprivileged-access instructions LDTR, STTR etc behave as normal
3
loads and stores. Implement the check that handles this.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Miguel Luis <miguel.luis@oracle.com>
8
---
9
target/arm/tcg/hflags.c | 6 ++++--
10
1 file changed, 4 insertions(+), 2 deletions(-)
11
12
diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/tcg/hflags.c
15
+++ b/target/arm/tcg/hflags.c
16
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
17
switch (mmu_idx) {
18
case ARMMMUIdx_E10_1:
19
case ARMMMUIdx_E10_1_PAN:
20
- /* TODO: ARMv8.3-NV */
21
- DP_TBFLAG_A64(flags, UNPRIV, 1);
22
+ /* FEAT_NV: NV,NV1 == 1,1 means we don't do UNPRIV accesses */
23
+ if ((hcr & (HCR_NV | HCR_NV1)) != (HCR_NV | HCR_NV1)) {
24
+ DP_TBFLAG_A64(flags, UNPRIV, 1);
25
+ }
26
break;
27
case ARMMMUIdx_E20_2:
28
case ARMMMUIdx_E20_2_PAN:
29
--
30
2.34.1
diff view generated by jsdifflib
Deleted patch
1
FEAT_NV requires that when HCR_EL2.{NV,NV1} == {1,1} the handling
2
of some of the page table attribute bits changes for the EL1&0
3
translation regime:
4
1
5
* for block and page descriptors:
6
- bit [54] holds PXN, not UXN
7
- bit [53] is RES0, and the effective value of UXN is 0
8
- bit [6], AP[1], is treated as 0
9
* for table descriptors, when hierarchical permissions are enabled:
10
- bit [60] holds PXNTable, not UXNTable
11
- bit [59] is RES0
12
- bit [61], APTable[0] is treated as 0
13
14
Implement these changes to the page table attribute handling.
15
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Tested-by: Miguel Luis <miguel.luis@oracle.com>
19
---
20
target/arm/ptw.c | 21 +++++++++++++++++++++
21
1 file changed, 21 insertions(+)
22
23
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/ptw.c
26
+++ b/target/arm/ptw.c
27
@@ -XXX,XX +XXX,XX @@ static bool lpae_block_desc_valid(ARMCPU *cpu, bool ds,
28
}
29
}
30
31
+static bool nv_nv1_enabled(CPUARMState *env, S1Translate *ptw)
32
+{
33
+ uint64_t hcr = arm_hcr_el2_eff_secstate(env, ptw->in_space);
34
+ return (hcr & (HCR_NV | HCR_NV1)) == (HCR_NV | HCR_NV1);
35
+}
36
+
37
/**
38
* get_phys_addr_lpae: perform one stage of page table walk, LPAE format
39
*
40
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
41
xn = extract64(attrs, 54, 1);
42
pxn = extract64(attrs, 53, 1);
43
44
+ if (el == 1 && nv_nv1_enabled(env, ptw)) {
45
+ /*
46
+ * With FEAT_NV, when HCR_EL2.{NV,NV1} == {1,1}, the block/page
47
+ * descriptor bit 54 holds PXN, 53 is RES0, and the effective value
48
+ * of UXN is 0. Similarly for bits 59 and 60 in table descriptors
49
+ * (which we have already folded into bits 53 and 54 of attrs).
50
+ * AP[1] (descriptor bit 6, our ap bit 0) is treated as 0.
51
+ * Similarly, APTable[0] from the table descriptor is treated as 0;
52
+ * we already folded this into AP[1] and squashing that to 0 does
53
+ * the right thing.
54
+ */
55
+ pxn = xn;
56
+ xn = 0;
57
+ ap &= ~1;
58
+ }
59
/*
60
* Note that we modified ptw->in_space earlier for NSTable, but
61
* result->f.attrs retains a copy of the original security space.
62
--
63
2.34.1
diff view generated by jsdifflib
Deleted patch
1
FEAT_NV2 defines another new bit in HCR_EL2: NV2. When the
2
feature is enabled, allow this bit to be written in HCR_EL2.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Miguel Luis <miguel.luis@oracle.com>
7
---
8
target/arm/cpu-features.h | 5 +++++
9
target/arm/helper.c | 3 +++
10
2 files changed, 8 insertions(+)
11
12
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu-features.h
15
+++ b/target/arm/cpu-features.h
16
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_nv(const ARMISARegisters *id)
17
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, NV) != 0;
18
}
19
20
+static inline bool isar_feature_aa64_nv2(const ARMISARegisters *id)
21
+{
22
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, NV) >= 2;
23
+}
24
+
25
static inline bool isar_feature_aa64_pmuv3p1(const ARMISARegisters *id)
26
{
27
return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 4 &&
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 void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
33
if (cpu_isar_feature(aa64_nv, cpu)) {
34
valid_mask |= HCR_NV | HCR_NV1 | HCR_AT;
35
}
36
+ if (cpu_isar_feature(aa64_nv2, cpu)) {
37
+ valid_mask |= HCR_NV2;
38
+ }
39
}
40
41
if (cpu_isar_feature(any_evt, cpu)) {
42
--
43
2.34.1
diff view generated by jsdifflib
Deleted patch
1
For FEAT_NV2, a new system register VNCR_EL2 holds the base
2
address of the memory which nested-guest system register
3
accesses are redirected to. Implement this register.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Miguel Luis <miguel.luis@oracle.com>
8
---
9
target/arm/cpu.h | 3 +++
10
target/arm/helper.c | 26 ++++++++++++++++++++++++++
11
2 files changed, 29 insertions(+)
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 @@ typedef struct CPUArchState {
18
uint64_t gpccr_el3;
19
uint64_t gptbr_el3;
20
uint64_t mfar_el3;
21
+
22
+ /* NV2 register */
23
+ uint64_t vncr_el2;
24
} cp15;
25
26
struct {
27
diff --git a/target/arm/helper.c b/target/arm/helper.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/helper.c
30
+++ b/target/arm/helper.c
31
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo fgt_reginfo[] = {
32
.access = PL2_RW, .accessfn = access_fgt,
33
.fieldoffset = offsetof(CPUARMState, cp15.fgt_exec[FGTREG_HFGITR]) },
34
};
35
+
36
+static void vncr_write(CPUARMState *env, const ARMCPRegInfo *ri,
37
+ uint64_t value)
38
+{
39
+ /*
40
+ * Clear the RES0 bottom 12 bits; this means at runtime we can guarantee
41
+ * that VNCR_EL2 + offset is 64-bit aligned. We don't need to do anything
42
+ * about the RESS bits at the top -- we choose the "generate an EL2
43
+ * translation abort on use" CONSTRAINED UNPREDICTABLE option (i.e. let
44
+ * the ptw.c code detect the resulting invalid address).
45
+ */
46
+ env->cp15.vncr_el2 = value & ~0xfffULL;
47
+}
48
+
49
+static const ARMCPRegInfo nv2_reginfo[] = {
50
+ { .name = "VNCR_EL2", .state = ARM_CP_STATE_AA64,
51
+ .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 2, .opc2 = 0,
52
+ .access = PL2_RW,
53
+ .writefn = vncr_write,
54
+ .fieldoffset = offsetof(CPUARMState, cp15.vncr_el2) },
55
+};
56
+
57
#endif /* TARGET_AARCH64 */
58
59
static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
60
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
61
define_arm_cp_regs(cpu, rme_mte_reginfo);
62
}
63
}
64
+
65
+ if (cpu_isar_feature(aa64_nv2, cpu)) {
66
+ define_arm_cp_regs(cpu, nv2_reginfo);
67
+ }
68
#endif
69
70
if (cpu_isar_feature(any_predinv, cpu)) {
71
--
72
2.34.1
diff view generated by jsdifflib
Deleted patch
1
With FEAT_NV2, the condition for when SPSR_EL1.M should report that
2
an exception was taken from EL2 changes.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Miguel Luis <miguel.luis@oracle.com>
7
---
8
target/arm/helper.c | 16 ++++++++++++----
9
1 file changed, 12 insertions(+), 4 deletions(-)
10
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
14
+++ b/target/arm/helper.c
15
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
16
aarch64_save_sp(env, arm_current_el(env));
17
env->elr_el[new_el] = env->pc;
18
19
- if (cur_el == 1 && new_el == 1 &&
20
- ((arm_hcr_el2_eff(env) & (HCR_NV | HCR_NV1)) == HCR_NV)) {
21
- /* I_ZJRNN: report EL2 in the SPSR by setting M[3:2] to 0b10 */
22
- old_mode = deposit32(old_mode, 2, 2, 2);
23
+ if (cur_el == 1 && new_el == 1) {
24
+ uint64_t hcr = arm_hcr_el2_eff(env);
25
+ if ((hcr & (HCR_NV | HCR_NV1 | HCR_NV2)) == HCR_NV ||
26
+ (hcr & (HCR_NV | HCR_NV2)) == (HCR_NV | HCR_NV2)) {
27
+ /*
28
+ * FEAT_NV, FEAT_NV2 may need to report EL2 in the SPSR
29
+ * by setting M[3:2] to 0b10.
30
+ * If NV2 is disabled, change SPSR when NV,NV1 == 1,0 (I_ZJRNN)
31
+ * If NV2 is enabled, change SPSR when NV is 1 (I_DBTLM)
32
+ */
33
+ old_mode = deposit32(old_mode, 2, 2, 2);
34
+ }
35
}
36
} else {
37
old_mode = cpsr_read_for_spsr_elx(env);
38
--
39
2.34.1
diff view generated by jsdifflib
Deleted patch
1
Under FEAT_NV2, when HCR_EL2.{NV,NV2} == 0b11 at EL1, accesses to the
2
registers SPSR_EL2, ELR_EL2, ESR_EL2, FAR_EL2 and TFSR_EL2 (which
3
would UNDEF without FEAT_NV or FEAT_NV2) should instead access the
4
equivalent EL1 registers SPSR_EL1, ELR_EL1, ESR_EL1, FAR_EL1 and
5
TFSR_EL1.
6
1
7
Because there are only five registers involved and the encoding for
8
the EL1 register is identical to that of the EL2 register except
9
that opc1 is 0, we handle this by finding the EL1 register in the
10
hash table and using it instead.
11
12
Note that traps that apply to direct accesses to the EL1 register,
13
such as active fine-grained traps or other trap bits, do not trigger
14
when it is accessed via the EL2 encoding in this way. However, some
15
traps that are defined by the EL2 register may apply. We therefore
16
call the EL2 register's accessfn first. The only one of the five
17
which has such traps is TFSR_EL2: make sure its accessfn correctly
18
handles both FEAT_NV (where we trap to EL2 without checking ATA bits)
19
and FEAT_NV2 (where we check ATA bits and then redirect to TFSR_EL1).
20
21
(We don't need the NV1 tbflag bit until the next patch, but we
22
introduce it here to avoid putting the NV, NV1, NV2 bits in an
23
odd order.)
24
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Tested-by: Miguel Luis <miguel.luis@oracle.com>
28
---
29
target/arm/cpregs.h | 5 +++++
30
target/arm/cpu.h | 2 ++
31
target/arm/tcg/translate.h | 4 ++++
32
target/arm/helper.c | 13 +++++++++----
33
target/arm/tcg/hflags.c | 6 ++++++
34
target/arm/tcg/translate-a64.c | 33 ++++++++++++++++++++++++++++++++-
35
6 files changed, 58 insertions(+), 5 deletions(-)
36
37
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/cpregs.h
40
+++ b/target/arm/cpregs.h
41
@@ -XXX,XX +XXX,XX @@ enum {
42
* ARM pseudocode function CheckSMEAccess().
43
*/
44
ARM_CP_SME = 1 << 19,
45
+ /*
46
+ * Flag: one of the four EL2 registers which redirect to the
47
+ * equivalent EL1 register when FEAT_NV2 is enabled.
48
+ */
49
+ ARM_CP_NV2_REDIRECT = 1 << 20,
50
};
51
52
/*
53
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/cpu.h
56
+++ b/target/arm/cpu.h
57
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, TRAP_ERET, 29, 1)
58
FIELD(TBFLAG_A64, NAA, 30, 1)
59
FIELD(TBFLAG_A64, ATA0, 31, 1)
60
FIELD(TBFLAG_A64, NV, 32, 1)
61
+FIELD(TBFLAG_A64, NV1, 33, 1)
62
+FIELD(TBFLAG_A64, NV2, 34, 1)
63
64
/*
65
* Helpers for using the above. Note that only the A64 accessors use
66
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/tcg/translate.h
69
+++ b/target/arm/tcg/translate.h
70
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
71
bool naa;
72
/* True if FEAT_NV HCR_EL2.NV is enabled */
73
bool nv;
74
+ /* True if NV enabled and HCR_EL2.NV1 is set */
75
+ bool nv1;
76
+ /* True if NV enabled and HCR_EL2.NV2 is set */
77
+ bool nv2;
78
/*
79
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
80
* < 0, set by the current instruction.
81
diff --git a/target/arm/helper.c b/target/arm/helper.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/helper.c
84
+++ b/target/arm/helper.c
85
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
86
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 7,
87
.access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
88
{ .name = "ELR_EL2", .state = ARM_CP_STATE_AA64,
89
- .type = ARM_CP_ALIAS,
90
+ .type = ARM_CP_ALIAS | ARM_CP_NV2_REDIRECT,
91
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1,
92
.access = PL2_RW,
93
.fieldoffset = offsetof(CPUARMState, elr_el[2]) },
94
{ .name = "ESR_EL2", .state = ARM_CP_STATE_BOTH,
95
+ .type = ARM_CP_NV2_REDIRECT,
96
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
97
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[2]) },
98
{ .name = "FAR_EL2", .state = ARM_CP_STATE_BOTH,
99
+ .type = ARM_CP_NV2_REDIRECT,
100
.opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
101
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[2]) },
102
{ .name = "HIFAR", .state = ARM_CP_STATE_AA32,
103
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
104
.access = PL2_RW,
105
.fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el[2]) },
106
{ .name = "SPSR_EL2", .state = ARM_CP_STATE_AA64,
107
- .type = ARM_CP_ALIAS,
108
+ .type = ARM_CP_ALIAS | ARM_CP_NV2_REDIRECT,
109
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0,
110
.access = PL2_RW,
111
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_HYP]) },
112
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tfsr_el2(CPUARMState *env, const ARMCPRegInfo *ri,
113
/*
114
* TFSR_EL2: similar to generic access_mte(), but we need to
115
* account for FEAT_NV. At EL1 this must be a FEAT_NV access;
116
- * we will trap to EL2 and the HCR/SCR traps do not apply.
117
+ * if NV2 is enabled then we will redirect this to TFSR_EL1
118
+ * after doing the HCR and SCR ATA traps; otherwise this will
119
+ * be a trap to EL2 and the HCR/SCR traps do not apply.
120
*/
121
int el = arm_current_el(env);
122
123
- if (el == 1) {
124
+ if (el == 1 && (arm_hcr_el2_eff(env) & HCR_NV2)) {
125
return CP_ACCESS_OK;
126
}
127
if (el < 2 && arm_is_el2_enabled(env)) {
128
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_reginfo[] = {
129
.access = PL1_RW, .accessfn = access_tfsr_el1,
130
.fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[1]) },
131
{ .name = "TFSR_EL2", .state = ARM_CP_STATE_AA64,
132
+ .type = ARM_CP_NV2_REDIRECT,
133
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 6, .opc2 = 0,
134
.access = PL2_RW, .accessfn = access_tfsr_el2,
135
.fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[2]) },
136
diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c
137
index XXXXXXX..XXXXXXX 100644
138
--- a/target/arm/tcg/hflags.c
139
+++ b/target/arm/tcg/hflags.c
140
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
141
if (el == 1 && (hcr & HCR_NV)) {
142
DP_TBFLAG_A64(flags, TRAP_ERET, 1);
143
DP_TBFLAG_A64(flags, NV, 1);
144
+ if (hcr & HCR_NV1) {
145
+ DP_TBFLAG_A64(flags, NV1, 1);
146
+ }
147
+ if (hcr & HCR_NV2) {
148
+ DP_TBFLAG_A64(flags, NV2, 1);
149
+ }
150
}
151
152
if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
153
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
154
index XXXXXXX..XXXXXXX 100644
155
--- a/target/arm/tcg/translate-a64.c
156
+++ b/target/arm/tcg/translate-a64.c
157
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
158
const ARMCPRegInfo *ri = get_arm_cp_reginfo(s->cp_regs, key);
159
bool need_exit_tb = false;
160
bool nv_trap_to_el2 = false;
161
+ bool nv_redirect_reg = false;
162
bool skip_fp_access_checks = false;
163
TCGv_ptr tcg_ri = NULL;
164
TCGv_i64 tcg_rt;
165
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
166
* for registers accessible at EL1).
167
*/
168
skip_fp_access_checks = true;
169
- if (s->nv && arm_cpreg_traps_in_nv(ri)) {
170
+ if (s->nv2 && (ri->type & ARM_CP_NV2_REDIRECT)) {
171
+ /*
172
+ * This is one of the few EL2 registers which should redirect
173
+ * to the equivalent EL1 register. We do that after running
174
+ * the EL2 register's accessfn.
175
+ */
176
+ nv_redirect_reg = true;
177
+ } else if (s->nv && arm_cpreg_traps_in_nv(ri)) {
178
/*
179
* This register / instruction exists and is an EL2 register, so
180
* we must trap to EL2 if accessed in nested virtualization EL1
181
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
182
return;
183
}
184
185
+ if (nv_redirect_reg) {
186
+ /*
187
+ * FEAT_NV2 redirection of an EL2 register to an EL1 register.
188
+ * Conveniently in all cases the encoding of the EL1 register is
189
+ * identical to the EL2 register except that opc1 is 0.
190
+ * Get the reginfo for the EL1 register to use for the actual access.
191
+ * We don't use the EL1 register's access function, and
192
+ * fine-grained-traps on EL1 also do not apply here.
193
+ */
194
+ key = ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP,
195
+ crn, crm, op0, 0, op2);
196
+ ri = get_arm_cp_reginfo(s->cp_regs, key);
197
+ assert(ri);
198
+ assert(cp_access_ok(s->current_el, ri, isread));
199
+ /*
200
+ * We might not have done an update_pc earlier, so check we don't
201
+ * need it. We could support this in future if necessary.
202
+ */
203
+ assert(!(ri->type & ARM_CP_RAISES_EXC));
204
+ }
205
+
206
/* Handle special cases first */
207
switch (ri->type & ARM_CP_SPECIAL_MASK) {
208
case 0:
209
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
210
dc->sme_trap_nonstreaming = EX_TBFLAG_A64(tb_flags, SME_TRAP_NONSTREAMING);
211
dc->naa = EX_TBFLAG_A64(tb_flags, NAA);
212
dc->nv = EX_TBFLAG_A64(tb_flags, NV);
213
+ dc->nv1 = EX_TBFLAG_A64(tb_flags, NV1);
214
+ dc->nv2 = EX_TBFLAG_A64(tb_flags, NV2);
215
dc->vec_len = 0;
216
dc->vec_stride = 0;
217
dc->cp_regs = arm_cpu->cp_regs;
218
--
219
2.34.1
diff view generated by jsdifflib
Deleted patch
1
FEAT_NV2 requires that when HCR_EL2.{NV,NV2} == 0b11 then accesses by
2
EL1 to certain system registers are redirected to RAM. The full list
3
of affected registers is in the table in rule R_CSRPQ in the Arm ARM.
4
The registers may be normally accessible at EL1 (like ACTLR_EL1), or
5
normally UNDEF at EL1 (like HCR_EL2). Some registers redirect to RAM
6
only when HCR_EL2.NV1 is 0, and some only when HCR_EL2.NV1 is 1;
7
others trap in both cases.
8
1
9
Add the infrastructure for identifying which registers should be
10
redirected and turning them into memory accesses.
11
12
This code does not set the correct syndrome or arrange for the
13
exception to be taken to the correct target EL if the access via
14
VNCR_EL2 faults; we will do that in the next commit.
15
16
Subsequent commits will mark up the relevant regdefs to set their
17
nv2_redirect_offset, and if relevant one of the two flags which
18
indicates that the redirect happens only for a particular value of
19
HCR_EL2.NV1.
20
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Tested-by: Miguel Luis <miguel.luis@oracle.com>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
---
25
target/arm/cpregs.h | 12 ++++++++
26
target/arm/cpu.h | 4 +++
27
target/arm/tcg/translate.h | 6 ++++
28
target/arm/tcg/hflags.c | 6 ++++
29
target/arm/tcg/translate-a64.c | 56 ++++++++++++++++++++++++++++++++++
30
5 files changed, 84 insertions(+)
31
32
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/cpregs.h
35
+++ b/target/arm/cpregs.h
36
@@ -XXX,XX +XXX,XX @@ typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque);
37
38
#define CP_ANY 0xff
39
40
+/* Flags in the high bits of nv2_redirect_offset */
41
+#define NV2_REDIR_NV1 0x4000 /* Only redirect when HCR_EL2.NV1 == 1 */
42
+#define NV2_REDIR_NO_NV1 0x8000 /* Only redirect when HCR_EL2.NV1 == 0 */
43
+#define NV2_REDIR_FLAG_MASK 0xc000
44
+
45
/* Definition of an ARM coprocessor register */
46
struct ARMCPRegInfo {
47
/* Name of register (useful mainly for debugging, need not be unique) */
48
@@ -XXX,XX +XXX,XX @@ struct ARMCPRegInfo {
49
* value encodes both the trap register and bit within it.
50
*/
51
FGTBit fgt;
52
+
53
+ /*
54
+ * Offset from VNCR_EL2 when FEAT_NV2 redirects access to memory;
55
+ * may include an NV2_REDIR_* flag.
56
+ */
57
+ uint32_t nv2_redirect_offset;
58
+
59
/*
60
* The opaque pointer passed to define_arm_cp_regs_with_opaque() when
61
* this register was defined: can be used to hand data through to the
62
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
63
index XXXXXXX..XXXXXXX 100644
64
--- a/target/arm/cpu.h
65
+++ b/target/arm/cpu.h
66
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, ATA0, 31, 1)
67
FIELD(TBFLAG_A64, NV, 32, 1)
68
FIELD(TBFLAG_A64, NV1, 33, 1)
69
FIELD(TBFLAG_A64, NV2, 34, 1)
70
+/* Set if FEAT_NV2 RAM accesses use the EL2&0 translation regime */
71
+FIELD(TBFLAG_A64, NV2_MEM_E20, 35, 1)
72
+/* Set if FEAT_NV2 RAM accesses are big-endian */
73
+FIELD(TBFLAG_A64, NV2_MEM_BE, 36, 1)
74
75
/*
76
* Helpers for using the above. Note that only the A64 accessors use
77
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/tcg/translate.h
80
+++ b/target/arm/tcg/translate.h
81
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
82
bool nv1;
83
/* True if NV enabled and HCR_EL2.NV2 is set */
84
bool nv2;
85
+ /* True if NV2 enabled and NV2 RAM accesses use EL2&0 translation regime */
86
+ bool nv2_mem_e20;
87
+ /* True if NV2 enabled and NV2 RAM accesses are big-endian */
88
+ bool nv2_mem_be;
89
/*
90
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
91
* < 0, set by the current instruction.
92
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
93
int c15_cpar;
94
/* TCG op of the current insn_start. */
95
TCGOp *insn_start;
96
+ /* Offset from VNCR_EL2 when FEAT_NV2 redirects this reg to memory */
97
+ uint32_t nv2_redirect_offset;
98
} DisasContext;
99
100
typedef struct DisasCompare {
101
diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c
102
index XXXXXXX..XXXXXXX 100644
103
--- a/target/arm/tcg/hflags.c
104
+++ b/target/arm/tcg/hflags.c
105
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
106
}
107
if (hcr & HCR_NV2) {
108
DP_TBFLAG_A64(flags, NV2, 1);
109
+ if (hcr & HCR_E2H) {
110
+ DP_TBFLAG_A64(flags, NV2_MEM_E20, 1);
111
+ }
112
+ if (env->cp15.sctlr_el[2] & SCTLR_EE) {
113
+ DP_TBFLAG_A64(flags, NV2_MEM_BE, 1);
114
+ }
115
}
116
}
117
118
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
119
index XXXXXXX..XXXXXXX 100644
120
--- a/target/arm/tcg/translate-a64.c
121
+++ b/target/arm/tcg/translate-a64.c
122
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
123
bool nv_trap_to_el2 = false;
124
bool nv_redirect_reg = false;
125
bool skip_fp_access_checks = false;
126
+ bool nv2_mem_redirect = false;
127
TCGv_ptr tcg_ri = NULL;
128
TCGv_i64 tcg_rt;
129
uint32_t syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
130
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
131
return;
132
}
133
134
+ if (s->nv2 && ri->nv2_redirect_offset) {
135
+ /*
136
+ * Some registers always redirect to memory; some only do so if
137
+ * HCR_EL2.NV1 is 0, and some only if NV1 is 1 (these come in
138
+ * pairs which share an offset; see the table in R_CSRPQ).
139
+ */
140
+ if (ri->nv2_redirect_offset & NV2_REDIR_NV1) {
141
+ nv2_mem_redirect = s->nv1;
142
+ } else if (ri->nv2_redirect_offset & NV2_REDIR_NO_NV1) {
143
+ nv2_mem_redirect = !s->nv1;
144
+ } else {
145
+ nv2_mem_redirect = true;
146
+ }
147
+ }
148
+
149
/* Check access permissions */
150
if (!cp_access_ok(s->current_el, ri, isread)) {
151
/*
152
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
153
* the EL2 register's accessfn.
154
*/
155
nv_redirect_reg = true;
156
+ assert(!nv2_mem_redirect);
157
+ } else if (nv2_mem_redirect) {
158
+ /*
159
+ * NV2 redirect-to-memory takes precedence over trap to EL2 or
160
+ * UNDEF to EL1.
161
+ */
162
} else if (s->nv && arm_cpreg_traps_in_nv(ri)) {
163
/*
164
* This register / instruction exists and is an EL2 register, so
165
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
166
assert(!(ri->type & ARM_CP_RAISES_EXC));
167
}
168
169
+ if (nv2_mem_redirect) {
170
+ /*
171
+ * This system register is being redirected into an EL2 memory access.
172
+ * This means it is not an IO operation, doesn't change hflags,
173
+ * and need not end the TB, because it has no side effects.
174
+ *
175
+ * The access is 64-bit single copy atomic, guaranteed aligned because
176
+ * of the definition of VCNR_EL2. Its endianness depends on
177
+ * SCTLR_EL2.EE, not on the data endianness of EL1.
178
+ * It is done under either the EL2 translation regime or the EL2&0
179
+ * translation regime, depending on HCR_EL2.E2H. It behaves as if
180
+ * PSTATE.PAN is 0.
181
+ */
182
+ TCGv_i64 ptr = tcg_temp_new_i64();
183
+ MemOp mop = MO_64 | MO_ALIGN | MO_ATOM_IFALIGN;
184
+ ARMMMUIdx armmemidx = s->nv2_mem_e20 ? ARMMMUIdx_E20_2 : ARMMMUIdx_E2;
185
+ int memidx = arm_to_core_mmu_idx(armmemidx);
186
+
187
+ mop |= (s->nv2_mem_be ? MO_BE : MO_LE);
188
+
189
+ tcg_gen_ld_i64(ptr, tcg_env, offsetof(CPUARMState, cp15.vncr_el2));
190
+ tcg_gen_addi_i64(ptr, ptr,
191
+ (ri->nv2_redirect_offset & ~NV2_REDIR_FLAG_MASK));
192
+ tcg_rt = cpu_reg(s, rt);
193
+ if (isread) {
194
+ tcg_gen_qemu_ld_i64(tcg_rt, ptr, memidx, mop);
195
+ } else {
196
+ tcg_gen_qemu_st_i64(tcg_rt, ptr, memidx, mop);
197
+ }
198
+ return;
199
+ }
200
+
201
/* Handle special cases first */
202
switch (ri->type & ARM_CP_SPECIAL_MASK) {
203
case 0:
204
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
205
dc->nv = EX_TBFLAG_A64(tb_flags, NV);
206
dc->nv1 = EX_TBFLAG_A64(tb_flags, NV1);
207
dc->nv2 = EX_TBFLAG_A64(tb_flags, NV2);
208
+ dc->nv2_mem_e20 = EX_TBFLAG_A64(tb_flags, NV2_MEM_E20);
209
+ dc->nv2_mem_be = EX_TBFLAG_A64(tb_flags, NV2_MEM_BE);
210
dc->vec_len = 0;
211
dc->vec_stride = 0;
212
dc->cp_regs = arm_cpu->cp_regs;
213
--
214
2.34.1
diff view generated by jsdifflib
Deleted patch
1
If FEAT_NV2 redirects a system register access to a memory offset
2
from VNCR_EL2, that access might fault. In this case we need to
3
report the correct syndrome information:
4
* Data Abort, from same-EL
5
* no ISS information
6
* the VNCR bit (bit 13) is set
7
1
8
and the exception must be taken to EL2.
9
10
Save an appropriate syndrome template when generating code; we can
11
then use that to:
12
* select the right target EL
13
* reconstitute a correct final syndrome for the data abort
14
* report the right syndrome if we take a FEAT_RME granule protection
15
fault on the VNCR-based write
16
17
Note that because VNCR is bit 13, we must start keeping bit 13 in
18
template syndromes, by adjusting ARM_INSN_START_WORD2_SHIFT.
19
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Tested-by: Miguel Luis <miguel.luis@oracle.com>
23
---
24
target/arm/cpu.h | 4 ++--
25
target/arm/syndrome.h | 20 ++++++++++++++++----
26
target/arm/tcg/tlb_helper.c | 27 +++++++++++++++++++++++++--
27
target/arm/tcg/translate-a64.c | 4 ++++
28
4 files changed, 47 insertions(+), 8 deletions(-)
29
30
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/cpu.h
33
+++ b/target/arm/cpu.h
34
@@ -XXX,XX +XXX,XX @@ enum {
35
#define TARGET_INSN_START_EXTRA_WORDS 2
36
37
/* The 2nd extra word holding syndrome info for data aborts does not use
38
- * the upper 6 bits nor the lower 14 bits. We mask and shift it down to
39
+ * the upper 6 bits nor the lower 13 bits. We mask and shift it down to
40
* help the sleb128 encoder do a better job.
41
* When restoring the CPU state, we shift it back up.
42
*/
43
#define ARM_INSN_START_WORD2_MASK ((1 << 26) - 1)
44
-#define ARM_INSN_START_WORD2_SHIFT 14
45
+#define ARM_INSN_START_WORD2_SHIFT 13
46
47
/* We currently assume float and double are IEEE single and double
48
precision respectively.
49
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/syndrome.h
52
+++ b/target/arm/syndrome.h
53
@@ -XXX,XX +XXX,XX @@ typedef enum {
54
#define ARM_EL_IL (1 << ARM_EL_IL_SHIFT)
55
#define ARM_EL_ISV (1 << ARM_EL_ISV_SHIFT)
56
57
+/* In the Data Abort syndrome */
58
+#define ARM_EL_VNCR (1 << 13)
59
+
60
static inline uint32_t syn_get_ec(uint32_t syn)
61
{
62
return syn >> ARM_EL_EC_SHIFT;
63
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_bxjtrap(int cv, int cond, int rm)
64
(cv << 24) | (cond << 20) | rm;
65
}
66
67
-static inline uint32_t syn_gpc(int s2ptw, int ind, int gpcsc,
68
+static inline uint32_t syn_gpc(int s2ptw, int ind, int gpcsc, int vncr,
69
int cm, int s1ptw, int wnr, int fsc)
70
{
71
- /* TODO: FEAT_NV2 adds VNCR */
72
return (EC_GPC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (s2ptw << 21)
73
- | (ind << 20) | (gpcsc << 14) | (cm << 8) | (s1ptw << 7)
74
- | (wnr << 6) | fsc;
75
+ | (ind << 20) | (gpcsc << 14) | (vncr << 13) | (cm << 8)
76
+ | (s1ptw << 7) | (wnr << 6) | fsc;
77
}
78
79
static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
80
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_data_abort_with_iss(int same_el,
81
| (ea << 9) | (cm << 8) | (s1ptw << 7) | (wnr << 6) | fsc;
82
}
83
84
+/*
85
+ * Faults due to FEAT_NV2 VNCR_EL2-based accesses report as same-EL
86
+ * Data Aborts with the VNCR bit set.
87
+ */
88
+static inline uint32_t syn_data_abort_vncr(int ea, int wnr, int fsc)
89
+{
90
+ return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (1 << ARM_EL_EC_SHIFT)
91
+ | ARM_EL_IL | ARM_EL_VNCR | (wnr << 6) | fsc;
92
+}
93
+
94
static inline uint32_t syn_swstep(int same_el, int isv, int ex)
95
{
96
return (EC_SOFTWARESTEP << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
97
diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c
98
index XXXXXXX..XXXXXXX 100644
99
--- a/target/arm/tcg/tlb_helper.c
100
+++ b/target/arm/tcg/tlb_helper.c
101
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
102
* ST64BV, or ST64BV0 insns report syndrome info even for stage-1
103
* faults and regardless of the target EL.
104
*/
105
- if (!(template_syn & ARM_EL_ISV) || target_el != 2
106
+ if (template_syn & ARM_EL_VNCR) {
107
+ /*
108
+ * FEAT_NV2 faults on accesses via VNCR_EL2 are a special case:
109
+ * they are always reported as "same EL", even though we are going
110
+ * from EL1 to EL2.
111
+ */
112
+ assert(!fi->stage2);
113
+ syn = syn_data_abort_vncr(fi->ea, is_write, fsc);
114
+ } else if (!(template_syn & ARM_EL_ISV) || target_el != 2
115
|| fi->s1ptw || !fi->stage2) {
116
syn = syn_data_abort_no_iss(same_el, 0,
117
fi->ea, 0, fi->s1ptw, is_write, fsc);
118
@@ -XXX,XX +XXX,XX @@ void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
119
int current_el = arm_current_el(env);
120
bool same_el;
121
uint32_t syn, exc, fsr, fsc;
122
+ /*
123
+ * We know this must be a data or insn abort, and that
124
+ * env->exception.syndrome contains the template syndrome set
125
+ * up at translate time. So we can check only the VNCR bit
126
+ * (and indeed syndrome does not have the EC field in it,
127
+ * because we masked that out in disas_set_insn_syndrome())
128
+ */
129
+ bool is_vncr = (mmu_idx != MMU_INST_FETCH) &&
130
+ (env->exception.syndrome & ARM_EL_VNCR);
131
+
132
+ if (is_vncr) {
133
+ /* FEAT_NV2 faults on accesses via VNCR_EL2 go to EL2 */
134
+ target_el = 2;
135
+ }
136
137
if (report_as_gpc_exception(cpu, current_el, fi)) {
138
target_el = 3;
139
@@ -XXX,XX +XXX,XX @@ void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
140
141
syn = syn_gpc(fi->stage2 && fi->type == ARMFault_GPCFOnWalk,
142
access_type == MMU_INST_FETCH,
143
- encode_gpcsc(fi), 0, fi->s1ptw,
144
+ encode_gpcsc(fi), is_vncr,
145
+ 0, fi->s1ptw,
146
access_type == MMU_DATA_STORE, fsc);
147
148
env->cp15.mfar_el3 = fi->paddr;
149
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
150
index XXXXXXX..XXXXXXX 100644
151
--- a/target/arm/tcg/translate-a64.c
152
+++ b/target/arm/tcg/translate-a64.c
153
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
154
MemOp mop = MO_64 | MO_ALIGN | MO_ATOM_IFALIGN;
155
ARMMMUIdx armmemidx = s->nv2_mem_e20 ? ARMMMUIdx_E20_2 : ARMMMUIdx_E2;
156
int memidx = arm_to_core_mmu_idx(armmemidx);
157
+ uint32_t syn;
158
159
mop |= (s->nv2_mem_be ? MO_BE : MO_LE);
160
161
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
162
tcg_gen_addi_i64(ptr, ptr,
163
(ri->nv2_redirect_offset & ~NV2_REDIR_FLAG_MASK));
164
tcg_rt = cpu_reg(s, rt);
165
+
166
+ syn = syn_data_abort_vncr(0, !isread, 0);
167
+ disas_set_insn_syndrome(s, syn);
168
if (isread) {
169
tcg_gen_qemu_ld_i64(tcg_rt, ptr, memidx, mop);
170
} else {
171
--
172
2.34.1
diff view generated by jsdifflib
Deleted patch
1
Mark up the cpreginfo structs to indicate offsets for system
2
registers from VNCR_EL2, as defined in table D8-66 in rule R_CSRPQ in
3
the Arm ARM. This commit covers offsets below 0x100; all of these
4
registers are redirected to memory regardless of the value of
5
HCR_EL2.NV1.
6
1
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Miguel Luis <miguel.luis@oracle.com>
10
---
11
target/arm/helper.c | 12 ++++++++++++
12
1 file changed, 12 insertions(+)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo hcrx_el2_reginfo = {
19
.name = "HCRX_EL2", .state = ARM_CP_STATE_AA64,
20
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 2,
21
.access = PL2_RW, .writefn = hcrx_write, .accessfn = access_hxen,
22
+ .nv2_redirect_offset = 0xa0,
23
.fieldoffset = offsetof(CPUARMState, cp15.hcrx_el2),
24
};
25
26
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
27
.type = ARM_CP_IO,
28
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
29
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
30
+ .nv2_redirect_offset = 0x78,
31
.writefn = hcr_write, .raw_writefn = raw_write },
32
{ .name = "HCR", .state = ARM_CP_STATE_AA32,
33
.type = ARM_CP_ALIAS | ARM_CP_IO,
34
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
35
{ .name = "VTCR_EL2", .state = ARM_CP_STATE_AA64,
36
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2,
37
.access = PL2_RW,
38
+ .nv2_redirect_offset = 0x40,
39
/* no .writefn needed as this can't cause an ASID change */
40
.fieldoffset = offsetof(CPUARMState, cp15.vtcr_el2) },
41
{ .name = "VTTBR", .state = ARM_CP_STATE_AA32,
42
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
43
{ .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64,
44
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0,
45
.access = PL2_RW, .writefn = vttbr_write, .raw_writefn = raw_write,
46
+ .nv2_redirect_offset = 0x20,
47
.fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2) },
48
{ .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH,
49
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0,
50
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
51
{ .name = "TPIDR_EL2", .state = ARM_CP_STATE_BOTH,
52
.opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 2,
53
.access = PL2_RW, .resetvalue = 0,
54
+ .nv2_redirect_offset = 0x90,
55
.fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[2]) },
56
{ .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64,
57
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0,
58
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
59
.opc0 = 3, .opc1 = 4, .crn = 14, .crm = 0, .opc2 = 3,
60
.access = PL2_RW, .type = ARM_CP_IO, .resetvalue = 0,
61
.writefn = gt_cntvoff_write,
62
+ .nv2_redirect_offset = 0x60,
63
.fieldoffset = offsetof(CPUARMState, cp15.cntvoff_el2) },
64
{ .name = "CNTVOFF", .cp = 15, .opc1 = 4, .crm = 14,
65
.access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS | ARM_CP_IO,
66
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
67
{ .name = "HSTR_EL2", .state = ARM_CP_STATE_BOTH,
68
.cp = 15, .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 3,
69
.access = PL2_RW,
70
+ .nv2_redirect_offset = 0x80,
71
.fieldoffset = offsetof(CPUARMState, cp15.hstr_el2) },
72
};
73
74
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_sec_cp_reginfo[] = {
75
{ .name = "VSTTBR_EL2", .state = ARM_CP_STATE_AA64,
76
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 6, .opc2 = 0,
77
.access = PL2_RW, .accessfn = sel2_access,
78
+ .nv2_redirect_offset = 0x30,
79
.fieldoffset = offsetof(CPUARMState, cp15.vsttbr_el2) },
80
{ .name = "VSTCR_EL2", .state = ARM_CP_STATE_AA64,
81
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 6, .opc2 = 2,
82
.access = PL2_RW, .accessfn = sel2_access,
83
+ .nv2_redirect_offset = 0x48,
84
.fieldoffset = offsetof(CPUARMState, cp15.vstcr_el2) },
85
};
86
87
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo nv2_reginfo[] = {
88
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 2, .opc2 = 0,
89
.access = PL2_RW,
90
.writefn = vncr_write,
91
+ .nv2_redirect_offset = 0xb0,
92
.fieldoffset = offsetof(CPUARMState, cp15.vncr_el2) },
93
};
94
95
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
96
.opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,
97
.access = PL2_RW, .resetvalue = cpu->midr,
98
.type = ARM_CP_EL3_NO_EL2_C_NZ,
99
+ .nv2_redirect_offset = 0x88,
100
.fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) },
101
{ .name = "VMPIDR", .state = ARM_CP_STATE_AA32,
102
.cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,
103
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
104
.opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,
105
.access = PL2_RW, .resetvalue = vmpidr_def,
106
.type = ARM_CP_EL3_NO_EL2_C_NZ,
107
+ .nv2_redirect_offset = 0x50,
108
.fieldoffset = offsetof(CPUARMState, cp15.vmpidr_el2) },
109
};
110
/*
111
--
112
2.34.1
diff view generated by jsdifflib
Deleted patch
1
Mark up the cpreginfo structs to indicate offsets for system
2
registers from VNCR_EL2, as defined in table D8-66 in rule R_CSRPQ in
3
the Arm ARM. This commit covers offsets 0x100 to 0x160.
4
1
5
Many (but not all) of the registers in this range have _EL12 aliases,
6
and the slot in memory is shared between the _EL12 version of the
7
register and the _EL1 version. Where we programmatically generate
8
the regdef for the _EL12 register, arrange that its
9
nv2_redirect_offset is set up correctly to do this.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Tested-by: Miguel Luis <miguel.luis@oracle.com>
14
---
15
target/arm/debug_helper.c | 1 +
16
target/arm/helper.c | 22 ++++++++++++++++++++++
17
2 files changed, 23 insertions(+)
18
19
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/debug_helper.c
22
+++ b/target/arm/debug_helper.c
23
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
24
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
25
.access = PL1_RW, .accessfn = access_tda,
26
.fgt = FGT_MDSCR_EL1,
27
+ .nv2_redirect_offset = 0x158,
28
.fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1),
29
.resetvalue = 0 },
30
/*
31
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/helper.c
34
+++ b/target/arm/helper.c
35
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cp_reginfo[] = {
36
.opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
37
.access = PL1_RW, .accessfn = access_tvm_trvm,
38
.fgt = FGT_CONTEXTIDR_EL1,
39
+ .nv2_redirect_offset = 0x108 | NV2_REDIR_NV1,
40
.secure = ARM_CP_SECSTATE_NS,
41
.fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[1]),
42
.resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
43
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
44
{ .name = "CPACR", .state = ARM_CP_STATE_BOTH, .opc0 = 3,
45
.crn = 1, .crm = 0, .opc1 = 0, .opc2 = 2, .accessfn = cpacr_access,
46
.fgt = FGT_CPACR_EL1,
47
+ .nv2_redirect_offset = 0x100 | NV2_REDIR_NV1,
48
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.cpacr_el1),
49
.resetfn = cpacr_reset, .writefn = cpacr_write, .readfn = cpacr_read },
50
};
51
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
52
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 0,
53
.access = PL1_RW, .accessfn = access_tvm_trvm,
54
.fgt = FGT_AFSR0_EL1,
55
+ .nv2_redirect_offset = 0x128 | NV2_REDIR_NV1,
56
.type = ARM_CP_CONST, .resetvalue = 0 },
57
{ .name = "AFSR1_EL1", .state = ARM_CP_STATE_BOTH,
58
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 1,
59
.access = PL1_RW, .accessfn = access_tvm_trvm,
60
.fgt = FGT_AFSR1_EL1,
61
+ .nv2_redirect_offset = 0x130 | NV2_REDIR_NV1,
62
.type = ARM_CP_CONST, .resetvalue = 0 },
63
/*
64
* MAIR can just read-as-written because we don't implement caches
65
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
66
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0,
67
.access = PL1_RW, .accessfn = access_tvm_trvm,
68
.fgt = FGT_MAIR_EL1,
69
+ .nv2_redirect_offset = 0x140 | NV2_REDIR_NV1,
70
.fieldoffset = offsetof(CPUARMState, cp15.mair_el[1]),
71
.resetvalue = 0 },
72
{ .name = "MAIR_EL3", .state = ARM_CP_STATE_AA64,
73
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
74
.opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0,
75
.access = PL1_RW, .accessfn = access_tvm_trvm,
76
.fgt = FGT_ESR_EL1,
77
+ .nv2_redirect_offset = 0x138 | NV2_REDIR_NV1,
78
.fieldoffset = offsetof(CPUARMState, cp15.esr_el[1]), .resetvalue = 0, },
79
{ .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
80
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0,
81
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
82
.opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
83
.access = PL1_RW, .accessfn = access_tvm_trvm,
84
.fgt = FGT_TCR_EL1,
85
+ .nv2_redirect_offset = 0x120 | NV2_REDIR_NV1,
86
.writefn = vmsa_tcr_el12_write,
87
.raw_writefn = raw_write,
88
.resetvalue = 0,
89
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
90
.opc0 = 3, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 0,
91
.access = PL1_RW, .accessfn = access_tvm_trvm,
92
.fgt = FGT_AMAIR_EL1,
93
+ .nv2_redirect_offset = 0x148 | NV2_REDIR_NV1,
94
.type = ARM_CP_CONST, .resetvalue = 0 },
95
/* AMAIR1 is mapped to AMAIR_EL1[63:32] */
96
{ .name = "AMAIR1", .cp = 15, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 1,
97
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
98
.type = ARM_CP_ALIAS,
99
.opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 0,
100
.access = PL1_RW, .accessfn = access_nv1,
101
+ .nv2_redirect_offset = 0x160 | NV2_REDIR_NV1,
102
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_SVC]) },
103
/*
104
* We rely on the access checks not allowing the guest to write to the
105
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
106
new_reg->writefn = el2_e2h_e12_write;
107
new_reg->accessfn = el2_e2h_e12_access;
108
109
+ /*
110
+ * If the _EL1 register is redirected to memory by FEAT_NV2,
111
+ * then it shares the offset with the _EL12 register,
112
+ * and which one is redirected depends on HCR_EL2.NV1.
113
+ */
114
+ if (new_reg->nv2_redirect_offset) {
115
+ assert(new_reg->nv2_redirect_offset & NV2_REDIR_NV1);
116
+ new_reg->nv2_redirect_offset &= ~NV2_REDIR_NV1;
117
+ new_reg->nv2_redirect_offset |= NV2_REDIR_NO_NV1;
118
+ }
119
+
120
ok = g_hash_table_insert(cpu->cp_regs,
121
(gpointer)(uintptr_t)a->new_key, new_reg);
122
g_assert(ok);
123
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
124
{ .name = "ACTLR_EL1", .state = ARM_CP_STATE_BOTH,
125
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 1,
126
.access = PL1_RW, .accessfn = access_tacr,
127
+ .nv2_redirect_offset = 0x118,
128
.type = ARM_CP_CONST, .resetvalue = cpu->reset_auxcr },
129
{ .name = "ACTLR_EL2", .state = ARM_CP_STATE_BOTH,
130
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 1,
131
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
132
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0,
133
.access = PL1_RW, .accessfn = access_tvm_trvm,
134
.fgt = FGT_SCTLR_EL1,
135
+ .nv2_redirect_offset = 0x110 | NV2_REDIR_NV1,
136
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.sctlr_s),
137
offsetof(CPUARMState, cp15.sctlr_ns) },
138
.writefn = sctlr_write, .resetvalue = cpu->reset_sctlr,
139
--
140
2.34.1
diff view generated by jsdifflib
Deleted patch
1
Mark up the cpreginfo structs to indicate offsets for system
2
registers from VNCR_EL2, as defined in table D8-66 in rule R_CSRPQ in
3
the Arm ARM. This commit covers offsets 0x168 to 0x1f8.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Miguel Luis <miguel.luis@oracle.com>
8
---
9
target/arm/helper.c | 18 ++++++++++++++++++
10
1 file changed, 18 insertions(+)
11
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
15
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
17
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 1,
18
.type = ARM_CP_IO, .access = PL0_RW,
19
.accessfn = gt_ptimer_access,
20
+ .nv2_redirect_offset = 0x180 | NV2_REDIR_NV1,
21
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl),
22
.resetvalue = 0,
23
.readfn = gt_phys_redir_ctl_read, .raw_readfn = raw_read,
24
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
25
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 1,
26
.type = ARM_CP_IO, .access = PL0_RW,
27
.accessfn = gt_vtimer_access,
28
+ .nv2_redirect_offset = 0x170 | NV2_REDIR_NV1,
29
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl),
30
.resetvalue = 0,
31
.readfn = gt_virt_redir_ctl_read, .raw_readfn = raw_read,
32
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
33
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 2,
34
.access = PL0_RW,
35
.type = ARM_CP_IO,
36
+ .nv2_redirect_offset = 0x178 | NV2_REDIR_NV1,
37
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval),
38
.resetvalue = 0, .accessfn = gt_ptimer_access,
39
.readfn = gt_phys_redir_cval_read, .raw_readfn = raw_read,
40
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
41
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 2,
42
.access = PL0_RW,
43
.type = ARM_CP_IO,
44
+ .nv2_redirect_offset = 0x168 | NV2_REDIR_NV1,
45
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval),
46
.resetvalue = 0, .accessfn = gt_vtimer_access,
47
.readfn = gt_virt_redir_cval_read, .raw_readfn = raw_read,
48
@@ -XXX,XX +XXX,XX @@ static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
49
static const ARMCPRegInfo zcr_reginfo[] = {
50
{ .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
51
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
52
+ .nv2_redirect_offset = 0x1e0 | NV2_REDIR_NV1,
53
.access = PL1_RW, .type = ARM_CP_SVE,
54
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
55
.writefn = zcr_write, .raw_writefn = raw_write },
56
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo sme_reginfo[] = {
57
.writefn = svcr_write, .raw_writefn = raw_write },
58
{ .name = "SMCR_EL1", .state = ARM_CP_STATE_AA64,
59
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 6,
60
+ .nv2_redirect_offset = 0x1f0 | NV2_REDIR_NV1,
61
.access = PL1_RW, .type = ARM_CP_SME,
62
.fieldoffset = offsetof(CPUARMState, vfp.smcr_el[1]),
63
.writefn = smcr_write, .raw_writefn = raw_write },
64
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo sme_reginfo[] = {
65
.type = ARM_CP_CONST, .resetvalue = 0 },
66
{ .name = "SMPRIMAP_EL2", .state = ARM_CP_STATE_AA64,
67
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 5,
68
+ .nv2_redirect_offset = 0x1f8,
69
.access = PL2_RW, .accessfn = access_smprimap,
70
.type = ARM_CP_CONST, .resetvalue = 0 },
71
};
72
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_reginfo[] = {
73
{ .name = "TFSR_EL1", .state = ARM_CP_STATE_AA64,
74
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 6, .opc2 = 0,
75
.access = PL1_RW, .accessfn = access_tfsr_el1,
76
+ .nv2_redirect_offset = 0x190 | NV2_REDIR_NV1,
77
.fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[1]) },
78
{ .name = "TFSR_EL2", .state = ARM_CP_STATE_AA64,
79
.type = ARM_CP_NV2_REDIRECT,
80
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo scxtnum_reginfo[] = {
81
.opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 7,
82
.access = PL1_RW, .accessfn = access_scxtnum_el1,
83
.fgt = FGT_SCXTNUM_EL1,
84
+ .nv2_redirect_offset = 0x188 | NV2_REDIR_NV1,
85
.fieldoffset = offsetof(CPUARMState, scxtnum_el[1]) },
86
{ .name = "SCXTNUM_EL2", .state = ARM_CP_STATE_AA64,
87
.opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 7,
88
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_fgt(CPUARMState *env, const ARMCPRegInfo *ri,
89
static const ARMCPRegInfo fgt_reginfo[] = {
90
{ .name = "HFGRTR_EL2", .state = ARM_CP_STATE_AA64,
91
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4,
92
+ .nv2_redirect_offset = 0x1b8,
93
.access = PL2_RW, .accessfn = access_fgt,
94
.fieldoffset = offsetof(CPUARMState, cp15.fgt_read[FGTREG_HFGRTR]) },
95
{ .name = "HFGWTR_EL2", .state = ARM_CP_STATE_AA64,
96
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 5,
97
+ .nv2_redirect_offset = 0x1c0,
98
.access = PL2_RW, .accessfn = access_fgt,
99
.fieldoffset = offsetof(CPUARMState, cp15.fgt_write[FGTREG_HFGWTR]) },
100
{ .name = "HDFGRTR_EL2", .state = ARM_CP_STATE_AA64,
101
.opc0 = 3, .opc1 = 4, .crn = 3, .crm = 1, .opc2 = 4,
102
+ .nv2_redirect_offset = 0x1d0,
103
.access = PL2_RW, .accessfn = access_fgt,
104
.fieldoffset = offsetof(CPUARMState, cp15.fgt_read[FGTREG_HDFGRTR]) },
105
{ .name = "HDFGWTR_EL2", .state = ARM_CP_STATE_AA64,
106
.opc0 = 3, .opc1 = 4, .crn = 3, .crm = 1, .opc2 = 5,
107
+ .nv2_redirect_offset = 0x1d8,
108
.access = PL2_RW, .accessfn = access_fgt,
109
.fieldoffset = offsetof(CPUARMState, cp15.fgt_write[FGTREG_HDFGWTR]) },
110
{ .name = "HFGITR_EL2", .state = ARM_CP_STATE_AA64,
111
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 6,
112
+ .nv2_redirect_offset = 0x1c8,
113
.access = PL2_RW, .accessfn = access_fgt,
114
.fieldoffset = offsetof(CPUARMState, cp15.fgt_exec[FGTREG_HFGITR]) },
115
};
116
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vhe_reginfo[] = {
117
.opc0 = 3, .opc1 = 5, .crn = 14, .crm = 2, .opc2 = 1,
118
.type = ARM_CP_IO | ARM_CP_ALIAS,
119
.access = PL2_RW, .accessfn = e2h_access,
120
+ .nv2_redirect_offset = 0x180 | NV2_REDIR_NO_NV1,
121
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl),
122
.writefn = gt_phys_ctl_write, .raw_writefn = raw_write },
123
{ .name = "CNTV_CTL_EL02", .state = ARM_CP_STATE_AA64,
124
.opc0 = 3, .opc1 = 5, .crn = 14, .crm = 3, .opc2 = 1,
125
.type = ARM_CP_IO | ARM_CP_ALIAS,
126
.access = PL2_RW, .accessfn = e2h_access,
127
+ .nv2_redirect_offset = 0x170 | NV2_REDIR_NO_NV1,
128
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl),
129
.writefn = gt_virt_ctl_write, .raw_writefn = raw_write },
130
{ .name = "CNTP_TVAL_EL02", .state = ARM_CP_STATE_AA64,
131
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vhe_reginfo[] = {
132
.opc0 = 3, .opc1 = 5, .crn = 14, .crm = 2, .opc2 = 2,
133
.type = ARM_CP_IO | ARM_CP_ALIAS,
134
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval),
135
+ .nv2_redirect_offset = 0x178 | NV2_REDIR_NO_NV1,
136
.access = PL2_RW, .accessfn = e2h_access,
137
.writefn = gt_phys_cval_write, .raw_writefn = raw_write },
138
{ .name = "CNTV_CVAL_EL02", .state = ARM_CP_STATE_AA64,
139
.opc0 = 3, .opc1 = 5, .crn = 14, .crm = 3, .opc2 = 2,
140
.type = ARM_CP_IO | ARM_CP_ALIAS,
141
+ .nv2_redirect_offset = 0x168 | NV2_REDIR_NO_NV1,
142
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval),
143
.access = PL2_RW, .accessfn = e2h_access,
144
.writefn = gt_virt_cval_write, .raw_writefn = raw_write },
145
--
146
2.34.1
diff view generated by jsdifflib
Deleted patch
1
Mark up the cpreginfo structs to indicate offsets for system
2
registers from VNCR_EL2, as defined in table D8-66 in rule R_CSRPQ in
3
the Arm ARM. This covers all the remaining offsets at 0x200 and
4
above, except for the GIC ICH_* registers.
5
1
6
(Note that because we don't implement FEAT_SPE, FEAT_TRF,
7
FEAT_MPAM, FEAT_BRBE or FEAT_AMUv1p1 we don't implement any
8
of the registers that use offsets at 0x800 and above.)
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Tested-by: Miguel Luis <miguel.luis@oracle.com>
13
---
14
target/arm/helper.c | 8 ++++++++
15
1 file changed, 8 insertions(+)
16
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
20
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_pmsa_cp_reginfo[] = {
22
.opc0 = 3, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
23
.access = PL1_RW, .accessfn = access_tvm_trvm,
24
.fgt = FGT_FAR_EL1,
25
+ .nv2_redirect_offset = 0x220 | NV2_REDIR_NV1,
26
.fieldoffset = offsetof(CPUARMState, cp15.far_el[1]),
27
.resetvalue = 0, },
28
};
29
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
30
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0,
31
.access = PL1_RW, .accessfn = access_tvm_trvm,
32
.fgt = FGT_TTBR0_EL1,
33
+ .nv2_redirect_offset = 0x200 | NV2_REDIR_NV1,
34
.writefn = vmsa_ttbr_write, .resetvalue = 0, .raw_writefn = raw_write,
35
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
36
offsetof(CPUARMState, cp15.ttbr0_ns) } },
37
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
38
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 1,
39
.access = PL1_RW, .accessfn = access_tvm_trvm,
40
.fgt = FGT_TTBR1_EL1,
41
+ .nv2_redirect_offset = 0x210 | NV2_REDIR_NV1,
42
.writefn = vmsa_ttbr_write, .resetvalue = 0, .raw_writefn = raw_write,
43
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
44
offsetof(CPUARMState, cp15.ttbr1_ns) } },
45
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
46
.type = ARM_CP_ALIAS,
47
.opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 1,
48
.access = PL1_RW, .accessfn = access_nv1,
49
+ .nv2_redirect_offset = 0x230 | NV2_REDIR_NV1,
50
.fieldoffset = offsetof(CPUARMState, elr_el[1]) },
51
{ .name = "SPSR_EL1", .state = ARM_CP_STATE_AA64,
52
.type = ARM_CP_ALIAS,
53
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
54
.fieldoffset = offsetof(CPUARMState, sp_el[0]) },
55
{ .name = "SP_EL1", .state = ARM_CP_STATE_AA64,
56
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 1, .opc2 = 0,
57
+ .nv2_redirect_offset = 0x240,
58
.access = PL2_RW, .type = ARM_CP_ALIAS | ARM_CP_EL3_NO_EL2_KEEP,
59
.fieldoffset = offsetof(CPUARMState, sp_el[1]) },
60
{ .name = "SPSel", .state = ARM_CP_STATE_AA64,
61
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo minimal_ras_reginfo[] = {
62
.type = ARM_CP_CONST, .resetvalue = 0 },
63
{ .name = "VDISR_EL2", .state = ARM_CP_STATE_BOTH,
64
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 1, .opc2 = 1,
65
+ .nv2_redirect_offset = 0x500,
66
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.vdisr_el2) },
67
{ .name = "VSESR_EL2", .state = ARM_CP_STATE_BOTH,
68
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 3,
69
+ .nv2_redirect_offset = 0x508,
70
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.vsesr_el2) },
71
};
72
73
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
74
.access = PL1_RW, .writefn = vbar_write,
75
.accessfn = access_nv1,
76
.fgt = FGT_VBAR_EL1,
77
+ .nv2_redirect_offset = 0x250 | NV2_REDIR_NV1,
78
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s),
79
offsetof(CPUARMState, cp15.vbar_ns) },
80
.resetvalue = 0 },
81
--
82
2.34.1
diff view generated by jsdifflib
Deleted patch
1
Mark up the cpreginfo structs for the GIC CPU registers to indicate
2
the offsets from VNCR_EL2, as defined in table D8-66 in rule R_CSRPQ
3
in the Arm ARM.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Miguel Luis <miguel.luis@oracle.com>
8
---
9
hw/intc/arm_gicv3_cpuif.c | 11 +++++++++++
10
1 file changed, 11 insertions(+)
11
12
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/intc/arm_gicv3_cpuif.c
15
+++ b/hw/intc/arm_gicv3_cpuif.c
16
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_hcr_reginfo[] = {
17
{ .name = "ICH_AP0R0_EL2", .state = ARM_CP_STATE_BOTH,
18
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 8, .opc2 = 0,
19
.type = ARM_CP_IO | ARM_CP_NO_RAW,
20
+ .nv2_redirect_offset = 0x480,
21
.access = PL2_RW,
22
.readfn = ich_ap_read,
23
.writefn = ich_ap_write,
24
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_hcr_reginfo[] = {
25
{ .name = "ICH_AP1R0_EL2", .state = ARM_CP_STATE_BOTH,
26
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 9, .opc2 = 0,
27
.type = ARM_CP_IO | ARM_CP_NO_RAW,
28
+ .nv2_redirect_offset = 0x4a0,
29
.access = PL2_RW,
30
.readfn = ich_ap_read,
31
.writefn = ich_ap_write,
32
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_hcr_reginfo[] = {
33
{ .name = "ICH_HCR_EL2", .state = ARM_CP_STATE_BOTH,
34
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 11, .opc2 = 0,
35
.type = ARM_CP_IO | ARM_CP_NO_RAW,
36
+ .nv2_redirect_offset = 0x4c0,
37
.access = PL2_RW,
38
.readfn = ich_hcr_read,
39
.writefn = ich_hcr_write,
40
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_hcr_reginfo[] = {
41
{ .name = "ICH_VMCR_EL2", .state = ARM_CP_STATE_BOTH,
42
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 11, .opc2 = 7,
43
.type = ARM_CP_IO | ARM_CP_NO_RAW,
44
+ .nv2_redirect_offset = 0x4c8,
45
.access = PL2_RW,
46
.readfn = ich_vmcr_read,
47
.writefn = ich_vmcr_write,
48
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_ich_apxr1_reginfo[] = {
49
{ .name = "ICH_AP0R1_EL2", .state = ARM_CP_STATE_BOTH,
50
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 8, .opc2 = 1,
51
.type = ARM_CP_IO | ARM_CP_NO_RAW,
52
+ .nv2_redirect_offset = 0x488,
53
.access = PL2_RW,
54
.readfn = ich_ap_read,
55
.writefn = ich_ap_write,
56
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_ich_apxr1_reginfo[] = {
57
{ .name = "ICH_AP1R1_EL2", .state = ARM_CP_STATE_BOTH,
58
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 9, .opc2 = 1,
59
.type = ARM_CP_IO | ARM_CP_NO_RAW,
60
+ .nv2_redirect_offset = 0x4a8,
61
.access = PL2_RW,
62
.readfn = ich_ap_read,
63
.writefn = ich_ap_write,
64
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_ich_apxr23_reginfo[] = {
65
{ .name = "ICH_AP0R2_EL2", .state = ARM_CP_STATE_BOTH,
66
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 8, .opc2 = 2,
67
.type = ARM_CP_IO | ARM_CP_NO_RAW,
68
+ .nv2_redirect_offset = 0x490,
69
.access = PL2_RW,
70
.readfn = ich_ap_read,
71
.writefn = ich_ap_write,
72
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_ich_apxr23_reginfo[] = {
73
{ .name = "ICH_AP0R3_EL2", .state = ARM_CP_STATE_BOTH,
74
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 8, .opc2 = 3,
75
.type = ARM_CP_IO | ARM_CP_NO_RAW,
76
+ .nv2_redirect_offset = 0x498,
77
.access = PL2_RW,
78
.readfn = ich_ap_read,
79
.writefn = ich_ap_write,
80
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_ich_apxr23_reginfo[] = {
81
{ .name = "ICH_AP1R2_EL2", .state = ARM_CP_STATE_BOTH,
82
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 9, .opc2 = 2,
83
.type = ARM_CP_IO | ARM_CP_NO_RAW,
84
+ .nv2_redirect_offset = 0x4b0,
85
.access = PL2_RW,
86
.readfn = ich_ap_read,
87
.writefn = ich_ap_write,
88
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_ich_apxr23_reginfo[] = {
89
{ .name = "ICH_AP1R3_EL2", .state = ARM_CP_STATE_BOTH,
90
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 9, .opc2 = 3,
91
.type = ARM_CP_IO | ARM_CP_NO_RAW,
92
+ .nv2_redirect_offset = 0x4b8,
93
.access = PL2_RW,
94
.readfn = ich_ap_read,
95
.writefn = ich_ap_write,
96
@@ -XXX,XX +XXX,XX @@ void gicv3_init_cpuif(GICv3State *s)
97
.opc0 = 3, .opc1 = 4, .crn = 12,
98
.crm = 12 + (j >> 3), .opc2 = j & 7,
99
.type = ARM_CP_IO | ARM_CP_NO_RAW,
100
+ .nv2_redirect_offset = 0x400 + 8 * j,
101
.access = PL2_RW,
102
.readfn = ich_lr_read,
103
.writefn = ich_lr_write,
104
--
105
2.34.1
diff view generated by jsdifflib