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 |