1
Hi; this is the latest target-arm queue; most of this is a refactoring
1
Hi; here's the first target-arm pullreq for the 8.1 cycle.
2
patchset from RTH for the arm page-table-walk emulation.
2
Nothing particularly huge in here, just the various things
3
that had accumulated during the freeze.
3
4
4
thanks
5
thanks
5
-- PMM
6
-- PMM
6
7
7
The following changes since commit f1d33f55c47dfdaf8daacd618588ad3ae4c452d1:
8
The following changes since commit 2d82c32b2ceaca3dc3da5e36e10976f34bfcb598:
8
9
9
Merge tag 'pull-testing-gdbstub-plugins-gitdm-061022-3' of https://github.com/stsquad/qemu into staging (2022-10-06 07:11:56 -0400)
10
Open 8.1 development tree (2023-04-20 10:05:25 +0100)
10
11
11
are available in the Git repository at:
12
are available in the Git repository at:
12
13
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20221010
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230420
14
15
15
for you to fetch changes up to 915f62844cf62e428c7c178149b5ff1cbe129b07:
16
for you to fetch changes up to 1ed1f338520cda0574b7e04f5e8e85e049740548:
16
17
17
docs/system/arm/emulation.rst: Report FEAT_GTG support (2022-10-10 14:52:25 +0100)
18
arm/mcimx7d-sabre: Set fec2-phy-connected property to false (2023-04-20 10:46:43 +0100)
18
19
19
----------------------------------------------------------------
20
----------------------------------------------------------------
20
target-arm queue:
21
target-arm queue:
21
* Retry KVM_CREATE_VM call if it fails EINTR
22
* hw/arm: Fix some typos in comments (most found by codespell)
22
* allow setting SCR_EL3.EnTP2 when FEAT_SME is implemented
23
* exynos: Fix out-of-bounds access in exynos4210_gcomp_find debug printf
23
* docs/nuvoton: Update URL for images
24
* Orangepi-PC, Cubieboard: add Allwinner WDT watchdog emulation
24
* refactoring of page table walk code
25
* tests/avocado: Add reboot tests to Cubieboard
25
* hw/arm/boot: set CPTR_EL3.ESM and SCR_EL3.EnTP2 when booting Linux with EL3
26
* hw/timer/imx_epit: Fix bugs in timer limit checking
26
* Don't allow guest to use unimplemented granule sizes
27
* target/arm: Remove KVM AArch32 CPU definitions
27
* Report FEAT_GTG support
28
* hw/arm/virt: Restrict Cortex-A7 check to TCG
29
* target/arm: Initialize debug capabilities only once
30
* target/arm: Implement FEAT_PAN3
31
* docs/devel/kconfig.rst: Fix incorrect markup
32
* target/arm: Report pauth information to gdb as 'pauth_v2'
33
* mcimxd7-sabre, mcimx6ul-evk: Correctly model the way the PHY
34
on the second ethernet device must be configured via the
35
first one
28
36
29
----------------------------------------------------------------
37
----------------------------------------------------------------
30
Jerome Forissier (2):
38
Akihiko Odaki (1):
31
target/arm: allow setting SCR_EL3.EnTP2 when FEAT_SME is implemented
39
target/arm: Initialize debug capabilities only once
32
hw/arm/boot: set CPTR_EL3.ESM and SCR_EL3.EnTP2 when booting Linux with EL3
33
40
34
Joel Stanley (1):
41
Axel Heider (2):
35
docs/nuvoton: Update URL for images
42
hw/timer/imx_epit: don't shadow variable
43
hw/timer/imx_epit: fix limit check
36
44
37
Peter Maydell (4):
45
Feng Jiang (1):
38
target/arm/kvm: Retry KVM_CREATE_VM call if it fails EINTR
46
exynos: Fix out-of-bounds access in exynos4210_gcomp_find debug printf
39
target/arm: Don't allow guest to use unimplemented granule sizes
40
target/arm: Use ARMGranuleSize in ARMVAParameters
41
docs/system/arm/emulation.rst: Report FEAT_GTG support
42
47
43
Richard Henderson (21):
48
Guenter Roeck (5):
44
target/arm: Split s2walk_secure from ipa_secure in get_phys_addr
49
hw/net/imx_fec: Support two Ethernet interfaces connected to single MDIO bus
45
target/arm: Make the final stage1+2 write to secure be unconditional
50
fsl-imx6ul: Add fec[12]-phy-connected properties
46
target/arm: Add is_secure parameter to get_phys_addr_lpae
51
arm/mcimx6ul-evk: Set fec1-phy-connected property to false
47
target/arm: Fix S2 disabled check in S1_ptw_translate
52
fsl-imx7: Add fec[12]-phy-connected properties
48
target/arm: Add is_secure parameter to regime_translation_disabled
53
arm/mcimx7d-sabre: Set fec2-phy-connected property to false
49
target/arm: Split out get_phys_addr_with_secure
50
target/arm: Add is_secure parameter to v7m_read_half_insn
51
target/arm: Add TBFLAG_M32.SECURE
52
target/arm: Merge regime_is_secure into get_phys_addr
53
target/arm: Add is_secure parameter to do_ats_write
54
target/arm: Fold secure and non-secure a-profile mmu indexes
55
target/arm: Reorg regime_translation_disabled
56
target/arm: Drop secure check for HCR.TGE vs SCTLR_EL1.M
57
target/arm: Introduce arm_hcr_el2_eff_secstate
58
target/arm: Hoist read of *is_secure in S1_ptw_translate
59
target/arm: Remove env argument from combined_attrs_fwb
60
target/arm: Pass HCR to attribute subroutines.
61
target/arm: Fix ATS12NSO* from S PL1
62
target/arm: Split out get_phys_addr_disabled
63
target/arm: Fix cacheattr in get_phys_addr_disabled
64
target/arm: Use tlb_set_page_full
65
54
66
docs/system/arm/emulation.rst | 1 +
55
Peter Maydell (5):
67
docs/system/arm/nuvoton.rst | 4 +-
56
target/arm: Pass ARMMMUFaultInfo to merge_syn_data_abort()
68
target/arm/cpu-param.h | 2 +-
57
target/arm: Don't set ISV when reporting stage 1 faults in ESR_EL2
69
target/arm/cpu.h | 181 ++++++++------
58
target/arm: Implement FEAT_PAN3
70
target/arm/internals.h | 150 ++++++-----
59
docs/devel/kconfig.rst: Fix incorrect markup
71
hw/arm/boot.c | 4 +
60
target/arm: Report pauth information to gdb as 'pauth_v2'
72
target/arm/helper.c | 332 ++++++++++++++----------
61
73
target/arm/kvm.c | 4 +-
62
Philippe Mathieu-Daudé (2):
74
target/arm/m_helper.c | 29 ++-
63
target/arm: Remove KVM AArch32 CPU definitions
75
target/arm/ptw.c | 570 ++++++++++++++++++++++--------------------
64
hw/arm/virt: Restrict Cortex-A7 check to TCG
76
target/arm/tlb_helper.c | 9 +-
65
77
target/arm/translate-a64.c | 8 -
66
Stefan Weil (1):
78
target/arm/translate.c | 9 +-
67
hw/arm: Fix some typos in comments (most found by codespell)
79
13 files changed, 717 insertions(+), 586 deletions(-)
68
69
Strahinja Jankovic (4):
70
hw/watchdog: Allwinner WDT emulation for system reset
71
hw/arm: Add WDT to Allwinner-A10 and Cubieboard
72
hw/arm: Add WDT to Allwinner-H3 and Orangepi-PC
73
tests/avocado: Add reboot tests to Cubieboard
74
75
docs/devel/kconfig.rst | 2 +-
76
docs/system/arm/cubieboard.rst | 1 +
77
docs/system/arm/emulation.rst | 1 +
78
docs/system/arm/orangepi.rst | 1 +
79
include/hw/arm/allwinner-a10.h | 2 +
80
include/hw/arm/allwinner-h3.h | 5 +-
81
include/hw/arm/fsl-imx6ul.h | 1 +
82
include/hw/arm/fsl-imx7.h | 1 +
83
include/hw/net/imx_fec.h | 2 +
84
include/hw/watchdog/allwinner-wdt.h | 123 +++++++++++
85
target/arm/cpu.h | 5 +
86
target/arm/kvm-consts.h | 9 +-
87
target/arm/kvm_arm.h | 8 +
88
hw/arm/allwinner-a10.c | 7 +
89
hw/arm/allwinner-h3.c | 8 +
90
hw/arm/exynos4210.c | 4 +-
91
hw/arm/fsl-imx6ul.c | 20 ++
92
hw/arm/fsl-imx7.c | 20 ++
93
hw/arm/mcimx6ul-evk.c | 2 +
94
hw/arm/mcimx7d-sabre.c | 2 +
95
hw/arm/musicpal.c | 2 +-
96
hw/arm/omap1.c | 2 +-
97
hw/arm/omap2.c | 2 +-
98
hw/arm/virt-acpi-build.c | 2 +-
99
hw/arm/virt.c | 4 +-
100
hw/arm/xlnx-versal-virt.c | 2 +-
101
hw/net/imx_fec.c | 27 ++-
102
hw/timer/exynos4210_mct.c | 13 +-
103
hw/timer/imx_epit.c | 2 +-
104
hw/watchdog/allwinner-wdt.c | 416 ++++++++++++++++++++++++++++++++++++
105
target/arm/cpu64.c | 2 +-
106
target/arm/cpu_tcg.c | 2 -
107
target/arm/gdbstub.c | 9 +-
108
target/arm/kvm.c | 2 +
109
target/arm/kvm64.c | 18 +-
110
target/arm/ptw.c | 14 +-
111
target/arm/tcg/tlb_helper.c | 26 ++-
112
gdb-xml/aarch64-pauth.xml | 2 +-
113
hw/arm/Kconfig | 4 +-
114
hw/watchdog/Kconfig | 4 +
115
hw/watchdog/meson.build | 1 +
116
hw/watchdog/trace-events | 7 +
117
tests/avocado/boot_linux_console.py | 15 +-
118
43 files changed, 738 insertions(+), 64 deletions(-)
119
create mode 100644 include/hw/watchdog/allwinner-wdt.h
120
create mode 100644 hw/watchdog/allwinner-wdt.c
121
diff view generated by jsdifflib
Deleted patch
1
Occasionally the KVM_CREATE_VM ioctl can return EINTR, even though
2
there is no pending signal to be taken. In commit 94ccff13382055
3
we added a retry-on-EINTR loop to the KVM_CREATE_VM call in the
4
generic KVM code. Adopt the same approach for the use of the
5
ioctl in the Arm-specific KVM code (where we use it to create a
6
scratch VM for probing for various things).
7
1
8
For more information, see the mailing list thread:
9
https://lore.kernel.org/qemu-devel/8735e0s1zw.wl-maz@kernel.org/
10
11
Reported-by: Vitaly Chikunov <vt@altlinux.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Vitaly Chikunov <vt@altlinux.org>
14
Reviewed-by: Eric Auger <eric.auger@redhat.com>
15
Acked-by: Marc Zyngier <maz@kernel.org>
16
Message-id: 20220930113824.1933293-1-peter.maydell@linaro.org
17
---
18
target/arm/kvm.c | 4 +++-
19
1 file changed, 3 insertions(+), 1 deletion(-)
20
21
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/kvm.c
24
+++ b/target/arm/kvm.c
25
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
26
if (max_vm_pa_size < 0) {
27
max_vm_pa_size = 0;
28
}
29
- vmfd = ioctl(kvmfd, KVM_CREATE_VM, max_vm_pa_size);
30
+ do {
31
+ vmfd = ioctl(kvmfd, KVM_CREATE_VM, max_vm_pa_size);
32
+ } while (vmfd == -1 && errno == EINTR);
33
if (vmfd < 0) {
34
goto err;
35
}
36
--
37
2.25.1
diff view generated by jsdifflib
Deleted patch
1
From: Jerome Forissier <jerome.forissier@linaro.org>
2
1
3
Updates write_scr() to allow setting SCR_EL3.EnTP2 when FEAT_SME is
4
implemented. SCR_EL3 being a 64-bit register, valid_mask is changed
5
to uint64_t and the SCR_* constants in target/arm/cpu.h are extended
6
to 64-bit so that masking and bitwise not (~) behave as expected.
7
8
This enables booting Linux with Trusted Firmware-A at EL3 with
9
"-M virt,secure=on -cpu max".
10
11
Cc: qemu-stable@nongnu.org
12
Fixes: 78cb9776662a ("target/arm: Enable SME for -cpu max")
13
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
14
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20221004072354.27037-1-jerome.forissier@linaro.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
target/arm/cpu.h | 54 ++++++++++++++++++++++-----------------------
20
target/arm/helper.c | 5 ++++-
21
2 files changed, 31 insertions(+), 28 deletions(-)
22
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/cpu.h
26
+++ b/target/arm/cpu.h
27
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
28
29
#define HPFAR_NS (1ULL << 63)
30
31
-#define SCR_NS (1U << 0)
32
-#define SCR_IRQ (1U << 1)
33
-#define SCR_FIQ (1U << 2)
34
-#define SCR_EA (1U << 3)
35
-#define SCR_FW (1U << 4)
36
-#define SCR_AW (1U << 5)
37
-#define SCR_NET (1U << 6)
38
-#define SCR_SMD (1U << 7)
39
-#define SCR_HCE (1U << 8)
40
-#define SCR_SIF (1U << 9)
41
-#define SCR_RW (1U << 10)
42
-#define SCR_ST (1U << 11)
43
-#define SCR_TWI (1U << 12)
44
-#define SCR_TWE (1U << 13)
45
-#define SCR_TLOR (1U << 14)
46
-#define SCR_TERR (1U << 15)
47
-#define SCR_APK (1U << 16)
48
-#define SCR_API (1U << 17)
49
-#define SCR_EEL2 (1U << 18)
50
-#define SCR_EASE (1U << 19)
51
-#define SCR_NMEA (1U << 20)
52
-#define SCR_FIEN (1U << 21)
53
-#define SCR_ENSCXT (1U << 25)
54
-#define SCR_ATA (1U << 26)
55
-#define SCR_FGTEN (1U << 27)
56
-#define SCR_ECVEN (1U << 28)
57
-#define SCR_TWEDEN (1U << 29)
58
+#define SCR_NS (1ULL << 0)
59
+#define SCR_IRQ (1ULL << 1)
60
+#define SCR_FIQ (1ULL << 2)
61
+#define SCR_EA (1ULL << 3)
62
+#define SCR_FW (1ULL << 4)
63
+#define SCR_AW (1ULL << 5)
64
+#define SCR_NET (1ULL << 6)
65
+#define SCR_SMD (1ULL << 7)
66
+#define SCR_HCE (1ULL << 8)
67
+#define SCR_SIF (1ULL << 9)
68
+#define SCR_RW (1ULL << 10)
69
+#define SCR_ST (1ULL << 11)
70
+#define SCR_TWI (1ULL << 12)
71
+#define SCR_TWE (1ULL << 13)
72
+#define SCR_TLOR (1ULL << 14)
73
+#define SCR_TERR (1ULL << 15)
74
+#define SCR_APK (1ULL << 16)
75
+#define SCR_API (1ULL << 17)
76
+#define SCR_EEL2 (1ULL << 18)
77
+#define SCR_EASE (1ULL << 19)
78
+#define SCR_NMEA (1ULL << 20)
79
+#define SCR_FIEN (1ULL << 21)
80
+#define SCR_ENSCXT (1ULL << 25)
81
+#define SCR_ATA (1ULL << 26)
82
+#define SCR_FGTEN (1ULL << 27)
83
+#define SCR_ECVEN (1ULL << 28)
84
+#define SCR_TWEDEN (1ULL << 29)
85
#define SCR_TWEDEL MAKE_64BIT_MASK(30, 4)
86
#define SCR_TME (1ULL << 34)
87
#define SCR_AMVOFFEN (1ULL << 35)
88
diff --git a/target/arm/helper.c b/target/arm/helper.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/helper.c
91
+++ b/target/arm/helper.c
92
@@ -XXX,XX +XXX,XX @@ static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
93
static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
94
{
95
/* Begin with base v8.0 state. */
96
- uint32_t valid_mask = 0x3fff;
97
+ uint64_t valid_mask = 0x3fff;
98
ARMCPU *cpu = env_archcpu(env);
99
100
/*
101
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
102
if (cpu_isar_feature(aa64_doublefault, cpu)) {
103
valid_mask |= SCR_EASE | SCR_NMEA;
104
}
105
+ if (cpu_isar_feature(aa64_sme, cpu)) {
106
+ valid_mask |= SCR_ENTP2;
107
+ }
108
} else {
109
valid_mask &= ~(SCR_RW | SCR_ST);
110
if (cpu_isar_feature(aa32_ras, cpu)) {
111
--
112
2.25.1
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
From: Stefan Weil <sw@weilnetz.de>
2
2
3
openpower.xyz was retired some time ago. The OpenBMC Jenkins is where
3
Signed-off-by: Stefan Weil <sw@weilnetz.de>
4
images can be found these days.
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
5
Message-id: 20230409200526.1156456-1-sw@weilnetz.de
6
Signed-off-by: Joel Stanley <joel@jms.id.au>
7
Reviewed-by: Hao Wu <wuhaotsh@google.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20221004050042.22681-1-joel@jms.id.au
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
7
---
13
docs/system/arm/nuvoton.rst | 4 ++--
8
hw/arm/exynos4210.c | 4 ++--
14
1 file changed, 2 insertions(+), 2 deletions(-)
9
hw/arm/musicpal.c | 2 +-
10
hw/arm/omap1.c | 2 +-
11
hw/arm/omap2.c | 2 +-
12
hw/arm/virt-acpi-build.c | 2 +-
13
hw/arm/virt.c | 2 +-
14
hw/arm/xlnx-versal-virt.c | 2 +-
15
hw/arm/Kconfig | 2 +-
16
8 files changed, 9 insertions(+), 9 deletions(-)
15
17
16
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
18
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/docs/system/arm/nuvoton.rst
20
--- a/hw/arm/exynos4210.c
19
+++ b/docs/system/arm/nuvoton.rst
21
+++ b/hw/arm/exynos4210.c
20
@@ -XXX,XX +XXX,XX @@ Boot options
22
@@ -XXX,XX +XXX,XX @@ static int mapline_size(const int *mapline)
21
23
22
The Nuvoton machines can boot from an OpenBMC firmware image, or directly into
24
/*
23
a kernel using the ``-kernel`` option. OpenBMC images for ``quanta-gsj`` and
25
* Initialize board IRQs.
24
-possibly others can be downloaded from the OpenPOWER jenkins :
26
- * These IRQs contain splitted Int/External Combiner and External Gic IRQs.
25
+possibly others can be downloaded from the OpenBMC jenkins :
27
+ * These IRQs contain split Int/External Combiner and External Gic IRQs.
26
28
*/
27
- https://openpower.xyz/
29
static void exynos4210_init_board_irqs(Exynos4210State *s)
28
+ https://jenkins.openbmc.org/
30
{
29
31
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
30
The firmware image should be attached as an MTD drive. Example :
32
* - SDMA
31
33
* - ADMA2
34
*
35
- * As this part of the Exynos4210 is not publically available,
36
+ * As this part of the Exynos4210 is not publicly available,
37
* we used the "HS-MMC Controller S3C2416X RISC Microprocessor"
38
* public datasheet which is very similar (implementing
39
* MMC Specification Version 4.0 being the only difference noted)
40
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/arm/musicpal.c
43
+++ b/hw/arm/musicpal.c
44
@@ -XXX,XX +XXX,XX @@
45
#define MP_LCD_SPI_CMD 0x00104011
46
#define MP_LCD_SPI_INVALID 0x00000000
47
48
-/* Commmands */
49
+/* Commands */
50
#define MP_LCD_INST_SETPAGE0 0xB0
51
/* ... */
52
#define MP_LCD_INST_SETPAGE7 0xB7
53
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/arm/omap1.c
56
+++ b/hw/arm/omap1.c
57
@@ -XXX,XX +XXX,XX @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *dram,
58
s->led[1] = omap_lpg_init(system_memory,
59
0xfffbd800, omap_findclk(s, "clk32-kHz"));
60
61
- /* Register mappings not currenlty implemented:
62
+ /* Register mappings not currently implemented:
63
* MCSI2 Comm    fffb2000 - fffb27ff (not mapped on OMAP310)
64
* MCSI1 Bluetooth    fffb2800 - fffb2fff (not mapped on OMAP310)
65
* USB W2FC        fffb4000 - fffb47ff
66
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/arm/omap2.c
69
+++ b/hw/arm/omap2.c
70
@@ -XXX,XX +XXX,XX @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sdram,
71
omap_findclk(s, "func_96m_clk"),
72
omap_findclk(s, "core_l4_iclk"));
73
74
- /* All register mappings (includin those not currenlty implemented):
75
+ /* All register mappings (including those not currently implemented):
76
* SystemControlMod    48000000 - 48000fff
77
* SystemControlL4    48001000 - 48001fff
78
* 32kHz Timer Mod    48004000 - 48004fff
79
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/hw/arm/virt-acpi-build.c
82
+++ b/hw/arm/virt-acpi-build.c
83
@@ -XXX,XX +XXX,XX @@ static void build_append_gicr(GArray *table_data, uint64_t base, uint32_t size)
84
build_append_int_noprefix(table_data, 0xE, 1); /* Type */
85
build_append_int_noprefix(table_data, 16, 1); /* Length */
86
build_append_int_noprefix(table_data, 0, 2); /* Reserved */
87
- /* Discovery Range Base Addres */
88
+ /* Discovery Range Base Address */
89
build_append_int_noprefix(table_data, base, 8);
90
build_append_int_noprefix(table_data, size, 4); /* Discovery Range Length */
91
}
92
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/hw/arm/virt.c
95
+++ b/hw/arm/virt.c
96
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
97
int pa_bits;
98
99
/*
100
- * Instanciate a temporary CPU object to find out about what
101
+ * Instantiate a temporary CPU object to find out about what
102
* we are about to deal with. Once this is done, get rid of
103
* the object.
104
*/
105
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/hw/arm/xlnx-versal-virt.c
108
+++ b/hw/arm/xlnx-versal-virt.c
109
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
110
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
111
112
/* Make the APU cpu address space visible to virtio and other
113
- * modules unaware of muliple address-spaces. */
114
+ * modules unaware of multiple address-spaces. */
115
memory_region_add_subregion_overlap(get_system_memory(),
116
0, &s->soc.fpd.apu.mr, 0);
117
118
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
119
index XXXXXXX..XXXXXXX 100644
120
--- a/hw/arm/Kconfig
121
+++ b/hw/arm/Kconfig
122
@@ -XXX,XX +XXX,XX @@ config OLIMEX_STM32_H405
123
config NSERIES
124
bool
125
select OMAP
126
- select TMP105 # tempature sensor
127
+ select TMP105 # temperature sensor
128
select BLIZZARD # LCD/TV controller
129
select ONENAND
130
select TSC210X # touchscreen/sensors/audio
32
--
131
--
33
2.25.1
132
2.34.1
34
133
35
134
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
The starting security state comes with the translation regime,
4
not the current state of arm_is_secure_below_el3().
5
6
Create a new local variable, s2walk_secure, which does not need
7
to be written back to result->attrs.secure -- we compute that
8
value later, after the S2 walk is complete.
9
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20221001162318.153420-2-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
target/arm/ptw.c | 18 +++++++++---------
16
1 file changed, 9 insertions(+), 9 deletions(-)
17
18
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/ptw.c
21
+++ b/target/arm/ptw.c
22
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
23
hwaddr ipa;
24
int s1_prot;
25
int ret;
26
- bool ipa_secure;
27
+ bool ipa_secure, s2walk_secure;
28
ARMCacheAttrs cacheattrs1;
29
ARMMMUIdx s2_mmu_idx;
30
bool is_el0;
31
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
32
33
ipa = result->phys;
34
ipa_secure = result->attrs.secure;
35
- if (arm_is_secure_below_el3(env)) {
36
- if (ipa_secure) {
37
- result->attrs.secure = !(env->cp15.vstcr_el2 & VSTCR_SW);
38
- } else {
39
- result->attrs.secure = !(env->cp15.vtcr_el2 & VTCR_NSW);
40
- }
41
+ if (is_secure) {
42
+ /* Select TCR based on the NS bit from the S1 walk. */
43
+ s2walk_secure = !(ipa_secure
44
+ ? env->cp15.vstcr_el2 & VSTCR_SW
45
+ : env->cp15.vtcr_el2 & VTCR_NSW);
46
} else {
47
assert(!ipa_secure);
48
+ s2walk_secure = false;
49
}
50
51
- s2_mmu_idx = (result->attrs.secure
52
+ s2_mmu_idx = (s2walk_secure
53
? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2);
54
is_el0 = mmu_idx == ARMMMUIdx_E10_0 || mmu_idx == ARMMMUIdx_SE10_0;
55
56
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
57
result->cacheattrs);
58
59
/* Check if IPA translates to secure or non-secure PA space. */
60
- if (arm_is_secure_below_el3(env)) {
61
+ if (is_secure) {
62
if (ipa_secure) {
63
result->attrs.secure =
64
!(env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW));
65
--
66
2.25.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Feng Jiang <jiangfeng@kylinos.cn>
2
2
3
Do not apply memattr or shareability for Stage2 translations.
3
One of the debug printfs in exynos4210_gcomp_find() will
4
Make sure to apply HCR_{DC,DCT} only to Regime_EL10, per the
4
access outside the 's->g_timer.reg.comp[]' array if there
5
pseudocode in AArch64.S1DisabledOutput.
5
was no active comparator and 'res' is -1. Add a conditional
6
to avoid this.
6
7
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
This doesn't happen in normal use because the debug printfs
9
are by default not compiled in.
10
11
Signed-off-by: Feng Jiang <jiangfeng@kylinos.cn>
12
Message-id: 20230404074506.112615-1-jiangfeng@kylinos.cn
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20221001162318.153420-20-richard.henderson@linaro.org
14
[PMM: Adjusted commit message to clarify that the overrun
15
only happens if you've enabled debug printfs]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
17
---
12
target/arm/ptw.c | 48 +++++++++++++++++++++++++-----------------------
18
hw/timer/exynos4210_mct.c | 13 ++++++++-----
13
1 file changed, 25 insertions(+), 23 deletions(-)
19
1 file changed, 8 insertions(+), 5 deletions(-)
14
20
15
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
21
diff --git a/hw/timer/exynos4210_mct.c b/hw/timer/exynos4210_mct.c
16
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/ptw.c
23
--- a/hw/timer/exynos4210_mct.c
18
+++ b/target/arm/ptw.c
24
+++ b/hw/timer/exynos4210_mct.c
19
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
25
@@ -XXX,XX +XXX,XX @@ static int32_t exynos4210_gcomp_find(Exynos4210MCTState *s)
20
GetPhysAddrResult *result,
26
res = min_comp_i;
21
ARMMMUFaultInfo *fi)
22
{
23
- uint64_t hcr;
24
- uint8_t memattr;
25
+ uint8_t memattr = 0x00; /* Device nGnRnE */
26
+ uint8_t shareability = 0; /* non-sharable */
27
28
if (mmu_idx != ARMMMUIdx_Stage2 && mmu_idx != ARMMMUIdx_Stage2_S) {
29
int r_el = regime_el(env, mmu_idx);
30
+
31
if (arm_el_is_aa64(env, r_el)) {
32
int pamax = arm_pamax(env_archcpu(env));
33
uint64_t tcr = env->cp15.tcr_el[r_el];
34
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
35
*/
36
address = extract64(address, 0, 52);
37
}
38
+
39
+ /* Fill in cacheattr a-la AArch64.TranslateAddressS1Off. */
40
+ if (r_el == 1) {
41
+ uint64_t hcr = arm_hcr_el2_eff_secstate(env, is_secure);
42
+ if (hcr & HCR_DC) {
43
+ if (hcr & HCR_DCT) {
44
+ memattr = 0xf0; /* Tagged, Normal, WB, RWA */
45
+ } else {
46
+ memattr = 0xff; /* Normal, WB, RWA */
47
+ }
48
+ }
49
+ }
50
+ if (memattr == 0 && access_type == MMU_INST_FETCH) {
51
+ if (regime_sctlr(env, mmu_idx) & SCTLR_I) {
52
+ memattr = 0xee; /* Normal, WT, RA, NT */
53
+ } else {
54
+ memattr = 0x44; /* Normal, NC, No */
55
+ }
56
+ shareability = 2; /* outer sharable */
57
+ }
58
+ result->cacheattrs.is_s2_format = false;
59
}
27
}
60
28
61
result->phys = address;
29
- DPRINTF("found comparator %d: comp 0x%llx distance 0x%llx, gfrc 0x%llx\n",
62
result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
30
- res,
63
result->page_size = TARGET_PAGE_SIZE;
31
- s->g_timer.reg.comp[res],
64
-
32
- distance_min,
65
- /* Fill in cacheattr a-la AArch64.TranslateAddressS1Off. */
33
- gfrc);
66
- hcr = arm_hcr_el2_eff_secstate(env, is_secure);
34
+ if (res >= 0) {
67
- result->cacheattrs.shareability = 0;
35
+ DPRINTF("found comparator %d: "
68
- result->cacheattrs.is_s2_format = false;
36
+ "comp 0x%llx distance 0x%llx, gfrc 0x%llx\n",
69
- if (hcr & HCR_DC) {
37
+ res,
70
- if (hcr & HCR_DCT) {
38
+ s->g_timer.reg.comp[res],
71
- memattr = 0xf0; /* Tagged, Normal, WB, RWA */
39
+ distance_min,
72
- } else {
40
+ gfrc);
73
- memattr = 0xff; /* Normal, WB, RWA */
41
+ }
74
- }
42
75
- } else if (access_type == MMU_INST_FETCH) {
43
return res;
76
- if (regime_sctlr(env, mmu_idx) & SCTLR_I) {
77
- memattr = 0xee; /* Normal, WT, RA, NT */
78
- } else {
79
- memattr = 0x44; /* Normal, NC, No */
80
- }
81
- result->cacheattrs.shareability = 2; /* outer sharable */
82
- } else {
83
- memattr = 0x00; /* Device, nGnRnE */
84
- }
85
+ result->cacheattrs.shareability = shareability;
86
result->cacheattrs.attrs = memattr;
87
return 0;
88
}
44
}
89
--
45
--
90
2.25.1
46
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Strahinja Jankovic <strahinjapjankovic@gmail.com>
2
2
3
This is the last use of regime_is_secure; remove it
3
This patch adds basic support for Allwinner WDT.
4
entirely before changing the layout of ARMMMUIdx.
4
Both sun4i and sun6i variants are supported.
5
However, interrupt generation is not supported, so WDT can be used only to trigger system reset.
5
6
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
8
Message-id: 20221001162318.153420-9-richard.henderson@linaro.org
9
Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com>
10
Message-id: 20230326202256.22980-2-strahinja.p.jankovic@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
target/arm/internals.h | 42 ----------------------------------------
13
include/hw/watchdog/allwinner-wdt.h | 123 ++++++++
12
target/arm/ptw.c | 44 ++++++++++++++++++++++++++++++++++++++++--
14
hw/watchdog/allwinner-wdt.c | 416 ++++++++++++++++++++++++++++
13
2 files changed, 42 insertions(+), 44 deletions(-)
15
hw/watchdog/Kconfig | 4 +
16
hw/watchdog/meson.build | 1 +
17
hw/watchdog/trace-events | 7 +
18
5 files changed, 551 insertions(+)
19
create mode 100644 include/hw/watchdog/allwinner-wdt.h
20
create mode 100644 hw/watchdog/allwinner-wdt.c
14
21
15
diff --git a/target/arm/internals.h b/target/arm/internals.h
22
diff --git a/include/hw/watchdog/allwinner-wdt.h b/include/hw/watchdog/allwinner-wdt.h
16
index XXXXXXX..XXXXXXX 100644
23
new file mode 100644
17
--- a/target/arm/internals.h
24
index XXXXXXX..XXXXXXX
18
+++ b/target/arm/internals.h
25
--- /dev/null
19
@@ -XXX,XX +XXX,XX @@ static inline bool regime_has_2_ranges(ARMMMUIdx mmu_idx)
26
+++ b/include/hw/watchdog/allwinner-wdt.h
20
}
27
@@ -XXX,XX +XXX,XX @@
21
}
28
+/*
22
29
+ * Allwinner Watchdog emulation
23
-/* Return true if this address translation regime is secure */
30
+ *
24
-static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
31
+ * Copyright (C) 2023 Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
25
-{
32
+ *
26
- switch (mmu_idx) {
33
+ * This file is derived from Allwinner RTC,
27
- case ARMMMUIdx_E10_0:
34
+ * by Niek Linnenbank.
28
- case ARMMMUIdx_E10_1:
35
+ *
29
- case ARMMMUIdx_E10_1_PAN:
36
+ * This program is free software: you can redistribute it and/or modify
30
- case ARMMMUIdx_E20_0:
37
+ * it under the terms of the GNU General Public License as published by
31
- case ARMMMUIdx_E20_2:
38
+ * the Free Software Foundation, either version 2 of the License, or
32
- case ARMMMUIdx_E20_2_PAN:
39
+ * (at your option) any later version.
33
- case ARMMMUIdx_Stage1_E0:
40
+ *
34
- case ARMMMUIdx_Stage1_E1:
41
+ * This program is distributed in the hope that it will be useful,
35
- case ARMMMUIdx_Stage1_E1_PAN:
42
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
36
- case ARMMMUIdx_E2:
43
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37
- case ARMMMUIdx_Stage2:
44
+ * GNU General Public License for more details.
38
- case ARMMMUIdx_MPrivNegPri:
45
+ *
39
- case ARMMMUIdx_MUserNegPri:
46
+ * You should have received a copy of the GNU General Public License
40
- case ARMMMUIdx_MPriv:
47
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
41
- case ARMMMUIdx_MUser:
48
+ */
42
- return false;
49
+
43
- case ARMMMUIdx_SE3:
50
+#ifndef HW_WATCHDOG_ALLWINNER_WDT_H
44
- case ARMMMUIdx_SE10_0:
51
+#define HW_WATCHDOG_ALLWINNER_WDT_H
45
- case ARMMMUIdx_SE10_1:
52
+
46
- case ARMMMUIdx_SE10_1_PAN:
53
+#include "qom/object.h"
47
- case ARMMMUIdx_SE20_0:
54
+#include "hw/ptimer.h"
48
- case ARMMMUIdx_SE20_2:
55
+#include "hw/sysbus.h"
49
- case ARMMMUIdx_SE20_2_PAN:
56
+
50
- case ARMMMUIdx_Stage1_SE0:
57
+/*
51
- case ARMMMUIdx_Stage1_SE1:
58
+ * This is a model of the Allwinner watchdog.
52
- case ARMMMUIdx_Stage1_SE1_PAN:
59
+ * Since watchdog registers belong to the timer module (and are shared with the
53
- case ARMMMUIdx_SE2:
60
+ * RTC module), the interrupt line from watchdog is not handled right now.
54
- case ARMMMUIdx_Stage2_S:
61
+ * In QEMU, we just wire up the watchdog reset to watchdog_perform_action(),
55
- case ARMMMUIdx_MSPrivNegPri:
62
+ * at least for the moment.
56
- case ARMMMUIdx_MSUserNegPri:
63
+ */
57
- case ARMMMUIdx_MSPriv:
64
+
58
- case ARMMMUIdx_MSUser:
65
+#define TYPE_AW_WDT "allwinner-wdt"
59
- return true;
66
+
60
- default:
67
+/** Allwinner WDT sun4i family (A10, A12), also sun7i (A20) */
61
- g_assert_not_reached();
68
+#define TYPE_AW_WDT_SUN4I TYPE_AW_WDT "-sun4i"
62
- }
69
+
63
-}
70
+/** Allwinner WDT sun6i family and newer (A31, H2+, H3, etc) */
64
-
71
+#define TYPE_AW_WDT_SUN6I TYPE_AW_WDT "-sun6i"
65
static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx)
72
+
66
{
73
+/** Number of WDT registers */
67
switch (mmu_idx) {
74
+#define AW_WDT_REGS_NUM (5)
68
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
75
+
69
index XXXXXXX..XXXXXXX 100644
76
+OBJECT_DECLARE_TYPE(AwWdtState, AwWdtClass, AW_WDT)
70
--- a/target/arm/ptw.c
77
+
71
+++ b/target/arm/ptw.c
78
+/**
72
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
79
+ * Allwinner WDT object instance state.
73
MMUAccessType access_type, ARMMMUIdx mmu_idx,
80
+ */
74
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
81
+struct AwWdtState {
75
{
82
+ /*< private >*/
76
+ bool is_secure;
83
+ SysBusDevice parent_obj;
77
+
84
+
78
+ switch (mmu_idx) {
85
+ /*< public >*/
79
+ case ARMMMUIdx_E10_0:
86
+ MemoryRegion iomem;
80
+ case ARMMMUIdx_E10_1:
87
+ struct ptimer_state *timer;
81
+ case ARMMMUIdx_E10_1_PAN:
88
+
82
+ case ARMMMUIdx_E20_0:
89
+ uint32_t regs[AW_WDT_REGS_NUM];
83
+ case ARMMMUIdx_E20_2:
90
+};
84
+ case ARMMMUIdx_E20_2_PAN:
91
+
85
+ case ARMMMUIdx_Stage1_E0:
92
+/**
86
+ case ARMMMUIdx_Stage1_E1:
93
+ * Allwinner WDT class-level struct.
87
+ case ARMMMUIdx_Stage1_E1_PAN:
94
+ *
88
+ case ARMMMUIdx_E2:
95
+ * This struct is filled by each sunxi device specific code
89
+ case ARMMMUIdx_Stage2:
96
+ * such that the generic code can use this struct to support
90
+ case ARMMMUIdx_MPrivNegPri:
97
+ * all devices.
91
+ case ARMMMUIdx_MUserNegPri:
98
+ */
92
+ case ARMMMUIdx_MPriv:
99
+struct AwWdtClass {
93
+ case ARMMMUIdx_MUser:
100
+ /*< private >*/
94
+ is_secure = false;
101
+ SysBusDeviceClass parent_class;
102
+ /*< public >*/
103
+
104
+ /** Defines device specific register map */
105
+ const uint8_t *regmap;
106
+
107
+ /** Size of the regmap in bytes */
108
+ size_t regmap_size;
109
+
110
+ /**
111
+ * Read device specific register
112
+ *
113
+ * @offset: register offset to read
114
+ * @return true if register read successful, false otherwise
115
+ */
116
+ bool (*read)(AwWdtState *s, uint32_t offset);
117
+
118
+ /**
119
+ * Write device specific register
120
+ *
121
+ * @offset: register offset to write
122
+ * @data: value to set in register
123
+ * @return true if register write successful, false otherwise
124
+ */
125
+ bool (*write)(AwWdtState *s, uint32_t offset, uint32_t data);
126
+
127
+ /**
128
+ * Check if watchdog can generate system reset
129
+ *
130
+ * @return true if watchdog can generate system reset
131
+ */
132
+ bool (*can_reset_system)(AwWdtState *s);
133
+
134
+ /**
135
+ * Check if provided key is valid
136
+ *
137
+ * @value: value written to register
138
+ * @return true if key is valid, false otherwise
139
+ */
140
+ bool (*is_key_valid)(AwWdtState *s, uint32_t val);
141
+
142
+ /**
143
+ * Get current INTV_VALUE setting
144
+ *
145
+ * @return current INTV_VALUE (0-15)
146
+ */
147
+ uint8_t (*get_intv_value)(AwWdtState *s);
148
+};
149
+
150
+#endif /* HW_WATCHDOG_ALLWINNER_WDT_H */
151
diff --git a/hw/watchdog/allwinner-wdt.c b/hw/watchdog/allwinner-wdt.c
152
new file mode 100644
153
index XXXXXXX..XXXXXXX
154
--- /dev/null
155
+++ b/hw/watchdog/allwinner-wdt.c
156
@@ -XXX,XX +XXX,XX @@
157
+/*
158
+ * Allwinner Watchdog emulation
159
+ *
160
+ * Copyright (C) 2023 Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
161
+ *
162
+ * This file is derived from Allwinner RTC,
163
+ * by Niek Linnenbank.
164
+ *
165
+ * This program is free software: you can redistribute it and/or modify
166
+ * it under the terms of the GNU General Public License as published by
167
+ * the Free Software Foundation, either version 2 of the License, or
168
+ * (at your option) any later version.
169
+ *
170
+ * This program is distributed in the hope that it will be useful,
171
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
172
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
173
+ * GNU General Public License for more details.
174
+ *
175
+ * You should have received a copy of the GNU General Public License
176
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
177
+ */
178
+
179
+#include "qemu/osdep.h"
180
+#include "qemu/log.h"
181
+#include "qemu/units.h"
182
+#include "qemu/module.h"
183
+#include "trace.h"
184
+#include "hw/sysbus.h"
185
+#include "hw/registerfields.h"
186
+#include "hw/watchdog/allwinner-wdt.h"
187
+#include "sysemu/watchdog.h"
188
+#include "migration/vmstate.h"
189
+
190
+/* WDT registers */
191
+enum {
192
+ REG_IRQ_EN = 0, /* Watchdog interrupt enable */
193
+ REG_IRQ_STA, /* Watchdog interrupt status */
194
+ REG_CTRL, /* Watchdog control register */
195
+ REG_CFG, /* Watchdog configuration register */
196
+ REG_MODE, /* Watchdog mode register */
197
+};
198
+
199
+/* Universal WDT register flags */
200
+#define WDT_RESTART_MASK (1 << 0)
201
+#define WDT_EN_MASK (1 << 0)
202
+
203
+/* sun4i specific WDT register flags */
204
+#define RST_EN_SUN4I_MASK (1 << 1)
205
+#define INTV_VALUE_SUN4I_SHIFT (3)
206
+#define INTV_VALUE_SUN4I_MASK (0xfu << INTV_VALUE_SUN4I_SHIFT)
207
+
208
+/* sun6i specific WDT register flags */
209
+#define RST_EN_SUN6I_MASK (1 << 0)
210
+#define KEY_FIELD_SUN6I_SHIFT (1)
211
+#define KEY_FIELD_SUN6I_MASK (0xfffu << KEY_FIELD_SUN6I_SHIFT)
212
+#define KEY_FIELD_SUN6I (0xA57u)
213
+#define INTV_VALUE_SUN6I_SHIFT (4)
214
+#define INTV_VALUE_SUN6I_MASK (0xfu << INTV_VALUE_SUN6I_SHIFT)
215
+
216
+/* Map of INTV_VALUE to 0.5s units. */
217
+static const uint8_t allwinner_wdt_count_map[] = {
218
+ 1,
219
+ 2,
220
+ 4,
221
+ 6,
222
+ 8,
223
+ 10,
224
+ 12,
225
+ 16,
226
+ 20,
227
+ 24,
228
+ 28,
229
+ 32
230
+};
231
+
232
+/* WDT sun4i register map (offset to name) */
233
+const uint8_t allwinner_wdt_sun4i_regmap[] = {
234
+ [0x0000] = REG_CTRL,
235
+ [0x0004] = REG_MODE,
236
+};
237
+
238
+/* WDT sun6i register map (offset to name) */
239
+const uint8_t allwinner_wdt_sun6i_regmap[] = {
240
+ [0x0000] = REG_IRQ_EN,
241
+ [0x0004] = REG_IRQ_STA,
242
+ [0x0010] = REG_CTRL,
243
+ [0x0014] = REG_CFG,
244
+ [0x0018] = REG_MODE,
245
+};
246
+
247
+static bool allwinner_wdt_sun4i_read(AwWdtState *s, uint32_t offset)
248
+{
249
+ /* no sun4i specific registers currently implemented */
250
+ return false;
251
+}
252
+
253
+static bool allwinner_wdt_sun4i_write(AwWdtState *s, uint32_t offset,
254
+ uint32_t data)
255
+{
256
+ /* no sun4i specific registers currently implemented */
257
+ return false;
258
+}
259
+
260
+static bool allwinner_wdt_sun4i_can_reset_system(AwWdtState *s)
261
+{
262
+ if (s->regs[REG_MODE] & RST_EN_SUN4I_MASK) {
263
+ return true;
264
+ } else {
265
+ return false;
266
+ }
267
+}
268
+
269
+static bool allwinner_wdt_sun4i_is_key_valid(AwWdtState *s, uint32_t val)
270
+{
271
+ /* sun4i has no key */
272
+ return true;
273
+}
274
+
275
+static uint8_t allwinner_wdt_sun4i_get_intv_value(AwWdtState *s)
276
+{
277
+ return ((s->regs[REG_MODE] & INTV_VALUE_SUN4I_MASK) >>
278
+ INTV_VALUE_SUN4I_SHIFT);
279
+}
280
+
281
+static bool allwinner_wdt_sun6i_read(AwWdtState *s, uint32_t offset)
282
+{
283
+ const AwWdtClass *c = AW_WDT_GET_CLASS(s);
284
+
285
+ switch (c->regmap[offset]) {
286
+ case REG_IRQ_EN:
287
+ case REG_IRQ_STA:
288
+ case REG_CFG:
289
+ return true;
290
+ default:
95
+ break;
291
+ break;
96
+ case ARMMMUIdx_SE3:
292
+ }
97
+ case ARMMMUIdx_SE10_0:
293
+ return false;
98
+ case ARMMMUIdx_SE10_1:
294
+}
99
+ case ARMMMUIdx_SE10_1_PAN:
295
+
100
+ case ARMMMUIdx_SE20_0:
296
+static bool allwinner_wdt_sun6i_write(AwWdtState *s, uint32_t offset,
101
+ case ARMMMUIdx_SE20_2:
297
+ uint32_t data)
102
+ case ARMMMUIdx_SE20_2_PAN:
298
+{
103
+ case ARMMMUIdx_Stage1_SE0:
299
+ const AwWdtClass *c = AW_WDT_GET_CLASS(s);
104
+ case ARMMMUIdx_Stage1_SE1:
300
+
105
+ case ARMMMUIdx_Stage1_SE1_PAN:
301
+ switch (c->regmap[offset]) {
106
+ case ARMMMUIdx_SE2:
302
+ case REG_IRQ_EN:
107
+ case ARMMMUIdx_Stage2_S:
303
+ case REG_IRQ_STA:
108
+ case ARMMMUIdx_MSPrivNegPri:
304
+ case REG_CFG:
109
+ case ARMMMUIdx_MSUserNegPri:
305
+ return true;
110
+ case ARMMMUIdx_MSPriv:
306
+ default:
111
+ case ARMMMUIdx_MSUser:
307
+ break;
112
+ is_secure = true;
308
+ }
309
+ return false;
310
+}
311
+
312
+static bool allwinner_wdt_sun6i_can_reset_system(AwWdtState *s)
313
+{
314
+ if (s->regs[REG_CFG] & RST_EN_SUN6I_MASK) {
315
+ return true;
316
+ } else {
317
+ return false;
318
+ }
319
+}
320
+
321
+static bool allwinner_wdt_sun6i_is_key_valid(AwWdtState *s, uint32_t val)
322
+{
323
+ uint16_t key = (val & KEY_FIELD_SUN6I_MASK) >> KEY_FIELD_SUN6I_SHIFT;
324
+ return (key == KEY_FIELD_SUN6I);
325
+}
326
+
327
+static uint8_t allwinner_wdt_sun6i_get_intv_value(AwWdtState *s)
328
+{
329
+ return ((s->regs[REG_MODE] & INTV_VALUE_SUN6I_MASK) >>
330
+ INTV_VALUE_SUN6I_SHIFT);
331
+}
332
+
333
+static void allwinner_wdt_update_timer(AwWdtState *s)
334
+{
335
+ const AwWdtClass *c = AW_WDT_GET_CLASS(s);
336
+ uint8_t count = c->get_intv_value(s);
337
+
338
+ ptimer_transaction_begin(s->timer);
339
+ ptimer_stop(s->timer);
340
+
341
+ /* Use map to convert. */
342
+ if (count < sizeof(allwinner_wdt_count_map)) {
343
+ ptimer_set_count(s->timer, allwinner_wdt_count_map[count]);
344
+ } else {
345
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: incorrect INTV_VALUE 0x%02x\n",
346
+ __func__, count);
347
+ }
348
+
349
+ ptimer_run(s->timer, 1);
350
+ ptimer_transaction_commit(s->timer);
351
+
352
+ trace_allwinner_wdt_update_timer(count);
353
+}
354
+
355
+static uint64_t allwinner_wdt_read(void *opaque, hwaddr offset,
356
+ unsigned size)
357
+{
358
+ AwWdtState *s = AW_WDT(opaque);
359
+ const AwWdtClass *c = AW_WDT_GET_CLASS(s);
360
+ uint64_t r;
361
+
362
+ if (offset >= c->regmap_size) {
363
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
364
+ __func__, (uint32_t)offset);
365
+ return 0;
366
+ }
367
+
368
+ switch (c->regmap[offset]) {
369
+ case REG_CTRL:
370
+ case REG_MODE:
371
+ r = s->regs[c->regmap[offset]];
113
+ break;
372
+ break;
114
+ default:
373
+ default:
115
+ g_assert_not_reached();
374
+ if (!c->read(s, offset)) {
116
+ }
375
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented register 0x%04x\n",
117
return get_phys_addr_with_secure(env, address, access_type, mmu_idx,
376
+ __func__, (uint32_t)offset);
118
- regime_is_secure(env, mmu_idx),
377
+ return 0;
119
- result, fi);
378
+ }
120
+ is_secure, result, fi);
379
+ r = s->regs[c->regmap[offset]];
121
}
380
+ break;
122
381
+ }
123
hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
382
+
383
+ trace_allwinner_wdt_read(offset, r, size);
384
+
385
+ return r;
386
+}
387
+
388
+static void allwinner_wdt_write(void *opaque, hwaddr offset,
389
+ uint64_t val, unsigned size)
390
+{
391
+ AwWdtState *s = AW_WDT(opaque);
392
+ const AwWdtClass *c = AW_WDT_GET_CLASS(s);
393
+ uint32_t old_val;
394
+
395
+ if (offset >= c->regmap_size) {
396
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
397
+ __func__, (uint32_t)offset);
398
+ return;
399
+ }
400
+
401
+ trace_allwinner_wdt_write(offset, val, size);
402
+
403
+ switch (c->regmap[offset]) {
404
+ case REG_CTRL:
405
+ if (c->is_key_valid(s, val)) {
406
+ if (val & WDT_RESTART_MASK) {
407
+ /* Kick timer */
408
+ allwinner_wdt_update_timer(s);
409
+ }
410
+ }
411
+ break;
412
+ case REG_MODE:
413
+ old_val = s->regs[REG_MODE];
414
+ s->regs[REG_MODE] = (uint32_t)val;
415
+
416
+ /* Check for rising edge on WDOG_MODE_EN */
417
+ if ((s->regs[REG_MODE] & ~old_val) & WDT_EN_MASK) {
418
+ allwinner_wdt_update_timer(s);
419
+ }
420
+ break;
421
+ default:
422
+ if (!c->write(s, offset, val)) {
423
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented register 0x%04x\n",
424
+ __func__, (uint32_t)offset);
425
+ }
426
+ s->regs[c->regmap[offset]] = (uint32_t)val;
427
+ break;
428
+ }
429
+}
430
+
431
+static const MemoryRegionOps allwinner_wdt_ops = {
432
+ .read = allwinner_wdt_read,
433
+ .write = allwinner_wdt_write,
434
+ .endianness = DEVICE_NATIVE_ENDIAN,
435
+ .valid = {
436
+ .min_access_size = 4,
437
+ .max_access_size = 4,
438
+ },
439
+ .impl.min_access_size = 4,
440
+};
441
+
442
+static void allwinner_wdt_expired(void *opaque)
443
+{
444
+ AwWdtState *s = AW_WDT(opaque);
445
+ const AwWdtClass *c = AW_WDT_GET_CLASS(s);
446
+
447
+ bool enabled = s->regs[REG_MODE] & WDT_EN_MASK;
448
+ bool reset_enabled = c->can_reset_system(s);
449
+
450
+ trace_allwinner_wdt_expired(enabled, reset_enabled);
451
+
452
+ /* Perform watchdog action if watchdog is enabled and can trigger reset */
453
+ if (enabled && reset_enabled) {
454
+ watchdog_perform_action();
455
+ }
456
+}
457
+
458
+static void allwinner_wdt_reset_enter(Object *obj, ResetType type)
459
+{
460
+ AwWdtState *s = AW_WDT(obj);
461
+
462
+ trace_allwinner_wdt_reset_enter();
463
+
464
+ /* Clear registers */
465
+ memset(s->regs, 0, sizeof(s->regs));
466
+}
467
+
468
+static const VMStateDescription allwinner_wdt_vmstate = {
469
+ .name = "allwinner-wdt",
470
+ .version_id = 1,
471
+ .minimum_version_id = 1,
472
+ .fields = (VMStateField[]) {
473
+ VMSTATE_PTIMER(timer, AwWdtState),
474
+ VMSTATE_UINT32_ARRAY(regs, AwWdtState, AW_WDT_REGS_NUM),
475
+ VMSTATE_END_OF_LIST()
476
+ }
477
+};
478
+
479
+static void allwinner_wdt_init(Object *obj)
480
+{
481
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
482
+ AwWdtState *s = AW_WDT(obj);
483
+ const AwWdtClass *c = AW_WDT_GET_CLASS(s);
484
+
485
+ /* Memory mapping */
486
+ memory_region_init_io(&s->iomem, OBJECT(s), &allwinner_wdt_ops, s,
487
+ TYPE_AW_WDT, c->regmap_size * 4);
488
+ sysbus_init_mmio(sbd, &s->iomem);
489
+}
490
+
491
+static void allwinner_wdt_realize(DeviceState *dev, Error **errp)
492
+{
493
+ AwWdtState *s = AW_WDT(dev);
494
+
495
+ s->timer = ptimer_init(allwinner_wdt_expired, s,
496
+ PTIMER_POLICY_NO_IMMEDIATE_TRIGGER |
497
+ PTIMER_POLICY_NO_IMMEDIATE_RELOAD |
498
+ PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
499
+
500
+ ptimer_transaction_begin(s->timer);
501
+ /* Set to 2Hz (0.5s period); other periods are multiples of 0.5s. */
502
+ ptimer_set_freq(s->timer, 2);
503
+ ptimer_set_limit(s->timer, 0xff, 1);
504
+ ptimer_transaction_commit(s->timer);
505
+}
506
+
507
+static void allwinner_wdt_class_init(ObjectClass *klass, void *data)
508
+{
509
+ DeviceClass *dc = DEVICE_CLASS(klass);
510
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
511
+
512
+ rc->phases.enter = allwinner_wdt_reset_enter;
513
+ dc->realize = allwinner_wdt_realize;
514
+ dc->vmsd = &allwinner_wdt_vmstate;
515
+}
516
+
517
+static void allwinner_wdt_sun4i_class_init(ObjectClass *klass, void *data)
518
+{
519
+ AwWdtClass *awc = AW_WDT_CLASS(klass);
520
+
521
+ awc->regmap = allwinner_wdt_sun4i_regmap;
522
+ awc->regmap_size = sizeof(allwinner_wdt_sun4i_regmap);
523
+ awc->read = allwinner_wdt_sun4i_read;
524
+ awc->write = allwinner_wdt_sun4i_write;
525
+ awc->can_reset_system = allwinner_wdt_sun4i_can_reset_system;
526
+ awc->is_key_valid = allwinner_wdt_sun4i_is_key_valid;
527
+ awc->get_intv_value = allwinner_wdt_sun4i_get_intv_value;
528
+}
529
+
530
+static void allwinner_wdt_sun6i_class_init(ObjectClass *klass, void *data)
531
+{
532
+ AwWdtClass *awc = AW_WDT_CLASS(klass);
533
+
534
+ awc->regmap = allwinner_wdt_sun6i_regmap;
535
+ awc->regmap_size = sizeof(allwinner_wdt_sun6i_regmap);
536
+ awc->read = allwinner_wdt_sun6i_read;
537
+ awc->write = allwinner_wdt_sun6i_write;
538
+ awc->can_reset_system = allwinner_wdt_sun6i_can_reset_system;
539
+ awc->is_key_valid = allwinner_wdt_sun6i_is_key_valid;
540
+ awc->get_intv_value = allwinner_wdt_sun6i_get_intv_value;
541
+}
542
+
543
+static const TypeInfo allwinner_wdt_info = {
544
+ .name = TYPE_AW_WDT,
545
+ .parent = TYPE_SYS_BUS_DEVICE,
546
+ .instance_init = allwinner_wdt_init,
547
+ .instance_size = sizeof(AwWdtState),
548
+ .class_init = allwinner_wdt_class_init,
549
+ .class_size = sizeof(AwWdtClass),
550
+ .abstract = true,
551
+};
552
+
553
+static const TypeInfo allwinner_wdt_sun4i_info = {
554
+ .name = TYPE_AW_WDT_SUN4I,
555
+ .parent = TYPE_AW_WDT,
556
+ .class_init = allwinner_wdt_sun4i_class_init,
557
+};
558
+
559
+static const TypeInfo allwinner_wdt_sun6i_info = {
560
+ .name = TYPE_AW_WDT_SUN6I,
561
+ .parent = TYPE_AW_WDT,
562
+ .class_init = allwinner_wdt_sun6i_class_init,
563
+};
564
+
565
+static void allwinner_wdt_register(void)
566
+{
567
+ type_register_static(&allwinner_wdt_info);
568
+ type_register_static(&allwinner_wdt_sun4i_info);
569
+ type_register_static(&allwinner_wdt_sun6i_info);
570
+}
571
+
572
+type_init(allwinner_wdt_register)
573
diff --git a/hw/watchdog/Kconfig b/hw/watchdog/Kconfig
574
index XXXXXXX..XXXXXXX 100644
575
--- a/hw/watchdog/Kconfig
576
+++ b/hw/watchdog/Kconfig
577
@@ -XXX,XX +XXX,XX @@ config WDT_IMX2
578
579
config WDT_SBSA
580
bool
581
+
582
+config ALLWINNER_WDT
583
+ bool
584
+ select PTIMER
585
diff --git a/hw/watchdog/meson.build b/hw/watchdog/meson.build
586
index XXXXXXX..XXXXXXX 100644
587
--- a/hw/watchdog/meson.build
588
+++ b/hw/watchdog/meson.build
589
@@ -XXX,XX +XXX,XX @@
590
softmmu_ss.add(files('watchdog.c'))
591
+softmmu_ss.add(when: 'CONFIG_ALLWINNER_WDT', if_true: files('allwinner-wdt.c'))
592
softmmu_ss.add(when: 'CONFIG_CMSDK_APB_WATCHDOG', if_true: files('cmsdk-apb-watchdog.c'))
593
softmmu_ss.add(when: 'CONFIG_WDT_IB6300ESB', if_true: files('wdt_i6300esb.c'))
594
softmmu_ss.add(when: 'CONFIG_WDT_IB700', if_true: files('wdt_ib700.c'))
595
diff --git a/hw/watchdog/trace-events b/hw/watchdog/trace-events
596
index XXXXXXX..XXXXXXX 100644
597
--- a/hw/watchdog/trace-events
598
+++ b/hw/watchdog/trace-events
599
@@ -XXX,XX +XXX,XX @@
600
# See docs/devel/tracing.rst for syntax documentation.
601
602
+# allwinner-wdt.c
603
+allwinner_wdt_read(uint64_t offset, uint64_t data, unsigned size) "Allwinner watchdog read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
604
+allwinner_wdt_write(uint64_t offset, uint64_t data, unsigned size) "Allwinner watchdog write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
605
+allwinner_wdt_reset_enter(void) "Allwinner watchdog: reset"
606
+allwinner_wdt_update_timer(uint8_t count) "Allwinner watchdog: count %" PRIu8
607
+allwinner_wdt_expired(bool enabled, bool reset_enabled) "Allwinner watchdog: enabled %u reset_enabled %u"
608
+
609
# cmsdk-apb-watchdog.c
610
cmsdk_apb_watchdog_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
611
cmsdk_apb_watchdog_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
124
--
612
--
125
2.25.1
613
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Strahinja Jankovic <strahinjapjankovic@gmail.com>
2
2
3
For page walking, we may require HCR for a security state
3
This patch adds WDT to Allwinner-A10 and Cubieboard.
4
that is not "current".
4
WDT is added as an overlay to the Timer module memory map.
5
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
8
Message-id: 20221001162318.153420-14-richard.henderson@linaro.org
8
Message-id: 20230326202256.22980-3-strahinja.p.jankovic@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
target/arm/cpu.h | 20 +++++++++++++-------
11
docs/system/arm/cubieboard.rst | 1 +
12
target/arm/helper.c | 11 ++++++++---
12
include/hw/arm/allwinner-a10.h | 2 ++
13
2 files changed, 21 insertions(+), 10 deletions(-)
13
hw/arm/allwinner-a10.c | 7 +++++++
14
hw/arm/Kconfig | 1 +
15
4 files changed, 11 insertions(+)
14
16
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/docs/system/arm/cubieboard.rst b/docs/system/arm/cubieboard.rst
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
19
--- a/docs/system/arm/cubieboard.rst
18
+++ b/target/arm/cpu.h
20
+++ b/docs/system/arm/cubieboard.rst
19
@@ -XXX,XX +XXX,XX @@ static inline bool arm_is_secure(CPUARMState *env)
21
@@ -XXX,XX +XXX,XX @@ Emulated devices:
20
* Return true if the current security state has AArch64 EL2 or AArch32 Hyp.
22
- USB controller
21
* This corresponds to the pseudocode EL2Enabled()
23
- SATA controller
22
*/
24
- TWI (I2C) controller
23
+static inline bool arm_is_el2_enabled_secstate(CPUARMState *env, bool secure)
25
+- Watchdog timer
24
+{
26
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
25
+ return arm_feature(env, ARM_FEATURE_EL2)
27
index XXXXXXX..XXXXXXX 100644
26
+ && (!secure || (env->cp15.scr_el3 & SCR_EEL2));
28
--- a/include/hw/arm/allwinner-a10.h
27
+}
29
+++ b/include/hw/arm/allwinner-a10.h
30
@@ -XXX,XX +XXX,XX @@
31
#include "hw/misc/allwinner-a10-ccm.h"
32
#include "hw/misc/allwinner-a10-dramc.h"
33
#include "hw/i2c/allwinner-i2c.h"
34
+#include "hw/watchdog/allwinner-wdt.h"
35
#include "sysemu/block-backend.h"
36
37
#include "target/arm/cpu.h"
38
@@ -XXX,XX +XXX,XX @@ struct AwA10State {
39
AwSdHostState mmc0;
40
AWI2CState i2c0;
41
AwRtcState rtc;
42
+ AwWdtState wdt;
43
MemoryRegion sram_a;
44
EHCISysBusState ehci[AW_A10_NUM_USB];
45
OHCISysBusState ohci[AW_A10_NUM_USB];
46
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/allwinner-a10.c
49
+++ b/hw/arm/allwinner-a10.c
50
@@ -XXX,XX +XXX,XX @@
51
#define AW_A10_EHCI_BASE 0x01c14000
52
#define AW_A10_OHCI_BASE 0x01c14400
53
#define AW_A10_SATA_BASE 0x01c18000
54
+#define AW_A10_WDT_BASE 0x01c20c90
55
#define AW_A10_RTC_BASE 0x01c20d00
56
#define AW_A10_I2C0_BASE 0x01c2ac00
57
58
@@ -XXX,XX +XXX,XX @@ static void aw_a10_init(Object *obj)
59
object_initialize_child(obj, "mmc0", &s->mmc0, TYPE_AW_SDHOST_SUN4I);
60
61
object_initialize_child(obj, "rtc", &s->rtc, TYPE_AW_RTC_SUN4I);
28
+
62
+
29
static inline bool arm_is_el2_enabled(CPUARMState *env)
63
+ object_initialize_child(obj, "wdt", &s->wdt, TYPE_AW_WDT_SUN4I);
30
{
31
- if (arm_feature(env, ARM_FEATURE_EL2)) {
32
- if (arm_is_secure_below_el3(env)) {
33
- return (env->cp15.scr_el3 & SCR_EEL2) != 0;
34
- }
35
- return true;
36
- }
37
- return false;
38
+ return arm_is_el2_enabled_secstate(env, arm_is_secure_below_el3(env));
39
}
64
}
40
65
41
#else
66
static void aw_a10_realize(DeviceState *dev, Error **errp)
42
@@ -XXX,XX +XXX,XX @@ static inline bool arm_is_secure(CPUARMState *env)
67
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
43
return false;
68
sysbus_realize(SYS_BUS_DEVICE(&s->i2c0), &error_fatal);
69
sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c0), 0, AW_A10_I2C0_BASE);
70
sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c0), 0, qdev_get_gpio_in(dev, 7));
71
+
72
+ /* WDT */
73
+ sysbus_realize(SYS_BUS_DEVICE(&s->wdt), &error_fatal);
74
+ sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->wdt), 0, AW_A10_WDT_BASE, 1);
44
}
75
}
45
76
46
+static inline bool arm_is_el2_enabled_secstate(CPUARMState *env, bool secure)
77
static void aw_a10_class_init(ObjectClass *oc, void *data)
47
+{
78
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
48
+ return false;
49
+}
50
+
51
static inline bool arm_is_el2_enabled(CPUARMState *env)
52
{
53
return false;
54
@@ -XXX,XX +XXX,XX @@ static inline bool arm_is_el2_enabled(CPUARMState *env)
55
* "for all purposes other than a direct read or write access of HCR_EL2."
56
* Not included here is HCR_RW.
57
*/
58
+uint64_t arm_hcr_el2_eff_secstate(CPUARMState *env, bool secure);
59
uint64_t arm_hcr_el2_eff(CPUARMState *env);
60
uint64_t arm_hcrx_el2_eff(CPUARMState *env);
61
62
diff --git a/target/arm/helper.c b/target/arm/helper.c
63
index XXXXXXX..XXXXXXX 100644
79
index XXXXXXX..XXXXXXX 100644
64
--- a/target/arm/helper.c
80
--- a/hw/arm/Kconfig
65
+++ b/target/arm/helper.c
81
+++ b/hw/arm/Kconfig
66
@@ -XXX,XX +XXX,XX @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
82
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_A10
67
}
83
select ALLWINNER_A10_PIC
68
84
select ALLWINNER_A10_CCM
69
/*
85
select ALLWINNER_A10_DRAMC
70
- * Return the effective value of HCR_EL2.
86
+ select ALLWINNER_WDT
71
+ * Return the effective value of HCR_EL2, at the given security state.
87
select ALLWINNER_EMAC
72
* Bits that are not included here:
88
select ALLWINNER_I2C
73
* RW (read from SCR_EL3.RW as needed)
89
select AXP209_PMU
74
*/
75
-uint64_t arm_hcr_el2_eff(CPUARMState *env)
76
+uint64_t arm_hcr_el2_eff_secstate(CPUARMState *env, bool secure)
77
{
78
uint64_t ret = env->cp15.hcr_el2;
79
80
- if (!arm_is_el2_enabled(env)) {
81
+ if (!arm_is_el2_enabled_secstate(env, secure)) {
82
/*
83
* "This register has no effect if EL2 is not enabled in the
84
* current Security state". This is ARMv8.4-SecEL2 speak for
85
@@ -XXX,XX +XXX,XX @@ uint64_t arm_hcr_el2_eff(CPUARMState *env)
86
return ret;
87
}
88
89
+uint64_t arm_hcr_el2_eff(CPUARMState *env)
90
+{
91
+ return arm_hcr_el2_eff_secstate(env, arm_is_secure_below_el3(env));
92
+}
93
+
94
/*
95
* Corresponds to ARM pseudocode function ELIsInHost().
96
*/
97
--
90
--
98
2.25.1
91
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Strahinja Jankovic <strahinjapjankovic@gmail.com>
2
2
3
These subroutines did not need ENV for anything except
3
This patch adds WDT to Allwinner-H3 and Orangepi-PC.
4
retrieving the effective value of HCR anyway.
4
WDT is added as an overlay to the Timer module memory area.
5
5
6
We have computed the effective value of HCR in the callers,
6
Signed-off-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
7
and this will be especially important for interpreting HCR
7
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
8
in a non-current security state.
8
Message-id: 20230326202256.22980-4-strahinja.p.jankovic@gmail.com
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20221001162318.153420-17-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
10
---
15
target/arm/ptw.c | 30 +++++++++++++++++-------------
11
docs/system/arm/orangepi.rst | 1 +
16
1 file changed, 17 insertions(+), 13 deletions(-)
12
include/hw/arm/allwinner-h3.h | 5 ++++-
13
hw/arm/allwinner-h3.c | 8 ++++++++
14
hw/arm/Kconfig | 1 +
15
4 files changed, 14 insertions(+), 1 deletion(-)
17
16
18
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
17
diff --git a/docs/system/arm/orangepi.rst b/docs/system/arm/orangepi.rst
19
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/ptw.c
19
--- a/docs/system/arm/orangepi.rst
21
+++ b/target/arm/ptw.c
20
+++ b/docs/system/arm/orangepi.rst
22
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
21
@@ -XXX,XX +XXX,XX @@ The Orange Pi PC machine supports the following devices:
23
return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0;
22
* System Control module
23
* Security Identifier device
24
* TWI (I2C)
25
+ * Watchdog timer
26
27
Limitations
28
"""""""""""
29
diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/include/hw/arm/allwinner-h3.h
32
+++ b/include/hw/arm/allwinner-h3.h
33
@@ -XXX,XX +XXX,XX @@
34
#include "hw/net/allwinner-sun8i-emac.h"
35
#include "hw/rtc/allwinner-rtc.h"
36
#include "hw/i2c/allwinner-i2c.h"
37
+#include "hw/watchdog/allwinner-wdt.h"
38
#include "target/arm/cpu.h"
39
#include "sysemu/block-backend.h"
40
41
@@ -XXX,XX +XXX,XX @@ enum {
42
AW_H3_DEV_RTC,
43
AW_H3_DEV_CPUCFG,
44
AW_H3_DEV_R_TWI,
45
- AW_H3_DEV_SDRAM
46
+ AW_H3_DEV_SDRAM,
47
+ AW_H3_DEV_WDT
48
};
49
50
/** Total number of CPU cores in the H3 SoC */
51
@@ -XXX,XX +XXX,XX @@ struct AwH3State {
52
AWI2CState r_twi;
53
AwSun8iEmacState emac;
54
AwRtcState rtc;
55
+ AwWdtState wdt;
56
GICState gic;
57
MemoryRegion sram_a1;
58
MemoryRegion sram_a2;
59
diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/arm/allwinner-h3.c
62
+++ b/hw/arm/allwinner-h3.c
63
@@ -XXX,XX +XXX,XX @@ const hwaddr allwinner_h3_memmap[] = {
64
[AW_H3_DEV_OHCI3] = 0x01c1d400,
65
[AW_H3_DEV_CCU] = 0x01c20000,
66
[AW_H3_DEV_PIT] = 0x01c20c00,
67
+ [AW_H3_DEV_WDT] = 0x01c20ca0,
68
[AW_H3_DEV_UART0] = 0x01c28000,
69
[AW_H3_DEV_UART1] = 0x01c28400,
70
[AW_H3_DEV_UART2] = 0x01c28800,
71
@@ -XXX,XX +XXX,XX @@ static void allwinner_h3_init(Object *obj)
72
object_initialize_child(obj, "twi1", &s->i2c1, TYPE_AW_I2C_SUN6I);
73
object_initialize_child(obj, "twi2", &s->i2c2, TYPE_AW_I2C_SUN6I);
74
object_initialize_child(obj, "r_twi", &s->r_twi, TYPE_AW_I2C_SUN6I);
75
+
76
+ object_initialize_child(obj, "wdt", &s->wdt, TYPE_AW_WDT_SUN6I);
24
}
77
}
25
78
26
-static bool ptw_attrs_are_device(CPUARMState *env, ARMCacheAttrs cacheattrs)
79
static void allwinner_h3_realize(DeviceState *dev, Error **errp)
27
+static bool ptw_attrs_are_device(uint64_t hcr, ARMCacheAttrs cacheattrs)
80
@@ -XXX,XX +XXX,XX @@ static void allwinner_h3_realize(DeviceState *dev, Error **errp)
28
{
81
sysbus_connect_irq(SYS_BUS_DEVICE(&s->r_twi), 0,
29
/*
82
qdev_get_gpio_in(DEVICE(&s->gic), AW_H3_GIC_SPI_R_TWI));
30
* For an S1 page table walk, the stage 1 attributes are always
83
31
@@ -XXX,XX +XXX,XX @@ static bool ptw_attrs_are_device(CPUARMState *env, ARMCacheAttrs cacheattrs)
84
+ /* WDT */
32
* when cacheattrs.attrs bit [2] is 0.
85
+ sysbus_realize(SYS_BUS_DEVICE(&s->wdt), &error_fatal);
33
*/
86
+ sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->wdt), 0,
34
assert(cacheattrs.is_s2_format);
87
+ s->memmap[AW_H3_DEV_WDT], 1);
35
- if (arm_hcr_el2_eff(env) & HCR_FWB) {
36
+ if (hcr & HCR_FWB) {
37
return (cacheattrs.attrs & 0x4) == 0;
38
} else {
39
return (cacheattrs.attrs & 0xc) == 0;
40
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
41
if (arm_mmu_idx_is_stage1_of_2(mmu_idx) &&
42
!regime_translation_disabled(env, s2_mmu_idx, is_secure)) {
43
GetPhysAddrResult s2 = {};
44
+ uint64_t hcr;
45
int ret;
46
47
ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, s2_mmu_idx,
48
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
49
fi->s1ns = !is_secure;
50
return ~0;
51
}
52
- if ((arm_hcr_el2_eff(env) & HCR_PTW) &&
53
- ptw_attrs_are_device(env, s2.cacheattrs)) {
54
+
88
+
55
+ hcr = arm_hcr_el2_eff(env);
89
/* Unimplemented devices */
56
+ if ((hcr & HCR_PTW) && ptw_attrs_are_device(hcr, s2.cacheattrs)) {
90
for (i = 0; i < ARRAY_SIZE(unimplemented); i++) {
57
/*
91
create_unimplemented_device(unimplemented[i].device_name,
58
* PTW set and S1 walk touched S2 Device memory:
92
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
59
* generate Permission fault.
93
index XXXXXXX..XXXXXXX 100644
60
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
94
--- a/hw/arm/Kconfig
61
* ref: shared/translation/attrs/S2AttrDecode()
95
+++ b/hw/arm/Kconfig
62
* .../S2ConvertAttrsHints()
96
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_H3
63
*/
97
select ALLWINNER_A10_PIT
64
-static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
98
select ALLWINNER_SUN8I_EMAC
65
+static uint8_t convert_stage2_attrs(uint64_t hcr, uint8_t s2attrs)
99
select ALLWINNER_I2C
66
{
100
+ select ALLWINNER_WDT
67
uint8_t hiattr = extract32(s2attrs, 2, 2);
101
select SERIAL
68
uint8_t loattr = extract32(s2attrs, 0, 2);
102
select ARM_TIMER
69
uint8_t hihint = 0, lohint = 0;
103
select ARM_GIC
70
71
if (hiattr != 0) { /* normal memory */
72
- if (arm_hcr_el2_eff(env) & HCR_CD) { /* cache disabled */
73
+ if (hcr & HCR_CD) { /* cache disabled */
74
hiattr = loattr = 1; /* non-cacheable */
75
} else {
76
if (hiattr != 1) { /* Write-through or write-back */
77
@@ -XXX,XX +XXX,XX @@ static uint8_t combine_cacheattr_nibble(uint8_t s1, uint8_t s2)
78
* s1 and s2 for the HCR_EL2.FWB == 0 case, returning the
79
* combined attributes in MAIR_EL1 format.
80
*/
81
-static uint8_t combined_attrs_nofwb(CPUARMState *env,
82
+static uint8_t combined_attrs_nofwb(uint64_t hcr,
83
ARMCacheAttrs s1, ARMCacheAttrs s2)
84
{
85
uint8_t s1lo, s2lo, s1hi, s2hi, s2_mair_attrs, ret_attrs;
86
87
- s2_mair_attrs = convert_stage2_attrs(env, s2.attrs);
88
+ s2_mair_attrs = convert_stage2_attrs(hcr, s2.attrs);
89
90
s1lo = extract32(s1.attrs, 0, 4);
91
s2lo = extract32(s2_mair_attrs, 0, 4);
92
@@ -XXX,XX +XXX,XX @@ static uint8_t combined_attrs_fwb(ARMCacheAttrs s1, ARMCacheAttrs s2)
93
* @s1: Attributes from stage 1 walk
94
* @s2: Attributes from stage 2 walk
95
*/
96
-static ARMCacheAttrs combine_cacheattrs(CPUARMState *env,
97
+static ARMCacheAttrs combine_cacheattrs(uint64_t hcr,
98
ARMCacheAttrs s1, ARMCacheAttrs s2)
99
{
100
ARMCacheAttrs ret;
101
@@ -XXX,XX +XXX,XX @@ static ARMCacheAttrs combine_cacheattrs(CPUARMState *env,
102
}
103
104
/* Combine memory type and cacheability attributes */
105
- if (arm_hcr_el2_eff(env) & HCR_FWB) {
106
+ if (hcr & HCR_FWB) {
107
ret.attrs = combined_attrs_fwb(s1, s2);
108
} else {
109
- ret.attrs = combined_attrs_nofwb(env, s1, s2);
110
+ ret.attrs = combined_attrs_nofwb(hcr, s1, s2);
111
}
112
113
/*
114
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
115
ARMCacheAttrs cacheattrs1;
116
ARMMMUIdx s2_mmu_idx;
117
bool is_el0;
118
+ uint64_t hcr;
119
120
ret = get_phys_addr_with_secure(env, address, access_type,
121
s1_mmu_idx, is_secure, result, fi);
122
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
123
}
124
125
/* Combine the S1 and S2 cache attributes. */
126
- if (arm_hcr_el2_eff(env) & HCR_DC) {
127
+ hcr = arm_hcr_el2_eff(env);
128
+ if (hcr & HCR_DC) {
129
/*
130
* HCR.DC forces the first stage attributes to
131
* Normal Non-Shareable,
132
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
133
}
134
cacheattrs1.shareability = 0;
135
}
136
- result->cacheattrs = combine_cacheattrs(env, cacheattrs1,
137
+ result->cacheattrs = combine_cacheattrs(hcr, cacheattrs1,
138
result->cacheattrs);
139
140
/*
141
--
104
--
142
2.25.1
105
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Strahinja Jankovic <strahinjapjankovic@gmail.com>
2
2
3
Adjust GetPhysAddrResult to fill in CPUTLBEntryFull,
3
Cubieboard tests end with comment "reboot not functioning; omit test".
4
so that it may be passed directly to tlb_set_page_full.
4
Fix this so reboot is done at the end of each test.
5
5
6
The change is large, but mostly mechanical. The major
6
Signed-off-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
7
non-mechanical change is page_size -> lg_page_size.
7
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
8
Most of the time this is obvious, and is related to
8
Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com>
9
TARGET_PAGE_BITS.
9
Message-id: 20230326202256.22980-5-strahinja.p.jankovic@gmail.com
10
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20221001162318.153420-21-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
11
---
16
target/arm/internals.h | 5 +-
12
tests/avocado/boot_linux_console.py | 15 ++++++++++++---
17
target/arm/helper.c | 12 +--
13
1 file changed, 12 insertions(+), 3 deletions(-)
18
target/arm/m_helper.c | 20 ++---
19
target/arm/ptw.c | 179 ++++++++++++++++++++--------------------
20
target/arm/tlb_helper.c | 9 +-
21
5 files changed, 111 insertions(+), 114 deletions(-)
22
14
23
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
diff --git a/tests/avocado/boot_linux_console.py b/tests/avocado/boot_linux_console.py
24
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/internals.h
17
--- a/tests/avocado/boot_linux_console.py
26
+++ b/target/arm/internals.h
18
+++ b/tests/avocado/boot_linux_console.py
27
@@ -XXX,XX +XXX,XX @@ typedef struct ARMCacheAttrs {
19
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_initrd(self):
28
20
'Allwinner sun4i/sun5i')
29
/* Fields that are valid upon success. */
21
exec_command_and_wait_for_pattern(self, 'cat /proc/iomem',
30
typedef struct GetPhysAddrResult {
22
'system-control@1c00000')
31
- hwaddr phys;
23
- # cubieboard's reboot is not functioning; omit reboot test.
32
- target_ulong page_size;
24
+ exec_command_and_wait_for_pattern(self, 'reboot',
33
- int prot;
25
+ 'reboot: Restarting system')
34
- MemTxAttrs attrs;
26
+ # Wait for VM to shut down gracefully
35
+ CPUTLBEntryFull f;
27
+ self.vm.wait()
36
ARMCacheAttrs cacheattrs;
28
37
} GetPhysAddrResult;
29
def test_arm_cubieboard_sata(self):
38
30
"""
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
31
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_sata(self):
40
index XXXXXXX..XXXXXXX 100644
32
'Allwinner sun4i/sun5i')
41
--- a/target/arm/helper.c
33
exec_command_and_wait_for_pattern(self, 'cat /proc/partitions',
42
+++ b/target/arm/helper.c
34
'sda')
43
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
35
- # cubieboard's reboot is not functioning; omit reboot test.
44
/* Create a 64-bit PAR */
36
+ exec_command_and_wait_for_pattern(self, 'reboot',
45
par64 = (1 << 11); /* LPAE bit always set */
37
+ 'reboot: Restarting system')
46
if (!ret) {
38
+ # Wait for VM to shut down gracefully
47
- par64 |= res.phys & ~0xfffULL;
39
+ self.vm.wait()
48
- if (!res.attrs.secure) {
40
49
+ par64 |= res.f.phys_addr & ~0xfffULL;
41
@skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
50
+ if (!res.f.attrs.secure) {
42
def test_arm_cubieboard_openwrt_22_03_2(self):
51
par64 |= (1 << 9); /* NS */
43
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_openwrt_22_03_2(self):
52
}
44
53
par64 |= (uint64_t)res.cacheattrs.attrs << 56; /* ATTR */
45
exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
54
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
46
'Allwinner sun4i/sun5i')
55
*/
47
- # cubieboard's reboot is not functioning; omit reboot test.
56
if (!ret) {
48
+ exec_command_and_wait_for_pattern(self, 'reboot',
57
/* We do not set any attribute bits in the PAR */
49
+ 'reboot: Restarting system')
58
- if (res.page_size == (1 << 24)
50
+ # Wait for VM to shut down gracefully
59
+ if (res.f.lg_page_size == 24
51
+ self.vm.wait()
60
&& arm_feature(env, ARM_FEATURE_V7)) {
52
61
- par64 = (res.phys & 0xff000000) | (1 << 1);
53
@skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout')
62
+ par64 = (res.f.phys_addr & 0xff000000) | (1 << 1);
54
def test_arm_quanta_gsj(self):
63
} else {
64
- par64 = res.phys & 0xfffff000;
65
+ par64 = res.f.phys_addr & 0xfffff000;
66
}
67
- if (!res.attrs.secure) {
68
+ if (!res.f.attrs.secure) {
69
par64 |= (1 << 9); /* NS */
70
}
71
} else {
72
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/m_helper.c
75
+++ b/target/arm/m_helper.c
76
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
77
}
78
goto pend_fault;
79
}
80
- address_space_stl_le(arm_addressspace(cs, res.attrs), res.phys, value,
81
- res.attrs, &txres);
82
+ address_space_stl_le(arm_addressspace(cs, res.f.attrs), res.f.phys_addr,
83
+ value, res.f.attrs, &txres);
84
if (txres != MEMTX_OK) {
85
/* BusFault trying to write the data */
86
if (mode == STACK_LAZYFP) {
87
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_read(ARMCPU *cpu, uint32_t *dest, uint32_t addr,
88
goto pend_fault;
89
}
90
91
- value = address_space_ldl(arm_addressspace(cs, res.attrs), res.phys,
92
- res.attrs, &txres);
93
+ value = address_space_ldl(arm_addressspace(cs, res.f.attrs),
94
+ res.f.phys_addr, res.f.attrs, &txres);
95
if (txres != MEMTX_OK) {
96
/* BusFault trying to read the data */
97
qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.UNSTKERR\n");
98
@@ -XXX,XX +XXX,XX @@ static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx, bool secure,
99
qemu_log_mask(CPU_LOG_INT, "...really MemManage with CFSR.IACCVIOL\n");
100
return false;
101
}
102
- *insn = address_space_lduw_le(arm_addressspace(cs, res.attrs), res.phys,
103
- res.attrs, &txres);
104
+ *insn = address_space_lduw_le(arm_addressspace(cs, res.f.attrs),
105
+ res.f.phys_addr, res.f.attrs, &txres);
106
if (txres != MEMTX_OK) {
107
env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_IBUSERR_MASK;
108
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS, false);
109
@@ -XXX,XX +XXX,XX @@ static bool v7m_read_sg_stack_word(ARMCPU *cpu, ARMMMUIdx mmu_idx,
110
}
111
return false;
112
}
113
- value = address_space_ldl(arm_addressspace(cs, res.attrs), res.phys,
114
- res.attrs, &txres);
115
+ value = address_space_ldl(arm_addressspace(cs, res.f.attrs),
116
+ res.f.phys_addr, res.f.attrs, &txres);
117
if (txres != MEMTX_OK) {
118
/* BusFault trying to read the data */
119
qemu_log_mask(CPU_LOG_INT,
120
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
121
} else {
122
mrvalid = true;
123
}
124
- r = res.prot & PAGE_READ;
125
- rw = res.prot & PAGE_WRITE;
126
+ r = res.f.prot & PAGE_READ;
127
+ rw = res.f.prot & PAGE_WRITE;
128
} else {
129
r = false;
130
rw = false;
131
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/target/arm/ptw.c
134
+++ b/target/arm/ptw.c
135
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
136
assert(!is_secure);
137
}
138
139
- addr = s2.phys;
140
+ addr = s2.f.phys_addr;
141
}
142
return addr;
143
}
144
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
145
/* 1Mb section. */
146
phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
147
ap = (desc >> 10) & 3;
148
- result->page_size = 1024 * 1024;
149
+ result->f.lg_page_size = 20; /* 1MB */
150
} else {
151
/* Lookup l2 entry. */
152
if (type == 1) {
153
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
154
case 1: /* 64k page. */
155
phys_addr = (desc & 0xffff0000) | (address & 0xffff);
156
ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
157
- result->page_size = 0x10000;
158
+ result->f.lg_page_size = 16;
159
break;
160
case 2: /* 4k page. */
161
phys_addr = (desc & 0xfffff000) | (address & 0xfff);
162
ap = (desc >> (4 + ((address >> 9) & 6))) & 3;
163
- result->page_size = 0x1000;
164
+ result->f.lg_page_size = 12;
165
break;
166
case 3: /* 1k page, or ARMv6/XScale "extended small (4k) page" */
167
if (type == 1) {
168
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
169
if (arm_feature(env, ARM_FEATURE_XSCALE)
170
|| arm_feature(env, ARM_FEATURE_V6)) {
171
phys_addr = (desc & 0xfffff000) | (address & 0xfff);
172
- result->page_size = 0x1000;
173
+ result->f.lg_page_size = 12;
174
} else {
175
/*
176
* UNPREDICTABLE in ARMv5; we choose to take a
177
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
178
}
179
} else {
180
phys_addr = (desc & 0xfffffc00) | (address & 0x3ff);
181
- result->page_size = 0x400;
182
+ result->f.lg_page_size = 10;
183
}
184
ap = (desc >> 4) & 3;
185
break;
186
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
187
g_assert_not_reached();
188
}
189
}
190
- result->prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
191
- result->prot |= result->prot ? PAGE_EXEC : 0;
192
- if (!(result->prot & (1 << access_type))) {
193
+ result->f.prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
194
+ result->f.prot |= result->f.prot ? PAGE_EXEC : 0;
195
+ if (!(result->f.prot & (1 << access_type))) {
196
/* Access permission fault. */
197
fi->type = ARMFault_Permission;
198
goto do_fault;
199
}
200
- result->phys = phys_addr;
201
+ result->f.phys_addr = phys_addr;
202
return false;
203
do_fault:
204
fi->domain = domain;
205
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
206
phys_addr = (desc & 0xff000000) | (address & 0x00ffffff);
207
phys_addr |= (uint64_t)extract32(desc, 20, 4) << 32;
208
phys_addr |= (uint64_t)extract32(desc, 5, 4) << 36;
209
- result->page_size = 0x1000000;
210
+ result->f.lg_page_size = 24; /* 16MB */
211
} else {
212
/* Section. */
213
phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
214
- result->page_size = 0x100000;
215
+ result->f.lg_page_size = 20; /* 1MB */
216
}
217
ap = ((desc >> 10) & 3) | ((desc >> 13) & 4);
218
xn = desc & (1 << 4);
219
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
220
case 1: /* 64k page. */
221
phys_addr = (desc & 0xffff0000) | (address & 0xffff);
222
xn = desc & (1 << 15);
223
- result->page_size = 0x10000;
224
+ result->f.lg_page_size = 16;
225
break;
226
case 2: case 3: /* 4k page. */
227
phys_addr = (desc & 0xfffff000) | (address & 0xfff);
228
xn = desc & 1;
229
- result->page_size = 0x1000;
230
+ result->f.lg_page_size = 12;
231
break;
232
default:
233
/* Never happens, but compiler isn't smart enough to tell. */
234
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
235
}
236
}
237
if (domain_prot == 3) {
238
- result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
239
+ result->f.prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
240
} else {
241
if (pxn && !regime_is_user(env, mmu_idx)) {
242
xn = 1;
243
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
244
fi->type = ARMFault_AccessFlag;
245
goto do_fault;
246
}
247
- result->prot = simple_ap_to_rw_prot(env, mmu_idx, ap >> 1);
248
+ result->f.prot = simple_ap_to_rw_prot(env, mmu_idx, ap >> 1);
249
} else {
250
- result->prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
251
+ result->f.prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
252
}
253
- if (result->prot && !xn) {
254
- result->prot |= PAGE_EXEC;
255
+ if (result->f.prot && !xn) {
256
+ result->f.prot |= PAGE_EXEC;
257
}
258
- if (!(result->prot & (1 << access_type))) {
259
+ if (!(result->f.prot & (1 << access_type))) {
260
/* Access permission fault. */
261
fi->type = ARMFault_Permission;
262
goto do_fault;
263
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
264
* the CPU doesn't support TZ or this is a non-secure translation
265
* regime, because the attribute will already be non-secure.
266
*/
267
- result->attrs.secure = false;
268
+ result->f.attrs.secure = false;
269
}
270
- result->phys = phys_addr;
271
+ result->f.phys_addr = phys_addr;
272
return false;
273
do_fault:
274
fi->domain = domain;
275
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
276
if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
277
ns = mmu_idx == ARMMMUIdx_Stage2;
278
xn = extract32(attrs, 11, 2);
279
- result->prot = get_S2prot(env, ap, xn, s1_is_el0);
280
+ result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
281
} else {
282
ns = extract32(attrs, 3, 1);
283
xn = extract32(attrs, 12, 1);
284
pxn = extract32(attrs, 11, 1);
285
- result->prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
286
+ result->f.prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
287
}
288
289
fault_type = ARMFault_Permission;
290
- if (!(result->prot & (1 << access_type))) {
291
+ if (!(result->f.prot & (1 << access_type))) {
292
goto do_fault;
293
}
294
295
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
296
* the CPU doesn't support TZ or this is a non-secure translation
297
* regime, because the attribute will already be non-secure.
298
*/
299
- result->attrs.secure = false;
300
+ result->f.attrs.secure = false;
301
}
302
/* When in aarch64 mode, and BTI is enabled, remember GP in the IOTLB. */
303
if (aarch64 && guarded && cpu_isar_feature(aa64_bti, cpu)) {
304
- arm_tlb_bti_gp(&result->attrs) = true;
305
+ arm_tlb_bti_gp(&result->f.attrs) = true;
306
}
307
308
if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
309
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
310
result->cacheattrs.shareability = extract32(attrs, 6, 2);
311
}
312
313
- result->phys = descaddr;
314
- result->page_size = page_size;
315
+ result->f.phys_addr = descaddr;
316
+ result->f.lg_page_size = ctz64(page_size);
317
return false;
318
319
do_fault:
320
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
321
322
if (regime_translation_disabled(env, mmu_idx, is_secure)) {
323
/* MPU disabled. */
324
- result->phys = address;
325
- result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
326
+ result->f.phys_addr = address;
327
+ result->f.prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
328
return false;
329
}
330
331
- result->phys = address;
332
+ result->f.phys_addr = address;
333
for (n = 7; n >= 0; n--) {
334
base = env->cp15.c6_region[n];
335
if ((base & 1) == 0) {
336
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
337
fi->level = 1;
338
return true;
339
}
340
- result->prot = PAGE_READ | PAGE_WRITE;
341
+ result->f.prot = PAGE_READ | PAGE_WRITE;
342
break;
343
case 2:
344
- result->prot = PAGE_READ;
345
+ result->f.prot = PAGE_READ;
346
if (!is_user) {
347
- result->prot |= PAGE_WRITE;
348
+ result->f.prot |= PAGE_WRITE;
349
}
350
break;
351
case 3:
352
- result->prot = PAGE_READ | PAGE_WRITE;
353
+ result->f.prot = PAGE_READ | PAGE_WRITE;
354
break;
355
case 5:
356
if (is_user) {
357
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
358
fi->level = 1;
359
return true;
360
}
361
- result->prot = PAGE_READ;
362
+ result->f.prot = PAGE_READ;
363
break;
364
case 6:
365
- result->prot = PAGE_READ;
366
+ result->f.prot = PAGE_READ;
367
break;
368
default:
369
/* Bad permission. */
370
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
371
fi->level = 1;
372
return true;
373
}
374
- result->prot |= PAGE_EXEC;
375
+ result->f.prot |= PAGE_EXEC;
376
return false;
377
}
378
379
static void get_phys_addr_pmsav7_default(CPUARMState *env, ARMMMUIdx mmu_idx,
380
- int32_t address, int *prot)
381
+ int32_t address, uint8_t *prot)
382
{
383
if (!arm_feature(env, ARM_FEATURE_M)) {
384
*prot = PAGE_READ | PAGE_WRITE;
385
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
386
int n;
387
bool is_user = regime_is_user(env, mmu_idx);
388
389
- result->phys = address;
390
- result->page_size = TARGET_PAGE_SIZE;
391
- result->prot = 0;
392
+ result->f.phys_addr = address;
393
+ result->f.lg_page_size = TARGET_PAGE_BITS;
394
+ result->f.prot = 0;
395
396
if (regime_translation_disabled(env, mmu_idx, secure) ||
397
m_is_ppb_region(env, address)) {
398
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
399
* which always does a direct read using address_space_ldl(), rather
400
* than going via this function, so we don't need to check that here.
401
*/
402
- get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->prot);
403
+ get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->f.prot);
404
} else { /* MPU enabled */
405
for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {
406
/* region search */
407
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
408
if (ranges_overlap(base, rmask,
409
address & TARGET_PAGE_MASK,
410
TARGET_PAGE_SIZE)) {
411
- result->page_size = 1;
412
+ result->f.lg_page_size = 0;
413
}
414
continue;
415
}
416
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
417
continue;
418
}
419
if (rsize < TARGET_PAGE_BITS) {
420
- result->page_size = 1 << rsize;
421
+ result->f.lg_page_size = rsize;
422
}
423
break;
424
}
425
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
426
fi->type = ARMFault_Background;
427
return true;
428
}
429
- get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->prot);
430
+ get_phys_addr_pmsav7_default(env, mmu_idx, address,
431
+ &result->f.prot);
432
} else { /* a MPU hit! */
433
uint32_t ap = extract32(env->pmsav7.dracr[n], 8, 3);
434
uint32_t xn = extract32(env->pmsav7.dracr[n], 12, 1);
435
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
436
case 5:
437
break; /* no access */
438
case 3:
439
- result->prot |= PAGE_WRITE;
440
+ result->f.prot |= PAGE_WRITE;
441
/* fall through */
442
case 2:
443
case 6:
444
- result->prot |= PAGE_READ | PAGE_EXEC;
445
+ result->f.prot |= PAGE_READ | PAGE_EXEC;
446
break;
447
case 7:
448
/* for v7M, same as 6; for R profile a reserved value */
449
if (arm_feature(env, ARM_FEATURE_M)) {
450
- result->prot |= PAGE_READ | PAGE_EXEC;
451
+ result->f.prot |= PAGE_READ | PAGE_EXEC;
452
break;
453
}
454
/* fall through */
455
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
456
case 1:
457
case 2:
458
case 3:
459
- result->prot |= PAGE_WRITE;
460
+ result->f.prot |= PAGE_WRITE;
461
/* fall through */
462
case 5:
463
case 6:
464
- result->prot |= PAGE_READ | PAGE_EXEC;
465
+ result->f.prot |= PAGE_READ | PAGE_EXEC;
466
break;
467
case 7:
468
/* for v7M, same as 6; for R profile a reserved value */
469
if (arm_feature(env, ARM_FEATURE_M)) {
470
- result->prot |= PAGE_READ | PAGE_EXEC;
471
+ result->f.prot |= PAGE_READ | PAGE_EXEC;
472
break;
473
}
474
/* fall through */
475
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
476
477
/* execute never */
478
if (xn) {
479
- result->prot &= ~PAGE_EXEC;
480
+ result->f.prot &= ~PAGE_EXEC;
481
}
482
}
483
}
484
485
fi->type = ARMFault_Permission;
486
fi->level = 1;
487
- return !(result->prot & (1 << access_type));
488
+ return !(result->f.prot & (1 << access_type));
489
}
490
491
bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
492
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
493
uint32_t addr_page_base = address & TARGET_PAGE_MASK;
494
uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1);
495
496
- result->page_size = TARGET_PAGE_SIZE;
497
- result->phys = address;
498
- result->prot = 0;
499
+ result->f.lg_page_size = TARGET_PAGE_BITS;
500
+ result->f.phys_addr = address;
501
+ result->f.prot = 0;
502
if (mregion) {
503
*mregion = -1;
504
}
505
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
506
ranges_overlap(base, limit - base + 1,
507
addr_page_base,
508
TARGET_PAGE_SIZE)) {
509
- result->page_size = 1;
510
+ result->f.lg_page_size = 0;
511
}
512
continue;
513
}
514
515
if (base > addr_page_base || limit < addr_page_limit) {
516
- result->page_size = 1;
517
+ result->f.lg_page_size = 0;
518
}
519
520
if (matchregion != -1) {
521
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
522
523
if (matchregion == -1) {
524
/* hit using the background region */
525
- get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->prot);
526
+ get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->f.prot);
527
} else {
528
uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2);
529
uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1);
530
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
531
xn = 1;
532
}
533
534
- result->prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
535
- if (result->prot && !xn && !(pxn && !is_user)) {
536
- result->prot |= PAGE_EXEC;
537
+ result->f.prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
538
+ if (result->f.prot && !xn && !(pxn && !is_user)) {
539
+ result->f.prot |= PAGE_EXEC;
540
}
541
/*
542
* We don't need to look the attribute up in the MAIR0/MAIR1
543
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
544
545
fi->type = ARMFault_Permission;
546
fi->level = 1;
547
- return !(result->prot & (1 << access_type));
548
+ return !(result->f.prot & (1 << access_type));
549
}
550
551
static bool v8m_is_sau_exempt(CPUARMState *env,
552
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
553
} else {
554
fi->type = ARMFault_QEMU_SFault;
555
}
556
- result->page_size = sattrs.subpage ? 1 : TARGET_PAGE_SIZE;
557
- result->phys = address;
558
- result->prot = 0;
559
+ result->f.lg_page_size = sattrs.subpage ? 0 : TARGET_PAGE_BITS;
560
+ result->f.phys_addr = address;
561
+ result->f.prot = 0;
562
return true;
563
}
564
} else {
565
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
566
* might downgrade a secure access to nonsecure.
567
*/
568
if (sattrs.ns) {
569
- result->attrs.secure = false;
570
+ result->f.attrs.secure = false;
571
} else if (!secure) {
572
/*
573
* NS access to S memory must fault.
574
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
575
* for M_FAKE_FSR_SFAULT in arm_v7m_cpu_do_interrupt().
576
*/
577
fi->type = ARMFault_QEMU_SFault;
578
- result->page_size = sattrs.subpage ? 1 : TARGET_PAGE_SIZE;
579
- result->phys = address;
580
- result->prot = 0;
581
+ result->f.lg_page_size = sattrs.subpage ? 0 : TARGET_PAGE_BITS;
582
+ result->f.phys_addr = address;
583
+ result->f.prot = 0;
584
return true;
585
}
586
}
587
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
588
ret = pmsav8_mpu_lookup(env, address, access_type, mmu_idx, secure,
589
result, fi, NULL);
590
if (sattrs.subpage) {
591
- result->page_size = 1;
592
+ result->f.lg_page_size = 0;
593
}
594
return ret;
595
}
596
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
597
result->cacheattrs.is_s2_format = false;
598
}
599
600
- result->phys = address;
601
- result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
602
- result->page_size = TARGET_PAGE_SIZE;
603
+ result->f.phys_addr = address;
604
+ result->f.prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
605
+ result->f.lg_page_size = TARGET_PAGE_BITS;
606
result->cacheattrs.shareability = shareability;
607
result->cacheattrs.attrs = memattr;
608
return 0;
609
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
610
return ret;
611
}
612
613
- ipa = result->phys;
614
- ipa_secure = result->attrs.secure;
615
+ ipa = result->f.phys_addr;
616
+ ipa_secure = result->f.attrs.secure;
617
if (is_secure) {
618
/* Select TCR based on the NS bit from the S1 walk. */
619
s2walk_secure = !(ipa_secure
620
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
621
* Save the stage1 results so that we may merge
622
* prot and cacheattrs later.
623
*/
624
- s1_prot = result->prot;
625
+ s1_prot = result->f.prot;
626
cacheattrs1 = result->cacheattrs;
627
memset(result, 0, sizeof(*result));
628
629
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
630
fi->s2addr = ipa;
631
632
/* Combine the S1 and S2 perms. */
633
- result->prot &= s1_prot;
634
+ result->f.prot &= s1_prot;
635
636
/* If S2 fails, return early. */
637
if (ret) {
638
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
639
* Check if IPA translates to secure or non-secure PA space.
640
* Note that VSTCR overrides VTCR and {N}SW overrides {N}SA.
641
*/
642
- result->attrs.secure =
643
+ result->f.attrs.secure =
644
(is_secure
645
&& !(env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW))
646
&& (ipa_secure
647
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
648
* cannot upgrade an non-secure translation regime's attributes
649
* to secure.
650
*/
651
- result->attrs.secure = is_secure;
652
- result->attrs.user = regime_is_user(env, mmu_idx);
653
+ result->f.attrs.secure = is_secure;
654
+ result->f.attrs.user = regime_is_user(env, mmu_idx);
655
656
/*
657
* Fast Context Switch Extension. This doesn't exist at all in v8.
658
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
659
660
if (arm_feature(env, ARM_FEATURE_PMSA)) {
661
bool ret;
662
- result->page_size = TARGET_PAGE_SIZE;
663
+ result->f.lg_page_size = TARGET_PAGE_BITS;
664
665
if (arm_feature(env, ARM_FEATURE_V8)) {
666
/* PMSAv8 */
667
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
668
(access_type == MMU_DATA_STORE ? "writing" : "execute"),
669
(uint32_t)address, mmu_idx,
670
ret ? "Miss" : "Hit",
671
- result->prot & PAGE_READ ? 'r' : '-',
672
- result->prot & PAGE_WRITE ? 'w' : '-',
673
- result->prot & PAGE_EXEC ? 'x' : '-');
674
+ result->f.prot & PAGE_READ ? 'r' : '-',
675
+ result->f.prot & PAGE_WRITE ? 'w' : '-',
676
+ result->f.prot & PAGE_EXEC ? 'x' : '-');
677
678
return ret;
679
}
680
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
681
bool ret;
682
683
ret = get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &res, &fi);
684
- *attrs = res.attrs;
685
+ *attrs = res.f.attrs;
686
687
if (ret) {
688
return -1;
689
}
690
- return res.phys;
691
+ return res.f.phys_addr;
692
}
693
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
694
index XXXXXXX..XXXXXXX 100644
695
--- a/target/arm/tlb_helper.c
696
+++ b/target/arm/tlb_helper.c
697
@@ -XXX,XX +XXX,XX @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
698
* target page size are handled specially, so for those we
699
* pass in the exact addresses.
700
*/
701
- if (res.page_size >= TARGET_PAGE_SIZE) {
702
- res.phys &= TARGET_PAGE_MASK;
703
+ if (res.f.lg_page_size >= TARGET_PAGE_BITS) {
704
+ res.f.phys_addr &= TARGET_PAGE_MASK;
705
address &= TARGET_PAGE_MASK;
706
}
707
/* Notice and record tagged memory. */
708
if (cpu_isar_feature(aa64_mte, cpu) && res.cacheattrs.attrs == 0xf0) {
709
- arm_tlb_mte_tagged(&res.attrs) = true;
710
+ arm_tlb_mte_tagged(&res.f.attrs) = true;
711
}
712
713
- tlb_set_page_with_attrs(cs, address, res.phys, res.attrs,
714
- res.prot, mmu_idx, res.page_size);
715
+ tlb_set_page_full(cs, mmu_idx, address, &res.f);
716
return true;
717
} else if (probe) {
718
return false;
719
--
55
--
720
2.25.1
56
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Axel Heider <axel.heider@hensoldt.net>
2
2
3
Use arm_hcr_el2_eff_secstate instead of arm_hcr_el2_eff, so
3
Fix issue reported by Coverity.
4
that we use is_secure instead of the current security state.
5
These AT* operations have been broken since arm_hcr_el2_eff
6
gained a check for "el2 enabled" for Secure EL2.
7
4
5
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
6
Message-id: 168070611775.20412.2883242077302841473-1@git.sr.ht
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20221001162318.153420-18-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
9
---
13
target/arm/ptw.c | 8 ++++----
10
hw/timer/imx_epit.c | 2 +-
14
1 file changed, 4 insertions(+), 4 deletions(-)
11
1 file changed, 1 insertion(+), 1 deletion(-)
15
12
16
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
13
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/ptw.c
15
--- a/hw/timer/imx_epit.c
19
+++ b/target/arm/ptw.c
16
+++ b/hw/timer/imx_epit.c
20
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
17
@@ -XXX,XX +XXX,XX @@ static void imx_epit_update_compare_timer(IMXEPITState *s)
21
}
18
* the compare value. Otherwise it may fire at most once in the
22
}
19
* current round.
23
20
*/
24
- hcr_el2 = arm_hcr_el2_eff(env);
21
- bool is_oneshot = (limit >= s->cmp);
25
+ hcr_el2 = arm_hcr_el2_eff_secstate(env, is_secure);
22
+ is_oneshot = (limit >= s->cmp);
26
23
if (counter >= s->cmp) {
27
switch (mmu_idx) {
24
/* The compare timer fires in the current round. */
28
case ARMMMUIdx_Stage2:
25
counter -= s->cmp;
29
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
30
return ~0;
31
}
32
33
- hcr = arm_hcr_el2_eff(env);
34
+ hcr = arm_hcr_el2_eff_secstate(env, is_secure);
35
if ((hcr & HCR_PTW) && ptw_attrs_are_device(hcr, s2.cacheattrs)) {
36
/*
37
* PTW set and S1 walk touched S2 Device memory:
38
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
39
}
40
41
/* Combine the S1 and S2 cache attributes. */
42
- hcr = arm_hcr_el2_eff(env);
43
+ hcr = arm_hcr_el2_eff_secstate(env, is_secure);
44
if (hcr & HCR_DC) {
45
/*
46
* HCR.DC forces the first stage attributes to
47
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
48
result->page_size = TARGET_PAGE_SIZE;
49
50
/* Fill in cacheattr a-la AArch64.TranslateAddressS1Off. */
51
- hcr = arm_hcr_el2_eff(env);
52
+ hcr = arm_hcr_el2_eff_secstate(env, is_secure);
53
result->cacheattrs.shareability = 0;
54
result->cacheattrs.is_s2_format = false;
55
if (hcr & HCR_DC) {
56
--
26
--
57
2.25.1
27
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Axel Heider <axel.heider@hensoldt.net>
2
2
3
This value is unused.
3
Fix the limit check. If the limit is less than the compare value,
4
the timer can never reach this value, thus it will never fire.
4
5
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1491
7
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
8
Message-id: 168070611775.20412.2883242077302841473-2@git.sr.ht
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20221001162318.153420-16-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
11
---
10
target/arm/ptw.c | 5 ++---
12
hw/timer/imx_epit.c | 2 +-
11
1 file changed, 2 insertions(+), 3 deletions(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
12
14
13
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/ptw.c
17
--- a/hw/timer/imx_epit.c
16
+++ b/target/arm/ptw.c
18
+++ b/hw/timer/imx_epit.c
17
@@ -XXX,XX +XXX,XX @@ static uint8_t force_cacheattr_nibble_wb(uint8_t attr)
19
@@ -XXX,XX +XXX,XX @@ static void imx_epit_update_compare_timer(IMXEPITState *s)
18
* s1 and s2 for the HCR_EL2.FWB == 1 case, returning the
20
* the compare value. Otherwise it may fire at most once in the
19
* combined attributes in MAIR_EL1 format.
21
* current round.
20
*/
22
*/
21
-static uint8_t combined_attrs_fwb(CPUARMState *env,
23
- is_oneshot = (limit >= s->cmp);
22
- ARMCacheAttrs s1, ARMCacheAttrs s2)
24
+ is_oneshot = (limit < s->cmp);
23
+static uint8_t combined_attrs_fwb(ARMCacheAttrs s1, ARMCacheAttrs s2)
25
if (counter >= s->cmp) {
24
{
26
/* The compare timer fires in the current round. */
25
switch (s2.attrs) {
27
counter -= s->cmp;
26
case 7:
27
@@ -XXX,XX +XXX,XX @@ static ARMCacheAttrs combine_cacheattrs(CPUARMState *env,
28
29
/* Combine memory type and cacheability attributes */
30
if (arm_hcr_el2_eff(env) & HCR_FWB) {
31
- ret.attrs = combined_attrs_fwb(env, s1, s2);
32
+ ret.attrs = combined_attrs_fwb(s1, s2);
33
} else {
34
ret.attrs = combined_attrs_nofwb(env, s1, s2);
35
}
36
--
28
--
37
2.25.1
29
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Remove the use of regime_is_secure from get_phys_addr_lpae,
3
Missed in commit 80485d88f9 ("target/arm: Restrict
4
using the new parameter instead.
4
v7A TCG cpus to TCG accel").
5
5
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20221001162318.153420-3-richard.henderson@linaro.org
8
Message-id: 20230405100848.76145-2-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
target/arm/ptw.c | 20 ++++++++++----------
11
target/arm/kvm-consts.h | 9 +++------
12
1 file changed, 10 insertions(+), 10 deletions(-)
12
target/arm/cpu_tcg.c | 2 --
13
2 files changed, 3 insertions(+), 8 deletions(-)
13
14
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/ptw.c
17
--- a/target/arm/kvm-consts.h
17
+++ b/target/arm/ptw.c
18
+++ b/target/arm/kvm-consts.h
18
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ MISMATCH_CHECK(QEMU_PSCI_RET_INTERNAL_FAILURE, PSCI_RET_INTERNAL_FAILURE);
19
20
MISMATCH_CHECK(QEMU_PSCI_RET_NOT_PRESENT, PSCI_RET_NOT_PRESENT);
20
static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
21
MISMATCH_CHECK(QEMU_PSCI_RET_DISABLED, PSCI_RET_DISABLED);
21
MMUAccessType access_type, ARMMMUIdx mmu_idx,
22
22
- bool s1_is_el0, GetPhysAddrResult *result,
23
-/* Note that KVM uses overlapping values for AArch32 and AArch64
23
- ARMMMUFaultInfo *fi)
24
- * target CPU numbers. AArch32 targets:
24
+ bool is_secure, bool s1_is_el0,
25
+/*
25
+ GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
26
+ * Note that KVM uses overlapping values for AArch32 and AArch64
26
__attribute__((nonnull));
27
+ * target CPU numbers. AArch64 targets:
27
28
/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
29
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
30
GetPhysAddrResult s2 = {};
31
int ret;
32
33
- ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, s2_mmu_idx, false,
34
- &s2, fi);
35
+ ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, s2_mmu_idx,
36
+ *is_secure, false, &s2, fi);
37
if (ret) {
38
assert(fi->type != ARMFault_None);
39
fi->s2addr = addr;
40
@@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
41
*/
28
*/
42
static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
29
-#define QEMU_KVM_ARM_TARGET_CORTEX_A15 0
43
MMUAccessType access_type, ARMMMUIdx mmu_idx,
30
-#define QEMU_KVM_ARM_TARGET_CORTEX_A7 1
44
- bool s1_is_el0, GetPhysAddrResult *result,
31
-
45
- ARMMMUFaultInfo *fi)
32
-/* AArch64 targets: */
46
+ bool is_secure, bool s1_is_el0,
33
#define QEMU_KVM_ARM_TARGET_AEM_V8 0
47
+ GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
34
#define QEMU_KVM_ARM_TARGET_FOUNDATION_V8 1
48
{
35
#define QEMU_KVM_ARM_TARGET_CORTEX_A57 2
49
ARMCPU *cpu = env_archcpu(env);
36
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
50
/* Read an LPAE long-descriptor translation table. */
37
index XXXXXXX..XXXXXXX 100644
51
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
38
--- a/target/arm/cpu_tcg.c
52
* remain non-secure. We implement this by just ORing in the NSTable/NS
39
+++ b/target/arm/cpu_tcg.c
53
* bits at each step.
40
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
54
*/
41
set_feature(&cpu->env, ARM_FEATURE_EL2);
55
- tableattrs = regime_is_secure(env, mmu_idx) ? 0 : (1 << 4);
42
set_feature(&cpu->env, ARM_FEATURE_EL3);
56
+ tableattrs = is_secure ? 0 : (1 << 4);
43
set_feature(&cpu->env, ARM_FEATURE_PMU);
57
for (;;) {
44
- cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A7;
58
uint64_t descriptor;
45
cpu->midr = 0x410fc075;
59
bool nstable;
46
cpu->reset_fpsid = 0x41023075;
60
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
47
cpu->isar.mvfr0 = 0x10110222;
61
memset(result, 0, sizeof(*result));
48
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
62
49
set_feature(&cpu->env, ARM_FEATURE_EL2);
63
ret = get_phys_addr_lpae(env, ipa, access_type, s2_mmu_idx,
50
set_feature(&cpu->env, ARM_FEATURE_EL3);
64
- is_el0, result, fi);
51
set_feature(&cpu->env, ARM_FEATURE_PMU);
65
+ s2walk_secure, is_el0, result, fi);
52
- cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
66
fi->s2addr = ipa;
53
/* r4p0 cpu, not requiring expensive tlb flush errata */
67
54
cpu->midr = 0x414fc0f0;
68
/* Combine the S1 and S2 perms. */
55
cpu->revidr = 0x0;
69
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
70
}
71
72
if (regime_using_lpae_format(env, mmu_idx)) {
73
- return get_phys_addr_lpae(env, address, access_type, mmu_idx, false,
74
- result, fi);
75
+ return get_phys_addr_lpae(env, address, access_type, mmu_idx,
76
+ is_secure, false, result, fi);
77
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
78
return get_phys_addr_v6(env, address, access_type, mmu_idx,
79
is_secure, result, fi);
80
--
56
--
81
2.25.1
57
2.34.1
82
58
83
59
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Remove the use of regime_is_secure from v7m_read_half_insn, using
3
The Cortex-A7 core is only available when TCG is enabled (see
4
the new parameter instead.
4
commit 80485d88f9 "target/arm: Restrict v7A TCG cpus to TCG accel").
5
5
6
As it happens, both callers pass true, propagated from the argument
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
to arm_v7m_mmu_idx_for_secstate which created the mmu_idx argument,
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
but that is a detail of v7m_handle_execute_nsc we need not expose
8
Message-id: 20230405100848.76145-3-philmd@linaro.org
9
to the callee.
10
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20221001162318.153420-7-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
10
---
17
target/arm/m_helper.c | 9 ++++-----
11
hw/arm/virt.c | 2 ++
18
1 file changed, 4 insertions(+), 5 deletions(-)
12
1 file changed, 2 insertions(+)
19
13
20
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
14
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/m_helper.c
16
--- a/hw/arm/virt.c
23
+++ b/target/arm/m_helper.c
17
+++ b/hw/arm/virt.c
24
@@ -XXX,XX +XXX,XX @@ static bool do_v7m_function_return(ARMCPU *cpu)
18
@@ -XXX,XX +XXX,XX @@ static const int a15irqmap[] = {
25
return true;
19
};
26
}
20
27
21
static const char *valid_cpus[] = {
28
-static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx,
22
+#ifdef CONFIG_TCG
29
+static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx, bool secure,
23
ARM_CPU_TYPE_NAME("cortex-a7"),
30
uint32_t addr, uint16_t *insn)
24
+#endif
31
{
25
ARM_CPU_TYPE_NAME("cortex-a15"),
32
/*
26
ARM_CPU_TYPE_NAME("cortex-a35"),
33
@@ -XXX,XX +XXX,XX @@ static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx,
27
ARM_CPU_TYPE_NAME("cortex-a53"),
34
ARMMMUFaultInfo fi = {};
35
MemTxResult txres;
36
37
- v8m_security_lookup(env, addr, MMU_INST_FETCH, mmu_idx,
38
- regime_is_secure(env, mmu_idx), &sattrs);
39
+ v8m_security_lookup(env, addr, MMU_INST_FETCH, mmu_idx, secure, &sattrs);
40
if (!sattrs.nsc || sattrs.ns) {
41
/*
42
* This must be the second half of the insn, and it straddles a
43
@@ -XXX,XX +XXX,XX @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
44
/* We want to do the MPU lookup as secure; work out what mmu_idx that is */
45
mmu_idx = arm_v7m_mmu_idx_for_secstate(env, true);
46
47
- if (!v7m_read_half_insn(cpu, mmu_idx, env->regs[15], &insn)) {
48
+ if (!v7m_read_half_insn(cpu, mmu_idx, true, env->regs[15], &insn)) {
49
return false;
50
}
51
52
@@ -XXX,XX +XXX,XX @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
53
goto gen_invep;
54
}
55
56
- if (!v7m_read_half_insn(cpu, mmu_idx, env->regs[15] + 2, &insn)) {
57
+ if (!v7m_read_half_insn(cpu, mmu_idx, true, env->regs[15] + 2, &insn)) {
58
return false;
59
}
60
61
--
28
--
62
2.25.1
29
2.34.1
63
30
64
31
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
2
3
Retain the existing get_phys_addr interface using the security
3
kvm_arm_init_debug() used to be called several times on a SMP system as
4
state derived from mmu_idx. Move the kerneldoc comments to the
4
kvm_arch_init_vcpu() calls it. Move the call to kvm_arch_init() to make
5
header file where they belong.
5
sure it will be called only once; otherwise it will overwrite pointers
6
to memory allocated with the previous call and leak it.
6
7
8
Fixes: e4482ab7e3 ("target-arm: kvm - add support for HW assisted debug")
9
Suggested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
11
Message-id: 20230405153644.25300-1-akihiko.odaki@daynix.com
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20221001162318.153420-6-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
14
---
12
target/arm/internals.h | 40 ++++++++++++++++++++++++++++++++++++++
15
target/arm/kvm_arm.h | 8 ++++++++
13
target/arm/ptw.c | 44 ++++++++++++++----------------------------
16
target/arm/kvm.c | 2 ++
14
2 files changed, 55 insertions(+), 29 deletions(-)
17
target/arm/kvm64.c | 18 ++++--------------
18
3 files changed, 14 insertions(+), 14 deletions(-)
15
19
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
20
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/internals.h
22
--- a/target/arm/kvm_arm.h
19
+++ b/target/arm/internals.h
23
+++ b/target/arm/kvm_arm.h
20
@@ -XXX,XX +XXX,XX @@ typedef struct GetPhysAddrResult {
24
@@ -XXX,XX +XXX,XX @@
21
ARMCacheAttrs cacheattrs;
25
#define KVM_ARM_VGIC_V2 (1 << 0)
22
} GetPhysAddrResult;
26
#define KVM_ARM_VGIC_V3 (1 << 1)
23
27
24
+/**
28
+/**
25
+ * get_phys_addr_with_secure: get the physical address for a virtual address
29
+ * kvm_arm_init_debug() - initialize guest debug capabilities
26
+ * @env: CPUARMState
30
+ * @s: KVMState
27
+ * @address: virtual address to get physical address for
28
+ * @access_type: 0 for read, 1 for write, 2 for execute
29
+ * @mmu_idx: MMU index indicating required translation regime
30
+ * @is_secure: security state for the access
31
+ * @result: set on translation success.
32
+ * @fi: set to fault info if the translation fails
33
+ *
31
+ *
34
+ * Find the physical address corresponding to the given virtual address,
32
+ * Should be called only once before using guest debug capabilities.
35
+ * by doing a translation table walk on MMU based systems or using the
36
+ * MPU state on MPU based systems.
37
+ *
38
+ * Returns false if the translation was successful. Otherwise, phys_ptr, attrs,
39
+ * prot and page_size may not be filled in, and the populated fsr value provides
40
+ * information on why the translation aborted, in the format of a
41
+ * DFSR/IFSR fault register, with the following caveats:
42
+ * * we honour the short vs long DFSR format differences.
43
+ * * the WnR bit is never set (the caller must do this).
44
+ * * for PSMAv5 based systems we don't bother to return a full FSR format
45
+ * value.
46
+ */
33
+ */
47
+bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
34
+void kvm_arm_init_debug(KVMState *s);
48
+ MMUAccessType access_type,
49
+ ARMMMUIdx mmu_idx, bool is_secure,
50
+ GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
51
+ __attribute__((nonnull));
52
+
35
+
53
+/**
36
/**
54
+ * get_phys_addr: get the physical address for a virtual address
37
* kvm_arm_vcpu_init:
55
+ * @env: CPUARMState
38
* @cs: CPUState
56
+ * @address: virtual address to get physical address for
39
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
57
+ * @access_type: 0 for read, 1 for write, 2 for execute
58
+ * @mmu_idx: MMU index indicating required translation regime
59
+ * @result: set on translation success.
60
+ * @fi: set to fault info if the translation fails
61
+ *
62
+ * Similarly, but use the security regime of @mmu_idx.
63
+ */
64
bool get_phys_addr(CPUARMState *env, target_ulong address,
65
MMUAccessType access_type, ARMMMUIdx mmu_idx,
66
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
67
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
68
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
69
--- a/target/arm/ptw.c
41
--- a/target/arm/kvm.c
70
+++ b/target/arm/ptw.c
42
+++ b/target/arm/kvm.c
71
@@ -XXX,XX +XXX,XX @@ static ARMCacheAttrs combine_cacheattrs(CPUARMState *env,
43
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init(MachineState *ms, KVMState *s)
44
}
45
}
46
47
+ kvm_arm_init_debug(s);
48
+
72
return ret;
49
return ret;
73
}
50
}
74
51
52
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/kvm64.c
55
+++ b/target/arm/kvm64.c
56
@@ -XXX,XX +XXX,XX @@ GArray *hw_breakpoints, *hw_watchpoints;
57
#define get_hw_bp(i) (&g_array_index(hw_breakpoints, HWBreakpoint, i))
58
#define get_hw_wp(i) (&g_array_index(hw_watchpoints, HWWatchpoint, i))
59
75
-/**
60
-/**
76
- * get_phys_addr - get the physical address for this virtual address
61
- * kvm_arm_init_debug() - check for guest debug capabilities
62
- * @cs: CPUState
77
- *
63
- *
78
- * Find the physical address corresponding to the given virtual address,
64
- * kvm_check_extension returns the number of debug registers we have
79
- * by doing a translation table walk on MMU based systems or using the
65
- * or 0 if we have none.
80
- * MPU state on MPU based systems.
81
- *
66
- *
82
- * Returns false if the translation was successful. Otherwise, phys_ptr, attrs,
83
- * prot and page_size may not be filled in, and the populated fsr value provides
84
- * information on why the translation aborted, in the format of a
85
- * DFSR/IFSR fault register, with the following caveats:
86
- * * we honour the short vs long DFSR format differences.
87
- * * the WnR bit is never set (the caller must do this).
88
- * * for PSMAv5 based systems we don't bother to return a full FSR format
89
- * value.
90
- *
91
- * @env: CPUARMState
92
- * @address: virtual address to get physical address for
93
- * @access_type: 0 for read, 1 for write, 2 for execute
94
- * @mmu_idx: MMU index indicating required translation regime
95
- * @result: set on translation success.
96
- * @fi: set to fault info if the translation fails
97
- */
67
- */
98
-bool get_phys_addr(CPUARMState *env, target_ulong address,
68
-static void kvm_arm_init_debug(CPUState *cs)
99
- MMUAccessType access_type, ARMMMUIdx mmu_idx,
69
+void kvm_arm_init_debug(KVMState *s)
100
- GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
101
+bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
102
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
103
+ bool is_secure, GetPhysAddrResult *result,
104
+ ARMMMUFaultInfo *fi)
105
{
70
{
106
ARMMMUIdx s1_mmu_idx = stage_1_mmu_idx(mmu_idx);
71
- have_guest_debug = kvm_check_extension(cs->kvm_state,
107
- bool is_secure = regime_is_secure(env, mmu_idx);
72
+ have_guest_debug = kvm_check_extension(s,
108
73
KVM_CAP_SET_GUEST_DEBUG);
109
if (mmu_idx != s1_mmu_idx) {
74
110
/*
75
- max_hw_wps = kvm_check_extension(cs->kvm_state, KVM_CAP_GUEST_DEBUG_HW_WPS);
111
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
76
+ max_hw_wps = kvm_check_extension(s, KVM_CAP_GUEST_DEBUG_HW_WPS);
112
ARMMMUIdx s2_mmu_idx;
77
hw_watchpoints = g_array_sized_new(true, true,
113
bool is_el0;
78
sizeof(HWWatchpoint), max_hw_wps);
114
79
115
- ret = get_phys_addr(env, address, access_type, s1_mmu_idx,
80
- max_hw_bps = kvm_check_extension(cs->kvm_state, KVM_CAP_GUEST_DEBUG_HW_BPS);
116
- result, fi);
81
+ max_hw_bps = kvm_check_extension(s, KVM_CAP_GUEST_DEBUG_HW_BPS);
117
+ ret = get_phys_addr_with_secure(env, address, access_type,
82
hw_breakpoints = g_array_sized_new(true, true,
118
+ s1_mmu_idx, is_secure, result, fi);
83
sizeof(HWBreakpoint), max_hw_bps);
119
84
return;
120
/* If S1 fails or S2 is disabled, return early. */
85
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
121
if (ret || regime_translation_disabled(env, ARMMMUIdx_Stage2,
122
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
123
}
86
}
124
}
87
cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
125
88
126
+bool get_phys_addr(CPUARMState *env, target_ulong address,
89
- kvm_arm_init_debug(cs);
127
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
90
-
128
+ GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
91
/* Check whether user space can specify guest syndrome value */
129
+{
92
kvm_arm_init_serror_injection(cs);
130
+ return get_phys_addr_with_secure(env, address, access_type, mmu_idx,
93
131
+ regime_is_secure(env, mmu_idx),
132
+ result, fi);
133
+}
134
+
135
hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
136
MemTxAttrs *attrs)
137
{
138
--
94
--
139
2.25.1
95
2.34.1
96
97
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
We already pass merge_syn_data_abort() two fields from the
2
ARMMMUFaultInfo struct, and we're about to want to use a third field.
3
Refactor to just pass a pointer to the fault info.
2
4
3
Remove the use of regime_is_secure from regime_translation_disabled,
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
using the new parameter instead.
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20230331145045.2584941-2-peter.maydell@linaro.org
9
---
10
target/arm/tcg/tlb_helper.c | 15 +++++++--------
11
1 file changed, 7 insertions(+), 8 deletions(-)
5
12
6
This fixes a bug in S1_ptw_translate and get_phys_addr where we had
13
diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c
7
passed ARMMMUIdx_Stage2 and not ARMMMUIdx_Stage2_S to determine if
8
Stage2 is disabled, affecting FEAT_SEL2.
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20221001162318.153420-5-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
target/arm/ptw.c | 20 +++++++++++---------
17
1 file changed, 11 insertions(+), 9 deletions(-)
18
19
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
20
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/ptw.c
15
--- a/target/arm/tcg/tlb_helper.c
22
+++ b/target/arm/ptw.c
16
+++ b/target/arm/tcg/tlb_helper.c
23
@@ -XXX,XX +XXX,XX @@ static uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx, int ttbrn)
17
@@ -XXX,XX +XXX,XX @@ bool arm_s1_regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx)
24
}
18
}
25
19
26
/* Return true if the specified stage of address translation is disabled */
20
static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
27
-static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx)
21
+ ARMMMUFaultInfo *fi,
28
+static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
22
unsigned int target_el,
29
+ bool is_secure)
23
- bool same_el, bool ea,
24
- bool s1ptw, bool is_write,
25
+ bool same_el, bool is_write,
26
int fsc)
30
{
27
{
31
uint64_t hcr_el2;
28
uint32_t syn;
32
29
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
33
if (arm_feature(env, ARM_FEATURE_M)) {
30
* ISS encoding for an exception from a Data Abort, the
34
- switch (env->v7m.mpu_ctrl[regime_is_secure(env, mmu_idx)] &
31
* ISV field.
35
+ switch (env->v7m.mpu_ctrl[is_secure] &
32
*/
36
(R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK)) {
33
- if (!(template_syn & ARM_EL_ISV) || target_el != 2 || s1ptw) {
37
case R_V7M_MPU_CTRL_ENABLE_MASK:
34
+ if (!(template_syn & ARM_EL_ISV) || target_el != 2 || fi->s1ptw) {
38
/* Enabled, but not for HardFault and NMI */
35
syn = syn_data_abort_no_iss(same_el, 0,
39
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx)
36
- ea, 0, s1ptw, is_write, fsc);
40
37
+ fi->ea, 0, fi->s1ptw, is_write, fsc);
41
if (hcr_el2 & HCR_TGE) {
38
} else {
42
/* TGE means that NS EL0/1 act as if SCTLR_EL1.M is zero */
43
- if (!regime_is_secure(env, mmu_idx) && regime_el(env, mmu_idx) == 1) {
44
+ if (!is_secure && regime_el(env, mmu_idx) == 1) {
45
return true;
46
}
47
}
48
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
49
ARMMMUIdx s2_mmu_idx = *is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
50
51
if (arm_mmu_idx_is_stage1_of_2(mmu_idx) &&
52
- !regime_translation_disabled(env, s2_mmu_idx)) {
53
+ !regime_translation_disabled(env, s2_mmu_idx, *is_secure)) {
54
GetPhysAddrResult s2 = {};
55
int ret;
56
57
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
58
uint32_t base;
59
bool is_user = regime_is_user(env, mmu_idx);
60
61
- if (regime_translation_disabled(env, mmu_idx)) {
62
+ if (regime_translation_disabled(env, mmu_idx, is_secure)) {
63
/* MPU disabled. */
64
result->phys = address;
65
result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
66
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
67
result->page_size = TARGET_PAGE_SIZE;
68
result->prot = 0;
69
70
- if (regime_translation_disabled(env, mmu_idx) ||
71
+ if (regime_translation_disabled(env, mmu_idx, secure) ||
72
m_is_ppb_region(env, address)) {
73
/*
39
/*
74
* MPU disabled or M profile PPB access: use default memory map.
40
* Fields: IL, ISV, SAS, SSE, SRT, SF and AR come from the template
75
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
41
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
76
* are done in arm_v7m_load_vector(), which always does a direct
42
*/
77
* read using address_space_ldl(), rather than going via this function.
43
syn = syn_data_abort_with_iss(same_el,
78
*/
44
0, 0, 0, 0, 0,
79
- if (regime_translation_disabled(env, mmu_idx)) { /* MPU disabled */
45
- ea, 0, s1ptw, is_write, fsc,
80
+ if (regime_translation_disabled(env, mmu_idx, secure)) { /* MPU disabled */
46
+ fi->ea, 0, fi->s1ptw, is_write, fsc,
81
hit = true;
47
true);
82
} else if (m_is_ppb_region(env, address)) {
48
/* Merge the runtime syndrome with the template syndrome. */
83
hit = true;
49
syn |= template_syn;
84
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
50
@@ -XXX,XX +XXX,XX @@ void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
85
result, fi);
51
syn = syn_insn_abort(same_el, fi->ea, fi->s1ptw, fsc);
86
52
exc = EXCP_PREFETCH_ABORT;
87
/* If S1 fails or S2 is disabled, return early. */
53
} else {
88
- if (ret || regime_translation_disabled(env, ARMMMUIdx_Stage2)) {
54
- syn = merge_syn_data_abort(env->exception.syndrome, target_el,
89
+ if (ret || regime_translation_disabled(env, ARMMMUIdx_Stage2,
55
- same_el, fi->ea, fi->s1ptw,
90
+ is_secure)) {
56
- access_type == MMU_DATA_STORE,
91
return ret;
57
+ syn = merge_syn_data_abort(env->exception.syndrome, fi, target_el,
92
}
58
+ same_el, access_type == MMU_DATA_STORE,
93
59
fsc);
94
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
60
if (access_type == MMU_DATA_STORE
95
61
&& arm_feature(env, ARM_FEATURE_V6)) {
96
/* Definitely a real MMU, not an MPU */
97
98
- if (regime_translation_disabled(env, mmu_idx)) {
99
+ if (regime_translation_disabled(env, mmu_idx, is_secure)) {
100
uint64_t hcr;
101
uint8_t memattr;
102
103
--
62
--
104
2.25.1
63
2.34.1
105
64
106
65
diff view generated by jsdifflib
1
Arm CPUs support some subset of the granule (page) sizes 4K, 16K and
1
The syndrome value reported to ESR_EL2 should only contain the
2
64K. The guest selects the one it wants using bits in the TCR_ELx
2
detailed instruction syndrome information when the fault has been
3
registers. If it tries to program these registers with a value that
3
caused by a stage 2 abort, not when the fault was a stage 1 abort
4
is either reserved or which requests a size that the CPU does not
4
(i.e. caused by execution at EL2). We were getting this wrong and
5
implement, the architecture requires that the CPU behaves as if the
5
reporting the detailed ISV information all the time.
6
field was programmed to some size that has been implemented.
7
Currently we don't implement this, and instead let the guest use any
8
granule size, even if the CPU ID register fields say it isn't
9
present.
10
6
11
Make aa64_va_parameters() check against the supported granule size
7
Fix the bug by checking fi->stage2. Add a TODO comment noting the
12
and force use of a different one if it is not implemented.
8
cases where we'll have to come back and revisit this when we
9
implement FEAT_LS64 and friends.
13
10
14
(A subsequent commit will make ARMVAParameters use the new enum
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
rather than the current pair of using16k/using64k bools.)
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20230331145045.2584941-3-peter.maydell@linaro.org
14
---
15
target/arm/tcg/tlb_helper.c | 13 ++++++++++---
16
1 file changed, 10 insertions(+), 3 deletions(-)
16
17
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Message-id: 20221003162315.2833797-2-peter.maydell@linaro.org
20
---
21
target/arm/cpu.h | 33 +++++++++++++
22
target/arm/internals.h | 9 ++++
23
target/arm/helper.c | 102 +++++++++++++++++++++++++++++++++++++----
24
3 files changed, 136 insertions(+), 8 deletions(-)
25
26
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
27
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/cpu.h
20
--- a/target/arm/tcg/tlb_helper.c
29
+++ b/target/arm/cpu.h
21
+++ b/target/arm/tcg/tlb_helper.c
30
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_tgran16_2_lpa2(const ARMISARegisters *id)
22
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
31
return t >= 3 || (t == 0 && isar_feature_aa64_tgran16_lpa2(id));
23
uint32_t syn;
32
}
24
33
25
/*
34
+static inline bool isar_feature_aa64_tgran4(const ARMISARegisters *id)
26
- * ISV is only set for data aborts routed to EL2 and
35
+{
27
- * never for stage-1 page table walks faulting on stage 2.
36
+ return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 0;
28
+ * ISV is only set for stage-2 data aborts routed to EL2 and
37
+}
29
+ * never for stage-1 page table walks faulting on stage 2
38
+
30
+ * or for stage-1 faults.
39
+static inline bool isar_feature_aa64_tgran16(const ARMISARegisters *id)
31
*
40
+{
32
* Furthermore, ISV is only set for certain kinds of load/stores.
41
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 1;
33
* If the template syndrome does not have ISV set, we should leave
42
+}
34
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
43
+
35
* See ARMv8 specs, D7-1974:
44
+static inline bool isar_feature_aa64_tgran64(const ARMISARegisters *id)
36
* ISS encoding for an exception from a Data Abort, the
45
+{
37
* ISV field.
46
+ return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64) >= 0;
38
+ *
47
+}
39
+ * TODO: FEAT_LS64/FEAT_LS64_V/FEAT_SL64_ACCDATA: Translation,
48
+
40
+ * Access Flag, and Permission faults caused by LD64B, ST64B,
49
+static inline bool isar_feature_aa64_tgran4_2(const ARMISARegisters *id)
41
+ * ST64BV, or ST64BV0 insns report syndrome info even for stage-1
50
+{
42
+ * faults and regardless of the target EL.
51
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2);
43
*/
52
+ return t >= 2 || (t == 0 && isar_feature_aa64_tgran4(id));
44
- if (!(template_syn & ARM_EL_ISV) || target_el != 2 || fi->s1ptw) {
53
+}
45
+ if (!(template_syn & ARM_EL_ISV) || target_el != 2
54
+
46
+ || fi->s1ptw || !fi->stage2) {
55
+static inline bool isar_feature_aa64_tgran16_2(const ARMISARegisters *id)
47
syn = syn_data_abort_no_iss(same_el, 0,
56
+{
48
fi->ea, 0, fi->s1ptw, is_write, fsc);
57
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2);
58
+ return t >= 2 || (t == 0 && isar_feature_aa64_tgran16(id));
59
+}
60
+
61
+static inline bool isar_feature_aa64_tgran64_2(const ARMISARegisters *id)
62
+{
63
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64_2);
64
+ return t >= 2 || (t == 0 && isar_feature_aa64_tgran64(id));
65
+}
66
+
67
static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
68
{
69
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
70
diff --git a/target/arm/internals.h b/target/arm/internals.h
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/arm/internals.h
73
+++ b/target/arm/internals.h
74
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
75
return valid;
76
}
77
78
+/* Granule size (i.e. page size) */
79
+typedef enum ARMGranuleSize {
80
+ /* Same order as TG0 encoding */
81
+ Gran4K,
82
+ Gran64K,
83
+ Gran16K,
84
+ GranInvalid,
85
+} ARMGranuleSize;
86
+
87
/*
88
* Parameters of a given virtual address, as extracted from the
89
* translation control register (TCR) for a given regime.
90
diff --git a/target/arm/helper.c b/target/arm/helper.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/helper.c
93
+++ b/target/arm/helper.c
94
@@ -XXX,XX +XXX,XX @@ static int aa64_va_parameter_tcma(uint64_t tcr, ARMMMUIdx mmu_idx)
95
}
96
}
97
98
+static ARMGranuleSize tg0_to_gran_size(int tg)
99
+{
100
+ switch (tg) {
101
+ case 0:
102
+ return Gran4K;
103
+ case 1:
104
+ return Gran64K;
105
+ case 2:
106
+ return Gran16K;
107
+ default:
108
+ return GranInvalid;
109
+ }
110
+}
111
+
112
+static ARMGranuleSize tg1_to_gran_size(int tg)
113
+{
114
+ switch (tg) {
115
+ case 1:
116
+ return Gran16K;
117
+ case 2:
118
+ return Gran4K;
119
+ case 3:
120
+ return Gran64K;
121
+ default:
122
+ return GranInvalid;
123
+ }
124
+}
125
+
126
+static inline bool have4k(ARMCPU *cpu, bool stage2)
127
+{
128
+ return stage2 ? cpu_isar_feature(aa64_tgran4_2, cpu)
129
+ : cpu_isar_feature(aa64_tgran4, cpu);
130
+}
131
+
132
+static inline bool have16k(ARMCPU *cpu, bool stage2)
133
+{
134
+ return stage2 ? cpu_isar_feature(aa64_tgran16_2, cpu)
135
+ : cpu_isar_feature(aa64_tgran16, cpu);
136
+}
137
+
138
+static inline bool have64k(ARMCPU *cpu, bool stage2)
139
+{
140
+ return stage2 ? cpu_isar_feature(aa64_tgran64_2, cpu)
141
+ : cpu_isar_feature(aa64_tgran64, cpu);
142
+}
143
+
144
+static ARMGranuleSize sanitize_gran_size(ARMCPU *cpu, ARMGranuleSize gran,
145
+ bool stage2)
146
+{
147
+ switch (gran) {
148
+ case Gran4K:
149
+ if (have4k(cpu, stage2)) {
150
+ return gran;
151
+ }
152
+ break;
153
+ case Gran16K:
154
+ if (have16k(cpu, stage2)) {
155
+ return gran;
156
+ }
157
+ break;
158
+ case Gran64K:
159
+ if (have64k(cpu, stage2)) {
160
+ return gran;
161
+ }
162
+ break;
163
+ case GranInvalid:
164
+ break;
165
+ }
166
+ /*
167
+ * If the guest selects a granule size that isn't implemented,
168
+ * the architecture requires that we behave as if it selected one
169
+ * that is (with an IMPDEF choice of which one to pick). We choose
170
+ * to implement the smallest supported granule size.
171
+ */
172
+ if (have4k(cpu, stage2)) {
173
+ return Gran4K;
174
+ }
175
+ if (have16k(cpu, stage2)) {
176
+ return Gran16K;
177
+ }
178
+ assert(have64k(cpu, stage2));
179
+ return Gran64K;
180
+}
181
+
182
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
183
ARMMMUIdx mmu_idx, bool data)
184
{
185
uint64_t tcr = regime_tcr(env, mmu_idx);
186
bool epd, hpd, using16k, using64k, tsz_oob, ds;
187
int select, tsz, tbi, max_tsz, min_tsz, ps, sh;
188
+ ARMGranuleSize gran;
189
ARMCPU *cpu = env_archcpu(env);
190
+ bool stage2 = mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S;
191
192
if (!regime_has_2_ranges(mmu_idx)) {
193
select = 0;
194
tsz = extract32(tcr, 0, 6);
195
- using64k = extract32(tcr, 14, 1);
196
- using16k = extract32(tcr, 15, 1);
197
- if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
198
+ gran = tg0_to_gran_size(extract32(tcr, 14, 2));
199
+ if (stage2) {
200
/* VTCR_EL2 */
201
hpd = false;
202
} else {
203
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
204
select = extract64(va, 55, 1);
205
if (!select) {
206
tsz = extract32(tcr, 0, 6);
207
+ gran = tg0_to_gran_size(extract32(tcr, 14, 2));
208
epd = extract32(tcr, 7, 1);
209
sh = extract32(tcr, 12, 2);
210
- using64k = extract32(tcr, 14, 1);
211
- using16k = extract32(tcr, 15, 1);
212
hpd = extract64(tcr, 41, 1);
213
} else {
214
- int tg = extract32(tcr, 30, 2);
215
- using16k = tg == 1;
216
- using64k = tg == 3;
217
tsz = extract32(tcr, 16, 6);
218
+ gran = tg1_to_gran_size(extract32(tcr, 30, 2));
219
epd = extract32(tcr, 23, 1);
220
sh = extract32(tcr, 28, 2);
221
hpd = extract64(tcr, 42, 1);
222
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
223
ds = extract64(tcr, 59, 1);
224
}
225
226
+ gran = sanitize_gran_size(cpu, gran, stage2);
227
+ using64k = gran == Gran64K;
228
+ using16k = gran == Gran16K;
229
+
230
if (cpu_isar_feature(aa64_st, cpu)) {
231
max_tsz = 48 - using64k;
232
} else {
49
} else {
233
--
50
--
234
2.25.1
51
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
FEAT_PAN3 adds an EPAN bit to SCTLR_EL1 and SCTLR_EL2, which allows
2
the PAN bit to make memory non-privileged-read/write if it is
3
user-executable as well as if it is user-read/write.
2
4
3
For a-profile aarch64, which does not bank system registers, it takes
5
Implement this feature and enable it in the AArch64 'max' CPU.
4
quite a lot of code to switch between security states. In the process,
5
registers such as TCR_EL{1,2} must be swapped, which in itself requires
6
the flushing of softmmu tlbs. Therefore it doesn't buy us anything to
7
separate tlbs by security state.
8
6
9
Retain the distinction between Stage2 and Stage2_S.
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230331145045.2584941-4-peter.maydell@linaro.org
10
---
11
docs/system/arm/emulation.rst | 1 +
12
target/arm/cpu.h | 5 +++++
13
target/arm/cpu64.c | 2 +-
14
target/arm/ptw.c | 14 +++++++++++++-
15
4 files changed, 20 insertions(+), 2 deletions(-)
10
16
11
This will be important as we implement FEAT_RME, and do not wish to
17
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
12
add a third set of mmu indexes for Realm state.
13
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20221001162318.153420-11-richard.henderson@linaro.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
target/arm/cpu-param.h | 2 +-
20
target/arm/cpu.h | 72 +++++++------------
21
target/arm/internals.h | 31 +-------
22
target/arm/helper.c | 144 +++++++++++++------------------------
23
target/arm/ptw.c | 25 ++-----
24
target/arm/translate-a64.c | 8 ---
25
target/arm/translate.c | 6 +-
26
7 files changed, 85 insertions(+), 203 deletions(-)
27
28
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
29
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu-param.h
19
--- a/docs/system/arm/emulation.rst
31
+++ b/target/arm/cpu-param.h
20
+++ b/docs/system/arm/emulation.rst
32
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
33
# define TARGET_PAGE_BITS_MIN 10
22
- FEAT_MTE3 (MTE Asymmetric Fault Handling)
34
#endif
23
- FEAT_PAN (Privileged access never)
35
24
- FEAT_PAN2 (AT S1E1R and AT S1E1W instruction variants affected by PSTATE.PAN)
36
-#define NB_MMU_MODES 15
25
+- FEAT_PAN3 (Support for SCTLR_ELx.EPAN)
37
+#define NB_MMU_MODES 8
26
- FEAT_PAuth (Pointer authentication)
38
27
- FEAT_PMULL (PMULL, PMULL2 instructions)
39
#endif
28
- FEAT_PMUv3p1 (PMU Extensions v3.1)
40
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
29
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
41
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/cpu.h
31
--- a/target/arm/cpu.h
43
+++ b/target/arm/cpu.h
32
+++ b/target/arm/cpu.h
44
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
33
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ats1e1(const ARMISARegisters *id)
45
* table over and over.
34
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 2;
46
* 6. we need separate EL1/EL2 mmu_idx for handling the Privileged Access
35
}
47
* Never (PAN) bit within PSTATE.
36
48
+ * 7. we fold together the secure and non-secure regimes for A-profile,
37
+static inline bool isar_feature_aa64_pan3(const ARMISARegisters *id)
49
+ * because there are no banked system registers for aarch64, so the
38
+{
50
+ * process of switching between secure and non-secure is
39
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 3;
51
+ * already heavyweight.
40
+}
52
*
41
+
53
* This gives us the following list of cases:
42
static inline bool isar_feature_aa64_hcx(const ARMISARegisters *id)
54
*
43
{
55
- * NS EL0 EL1&0 stage 1+2 (aka NS PL0)
44
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HCX) != 0;
56
- * NS EL1 EL1&0 stage 1+2 (aka NS PL1)
45
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
57
- * NS EL1 EL1&0 stage 1+2 +PAN
58
- * NS EL0 EL2&0
59
- * NS EL2 EL2&0
60
- * NS EL2 EL2&0 +PAN
61
- * NS EL2 (aka NS PL2)
62
- * S EL0 EL1&0 (aka S PL0)
63
- * S EL1 EL1&0 (not used if EL3 is 32 bit)
64
- * S EL1 EL1&0 +PAN
65
- * S EL3 (aka S PL1)
66
+ * EL0 EL1&0 stage 1+2 (aka NS PL0)
67
+ * EL1 EL1&0 stage 1+2 (aka NS PL1)
68
+ * EL1 EL1&0 stage 1+2 +PAN
69
+ * EL0 EL2&0
70
+ * EL2 EL2&0
71
+ * EL2 EL2&0 +PAN
72
+ * EL2 (aka NS PL2)
73
+ * EL3 (aka S PL1)
74
*
75
- * for a total of 11 different mmu_idx.
76
+ * for a total of 8 different mmu_idx.
77
*
78
* R profile CPUs have an MPU, but can use the same set of MMU indexes
79
- * as A profile. They only need to distinguish NS EL0 and NS EL1 (and
80
- * NS EL2 if we ever model a Cortex-R52).
81
+ * as A profile. They only need to distinguish EL0 and EL1 (and
82
+ * EL2 if we ever model a Cortex-R52).
83
*
84
* M profile CPUs are rather different as they do not have a true MMU.
85
* They have the following different MMU indexes:
86
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
87
#define ARM_MMU_IDX_NOTLB 0x20 /* does not have a TLB */
88
#define ARM_MMU_IDX_M 0x40 /* M profile */
89
90
-/* Meanings of the bits for A profile mmu idx values */
91
-#define ARM_MMU_IDX_A_NS 0x8
92
-
93
/* Meanings of the bits for M profile mmu idx values */
94
#define ARM_MMU_IDX_M_PRIV 0x1
95
#define ARM_MMU_IDX_M_NEGPRI 0x2
96
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
97
/*
98
* A-profile.
99
*/
100
- ARMMMUIdx_SE10_0 = 0 | ARM_MMU_IDX_A,
101
- ARMMMUIdx_SE20_0 = 1 | ARM_MMU_IDX_A,
102
- ARMMMUIdx_SE10_1 = 2 | ARM_MMU_IDX_A,
103
- ARMMMUIdx_SE20_2 = 3 | ARM_MMU_IDX_A,
104
- ARMMMUIdx_SE10_1_PAN = 4 | ARM_MMU_IDX_A,
105
- ARMMMUIdx_SE20_2_PAN = 5 | ARM_MMU_IDX_A,
106
- ARMMMUIdx_SE2 = 6 | ARM_MMU_IDX_A,
107
- ARMMMUIdx_SE3 = 7 | ARM_MMU_IDX_A,
108
-
109
- ARMMMUIdx_E10_0 = ARMMMUIdx_SE10_0 | ARM_MMU_IDX_A_NS,
110
- ARMMMUIdx_E20_0 = ARMMMUIdx_SE20_0 | ARM_MMU_IDX_A_NS,
111
- ARMMMUIdx_E10_1 = ARMMMUIdx_SE10_1 | ARM_MMU_IDX_A_NS,
112
- ARMMMUIdx_E20_2 = ARMMMUIdx_SE20_2 | ARM_MMU_IDX_A_NS,
113
- ARMMMUIdx_E10_1_PAN = ARMMMUIdx_SE10_1_PAN | ARM_MMU_IDX_A_NS,
114
- ARMMMUIdx_E20_2_PAN = ARMMMUIdx_SE20_2_PAN | ARM_MMU_IDX_A_NS,
115
- ARMMMUIdx_E2 = ARMMMUIdx_SE2 | ARM_MMU_IDX_A_NS,
116
+ ARMMMUIdx_E10_0 = 0 | ARM_MMU_IDX_A,
117
+ ARMMMUIdx_E20_0 = 1 | ARM_MMU_IDX_A,
118
+ ARMMMUIdx_E10_1 = 2 | ARM_MMU_IDX_A,
119
+ ARMMMUIdx_E20_2 = 3 | ARM_MMU_IDX_A,
120
+ ARMMMUIdx_E10_1_PAN = 4 | ARM_MMU_IDX_A,
121
+ ARMMMUIdx_E20_2_PAN = 5 | ARM_MMU_IDX_A,
122
+ ARMMMUIdx_E2 = 6 | ARM_MMU_IDX_A,
123
+ ARMMMUIdx_E3 = 7 | ARM_MMU_IDX_A,
124
125
/*
126
* These are not allocated TLBs and are used only for AT system
127
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
128
ARMMMUIdx_Stage1_E0 = 0 | ARM_MMU_IDX_NOTLB,
129
ARMMMUIdx_Stage1_E1 = 1 | ARM_MMU_IDX_NOTLB,
130
ARMMMUIdx_Stage1_E1_PAN = 2 | ARM_MMU_IDX_NOTLB,
131
- ARMMMUIdx_Stage1_SE0 = 3 | ARM_MMU_IDX_NOTLB,
132
- ARMMMUIdx_Stage1_SE1 = 4 | ARM_MMU_IDX_NOTLB,
133
- ARMMMUIdx_Stage1_SE1_PAN = 5 | ARM_MMU_IDX_NOTLB,
134
/*
135
* Not allocated a TLB: used only for second stage of an S12 page
136
* table walk, or for descriptor loads during first stage of an S1
137
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
138
* then various TLB flush insns which currently are no-ops or flush
139
* only stage 1 MMU indexes will need to change to flush stage 2.
140
*/
141
- ARMMMUIdx_Stage2 = 6 | ARM_MMU_IDX_NOTLB,
142
- ARMMMUIdx_Stage2_S = 7 | ARM_MMU_IDX_NOTLB,
143
+ ARMMMUIdx_Stage2 = 3 | ARM_MMU_IDX_NOTLB,
144
+ ARMMMUIdx_Stage2_S = 4 | ARM_MMU_IDX_NOTLB,
145
146
/*
147
* M-profile.
148
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
149
TO_CORE_BIT(E2),
150
TO_CORE_BIT(E20_2),
151
TO_CORE_BIT(E20_2_PAN),
152
- TO_CORE_BIT(SE10_0),
153
- TO_CORE_BIT(SE20_0),
154
- TO_CORE_BIT(SE10_1),
155
- TO_CORE_BIT(SE20_2),
156
- TO_CORE_BIT(SE10_1_PAN),
157
- TO_CORE_BIT(SE20_2_PAN),
158
- TO_CORE_BIT(SE2),
159
- TO_CORE_BIT(SE3),
160
+ TO_CORE_BIT(E3),
161
162
TO_CORE_BIT(MUser),
163
TO_CORE_BIT(MPriv),
164
diff --git a/target/arm/internals.h b/target/arm/internals.h
165
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
166
--- a/target/arm/internals.h
47
--- a/target/arm/cpu64.c
167
+++ b/target/arm/internals.h
48
+++ b/target/arm/cpu64.c
168
@@ -XXX,XX +XXX,XX @@ static inline bool regime_has_2_ranges(ARMMMUIdx mmu_idx)
49
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
169
case ARMMMUIdx_Stage1_E0:
50
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); /* FEAT_VHE */
170
case ARMMMUIdx_Stage1_E1:
51
t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* FEAT_HPDS */
171
case ARMMMUIdx_Stage1_E1_PAN:
52
t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1); /* FEAT_LOR */
172
- case ARMMMUIdx_Stage1_SE0:
53
- t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* FEAT_PAN2 */
173
- case ARMMMUIdx_Stage1_SE1:
54
+ t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 3); /* FEAT_PAN3 */
174
- case ARMMMUIdx_Stage1_SE1_PAN:
55
t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* FEAT_XNX */
175
case ARMMMUIdx_E10_0:
56
t = FIELD_DP64(t, ID_AA64MMFR1, ETS, 1); /* FEAT_ETS */
176
case ARMMMUIdx_E10_1:
57
t = FIELD_DP64(t, ID_AA64MMFR1, HCX, 1); /* FEAT_HCX */
177
case ARMMMUIdx_E10_1_PAN:
178
case ARMMMUIdx_E20_0:
179
case ARMMMUIdx_E20_2:
180
case ARMMMUIdx_E20_2_PAN:
181
- case ARMMMUIdx_SE10_0:
182
- case ARMMMUIdx_SE10_1:
183
- case ARMMMUIdx_SE10_1_PAN:
184
- case ARMMMUIdx_SE20_0:
185
- case ARMMMUIdx_SE20_2:
186
- case ARMMMUIdx_SE20_2_PAN:
187
return true;
188
default:
189
return false;
190
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx)
191
{
192
switch (mmu_idx) {
193
case ARMMMUIdx_Stage1_E1_PAN:
194
- case ARMMMUIdx_Stage1_SE1_PAN:
195
case ARMMMUIdx_E10_1_PAN:
196
case ARMMMUIdx_E20_2_PAN:
197
- case ARMMMUIdx_SE10_1_PAN:
198
- case ARMMMUIdx_SE20_2_PAN:
199
return true;
200
default:
201
return false;
202
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx)
203
static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
204
{
205
switch (mmu_idx) {
206
- case ARMMMUIdx_SE20_0:
207
- case ARMMMUIdx_SE20_2:
208
- case ARMMMUIdx_SE20_2_PAN:
209
case ARMMMUIdx_E20_0:
210
case ARMMMUIdx_E20_2:
211
case ARMMMUIdx_E20_2_PAN:
212
case ARMMMUIdx_Stage2:
213
case ARMMMUIdx_Stage2_S:
214
- case ARMMMUIdx_SE2:
215
case ARMMMUIdx_E2:
216
return 2;
217
- case ARMMMUIdx_SE3:
218
+ case ARMMMUIdx_E3:
219
return 3;
220
- case ARMMMUIdx_SE10_0:
221
- case ARMMMUIdx_Stage1_SE0:
222
- return arm_el_is_aa64(env, 3) ? 1 : 3;
223
- case ARMMMUIdx_SE10_1:
224
- case ARMMMUIdx_SE10_1_PAN:
225
+ case ARMMMUIdx_E10_0:
226
case ARMMMUIdx_Stage1_E0:
227
+ return arm_el_is_aa64(env, 3) || !arm_is_secure_below_el3(env) ? 1 : 3;
228
case ARMMMUIdx_Stage1_E1:
229
case ARMMMUIdx_Stage1_E1_PAN:
230
- case ARMMMUIdx_Stage1_SE1:
231
- case ARMMMUIdx_Stage1_SE1_PAN:
232
- case ARMMMUIdx_E10_0:
233
case ARMMMUIdx_E10_1:
234
case ARMMMUIdx_E10_1_PAN:
235
case ARMMMUIdx_MPrivNegPri:
236
@@ -XXX,XX +XXX,XX @@ static inline bool arm_mmu_idx_is_stage1_of_2(ARMMMUIdx mmu_idx)
237
case ARMMMUIdx_Stage1_E0:
238
case ARMMMUIdx_Stage1_E1:
239
case ARMMMUIdx_Stage1_E1_PAN:
240
- case ARMMMUIdx_Stage1_SE0:
241
- case ARMMMUIdx_Stage1_SE1:
242
- case ARMMMUIdx_Stage1_SE1_PAN:
243
return true;
244
default:
245
return false;
246
diff --git a/target/arm/helper.c b/target/arm/helper.c
247
index XXXXXXX..XXXXXXX 100644
248
--- a/target/arm/helper.c
249
+++ b/target/arm/helper.c
250
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
251
/* Begin with base v8.0 state. */
252
uint64_t valid_mask = 0x3fff;
253
ARMCPU *cpu = env_archcpu(env);
254
+ uint64_t changed;
255
256
/*
257
* Because SCR_EL3 is the "real" cpreg and SCR is the alias, reset always
258
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
259
260
/* Clear all-context RES0 bits. */
261
value &= valid_mask;
262
- raw_write(env, ri, value);
263
+ changed = env->cp15.scr_el3 ^ value;
264
+ env->cp15.scr_el3 = value;
265
+
266
+ /*
267
+ * If SCR_EL3.NS changes, i.e. arm_is_secure_below_el3, then
268
+ * we must invalidate all TLBs below EL3.
269
+ */
270
+ if (changed & SCR_NS) {
271
+ tlb_flush_by_mmuidx(env_cpu(env), (ARMMMUIdxBit_E10_0 |
272
+ ARMMMUIdxBit_E20_0 |
273
+ ARMMMUIdxBit_E10_1 |
274
+ ARMMMUIdxBit_E20_2 |
275
+ ARMMMUIdxBit_E10_1_PAN |
276
+ ARMMMUIdxBit_E20_2_PAN |
277
+ ARMMMUIdxBit_E2));
278
+ }
279
}
280
281
static void scr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
282
@@ -XXX,XX +XXX,XX @@ static int gt_phys_redir_timeridx(CPUARMState *env)
283
case ARMMMUIdx_E20_0:
284
case ARMMMUIdx_E20_2:
285
case ARMMMUIdx_E20_2_PAN:
286
- case ARMMMUIdx_SE20_0:
287
- case ARMMMUIdx_SE20_2:
288
- case ARMMMUIdx_SE20_2_PAN:
289
return GTIMER_HYP;
290
default:
291
return GTIMER_PHYS;
292
@@ -XXX,XX +XXX,XX @@ static int gt_virt_redir_timeridx(CPUARMState *env)
293
case ARMMMUIdx_E20_0:
294
case ARMMMUIdx_E20_2:
295
case ARMMMUIdx_E20_2_PAN:
296
- case ARMMMUIdx_SE20_0:
297
- case ARMMMUIdx_SE20_2:
298
- case ARMMMUIdx_SE20_2_PAN:
299
return GTIMER_HYPVIRT;
300
default:
301
return GTIMER_VIRT;
302
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
303
/* stage 1 current state PL1: ATS1CPR, ATS1CPW, ATS1CPRP, ATS1CPWP */
304
switch (el) {
305
case 3:
306
- mmu_idx = ARMMMUIdx_SE3;
307
+ mmu_idx = ARMMMUIdx_E3;
308
secure = true;
309
break;
310
case 2:
311
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
312
/* fall through */
313
case 1:
314
if (ri->crm == 9 && (env->uncached_cpsr & CPSR_PAN)) {
315
- mmu_idx = (secure ? ARMMMUIdx_Stage1_SE1_PAN
316
- : ARMMMUIdx_Stage1_E1_PAN);
317
+ mmu_idx = ARMMMUIdx_Stage1_E1_PAN;
318
} else {
319
- mmu_idx = secure ? ARMMMUIdx_Stage1_SE1 : ARMMMUIdx_Stage1_E1;
320
+ mmu_idx = ARMMMUIdx_Stage1_E1;
321
}
322
break;
323
default:
324
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
325
/* stage 1 current state PL0: ATS1CUR, ATS1CUW */
326
switch (el) {
327
case 3:
328
- mmu_idx = ARMMMUIdx_SE10_0;
329
+ mmu_idx = ARMMMUIdx_E10_0;
330
secure = true;
331
break;
332
case 2:
333
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
334
mmu_idx = ARMMMUIdx_Stage1_E0;
335
break;
336
case 1:
337
- mmu_idx = secure ? ARMMMUIdx_Stage1_SE0 : ARMMMUIdx_Stage1_E0;
338
+ mmu_idx = ARMMMUIdx_Stage1_E0;
339
break;
340
default:
341
g_assert_not_reached();
342
@@ -XXX,XX +XXX,XX @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
343
switch (ri->opc1) {
344
case 0: /* AT S1E1R, AT S1E1W, AT S1E1RP, AT S1E1WP */
345
if (ri->crm == 9 && (env->pstate & PSTATE_PAN)) {
346
- mmu_idx = (secure ? ARMMMUIdx_Stage1_SE1_PAN
347
- : ARMMMUIdx_Stage1_E1_PAN);
348
+ mmu_idx = ARMMMUIdx_Stage1_E1_PAN;
349
} else {
350
- mmu_idx = secure ? ARMMMUIdx_Stage1_SE1 : ARMMMUIdx_Stage1_E1;
351
+ mmu_idx = ARMMMUIdx_Stage1_E1;
352
}
353
break;
354
case 4: /* AT S1E2R, AT S1E2W */
355
- mmu_idx = secure ? ARMMMUIdx_SE2 : ARMMMUIdx_E2;
356
+ mmu_idx = ARMMMUIdx_E2;
357
break;
358
case 6: /* AT S1E3R, AT S1E3W */
359
- mmu_idx = ARMMMUIdx_SE3;
360
+ mmu_idx = ARMMMUIdx_E3;
361
secure = true;
362
break;
363
default:
364
@@ -XXX,XX +XXX,XX @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
365
}
366
break;
367
case 2: /* AT S1E0R, AT S1E0W */
368
- mmu_idx = secure ? ARMMMUIdx_Stage1_SE0 : ARMMMUIdx_Stage1_E0;
369
+ mmu_idx = ARMMMUIdx_Stage1_E0;
370
break;
371
case 4: /* AT S12E1R, AT S12E1W */
372
- mmu_idx = secure ? ARMMMUIdx_SE10_1 : ARMMMUIdx_E10_1;
373
+ mmu_idx = ARMMMUIdx_E10_1;
374
break;
375
case 6: /* AT S12E0R, AT S12E0W */
376
- mmu_idx = secure ? ARMMMUIdx_SE10_0 : ARMMMUIdx_E10_0;
377
+ mmu_idx = ARMMMUIdx_E10_0;
378
break;
379
default:
380
g_assert_not_reached();
381
@@ -XXX,XX +XXX,XX @@ static void vmsa_tcr_ttbr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
382
uint16_t mask = ARMMMUIdxBit_E20_2 |
383
ARMMMUIdxBit_E20_2_PAN |
384
ARMMMUIdxBit_E20_0;
385
-
386
- if (arm_is_secure_below_el3(env)) {
387
- mask >>= ARM_MMU_IDX_A_NS;
388
- }
389
-
390
tlb_flush_by_mmuidx(env_cpu(env), mask);
391
}
392
raw_write(env, ri, value);
393
@@ -XXX,XX +XXX,XX @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
394
uint16_t mask = ARMMMUIdxBit_E10_1 |
395
ARMMMUIdxBit_E10_1_PAN |
396
ARMMMUIdxBit_E10_0;
397
-
398
- if (arm_is_secure_below_el3(env)) {
399
- mask >>= ARM_MMU_IDX_A_NS;
400
- }
401
-
402
tlb_flush_by_mmuidx(cs, mask);
403
raw_write(env, ri, value);
404
}
405
@@ -XXX,XX +XXX,XX @@ static int vae1_tlbmask(CPUARMState *env)
406
ARMMMUIdxBit_E10_1_PAN |
407
ARMMMUIdxBit_E10_0;
408
}
409
-
410
- if (arm_is_secure_below_el3(env)) {
411
- mask >>= ARM_MMU_IDX_A_NS;
412
- }
413
-
414
return mask;
415
}
416
417
@@ -XXX,XX +XXX,XX @@ static int vae1_tlbbits(CPUARMState *env, uint64_t addr)
418
mmu_idx = ARMMMUIdx_E10_0;
419
}
420
421
- if (arm_is_secure_below_el3(env)) {
422
- mmu_idx &= ~ARM_MMU_IDX_A_NS;
423
- }
424
-
425
return tlbbits_for_regime(env, mmu_idx, addr);
426
}
427
428
@@ -XXX,XX +XXX,XX @@ static int alle1_tlbmask(CPUARMState *env)
429
* stage 2 translations, whereas most other scopes only invalidate
430
* stage 1 translations.
431
*/
432
- if (arm_is_secure_below_el3(env)) {
433
- return ARMMMUIdxBit_SE10_1 |
434
- ARMMMUIdxBit_SE10_1_PAN |
435
- ARMMMUIdxBit_SE10_0;
436
- } else {
437
- return ARMMMUIdxBit_E10_1 |
438
- ARMMMUIdxBit_E10_1_PAN |
439
- ARMMMUIdxBit_E10_0;
440
- }
441
+ return (ARMMMUIdxBit_E10_1 |
442
+ ARMMMUIdxBit_E10_1_PAN |
443
+ ARMMMUIdxBit_E10_0);
444
}
445
446
static int e2_tlbmask(CPUARMState *env)
447
{
448
- if (arm_is_secure_below_el3(env)) {
449
- return ARMMMUIdxBit_SE20_0 |
450
- ARMMMUIdxBit_SE20_2 |
451
- ARMMMUIdxBit_SE20_2_PAN |
452
- ARMMMUIdxBit_SE2;
453
- } else {
454
- return ARMMMUIdxBit_E20_0 |
455
- ARMMMUIdxBit_E20_2 |
456
- ARMMMUIdxBit_E20_2_PAN |
457
- ARMMMUIdxBit_E2;
458
- }
459
+ return (ARMMMUIdxBit_E20_0 |
460
+ ARMMMUIdxBit_E20_2 |
461
+ ARMMMUIdxBit_E20_2_PAN |
462
+ ARMMMUIdxBit_E2);
463
}
464
465
static void tlbi_aa64_alle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
466
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle3_write(CPUARMState *env, const ARMCPRegInfo *ri,
467
ARMCPU *cpu = env_archcpu(env);
468
CPUState *cs = CPU(cpu);
469
470
- tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_SE3);
471
+ tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_E3);
472
}
473
474
static void tlbi_aa64_alle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
475
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
476
{
477
CPUState *cs = env_cpu(env);
478
479
- tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_SE3);
480
+ tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_E3);
481
}
482
483
static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri,
484
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3_write(CPUARMState *env, const ARMCPRegInfo *ri,
485
CPUState *cs = CPU(cpu);
486
uint64_t pageaddr = sextract64(value << 12, 0, 56);
487
488
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_SE3);
489
+ tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_E3);
490
}
491
492
static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
493
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
494
{
495
CPUState *cs = env_cpu(env);
496
uint64_t pageaddr = sextract64(value << 12, 0, 56);
497
- bool secure = arm_is_secure_below_el3(env);
498
- int mask = secure ? ARMMMUIdxBit_SE2 : ARMMMUIdxBit_E2;
499
- int bits = tlbbits_for_regime(env, secure ? ARMMMUIdx_SE2 : ARMMMUIdx_E2,
500
- pageaddr);
501
+ int bits = tlbbits_for_regime(env, ARMMMUIdx_E2, pageaddr);
502
503
- tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
504
+ tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr,
505
+ ARMMMUIdxBit_E2, bits);
506
}
507
508
static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
509
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
510
{
511
CPUState *cs = env_cpu(env);
512
uint64_t pageaddr = sextract64(value << 12, 0, 56);
513
- int bits = tlbbits_for_regime(env, ARMMMUIdx_SE3, pageaddr);
514
+ int bits = tlbbits_for_regime(env, ARMMMUIdx_E3, pageaddr);
515
516
tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr,
517
- ARMMMUIdxBit_SE3, bits);
518
+ ARMMMUIdxBit_E3, bits);
519
}
520
521
#ifdef TARGET_AARCH64
522
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_rvae1is_write(CPUARMState *env,
523
524
static int vae2_tlbmask(CPUARMState *env)
525
{
526
- return (arm_is_secure_below_el3(env)
527
- ? ARMMMUIdxBit_SE2 : ARMMMUIdxBit_E2);
528
+ return ARMMMUIdxBit_E2;
529
}
530
531
static void tlbi_aa64_rvae2_write(CPUARMState *env,
532
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_rvae3_write(CPUARMState *env,
533
* flush-last-level-only.
534
*/
535
536
- do_rvae_write(env, value, ARMMMUIdxBit_SE3,
537
- tlb_force_broadcast(env));
538
+ do_rvae_write(env, value, ARMMMUIdxBit_E3, tlb_force_broadcast(env));
539
}
540
541
static void tlbi_aa64_rvae3is_write(CPUARMState *env,
542
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_rvae3is_write(CPUARMState *env,
543
* flush-last-level-only or inner/outer specific flushes.
544
*/
545
546
- do_rvae_write(env, value, ARMMMUIdxBit_SE3, true);
547
+ do_rvae_write(env, value, ARMMMUIdxBit_E3, true);
548
}
549
#endif
550
551
@@ -XXX,XX +XXX,XX @@ uint64_t arm_sctlr(CPUARMState *env, int el)
552
/* Only EL0 needs to be adjusted for EL1&0 or EL2&0. */
553
if (el == 0) {
554
ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, 0);
555
- el = (mmu_idx == ARMMMUIdx_E20_0 || mmu_idx == ARMMMUIdx_SE20_0)
556
- ? 2 : 1;
557
+ el = mmu_idx == ARMMMUIdx_E20_0 ? 2 : 1;
558
}
559
return env->cp15.sctlr_el[el];
560
}
561
@@ -XXX,XX +XXX,XX @@ int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
562
switch (mmu_idx) {
563
case ARMMMUIdx_E10_0:
564
case ARMMMUIdx_E20_0:
565
- case ARMMMUIdx_SE10_0:
566
- case ARMMMUIdx_SE20_0:
567
return 0;
568
case ARMMMUIdx_E10_1:
569
case ARMMMUIdx_E10_1_PAN:
570
- case ARMMMUIdx_SE10_1:
571
- case ARMMMUIdx_SE10_1_PAN:
572
return 1;
573
case ARMMMUIdx_E2:
574
case ARMMMUIdx_E20_2:
575
case ARMMMUIdx_E20_2_PAN:
576
- case ARMMMUIdx_SE2:
577
- case ARMMMUIdx_SE20_2:
578
- case ARMMMUIdx_SE20_2_PAN:
579
return 2;
580
- case ARMMMUIdx_SE3:
581
+ case ARMMMUIdx_E3:
582
return 3;
583
default:
584
g_assert_not_reached();
585
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el)
586
}
587
break;
588
case 3:
589
- return ARMMMUIdx_SE3;
590
+ return ARMMMUIdx_E3;
591
default:
592
g_assert_not_reached();
593
}
594
595
- if (arm_is_secure_below_el3(env)) {
596
- idx &= ~ARM_MMU_IDX_A_NS;
597
- }
598
-
599
return idx;
600
}
601
602
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
603
switch (mmu_idx) {
604
case ARMMMUIdx_E10_1:
605
case ARMMMUIdx_E10_1_PAN:
606
- case ARMMMUIdx_SE10_1:
607
- case ARMMMUIdx_SE10_1_PAN:
608
/* TODO: ARMv8.3-NV */
609
DP_TBFLAG_A64(flags, UNPRIV, 1);
610
break;
611
case ARMMMUIdx_E20_2:
612
case ARMMMUIdx_E20_2_PAN:
613
- case ARMMMUIdx_SE20_2:
614
- case ARMMMUIdx_SE20_2_PAN:
615
/*
616
* Note that EL20_2 is gated by HCR_EL2.E2H == 1, but EL20_0 is
617
* gated by HCR_EL2.<E2H,TGE> == '11', and so is LDTR.
618
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
58
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
619
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
620
--- a/target/arm/ptw.c
60
--- a/target/arm/ptw.c
621
+++ b/target/arm/ptw.c
61
+++ b/target/arm/ptw.c
622
@@ -XXX,XX +XXX,XX @@ unsigned int arm_pamax(ARMCPU *cpu)
62
@@ -XXX,XX +XXX,XX @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
623
ARMMMUIdx stage_1_mmu_idx(ARMMMUIdx mmu_idx)
63
static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
64
int ap, int ns, int xn, int pxn)
624
{
65
{
625
switch (mmu_idx) {
66
+ ARMCPU *cpu = env_archcpu(env);
626
- case ARMMMUIdx_SE10_0:
67
bool is_user = regime_is_user(env, mmu_idx);
627
- return ARMMMUIdx_Stage1_SE0;
68
int prot_rw, user_rw;
628
- case ARMMMUIdx_SE10_1:
69
bool have_wxn;
629
- return ARMMMUIdx_Stage1_SE1;
70
@@ -XXX,XX +XXX,XX @@ static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
630
- case ARMMMUIdx_SE10_1_PAN:
71
if (is_user) {
631
- return ARMMMUIdx_Stage1_SE1_PAN;
72
prot_rw = user_rw;
632
case ARMMMUIdx_E10_0:
73
} else {
633
return ARMMMUIdx_Stage1_E0;
74
+ /*
634
case ARMMMUIdx_E10_1:
75
+ * PAN controls can forbid data accesses but don't affect insn fetch.
635
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_big_endian(CPUARMState *env, ARMMMUIdx mmu_idx)
76
+ * Plain PAN forbids data accesses if EL0 has data permissions;
636
static bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
77
+ * PAN3 forbids data accesses if EL0 has either data or exec perms.
637
{
78
+ * Note that for AArch64 the 'user can exec' case is exactly !xn.
638
switch (mmu_idx) {
79
+ * We make the IMPDEF choices that SCR_EL3.SIF and Realm EL2&0
639
- case ARMMMUIdx_SE10_0:
80
+ * do not affect EPAN.
640
case ARMMMUIdx_E20_0:
81
+ */
641
- case ARMMMUIdx_SE20_0:
82
if (user_rw && regime_is_pan(env, mmu_idx)) {
642
case ARMMMUIdx_Stage1_E0:
83
- /* PAN forbids data accesses but doesn't affect insn fetch */
643
- case ARMMMUIdx_Stage1_SE0:
84
+ prot_rw = 0;
644
case ARMMMUIdx_MUser:
85
+ } else if (cpu_isar_feature(aa64_pan3, cpu) && is_aa64 &&
645
case ARMMMUIdx_MSUser:
86
+ regime_is_pan(env, mmu_idx) &&
646
case ARMMMUIdx_MUserNegPri:
87
+ (regime_sctlr(env, mmu_idx) & SCTLR_EPAN) && !xn) {
647
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
88
prot_rw = 0;
648
89
} else {
649
s2_mmu_idx = (s2walk_secure
90
prot_rw = simple_ap_to_rw_prot_is_user(ap, false);
650
? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2);
651
- is_el0 = mmu_idx == ARMMMUIdx_E10_0 || mmu_idx == ARMMMUIdx_SE10_0;
652
+ is_el0 = mmu_idx == ARMMMUIdx_E10_0;
653
654
/*
655
* S1 is done, now do S2 translation.
656
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
657
case ARMMMUIdx_Stage1_E1:
658
case ARMMMUIdx_Stage1_E1_PAN:
659
case ARMMMUIdx_E2:
660
+ is_secure = arm_is_secure_below_el3(env);
661
+ break;
662
case ARMMMUIdx_Stage2:
663
case ARMMMUIdx_MPrivNegPri:
664
case ARMMMUIdx_MUserNegPri:
665
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
666
case ARMMMUIdx_MUser:
667
is_secure = false;
668
break;
669
- case ARMMMUIdx_SE3:
670
- case ARMMMUIdx_SE10_0:
671
- case ARMMMUIdx_SE10_1:
672
- case ARMMMUIdx_SE10_1_PAN:
673
- case ARMMMUIdx_SE20_0:
674
- case ARMMMUIdx_SE20_2:
675
- case ARMMMUIdx_SE20_2_PAN:
676
- case ARMMMUIdx_Stage1_SE0:
677
- case ARMMMUIdx_Stage1_SE1:
678
- case ARMMMUIdx_Stage1_SE1_PAN:
679
- case ARMMMUIdx_SE2:
680
+ case ARMMMUIdx_E3:
681
case ARMMMUIdx_Stage2_S:
682
case ARMMMUIdx_MSPrivNegPri:
683
case ARMMMUIdx_MSUserNegPri:
684
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
685
index XXXXXXX..XXXXXXX 100644
686
--- a/target/arm/translate-a64.c
687
+++ b/target/arm/translate-a64.c
688
@@ -XXX,XX +XXX,XX @@ static int get_a64_user_mem_index(DisasContext *s)
689
case ARMMMUIdx_E20_2_PAN:
690
useridx = ARMMMUIdx_E20_0;
691
break;
692
- case ARMMMUIdx_SE10_1:
693
- case ARMMMUIdx_SE10_1_PAN:
694
- useridx = ARMMMUIdx_SE10_0;
695
- break;
696
- case ARMMMUIdx_SE20_2:
697
- case ARMMMUIdx_SE20_2_PAN:
698
- useridx = ARMMMUIdx_SE20_0;
699
- break;
700
default:
701
g_assert_not_reached();
702
}
703
diff --git a/target/arm/translate.c b/target/arm/translate.c
704
index XXXXXXX..XXXXXXX 100644
705
--- a/target/arm/translate.c
706
+++ b/target/arm/translate.c
707
@@ -XXX,XX +XXX,XX @@ static inline int get_a32_user_mem_index(DisasContext *s)
708
* otherwise, access as if at PL0.
709
*/
710
switch (s->mmu_idx) {
711
+ case ARMMMUIdx_E3:
712
case ARMMMUIdx_E2: /* this one is UNPREDICTABLE */
713
case ARMMMUIdx_E10_0:
714
case ARMMMUIdx_E10_1:
715
case ARMMMUIdx_E10_1_PAN:
716
return arm_to_core_mmu_idx(ARMMMUIdx_E10_0);
717
- case ARMMMUIdx_SE3:
718
- case ARMMMUIdx_SE10_0:
719
- case ARMMMUIdx_SE10_1:
720
- case ARMMMUIdx_SE10_1_PAN:
721
- return arm_to_core_mmu_idx(ARMMMUIdx_SE10_0);
722
case ARMMMUIdx_MUser:
723
case ARMMMUIdx_MPriv:
724
return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
725
--
91
--
726
2.25.1
92
2.34.1
diff view generated by jsdifflib
1
FEAT_GTG is a change tho the ID register ID_AA64MMFR0_EL1 so that it
1
In rST markup syntax, the inline markup (*italics*, **bold** and
2
can report a different set of supported granule (page) sizes for
2
``monospaced``) must be separated from the surrending text by
3
stage 1 and stage 2 translation tables. As of commit c20281b2a5048
3
non-word characters, otherwise it is not interpreted as markup.
4
we already report the granule sizes that way for '-cpu max', and now
4
To force interpretation as markup in the middle of a word,
5
we also correctly make attempts to use unimplemented granule sizes
5
you need to use a backslash-escaped space (which will not
6
fail, so we can report the support of the feature in the
6
appear as a space in the output).
7
documentation.
8
7
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Fix a missing backslash-space in this file, which meant that the ``
9
after "select" was output literally and the monospacing was
10
incorrectly extended all the way to the end of the next monospaced
11
word.
12
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20221003162315.2833797-4-peter.maydell@linaro.org
14
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
16
Message-id: 20230411105424.3994585-1-peter.maydell@linaro.org
12
---
17
---
13
docs/system/arm/emulation.rst | 1 +
18
docs/devel/kconfig.rst | 2 +-
14
1 file changed, 1 insertion(+)
19
1 file changed, 1 insertion(+), 1 deletion(-)
15
20
16
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
21
diff --git a/docs/devel/kconfig.rst b/docs/devel/kconfig.rst
17
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
18
--- a/docs/system/arm/emulation.rst
23
--- a/docs/devel/kconfig.rst
19
+++ b/docs/system/arm/emulation.rst
24
+++ b/docs/devel/kconfig.rst
20
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
25
@@ -XXX,XX +XXX,XX @@ or commenting out lines in the second group.
21
- FEAT_FRINTTS (Floating-point to integer instructions)
26
22
- FEAT_FlagM (Flag manipulation instructions v2)
27
It is also possible to run QEMU's configure script with the
23
- FEAT_FlagM2 (Enhancements to flag manipulation instructions)
28
``--without-default-devices`` option. When this is done, everything defaults
24
+- FEAT_GTG (Guest translation granule size)
29
-to ``n`` unless it is ``select``ed or explicitly switched on in the
25
- FEAT_HCX (Support for the HCRX_EL2 register)
30
+to ``n`` unless it is ``select``\ ed or explicitly switched on in the
26
- FEAT_HPDS (Hierarchical permission disables)
31
``.mak`` files. In other words, ``default`` and ``imply`` directives
27
- FEAT_I8MM (AArch64 Int8 matrix multiplication instructions)
32
are disabled. When QEMU is built with this option, the user will probably
33
want to change some lines in the first group, for example like this::
28
--
34
--
29
2.25.1
35
2.34.1
36
37
diff view generated by jsdifflib
1
Now we have an enum for the granule size, use it in the
1
So that we can avoid the "older gdb crashes" problem described in
2
ARMVAParameters struct instead of the using16k/using64k bools.
2
commit 5787d17a42f7af4 and which caused us to disable reporting pauth
3
information via the gdbstub, newer gdb is going to implement support
4
for recognizing the pauth information via a new feature name:
5
org.gnu.gdb.aarch64.pauth_v2
6
7
Older gdb won't recognize this feature name, so we can re-enable the
8
pauth support under the new name without risking them crashing.
3
9
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>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20221003162315.2833797-3-peter.maydell@linaro.org
12
Message-id: 20230406150827.3322670-1-peter.maydell@linaro.org
7
---
13
---
8
target/arm/internals.h | 23 +++++++++++++++++++++--
14
target/arm/gdbstub.c | 9 ++++-----
9
target/arm/helper.c | 39 ++++++++++++++++++++++++++++-----------
15
gdb-xml/aarch64-pauth.xml | 2 +-
10
target/arm/ptw.c | 8 +-------
16
2 files changed, 5 insertions(+), 6 deletions(-)
11
3 files changed, 50 insertions(+), 20 deletions(-)
12
17
13
diff --git a/target/arm/internals.h b/target/arm/internals.h
18
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
14
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/internals.h
20
--- a/target/arm/gdbstub.c
16
+++ b/target/arm/internals.h
21
+++ b/target/arm/gdbstub.c
17
@@ -XXX,XX +XXX,XX @@ typedef enum ARMGranuleSize {
22
@@ -XXX,XX +XXX,XX @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
18
GranInvalid,
23
aarch64_gdb_set_fpu_reg,
19
} ARMGranuleSize;
24
34, "aarch64-fpu.xml", 0);
20
25
}
21
+/**
26
-#if 0
22
+ * arm_granule_bits: Return address size of the granule in bits
27
/*
23
+ *
28
- * GDB versions 9 through 12 have a bug which means they will
24
+ * Return the address size of the granule in bits. This corresponds
29
- * crash if they see this XML from QEMU; disable it for the 8.0
25
+ * to the pseudocode TGxGranuleBits().
30
- * release, pending a better solution.
26
+ */
31
+ * Note that we report pauth information via the feature name
27
+static inline int arm_granule_bits(ARMGranuleSize gran)
32
+ * org.gnu.gdb.aarch64.pauth_v2, not org.gnu.gdb.aarch64.pauth.
28
+{
33
+ * GDB versions 9 through 12 have a bug where they will crash
29
+ switch (gran) {
34
+ * if they see the latter XML from QEMU.
30
+ case Gran64K:
35
*/
31
+ return 16;
36
if (isar_feature_aa64_pauth(&cpu->isar)) {
32
+ case Gran16K:
37
gdb_register_coprocessor(cs, aarch64_gdb_get_pauth_reg,
33
+ return 14;
38
aarch64_gdb_set_pauth_reg,
34
+ case Gran4K:
39
4, "aarch64-pauth.xml", 0);
35
+ return 12;
40
}
36
+ default:
41
-#endif
37
+ g_assert_not_reached();
42
#endif
38
+ }
43
} else {
39
+}
44
if (arm_feature(env, ARM_FEATURE_NEON)) {
40
+
45
diff --git a/gdb-xml/aarch64-pauth.xml b/gdb-xml/aarch64-pauth.xml
41
/*
42
* Parameters of a given virtual address, as extracted from the
43
* translation control register (TCR) for a given regime.
44
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
45
bool tbi : 1;
46
bool epd : 1;
47
bool hpd : 1;
48
- bool using16k : 1;
49
- bool using64k : 1;
50
bool tsz_oob : 1; /* tsz has been clamped to legal range */
51
bool ds : 1;
52
+ ARMGranuleSize gran : 2;
53
} ARMVAParameters;
54
55
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
56
diff --git a/target/arm/helper.c b/target/arm/helper.c
57
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/helper.c
47
--- a/gdb-xml/aarch64-pauth.xml
59
+++ b/target/arm/helper.c
48
+++ b/gdb-xml/aarch64-pauth.xml
60
@@ -XXX,XX +XXX,XX @@ typedef struct {
49
@@ -XXX,XX +XXX,XX @@
61
uint64_t length;
50
notice and this notice are preserved. -->
62
} TLBIRange;
51
63
52
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
64
+static ARMGranuleSize tlbi_range_tg_to_gran_size(int tg)
53
-<feature name="org.gnu.gdb.aarch64.pauth">
65
+{
54
+<feature name="org.gnu.gdb.aarch64.pauth_v2">
66
+ /*
55
<reg name="pauth_dmask" bitsize="64"/>
67
+ * Note that the TLBI range TG field encoding differs from both
56
<reg name="pauth_cmask" bitsize="64"/>
68
+ * TG0 and TG1 encodings.
57
<reg name="pauth_dmask_high" bitsize="64"/>
69
+ */
70
+ switch (tg) {
71
+ case 1:
72
+ return Gran4K;
73
+ case 2:
74
+ return Gran16K;
75
+ case 3:
76
+ return Gran64K;
77
+ default:
78
+ return GranInvalid;
79
+ }
80
+}
81
+
82
static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
83
uint64_t value)
84
{
85
@@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
86
uint64_t select = sextract64(value, 36, 1);
87
ARMVAParameters param = aa64_va_parameters(env, select, mmuidx, true);
88
TLBIRange ret = { };
89
+ ARMGranuleSize gran;
90
91
page_size_granule = extract64(value, 46, 2);
92
+ gran = tlbi_range_tg_to_gran_size(page_size_granule);
93
94
/* The granule encoded in value must match the granule in use. */
95
- if (page_size_granule != (param.using64k ? 3 : param.using16k ? 2 : 1)) {
96
+ if (gran != param.gran) {
97
qemu_log_mask(LOG_GUEST_ERROR, "Invalid tlbi page size granule %d\n",
98
page_size_granule);
99
return ret;
100
}
101
102
- page_shift = (page_size_granule - 1) * 2 + 12;
103
+ page_shift = arm_granule_bits(gran);
104
num = extract64(value, 39, 5);
105
scale = extract64(value, 44, 2);
106
exponent = (5 * scale) + 1;
107
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
108
ARMMMUIdx mmu_idx, bool data)
109
{
110
uint64_t tcr = regime_tcr(env, mmu_idx);
111
- bool epd, hpd, using16k, using64k, tsz_oob, ds;
112
+ bool epd, hpd, tsz_oob, ds;
113
int select, tsz, tbi, max_tsz, min_tsz, ps, sh;
114
ARMGranuleSize gran;
115
ARMCPU *cpu = env_archcpu(env);
116
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
117
}
118
119
gran = sanitize_gran_size(cpu, gran, stage2);
120
- using64k = gran == Gran64K;
121
- using16k = gran == Gran16K;
122
123
if (cpu_isar_feature(aa64_st, cpu)) {
124
- max_tsz = 48 - using64k;
125
+ max_tsz = 48 - (gran == Gran64K);
126
} else {
127
max_tsz = 39;
128
}
129
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
130
* adjust the effective value of DS, as documented.
131
*/
132
min_tsz = 16;
133
- if (using64k) {
134
+ if (gran == Gran64K) {
135
if (cpu_isar_feature(aa64_lva, cpu)) {
136
min_tsz = 12;
137
}
138
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
139
switch (mmu_idx) {
140
case ARMMMUIdx_Stage2:
141
case ARMMMUIdx_Stage2_S:
142
- if (using16k) {
143
+ if (gran == Gran16K) {
144
ds = cpu_isar_feature(aa64_tgran16_2_lpa2, cpu);
145
} else {
146
ds = cpu_isar_feature(aa64_tgran4_2_lpa2, cpu);
147
}
148
break;
149
default:
150
- if (using16k) {
151
+ if (gran == Gran16K) {
152
ds = cpu_isar_feature(aa64_tgran16_lpa2, cpu);
153
} else {
154
ds = cpu_isar_feature(aa64_tgran4_lpa2, cpu);
155
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
156
.tbi = tbi,
157
.epd = epd,
158
.hpd = hpd,
159
- .using16k = using16k,
160
- .using64k = using64k,
161
.tsz_oob = tsz_oob,
162
.ds = ds,
163
+ .gran = gran,
164
};
165
}
166
167
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
168
index XXXXXXX..XXXXXXX 100644
169
--- a/target/arm/ptw.c
170
+++ b/target/arm/ptw.c
171
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
172
}
173
}
174
175
- if (param.using64k) {
176
- stride = 13;
177
- } else if (param.using16k) {
178
- stride = 11;
179
- } else {
180
- stride = 9;
181
- }
182
+ stride = arm_granule_bits(param.gran) - 3;
183
184
/*
185
* Note that QEMU ignores shareability and cacheability attributes,
186
--
58
--
187
2.25.1
59
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
Remove the use of regime_is_secure from arm_tr_init_disas_context.
3
The SOC on i.MX6UL and i.MX7 has 2 Ethernet interfaces. The PHY on each may
4
Instead, provide the value of v8m_secure directly from tb_flags.
4
be connected to separate MDIO busses, or both may be connected on the same
5
Rather than use regime_is_secure, use the env->v7m.secure directly,
5
MDIO bus using different PHY addresses. Commit 461c51ad4275 ("Add a phy-num
6
as per arm_mmu_idx_el.
6
property to the i.MX FEC emulator") added support for specifying PHY
7
addresses, but it did not provide support for linking the second PHY on
8
a given MDIO bus to the other Ethernet interface.
7
9
10
To be able to support two PHY instances on a single MDIO bus, two properties
11
are needed: First, there needs to be a flag indicating if the MDIO bus on
12
a given Ethernet interface is connected. If not, attempts to read from this
13
bus must always return 0xffff. Implement this property as phy-connected.
14
Second, if the MDIO bus on an interface is active, it needs a link to the
15
consumer interface to be able to provide PHY access for it. Implement this
16
property as phy-consumer.
17
18
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
19
Message-id: 20230315145248.1639364-2-linux@roeck-us.net
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20221001162318.153420-8-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
22
---
13
target/arm/cpu.h | 2 ++
23
include/hw/net/imx_fec.h | 2 ++
14
target/arm/helper.c | 4 ++++
24
hw/net/imx_fec.c | 27 +++++++++++++++++++++++----
15
target/arm/translate.c | 3 +--
25
2 files changed, 25 insertions(+), 4 deletions(-)
16
3 files changed, 7 insertions(+), 2 deletions(-)
17
26
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
27
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
19
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
29
--- a/include/hw/net/imx_fec.h
21
+++ b/target/arm/cpu.h
30
+++ b/include/hw/net/imx_fec.h
22
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_M32, NEW_FP_CTXT_NEEDED, 3, 1) /* Not cached. */
31
@@ -XXX,XX +XXX,XX @@ struct IMXFECState {
23
FIELD(TBFLAG_M32, FPCCR_S_WRONG, 4, 1) /* Not cached. */
32
uint32_t phy_int;
24
/* Set if MVE insns are definitely not predicated by VPR or LTPSIZE */
33
uint32_t phy_int_mask;
25
FIELD(TBFLAG_M32, MVE_NO_PRED, 5, 1) /* Not cached. */
34
uint32_t phy_num;
26
+/* Set if in secure mode */
35
+ bool phy_connected;
27
+FIELD(TBFLAG_M32, SECURE, 6, 1)
36
+ struct IMXFECState *phy_consumer;
28
37
29
/*
38
bool is_fec;
30
* Bit usage when in AArch64 state
39
31
diff --git a/target/arm/helper.c b/target/arm/helper.c
40
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
32
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/helper.c
42
--- a/hw/net/imx_fec.c
34
+++ b/target/arm/helper.c
43
+++ b/hw/net/imx_fec.c
35
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_m32(CPUARMState *env, int fp_el,
44
@@ -XXX,XX +XXX,XX @@ static uint32_t imx_phy_read(IMXFECState *s, int reg)
36
DP_TBFLAG_M32(flags, STACKCHECK, 1);
45
uint32_t val;
46
uint32_t phy = reg / 32;
47
48
- if (phy != s->phy_num) {
49
- trace_imx_phy_read_num(phy, s->phy_num);
50
+ if (!s->phy_connected) {
51
return 0xffff;
37
}
52
}
38
53
39
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) && env->v7m.secure) {
54
+ if (phy != s->phy_num) {
40
+ DP_TBFLAG_M32(flags, SECURE, 1);
55
+ if (s->phy_consumer && phy == s->phy_consumer->phy_num) {
56
+ s = s->phy_consumer;
57
+ } else {
58
+ trace_imx_phy_read_num(phy, s->phy_num);
59
+ return 0xffff;
60
+ }
41
+ }
61
+ }
42
+
62
+
43
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
63
reg %= 32;
44
}
64
45
65
switch (reg) {
46
diff --git a/target/arm/translate.c b/target/arm/translate.c
66
@@ -XXX,XX +XXX,XX @@ static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
47
index XXXXXXX..XXXXXXX 100644
67
{
48
--- a/target/arm/translate.c
68
uint32_t phy = reg / 32;
49
+++ b/target/arm/translate.c
69
50
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
70
- if (phy != s->phy_num) {
51
dc->vfp_enabled = 1;
71
- trace_imx_phy_write_num(phy, s->phy_num);
52
dc->be_data = MO_TE;
72
+ if (!s->phy_connected) {
53
dc->v7m_handler_mode = EX_TBFLAG_M32(tb_flags, HANDLER);
73
return;
54
- dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
74
}
55
- regime_is_secure(env, dc->mmu_idx);
75
56
+ dc->v8m_secure = EX_TBFLAG_M32(tb_flags, SECURE);
76
+ if (phy != s->phy_num) {
57
dc->v8m_stackcheck = EX_TBFLAG_M32(tb_flags, STACKCHECK);
77
+ if (s->phy_consumer && phy == s->phy_consumer->phy_num) {
58
dc->v8m_fpccr_s_wrong = EX_TBFLAG_M32(tb_flags, FPCCR_S_WRONG);
78
+ s = s->phy_consumer;
59
dc->v7m_new_fp_ctxt_needed =
79
+ } else {
80
+ trace_imx_phy_write_num(phy, s->phy_num);
81
+ return;
82
+ }
83
+ }
84
+
85
reg %= 32;
86
87
trace_imx_phy_write(val, phy, reg);
88
@@ -XXX,XX +XXX,XX @@ static Property imx_eth_properties[] = {
89
DEFINE_NIC_PROPERTIES(IMXFECState, conf),
90
DEFINE_PROP_UINT32("tx-ring-num", IMXFECState, tx_ring_num, 1),
91
DEFINE_PROP_UINT32("phy-num", IMXFECState, phy_num, 0),
92
+ DEFINE_PROP_BOOL("phy-connected", IMXFECState, phy_connected, true),
93
+ DEFINE_PROP_LINK("phy-consumer", IMXFECState, phy_consumer, TYPE_IMX_FEC,
94
+ IMXFECState *),
95
DEFINE_PROP_END_OF_LIST(),
96
};
97
60
--
98
--
61
2.25.1
99
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
Use get_phys_addr_with_secure directly. For a-profile, this is the
3
Add fec[12]-phy-connected properties and use it to set phy-connected
4
one place where the value of is_secure may not equal arm_is_secure(env).
4
and phy-consumer properties for imx_fec.
5
5
6
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
7
Message-id: 20230315145248.1639364-3-linux@roeck-us.net
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20221001162318.153420-10-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
target/arm/helper.c | 19 ++++++++++++++-----
11
include/hw/arm/fsl-imx6ul.h | 1 +
12
1 file changed, 14 insertions(+), 5 deletions(-)
12
hw/arm/fsl-imx6ul.c | 20 ++++++++++++++++++++
13
2 files changed, 21 insertions(+)
13
14
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
--- a/include/hw/arm/fsl-imx6ul.h
17
+++ b/target/arm/helper.c
18
+++ b/include/hw/arm/fsl-imx6ul.h
18
@@ -XXX,XX +XXX,XX @@ static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri,
19
@@ -XXX,XX +XXX,XX @@ struct FslIMX6ULState {
19
20
MemoryRegion ocram_alias;
20
#ifdef CONFIG_TCG
21
21
static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
22
uint32_t phy_num[FSL_IMX6UL_NUM_ETHS];
22
- MMUAccessType access_type, ARMMMUIdx mmu_idx)
23
+ bool phy_connected[FSL_IMX6UL_NUM_ETHS];
23
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
24
};
24
+ bool is_secure)
25
25
{
26
enum FslIMX6ULMemoryMap {
26
bool ret;
27
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
27
uint64_t par64;
28
index XXXXXXX..XXXXXXX 100644
28
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
29
--- a/hw/arm/fsl-imx6ul.c
29
ARMMMUFaultInfo fi = {};
30
+++ b/hw/arm/fsl-imx6ul.c
30
GetPhysAddrResult res = {};
31
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
31
32
- ret = get_phys_addr(env, value, access_type, mmu_idx, &res, &fi);
33
+ ret = get_phys_addr_with_secure(env, value, access_type, mmu_idx,
34
+ is_secure, &res, &fi);
35
32
36
/*
33
/*
37
* ATS operations only do S1 or S1+S2 translations, so we never
34
* Ethernet
38
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
35
+ *
39
switch (el) {
36
+ * We must use two loops since phy_connected affects the other interface
40
case 3:
37
+ * and we have to set all properties before calling sysbus_realize().
41
mmu_idx = ARMMMUIdx_SE3;
38
*/
42
+ secure = true;
39
+ for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
43
break;
40
+ object_property_set_bool(OBJECT(&s->eth[i]), "phy-connected",
44
case 2:
41
+ s->phy_connected[i], &error_abort);
45
g_assert(!secure); /* ARMv8.4-SecEL2 is 64-bit only */
42
+ /*
46
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
43
+ * If the MDIO bus on this controller is not connected, assume the
47
switch (el) {
44
+ * other controller provides support for it.
48
case 3:
45
+ */
49
mmu_idx = ARMMMUIdx_SE10_0;
46
+ if (!s->phy_connected[i]) {
50
+ secure = true;
47
+ object_property_set_link(OBJECT(&s->eth[1 - i]), "phy-consumer",
51
break;
48
+ OBJECT(&s->eth[i]), &error_abort);
52
case 2:
49
+ }
53
g_assert(!secure); /* ARMv8.4-SecEL2 is 64-bit only */
50
+ }
54
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
51
+
55
case 4:
52
for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
56
/* stage 1+2 NonSecure PL1: ATS12NSOPR, ATS12NSOPW */
53
static const hwaddr FSL_IMX6UL_ENETn_ADDR[FSL_IMX6UL_NUM_ETHS] = {
57
mmu_idx = ARMMMUIdx_E10_1;
54
FSL_IMX6UL_ENET1_ADDR,
58
+ secure = false;
55
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
59
break;
56
static Property fsl_imx6ul_properties[] = {
60
case 6:
57
DEFINE_PROP_UINT32("fec1-phy-num", FslIMX6ULState, phy_num[0], 0),
61
/* stage 1+2 NonSecure PL0: ATS12NSOUR, ATS12NSOUW */
58
DEFINE_PROP_UINT32("fec2-phy-num", FslIMX6ULState, phy_num[1], 1),
62
mmu_idx = ARMMMUIdx_E10_0;
59
+ DEFINE_PROP_BOOL("fec1-phy-connected", FslIMX6ULState, phy_connected[0],
63
+ secure = false;
60
+ true),
64
break;
61
+ DEFINE_PROP_BOOL("fec2-phy-connected", FslIMX6ULState, phy_connected[1],
65
default:
62
+ true),
66
g_assert_not_reached();
63
DEFINE_PROP_END_OF_LIST(),
67
}
64
};
68
65
69
- par64 = do_ats_write(env, value, access_type, mmu_idx);
70
+ par64 = do_ats_write(env, value, access_type, mmu_idx, secure);
71
72
A32_BANKED_CURRENT_REG_SET(env, par, par64);
73
#else
74
@@ -XXX,XX +XXX,XX @@ static void ats1h_write(CPUARMState *env, const ARMCPRegInfo *ri,
75
MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD;
76
uint64_t par64;
77
78
- par64 = do_ats_write(env, value, access_type, ARMMMUIdx_E2);
79
+ /* There is no SecureEL2 for AArch32. */
80
+ par64 = do_ats_write(env, value, access_type, ARMMMUIdx_E2, false);
81
82
A32_BANKED_CURRENT_REG_SET(env, par, par64);
83
#else
84
@@ -XXX,XX +XXX,XX @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
85
break;
86
case 6: /* AT S1E3R, AT S1E3W */
87
mmu_idx = ARMMMUIdx_SE3;
88
+ secure = true;
89
break;
90
default:
91
g_assert_not_reached();
92
@@ -XXX,XX +XXX,XX @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
93
g_assert_not_reached();
94
}
95
96
- env->cp15.par_el[1] = do_ats_write(env, value, access_type, mmu_idx);
97
+ env->cp15.par_el[1] = do_ats_write(env, value, access_type,
98
+ mmu_idx, secure);
99
#else
100
/* Handled by hardware accelerator. */
101
g_assert_not_reached();
102
--
66
--
103
2.25.1
67
2.34.1
diff view generated by jsdifflib
1
From: Jerome Forissier <jerome.forissier@linaro.org>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
According to the Linux kernel booting.rst [1], CPTR_EL3.ESM and
3
On mcimx6ul-evk, the MDIO bus is connected to the second Ethernet
4
SCR_EL3.EnTP2 must be initialized to 1 when EL3 is present and FEAT_SME
4
interface. Set fec1-phy-connected to false to reflect this.
5
is advertised. This has to be taken care of when QEMU boots directly
6
into the kernel (i.e., "-M virt,secure=on -cpu max -kernel Image").
7
5
8
Cc: qemu-stable@nongnu.org
6
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
9
Fixes: 78cb9776662a ("target/arm: Enable SME for -cpu max")
7
Message-id: 20230315145248.1639364-4-linux@roeck-us.net
10
Link: [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/arm64/booting.rst?h=v6.0#n321
11
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
12
Message-id: 20221003145641.1921467-1-jerome.forissier@linaro.org
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
10
---
16
hw/arm/boot.c | 4 ++++
11
hw/arm/mcimx6ul-evk.c | 2 ++
17
1 file changed, 4 insertions(+)
12
1 file changed, 2 insertions(+)
18
13
19
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
14
diff --git a/hw/arm/mcimx6ul-evk.c b/hw/arm/mcimx6ul-evk.c
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/boot.c
16
--- a/hw/arm/mcimx6ul-evk.c
22
+++ b/hw/arm/boot.c
17
+++ b/hw/arm/mcimx6ul-evk.c
23
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
18
@@ -XXX,XX +XXX,XX @@ static void mcimx6ul_evk_init(MachineState *machine)
24
if (cpu_isar_feature(aa64_sve, cpu)) {
19
object_property_add_child(OBJECT(machine), "soc", OBJECT(s));
25
env->cp15.cptr_el[3] |= R_CPTR_EL3_EZ_MASK;
20
object_property_set_uint(OBJECT(s), "fec1-phy-num", 2, &error_fatal);
26
}
21
object_property_set_uint(OBJECT(s), "fec2-phy-num", 1, &error_fatal);
27
+ if (cpu_isar_feature(aa64_sme, cpu)) {
22
+ object_property_set_bool(OBJECT(s), "fec1-phy-connected", false,
28
+ env->cp15.cptr_el[3] |= R_CPTR_EL3_ESM_MASK;
23
+ &error_fatal);
29
+ env->cp15.scr_el3 |= SCR_ENTP2;
24
qdev_realize(DEVICE(s), NULL, &error_fatal);
30
+ }
25
31
/* AArch64 kernels never boot in secure mode */
26
memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_MMDC_ADDR,
32
assert(!info->secure_boot);
33
/* This hook is only supported for AArch32 currently:
34
--
27
--
35
2.25.1
28
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
Add fec[12]-phy-connected properties and use it to set phy-connected
4
and phy-consumer properties for imx_fec.
5
6
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
7
Message-id: 20230315145248.1639364-5-linux@roeck-us.net
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20221001162318.153420-19-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
target/arm/ptw.c | 138 +++++++++++++++++++++++++----------------------
11
include/hw/arm/fsl-imx7.h | 1 +
9
1 file changed, 74 insertions(+), 64 deletions(-)
12
hw/arm/fsl-imx7.c | 20 ++++++++++++++++++++
13
2 files changed, 21 insertions(+)
10
14
11
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/ptw.c
17
--- a/include/hw/arm/fsl-imx7.h
14
+++ b/target/arm/ptw.c
18
+++ b/include/hw/arm/fsl-imx7.h
15
@@ -XXX,XX +XXX,XX @@ static ARMCacheAttrs combine_cacheattrs(uint64_t hcr,
19
@@ -XXX,XX +XXX,XX @@ struct FslIMX7State {
16
return ret;
20
ChipideaState usb[FSL_IMX7_NUM_USBS];
17
}
21
DesignwarePCIEHost pcie;
18
22
uint32_t phy_num[FSL_IMX7_NUM_ETHS];
19
+/*
23
+ bool phy_connected[FSL_IMX7_NUM_ETHS];
20
+ * MMU disabled. S1 addresses within aa64 translation regimes are
24
};
21
+ * still checked for bounds -- see AArch64.S1DisabledOutput().
25
22
+ */
26
enum FslIMX7MemoryMap {
23
+static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
27
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
24
+ MMUAccessType access_type,
28
index XXXXXXX..XXXXXXX 100644
25
+ ARMMMUIdx mmu_idx, bool is_secure,
29
--- a/hw/arm/fsl-imx7.c
26
+ GetPhysAddrResult *result,
30
+++ b/hw/arm/fsl-imx7.c
27
+ ARMMMUFaultInfo *fi)
31
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
28
+{
32
29
+ uint64_t hcr;
33
/*
30
+ uint8_t memattr;
34
* Ethernet
31
+
35
+ *
32
+ if (mmu_idx != ARMMMUIdx_Stage2 && mmu_idx != ARMMMUIdx_Stage2_S) {
36
+ * We must use two loops since phy_connected affects the other interface
33
+ int r_el = regime_el(env, mmu_idx);
37
+ * and we have to set all properties before calling sysbus_realize().
34
+ if (arm_el_is_aa64(env, r_el)) {
38
*/
35
+ int pamax = arm_pamax(env_archcpu(env));
39
+ for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
36
+ uint64_t tcr = env->cp15.tcr_el[r_el];
40
+ object_property_set_bool(OBJECT(&s->eth[i]), "phy-connected",
37
+ int addrtop, tbi;
41
+ s->phy_connected[i], &error_abort);
38
+
42
+ /*
39
+ tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
43
+ * If the MDIO bus on this controller is not connected, assume the
40
+ if (access_type == MMU_INST_FETCH) {
44
+ * other controller provides support for it.
41
+ tbi &= ~aa64_va_parameter_tbid(tcr, mmu_idx);
45
+ */
42
+ }
46
+ if (!s->phy_connected[i]) {
43
+ tbi = (tbi >> extract64(address, 55, 1)) & 1;
47
+ object_property_set_link(OBJECT(&s->eth[1 - i]), "phy-consumer",
44
+ addrtop = (tbi ? 55 : 63);
48
+ OBJECT(&s->eth[i]), &error_abort);
45
+
46
+ if (extract64(address, pamax, addrtop - pamax + 1) != 0) {
47
+ fi->type = ARMFault_AddressSize;
48
+ fi->level = 0;
49
+ fi->stage2 = false;
50
+ return 1;
51
+ }
52
+
53
+ /*
54
+ * When TBI is disabled, we've just validated that all of the
55
+ * bits above PAMax are zero, so logically we only need to
56
+ * clear the top byte for TBI. But it's clearer to follow
57
+ * the pseudocode set of addrdesc.paddress.
58
+ */
59
+ address = extract64(address, 0, 52);
60
+ }
49
+ }
61
+ }
50
+ }
62
+
51
+
63
+ result->phys = address;
52
for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
64
+ result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
53
static const hwaddr FSL_IMX7_ENETn_ADDR[FSL_IMX7_NUM_ETHS] = {
65
+ result->page_size = TARGET_PAGE_SIZE;
54
FSL_IMX7_ENET1_ADDR,
66
+
55
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
67
+ /* Fill in cacheattr a-la AArch64.TranslateAddressS1Off. */
56
static Property fsl_imx7_properties[] = {
68
+ hcr = arm_hcr_el2_eff_secstate(env, is_secure);
57
DEFINE_PROP_UINT32("fec1-phy-num", FslIMX7State, phy_num[0], 0),
69
+ result->cacheattrs.shareability = 0;
58
DEFINE_PROP_UINT32("fec2-phy-num", FslIMX7State, phy_num[1], 1),
70
+ result->cacheattrs.is_s2_format = false;
59
+ DEFINE_PROP_BOOL("fec1-phy-connected", FslIMX7State, phy_connected[0],
71
+ if (hcr & HCR_DC) {
60
+ true),
72
+ if (hcr & HCR_DCT) {
61
+ DEFINE_PROP_BOOL("fec2-phy-connected", FslIMX7State, phy_connected[1],
73
+ memattr = 0xf0; /* Tagged, Normal, WB, RWA */
62
+ true),
74
+ } else {
63
DEFINE_PROP_END_OF_LIST(),
75
+ memattr = 0xff; /* Normal, WB, RWA */
64
};
76
+ }
65
77
+ } else if (access_type == MMU_INST_FETCH) {
78
+ if (regime_sctlr(env, mmu_idx) & SCTLR_I) {
79
+ memattr = 0xee; /* Normal, WT, RA, NT */
80
+ } else {
81
+ memattr = 0x44; /* Normal, NC, No */
82
+ }
83
+ result->cacheattrs.shareability = 2; /* outer sharable */
84
+ } else {
85
+ memattr = 0x00; /* Device, nGnRnE */
86
+ }
87
+ result->cacheattrs.attrs = memattr;
88
+ return 0;
89
+}
90
+
91
bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
92
MMUAccessType access_type, ARMMMUIdx mmu_idx,
93
bool is_secure, GetPhysAddrResult *result,
94
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
95
/* Definitely a real MMU, not an MPU */
96
97
if (regime_translation_disabled(env, mmu_idx, is_secure)) {
98
- uint64_t hcr;
99
- uint8_t memattr;
100
-
101
- /*
102
- * MMU disabled. S1 addresses within aa64 translation regimes are
103
- * still checked for bounds -- see AArch64.TranslateAddressS1Off.
104
- */
105
- if (mmu_idx != ARMMMUIdx_Stage2 && mmu_idx != ARMMMUIdx_Stage2_S) {
106
- int r_el = regime_el(env, mmu_idx);
107
- if (arm_el_is_aa64(env, r_el)) {
108
- int pamax = arm_pamax(env_archcpu(env));
109
- uint64_t tcr = env->cp15.tcr_el[r_el];
110
- int addrtop, tbi;
111
-
112
- tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
113
- if (access_type == MMU_INST_FETCH) {
114
- tbi &= ~aa64_va_parameter_tbid(tcr, mmu_idx);
115
- }
116
- tbi = (tbi >> extract64(address, 55, 1)) & 1;
117
- addrtop = (tbi ? 55 : 63);
118
-
119
- if (extract64(address, pamax, addrtop - pamax + 1) != 0) {
120
- fi->type = ARMFault_AddressSize;
121
- fi->level = 0;
122
- fi->stage2 = false;
123
- return 1;
124
- }
125
-
126
- /*
127
- * When TBI is disabled, we've just validated that all of the
128
- * bits above PAMax are zero, so logically we only need to
129
- * clear the top byte for TBI. But it's clearer to follow
130
- * the pseudocode set of addrdesc.paddress.
131
- */
132
- address = extract64(address, 0, 52);
133
- }
134
- }
135
- result->phys = address;
136
- result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
137
- result->page_size = TARGET_PAGE_SIZE;
138
-
139
- /* Fill in cacheattr a-la AArch64.TranslateAddressS1Off. */
140
- hcr = arm_hcr_el2_eff_secstate(env, is_secure);
141
- result->cacheattrs.shareability = 0;
142
- result->cacheattrs.is_s2_format = false;
143
- if (hcr & HCR_DC) {
144
- if (hcr & HCR_DCT) {
145
- memattr = 0xf0; /* Tagged, Normal, WB, RWA */
146
- } else {
147
- memattr = 0xff; /* Normal, WB, RWA */
148
- }
149
- } else if (access_type == MMU_INST_FETCH) {
150
- if (regime_sctlr(env, mmu_idx) & SCTLR_I) {
151
- memattr = 0xee; /* Normal, WT, RA, NT */
152
- } else {
153
- memattr = 0x44; /* Normal, NC, No */
154
- }
155
- result->cacheattrs.shareability = 2; /* outer sharable */
156
- } else {
157
- memattr = 0x00; /* Device, nGnRnE */
158
- }
159
- result->cacheattrs.attrs = memattr;
160
- return 0;
161
+ return get_phys_addr_disabled(env, address, access_type, mmu_idx,
162
+ is_secure, result, fi);
163
}
164
-
165
if (regime_using_lpae_format(env, mmu_idx)) {
166
return get_phys_addr_lpae(env, address, access_type, mmu_idx,
167
is_secure, false, result, fi);
168
--
66
--
169
2.25.1
67
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
While the stage2 call to get_phys_addr_lpae should never set
3
On mcimx7d-sabre, the MDIO bus is connected to the first Ethernet
4
attrs.secure when given a non-secure input, it's just as easy
4
interface. Set fec2-phy-connected to false to reflect this.
5
to make the final update to attrs.secure be unconditional and
6
false in the case of non-secure input.
7
5
8
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20230315145248.1639364-6-linux@roeck-us.net
10
Message-id: 20221007152159.1414065-1-richard.henderson@linaro.org
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
10
---
14
target/arm/ptw.c | 21 ++++++++++-----------
11
hw/arm/mcimx7d-sabre.c | 2 ++
15
1 file changed, 10 insertions(+), 11 deletions(-)
12
1 file changed, 2 insertions(+)
16
13
17
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
14
diff --git a/hw/arm/mcimx7d-sabre.c b/hw/arm/mcimx7d-sabre.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/ptw.c
16
--- a/hw/arm/mcimx7d-sabre.c
20
+++ b/target/arm/ptw.c
17
+++ b/hw/arm/mcimx7d-sabre.c
21
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
18
@@ -XXX,XX +XXX,XX @@ static void mcimx7d_sabre_init(MachineState *machine)
22
result->cacheattrs = combine_cacheattrs(env, cacheattrs1,
19
23
result->cacheattrs);
20
s = FSL_IMX7(object_new(TYPE_FSL_IMX7));
24
21
object_property_add_child(OBJECT(machine), "soc", OBJECT(s));
25
- /* Check if IPA translates to secure or non-secure PA space. */
22
+ object_property_set_bool(OBJECT(s), "fec2-phy-connected", false,
26
- if (is_secure) {
23
+ &error_fatal);
27
- if (ipa_secure) {
24
qdev_realize(DEVICE(s), NULL, &error_fatal);
28
- result->attrs.secure =
25
29
- !(env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW));
26
memory_region_add_subregion(get_system_memory(), FSL_IMX7_MMDC_ADDR,
30
- } else {
31
- result->attrs.secure =
32
- !((env->cp15.vtcr_el2 & (VTCR_NSA | VTCR_NSW))
33
- || (env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW)));
34
- }
35
- }
36
+ /*
37
+ * Check if IPA translates to secure or non-secure PA space.
38
+ * Note that VSTCR overrides VTCR and {N}SW overrides {N}SA.
39
+ */
40
+ result->attrs.secure =
41
+ (is_secure
42
+ && !(env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW))
43
+ && (ipa_secure
44
+ || !(env->cp15.vtcr_el2 & (VTCR_NSA | VTCR_NSW))));
45
+
46
return 0;
47
} else {
48
/*
49
--
27
--
50
2.25.1
28
2.34.1
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Pass the correct stage2 mmu_idx to regime_translation_disabled,
4
which we computed afterward.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20221001162318.153420-4-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/ptw.c | 6 +++---
12
1 file changed, 3 insertions(+), 3 deletions(-)
13
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/ptw.c
17
+++ b/target/arm/ptw.c
18
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
19
hwaddr addr, bool *is_secure,
20
ARMMMUFaultInfo *fi)
21
{
22
+ ARMMMUIdx s2_mmu_idx = *is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
23
+
24
if (arm_mmu_idx_is_stage1_of_2(mmu_idx) &&
25
- !regime_translation_disabled(env, ARMMMUIdx_Stage2)) {
26
- ARMMMUIdx s2_mmu_idx = *is_secure ? ARMMMUIdx_Stage2_S
27
- : ARMMMUIdx_Stage2;
28
+ !regime_translation_disabled(env, s2_mmu_idx)) {
29
GetPhysAddrResult s2 = {};
30
int ret;
31
32
--
33
2.25.1
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Use a switch on mmu_idx for the a-profile indexes, instead of
4
three different if's vs regime_el and arm_mmu_idx_is_stage1_of_2.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20221001162318.153420-12-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/ptw.c | 32 +++++++++++++++++++++++++-------
12
1 file changed, 25 insertions(+), 7 deletions(-)
13
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/ptw.c
17
+++ b/target/arm/ptw.c
18
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
19
20
hcr_el2 = arm_hcr_el2_eff(env);
21
22
- if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
23
+ switch (mmu_idx) {
24
+ case ARMMMUIdx_Stage2:
25
+ case ARMMMUIdx_Stage2_S:
26
/* HCR.DC means HCR.VM behaves as 1 */
27
return (hcr_el2 & (HCR_DC | HCR_VM)) == 0;
28
- }
29
30
- if (hcr_el2 & HCR_TGE) {
31
+ case ARMMMUIdx_E10_0:
32
+ case ARMMMUIdx_E10_1:
33
+ case ARMMMUIdx_E10_1_PAN:
34
/* TGE means that NS EL0/1 act as if SCTLR_EL1.M is zero */
35
- if (!is_secure && regime_el(env, mmu_idx) == 1) {
36
+ if (!is_secure && (hcr_el2 & HCR_TGE)) {
37
return true;
38
}
39
- }
40
+ break;
41
42
- if ((hcr_el2 & HCR_DC) && arm_mmu_idx_is_stage1_of_2(mmu_idx)) {
43
+ case ARMMMUIdx_Stage1_E0:
44
+ case ARMMMUIdx_Stage1_E1:
45
+ case ARMMMUIdx_Stage1_E1_PAN:
46
/* HCR.DC means SCTLR_EL1.M behaves as 0 */
47
- return true;
48
+ if (hcr_el2 & HCR_DC) {
49
+ return true;
50
+ }
51
+ break;
52
+
53
+ case ARMMMUIdx_E20_0:
54
+ case ARMMMUIdx_E20_2:
55
+ case ARMMMUIdx_E20_2_PAN:
56
+ case ARMMMUIdx_E2:
57
+ case ARMMMUIdx_E3:
58
+ break;
59
+
60
+ default:
61
+ g_assert_not_reached();
62
}
63
64
return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0;
65
--
66
2.25.1
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
The effect of TGE does not only apply to non-secure state,
4
now that Secure EL2 exists.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20221001162318.153420-13-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/ptw.c | 4 ++--
12
1 file changed, 2 insertions(+), 2 deletions(-)
13
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/ptw.c
17
+++ b/target/arm/ptw.c
18
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
19
case ARMMMUIdx_E10_0:
20
case ARMMMUIdx_E10_1:
21
case ARMMMUIdx_E10_1_PAN:
22
- /* TGE means that NS EL0/1 act as if SCTLR_EL1.M is zero */
23
- if (!is_secure && (hcr_el2 & HCR_TGE)) {
24
+ /* TGE means that EL0/1 act as if SCTLR_EL1.M is zero */
25
+ if (hcr_el2 & HCR_TGE) {
26
return true;
27
}
28
break;
29
--
30
2.25.1
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Rename the argument to is_secure_ptr, and introduce a
4
local variable is_secure with the value. We only write
5
back to the pointer toward the end of the function.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20221001162318.153420-15-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/ptw.c | 22 ++++++++++++----------
13
1 file changed, 12 insertions(+), 10 deletions(-)
14
15
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/ptw.c
18
+++ b/target/arm/ptw.c
19
@@ -XXX,XX +XXX,XX @@ static bool ptw_attrs_are_device(CPUARMState *env, ARMCacheAttrs cacheattrs)
20
21
/* Translate a S1 pagetable walk through S2 if needed. */
22
static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
23
- hwaddr addr, bool *is_secure,
24
+ hwaddr addr, bool *is_secure_ptr,
25
ARMMMUFaultInfo *fi)
26
{
27
- ARMMMUIdx s2_mmu_idx = *is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
28
+ bool is_secure = *is_secure_ptr;
29
+ ARMMMUIdx s2_mmu_idx = is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
30
31
if (arm_mmu_idx_is_stage1_of_2(mmu_idx) &&
32
- !regime_translation_disabled(env, s2_mmu_idx, *is_secure)) {
33
+ !regime_translation_disabled(env, s2_mmu_idx, is_secure)) {
34
GetPhysAddrResult s2 = {};
35
int ret;
36
37
ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, s2_mmu_idx,
38
- *is_secure, false, &s2, fi);
39
+ is_secure, false, &s2, fi);
40
if (ret) {
41
assert(fi->type != ARMFault_None);
42
fi->s2addr = addr;
43
fi->stage2 = true;
44
fi->s1ptw = true;
45
- fi->s1ns = !*is_secure;
46
+ fi->s1ns = !is_secure;
47
return ~0;
48
}
49
if ((arm_hcr_el2_eff(env) & HCR_PTW) &&
50
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
51
fi->s2addr = addr;
52
fi->stage2 = true;
53
fi->s1ptw = true;
54
- fi->s1ns = !*is_secure;
55
+ fi->s1ns = !is_secure;
56
return ~0;
57
}
58
59
if (arm_is_secure_below_el3(env)) {
60
/* Check if page table walk is to secure or non-secure PA space. */
61
- if (*is_secure) {
62
- *is_secure = !(env->cp15.vstcr_el2 & VSTCR_SW);
63
+ if (is_secure) {
64
+ is_secure = !(env->cp15.vstcr_el2 & VSTCR_SW);
65
} else {
66
- *is_secure = !(env->cp15.vtcr_el2 & VTCR_NSW);
67
+ is_secure = !(env->cp15.vtcr_el2 & VTCR_NSW);
68
}
69
+ *is_secure_ptr = is_secure;
70
} else {
71
- assert(!*is_secure);
72
+ assert(!is_secure);
73
}
74
75
addr = s2.phys;
76
--
77
2.25.1
diff view generated by jsdifflib