1
The following changes since commit 003ba52a8b327180e284630b289c6ece5a3e08b9:
1
The following changes since commit 8f6330a807f2642dc2a3cdf33347aa28a4c00a87:
2
2
3
Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging (2023-02-16 11:16:39 +0000)
3
Merge tag 'pull-maintainer-updates-060324-1' of https://gitlab.com/stsquad/qemu into staging (2024-03-06 16:56:20 +0000)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230216
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240308
8
8
9
for you to fetch changes up to caf01d6a435d9f4a95aeae2f9fc6cb8b889b1fb8:
9
for you to fetch changes up to bbf6c6dbead82292a20951eb1204442a6b838de9:
10
10
11
tests/qtest: Restrict tpm-tis-devices-{swtpm}-test to CONFIG_TCG (2023-02-16 16:28:53 +0000)
11
target/arm: Move v7m-related code from cpu32.c into a separate file (2024-03-08 14:45:03 +0000)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
target-arm queue:
14
target-arm queue:
15
* Some mostly M-profile-related code cleanups
15
* Implement FEAT_ECV
16
* avocado: Retire the boot_linux.py AArch64 TCG tests
16
* STM32L4x5: Implement GPIO device
17
* hw/arm/smmuv3: Add GBPA register
17
* Fix 32-bit SMOPA
18
* arm/virt: don't try to spell out the accelerator
18
* Refactor v7m related code from cpu32.c into its own file
19
* hw/arm: Attach PSPI module to NPCM7XX SoC
19
* hw/rtc/sun4v-rtc: Relicense to GPLv2-or-later
20
* Some cleanup/refactoring patches aiming towards
21
allowing building Arm targets without CONFIG_TCG
22
20
23
----------------------------------------------------------------
21
----------------------------------------------------------------
24
Alex Bennée (1):
22
Inès Varhol (3):
25
tests/avocado: retire the Aarch64 TCG tests from boot_linux.py
23
hw/gpio: Implement STM32L4x5 GPIO
24
hw/arm: Connect STM32L4x5 GPIO to STM32L4x5 SoC
25
tests/qtest: Add STM32L4x5 GPIO QTest testcase
26
26
27
Claudio Fontana (3):
27
Peter Maydell (9):
28
target/arm: rename handle_semihosting to tcg_handle_semihosting
28
target/arm: Move some register related defines to internals.h
29
target/arm: wrap psci call with tcg_enabled
29
target/arm: Timer _EL02 registers UNDEF for E2H == 0
30
target/arm: wrap call to aarch64_sve_change_el in tcg_enabled()
30
target/arm: use FIELD macro for CNTHCTL bit definitions
31
target/arm: Don't allow RES0 CNTHCTL_EL2 bits to be written
32
target/arm: Implement new FEAT_ECV trap bits
33
target/arm: Define CNTPCTSS_EL0 and CNTVCTSS_EL0
34
target/arm: Implement FEAT_ECV CNTPOFF_EL2 handling
35
target/arm: Enable FEAT_ECV for 'max' CPU
36
hw/rtc/sun4v-rtc: Relicense to GPLv2-or-later
31
37
32
Cornelia Huck (1):
38
Richard Henderson (1):
33
arm/virt: don't try to spell out the accelerator
39
target/arm: Fix 32-bit SMOPA
34
40
35
Fabiano Rosas (7):
41
Thomas Huth (1):
36
target/arm: Move PC alignment check
42
target/arm: Move v7m-related code from cpu32.c into a separate file
37
target/arm: Move cpregs code out of cpu.h
38
tests/avocado: Skip tests that require a missing accelerator
39
tests/avocado: Tag TCG tests with accel:tcg
40
target/arm: Use "max" as default cpu for the virt machine with KVM
41
tests/qtest: arm-cpu-features: Match tests to required accelerators
42
tests/qtest: Restrict tpm-tis-devices-{swtpm}-test to CONFIG_TCG
43
43
44
Hao Wu (3):
44
MAINTAINERS | 1 +
45
MAINTAINERS: Add myself to maintainers and remove Havard
45
docs/system/arm/b-l475e-iot01a.rst | 2 +-
46
hw/ssi: Add Nuvoton PSPI Module
46
docs/system/arm/emulation.rst | 1 +
47
hw/arm: Attach PSPI module to NPCM7XX SoC
47
include/hw/arm/stm32l4x5_soc.h | 2 +
48
include/hw/gpio/stm32l4x5_gpio.h | 71 +++++
49
include/hw/misc/stm32l4x5_syscfg.h | 3 +-
50
include/hw/rtc/sun4v-rtc.h | 2 +-
51
target/arm/cpu-features.h | 10 +
52
target/arm/cpu.h | 129 +--------
53
target/arm/internals.h | 151 ++++++++++
54
hw/arm/stm32l4x5_soc.c | 71 ++++-
55
hw/gpio/stm32l4x5_gpio.c | 477 ++++++++++++++++++++++++++++++++
56
hw/misc/stm32l4x5_syscfg.c | 1 +
57
hw/rtc/sun4v-rtc.c | 2 +-
58
target/arm/helper.c | 189 ++++++++++++-
59
target/arm/tcg/cpu-v7m.c | 290 +++++++++++++++++++
60
target/arm/tcg/cpu32.c | 261 ------------------
61
target/arm/tcg/cpu64.c | 1 +
62
target/arm/tcg/sme_helper.c | 77 +++---
63
tests/qtest/stm32l4x5_gpio-test.c | 551 +++++++++++++++++++++++++++++++++++++
64
tests/tcg/aarch64/sme-smopa-1.c | 47 ++++
65
tests/tcg/aarch64/sme-smopa-2.c | 54 ++++
66
hw/arm/Kconfig | 3 +-
67
hw/gpio/Kconfig | 3 +
68
hw/gpio/meson.build | 1 +
69
hw/gpio/trace-events | 6 +
70
target/arm/meson.build | 3 +
71
target/arm/tcg/meson.build | 3 +
72
target/arm/trace-events | 1 +
73
tests/qtest/meson.build | 3 +-
74
tests/tcg/aarch64/Makefile.target | 2 +-
75
31 files changed, 1962 insertions(+), 456 deletions(-)
76
create mode 100644 include/hw/gpio/stm32l4x5_gpio.h
77
create mode 100644 hw/gpio/stm32l4x5_gpio.c
78
create mode 100644 target/arm/tcg/cpu-v7m.c
79
create mode 100644 tests/qtest/stm32l4x5_gpio-test.c
80
create mode 100644 tests/tcg/aarch64/sme-smopa-1.c
81
create mode 100644 tests/tcg/aarch64/sme-smopa-2.c
48
82
49
Jean-Philippe Brucker (2):
50
hw/arm/smmu-common: Support 64-bit addresses
51
hw/arm/smmu-common: Fix TTB1 handling
52
53
Mostafa Saleh (1):
54
hw/arm/smmuv3: Add GBPA register
55
56
Philippe Mathieu-Daudé (12):
57
hw/intc/armv7m_nvic: Use OBJECT_DECLARE_SIMPLE_TYPE() macro
58
target/arm: Simplify arm_v7m_mmu_idx_for_secstate() for user emulation
59
target/arm: Reduce arm_v7m_mmu_idx_[all/for_secstate_and_priv]() scope
60
target/arm: Constify ID_PFR1 on user emulation
61
target/arm: Convert CPUARMState::eabi to boolean
62
target/arm: Avoid resetting CPUARMState::eabi field
63
target/arm: Restrict CPUARMState::gicv3state to sysemu
64
target/arm: Restrict CPUARMState::arm_boot_info to sysemu
65
target/arm: Restrict CPUARMState::nvic to sysemu
66
target/arm: Store CPUARMState::nvic as NVICState*
67
target/arm: Declare CPU <-> NVIC helpers in 'hw/intc/armv7m_nvic.h'
68
hw/arm: Add missing XLNX_ZYNQMP_ARM -> USB_DWC3 Kconfig dependency
69
70
MAINTAINERS | 8 +-
71
docs/system/arm/nuvoton.rst | 2 +-
72
hw/arm/smmuv3-internal.h | 7 +
73
include/hw/arm/npcm7xx.h | 2 +
74
include/hw/arm/smmu-common.h | 2 -
75
include/hw/arm/smmuv3.h | 1 +
76
include/hw/intc/armv7m_nvic.h | 128 +++++++++++++++++-
77
include/hw/ssi/npcm_pspi.h | 53 ++++++++
78
linux-user/user-internals.h | 2 +-
79
target/arm/cpregs.h | 98 ++++++++++++++
80
target/arm/cpu.h | 228 ++-------------------------------
81
target/arm/internals.h | 14 --
82
hw/arm/npcm7xx.c | 25 +++-
83
hw/arm/smmu-common.c | 4 +-
84
hw/arm/smmuv3.c | 43 ++++++-
85
hw/arm/virt.c | 10 +-
86
hw/intc/armv7m_nvic.c | 38 ++----
87
hw/ssi/npcm_pspi.c | 221 ++++++++++++++++++++++++++++++++
88
linux-user/arm/cpu_loop.c | 4 +-
89
target/arm/cpu.c | 5 +-
90
target/arm/cpu_tcg.c | 3 +
91
target/arm/helper.c | 31 +++--
92
target/arm/m_helper.c | 86 +++++++------
93
target/arm/machine.c | 18 +--
94
tests/qtest/arm-cpu-features.c | 28 ++--
95
hw/arm/Kconfig | 1 +
96
hw/ssi/meson.build | 2 +-
97
hw/ssi/trace-events | 5 +
98
tests/avocado/avocado_qemu/__init__.py | 4 +
99
tests/avocado/boot_linux.py | 48 ++-----
100
tests/avocado/boot_linux_console.py | 1 +
101
tests/avocado/machine_aarch64_virt.py | 63 ++++++++-
102
tests/avocado/reverse_debugging.py | 8 ++
103
tests/qtest/meson.build | 4 +-
104
34 files changed, 798 insertions(+), 399 deletions(-)
105
create mode 100644 include/hw/ssi/npcm_pspi.h
106
create mode 100644 hw/ssi/npcm_pspi.c
107
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
Manually convert to OBJECT_DECLARE_SIMPLE_TYPE() macro,
4
similarly to automatic conversion from commit 8063396bf3
5
("Use OBJECT_DECLARE_SIMPLE_TYPE when possible").
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230206223502.25122-2-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/intc/armv7m_nvic.h | 5 +----
13
1 file changed, 1 insertion(+), 4 deletions(-)
14
15
diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/intc/armv7m_nvic.h
18
+++ b/include/hw/intc/armv7m_nvic.h
19
@@ -XXX,XX +XXX,XX @@
20
#include "qom/object.h"
21
22
#define TYPE_NVIC "armv7m_nvic"
23
-
24
-typedef struct NVICState NVICState;
25
-DECLARE_INSTANCE_CHECKER(NVICState, NVIC,
26
- TYPE_NVIC)
27
+OBJECT_DECLARE_SIMPLE_TYPE(NVICState, NVIC)
28
29
/* Highest permitted number of exceptions (architectural limit) */
30
#define NVIC_MAX_VECTORS 512
31
--
32
2.34.1
33
34
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20230206223502.25122-3-philmd@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
target/arm/m_helper.c | 11 ++++++++---
10
1 file changed, 8 insertions(+), 3 deletions(-)
11
12
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/m_helper.c
15
+++ b/target/arm/m_helper.c
16
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
17
return 0;
18
}
19
20
-#else
21
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
22
+{
23
+ return ARMMMUIdx_MUser;
24
+}
25
+
26
+#else /* !CONFIG_USER_ONLY */
27
28
/*
29
* What kind of stack write are we doing? This affects how exceptions
30
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
31
return tt_resp;
32
}
33
34
-#endif /* !CONFIG_USER_ONLY */
35
-
36
ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
37
bool secstate, bool priv, bool negpri)
38
{
39
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
40
41
return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
42
}
43
+
44
+#endif /* !CONFIG_USER_ONLY */
45
--
46
2.34.1
47
48
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
cpu.h has a lot of #defines relating to CPU register fields.
2
Most of these aren't actually used outside target/arm code,
3
so there's no point in cluttering up the cpu.h file with them.
4
Move some easy ones to internals.h.
2
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
3
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 20240301183219.2424889-2-peter.maydell@linaro.org
5
Message-id: 20230206223502.25122-8-philmd@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
target/arm/cpu.h | 3 ++-
11
target/arm/cpu.h | 128 -----------------------------------------
9
1 file changed, 2 insertions(+), 1 deletion(-)
12
target/arm/internals.h | 128 +++++++++++++++++++++++++++++++++++++++++
13
2 files changed, 128 insertions(+), 128 deletions(-)
10
14
11
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu.h
17
--- a/target/arm/cpu.h
14
+++ b/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
15
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
19
@@ -XXX,XX +XXX,XX @@ typedef struct ARMGenericTimer {
16
20
uint64_t ctl; /* Timer Control register */
17
void *nvic;
21
} ARMGenericTimer;
18
const struct arm_boot_info *boot_info;
22
19
+#if !defined(CONFIG_USER_ONLY)
23
-#define VTCR_NSW (1u << 29)
20
/* Store GICv3CPUState to access from this struct */
24
-#define VTCR_NSA (1u << 30)
21
void *gicv3state;
25
-#define VSTCR_SW VTCR_NSW
22
-#if defined(CONFIG_USER_ONLY)
26
-#define VSTCR_SA VTCR_NSA
23
+#else /* CONFIG_USER_ONLY */
27
-
24
/* For usermode syscall translation. */
28
/* Define a maximum sized vector register.
25
bool eabi;
29
* For 32-bit, this is a 128-bit NEON/AdvSIMD register.
26
#endif /* CONFIG_USER_ONLY */
30
* For 64-bit, this is a 2048-bit SVE register.
31
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
32
#define SCTLR_SPINTMASK (1ULL << 62) /* FEAT_NMI */
33
#define SCTLR_TIDCP (1ULL << 63) /* FEAT_TIDCP1 */
34
35
-/* Bit definitions for CPACR (AArch32 only) */
36
-FIELD(CPACR, CP10, 20, 2)
37
-FIELD(CPACR, CP11, 22, 2)
38
-FIELD(CPACR, TRCDIS, 28, 1) /* matches CPACR_EL1.TTA */
39
-FIELD(CPACR, D32DIS, 30, 1) /* up to v7; RAZ in v8 */
40
-FIELD(CPACR, ASEDIS, 31, 1)
41
-
42
-/* Bit definitions for CPACR_EL1 (AArch64 only) */
43
-FIELD(CPACR_EL1, ZEN, 16, 2)
44
-FIELD(CPACR_EL1, FPEN, 20, 2)
45
-FIELD(CPACR_EL1, SMEN, 24, 2)
46
-FIELD(CPACR_EL1, TTA, 28, 1) /* matches CPACR.TRCDIS */
47
-
48
-/* Bit definitions for HCPTR (AArch32 only) */
49
-FIELD(HCPTR, TCP10, 10, 1)
50
-FIELD(HCPTR, TCP11, 11, 1)
51
-FIELD(HCPTR, TASE, 15, 1)
52
-FIELD(HCPTR, TTA, 20, 1)
53
-FIELD(HCPTR, TAM, 30, 1) /* matches CPTR_EL2.TAM */
54
-FIELD(HCPTR, TCPAC, 31, 1) /* matches CPTR_EL2.TCPAC */
55
-
56
-/* Bit definitions for CPTR_EL2 (AArch64 only) */
57
-FIELD(CPTR_EL2, TZ, 8, 1) /* !E2H */
58
-FIELD(CPTR_EL2, TFP, 10, 1) /* !E2H, matches HCPTR.TCP10 */
59
-FIELD(CPTR_EL2, TSM, 12, 1) /* !E2H */
60
-FIELD(CPTR_EL2, ZEN, 16, 2) /* E2H */
61
-FIELD(CPTR_EL2, FPEN, 20, 2) /* E2H */
62
-FIELD(CPTR_EL2, SMEN, 24, 2) /* E2H */
63
-FIELD(CPTR_EL2, TTA, 28, 1)
64
-FIELD(CPTR_EL2, TAM, 30, 1) /* matches HCPTR.TAM */
65
-FIELD(CPTR_EL2, TCPAC, 31, 1) /* matches HCPTR.TCPAC */
66
-
67
-/* Bit definitions for CPTR_EL3 (AArch64 only) */
68
-FIELD(CPTR_EL3, EZ, 8, 1)
69
-FIELD(CPTR_EL3, TFP, 10, 1)
70
-FIELD(CPTR_EL3, ESM, 12, 1)
71
-FIELD(CPTR_EL3, TTA, 20, 1)
72
-FIELD(CPTR_EL3, TAM, 30, 1)
73
-FIELD(CPTR_EL3, TCPAC, 31, 1)
74
-
75
-#define MDCR_MTPME (1U << 28)
76
-#define MDCR_TDCC (1U << 27)
77
-#define MDCR_HLP (1U << 26) /* MDCR_EL2 */
78
-#define MDCR_SCCD (1U << 23) /* MDCR_EL3 */
79
-#define MDCR_HCCD (1U << 23) /* MDCR_EL2 */
80
-#define MDCR_EPMAD (1U << 21)
81
-#define MDCR_EDAD (1U << 20)
82
-#define MDCR_TTRF (1U << 19)
83
-#define MDCR_STE (1U << 18) /* MDCR_EL3 */
84
-#define MDCR_SPME (1U << 17) /* MDCR_EL3 */
85
-#define MDCR_HPMD (1U << 17) /* MDCR_EL2 */
86
-#define MDCR_SDD (1U << 16)
87
-#define MDCR_SPD (3U << 14)
88
-#define MDCR_TDRA (1U << 11)
89
-#define MDCR_TDOSA (1U << 10)
90
-#define MDCR_TDA (1U << 9)
91
-#define MDCR_TDE (1U << 8)
92
-#define MDCR_HPME (1U << 7)
93
-#define MDCR_TPM (1U << 6)
94
-#define MDCR_TPMCR (1U << 5)
95
-#define MDCR_HPMN (0x1fU)
96
-
97
-/* Not all of the MDCR_EL3 bits are present in the 32-bit SDCR */
98
-#define SDCR_VALID_MASK (MDCR_MTPME | MDCR_TDCC | MDCR_SCCD | \
99
- MDCR_EPMAD | MDCR_EDAD | MDCR_TTRF | \
100
- MDCR_STE | MDCR_SPME | MDCR_SPD)
101
-
102
#define CPSR_M (0x1fU)
103
#define CPSR_T (1U << 5)
104
#define CPSR_F (1U << 6)
105
@@ -XXX,XX +XXX,XX @@ FIELD(CPTR_EL3, TCPAC, 31, 1)
106
#define XPSR_NZCV CPSR_NZCV
107
#define XPSR_IT CPSR_IT
108
109
-#define TTBCR_N (7U << 0) /* TTBCR.EAE==0 */
110
-#define TTBCR_T0SZ (7U << 0) /* TTBCR.EAE==1 */
111
-#define TTBCR_PD0 (1U << 4)
112
-#define TTBCR_PD1 (1U << 5)
113
-#define TTBCR_EPD0 (1U << 7)
114
-#define TTBCR_IRGN0 (3U << 8)
115
-#define TTBCR_ORGN0 (3U << 10)
116
-#define TTBCR_SH0 (3U << 12)
117
-#define TTBCR_T1SZ (3U << 16)
118
-#define TTBCR_A1 (1U << 22)
119
-#define TTBCR_EPD1 (1U << 23)
120
-#define TTBCR_IRGN1 (3U << 24)
121
-#define TTBCR_ORGN1 (3U << 26)
122
-#define TTBCR_SH1 (1U << 28)
123
-#define TTBCR_EAE (1U << 31)
124
-
125
-FIELD(VTCR, T0SZ, 0, 6)
126
-FIELD(VTCR, SL0, 6, 2)
127
-FIELD(VTCR, IRGN0, 8, 2)
128
-FIELD(VTCR, ORGN0, 10, 2)
129
-FIELD(VTCR, SH0, 12, 2)
130
-FIELD(VTCR, TG0, 14, 2)
131
-FIELD(VTCR, PS, 16, 3)
132
-FIELD(VTCR, VS, 19, 1)
133
-FIELD(VTCR, HA, 21, 1)
134
-FIELD(VTCR, HD, 22, 1)
135
-FIELD(VTCR, HWU59, 25, 1)
136
-FIELD(VTCR, HWU60, 26, 1)
137
-FIELD(VTCR, HWU61, 27, 1)
138
-FIELD(VTCR, HWU62, 28, 1)
139
-FIELD(VTCR, NSW, 29, 1)
140
-FIELD(VTCR, NSA, 30, 1)
141
-FIELD(VTCR, DS, 32, 1)
142
-FIELD(VTCR, SL2, 33, 1)
143
-
144
/* Bit definitions for ARMv8 SPSR (PSTATE) format.
145
* Only these are valid when in AArch64 mode; in
146
* AArch32 mode SPSRs are basically CPSR-format.
147
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
148
#define HCR_TWEDEN (1ULL << 59)
149
#define HCR_TWEDEL MAKE_64BIT_MASK(60, 4)
150
151
-#define HCRX_ENAS0 (1ULL << 0)
152
-#define HCRX_ENALS (1ULL << 1)
153
-#define HCRX_ENASR (1ULL << 2)
154
-#define HCRX_FNXS (1ULL << 3)
155
-#define HCRX_FGTNXS (1ULL << 4)
156
-#define HCRX_SMPME (1ULL << 5)
157
-#define HCRX_TALLINT (1ULL << 6)
158
-#define HCRX_VINMI (1ULL << 7)
159
-#define HCRX_VFNMI (1ULL << 8)
160
-#define HCRX_CMOW (1ULL << 9)
161
-#define HCRX_MCE2 (1ULL << 10)
162
-#define HCRX_MSCEN (1ULL << 11)
163
-
164
-#define HPFAR_NS (1ULL << 63)
165
-
166
#define SCR_NS (1ULL << 0)
167
#define SCR_IRQ (1ULL << 1)
168
#define SCR_FIQ (1ULL << 2)
169
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
170
#define SCR_GPF (1ULL << 48)
171
#define SCR_NSE (1ULL << 62)
172
173
-#define HSTR_TTEE (1 << 16)
174
-#define HSTR_TJDBX (1 << 17)
175
-
176
-#define CNTHCTL_CNTVMASK (1 << 18)
177
-#define CNTHCTL_CNTPMASK (1 << 19)
178
-
179
/* Return the current FPSCR value. */
180
uint32_t vfp_get_fpscr(CPUARMState *env);
181
void vfp_set_fpscr(CPUARMState *env, uint32_t val);
182
diff --git a/target/arm/internals.h b/target/arm/internals.h
183
index XXXXXXX..XXXXXXX 100644
184
--- a/target/arm/internals.h
185
+++ b/target/arm/internals.h
186
@@ -XXX,XX +XXX,XX @@ FIELD(DBGWCR, WT, 20, 1)
187
FIELD(DBGWCR, MASK, 24, 5)
188
FIELD(DBGWCR, SSCE, 29, 1)
189
190
+#define VTCR_NSW (1u << 29)
191
+#define VTCR_NSA (1u << 30)
192
+#define VSTCR_SW VTCR_NSW
193
+#define VSTCR_SA VTCR_NSA
194
+
195
+/* Bit definitions for CPACR (AArch32 only) */
196
+FIELD(CPACR, CP10, 20, 2)
197
+FIELD(CPACR, CP11, 22, 2)
198
+FIELD(CPACR, TRCDIS, 28, 1) /* matches CPACR_EL1.TTA */
199
+FIELD(CPACR, D32DIS, 30, 1) /* up to v7; RAZ in v8 */
200
+FIELD(CPACR, ASEDIS, 31, 1)
201
+
202
+/* Bit definitions for CPACR_EL1 (AArch64 only) */
203
+FIELD(CPACR_EL1, ZEN, 16, 2)
204
+FIELD(CPACR_EL1, FPEN, 20, 2)
205
+FIELD(CPACR_EL1, SMEN, 24, 2)
206
+FIELD(CPACR_EL1, TTA, 28, 1) /* matches CPACR.TRCDIS */
207
+
208
+/* Bit definitions for HCPTR (AArch32 only) */
209
+FIELD(HCPTR, TCP10, 10, 1)
210
+FIELD(HCPTR, TCP11, 11, 1)
211
+FIELD(HCPTR, TASE, 15, 1)
212
+FIELD(HCPTR, TTA, 20, 1)
213
+FIELD(HCPTR, TAM, 30, 1) /* matches CPTR_EL2.TAM */
214
+FIELD(HCPTR, TCPAC, 31, 1) /* matches CPTR_EL2.TCPAC */
215
+
216
+/* Bit definitions for CPTR_EL2 (AArch64 only) */
217
+FIELD(CPTR_EL2, TZ, 8, 1) /* !E2H */
218
+FIELD(CPTR_EL2, TFP, 10, 1) /* !E2H, matches HCPTR.TCP10 */
219
+FIELD(CPTR_EL2, TSM, 12, 1) /* !E2H */
220
+FIELD(CPTR_EL2, ZEN, 16, 2) /* E2H */
221
+FIELD(CPTR_EL2, FPEN, 20, 2) /* E2H */
222
+FIELD(CPTR_EL2, SMEN, 24, 2) /* E2H */
223
+FIELD(CPTR_EL2, TTA, 28, 1)
224
+FIELD(CPTR_EL2, TAM, 30, 1) /* matches HCPTR.TAM */
225
+FIELD(CPTR_EL2, TCPAC, 31, 1) /* matches HCPTR.TCPAC */
226
+
227
+/* Bit definitions for CPTR_EL3 (AArch64 only) */
228
+FIELD(CPTR_EL3, EZ, 8, 1)
229
+FIELD(CPTR_EL3, TFP, 10, 1)
230
+FIELD(CPTR_EL3, ESM, 12, 1)
231
+FIELD(CPTR_EL3, TTA, 20, 1)
232
+FIELD(CPTR_EL3, TAM, 30, 1)
233
+FIELD(CPTR_EL3, TCPAC, 31, 1)
234
+
235
+#define MDCR_MTPME (1U << 28)
236
+#define MDCR_TDCC (1U << 27)
237
+#define MDCR_HLP (1U << 26) /* MDCR_EL2 */
238
+#define MDCR_SCCD (1U << 23) /* MDCR_EL3 */
239
+#define MDCR_HCCD (1U << 23) /* MDCR_EL2 */
240
+#define MDCR_EPMAD (1U << 21)
241
+#define MDCR_EDAD (1U << 20)
242
+#define MDCR_TTRF (1U << 19)
243
+#define MDCR_STE (1U << 18) /* MDCR_EL3 */
244
+#define MDCR_SPME (1U << 17) /* MDCR_EL3 */
245
+#define MDCR_HPMD (1U << 17) /* MDCR_EL2 */
246
+#define MDCR_SDD (1U << 16)
247
+#define MDCR_SPD (3U << 14)
248
+#define MDCR_TDRA (1U << 11)
249
+#define MDCR_TDOSA (1U << 10)
250
+#define MDCR_TDA (1U << 9)
251
+#define MDCR_TDE (1U << 8)
252
+#define MDCR_HPME (1U << 7)
253
+#define MDCR_TPM (1U << 6)
254
+#define MDCR_TPMCR (1U << 5)
255
+#define MDCR_HPMN (0x1fU)
256
+
257
+/* Not all of the MDCR_EL3 bits are present in the 32-bit SDCR */
258
+#define SDCR_VALID_MASK (MDCR_MTPME | MDCR_TDCC | MDCR_SCCD | \
259
+ MDCR_EPMAD | MDCR_EDAD | MDCR_TTRF | \
260
+ MDCR_STE | MDCR_SPME | MDCR_SPD)
261
+
262
+#define TTBCR_N (7U << 0) /* TTBCR.EAE==0 */
263
+#define TTBCR_T0SZ (7U << 0) /* TTBCR.EAE==1 */
264
+#define TTBCR_PD0 (1U << 4)
265
+#define TTBCR_PD1 (1U << 5)
266
+#define TTBCR_EPD0 (1U << 7)
267
+#define TTBCR_IRGN0 (3U << 8)
268
+#define TTBCR_ORGN0 (3U << 10)
269
+#define TTBCR_SH0 (3U << 12)
270
+#define TTBCR_T1SZ (3U << 16)
271
+#define TTBCR_A1 (1U << 22)
272
+#define TTBCR_EPD1 (1U << 23)
273
+#define TTBCR_IRGN1 (3U << 24)
274
+#define TTBCR_ORGN1 (3U << 26)
275
+#define TTBCR_SH1 (1U << 28)
276
+#define TTBCR_EAE (1U << 31)
277
+
278
+FIELD(VTCR, T0SZ, 0, 6)
279
+FIELD(VTCR, SL0, 6, 2)
280
+FIELD(VTCR, IRGN0, 8, 2)
281
+FIELD(VTCR, ORGN0, 10, 2)
282
+FIELD(VTCR, SH0, 12, 2)
283
+FIELD(VTCR, TG0, 14, 2)
284
+FIELD(VTCR, PS, 16, 3)
285
+FIELD(VTCR, VS, 19, 1)
286
+FIELD(VTCR, HA, 21, 1)
287
+FIELD(VTCR, HD, 22, 1)
288
+FIELD(VTCR, HWU59, 25, 1)
289
+FIELD(VTCR, HWU60, 26, 1)
290
+FIELD(VTCR, HWU61, 27, 1)
291
+FIELD(VTCR, HWU62, 28, 1)
292
+FIELD(VTCR, NSW, 29, 1)
293
+FIELD(VTCR, NSA, 30, 1)
294
+FIELD(VTCR, DS, 32, 1)
295
+FIELD(VTCR, SL2, 33, 1)
296
+
297
+#define HCRX_ENAS0 (1ULL << 0)
298
+#define HCRX_ENALS (1ULL << 1)
299
+#define HCRX_ENASR (1ULL << 2)
300
+#define HCRX_FNXS (1ULL << 3)
301
+#define HCRX_FGTNXS (1ULL << 4)
302
+#define HCRX_SMPME (1ULL << 5)
303
+#define HCRX_TALLINT (1ULL << 6)
304
+#define HCRX_VINMI (1ULL << 7)
305
+#define HCRX_VFNMI (1ULL << 8)
306
+#define HCRX_CMOW (1ULL << 9)
307
+#define HCRX_MCE2 (1ULL << 10)
308
+#define HCRX_MSCEN (1ULL << 11)
309
+
310
+#define HPFAR_NS (1ULL << 63)
311
+
312
+#define HSTR_TTEE (1 << 16)
313
+#define HSTR_TJDBX (1 << 17)
314
+
315
+#define CNTHCTL_CNTVMASK (1 << 18)
316
+#define CNTHCTL_CNTPMASK (1 << 19)
317
+
318
/* We use a few fake FSR values for internal purposes in M profile.
319
* M profile cores don't have A/R format FSRs, but currently our
320
* get_phys_addr() code assumes A/R profile and reports failures via
27
--
321
--
28
2.34.1
322
2.34.1
29
323
30
324
diff view generated by jsdifflib
1
From: Claudio Fontana <cfontana@suse.de>
1
The timer _EL02 registers should UNDEF for invalid accesses from EL2
2
or EL3 when HCR_EL2.E2H == 0, not take a cp access trap. We were
3
delivering the exception to EL2 with the wrong syndrome.
2
4
3
for "all" builds (tcg + kvm), we want to avoid doing
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
the psci check if tcg is built-in, but not enabled.
5
6
Signed-off-by: Claudio Fontana <cfontana@suse.de>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Fabiano Rosas <farosas@suse.de>
7
Message-id: 20240301183219.2424889-3-peter.maydell@linaro.org
9
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
8
---
12
target/arm/helper.c | 3 ++-
9
target/arm/helper.c | 2 +-
13
1 file changed, 2 insertions(+), 1 deletion(-)
10
1 file changed, 1 insertion(+), 1 deletion(-)
14
11
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
14
--- a/target/arm/helper.c
18
+++ b/target/arm/helper.c
15
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static CPAccessResult e2h_access(CPUARMState *env, const ARMCPRegInfo *ri,
20
#include "hw/irq.h"
17
return CP_ACCESS_OK;
21
#include "sysemu/cpu-timers.h"
22
#include "sysemu/kvm.h"
23
+#include "sysemu/tcg.h"
24
#include "qapi/qapi-commands-machine-target.h"
25
#include "qapi/error.h"
26
#include "qemu/guest-random.h"
27
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_interrupt(CPUState *cs)
28
env->exception.syndrome);
29
}
18
}
30
19
if (!(arm_hcr_el2_eff(env) & HCR_E2H)) {
31
- if (arm_is_psci_call(cpu, cs->exception_index)) {
20
- return CP_ACCESS_TRAP;
32
+ if (tcg_enabled() && arm_is_psci_call(cpu, cs->exception_index)) {
21
+ return CP_ACCESS_TRAP_UNCATEGORIZED;
33
arm_handle_psci_call(cpu);
22
}
34
qemu_log_mask(CPU_LOG_INT, "...handled as PSCI call\n");
23
return CP_ACCESS_OK;
35
return;
24
}
36
--
25
--
37
2.34.1
26
2.34.1
38
39
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
We prefer the FIELD macro over ad-hoc #defines for register bits;
2
switch CNTHCTL to that style before we add any more bits.
2
3
3
arm_v7m_mmu_idx_all() and arm_v7m_mmu_idx_for_secstate_and_priv()
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
are only used for system emulation in m_helper.c.
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Move the definitions to avoid prototype forward declarations.
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230206223502.25122-4-philmd@linaro.org
7
Message-id: 20240301183219.2424889-4-peter.maydell@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
8
---
12
target/arm/internals.h | 14 --------
9
target/arm/internals.h | 27 +++++++++++++++++++++++++--
13
target/arm/m_helper.c | 74 +++++++++++++++++++++---------------------
10
target/arm/helper.c | 9 ++++-----
14
2 files changed, 37 insertions(+), 51 deletions(-)
11
2 files changed, 29 insertions(+), 7 deletions(-)
15
12
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
13
diff --git a/target/arm/internals.h b/target/arm/internals.h
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/internals.h
15
--- a/target/arm/internals.h
19
+++ b/target/arm/internals.h
16
+++ b/target/arm/internals.h
20
@@ -XXX,XX +XXX,XX @@ static inline ARMMMUIdx core_to_aa64_mmu_idx(int mmu_idx)
17
@@ -XXX,XX +XXX,XX @@ FIELD(VTCR, SL2, 33, 1)
21
18
#define HSTR_TTEE (1 << 16)
22
int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx);
19
#define HSTR_TJDBX (1 << 17)
23
20
24
-/*
21
-#define CNTHCTL_CNTVMASK (1 << 18)
25
- * Return the MMU index for a v7M CPU with all relevant information
22
-#define CNTHCTL_CNTPMASK (1 << 19)
26
- * manually specified.
23
+/*
27
- */
24
+ * Depending on the value of HCR_EL2.E2H, bits 0 and 1
28
-ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
25
+ * have different bit definitions, and EL1PCTEN might be
29
- bool secstate, bool priv, bool negpri);
26
+ * bit 0 or bit 10. We use _E2H1 and _E2H0 suffixes to
27
+ * disambiguate if necessary.
28
+ */
29
+FIELD(CNTHCTL, EL0PCTEN_E2H1, 0, 1)
30
+FIELD(CNTHCTL, EL0VCTEN_E2H1, 1, 1)
31
+FIELD(CNTHCTL, EL1PCTEN_E2H0, 0, 1)
32
+FIELD(CNTHCTL, EL1PCEN_E2H0, 1, 1)
33
+FIELD(CNTHCTL, EVNTEN, 2, 1)
34
+FIELD(CNTHCTL, EVNTDIR, 3, 1)
35
+FIELD(CNTHCTL, EVNTI, 4, 4)
36
+FIELD(CNTHCTL, EL0VTEN, 8, 1)
37
+FIELD(CNTHCTL, EL0PTEN, 9, 1)
38
+FIELD(CNTHCTL, EL1PCTEN_E2H1, 10, 1)
39
+FIELD(CNTHCTL, EL1PTEN, 11, 1)
40
+FIELD(CNTHCTL, ECV, 12, 1)
41
+FIELD(CNTHCTL, EL1TVT, 13, 1)
42
+FIELD(CNTHCTL, EL1TVCT, 14, 1)
43
+FIELD(CNTHCTL, EL1NVPCT, 15, 1)
44
+FIELD(CNTHCTL, EL1NVVCT, 16, 1)
45
+FIELD(CNTHCTL, EVNTIS, 17, 1)
46
+FIELD(CNTHCTL, CNTVMASK, 18, 1)
47
+FIELD(CNTHCTL, CNTPMASK, 19, 1)
48
49
/* We use a few fake FSR values for internal purposes in M profile.
50
* M profile cores don't have A/R format FSRs, but currently our
51
diff --git a/target/arm/helper.c b/target/arm/helper.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/helper.c
54
+++ b/target/arm/helper.c
55
@@ -XXX,XX +XXX,XX @@ static void gt_update_irq(ARMCPU *cpu, int timeridx)
56
* It is RES0 in Secure and NonSecure state.
57
*/
58
if ((ss == ARMSS_Root || ss == ARMSS_Realm) &&
59
- ((timeridx == GTIMER_VIRT && (cnthctl & CNTHCTL_CNTVMASK)) ||
60
- (timeridx == GTIMER_PHYS && (cnthctl & CNTHCTL_CNTPMASK)))) {
61
+ ((timeridx == GTIMER_VIRT && (cnthctl & R_CNTHCTL_CNTVMASK_MASK)) ||
62
+ (timeridx == GTIMER_PHYS && (cnthctl & R_CNTHCTL_CNTPMASK_MASK)))) {
63
irqstate = 0;
64
}
65
66
@@ -XXX,XX +XXX,XX @@ static void gt_cnthctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
67
{
68
ARMCPU *cpu = env_archcpu(env);
69
uint32_t oldval = env->cp15.cnthctl_el2;
30
-
70
-
31
-/*
71
raw_write(env, ri, value);
32
- * Return the MMU index for a v7M CPU in the specified security and
72
33
- * privilege state.
73
- if ((oldval ^ value) & CNTHCTL_CNTVMASK) {
34
- */
74
+ if ((oldval ^ value) & R_CNTHCTL_CNTVMASK_MASK) {
35
-ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
75
gt_update_irq(cpu, GTIMER_VIRT);
36
- bool secstate, bool priv);
76
- } else if ((oldval ^ value) & CNTHCTL_CNTPMASK) {
37
-
77
+ } else if ((oldval ^ value) & R_CNTHCTL_CNTPMASK_MASK) {
38
/* Return the MMU index for a v7M CPU in the specified security state */
78
gt_update_irq(cpu, GTIMER_PHYS);
39
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate);
79
}
40
41
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/m_helper.c
44
+++ b/target/arm/m_helper.c
45
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
46
47
#else /* !CONFIG_USER_ONLY */
48
49
+static ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
50
+ bool secstate, bool priv, bool negpri)
51
+{
52
+ ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
53
+
54
+ if (priv) {
55
+ mmu_idx |= ARM_MMU_IDX_M_PRIV;
56
+ }
57
+
58
+ if (negpri) {
59
+ mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
60
+ }
61
+
62
+ if (secstate) {
63
+ mmu_idx |= ARM_MMU_IDX_M_S;
64
+ }
65
+
66
+ return mmu_idx;
67
+}
68
+
69
+static ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
70
+ bool secstate, bool priv)
71
+{
72
+ bool negpri = armv7m_nvic_neg_prio_requested(env->nvic, secstate);
73
+
74
+ return arm_v7m_mmu_idx_all(env, secstate, priv, negpri);
75
+}
76
+
77
+/* Return the MMU index for a v7M CPU in the specified security state */
78
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
79
+{
80
+ bool priv = arm_v7m_is_handler_mode(env) ||
81
+ !(env->v7m.control[secstate] & 1);
82
+
83
+ return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
84
+}
85
+
86
/*
87
* What kind of stack write are we doing? This affects how exceptions
88
* generated during the stacking are treated.
89
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
90
return tt_resp;
91
}
80
}
92
93
-ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
94
- bool secstate, bool priv, bool negpri)
95
-{
96
- ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
97
-
98
- if (priv) {
99
- mmu_idx |= ARM_MMU_IDX_M_PRIV;
100
- }
101
-
102
- if (negpri) {
103
- mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
104
- }
105
-
106
- if (secstate) {
107
- mmu_idx |= ARM_MMU_IDX_M_S;
108
- }
109
-
110
- return mmu_idx;
111
-}
112
-
113
-ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
114
- bool secstate, bool priv)
115
-{
116
- bool negpri = armv7m_nvic_neg_prio_requested(env->nvic, secstate);
117
-
118
- return arm_v7m_mmu_idx_all(env, secstate, priv, negpri);
119
-}
120
-
121
-/* Return the MMU index for a v7M CPU in the specified security state */
122
-ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
123
-{
124
- bool priv = arm_v7m_is_handler_mode(env) ||
125
- !(env->v7m.control[secstate] & 1);
126
-
127
- return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
128
-}
129
-
130
#endif /* !CONFIG_USER_ONLY */
131
--
81
--
132
2.34.1
82
2.34.1
133
83
134
84
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
Don't allow the guest to write CNTHCTL_EL2 bits which don't exist.
2
This is not strictly architecturally required, but it is how we've
3
tended to implement registers more recently.
2
4
5
In particular, bits [19:18] are only present with FEAT_RME,
6
and bits [17:12] will only be present with FEAT_ECV.
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-id: 20240301183219.2424889-5-peter.maydell@linaro.org
5
Message-id: 20230206223502.25122-5-philmd@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
target/arm/helper.c | 12 ++++++++++--
12
target/arm/helper.c | 18 ++++++++++++++++++
9
1 file changed, 10 insertions(+), 2 deletions(-)
13
1 file changed, 18 insertions(+)
10
14
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
17
--- a/target/arm/helper.c
14
+++ b/target/arm/helper.c
18
+++ b/target/arm/helper.c
15
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
19
@@ -XXX,XX +XXX,XX @@ static void gt_cnthctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
16
}
17
}
18
19
+#ifndef CONFIG_USER_ONLY
20
/*
21
* We don't know until after realize whether there's a GICv3
22
* attached, and that is what registers the gicv3 sysregs.
23
@@ -XXX,XX +XXX,XX @@ static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri)
24
return pfr1;
25
}
26
27
-#ifndef CONFIG_USER_ONLY
28
static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
29
{
20
{
30
ARMCPU *cpu = env_archcpu(env);
21
ARMCPU *cpu = env_archcpu(env);
31
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
22
uint32_t oldval = env->cp15.cnthctl_el2;
32
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 1,
23
+ uint32_t valid_mask =
33
.access = PL1_R, .type = ARM_CP_NO_RAW,
24
+ R_CNTHCTL_EL0PCTEN_E2H1_MASK |
34
.accessfn = access_aa32_tid3,
25
+ R_CNTHCTL_EL0VCTEN_E2H1_MASK |
35
+#ifdef CONFIG_USER_ONLY
26
+ R_CNTHCTL_EVNTEN_MASK |
36
+ .type = ARM_CP_CONST,
27
+ R_CNTHCTL_EVNTDIR_MASK |
37
+ .resetvalue = cpu->isar.id_pfr1,
28
+ R_CNTHCTL_EVNTI_MASK |
38
+#else
29
+ R_CNTHCTL_EL0VTEN_MASK |
39
+ .type = ARM_CP_NO_RAW,
30
+ R_CNTHCTL_EL0PTEN_MASK |
40
+ .accessfn = access_aa32_tid3,
31
+ R_CNTHCTL_EL1PCTEN_E2H1_MASK |
41
.readfn = id_pfr1_read,
32
+ R_CNTHCTL_EL1PTEN_MASK;
42
- .writefn = arm_cp_write_ignore },
33
+
43
+ .writefn = arm_cp_write_ignore
34
+ if (cpu_isar_feature(aa64_rme, cpu)) {
44
+#endif
35
+ valid_mask |= R_CNTHCTL_CNTVMASK_MASK | R_CNTHCTL_CNTPMASK_MASK;
45
+ },
36
+ }
46
{ .name = "ID_DFR0", .state = ARM_CP_STATE_BOTH,
37
+
47
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2,
38
+ /* Clear RES0 bits */
48
.access = PL1_R, .type = ARM_CP_CONST,
39
+ value &= valid_mask;
40
+
41
raw_write(env, ri, value);
42
43
if ((oldval ^ value) & R_CNTHCTL_CNTVMASK_MASK) {
49
--
44
--
50
2.34.1
45
2.34.1
51
52
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20230206223502.25122-6-philmd@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
linux-user/user-internals.h | 2 +-
10
target/arm/cpu.h | 2 +-
11
linux-user/arm/cpu_loop.c | 4 ++--
12
3 files changed, 4 insertions(+), 4 deletions(-)
13
14
diff --git a/linux-user/user-internals.h b/linux-user/user-internals.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/linux-user/user-internals.h
17
+++ b/linux-user/user-internals.h
18
@@ -XXX,XX +XXX,XX @@ void print_termios(void *arg);
19
#ifdef TARGET_ARM
20
static inline int regpairs_aligned(CPUArchState *cpu_env, int num)
21
{
22
- return cpu_env->eabi == 1;
23
+ return cpu_env->eabi;
24
}
25
#elif defined(TARGET_MIPS) && defined(TARGET_ABI_MIPSO32)
26
static inline int regpairs_aligned(CPUArchState *cpu_env, int num) { return 1; }
27
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/cpu.h
30
+++ b/target/arm/cpu.h
31
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
32
33
#if defined(CONFIG_USER_ONLY)
34
/* For usermode syscall translation. */
35
- int eabi;
36
+ bool eabi;
37
#endif
38
39
struct CPUBreakpoint *cpu_breakpoint[16];
40
diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/linux-user/arm/cpu_loop.c
43
+++ b/linux-user/arm/cpu_loop.c
44
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
45
break;
46
case EXCP_SWI:
47
{
48
- env->eabi = 1;
49
+ env->eabi = true;
50
/* system call */
51
if (env->thumb) {
52
/* Thumb is always EABI style with syscall number in r7 */
53
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
54
* > 0xfffff and are handled below as out-of-range.
55
*/
56
n ^= ARM_SYSCALL_BASE;
57
- env->eabi = 0;
58
+ env->eabi = false;
59
}
60
}
61
62
--
63
2.34.1
64
65
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
Although the 'eabi' field is only used in user emulation where
4
CPU reset doesn't occur, it doesn't belong to the area to reset.
5
Move it after the 'end_reset_fields' for consistency.
6
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 20230206223502.25122-7-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 9 ++++-----
13
1 file changed, 4 insertions(+), 5 deletions(-)
14
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
20
ARMVectorReg zarray[ARM_MAX_VQ * 16];
21
#endif
22
23
-#if defined(CONFIG_USER_ONLY)
24
- /* For usermode syscall translation. */
25
- bool eabi;
26
-#endif
27
-
28
struct CPUBreakpoint *cpu_breakpoint[16];
29
struct CPUWatchpoint *cpu_watchpoint[16];
30
31
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
32
const struct arm_boot_info *boot_info;
33
/* Store GICv3CPUState to access from this struct */
34
void *gicv3state;
35
+#if defined(CONFIG_USER_ONLY)
36
+ /* For usermode syscall translation. */
37
+ bool eabi;
38
+#endif /* CONFIG_USER_ONLY */
39
40
#ifdef TARGET_TAGGED_ADDRESSES
41
/* Linux syscall tagged address support */
42
--
43
2.34.1
44
45
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-id: 20230206223502.25122-9-philmd@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/cpu.h | 2 +-
9
1 file changed, 1 insertion(+), 1 deletion(-)
10
11
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu.h
14
+++ b/target/arm/cpu.h
15
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
16
} sau;
17
18
void *nvic;
19
- const struct arm_boot_info *boot_info;
20
#if !defined(CONFIG_USER_ONLY)
21
+ const struct arm_boot_info *boot_info;
22
/* Store GICv3CPUState to access from this struct */
23
void *gicv3state;
24
#else /* CONFIG_USER_ONLY */
25
--
26
2.34.1
27
28
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20230206223502.25122-10-philmd@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/cpu.h | 2 +-
9
1 file changed, 1 insertion(+), 1 deletion(-)
10
11
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu.h
14
+++ b/target/arm/cpu.h
15
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
16
uint32_t ctrl;
17
} sau;
18
19
- void *nvic;
20
#if !defined(CONFIG_USER_ONLY)
21
+ void *nvic;
22
const struct arm_boot_info *boot_info;
23
/* Store GICv3CPUState to access from this struct */
24
void *gicv3state;
25
--
26
2.34.1
27
28
diff view generated by jsdifflib
1
From: Claudio Fontana <cfontana@suse.de>
1
The functionality defined by ID_AA64MMFR0_EL1.ECV == 1 is:
2
* four new trap bits for various counter and timer registers
3
* the CNTHCTL_EL2.EVNTIS and CNTKCTL_EL1.EVNTIS bits which control
4
scaling of the event stream. This is a no-op for us, because we don't
5
implement the event stream (our WFE is a NOP): all we need to do is
6
allow CNTHCTL_EL2.ENVTIS to be read and written.
7
* extensions to PMSCR_EL1.PCT, PMSCR_EL2.PCT, TRFCR_EL1.TS and
8
TRFCR_EL2.TS: these are all no-ops for us, because we don't implement
9
FEAT_SPE or FEAT_TRF.
10
* new registers CNTPCTSS_EL0 and NCTVCTSS_EL0 which are
11
"self-sychronizing" views of the CNTPCT_EL0 and CNTVCT_EL0, meaning
12
that no barriers are needed around their accesses. For us these
13
are just the same as the normal views, because all our sysregs are
14
inherently self-sychronizing.
2
15
3
Signed-off-by: Claudio Fontana <cfontana@suse.de>
16
In this commit we implement the trap handling and permit the new
17
CNTHCTL_EL2 bits to be written.
18
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Fabiano Rosas <farosas@suse.de>
21
Message-id: 20240301183219.2424889-6-peter.maydell@linaro.org
6
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
22
---
9
target/arm/helper.c | 12 +++++++-----
23
target/arm/cpu-features.h | 5 ++++
10
1 file changed, 7 insertions(+), 5 deletions(-)
24
target/arm/helper.c | 51 +++++++++++++++++++++++++++++++++++----
25
2 files changed, 51 insertions(+), 5 deletions(-)
11
26
27
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/cpu-features.h
30
+++ b/target/arm/cpu-features.h
31
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_fgt(const ARMISARegisters *id)
32
return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, FGT) != 0;
33
}
34
35
+static inline bool isar_feature_aa64_ecv_traps(const ARMISARegisters *id)
36
+{
37
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, ECV) > 0;
38
+}
39
+
40
static inline bool isar_feature_aa64_vh(const ARMISARegisters *id)
41
{
42
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0;
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
43
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
45
--- a/target/arm/helper.c
15
+++ b/target/arm/helper.c
46
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
47
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx,
17
unsigned int cur_el = arm_current_el(env);
48
: !extract32(env->cp15.cnthctl_el2, 0, 1))) {
18
int rt;
49
return CP_ACCESS_TRAP_EL2;
19
50
}
20
- /*
51
+ if (has_el2 && timeridx == GTIMER_VIRT) {
21
- * Note that new_el can never be 0. If cur_el is 0, then
52
+ if (FIELD_EX64(env->cp15.cnthctl_el2, CNTHCTL, EL1TVCT)) {
22
- * el0_a64 is is_a64(), else el0_a64 is ignored.
53
+ return CP_ACCESS_TRAP_EL2;
23
- */
54
+ }
24
- aarch64_sve_change_el(env, cur_el, new_el, is_a64(env));
55
+ }
25
+ if (tcg_enabled()) {
56
break;
26
+ /*
57
}
27
+ * Note that new_el can never be 0. If cur_el is 0, then
58
return CP_ACCESS_OK;
28
+ * el0_a64 is is_a64(), else el0_a64 is ignored.
59
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gt_timer_access(CPUARMState *env, int timeridx,
29
+ */
60
}
30
+ aarch64_sve_change_el(env, cur_el, new_el, is_a64(env));
61
}
62
}
63
+ if (has_el2 && timeridx == GTIMER_VIRT) {
64
+ if (FIELD_EX64(env->cp15.cnthctl_el2, CNTHCTL, EL1TVT)) {
65
+ return CP_ACCESS_TRAP_EL2;
66
+ }
67
+ }
68
break;
69
}
70
return CP_ACCESS_OK;
71
@@ -XXX,XX +XXX,XX @@ static void gt_cnthctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
72
if (cpu_isar_feature(aa64_rme, cpu)) {
73
valid_mask |= R_CNTHCTL_CNTVMASK_MASK | R_CNTHCTL_CNTPMASK_MASK;
74
}
75
+ if (cpu_isar_feature(aa64_ecv_traps, cpu)) {
76
+ valid_mask |=
77
+ R_CNTHCTL_EL1TVT_MASK |
78
+ R_CNTHCTL_EL1TVCT_MASK |
79
+ R_CNTHCTL_EL1NVPCT_MASK |
80
+ R_CNTHCTL_EL1NVVCT_MASK |
81
+ R_CNTHCTL_EVNTIS_MASK;
31
+ }
82
+ }
32
83
33
if (cur_el < new_el) {
84
/* Clear RES0 bits */
34
/*
85
value &= valid_mask;
86
@@ -XXX,XX +XXX,XX @@ static CPAccessResult e2h_access(CPUARMState *env, const ARMCPRegInfo *ri,
87
{
88
if (arm_current_el(env) == 1) {
89
/* This must be a FEAT_NV access */
90
- /* TODO: FEAT_ECV will need to check CNTHCTL_EL2 here */
91
return CP_ACCESS_OK;
92
}
93
if (!(arm_hcr_el2_eff(env) & HCR_E2H)) {
94
@@ -XXX,XX +XXX,XX @@ static CPAccessResult e2h_access(CPUARMState *env, const ARMCPRegInfo *ri,
95
return CP_ACCESS_OK;
96
}
97
98
+static CPAccessResult access_el1nvpct(CPUARMState *env, const ARMCPRegInfo *ri,
99
+ bool isread)
100
+{
101
+ if (arm_current_el(env) == 1) {
102
+ /* This must be a FEAT_NV access with NVx == 101 */
103
+ if (FIELD_EX64(env->cp15.cnthctl_el2, CNTHCTL, EL1NVPCT)) {
104
+ return CP_ACCESS_TRAP_EL2;
105
+ }
106
+ }
107
+ return e2h_access(env, ri, isread);
108
+}
109
+
110
+static CPAccessResult access_el1nvvct(CPUARMState *env, const ARMCPRegInfo *ri,
111
+ bool isread)
112
+{
113
+ if (arm_current_el(env) == 1) {
114
+ /* This must be a FEAT_NV access with NVx == 101 */
115
+ if (FIELD_EX64(env->cp15.cnthctl_el2, CNTHCTL, EL1NVVCT)) {
116
+ return CP_ACCESS_TRAP_EL2;
117
+ }
118
+ }
119
+ return e2h_access(env, ri, isread);
120
+}
121
+
122
/* Test if system register redirection is to occur in the current state. */
123
static bool redirect_for_e2h(CPUARMState *env)
124
{
125
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vhe_reginfo[] = {
126
{ .name = "CNTP_CTL_EL02", .state = ARM_CP_STATE_AA64,
127
.opc0 = 3, .opc1 = 5, .crn = 14, .crm = 2, .opc2 = 1,
128
.type = ARM_CP_IO | ARM_CP_ALIAS,
129
- .access = PL2_RW, .accessfn = e2h_access,
130
+ .access = PL2_RW, .accessfn = access_el1nvpct,
131
.nv2_redirect_offset = 0x180 | NV2_REDIR_NO_NV1,
132
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl),
133
.writefn = gt_phys_ctl_write, .raw_writefn = raw_write },
134
{ .name = "CNTV_CTL_EL02", .state = ARM_CP_STATE_AA64,
135
.opc0 = 3, .opc1 = 5, .crn = 14, .crm = 3, .opc2 = 1,
136
.type = ARM_CP_IO | ARM_CP_ALIAS,
137
- .access = PL2_RW, .accessfn = e2h_access,
138
+ .access = PL2_RW, .accessfn = access_el1nvvct,
139
.nv2_redirect_offset = 0x170 | NV2_REDIR_NO_NV1,
140
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl),
141
.writefn = gt_virt_ctl_write, .raw_writefn = raw_write },
142
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vhe_reginfo[] = {
143
.type = ARM_CP_IO | ARM_CP_ALIAS,
144
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval),
145
.nv2_redirect_offset = 0x178 | NV2_REDIR_NO_NV1,
146
- .access = PL2_RW, .accessfn = e2h_access,
147
+ .access = PL2_RW, .accessfn = access_el1nvpct,
148
.writefn = gt_phys_cval_write, .raw_writefn = raw_write },
149
{ .name = "CNTV_CVAL_EL02", .state = ARM_CP_STATE_AA64,
150
.opc0 = 3, .opc1 = 5, .crn = 14, .crm = 3, .opc2 = 2,
151
.type = ARM_CP_IO | ARM_CP_ALIAS,
152
.nv2_redirect_offset = 0x168 | NV2_REDIR_NO_NV1,
153
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval),
154
- .access = PL2_RW, .accessfn = e2h_access,
155
+ .access = PL2_RW, .accessfn = access_el1nvvct,
156
.writefn = gt_virt_cval_write, .raw_writefn = raw_write },
157
#endif
158
};
35
--
159
--
36
2.34.1
160
2.34.1
37
38
diff view generated by jsdifflib
1
From: Claudio Fontana <cfontana@suse.de>
1
For FEAT_ECV, new registers CNTPCTSS_EL0 and CNTVCTSS_EL0 are
2
defined, which are "self-synchronized" views of the physical and
3
virtual counts as seen in the CNTPCT_EL0 and CNTVCT_EL0 registers
4
(meaning that no barriers are needed around accesses to them to
5
ensure that reads of them do not occur speculatively and out-of-order
6
with other instructions).
2
7
3
make it clearer from the name that this is a tcg-only function.
8
For QEMU, all our system registers are self-synchronized, so we can
9
simply copy the existing implementation of CNTPCT_EL0 and CNTVCT_EL0
10
to the new register encodings.
4
11
5
Signed-off-by: Claudio Fontana <cfontana@suse.de>
12
This means we now implement all the functionality required for
6
Signed-off-by: Fabiano Rosas <farosas@suse.de>
13
ID_AA64MMFR0_EL1.ECV == 0b0001.
14
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
17
Message-id: 20240301183219.2424889-7-peter.maydell@linaro.org
9
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
18
---
12
target/arm/helper.c | 4 ++--
19
target/arm/helper.c | 43 +++++++++++++++++++++++++++++++++++++++++++
13
1 file changed, 2 insertions(+), 2 deletions(-)
20
1 file changed, 43 insertions(+)
14
21
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
22
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
24
--- a/target/arm/helper.c
18
+++ b/target/arm/helper.c
25
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
26
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
20
* trapped to the hypervisor in KVM.
27
},
21
*/
28
};
22
#ifdef CONFIG_TCG
29
23
-static void handle_semihosting(CPUState *cs)
30
+/*
24
+static void tcg_handle_semihosting(CPUState *cs)
31
+ * FEAT_ECV adds extra views of CNTVCT_EL0 and CNTPCT_EL0 which
25
{
32
+ * are "self-synchronizing". For QEMU all sysregs are self-synchronizing,
26
ARMCPU *cpu = ARM_CPU(cs);
33
+ * so our implementations here are identical to the normal registers.
27
CPUARMState *env = &cpu->env;
34
+ */
28
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_interrupt(CPUState *cs)
35
+static const ARMCPRegInfo gen_timer_ecv_cp_reginfo[] = {
29
*/
36
+ { .name = "CNTVCTSS", .cp = 15, .crm = 14, .opc1 = 9,
30
#ifdef CONFIG_TCG
37
+ .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_RAW | ARM_CP_IO,
31
if (cs->exception_index == EXCP_SEMIHOST) {
38
+ .accessfn = gt_vct_access,
32
- handle_semihosting(cs);
39
+ .readfn = gt_virt_cnt_read, .resetfn = arm_cp_reset_ignore,
33
+ tcg_handle_semihosting(cs);
40
+ },
34
return;
41
+ { .name = "CNTVCTSS_EL0", .state = ARM_CP_STATE_AA64,
42
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 6,
43
+ .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO,
44
+ .accessfn = gt_vct_access, .readfn = gt_virt_cnt_read,
45
+ },
46
+ { .name = "CNTPCTSS", .cp = 15, .crm = 14, .opc1 = 8,
47
+ .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_RAW | ARM_CP_IO,
48
+ .accessfn = gt_pct_access,
49
+ .readfn = gt_cnt_read, .resetfn = arm_cp_reset_ignore,
50
+ },
51
+ { .name = "CNTPCTSS_EL0", .state = ARM_CP_STATE_AA64,
52
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 5,
53
+ .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO,
54
+ .accessfn = gt_pct_access, .readfn = gt_cnt_read,
55
+ },
56
+};
57
+
58
#else
59
60
/*
61
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
62
},
63
};
64
65
+/*
66
+ * CNTVCTSS_EL0 has the same trap conditions as CNTVCT_EL0, so it also
67
+ * is exposed to userspace by Linux.
68
+ */
69
+static const ARMCPRegInfo gen_timer_ecv_cp_reginfo[] = {
70
+ { .name = "CNTVCTSS_EL0", .state = ARM_CP_STATE_AA64,
71
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 6,
72
+ .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO,
73
+ .readfn = gt_virt_cnt_read,
74
+ },
75
+};
76
+
77
#endif
78
79
static void par_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
80
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
81
if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) {
82
define_arm_cp_regs(cpu, generic_timer_cp_reginfo);
35
}
83
}
36
#endif
84
+ if (cpu_isar_feature(aa64_ecv_traps, cpu)) {
85
+ define_arm_cp_regs(cpu, gen_timer_ecv_cp_reginfo);
86
+ }
87
if (arm_feature(env, ARM_FEATURE_VAPA)) {
88
ARMCPRegInfo vapa_cp_reginfo[] = {
89
{ .name = "PAR", .cp = 15, .crn = 7, .crm = 4, .opc1 = 0, .opc2 = 0,
37
--
90
--
38
2.34.1
91
2.34.1
39
40
diff view generated by jsdifflib
1
From: Mostafa Saleh <smostafa@google.com>
1
When ID_AA64MMFR0_EL1.ECV is 0b0010, a new register CNTPOFF_EL2 is
2
implemented. This is similar to the existing CNTVOFF_EL2, except
3
that it controls a hypervisor-adjustable offset made to the physical
4
counter and timer.
2
5
3
GBPA register can be used to globally abort all
6
Implement the handling for this register, which includes control/trap
4
transactions.
7
bits in SCR_EL3 and CNTHCTL_EL2.
5
8
6
It is described in the SMMU manual in "6.3.14 SMMU_GBPA".
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
ABORT reset value is IMPLEMENTATION DEFINED, it is chosen to
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
be zero(Do not abort incoming transactions).
11
Message-id: 20240301183219.2424889-8-peter.maydell@linaro.org
12
---
13
target/arm/cpu-features.h | 5 +++
14
target/arm/cpu.h | 1 +
15
target/arm/helper.c | 68 +++++++++++++++++++++++++++++++++++++--
16
target/arm/trace-events | 1 +
17
4 files changed, 73 insertions(+), 2 deletions(-)
9
18
10
Other fields have default values of Use Incoming.
19
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
11
12
If UPDATE is not set, the write is ignored. This is the only permitted
13
behavior in SMMUv3.2 and later.(6.3.14.1 Update procedure)
14
15
As this patch adds a new state to the SMMU (GBPA), it is added
16
in a new subsection for forward migration compatibility.
17
GBPA is only migrated if its value is different from the reset value.
18
It does this to be backward migration compatible if SW didn't write
19
the register.
20
21
Signed-off-by: Mostafa Saleh <smostafa@google.com>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Reviewed-by: Eric Auger <eric.auger@redhat.com>
24
Message-id: 20230214094009.2445653-1-smostafa@google.com
25
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
---
28
hw/arm/smmuv3-internal.h | 7 +++++++
29
include/hw/arm/smmuv3.h | 1 +
30
hw/arm/smmuv3.c | 43 +++++++++++++++++++++++++++++++++++++++-
31
3 files changed, 50 insertions(+), 1 deletion(-)
32
33
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
34
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/smmuv3-internal.h
21
--- a/target/arm/cpu-features.h
36
+++ b/hw/arm/smmuv3-internal.h
22
+++ b/target/arm/cpu-features.h
37
@@ -XXX,XX +XXX,XX @@ REG32(CR0ACK, 0x24)
23
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ecv_traps(const ARMISARegisters *id)
38
REG32(CR1, 0x28)
24
return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, ECV) > 0;
39
REG32(CR2, 0x2c)
25
}
40
REG32(STATUSR, 0x40)
26
41
+REG32(GBPA, 0x44)
27
+static inline bool isar_feature_aa64_ecv(const ARMISARegisters *id)
42
+ FIELD(GBPA, ABORT, 20, 1)
28
+{
43
+ FIELD(GBPA, UPDATE, 31, 1)
29
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, ECV) > 1;
30
+}
44
+
31
+
45
+/* Use incoming. */
32
static inline bool isar_feature_aa64_vh(const ARMISARegisters *id)
46
+#define SMMU_GBPA_RESET_VAL 0x1000
33
{
34
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0;
35
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/cpu.h
38
+++ b/target/arm/cpu.h
39
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
40
uint64_t c14_cntkctl; /* Timer Control register */
41
uint64_t cnthctl_el2; /* Counter/Timer Hyp Control register */
42
uint64_t cntvoff_el2; /* Counter Virtual Offset register */
43
+ uint64_t cntpoff_el2; /* Counter Physical Offset register */
44
ARMGenericTimer c14_timer[NUM_GTIMERS];
45
uint32_t c15_cpar; /* XScale Coprocessor Access Register */
46
uint32_t c15_ticonfig; /* TI925T configuration byte. */
47
diff --git a/target/arm/helper.c b/target/arm/helper.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/helper.c
50
+++ b/target/arm/helper.c
51
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
52
if (cpu_isar_feature(aa64_rme, cpu)) {
53
valid_mask |= SCR_NSE | SCR_GPF;
54
}
55
+ if (cpu_isar_feature(aa64_ecv, cpu)) {
56
+ valid_mask |= SCR_ECVEN;
57
+ }
58
} else {
59
valid_mask &= ~(SCR_RW | SCR_ST);
60
if (cpu_isar_feature(aa32_ras, cpu)) {
61
@@ -XXX,XX +XXX,XX @@ void gt_rme_post_el_change(ARMCPU *cpu, void *ignored)
62
gt_update_irq(cpu, GTIMER_PHYS);
63
}
64
65
+static uint64_t gt_phys_raw_cnt_offset(CPUARMState *env)
66
+{
67
+ if ((env->cp15.scr_el3 & SCR_ECVEN) &&
68
+ FIELD_EX64(env->cp15.cnthctl_el2, CNTHCTL, ECV) &&
69
+ arm_is_el2_enabled(env) &&
70
+ (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
71
+ return env->cp15.cntpoff_el2;
72
+ }
73
+ return 0;
74
+}
47
+
75
+
48
REG32(IRQ_CTRL, 0x50)
76
+static uint64_t gt_phys_cnt_offset(CPUARMState *env)
49
FIELD(IRQ_CTRL, GERROR_IRQEN, 0, 1)
77
+{
50
FIELD(IRQ_CTRL, PRI_IRQEN, 1, 1)
78
+ if (arm_current_el(env) >= 2) {
51
diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
79
+ return 0;
52
index XXXXXXX..XXXXXXX 100644
80
+ }
53
--- a/include/hw/arm/smmuv3.h
81
+ return gt_phys_raw_cnt_offset(env);
54
+++ b/include/hw/arm/smmuv3.h
82
+}
55
@@ -XXX,XX +XXX,XX @@ struct SMMUv3State {
83
+
56
uint32_t cr[3];
84
static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
57
uint32_t cr0ack;
85
{
58
uint32_t statusr;
86
ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx];
59
+ uint32_t gbpa;
87
@@ -XXX,XX +XXX,XX @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
60
uint32_t irq_ctrl;
88
* reset timer to when ISTATUS next has to change
61
uint32_t gerror;
89
*/
62
uint32_t gerrorn;
90
uint64_t offset = timeridx == GTIMER_VIRT ?
63
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
91
- cpu->env.cp15.cntvoff_el2 : 0;
64
index XXXXXXX..XXXXXXX 100644
92
+ cpu->env.cp15.cntvoff_el2 : gt_phys_raw_cnt_offset(&cpu->env);
65
--- a/hw/arm/smmuv3.c
93
uint64_t count = gt_get_countervalue(&cpu->env);
66
+++ b/hw/arm/smmuv3.c
94
/* Note that this must be unsigned 64 bit arithmetic: */
67
@@ -XXX,XX +XXX,XX @@ static void smmuv3_init_regs(SMMUv3State *s)
95
int istatus = count - offset >= gt->cval;
68
s->gerror = 0;
96
@@ -XXX,XX +XXX,XX @@ static void gt_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri,
69
s->gerrorn = 0;
97
70
s->statusr = 0;
98
static uint64_t gt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
71
+ s->gbpa = SMMU_GBPA_RESET_VAL;
99
{
100
- return gt_get_countervalue(env);
101
+ return gt_get_countervalue(env) - gt_phys_cnt_offset(env);
72
}
102
}
73
103
74
static int smmu_get_ste(SMMUv3State *s, dma_addr_t addr, STE *buf,
104
static uint64_t gt_virt_cnt_offset(CPUARMState *env)
75
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
105
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
76
qemu_mutex_lock(&s->mutex);
106
case GTIMER_HYPVIRT:
77
107
offset = gt_virt_cnt_offset(env);
78
if (!smmu_enabled(s)) {
108
break;
79
- status = SMMU_TRANS_DISABLE;
109
+ case GTIMER_PHYS:
80
+ if (FIELD_EX32(s->gbpa, GBPA, ABORT)) {
110
+ offset = gt_phys_cnt_offset(env);
81
+ status = SMMU_TRANS_ABORT;
111
+ break;
82
+ } else {
83
+ status = SMMU_TRANS_DISABLE;
84
+ }
85
goto epilogue;
86
}
112
}
87
113
88
@@ -XXX,XX +XXX,XX @@ static MemTxResult smmu_writel(SMMUv3State *s, hwaddr offset,
114
return (uint32_t)(env->cp15.c14_timer[timeridx].cval -
89
case A_GERROR_IRQ_CFG2:
115
@@ -XXX,XX +XXX,XX @@ static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
90
s->gerror_irq_cfg2 = data;
116
case GTIMER_HYPVIRT:
91
return MEMTX_OK;
117
offset = gt_virt_cnt_offset(env);
92
+ case A_GBPA:
118
break;
93
+ /*
119
+ case GTIMER_PHYS:
94
+ * If UPDATE is not set, the write is ignored. This is the only
120
+ offset = gt_phys_cnt_offset(env);
95
+ * permitted behavior in SMMUv3.2 and later.
121
+ break;
96
+ */
122
}
97
+ if (data & R_GBPA_UPDATE_MASK) {
123
98
+ /* Ignore update bit as write is synchronous. */
124
trace_arm_gt_tval_write(timeridx, value);
99
+ s->gbpa = data & ~R_GBPA_UPDATE_MASK;
125
@@ -XXX,XX +XXX,XX @@ static void gt_cnthctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
100
+ }
126
R_CNTHCTL_EL1NVVCT_MASK |
101
+ return MEMTX_OK;
127
R_CNTHCTL_EVNTIS_MASK;
102
case A_STRTAB_BASE: /* 64b */
128
}
103
s->strtab_base = deposit64(s->strtab_base, 0, 32, data);
129
+ if (cpu_isar_feature(aa64_ecv, cpu)) {
104
return MEMTX_OK;
130
+ valid_mask |= R_CNTHCTL_ECV_MASK;
105
@@ -XXX,XX +XXX,XX @@ static MemTxResult smmu_readl(SMMUv3State *s, hwaddr offset,
131
+ }
106
case A_STATUSR:
132
107
*data = s->statusr;
133
/* Clear RES0 bits */
108
return MEMTX_OK;
134
value &= valid_mask;
109
+ case A_GBPA:
135
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gen_timer_ecv_cp_reginfo[] = {
110
+ *data = s->gbpa;
111
+ return MEMTX_OK;
112
case A_IRQ_CTRL:
113
case A_IRQ_CTRL_ACK:
114
*data = s->irq_ctrl;
115
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_smmuv3_queue = {
116
},
136
},
117
};
137
};
118
138
119
+static bool smmuv3_gbpa_needed(void *opaque)
139
+static CPAccessResult gt_cntpoff_access(CPUARMState *env,
140
+ const ARMCPRegInfo *ri,
141
+ bool isread)
120
+{
142
+{
121
+ SMMUv3State *s = opaque;
143
+ if (arm_current_el(env) == 2 && !(env->cp15.scr_el3 & SCR_ECVEN)) {
122
+
144
+ return CP_ACCESS_TRAP_EL3;
123
+ /* Only migrate GBPA if it has different reset value. */
145
+ }
124
+ return s->gbpa != SMMU_GBPA_RESET_VAL;
146
+ return CP_ACCESS_OK;
125
+}
147
+}
126
+
148
+
127
+static const VMStateDescription vmstate_gbpa = {
149
+static void gt_cntpoff_write(CPUARMState *env, const ARMCPRegInfo *ri,
128
+ .name = "smmuv3/gbpa",
150
+ uint64_t value)
129
+ .version_id = 1,
151
+{
130
+ .minimum_version_id = 1,
152
+ ARMCPU *cpu = env_archcpu(env);
131
+ .needed = smmuv3_gbpa_needed,
153
+
132
+ .fields = (VMStateField[]) {
154
+ trace_arm_gt_cntpoff_write(value);
133
+ VMSTATE_UINT32(gbpa, SMMUv3State),
155
+ raw_write(env, ri, value);
134
+ VMSTATE_END_OF_LIST()
156
+ gt_recalc_timer(cpu, GTIMER_PHYS);
157
+}
158
+
159
+static const ARMCPRegInfo gen_timer_cntpoff_reginfo = {
160
+ .name = "CNTPOFF_EL2", .state = ARM_CP_STATE_AA64,
161
+ .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 0, .opc2 = 6,
162
+ .access = PL2_RW, .type = ARM_CP_IO, .resetvalue = 0,
163
+ .accessfn = gt_cntpoff_access, .writefn = gt_cntpoff_write,
164
+ .nv2_redirect_offset = 0x1a8,
165
+ .fieldoffset = offsetof(CPUARMState, cp15.cntpoff_el2),
166
+};
167
#else
168
169
/*
170
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
171
if (cpu_isar_feature(aa64_ecv_traps, cpu)) {
172
define_arm_cp_regs(cpu, gen_timer_ecv_cp_reginfo);
173
}
174
+#ifndef CONFIG_USER_ONLY
175
+ if (cpu_isar_feature(aa64_ecv, cpu)) {
176
+ define_one_arm_cp_reg(cpu, &gen_timer_cntpoff_reginfo);
135
+ }
177
+ }
136
+};
178
+#endif
137
+
179
if (arm_feature(env, ARM_FEATURE_VAPA)) {
138
static const VMStateDescription vmstate_smmuv3 = {
180
ARMCPRegInfo vapa_cp_reginfo[] = {
139
.name = "smmuv3",
181
{ .name = "PAR", .cp = 15, .crn = 7, .crm = 4, .opc1 = 0, .opc2 = 0,
140
.version_id = 1,
182
diff --git a/target/arm/trace-events b/target/arm/trace-events
141
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_smmuv3 = {
183
index XXXXXXX..XXXXXXX 100644
142
184
--- a/target/arm/trace-events
143
VMSTATE_END_OF_LIST(),
185
+++ b/target/arm/trace-events
144
},
186
@@ -XXX,XX +XXX,XX @@ arm_gt_tval_write(int timer, uint64_t value) "gt_tval_write: timer %d value 0x%"
145
+ .subsections = (const VMStateDescription * []) {
187
arm_gt_ctl_write(int timer, uint64_t value) "gt_ctl_write: timer %d value 0x%" PRIx64
146
+ &vmstate_gbpa,
188
arm_gt_imask_toggle(int timer) "gt_ctl_write: timer %d IMASK toggle"
147
+ NULL
189
arm_gt_cntvoff_write(uint64_t value) "gt_cntvoff_write: value 0x%" PRIx64
148
+ }
190
+arm_gt_cntpoff_write(uint64_t value) "gt_cntpoff_write: value 0x%" PRIx64
149
};
191
arm_gt_update_irq(int timer, int irqstate) "gt_update_irq: timer %d irqstate %d"
150
192
151
static void smmuv3_instance_init(Object *obj)
193
# kvm.c
152
--
194
--
153
2.34.1
195
2.34.1
diff view generated by jsdifflib
1
From: Fabiano Rosas <farosas@suse.de>
1
Enable all FEAT_ECV features on the 'max' CPU.
2
2
3
This allows the test to be skipped when TCG is not present in the QEMU
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
binary.
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20240301183219.2424889-9-peter.maydell@linaro.org
7
---
8
docs/system/arm/emulation.rst | 1 +
9
target/arm/tcg/cpu64.c | 1 +
10
2 files changed, 2 insertions(+)
5
11
6
Signed-off-by: Fabiano Rosas <farosas@suse.de>
12
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
tests/avocado/boot_linux_console.py | 1 +
12
tests/avocado/reverse_debugging.py | 8 ++++++++
13
2 files changed, 9 insertions(+)
14
15
diff --git a/tests/avocado/boot_linux_console.py b/tests/avocado/boot_linux_console.py
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/tests/avocado/boot_linux_console.py
14
--- a/docs/system/arm/emulation.rst
18
+++ b/tests/avocado/boot_linux_console.py
15
+++ b/docs/system/arm/emulation.rst
19
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_uboot_netbsd9(self):
16
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
20
17
- FEAT_DotProd (Advanced SIMD dot product instructions)
21
def test_aarch64_raspi3_atf(self):
18
- FEAT_DoubleFault (Double Fault Extension)
22
"""
19
- FEAT_E0PD (Preventing EL0 access to halves of address maps)
23
+ :avocado: tags=accel:tcg
20
+- FEAT_ECV (Enhanced Counter Virtualization)
24
:avocado: tags=arch:aarch64
21
- FEAT_EPAC (Enhanced pointer authentication)
25
:avocado: tags=machine:raspi3b
22
- FEAT_ETS (Enhanced Translation Synchronization)
26
:avocado: tags=cpu:cortex-a53
23
- FEAT_EVT (Enhanced Virtualization Traps)
27
diff --git a/tests/avocado/reverse_debugging.py b/tests/avocado/reverse_debugging.py
24
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
28
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
29
--- a/tests/avocado/reverse_debugging.py
26
--- a/target/arm/tcg/cpu64.c
30
+++ b/tests/avocado/reverse_debugging.py
27
+++ b/target/arm/tcg/cpu64.c
31
@@ -XXX,XX +XXX,XX @@ def reverse_debugging(self, shift=7, args=None):
28
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
32
vm.shutdown()
29
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN64_2, 2); /* 64k stage2 supported */
33
30
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 2); /* 4k stage2 supported */
34
class ReverseDebugging_X86_64(ReverseDebugging):
31
t = FIELD_DP64(t, ID_AA64MMFR0, FGT, 1); /* FEAT_FGT */
35
+ """
32
+ t = FIELD_DP64(t, ID_AA64MMFR0, ECV, 2); /* FEAT_ECV */
36
+ :avocado: tags=accel:tcg
33
cpu->isar.id_aa64mmfr0 = t;
37
+ """
34
38
+
35
t = cpu->isar.id_aa64mmfr1;
39
REG_PC = 0x10
40
REG_CS = 0x12
41
def get_pc(self, g):
42
@@ -XXX,XX +XXX,XX @@ def test_x86_64_pc(self):
43
self.reverse_debugging()
44
45
class ReverseDebugging_AArch64(ReverseDebugging):
46
+ """
47
+ :avocado: tags=accel:tcg
48
+ """
49
+
50
REG_PC = 32
51
52
# unidentified gitlab timeout problem
53
--
36
--
54
2.34.1
37
2.34.1
55
38
56
39
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
2
3
Nuvoton's PSPI is a general purpose SPI module which enables
3
Features supported :
4
connections to SPI-based peripheral devices.
4
- the 8 STM32L4x5 GPIOs are initialized with their reset values
5
(except IDR, see below)
6
- input mode : setting a pin in input mode "externally" (using input
7
irqs) results in an out irq (transmitted to SYSCFG)
8
- output mode : setting a bit in ODR sets the corresponding out irq
9
(if this line is configured in output mode)
10
- pull-up, pull-down
11
- push-pull, open-drain
5
12
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
13
Difference with the real GPIOs :
7
Reviewed-by: Chris Rauer <crauer@google.com>
14
- Alternate Function and Analog mode aren't implemented :
8
Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org>
15
pins in AF/Analog behave like pins in input mode
9
Message-id: 20230208235433.3989937-3-wuhaotsh@google.com
16
- floating pins stay at their last value
17
- register IDR reset values differ from the real one :
18
values are coherent with the other registers reset values
19
and the fact that AF/Analog modes aren't implemented
20
- setting I/O output speed isn't supported
21
- locking port bits isn't supported
22
- ADC function isn't supported
23
- GPIOH has 16 pins instead of 2 pins
24
- writing to registers LCKR, AFRL, AFRH and ASCR is ineffective
25
26
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
27
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
28
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
29
Acked-by: Alistair Francis <alistair.francis@wdc.com>
30
Message-id: 20240305210444.310665-2-ines.varhol@telecom-paris.fr
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
32
---
12
MAINTAINERS | 6 +-
33
MAINTAINERS | 1 +
13
include/hw/ssi/npcm_pspi.h | 53 +++++++++
34
docs/system/arm/b-l475e-iot01a.rst | 2 +-
14
hw/ssi/npcm_pspi.c | 221 +++++++++++++++++++++++++++++++++++++
35
include/hw/gpio/stm32l4x5_gpio.h | 70 +++++
15
hw/ssi/meson.build | 2 +-
36
hw/gpio/stm32l4x5_gpio.c | 477 +++++++++++++++++++++++++++++
16
hw/ssi/trace-events | 5 +
37
hw/gpio/Kconfig | 3 +
17
5 files changed, 283 insertions(+), 4 deletions(-)
38
hw/gpio/meson.build | 1 +
18
create mode 100644 include/hw/ssi/npcm_pspi.h
39
hw/gpio/trace-events | 6 +
19
create mode 100644 hw/ssi/npcm_pspi.c
40
7 files changed, 559 insertions(+), 1 deletion(-)
41
create mode 100644 include/hw/gpio/stm32l4x5_gpio.h
42
create mode 100644 hw/gpio/stm32l4x5_gpio.c
20
43
21
diff --git a/MAINTAINERS b/MAINTAINERS
44
diff --git a/MAINTAINERS b/MAINTAINERS
22
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
23
--- a/MAINTAINERS
46
--- a/MAINTAINERS
24
+++ b/MAINTAINERS
47
+++ b/MAINTAINERS
25
@@ -XXX,XX +XXX,XX @@ M: Tyrone Ting <kfting@nuvoton.com>
48
@@ -XXX,XX +XXX,XX @@ F: hw/arm/stm32l4x5_soc.c
26
M: Hao Wu <wuhaotsh@google.com>
49
F: hw/misc/stm32l4x5_exti.c
27
L: qemu-arm@nongnu.org
50
F: hw/misc/stm32l4x5_syscfg.c
28
S: Supported
51
F: hw/misc/stm32l4x5_rcc.c
29
-F: hw/*/npcm7xx*
52
+F: hw/gpio/stm32l4x5_gpio.c
30
-F: include/hw/*/npcm7xx*
53
F: include/hw/*/stm32l4x5_*.h
31
-F: tests/qtest/npcm7xx*
54
32
+F: hw/*/npcm*
55
B-L475E-IOT01A IoT Node
33
+F: include/hw/*/npcm*
56
diff --git a/docs/system/arm/b-l475e-iot01a.rst b/docs/system/arm/b-l475e-iot01a.rst
34
+F: tests/qtest/npcm*
57
index XXXXXXX..XXXXXXX 100644
35
F: pc-bios/npcm7xx_bootrom.bin
58
--- a/docs/system/arm/b-l475e-iot01a.rst
36
F: roms/vbootrom
59
+++ b/docs/system/arm/b-l475e-iot01a.rst
37
F: docs/system/arm/nuvoton.rst
60
@@ -XXX,XX +XXX,XX @@ Currently B-L475E-IOT01A machine's only supports the following devices:
38
diff --git a/include/hw/ssi/npcm_pspi.h b/include/hw/ssi/npcm_pspi.h
61
- STM32L4x5 EXTI (Extended interrupts and events controller)
62
- STM32L4x5 SYSCFG (System configuration controller)
63
- STM32L4x5 RCC (Reset and clock control)
64
+- STM32L4x5 GPIOs (General-purpose I/Os)
65
66
Missing devices
67
"""""""""""""""
68
@@ -XXX,XX +XXX,XX @@ Missing devices
69
The B-L475E-IOT01A does *not* support the following devices:
70
71
- Serial ports (UART)
72
-- General-purpose I/Os (GPIO)
73
- Analog to Digital Converter (ADC)
74
- SPI controller
75
- Timer controller (TIMER)
76
diff --git a/include/hw/gpio/stm32l4x5_gpio.h b/include/hw/gpio/stm32l4x5_gpio.h
39
new file mode 100644
77
new file mode 100644
40
index XXXXXXX..XXXXXXX
78
index XXXXXXX..XXXXXXX
41
--- /dev/null
79
--- /dev/null
42
+++ b/include/hw/ssi/npcm_pspi.h
80
+++ b/include/hw/gpio/stm32l4x5_gpio.h
43
@@ -XXX,XX +XXX,XX @@
81
@@ -XXX,XX +XXX,XX @@
44
+/*
82
+/*
45
+ * Nuvoton Peripheral SPI Module
83
+ * STM32L4x5 GPIO (General Purpose Input/Ouput)
46
+ *
84
+ *
47
+ * Copyright 2023 Google LLC
85
+ * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
86
+ * Copyright (c) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
48
+ *
87
+ *
49
+ * This program is free software; you can redistribute it and/or modify it
88
+ * SPDX-License-Identifier: GPL-2.0-or-later
50
+ * under the terms of the GNU General Public License as published by the
51
+ * Free Software Foundation; either version 2 of the License, or
52
+ * (at your option) any later version.
53
+ *
89
+ *
54
+ * This program is distributed in the hope that it will be useful, but WITHOUT
90
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
55
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
91
+ * See the COPYING file in the top-level directory.
56
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
57
+ * for more details.
58
+ */
92
+ */
59
+#ifndef NPCM_PSPI_H
93
+
60
+#define NPCM_PSPI_H
94
+/*
61
+
95
+ * The reference used is the STMicroElectronics RM0351 Reference manual
62
+#include "hw/ssi/ssi.h"
96
+ * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
97
+ * https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html
98
+ */
99
+
100
+#ifndef HW_STM32L4X5_GPIO_H
101
+#define HW_STM32L4X5_GPIO_H
102
+
63
+#include "hw/sysbus.h"
103
+#include "hw/sysbus.h"
64
+
104
+#include "qom/object.h"
65
+/*
105
+
66
+ * Number of registers in our device state structure. Don't change this without
106
+#define TYPE_STM32L4X5_GPIO "stm32l4x5-gpio"
67
+ * incrementing the version_id in the vmstate.
107
+OBJECT_DECLARE_SIMPLE_TYPE(Stm32l4x5GpioState, STM32L4X5_GPIO)
68
+ */
108
+
69
+#define NPCM_PSPI_NR_REGS 3
109
+#define GPIO_NUM_PINS 16
70
+
110
+
71
+/**
111
+struct Stm32l4x5GpioState {
72
+ * NPCMPSPIState - Device state for one Flash Interface Unit.
112
+ SysBusDevice parent_obj;
73
+ * @parent: System bus device.
74
+ * @mmio: Memory region for register access.
75
+ * @spi: The SPI bus mastered by this controller.
76
+ * @regs: Register contents.
77
+ * @irq: The interrupt request queue for this module.
78
+ *
79
+ * Each PSPI has a shared bank of registers, and controls up to four chip
80
+ * selects. Each chip select has a dedicated memory region which may be used to
81
+ * read and write the flash connected to that chip select as if it were memory.
82
+ */
83
+typedef struct NPCMPSPIState {
84
+ SysBusDevice parent;
85
+
113
+
86
+ MemoryRegion mmio;
114
+ MemoryRegion mmio;
87
+
115
+
88
+ SSIBus *spi;
116
+ /* GPIO registers */
89
+ uint16_t regs[NPCM_PSPI_NR_REGS];
117
+ uint32_t moder;
90
+ qemu_irq irq;
118
+ uint32_t otyper;
91
+} NPCMPSPIState;
119
+ uint32_t ospeedr;
92
+
120
+ uint32_t pupdr;
93
+#define TYPE_NPCM_PSPI "npcm-pspi"
121
+ uint32_t idr;
94
+OBJECT_DECLARE_SIMPLE_TYPE(NPCMPSPIState, NPCM_PSPI)
122
+ uint32_t odr;
95
+
123
+ uint32_t lckr;
96
+#endif /* NPCM_PSPI_H */
124
+ uint32_t afrl;
97
diff --git a/hw/ssi/npcm_pspi.c b/hw/ssi/npcm_pspi.c
125
+ uint32_t afrh;
126
+ uint32_t ascr;
127
+
128
+ /* GPIO registers reset values */
129
+ uint32_t moder_reset;
130
+ uint32_t ospeedr_reset;
131
+ uint32_t pupdr_reset;
132
+
133
+ /*
134
+ * External driving of pins.
135
+ * The pins can be set externally through the device
136
+ * anonymous input GPIOs lines under certain conditions.
137
+ * The pin must not be in push-pull output mode,
138
+ * and can't be set high in open-drain mode.
139
+ * Pins driven externally and configured to
140
+ * output mode will in general be "disconnected"
141
+ * (see `get_gpio_pinmask_to_disconnect()`)
142
+ */
143
+ uint16_t disconnected_pins;
144
+ uint16_t pins_connected_high;
145
+
146
+ char *name;
147
+ Clock *clk;
148
+ qemu_irq pin[GPIO_NUM_PINS];
149
+};
150
+
151
+#endif
152
diff --git a/hw/gpio/stm32l4x5_gpio.c b/hw/gpio/stm32l4x5_gpio.c
98
new file mode 100644
153
new file mode 100644
99
index XXXXXXX..XXXXXXX
154
index XXXXXXX..XXXXXXX
100
--- /dev/null
155
--- /dev/null
101
+++ b/hw/ssi/npcm_pspi.c
156
+++ b/hw/gpio/stm32l4x5_gpio.c
102
@@ -XXX,XX +XXX,XX @@
157
@@ -XXX,XX +XXX,XX @@
103
+/*
158
+/*
104
+ * Nuvoton NPCM Peripheral SPI Module (PSPI)
159
+ * STM32L4x5 GPIO (General Purpose Input/Ouput)
105
+ *
160
+ *
106
+ * Copyright 2023 Google LLC
161
+ * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
162
+ * Copyright (c) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
107
+ *
163
+ *
108
+ * This program is free software; you can redistribute it and/or modify it
164
+ * SPDX-License-Identifier: GPL-2.0-or-later
109
+ * under the terms of the GNU General Public License as published by the
110
+ * Free Software Foundation; either version 2 of the License, or
111
+ * (at your option) any later version.
112
+ *
165
+ *
113
+ * This program is distributed in the hope that it will be useful, but WITHOUT
166
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
114
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
167
+ * See the COPYING file in the top-level directory.
115
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
116
+ * for more details.
117
+ */
168
+ */
118
+
169
+
170
+/*
171
+ * The reference used is the STMicroElectronics RM0351 Reference manual
172
+ * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
173
+ * https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html
174
+ */
175
+
119
+#include "qemu/osdep.h"
176
+#include "qemu/osdep.h"
120
+
177
+#include "qemu/log.h"
178
+#include "hw/gpio/stm32l4x5_gpio.h"
121
+#include "hw/irq.h"
179
+#include "hw/irq.h"
122
+#include "hw/registerfields.h"
180
+#include "hw/qdev-clock.h"
123
+#include "hw/ssi/npcm_pspi.h"
181
+#include "hw/qdev-properties.h"
182
+#include "qapi/visitor.h"
183
+#include "qapi/error.h"
124
+#include "migration/vmstate.h"
184
+#include "migration/vmstate.h"
125
+#include "qapi/error.h"
126
+#include "qemu/error-report.h"
127
+#include "qemu/log.h"
128
+#include "qemu/module.h"
129
+#include "qemu/units.h"
130
+
131
+#include "trace.h"
185
+#include "trace.h"
132
+
186
+
133
+REG16(PSPI_DATA, 0x0)
187
+#define GPIO_MODER 0x00
134
+REG16(PSPI_CTL1, 0x2)
188
+#define GPIO_OTYPER 0x04
135
+ FIELD(PSPI_CTL1, SPIEN, 0, 1)
189
+#define GPIO_OSPEEDR 0x08
136
+ FIELD(PSPI_CTL1, MOD, 2, 1)
190
+#define GPIO_PUPDR 0x0C
137
+ FIELD(PSPI_CTL1, EIR, 5, 1)
191
+#define GPIO_IDR 0x10
138
+ FIELD(PSPI_CTL1, EIW, 6, 1)
192
+#define GPIO_ODR 0x14
139
+ FIELD(PSPI_CTL1, SCM, 7, 1)
193
+#define GPIO_BSRR 0x18
140
+ FIELD(PSPI_CTL1, SCIDL, 8, 1)
194
+#define GPIO_LCKR 0x1C
141
+ FIELD(PSPI_CTL1, SCDV, 9, 7)
195
+#define GPIO_AFRL 0x20
142
+REG16(PSPI_STAT, 0x4)
196
+#define GPIO_AFRH 0x24
143
+ FIELD(PSPI_STAT, BSY, 0, 1)
197
+#define GPIO_BRR 0x28
144
+ FIELD(PSPI_STAT, RBF, 1, 1)
198
+#define GPIO_ASCR 0x2C
145
+
199
+
146
+static void npcm_pspi_update_irq(NPCMPSPIState *s)
200
+/* 0b11111111_11111111_00000000_00000000 */
147
+{
201
+#define RESERVED_BITS_MASK 0xFFFF0000
148
+ int level = 0;
202
+
149
+
203
+static void update_gpio_idr(Stm32l4x5GpioState *s);
150
+ /* Only fire IRQ when the module is enabled. */
204
+
151
+ if (FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, SPIEN)) {
205
+static bool is_pull_up(Stm32l4x5GpioState *s, unsigned pin)
152
+ /* Update interrupt as BSY is cleared. */
206
+{
153
+ if ((!FIELD_EX16(s->regs[R_PSPI_STAT], PSPI_STAT, BSY)) &&
207
+ return extract32(s->pupdr, 2 * pin, 2) == 1;
154
+ FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, EIW)) {
208
+}
155
+ level = 1;
209
+
210
+static bool is_pull_down(Stm32l4x5GpioState *s, unsigned pin)
211
+{
212
+ return extract32(s->pupdr, 2 * pin, 2) == 2;
213
+}
214
+
215
+static bool is_output(Stm32l4x5GpioState *s, unsigned pin)
216
+{
217
+ return extract32(s->moder, 2 * pin, 2) == 1;
218
+}
219
+
220
+static bool is_open_drain(Stm32l4x5GpioState *s, unsigned pin)
221
+{
222
+ return extract32(s->otyper, pin, 1) == 1;
223
+}
224
+
225
+static bool is_push_pull(Stm32l4x5GpioState *s, unsigned pin)
226
+{
227
+ return extract32(s->otyper, pin, 1) == 0;
228
+}
229
+
230
+static void stm32l4x5_gpio_reset_hold(Object *obj)
231
+{
232
+ Stm32l4x5GpioState *s = STM32L4X5_GPIO(obj);
233
+
234
+ s->moder = s->moder_reset;
235
+ s->otyper = 0x00000000;
236
+ s->ospeedr = s->ospeedr_reset;
237
+ s->pupdr = s->pupdr_reset;
238
+ s->idr = 0x00000000;
239
+ s->odr = 0x00000000;
240
+ s->lckr = 0x00000000;
241
+ s->afrl = 0x00000000;
242
+ s->afrh = 0x00000000;
243
+ s->ascr = 0x00000000;
244
+
245
+ s->disconnected_pins = 0xFFFF;
246
+ s->pins_connected_high = 0x0000;
247
+ update_gpio_idr(s);
248
+}
249
+
250
+static void stm32l4x5_gpio_set(void *opaque, int line, int level)
251
+{
252
+ Stm32l4x5GpioState *s = opaque;
253
+ /*
254
+ * The pin isn't set if line is configured in output mode
255
+ * except if level is 0 and the output is open-drain.
256
+ * This way there will be no short-circuit prone situations.
257
+ */
258
+ if (is_output(s, line) && !(is_open_drain(s, line) && (level == 0))) {
259
+ qemu_log_mask(LOG_GUEST_ERROR, "Line %d can't be driven externally\n",
260
+ line);
261
+ return;
262
+ }
263
+
264
+ s->disconnected_pins &= ~(1 << line);
265
+ if (level) {
266
+ s->pins_connected_high |= (1 << line);
267
+ } else {
268
+ s->pins_connected_high &= ~(1 << line);
269
+ }
270
+ trace_stm32l4x5_gpio_pins(s->name, s->disconnected_pins,
271
+ s->pins_connected_high);
272
+ update_gpio_idr(s);
273
+}
274
+
275
+
276
+static void update_gpio_idr(Stm32l4x5GpioState *s)
277
+{
278
+ uint32_t new_idr_mask = 0;
279
+ uint32_t new_idr = s->odr;
280
+ uint32_t old_idr = s->idr;
281
+ int new_pin_state, old_pin_state;
282
+
283
+ for (int i = 0; i < GPIO_NUM_PINS; i++) {
284
+ if (is_output(s, i)) {
285
+ if (is_push_pull(s, i)) {
286
+ new_idr_mask |= (1 << i);
287
+ } else if (!(s->odr & (1 << i))) {
288
+ /* open-drain ODR 0 */
289
+ new_idr_mask |= (1 << i);
290
+ /* open-drain ODR 1 */
291
+ } else if (!(s->disconnected_pins & (1 << i)) &&
292
+ !(s->pins_connected_high & (1 << i))) {
293
+ /* open-drain ODR 1 with pin connected low */
294
+ new_idr_mask |= (1 << i);
295
+ new_idr &= ~(1 << i);
296
+ /* open-drain ODR 1 with unactive pin */
297
+ } else if (is_pull_up(s, i)) {
298
+ new_idr_mask |= (1 << i);
299
+ } else if (is_pull_down(s, i)) {
300
+ new_idr_mask |= (1 << i);
301
+ new_idr &= ~(1 << i);
302
+ }
303
+ /*
304
+ * The only case left is for open-drain ODR 1
305
+ * with unactive pin without pull-up or pull-down :
306
+ * the value is floating.
307
+ */
308
+ /* input or analog mode with connected pin */
309
+ } else if (!(s->disconnected_pins & (1 << i))) {
310
+ if (s->pins_connected_high & (1 << i)) {
311
+ /* pin high */
312
+ new_idr_mask |= (1 << i);
313
+ new_idr |= (1 << i);
314
+ } else {
315
+ /* pin low */
316
+ new_idr_mask |= (1 << i);
317
+ new_idr &= ~(1 << i);
318
+ }
319
+ /* input or analog mode with disconnected pin */
320
+ } else {
321
+ if (is_pull_up(s, i)) {
322
+ /* pull-up */
323
+ new_idr_mask |= (1 << i);
324
+ new_idr |= (1 << i);
325
+ } else if (is_pull_down(s, i)) {
326
+ /* pull-down */
327
+ new_idr_mask |= (1 << i);
328
+ new_idr &= ~(1 << i);
329
+ }
330
+ /*
331
+ * The only case left is for a disconnected pin
332
+ * without pull-up or pull-down :
333
+ * the value is floating.
334
+ */
156
+ }
335
+ }
157
+
336
+ }
158
+ /* Update interrupt as RBF is set. */
337
+
159
+ if (FIELD_EX16(s->regs[R_PSPI_STAT], PSPI_STAT, RBF) &&
338
+ s->idr = (old_idr & ~new_idr_mask) | (new_idr & new_idr_mask);
160
+ FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, EIR)) {
339
+ trace_stm32l4x5_gpio_update_idr(s->name, old_idr, s->idr);
161
+ level = 1;
340
+
341
+ for (int i = 0; i < GPIO_NUM_PINS; i++) {
342
+ if (new_idr_mask & (1 << i)) {
343
+ new_pin_state = (new_idr & (1 << i)) > 0;
344
+ old_pin_state = (old_idr & (1 << i)) > 0;
345
+ if (new_pin_state > old_pin_state) {
346
+ qemu_irq_raise(s->pin[i]);
347
+ } else if (new_pin_state < old_pin_state) {
348
+ qemu_irq_lower(s->pin[i]);
349
+ }
162
+ }
350
+ }
163
+ }
351
+ }
164
+ qemu_set_irq(s->irq, level);
352
+}
165
+}
353
+
166
+
354
+/*
167
+static uint16_t npcm_pspi_read_data(NPCMPSPIState *s)
355
+ * Return mask of pins that are both configured in output
168
+{
356
+ * mode and externally driven (except pins in open-drain
169
+ uint16_t value = s->regs[R_PSPI_DATA];
357
+ * mode externally set to 0).
170
+
358
+ */
171
+ /* Clear stat bits as the value are read out. */
359
+static uint32_t get_gpio_pinmask_to_disconnect(Stm32l4x5GpioState *s)
172
+ s->regs[R_PSPI_STAT] = 0;
360
+{
173
+
361
+ uint32_t pins_to_disconnect = 0;
174
+ return value;
362
+ for (int i = 0; i < GPIO_NUM_PINS; i++) {
175
+}
363
+ /* for each connected pin in output mode */
176
+
364
+ if (!(s->disconnected_pins & (1 << i)) && is_output(s, i)) {
177
+static void npcm_pspi_write_data(NPCMPSPIState *s, uint16_t data)
365
+ /* if either push-pull or high level */
178
+{
366
+ if (is_push_pull(s, i) || s->pins_connected_high & (1 << i)) {
179
+ uint16_t value = 0;
367
+ pins_to_disconnect |= (1 << i);
180
+
368
+ qemu_log_mask(LOG_GUEST_ERROR,
181
+ if (FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, MOD)) {
369
+ "Line %d can't be driven externally\n",
182
+ value = ssi_transfer(s->spi, extract16(data, 8, 8)) << 8;
370
+ i);
183
+ }
371
+ }
184
+ value |= ssi_transfer(s->spi, extract16(data, 0, 8));
372
+ }
185
+ s->regs[R_PSPI_DATA] = value;
373
+ }
186
+
374
+ return pins_to_disconnect;
187
+ /* Mark data as available */
375
+}
188
+ s->regs[R_PSPI_STAT] = R_PSPI_STAT_BSY_MASK | R_PSPI_STAT_RBF_MASK;
376
+
189
+}
377
+/*
190
+
378
+ * Set field `disconnected_pins` and call `update_gpio_idr()`
191
+/* Control register read handler. */
379
+ */
192
+static uint64_t npcm_pspi_ctrl_read(void *opaque, hwaddr addr,
380
+static void disconnect_gpio_pins(Stm32l4x5GpioState *s, uint16_t lines)
193
+ unsigned int size)
381
+{
194
+{
382
+ s->disconnected_pins |= lines;
195
+ NPCMPSPIState *s = opaque;
383
+ trace_stm32l4x5_gpio_pins(s->name, s->disconnected_pins,
384
+ s->pins_connected_high);
385
+ update_gpio_idr(s);
386
+}
387
+
388
+static void disconnected_pins_set(Object *obj, Visitor *v,
389
+ const char *name, void *opaque, Error **errp)
390
+{
391
+ Stm32l4x5GpioState *s = STM32L4X5_GPIO(obj);
196
+ uint16_t value;
392
+ uint16_t value;
393
+ if (!visit_type_uint16(v, name, &value, errp)) {
394
+ return;
395
+ }
396
+ disconnect_gpio_pins(s, value);
397
+}
398
+
399
+static void disconnected_pins_get(Object *obj, Visitor *v,
400
+ const char *name, void *opaque, Error **errp)
401
+{
402
+ visit_type_uint16(v, name, (uint16_t *)opaque, errp);
403
+}
404
+
405
+static void clock_freq_get(Object *obj, Visitor *v,
406
+ const char *name, void *opaque, Error **errp)
407
+{
408
+ Stm32l4x5GpioState *s = STM32L4X5_GPIO(obj);
409
+ uint32_t clock_freq_hz = clock_get_hz(s->clk);
410
+ visit_type_uint32(v, name, &clock_freq_hz, errp);
411
+}
412
+
413
+static void stm32l4x5_gpio_write(void *opaque, hwaddr addr,
414
+ uint64_t val64, unsigned int size)
415
+{
416
+ Stm32l4x5GpioState *s = opaque;
417
+
418
+ uint32_t value = val64;
419
+ trace_stm32l4x5_gpio_write(s->name, addr, val64);
197
+
420
+
198
+ switch (addr) {
421
+ switch (addr) {
199
+ case A_PSPI_DATA:
422
+ case GPIO_MODER:
200
+ value = npcm_pspi_read_data(s);
423
+ s->moder = value;
201
+ break;
424
+ disconnect_gpio_pins(s, get_gpio_pinmask_to_disconnect(s));
202
+
425
+ qemu_log_mask(LOG_UNIMP,
203
+ case A_PSPI_CTL1:
426
+ "%s: Analog and AF modes aren't supported\n\
204
+ value = s->regs[R_PSPI_CTL1];
427
+ Analog and AF mode behave like input mode\n",
205
+ break;
428
+ __func__);
206
+
429
+ return;
207
+ case A_PSPI_STAT:
430
+ case GPIO_OTYPER:
208
+ value = s->regs[R_PSPI_STAT];
431
+ s->otyper = value & ~RESERVED_BITS_MASK;
209
+ break;
432
+ disconnect_gpio_pins(s, get_gpio_pinmask_to_disconnect(s));
210
+
433
+ return;
434
+ case GPIO_OSPEEDR:
435
+ qemu_log_mask(LOG_UNIMP,
436
+ "%s: Changing I/O output speed isn't supported\n\
437
+ I/O speed is already maximal\n",
438
+ __func__);
439
+ s->ospeedr = value;
440
+ return;
441
+ case GPIO_PUPDR:
442
+ s->pupdr = value;
443
+ update_gpio_idr(s);
444
+ return;
445
+ case GPIO_IDR:
446
+ qemu_log_mask(LOG_UNIMP,
447
+ "%s: GPIO->IDR is read-only\n",
448
+ __func__);
449
+ return;
450
+ case GPIO_ODR:
451
+ s->odr = value & ~RESERVED_BITS_MASK;
452
+ update_gpio_idr(s);
453
+ return;
454
+ case GPIO_BSRR: {
455
+ uint32_t bits_to_reset = (value & RESERVED_BITS_MASK) >> GPIO_NUM_PINS;
456
+ uint32_t bits_to_set = value & ~RESERVED_BITS_MASK;
457
+ /* If both BSx and BRx are set, BSx has priority.*/
458
+ s->odr &= ~bits_to_reset;
459
+ s->odr |= bits_to_set;
460
+ update_gpio_idr(s);
461
+ return;
462
+ }
463
+ case GPIO_LCKR:
464
+ qemu_log_mask(LOG_UNIMP,
465
+ "%s: Locking port bits configuration isn't supported\n",
466
+ __func__);
467
+ s->lckr = value & ~RESERVED_BITS_MASK;
468
+ return;
469
+ case GPIO_AFRL:
470
+ qemu_log_mask(LOG_UNIMP,
471
+ "%s: Alternate functions aren't supported\n",
472
+ __func__);
473
+ s->afrl = value;
474
+ return;
475
+ case GPIO_AFRH:
476
+ qemu_log_mask(LOG_UNIMP,
477
+ "%s: Alternate functions aren't supported\n",
478
+ __func__);
479
+ s->afrh = value;
480
+ return;
481
+ case GPIO_BRR: {
482
+ uint32_t bits_to_reset = value & ~RESERVED_BITS_MASK;
483
+ s->odr &= ~bits_to_reset;
484
+ update_gpio_idr(s);
485
+ return;
486
+ }
487
+ case GPIO_ASCR:
488
+ qemu_log_mask(LOG_UNIMP,
489
+ "%s: ADC function isn't supported\n",
490
+ __func__);
491
+ s->ascr = value & ~RESERVED_BITS_MASK;
492
+ return;
211
+ default:
493
+ default:
212
+ qemu_log_mask(LOG_GUEST_ERROR,
494
+ qemu_log_mask(LOG_GUEST_ERROR,
213
+ "%s: write to invalid offset 0x%" PRIx64 "\n",
495
+ "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, addr);
214
+ DEVICE(s)->canonical_path, addr);
496
+ }
497
+}
498
+
499
+static uint64_t stm32l4x5_gpio_read(void *opaque, hwaddr addr,
500
+ unsigned int size)
501
+{
502
+ Stm32l4x5GpioState *s = opaque;
503
+
504
+ trace_stm32l4x5_gpio_read(s->name, addr);
505
+
506
+ switch (addr) {
507
+ case GPIO_MODER:
508
+ return s->moder;
509
+ case GPIO_OTYPER:
510
+ return s->otyper;
511
+ case GPIO_OSPEEDR:
512
+ return s->ospeedr;
513
+ case GPIO_PUPDR:
514
+ return s->pupdr;
515
+ case GPIO_IDR:
516
+ return s->idr;
517
+ case GPIO_ODR:
518
+ return s->odr;
519
+ case GPIO_BSRR:
215
+ return 0;
520
+ return 0;
216
+ }
521
+ case GPIO_LCKR:
217
+ trace_npcm_pspi_ctrl_read(DEVICE(s)->canonical_path, addr, value);
522
+ return s->lckr;
218
+ npcm_pspi_update_irq(s);
523
+ case GPIO_AFRL:
219
+
524
+ return s->afrl;
220
+ return value;
525
+ case GPIO_AFRH:
221
+}
526
+ return s->afrh;
222
+
527
+ case GPIO_BRR:
223
+/* Control register write handler. */
528
+ return 0;
224
+static void npcm_pspi_ctrl_write(void *opaque, hwaddr addr, uint64_t v,
529
+ case GPIO_ASCR:
225
+ unsigned int size)
530
+ return s->ascr;
226
+{
227
+ NPCMPSPIState *s = opaque;
228
+ uint16_t value = v;
229
+
230
+ trace_npcm_pspi_ctrl_write(DEVICE(s)->canonical_path, addr, value);
231
+
232
+ switch (addr) {
233
+ case A_PSPI_DATA:
234
+ npcm_pspi_write_data(s, value);
235
+ break;
236
+
237
+ case A_PSPI_CTL1:
238
+ s->regs[R_PSPI_CTL1] = value;
239
+ break;
240
+
241
+ case A_PSPI_STAT:
242
+ qemu_log_mask(LOG_GUEST_ERROR,
243
+ "%s: write to read-only register PSPI_STAT: 0x%08"
244
+ PRIx64 "\n", DEVICE(s)->canonical_path, v);
245
+ break;
246
+
247
+ default:
531
+ default:
248
+ qemu_log_mask(LOG_GUEST_ERROR,
532
+ qemu_log_mask(LOG_GUEST_ERROR,
249
+ "%s: write to invalid offset 0x%" PRIx64 "\n",
533
+ "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, addr);
250
+ DEVICE(s)->canonical_path, addr);
534
+ return 0;
251
+ return;
535
+ }
252
+ }
536
+}
253
+ npcm_pspi_update_irq(s);
537
+
254
+}
538
+static const MemoryRegionOps stm32l4x5_gpio_ops = {
255
+
539
+ .read = stm32l4x5_gpio_read,
256
+static const MemoryRegionOps npcm_pspi_ctrl_ops = {
540
+ .write = stm32l4x5_gpio_write,
257
+ .read = npcm_pspi_ctrl_read,
541
+ .endianness = DEVICE_NATIVE_ENDIAN,
258
+ .write = npcm_pspi_ctrl_write,
542
+ .impl = {
259
+ .endianness = DEVICE_LITTLE_ENDIAN,
543
+ .min_access_size = 4,
260
+ .valid = {
544
+ .max_access_size = 4,
261
+ .min_access_size = 1,
262
+ .max_access_size = 2,
263
+ .unaligned = false,
545
+ .unaligned = false,
264
+ },
546
+ },
265
+ .impl = {
547
+ .valid = {
266
+ .min_access_size = 2,
548
+ .min_access_size = 4,
267
+ .max_access_size = 2,
549
+ .max_access_size = 4,
268
+ .unaligned = false,
550
+ .unaligned = false,
269
+ },
551
+ },
270
+};
552
+};
271
+
553
+
272
+static void npcm_pspi_enter_reset(Object *obj, ResetType type)
554
+static void stm32l4x5_gpio_init(Object *obj)
273
+{
555
+{
274
+ NPCMPSPIState *s = NPCM_PSPI(obj);
556
+ Stm32l4x5GpioState *s = STM32L4X5_GPIO(obj);
275
+
557
+
276
+ trace_npcm_pspi_enter_reset(DEVICE(obj)->canonical_path, type);
558
+ memory_region_init_io(&s->mmio, obj, &stm32l4x5_gpio_ops, s,
277
+ memset(s->regs, 0, sizeof(s->regs));
559
+ TYPE_STM32L4X5_GPIO, 0x400);
278
+}
560
+
279
+
561
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
280
+static void npcm_pspi_realize(DeviceState *dev, Error **errp)
562
+
281
+{
563
+ qdev_init_gpio_out(DEVICE(obj), s->pin, GPIO_NUM_PINS);
282
+ NPCMPSPIState *s = NPCM_PSPI(dev);
564
+ qdev_init_gpio_in(DEVICE(obj), stm32l4x5_gpio_set, GPIO_NUM_PINS);
283
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
565
+
284
+ Object *obj = OBJECT(dev);
566
+ s->clk = qdev_init_clock_in(DEVICE(s), "clk", NULL, s, 0);
285
+
567
+
286
+ s->spi = ssi_create_bus(dev, "pspi");
568
+ object_property_add(obj, "disconnected-pins", "uint16",
287
+ memory_region_init_io(&s->mmio, obj, &npcm_pspi_ctrl_ops, s,
569
+ disconnected_pins_get, disconnected_pins_set,
288
+ "mmio", 4 * KiB);
570
+ NULL, &s->disconnected_pins);
289
+ sysbus_init_mmio(sbd, &s->mmio);
571
+ object_property_add(obj, "clock-freq-hz", "uint32",
290
+ sysbus_init_irq(sbd, &s->irq);
572
+ clock_freq_get, NULL, NULL, NULL);
291
+}
573
+}
292
+
574
+
293
+static const VMStateDescription vmstate_npcm_pspi = {
575
+static void stm32l4x5_gpio_realize(DeviceState *dev, Error **errp)
294
+ .name = "npcm-pspi",
576
+{
295
+ .version_id = 0,
577
+ Stm32l4x5GpioState *s = STM32L4X5_GPIO(dev);
296
+ .minimum_version_id = 0,
578
+ if (!clock_has_source(s->clk)) {
297
+ .fields = (VMStateField[]) {
579
+ error_setg(errp, "GPIO: clk input must be connected");
298
+ VMSTATE_UINT16_ARRAY(regs, NPCMPSPIState, NPCM_PSPI_NR_REGS),
580
+ return;
299
+ VMSTATE_END_OF_LIST(),
581
+ }
582
+}
583
+
584
+static const VMStateDescription vmstate_stm32l4x5_gpio = {
585
+ .name = TYPE_STM32L4X5_GPIO,
586
+ .version_id = 1,
587
+ .minimum_version_id = 1,
588
+ .fields = (VMStateField[]){
589
+ VMSTATE_UINT32(moder, Stm32l4x5GpioState),
590
+ VMSTATE_UINT32(otyper, Stm32l4x5GpioState),
591
+ VMSTATE_UINT32(ospeedr, Stm32l4x5GpioState),
592
+ VMSTATE_UINT32(pupdr, Stm32l4x5GpioState),
593
+ VMSTATE_UINT32(idr, Stm32l4x5GpioState),
594
+ VMSTATE_UINT32(odr, Stm32l4x5GpioState),
595
+ VMSTATE_UINT32(lckr, Stm32l4x5GpioState),
596
+ VMSTATE_UINT32(afrl, Stm32l4x5GpioState),
597
+ VMSTATE_UINT32(afrh, Stm32l4x5GpioState),
598
+ VMSTATE_UINT32(ascr, Stm32l4x5GpioState),
599
+ VMSTATE_UINT16(disconnected_pins, Stm32l4x5GpioState),
600
+ VMSTATE_UINT16(pins_connected_high, Stm32l4x5GpioState),
601
+ VMSTATE_END_OF_LIST()
602
+ }
603
+};
604
+
605
+static Property stm32l4x5_gpio_properties[] = {
606
+ DEFINE_PROP_STRING("name", Stm32l4x5GpioState, name),
607
+ DEFINE_PROP_UINT32("mode-reset", Stm32l4x5GpioState, moder_reset, 0),
608
+ DEFINE_PROP_UINT32("ospeed-reset", Stm32l4x5GpioState, ospeedr_reset, 0),
609
+ DEFINE_PROP_UINT32("pupd-reset", Stm32l4x5GpioState, pupdr_reset, 0),
610
+ DEFINE_PROP_END_OF_LIST(),
611
+};
612
+
613
+static void stm32l4x5_gpio_class_init(ObjectClass *klass, void *data)
614
+{
615
+ DeviceClass *dc = DEVICE_CLASS(klass);
616
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
617
+
618
+ device_class_set_props(dc, stm32l4x5_gpio_properties);
619
+ dc->vmsd = &vmstate_stm32l4x5_gpio;
620
+ dc->realize = stm32l4x5_gpio_realize;
621
+ rc->phases.hold = stm32l4x5_gpio_reset_hold;
622
+}
623
+
624
+static const TypeInfo stm32l4x5_gpio_types[] = {
625
+ {
626
+ .name = TYPE_STM32L4X5_GPIO,
627
+ .parent = TYPE_SYS_BUS_DEVICE,
628
+ .instance_size = sizeof(Stm32l4x5GpioState),
629
+ .instance_init = stm32l4x5_gpio_init,
630
+ .class_init = stm32l4x5_gpio_class_init,
300
+ },
631
+ },
301
+};
632
+};
302
+
633
+
303
+
634
+DEFINE_TYPES(stm32l4x5_gpio_types)
304
+static void npcm_pspi_class_init(ObjectClass *klass, void *data)
635
diff --git a/hw/gpio/Kconfig b/hw/gpio/Kconfig
305
+{
306
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
307
+ DeviceClass *dc = DEVICE_CLASS(klass);
308
+
309
+ dc->desc = "NPCM Peripheral SPI Module";
310
+ dc->realize = npcm_pspi_realize;
311
+ dc->vmsd = &vmstate_npcm_pspi;
312
+ rc->phases.enter = npcm_pspi_enter_reset;
313
+}
314
+
315
+static const TypeInfo npcm_pspi_types[] = {
316
+ {
317
+ .name = TYPE_NPCM_PSPI,
318
+ .parent = TYPE_SYS_BUS_DEVICE,
319
+ .instance_size = sizeof(NPCMPSPIState),
320
+ .class_init = npcm_pspi_class_init,
321
+ },
322
+};
323
+DEFINE_TYPES(npcm_pspi_types);
324
diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
325
index XXXXXXX..XXXXXXX 100644
636
index XXXXXXX..XXXXXXX 100644
326
--- a/hw/ssi/meson.build
637
--- a/hw/gpio/Kconfig
327
+++ b/hw/ssi/meson.build
638
+++ b/hw/gpio/Kconfig
328
@@ -XXX,XX +XXX,XX @@
639
@@ -XXX,XX +XXX,XX @@ config GPIO_PWR
329
softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_smc.c'))
640
330
softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('mss-spi.c'))
641
config SIFIVE_GPIO
331
-softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_fiu.c'))
642
bool
332
+softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_fiu.c', 'npcm_pspi.c'))
643
+
333
softmmu_ss.add(when: 'CONFIG_PL022', if_true: files('pl022.c'))
644
+config STM32L4X5_GPIO
334
softmmu_ss.add(when: 'CONFIG_SIFIVE_SPI', if_true: files('sifive_spi.c'))
645
+ bool
335
softmmu_ss.add(when: 'CONFIG_SSI', if_true: files('ssi.c'))
646
diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build
336
diff --git a/hw/ssi/trace-events b/hw/ssi/trace-events
337
index XXXXXXX..XXXXXXX 100644
647
index XXXXXXX..XXXXXXX 100644
338
--- a/hw/ssi/trace-events
648
--- a/hw/gpio/meson.build
339
+++ b/hw/ssi/trace-events
649
+++ b/hw/gpio/meson.build
340
@@ -XXX,XX +XXX,XX @@ npcm7xx_fiu_ctrl_write(const char *id, uint64_t addr, uint32_t data) "%s offset:
650
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_RASPI', if_true: files(
341
npcm7xx_fiu_flash_read(const char *id, int cs, uint64_t addr, unsigned int size, uint64_t value) "%s[%d] offset: 0x%08" PRIx64 " size: %u value: 0x%" PRIx64
651
'bcm2835_gpio.c',
342
npcm7xx_fiu_flash_write(const char *id, unsigned cs, uint64_t addr, unsigned int size, uint64_t value) "%s[%d] offset: 0x%08" PRIx64 " size: %u value: 0x%" PRIx64
652
'bcm2838_gpio.c'
343
653
))
344
+# npcm_pspi.c
654
+system_ss.add(when: 'CONFIG_STM32L4X5_SOC', if_true: files('stm32l4x5_gpio.c'))
345
+npcm_pspi_enter_reset(const char *id, int reset_type) "%s reset type: %d"
655
system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_gpio.c'))
346
+npcm_pspi_ctrl_read(const char *id, uint64_t addr, uint16_t data) "%s offset: 0x%03" PRIx64 " value: 0x%04" PRIx16
656
system_ss.add(when: 'CONFIG_SIFIVE_GPIO', if_true: files('sifive_gpio.c'))
347
+npcm_pspi_ctrl_write(const char *id, uint64_t addr, uint16_t data) "%s offset: 0x%03" PRIx64 " value: 0x%04" PRIx16
657
diff --git a/hw/gpio/trace-events b/hw/gpio/trace-events
348
+
658
index XXXXXXX..XXXXXXX 100644
349
# ibex_spi_host.c
659
--- a/hw/gpio/trace-events
350
660
+++ b/hw/gpio/trace-events
351
ibex_spi_host_reset(const char *msg) "%s"
661
@@ -XXX,XX +XXX,XX @@ sifive_gpio_update_output_irq(int64_t line, int64_t value) "line %" PRIi64 " val
662
# aspeed_gpio.c
663
aspeed_gpio_read(uint64_t offset, uint64_t value) "offset: 0x%" PRIx64 " value 0x%" PRIx64
664
aspeed_gpio_write(uint64_t offset, uint64_t value) "offset: 0x%" PRIx64 " value 0x%" PRIx64
665
+
666
+# stm32l4x5_gpio.c
667
+stm32l4x5_gpio_read(char *gpio, uint64_t addr) "GPIO%s addr: 0x%" PRIx64 " "
668
+stm32l4x5_gpio_write(char *gpio, uint64_t addr, uint64_t data) "GPIO%s addr: 0x%" PRIx64 " val: 0x%" PRIx64 ""
669
+stm32l4x5_gpio_update_idr(char *gpio, uint32_t old_idr, uint32_t new_idr) "GPIO%s from: 0x%x to: 0x%x"
670
+stm32l4x5_gpio_pins(char *gpio, uint16_t disconnected, uint16_t high) "GPIO%s disconnected pins: 0x%x levels: 0x%x"
352
--
671
--
353
2.34.1
672
2.34.1
673
674
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
2
3
Since commit acc0b8b05a when running the ZynqMP ZCU102 board with
3
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
4
a QEMU configured using --without-default-devices, we get:
4
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
5
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
$ qemu-system-aarch64 -M xlnx-zcu102
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
7
qemu-system-aarch64: missing object type 'usb_dwc3'
7
Message-id: 20240305210444.310665-3-ines.varhol@telecom-paris.fr
8
Abort trap: 6
9
10
Fix by adding the missing Kconfig dependency.
11
12
Fixes: acc0b8b05a ("hw/arm/xlnx-zynqmp: Connect ZynqMP's USB controllers")
13
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Message-id: 20230216092327.2203-1-philmd@linaro.org
15
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
9
---
18
hw/arm/Kconfig | 1 +
10
include/hw/arm/stm32l4x5_soc.h | 2 +
19
1 file changed, 1 insertion(+)
11
include/hw/gpio/stm32l4x5_gpio.h | 1 +
20
12
include/hw/misc/stm32l4x5_syscfg.h | 3 +-
13
hw/arm/stm32l4x5_soc.c | 71 +++++++++++++++++++++++-------
14
hw/misc/stm32l4x5_syscfg.c | 1 +
15
hw/arm/Kconfig | 3 +-
16
6 files changed, 63 insertions(+), 18 deletions(-)
17
18
diff --git a/include/hw/arm/stm32l4x5_soc.h b/include/hw/arm/stm32l4x5_soc.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/stm32l4x5_soc.h
21
+++ b/include/hw/arm/stm32l4x5_soc.h
22
@@ -XXX,XX +XXX,XX @@
23
#include "hw/misc/stm32l4x5_syscfg.h"
24
#include "hw/misc/stm32l4x5_exti.h"
25
#include "hw/misc/stm32l4x5_rcc.h"
26
+#include "hw/gpio/stm32l4x5_gpio.h"
27
#include "qom/object.h"
28
29
#define TYPE_STM32L4X5_SOC "stm32l4x5-soc"
30
@@ -XXX,XX +XXX,XX @@ struct Stm32l4x5SocState {
31
OrIRQState exti_or_gates[NUM_EXTI_OR_GATES];
32
Stm32l4x5SyscfgState syscfg;
33
Stm32l4x5RccState rcc;
34
+ Stm32l4x5GpioState gpio[NUM_GPIOS];
35
36
MemoryRegion sram1;
37
MemoryRegion sram2;
38
diff --git a/include/hw/gpio/stm32l4x5_gpio.h b/include/hw/gpio/stm32l4x5_gpio.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/include/hw/gpio/stm32l4x5_gpio.h
41
+++ b/include/hw/gpio/stm32l4x5_gpio.h
42
@@ -XXX,XX +XXX,XX @@
43
#define TYPE_STM32L4X5_GPIO "stm32l4x5-gpio"
44
OBJECT_DECLARE_SIMPLE_TYPE(Stm32l4x5GpioState, STM32L4X5_GPIO)
45
46
+#define NUM_GPIOS 8
47
#define GPIO_NUM_PINS 16
48
49
struct Stm32l4x5GpioState {
50
diff --git a/include/hw/misc/stm32l4x5_syscfg.h b/include/hw/misc/stm32l4x5_syscfg.h
51
index XXXXXXX..XXXXXXX 100644
52
--- a/include/hw/misc/stm32l4x5_syscfg.h
53
+++ b/include/hw/misc/stm32l4x5_syscfg.h
54
@@ -XXX,XX +XXX,XX @@
55
56
#include "hw/sysbus.h"
57
#include "qom/object.h"
58
+#include "hw/gpio/stm32l4x5_gpio.h"
59
60
#define TYPE_STM32L4X5_SYSCFG "stm32l4x5-syscfg"
61
OBJECT_DECLARE_SIMPLE_TYPE(Stm32l4x5SyscfgState, STM32L4X5_SYSCFG)
62
63
-#define NUM_GPIOS 8
64
-#define GPIO_NUM_PINS 16
65
#define SYSCFG_NUM_EXTICR 4
66
67
struct Stm32l4x5SyscfgState {
68
diff --git a/hw/arm/stm32l4x5_soc.c b/hw/arm/stm32l4x5_soc.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/arm/stm32l4x5_soc.c
71
+++ b/hw/arm/stm32l4x5_soc.c
72
@@ -XXX,XX +XXX,XX @@
73
#include "sysemu/sysemu.h"
74
#include "hw/or-irq.h"
75
#include "hw/arm/stm32l4x5_soc.h"
76
+#include "hw/gpio/stm32l4x5_gpio.h"
77
#include "hw/qdev-clock.h"
78
#include "hw/misc/unimp.h"
79
80
@@ -XXX,XX +XXX,XX @@ static const int exti_or_gate1_lines_in[EXTI_OR_GATE1_NUM_LINES_IN] = {
81
16, 35, 36, 37, 38,
82
};
83
84
+static const struct {
85
+ uint32_t addr;
86
+ uint32_t moder_reset;
87
+ uint32_t ospeedr_reset;
88
+ uint32_t pupdr_reset;
89
+} stm32l4x5_gpio_cfg[NUM_GPIOS] = {
90
+ { 0x48000000, 0xABFFFFFF, 0x0C000000, 0x64000000 },
91
+ { 0x48000400, 0xFFFFFEBF, 0x00000000, 0x00000100 },
92
+ { 0x48000800, 0xFFFFFFFF, 0x00000000, 0x00000000 },
93
+ { 0x48000C00, 0xFFFFFFFF, 0x00000000, 0x00000000 },
94
+ { 0x48001000, 0xFFFFFFFF, 0x00000000, 0x00000000 },
95
+ { 0x48001400, 0xFFFFFFFF, 0x00000000, 0x00000000 },
96
+ { 0x48001800, 0xFFFFFFFF, 0x00000000, 0x00000000 },
97
+ { 0x48001C00, 0x0000000F, 0x00000000, 0x00000000 },
98
+};
99
+
100
static void stm32l4x5_soc_initfn(Object *obj)
101
{
102
Stm32l4x5SocState *s = STM32L4X5_SOC(obj);
103
@@ -XXX,XX +XXX,XX @@ static void stm32l4x5_soc_initfn(Object *obj)
104
}
105
object_initialize_child(obj, "syscfg", &s->syscfg, TYPE_STM32L4X5_SYSCFG);
106
object_initialize_child(obj, "rcc", &s->rcc, TYPE_STM32L4X5_RCC);
107
+
108
+ for (unsigned i = 0; i < NUM_GPIOS; i++) {
109
+ g_autofree char *name = g_strdup_printf("gpio%c", 'a' + i);
110
+ object_initialize_child(obj, name, &s->gpio[i], TYPE_STM32L4X5_GPIO);
111
+ }
112
}
113
114
static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
115
@@ -XXX,XX +XXX,XX @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
116
Stm32l4x5SocState *s = STM32L4X5_SOC(dev_soc);
117
const Stm32l4x5SocClass *sc = STM32L4X5_SOC_GET_CLASS(dev_soc);
118
MemoryRegion *system_memory = get_system_memory();
119
- DeviceState *armv7m;
120
+ DeviceState *armv7m, *dev;
121
SysBusDevice *busdev;
122
+ uint32_t pin_index;
123
124
if (!memory_region_init_rom(&s->flash, OBJECT(dev_soc), "flash",
125
sc->flash_size, errp)) {
126
@@ -XXX,XX +XXX,XX @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
127
return;
128
}
129
130
+ /* GPIOs */
131
+ for (unsigned i = 0; i < NUM_GPIOS; i++) {
132
+ g_autofree char *name = g_strdup_printf("%c", 'A' + i);
133
+ dev = DEVICE(&s->gpio[i]);
134
+ qdev_prop_set_string(dev, "name", name);
135
+ qdev_prop_set_uint32(dev, "mode-reset",
136
+ stm32l4x5_gpio_cfg[i].moder_reset);
137
+ qdev_prop_set_uint32(dev, "ospeed-reset",
138
+ stm32l4x5_gpio_cfg[i].ospeedr_reset);
139
+ qdev_prop_set_uint32(dev, "pupd-reset",
140
+ stm32l4x5_gpio_cfg[i].pupdr_reset);
141
+ busdev = SYS_BUS_DEVICE(&s->gpio[i]);
142
+ g_free(name);
143
+ name = g_strdup_printf("gpio%c-out", 'a' + i);
144
+ qdev_connect_clock_in(DEVICE(&s->gpio[i]), "clk",
145
+ qdev_get_clock_out(DEVICE(&(s->rcc)), name));
146
+ if (!sysbus_realize(busdev, errp)) {
147
+ return;
148
+ }
149
+ sysbus_mmio_map(busdev, 0, stm32l4x5_gpio_cfg[i].addr);
150
+ }
151
+
152
/* System configuration controller */
153
busdev = SYS_BUS_DEVICE(&s->syscfg);
154
if (!sysbus_realize(busdev, errp)) {
155
return;
156
}
157
sysbus_mmio_map(busdev, 0, SYSCFG_ADDR);
158
- /*
159
- * TODO: when the GPIO device is implemented, connect it
160
- * to SYCFG using `qdev_connect_gpio_out`, NUM_GPIOS and
161
- * GPIO_NUM_PINS.
162
- */
163
+
164
+ for (unsigned i = 0; i < NUM_GPIOS; i++) {
165
+ for (unsigned j = 0; j < GPIO_NUM_PINS; j++) {
166
+ pin_index = GPIO_NUM_PINS * i + j;
167
+ qdev_connect_gpio_out(DEVICE(&s->gpio[i]), j,
168
+ qdev_get_gpio_in(DEVICE(&s->syscfg),
169
+ pin_index));
170
+ }
171
+ }
172
173
/* EXTI device */
174
busdev = SYS_BUS_DEVICE(&s->exti);
175
@@ -XXX,XX +XXX,XX @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
176
}
177
}
178
179
- for (unsigned i = 0; i < 16; i++) {
180
+ for (unsigned i = 0; i < GPIO_NUM_PINS; i++) {
181
qdev_connect_gpio_out(DEVICE(&s->syscfg), i,
182
qdev_get_gpio_in(DEVICE(&s->exti), i));
183
}
184
@@ -XXX,XX +XXX,XX @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
185
/* RESERVED: 0x40024400, 0x7FDBC00 */
186
187
/* AHB2 BUS */
188
- create_unimplemented_device("GPIOA", 0x48000000, 0x400);
189
- create_unimplemented_device("GPIOB", 0x48000400, 0x400);
190
- create_unimplemented_device("GPIOC", 0x48000800, 0x400);
191
- create_unimplemented_device("GPIOD", 0x48000C00, 0x400);
192
- create_unimplemented_device("GPIOE", 0x48001000, 0x400);
193
- create_unimplemented_device("GPIOF", 0x48001400, 0x400);
194
- create_unimplemented_device("GPIOG", 0x48001800, 0x400);
195
- create_unimplemented_device("GPIOH", 0x48001C00, 0x400);
196
/* RESERVED: 0x48002000, 0x7FDBC00 */
197
create_unimplemented_device("OTG_FS", 0x50000000, 0x40000);
198
create_unimplemented_device("ADC", 0x50040000, 0x400);
199
diff --git a/hw/misc/stm32l4x5_syscfg.c b/hw/misc/stm32l4x5_syscfg.c
200
index XXXXXXX..XXXXXXX 100644
201
--- a/hw/misc/stm32l4x5_syscfg.c
202
+++ b/hw/misc/stm32l4x5_syscfg.c
203
@@ -XXX,XX +XXX,XX @@
204
#include "hw/irq.h"
205
#include "migration/vmstate.h"
206
#include "hw/misc/stm32l4x5_syscfg.h"
207
+#include "hw/gpio/stm32l4x5_gpio.h"
208
209
#define SYSCFG_MEMRMP 0x00
210
#define SYSCFG_CFGR1 0x04
21
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
211
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
22
index XXXXXXX..XXXXXXX 100644
212
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/Kconfig
213
--- a/hw/arm/Kconfig
24
+++ b/hw/arm/Kconfig
214
+++ b/hw/arm/Kconfig
25
@@ -XXX,XX +XXX,XX @@ config XLNX_ZYNQMP_ARM
215
@@ -XXX,XX +XXX,XX @@ config STM32L4X5_SOC
26
select XLNX_CSU_DMA
216
bool
27
select XLNX_ZYNQMP
217
select ARM_V7M
28
select XLNX_ZDMA
218
select OR_IRQ
29
+ select USB_DWC3
219
- select STM32L4X5_SYSCFG
30
220
select STM32L4X5_EXTI
31
config XLNX_VERSAL
221
+ select STM32L4X5_SYSCFG
222
select STM32L4X5_RCC
223
+ select STM32L4X5_GPIO
224
225
config XLNX_ZYNQMP_ARM
32
bool
226
bool
33
--
227
--
34
2.34.1
228
2.34.1
35
229
36
230
diff view generated by jsdifflib
1
From: Fabiano Rosas <farosas@suse.de>
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
2
3
These tests set -accel tcg, so restrict them to when TCG is present.
3
The testcase contains :
4
- `test_idr_reset_value()` :
5
Checks the reset values of MODER, OTYPER, PUPDR, ODR and IDR.
6
- `test_gpio_output_mode()` :
7
Checks that writing a bit in register ODR results in the corresponding
8
pin rising or lowering, if this pin is configured in output mode.
9
- `test_gpio_input_mode()` :
10
Checks that a input pin set high or low externally results
11
in the pin rising and lowering.
12
- `test_pull_up_pull_down()` :
13
Checks that a floating pin in pull-up/down mode is actually high/down.
14
- `test_push_pull()` :
15
Checks that a pin set externally is disconnected when configured in
16
push-pull output mode, and can't be set externally while in this mode.
17
- `test_open_drain()` :
18
Checks that a pin set externally high is disconnected when configured
19
in open-drain output mode, and can't be set high while in this mode.
20
- `test_bsrr_brr()` :
21
Checks that writing to BSRR and BRR has the desired result in ODR.
22
- `test_clock_enable()` :
23
Checks that GPIO clock is at the right frequency after enabling it.
4
24
5
Signed-off-by: Fabiano Rosas <farosas@suse.de>
25
Acked-by: Thomas Huth <thuth@redhat.com>
6
Acked-by: Richard Henderson <richard.henderson@linaro.org>
26
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
27
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
28
Message-id: 20240305210444.310665-4-ines.varhol@telecom-paris.fr
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
30
---
10
tests/qtest/meson.build | 4 ++--
31
tests/qtest/stm32l4x5_gpio-test.c | 551 ++++++++++++++++++++++++++++++
11
1 file changed, 2 insertions(+), 2 deletions(-)
32
tests/qtest/meson.build | 3 +-
33
2 files changed, 553 insertions(+), 1 deletion(-)
34
create mode 100644 tests/qtest/stm32l4x5_gpio-test.c
12
35
36
diff --git a/tests/qtest/stm32l4x5_gpio-test.c b/tests/qtest/stm32l4x5_gpio-test.c
37
new file mode 100644
38
index XXXXXXX..XXXXXXX
39
--- /dev/null
40
+++ b/tests/qtest/stm32l4x5_gpio-test.c
41
@@ -XXX,XX +XXX,XX @@
42
+/*
43
+ * QTest testcase for STM32L4x5_GPIO
44
+ *
45
+ * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
46
+ * Copyright (c) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
47
+ *
48
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
49
+ * See the COPYING file in the top-level directory.
50
+ */
51
+
52
+#include "qemu/osdep.h"
53
+#include "libqtest-single.h"
54
+
55
+#define GPIO_BASE_ADDR 0x48000000
56
+#define GPIO_SIZE 0x400
57
+#define NUM_GPIOS 8
58
+#define NUM_GPIO_PINS 16
59
+
60
+#define GPIO_A 0x48000000
61
+#define GPIO_B 0x48000400
62
+#define GPIO_C 0x48000800
63
+#define GPIO_D 0x48000C00
64
+#define GPIO_E 0x48001000
65
+#define GPIO_F 0x48001400
66
+#define GPIO_G 0x48001800
67
+#define GPIO_H 0x48001C00
68
+
69
+#define MODER 0x00
70
+#define OTYPER 0x04
71
+#define PUPDR 0x0C
72
+#define IDR 0x10
73
+#define ODR 0x14
74
+#define BSRR 0x18
75
+#define BRR 0x28
76
+
77
+#define MODER_INPUT 0
78
+#define MODER_OUTPUT 1
79
+
80
+#define PUPDR_NONE 0
81
+#define PUPDR_PULLUP 1
82
+#define PUPDR_PULLDOWN 2
83
+
84
+#define OTYPER_PUSH_PULL 0
85
+#define OTYPER_OPEN_DRAIN 1
86
+
87
+const uint32_t moder_reset[NUM_GPIOS] = {
88
+ 0xABFFFFFF,
89
+ 0xFFFFFEBF,
90
+ 0xFFFFFFFF,
91
+ 0xFFFFFFFF,
92
+ 0xFFFFFFFF,
93
+ 0xFFFFFFFF,
94
+ 0xFFFFFFFF,
95
+ 0x0000000F
96
+};
97
+
98
+const uint32_t pupdr_reset[NUM_GPIOS] = {
99
+ 0x64000000,
100
+ 0x00000100,
101
+ 0x00000000,
102
+ 0x00000000,
103
+ 0x00000000,
104
+ 0x00000000,
105
+ 0x00000000,
106
+ 0x00000000
107
+};
108
+
109
+const uint32_t idr_reset[NUM_GPIOS] = {
110
+ 0x0000A000,
111
+ 0x00000010,
112
+ 0x00000000,
113
+ 0x00000000,
114
+ 0x00000000,
115
+ 0x00000000,
116
+ 0x00000000,
117
+ 0x00000000
118
+};
119
+
120
+static uint32_t gpio_readl(unsigned int gpio, unsigned int offset)
121
+{
122
+ return readl(gpio + offset);
123
+}
124
+
125
+static void gpio_writel(unsigned int gpio, unsigned int offset, uint32_t value)
126
+{
127
+ writel(gpio + offset, value);
128
+}
129
+
130
+static void gpio_set_bit(unsigned int gpio, unsigned int reg,
131
+ unsigned int pin, uint32_t value)
132
+{
133
+ uint32_t mask = 0xFFFFFFFF & ~(0x1 << pin);
134
+ gpio_writel(gpio, reg, (gpio_readl(gpio, reg) & mask) | value << pin);
135
+}
136
+
137
+static void gpio_set_2bits(unsigned int gpio, unsigned int reg,
138
+ unsigned int pin, uint32_t value)
139
+{
140
+ uint32_t offset = 2 * pin;
141
+ uint32_t mask = 0xFFFFFFFF & ~(0x3 << offset);
142
+ gpio_writel(gpio, reg, (gpio_readl(gpio, reg) & mask) | value << offset);
143
+}
144
+
145
+static unsigned int get_gpio_id(uint32_t gpio_addr)
146
+{
147
+ return (gpio_addr - GPIO_BASE_ADDR) / GPIO_SIZE;
148
+}
149
+
150
+static void gpio_set_irq(unsigned int gpio, int num, int level)
151
+{
152
+ g_autofree char *name = g_strdup_printf("/machine/soc/gpio%c",
153
+ get_gpio_id(gpio) + 'a');
154
+ qtest_set_irq_in(global_qtest, name, NULL, num, level);
155
+}
156
+
157
+static void disconnect_all_pins(unsigned int gpio)
158
+{
159
+ g_autofree char *path = g_strdup_printf("/machine/soc/gpio%c",
160
+ get_gpio_id(gpio) + 'a');
161
+ QDict *r;
162
+
163
+ r = qtest_qmp(global_qtest, "{ 'execute': 'qom-set', 'arguments': "
164
+ "{ 'path': %s, 'property': 'disconnected-pins', 'value': %d } }",
165
+ path, 0xFFFF);
166
+ g_assert_false(qdict_haskey(r, "error"));
167
+ qobject_unref(r);
168
+}
169
+
170
+static uint32_t get_disconnected_pins(unsigned int gpio)
171
+{
172
+ g_autofree char *path = g_strdup_printf("/machine/soc/gpio%c",
173
+ get_gpio_id(gpio) + 'a');
174
+ uint32_t disconnected_pins = 0;
175
+ QDict *r;
176
+
177
+ r = qtest_qmp(global_qtest, "{ 'execute': 'qom-get', 'arguments':"
178
+ " { 'path': %s, 'property': 'disconnected-pins'} }", path);
179
+ g_assert_false(qdict_haskey(r, "error"));
180
+ disconnected_pins = qdict_get_int(r, "return");
181
+ qobject_unref(r);
182
+ return disconnected_pins;
183
+}
184
+
185
+static uint32_t reset(uint32_t gpio, unsigned int offset)
186
+{
187
+ switch (offset) {
188
+ case MODER:
189
+ return moder_reset[get_gpio_id(gpio)];
190
+ case PUPDR:
191
+ return pupdr_reset[get_gpio_id(gpio)];
192
+ case IDR:
193
+ return idr_reset[get_gpio_id(gpio)];
194
+ }
195
+ return 0x0;
196
+}
197
+
198
+static void system_reset(void)
199
+{
200
+ QDict *r;
201
+ r = qtest_qmp(global_qtest, "{'execute': 'system_reset'}");
202
+ g_assert_false(qdict_haskey(r, "error"));
203
+ qobject_unref(r);
204
+}
205
+
206
+static void test_idr_reset_value(void)
207
+{
208
+ /*
209
+ * Checks that the values in MODER, OTYPER, PUPDR and ODR
210
+ * after reset are correct, and that the value in IDR is
211
+ * coherent.
212
+ * Since AF and analog modes aren't implemented, IDR reset
213
+ * values aren't the same as with a real board.
214
+ *
215
+ * Register IDR contains the actual values of all GPIO pins.
216
+ * Its value depends on the pins' configuration
217
+ * (intput/output/analog : register MODER, push-pull/open-drain :
218
+ * register OTYPER, pull-up/pull-down/none : register PUPDR)
219
+ * and on the values stored in register ODR
220
+ * (in case the pin is in output mode).
221
+ */
222
+
223
+ gpio_writel(GPIO_A, MODER, 0xDEADBEEF);
224
+ gpio_writel(GPIO_A, ODR, 0xDEADBEEF);
225
+ gpio_writel(GPIO_A, OTYPER, 0xDEADBEEF);
226
+ gpio_writel(GPIO_A, PUPDR, 0xDEADBEEF);
227
+
228
+ gpio_writel(GPIO_B, MODER, 0xDEADBEEF);
229
+ gpio_writel(GPIO_B, ODR, 0xDEADBEEF);
230
+ gpio_writel(GPIO_B, OTYPER, 0xDEADBEEF);
231
+ gpio_writel(GPIO_B, PUPDR, 0xDEADBEEF);
232
+
233
+ gpio_writel(GPIO_C, MODER, 0xDEADBEEF);
234
+ gpio_writel(GPIO_C, ODR, 0xDEADBEEF);
235
+ gpio_writel(GPIO_C, OTYPER, 0xDEADBEEF);
236
+ gpio_writel(GPIO_C, PUPDR, 0xDEADBEEF);
237
+
238
+ gpio_writel(GPIO_H, MODER, 0xDEADBEEF);
239
+ gpio_writel(GPIO_H, ODR, 0xDEADBEEF);
240
+ gpio_writel(GPIO_H, OTYPER, 0xDEADBEEF);
241
+ gpio_writel(GPIO_H, PUPDR, 0xDEADBEEF);
242
+
243
+ system_reset();
244
+
245
+ uint32_t moder = gpio_readl(GPIO_A, MODER);
246
+ uint32_t odr = gpio_readl(GPIO_A, ODR);
247
+ uint32_t otyper = gpio_readl(GPIO_A, OTYPER);
248
+ uint32_t pupdr = gpio_readl(GPIO_A, PUPDR);
249
+ uint32_t idr = gpio_readl(GPIO_A, IDR);
250
+ /* 15: AF, 14: AF, 13: AF, 12: Analog ... */
251
+ /* here AF is the same as Analog and Input mode */
252
+ g_assert_cmphex(moder, ==, reset(GPIO_A, MODER));
253
+ g_assert_cmphex(odr, ==, reset(GPIO_A, ODR));
254
+ g_assert_cmphex(otyper, ==, reset(GPIO_A, OTYPER));
255
+ /* 15: pull-up, 14: pull-down, 13: pull-up, 12: neither ... */
256
+ g_assert_cmphex(pupdr, ==, reset(GPIO_A, PUPDR));
257
+ /* 15 : 1, 14: 0, 13: 1, 12 : reset value ... */
258
+ g_assert_cmphex(idr, ==, reset(GPIO_A, IDR));
259
+
260
+ moder = gpio_readl(GPIO_B, MODER);
261
+ odr = gpio_readl(GPIO_B, ODR);
262
+ otyper = gpio_readl(GPIO_B, OTYPER);
263
+ pupdr = gpio_readl(GPIO_B, PUPDR);
264
+ idr = gpio_readl(GPIO_B, IDR);
265
+ /* ... 5: Analog, 4: AF, 3: AF, 2: Analog ... */
266
+ /* here AF is the same as Analog and Input mode */
267
+ g_assert_cmphex(moder, ==, reset(GPIO_B, MODER));
268
+ g_assert_cmphex(odr, ==, reset(GPIO_B, ODR));
269
+ g_assert_cmphex(otyper, ==, reset(GPIO_B, OTYPER));
270
+ /* ... 5: neither, 4: pull-up, 3: neither ... */
271
+ g_assert_cmphex(pupdr, ==, reset(GPIO_B, PUPDR));
272
+ /* ... 5 : reset value, 4 : 1, 3 : reset value ... */
273
+ g_assert_cmphex(idr, ==, reset(GPIO_B, IDR));
274
+
275
+ moder = gpio_readl(GPIO_C, MODER);
276
+ odr = gpio_readl(GPIO_C, ODR);
277
+ otyper = gpio_readl(GPIO_C, OTYPER);
278
+ pupdr = gpio_readl(GPIO_C, PUPDR);
279
+ idr = gpio_readl(GPIO_C, IDR);
280
+ /* Analog, same as Input mode*/
281
+ g_assert_cmphex(moder, ==, reset(GPIO_C, MODER));
282
+ g_assert_cmphex(odr, ==, reset(GPIO_C, ODR));
283
+ g_assert_cmphex(otyper, ==, reset(GPIO_C, OTYPER));
284
+ /* no pull-up or pull-down */
285
+ g_assert_cmphex(pupdr, ==, reset(GPIO_C, PUPDR));
286
+ /* reset value */
287
+ g_assert_cmphex(idr, ==, reset(GPIO_C, IDR));
288
+
289
+ moder = gpio_readl(GPIO_H, MODER);
290
+ odr = gpio_readl(GPIO_H, ODR);
291
+ otyper = gpio_readl(GPIO_H, OTYPER);
292
+ pupdr = gpio_readl(GPIO_H, PUPDR);
293
+ idr = gpio_readl(GPIO_H, IDR);
294
+ /* Analog, same as Input mode */
295
+ g_assert_cmphex(moder, ==, reset(GPIO_H, MODER));
296
+ g_assert_cmphex(odr, ==, reset(GPIO_H, ODR));
297
+ g_assert_cmphex(otyper, ==, reset(GPIO_H, OTYPER));
298
+ /* no pull-up or pull-down */
299
+ g_assert_cmphex(pupdr, ==, reset(GPIO_H, PUPDR));
300
+ /* reset value */
301
+ g_assert_cmphex(idr, ==, reset(GPIO_H, IDR));
302
+}
303
+
304
+static void test_gpio_output_mode(const void *data)
305
+{
306
+ /*
307
+ * Checks that setting a bit in ODR sets the corresponding
308
+ * GPIO line high : it should set the right bit in IDR
309
+ * and send an irq to syscfg.
310
+ * Additionally, it checks that values written to ODR
311
+ * when not in output mode are stored and not discarded.
312
+ */
313
+ unsigned int pin = ((uint64_t)data) & 0xF;
314
+ uint32_t gpio = ((uint64_t)data) >> 32;
315
+ unsigned int gpio_id = get_gpio_id(gpio);
316
+
317
+ qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
318
+
319
+ /* Set a bit in ODR and check nothing happens */
320
+ gpio_set_bit(gpio, ODR, pin, 1);
321
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR));
322
+ g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin));
323
+
324
+ /* Configure the relevant line as output and check the pin is high */
325
+ gpio_set_2bits(gpio, MODER, pin, MODER_OUTPUT);
326
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) | (1 << pin));
327
+ g_assert_true(get_irq(gpio_id * NUM_GPIO_PINS + pin));
328
+
329
+ /* Reset the bit in ODR and check the pin is low */
330
+ gpio_set_bit(gpio, ODR, pin, 0);
331
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin));
332
+ g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin));
333
+
334
+ /* Clean the test */
335
+ gpio_writel(gpio, ODR, reset(gpio, ODR));
336
+ gpio_writel(gpio, MODER, reset(gpio, MODER));
337
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR));
338
+ g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin));
339
+}
340
+
341
+static void test_gpio_input_mode(const void *data)
342
+{
343
+ /*
344
+ * Test that setting a line high/low externally sets the
345
+ * corresponding GPIO line high/low : it should set the
346
+ * right bit in IDR and send an irq to syscfg.
347
+ */
348
+ unsigned int pin = ((uint64_t)data) & 0xF;
349
+ uint32_t gpio = ((uint64_t)data) >> 32;
350
+ unsigned int gpio_id = get_gpio_id(gpio);
351
+
352
+ qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
353
+
354
+ /* Configure a line as input, raise it, and check that the pin is high */
355
+ gpio_set_2bits(gpio, MODER, pin, MODER_INPUT);
356
+ gpio_set_irq(gpio, pin, 1);
357
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) | (1 << pin));
358
+ g_assert_true(get_irq(gpio_id * NUM_GPIO_PINS + pin));
359
+
360
+ /* Lower the line and check that the pin is low */
361
+ gpio_set_irq(gpio, pin, 0);
362
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin));
363
+ g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin));
364
+
365
+ /* Clean the test */
366
+ gpio_writel(gpio, MODER, reset(gpio, MODER));
367
+ disconnect_all_pins(gpio);
368
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR));
369
+}
370
+
371
+static void test_pull_up_pull_down(const void *data)
372
+{
373
+ /*
374
+ * Test that a floating pin with pull-up sets the pin
375
+ * high and vice-versa.
376
+ */
377
+ unsigned int pin = ((uint64_t)data) & 0xF;
378
+ uint32_t gpio = ((uint64_t)data) >> 32;
379
+ unsigned int gpio_id = get_gpio_id(gpio);
380
+
381
+ qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
382
+
383
+ /* Configure a line as input with pull-up, check the line is set high */
384
+ gpio_set_2bits(gpio, MODER, pin, MODER_INPUT);
385
+ gpio_set_2bits(gpio, PUPDR, pin, PUPDR_PULLUP);
386
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) | (1 << pin));
387
+ g_assert_true(get_irq(gpio_id * NUM_GPIO_PINS + pin));
388
+
389
+ /* Configure the line with pull-down, check the line is low */
390
+ gpio_set_2bits(gpio, PUPDR, pin, PUPDR_PULLDOWN);
391
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin));
392
+ g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin));
393
+
394
+ /* Clean the test */
395
+ gpio_writel(gpio, MODER, reset(gpio, MODER));
396
+ gpio_writel(gpio, PUPDR, reset(gpio, PUPDR));
397
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR));
398
+}
399
+
400
+static void test_push_pull(const void *data)
401
+{
402
+ /*
403
+ * Test that configuring a line in push-pull output mode
404
+ * disconnects the pin, that the pin can't be set or reset
405
+ * externally afterwards.
406
+ */
407
+ unsigned int pin = ((uint64_t)data) & 0xF;
408
+ uint32_t gpio = ((uint64_t)data) >> 32;
409
+ uint32_t gpio2 = GPIO_BASE_ADDR + (GPIO_H - gpio);
410
+
411
+ qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
412
+
413
+ /* Setting a line high externally, configuring it in push-pull output */
414
+ /* And checking the pin was disconnected */
415
+ gpio_set_irq(gpio, pin, 1);
416
+ gpio_set_2bits(gpio, MODER, pin, MODER_OUTPUT);
417
+ g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF);
418
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin));
419
+
420
+ /* Setting a line low externally, configuring it in push-pull output */
421
+ /* And checking the pin was disconnected */
422
+ gpio_set_irq(gpio2, pin, 0);
423
+ gpio_set_bit(gpio2, ODR, pin, 1);
424
+ gpio_set_2bits(gpio2, MODER, pin, MODER_OUTPUT);
425
+ g_assert_cmphex(get_disconnected_pins(gpio2), ==, 0xFFFF);
426
+ g_assert_cmphex(gpio_readl(gpio2, IDR), ==, reset(gpio2, IDR) | (1 << pin));
427
+
428
+ /* Trying to set a push-pull output pin, checking it doesn't work */
429
+ gpio_set_irq(gpio, pin, 1);
430
+ g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF);
431
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin));
432
+
433
+ /* Trying to reset a push-pull output pin, checking it doesn't work */
434
+ gpio_set_irq(gpio2, pin, 0);
435
+ g_assert_cmphex(get_disconnected_pins(gpio2), ==, 0xFFFF);
436
+ g_assert_cmphex(gpio_readl(gpio2, IDR), ==, reset(gpio2, IDR) | (1 << pin));
437
+
438
+ /* Clean the test */
439
+ gpio_writel(gpio, MODER, reset(gpio, MODER));
440
+ gpio_writel(gpio2, ODR, reset(gpio2, ODR));
441
+ gpio_writel(gpio2, MODER, reset(gpio2, MODER));
442
+}
443
+
444
+static void test_open_drain(const void *data)
445
+{
446
+ /*
447
+ * Test that configuring a line in open-drain output mode
448
+ * disconnects a pin set high externally and that the pin
449
+ * can't be set high externally while configured in open-drain.
450
+ *
451
+ * However a pin set low externally shouldn't be disconnected,
452
+ * and it can be set low externally when in open-drain mode.
453
+ */
454
+ unsigned int pin = ((uint64_t)data) & 0xF;
455
+ uint32_t gpio = ((uint64_t)data) >> 32;
456
+ uint32_t gpio2 = GPIO_BASE_ADDR + (GPIO_H - gpio);
457
+
458
+ qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
459
+
460
+ /* Setting a line high externally, configuring it in open-drain output */
461
+ /* And checking the pin was disconnected */
462
+ gpio_set_irq(gpio, pin, 1);
463
+ gpio_set_bit(gpio, OTYPER, pin, OTYPER_OPEN_DRAIN);
464
+ gpio_set_2bits(gpio, MODER, pin, MODER_OUTPUT);
465
+ g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF);
466
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin));
467
+
468
+ /* Setting a line low externally, configuring it in open-drain output */
469
+ /* And checking the pin wasn't disconnected */
470
+ gpio_set_irq(gpio2, pin, 0);
471
+ gpio_set_bit(gpio2, ODR, pin, 1);
472
+ gpio_set_bit(gpio2, OTYPER, pin, OTYPER_OPEN_DRAIN);
473
+ gpio_set_2bits(gpio2, MODER, pin, MODER_OUTPUT);
474
+ g_assert_cmphex(get_disconnected_pins(gpio2), ==, 0xFFFF & ~(1 << pin));
475
+ g_assert_cmphex(gpio_readl(gpio2, IDR), ==,
476
+ reset(gpio2, IDR) & ~(1 << pin));
477
+
478
+ /* Trying to set a open-drain output pin, checking it doesn't work */
479
+ gpio_set_irq(gpio, pin, 1);
480
+ g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF);
481
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin));
482
+
483
+ /* Trying to reset a open-drain output pin, checking it works */
484
+ gpio_set_bit(gpio, ODR, pin, 1);
485
+ gpio_set_irq(gpio, pin, 0);
486
+ g_assert_cmphex(get_disconnected_pins(gpio2), ==, 0xFFFF & ~(1 << pin));
487
+ g_assert_cmphex(gpio_readl(gpio2, IDR), ==,
488
+ reset(gpio2, IDR) & ~(1 << pin));
489
+
490
+ /* Clean the test */
491
+ disconnect_all_pins(gpio2);
492
+ gpio_writel(gpio2, OTYPER, reset(gpio2, OTYPER));
493
+ gpio_writel(gpio2, ODR, reset(gpio2, ODR));
494
+ gpio_writel(gpio2, MODER, reset(gpio2, MODER));
495
+ g_assert_cmphex(gpio_readl(gpio2, IDR), ==, reset(gpio2, IDR));
496
+ disconnect_all_pins(gpio);
497
+ gpio_writel(gpio, OTYPER, reset(gpio, OTYPER));
498
+ gpio_writel(gpio, ODR, reset(gpio, ODR));
499
+ gpio_writel(gpio, MODER, reset(gpio, MODER));
500
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR));
501
+}
502
+
503
+static void test_bsrr_brr(const void *data)
504
+{
505
+ /*
506
+ * Test that writing a '1' in BSS and BSRR
507
+ * has the desired effect on ODR.
508
+ * In BSRR, BSx has priority over BRx.
509
+ */
510
+ unsigned int pin = ((uint64_t)data) & 0xF;
511
+ uint32_t gpio = ((uint64_t)data) >> 32;
512
+
513
+ gpio_writel(gpio, BSRR, (1 << pin));
514
+ g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR) | (1 << pin));
515
+
516
+ gpio_writel(gpio, BSRR, (1 << (pin + NUM_GPIO_PINS)));
517
+ g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR));
518
+
519
+ gpio_writel(gpio, BSRR, (1 << pin));
520
+ g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR) | (1 << pin));
521
+
522
+ gpio_writel(gpio, BRR, (1 << pin));
523
+ g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR));
524
+
525
+ /* BSx should have priority over BRx */
526
+ gpio_writel(gpio, BSRR, (1 << pin) | (1 << (pin + NUM_GPIO_PINS)));
527
+ g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR) | (1 << pin));
528
+
529
+ gpio_writel(gpio, BRR, (1 << pin));
530
+ g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR));
531
+
532
+ gpio_writel(gpio, ODR, reset(gpio, ODR));
533
+}
534
+
535
+int main(int argc, char **argv)
536
+{
537
+ int ret;
538
+
539
+ g_test_init(&argc, &argv, NULL);
540
+ g_test_set_nonfatal_assertions();
541
+ qtest_add_func("stm32l4x5/gpio/test_idr_reset_value",
542
+ test_idr_reset_value);
543
+ /*
544
+ * The inputs for the tests (gpio and pin) can be changed,
545
+ * but the tests don't work for pins that are high at reset
546
+ * (GPIOA15, GPIO13 and GPIOB5).
547
+ * Specifically, rising the pin then checking `get_irq()`
548
+ * is problematic since the pin was already high.
549
+ */
550
+ qtest_add_data_func("stm32l4x5/gpio/test_gpioc5_output_mode",
551
+ (void *)((uint64_t)GPIO_C << 32 | 5),
552
+ test_gpio_output_mode);
553
+ qtest_add_data_func("stm32l4x5/gpio/test_gpioh3_output_mode",
554
+ (void *)((uint64_t)GPIO_H << 32 | 3),
555
+ test_gpio_output_mode);
556
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_input_mode1",
557
+ (void *)((uint64_t)GPIO_D << 32 | 6),
558
+ test_gpio_input_mode);
559
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_input_mode2",
560
+ (void *)((uint64_t)GPIO_C << 32 | 10),
561
+ test_gpio_input_mode);
562
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_pull_up_pull_down1",
563
+ (void *)((uint64_t)GPIO_B << 32 | 5),
564
+ test_pull_up_pull_down);
565
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_pull_up_pull_down2",
566
+ (void *)((uint64_t)GPIO_F << 32 | 1),
567
+ test_pull_up_pull_down);
568
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_push_pull1",
569
+ (void *)((uint64_t)GPIO_G << 32 | 6),
570
+ test_push_pull);
571
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_push_pull2",
572
+ (void *)((uint64_t)GPIO_H << 32 | 3),
573
+ test_push_pull);
574
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_open_drain1",
575
+ (void *)((uint64_t)GPIO_C << 32 | 4),
576
+ test_open_drain);
577
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_open_drain2",
578
+ (void *)((uint64_t)GPIO_E << 32 | 11),
579
+ test_open_drain);
580
+ qtest_add_data_func("stm32l4x5/gpio/test_bsrr_brr1",
581
+ (void *)((uint64_t)GPIO_A << 32 | 12),
582
+ test_bsrr_brr);
583
+ qtest_add_data_func("stm32l4x5/gpio/test_bsrr_brr2",
584
+ (void *)((uint64_t)GPIO_D << 32 | 0),
585
+ test_bsrr_brr);
586
+
587
+ qtest_start("-machine b-l475e-iot01a");
588
+ ret = g_test_run();
589
+ qtest_end();
590
+
591
+ return ret;
592
+}
13
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
593
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
14
index XXXXXXX..XXXXXXX 100644
594
index XXXXXXX..XXXXXXX 100644
15
--- a/tests/qtest/meson.build
595
--- a/tests/qtest/meson.build
16
+++ b/tests/qtest/meson.build
596
+++ b/tests/qtest/meson.build
17
@@ -XXX,XX +XXX,XX @@ qtests_arm = \
597
@@ -XXX,XX +XXX,XX @@ qtests_aspeed = \
18
# TODO: once aarch64 TCG is fixed on ARM 32 bit host, make bios-tables-test unconditional
598
qtests_stm32l4x5 = \
19
qtests_aarch64 = \
599
['stm32l4x5_exti-test',
20
(cpu != 'arm' and unpack_edk2_blobs ? ['bios-tables-test'] : []) + \
600
'stm32l4x5_syscfg-test',
21
- (config_all_devices.has_key('CONFIG_TPM_TIS_SYSBUS') ? ['tpm-tis-device-test'] : []) + \
601
- 'stm32l4x5_rcc-test']
22
- (config_all_devices.has_key('CONFIG_TPM_TIS_SYSBUS') ? ['tpm-tis-device-swtpm-test'] : []) + \
602
+ 'stm32l4x5_rcc-test',
23
+ (config_all.has_key('CONFIG_TCG') and config_all_devices.has_key('CONFIG_TPM_TIS_SYSBUS') ? \
603
+ 'stm32l4x5_gpio-test']
24
+ ['tpm-tis-device-test', 'tpm-tis-device-swtpm-test'] : []) + \
604
25
(config_all_devices.has_key('CONFIG_XLNX_ZYNQMP_ARM') ? ['xlnx-can-test', 'fuzz-xlnx-dp-test'] : []) + \
605
qtests_arm = \
26
(config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) + \
606
(config_all_devices.has_key('CONFIG_MPS2') ? ['sse-timer-test'] : []) + \
27
['arm-cpu-features',
28
--
607
--
29
2.34.1
608
2.34.1
609
610
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
There is no point in using a void pointer to access the NVIC.
3
While the 8-bit input elements are sequential in the input vector,
4
Use the real type to avoid casting it while debugging.
4
the 32-bit output elements are not sequential in the output matrix.
5
5
Do not attempt to compute 2 32-bit outputs at the same time.
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Cc: qemu-stable@nongnu.org
8
Message-id: 20230206223502.25122-11-philmd@linaro.org
8
Fixes: 23a5e3859f5 ("target/arm: Implement SME integer outer product")
9
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2083
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Message-id: 20240305163931.242795-1-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
14
---
11
target/arm/cpu.h | 46 ++++++++++++++++++++++---------------------
15
target/arm/tcg/sme_helper.c | 77 ++++++++++++++++++-------------
12
hw/intc/armv7m_nvic.c | 38 ++++++++++++-----------------------
16
tests/tcg/aarch64/sme-smopa-1.c | 47 +++++++++++++++++++
13
target/arm/cpu.c | 1 +
17
tests/tcg/aarch64/sme-smopa-2.c | 54 ++++++++++++++++++++++
14
target/arm/m_helper.c | 2 +-
18
tests/tcg/aarch64/Makefile.target | 2 +-
15
4 files changed, 39 insertions(+), 48 deletions(-)
19
4 files changed, 147 insertions(+), 33 deletions(-)
16
20
create mode 100644 tests/tcg/aarch64/sme-smopa-1.c
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
create mode 100644 tests/tcg/aarch64/sme-smopa-2.c
22
23
diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c
18
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
25
--- a/target/arm/tcg/sme_helper.c
20
+++ b/target/arm/cpu.h
26
+++ b/target/arm/tcg/sme_helper.c
21
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMTBFlags {
27
@@ -XXX,XX +XXX,XX @@ void HELPER(sme_bfmopa)(void *vza, void *vzn, void *vzm, void *vpn,
22
23
typedef struct ARMMMUFaultInfo ARMMMUFaultInfo;
24
25
+typedef struct NVICState NVICState;
26
+
27
typedef struct CPUArchState {
28
/* Regs for current mode. */
29
uint32_t regs[16];
30
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
31
} sau;
32
33
#if !defined(CONFIG_USER_ONLY)
34
- void *nvic;
35
+ NVICState *nvic;
36
const struct arm_boot_info *boot_info;
37
/* Store GICv3CPUState to access from this struct */
38
void *gicv3state;
39
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
40
41
/* Interface between CPU and Interrupt controller. */
42
#ifndef CONFIG_USER_ONLY
43
-bool armv7m_nvic_can_take_pending_exception(void *opaque);
44
+bool armv7m_nvic_can_take_pending_exception(NVICState *s);
45
#else
46
-static inline bool armv7m_nvic_can_take_pending_exception(void *opaque)
47
+static inline bool armv7m_nvic_can_take_pending_exception(NVICState *s)
48
{
49
return true;
50
}
51
#endif
52
/**
53
* armv7m_nvic_set_pending: mark the specified exception as pending
54
- * @opaque: the NVIC
55
+ * @s: the NVIC
56
* @irq: the exception number to mark pending
57
* @secure: false for non-banked exceptions or for the nonsecure
58
* version of a banked exception, true for the secure version of a banked
59
@@ -XXX,XX +XXX,XX @@ static inline bool armv7m_nvic_can_take_pending_exception(void *opaque)
60
* if @secure is true and @irq does not specify one of the fixed set
61
* of architecturally banked exceptions.
62
*/
63
-void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
64
+void armv7m_nvic_set_pending(NVICState *s, int irq, bool secure);
65
/**
66
* armv7m_nvic_set_pending_derived: mark this derived exception as pending
67
- * @opaque: the NVIC
68
+ * @s: the NVIC
69
* @irq: the exception number to mark pending
70
* @secure: false for non-banked exceptions or for the nonsecure
71
* version of a banked exception, true for the secure version of a banked
72
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
73
* exceptions (exceptions generated in the course of trying to take
74
* a different exception).
75
*/
76
-void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
77
+void armv7m_nvic_set_pending_derived(NVICState *s, int irq, bool secure);
78
/**
79
* armv7m_nvic_set_pending_lazyfp: mark this lazy FP exception as pending
80
- * @opaque: the NVIC
81
+ * @s: the NVIC
82
* @irq: the exception number to mark pending
83
* @secure: false for non-banked exceptions or for the nonsecure
84
* version of a banked exception, true for the secure version of a banked
85
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
86
* Similar to armv7m_nvic_set_pending(), but specifically for exceptions
87
* generated in the course of lazy stacking of FP registers.
88
*/
89
-void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure);
90
+void armv7m_nvic_set_pending_lazyfp(NVICState *s, int irq, bool secure);
91
/**
92
* armv7m_nvic_get_pending_irq_info: return highest priority pending
93
* exception, and whether it targets Secure state
94
- * @opaque: the NVIC
95
+ * @s: the NVIC
96
* @pirq: set to pending exception number
97
* @ptargets_secure: set to whether pending exception targets Secure
98
*
99
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure);
100
* to true if the current highest priority pending exception should
101
* be taken to Secure state, false for NS.
102
*/
103
-void armv7m_nvic_get_pending_irq_info(void *opaque, int *pirq,
104
+void armv7m_nvic_get_pending_irq_info(NVICState *s, int *pirq,
105
bool *ptargets_secure);
106
/**
107
* armv7m_nvic_acknowledge_irq: make highest priority pending exception active
108
- * @opaque: the NVIC
109
+ * @s: the NVIC
110
*
111
* Move the current highest priority pending exception from the pending
112
* state to the active state, and update v7m.exception to indicate that
113
* it is the exception currently being handled.
114
*/
115
-void armv7m_nvic_acknowledge_irq(void *opaque);
116
+void armv7m_nvic_acknowledge_irq(NVICState *s);
117
/**
118
* armv7m_nvic_complete_irq: complete specified interrupt or exception
119
- * @opaque: the NVIC
120
+ * @s: the NVIC
121
* @irq: the exception number to complete
122
* @secure: true if this exception was secure
123
*
124
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_acknowledge_irq(void *opaque);
125
* 0 if there is still an irq active after this one was completed
126
* (Ignoring -1, this is the same as the RETTOBASE value before completion.)
127
*/
128
-int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure);
129
+int armv7m_nvic_complete_irq(NVICState *s, int irq, bool secure);
130
/**
131
* armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
132
- * @opaque: the NVIC
133
+ * @s: the NVIC
134
* @irq: the exception number to mark pending
135
* @secure: false for non-banked exceptions or for the nonsecure
136
* version of a banked exception, true for the secure version of a banked
137
@@ -XXX,XX +XXX,XX @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure);
138
* interrupt the current execution priority. This controls whether the
139
* RDY bit for it in the FPCCR is set.
140
*/
141
-bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure);
142
+bool armv7m_nvic_get_ready_status(NVICState *s, int irq, bool secure);
143
/**
144
* armv7m_nvic_raw_execution_priority: return the raw execution priority
145
- * @opaque: the NVIC
146
+ * @s: the NVIC
147
*
148
* Returns: the raw execution priority as defined by the v8M architecture.
149
* This is the execution priority minus the effects of AIRCR.PRIS,
150
* and minus any PRIMASK/FAULTMASK/BASEPRI priority boosting.
151
* (v8M ARM ARM I_PKLD.)
152
*/
153
-int armv7m_nvic_raw_execution_priority(void *opaque);
154
+int armv7m_nvic_raw_execution_priority(NVICState *s);
155
/**
156
* armv7m_nvic_neg_prio_requested: return true if the requested execution
157
* priority is negative for the specified security state.
158
- * @opaque: the NVIC
159
+ * @s: the NVIC
160
* @secure: the security state to test
161
* This corresponds to the pseudocode IsReqExecPriNeg().
162
*/
163
#ifndef CONFIG_USER_ONLY
164
-bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure);
165
+bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure);
166
#else
167
-static inline bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure)
168
+static inline bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure)
169
{
170
return false;
171
}
172
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
173
index XXXXXXX..XXXXXXX 100644
174
--- a/hw/intc/armv7m_nvic.c
175
+++ b/hw/intc/armv7m_nvic.c
176
@@ -XXX,XX +XXX,XX @@ static inline int nvic_exec_prio(NVICState *s)
177
return MIN(running, s->exception_prio);
178
}
179
180
-bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure)
181
+bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure)
182
{
183
/* Return true if the requested execution priority is negative
184
* for the specified security state, ie that security state
185
@@ -XXX,XX +XXX,XX @@ bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure)
186
* mean we don't allow FAULTMASK_NS to actually make the execution
187
* priority negative). Compare pseudocode IsReqExcPriNeg().
188
*/
189
- NVICState *s = opaque;
190
-
191
if (s->cpu->env.v7m.faultmask[secure]) {
192
return true;
193
}
194
@@ -XXX,XX +XXX,XX @@ bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure)
195
return false;
196
}
197
198
-bool armv7m_nvic_can_take_pending_exception(void *opaque)
199
+bool armv7m_nvic_can_take_pending_exception(NVICState *s)
200
{
201
- NVICState *s = opaque;
202
-
203
return nvic_exec_prio(s) > nvic_pending_prio(s);
204
}
205
206
-int armv7m_nvic_raw_execution_priority(void *opaque)
207
+int armv7m_nvic_raw_execution_priority(NVICState *s)
208
{
209
- NVICState *s = opaque;
210
-
211
return s->exception_prio;
212
}
213
214
@@ -XXX,XX +XXX,XX @@ static void nvic_irq_update(NVICState *s)
215
* if @secure is true and @irq does not specify one of the fixed set
216
* of architecturally banked exceptions.
217
*/
218
-static void armv7m_nvic_clear_pending(void *opaque, int irq, bool secure)
219
+static void armv7m_nvic_clear_pending(NVICState *s, int irq, bool secure)
220
{
221
- NVICState *s = (NVICState *)opaque;
222
VecInfo *vec;
223
224
assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
225
@@ -XXX,XX +XXX,XX @@ static void do_armv7m_nvic_set_pending(void *opaque, int irq, bool secure,
226
}
28
}
227
}
29
}
228
30
229
-void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
31
-typedef uint64_t IMOPFn(uint64_t, uint64_t, uint64_t, uint8_t, bool);
230
+void armv7m_nvic_set_pending(NVICState *s, int irq, bool secure)
32
+typedef uint32_t IMOPFn32(uint32_t, uint32_t, uint32_t, uint8_t, bool);
33
+static inline void do_imopa_s(uint32_t *za, uint32_t *zn, uint32_t *zm,
34
+ uint8_t *pn, uint8_t *pm,
35
+ uint32_t desc, IMOPFn32 *fn)
36
+{
37
+ intptr_t row, col, oprsz = simd_oprsz(desc) / 4;
38
+ bool neg = simd_data(desc);
39
40
-static inline void do_imopa(uint64_t *za, uint64_t *zn, uint64_t *zm,
41
- uint8_t *pn, uint8_t *pm,
42
- uint32_t desc, IMOPFn *fn)
43
+ for (row = 0; row < oprsz; ++row) {
44
+ uint8_t pa = (pn[H1(row >> 1)] >> ((row & 1) * 4)) & 0xf;
45
+ uint32_t *za_row = &za[tile_vslice_index(row)];
46
+ uint32_t n = zn[H4(row)];
47
+
48
+ for (col = 0; col < oprsz; ++col) {
49
+ uint8_t pb = pm[H1(col >> 1)] >> ((col & 1) * 4);
50
+ uint32_t *a = &za_row[H4(col)];
51
+
52
+ *a = fn(n, zm[H4(col)], *a, pa & pb, neg);
53
+ }
54
+ }
55
+}
56
+
57
+typedef uint64_t IMOPFn64(uint64_t, uint64_t, uint64_t, uint8_t, bool);
58
+static inline void do_imopa_d(uint64_t *za, uint64_t *zn, uint64_t *zm,
59
+ uint8_t *pn, uint8_t *pm,
60
+ uint32_t desc, IMOPFn64 *fn)
231
{
61
{
232
- do_armv7m_nvic_set_pending(opaque, irq, secure, false);
62
intptr_t row, col, oprsz = simd_oprsz(desc) / 8;
233
+ do_armv7m_nvic_set_pending(s, irq, secure, false);
63
bool neg = simd_data(desc);
64
@@ -XXX,XX +XXX,XX @@ static inline void do_imopa(uint64_t *za, uint64_t *zn, uint64_t *zm,
234
}
65
}
235
66
236
-void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
67
#define DEF_IMOP_32(NAME, NTYPE, MTYPE) \
237
+void armv7m_nvic_set_pending_derived(NVICState *s, int irq, bool secure)
68
-static uint64_t NAME(uint64_t n, uint64_t m, uint64_t a, uint8_t p, bool neg) \
238
{
69
+static uint32_t NAME(uint32_t n, uint32_t m, uint32_t a, uint8_t p, bool neg) \
239
- do_armv7m_nvic_set_pending(opaque, irq, secure, true);
70
{ \
240
+ do_armv7m_nvic_set_pending(s, irq, secure, true);
71
- uint32_t sum0 = 0, sum1 = 0; \
72
+ uint32_t sum = 0; \
73
/* Apply P to N as a mask, making the inactive elements 0. */ \
74
n &= expand_pred_b(p); \
75
- sum0 += (NTYPE)(n >> 0) * (MTYPE)(m >> 0); \
76
- sum0 += (NTYPE)(n >> 8) * (MTYPE)(m >> 8); \
77
- sum0 += (NTYPE)(n >> 16) * (MTYPE)(m >> 16); \
78
- sum0 += (NTYPE)(n >> 24) * (MTYPE)(m >> 24); \
79
- sum1 += (NTYPE)(n >> 32) * (MTYPE)(m >> 32); \
80
- sum1 += (NTYPE)(n >> 40) * (MTYPE)(m >> 40); \
81
- sum1 += (NTYPE)(n >> 48) * (MTYPE)(m >> 48); \
82
- sum1 += (NTYPE)(n >> 56) * (MTYPE)(m >> 56); \
83
- if (neg) { \
84
- sum0 = (uint32_t)a - sum0, sum1 = (uint32_t)(a >> 32) - sum1; \
85
- } else { \
86
- sum0 = (uint32_t)a + sum0, sum1 = (uint32_t)(a >> 32) + sum1; \
87
- } \
88
- return ((uint64_t)sum1 << 32) | sum0; \
89
+ sum += (NTYPE)(n >> 0) * (MTYPE)(m >> 0); \
90
+ sum += (NTYPE)(n >> 8) * (MTYPE)(m >> 8); \
91
+ sum += (NTYPE)(n >> 16) * (MTYPE)(m >> 16); \
92
+ sum += (NTYPE)(n >> 24) * (MTYPE)(m >> 24); \
93
+ return neg ? a - sum : a + sum; \
241
}
94
}
242
95
243
-void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
96
#define DEF_IMOP_64(NAME, NTYPE, MTYPE) \
244
+void armv7m_nvic_set_pending_lazyfp(NVICState *s, int irq, bool secure)
97
@@ -XXX,XX +XXX,XX @@ DEF_IMOP_64(umopa_d, uint16_t, uint16_t)
245
{
98
DEF_IMOP_64(sumopa_d, int16_t, uint16_t)
246
/*
99
DEF_IMOP_64(usmopa_d, uint16_t, int16_t)
247
* Pend an exception during lazy FP stacking. This differs
100
248
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
101
-#define DEF_IMOPH(NAME) \
249
* whether we should escalate depends on the saved context
102
- void HELPER(sme_##NAME)(void *vza, void *vzn, void *vzm, void *vpn, \
250
* in the FPCCR register, not on the current state of the CPU/NVIC.
103
- void *vpm, uint32_t desc) \
251
*/
104
- { do_imopa(vza, vzn, vzm, vpn, vpm, desc, NAME); }
252
- NVICState *s = (NVICState *)opaque;
105
+#define DEF_IMOPH(NAME, S) \
253
bool banked = exc_is_banked(irq);
106
+ void HELPER(sme_##NAME##_##S)(void *vza, void *vzn, void *vzm, \
254
VecInfo *vec;
107
+ void *vpn, void *vpm, uint32_t desc) \
255
bool targets_secure;
108
+ { do_imopa_##S(vza, vzn, vzm, vpn, vpm, desc, NAME##_##S); }
256
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
109
257
}
110
-DEF_IMOPH(smopa_s)
258
111
-DEF_IMOPH(umopa_s)
259
/* Make pending IRQ active. */
112
-DEF_IMOPH(sumopa_s)
260
-void armv7m_nvic_acknowledge_irq(void *opaque)
113
-DEF_IMOPH(usmopa_s)
261
+void armv7m_nvic_acknowledge_irq(NVICState *s)
114
-DEF_IMOPH(smopa_d)
262
{
115
-DEF_IMOPH(umopa_d)
263
- NVICState *s = (NVICState *)opaque;
116
-DEF_IMOPH(sumopa_d)
264
CPUARMState *env = &s->cpu->env;
117
-DEF_IMOPH(usmopa_d)
265
const int pending = s->vectpending;
118
+DEF_IMOPH(smopa, s)
266
const int running = nvic_exec_prio(s);
119
+DEF_IMOPH(umopa, s)
267
@@ -XXX,XX +XXX,XX @@ static bool vectpending_targets_secure(NVICState *s)
120
+DEF_IMOPH(sumopa, s)
268
exc_targets_secure(s, s->vectpending);
121
+DEF_IMOPH(usmopa, s)
269
}
122
+
270
123
+DEF_IMOPH(smopa, d)
271
-void armv7m_nvic_get_pending_irq_info(void *opaque,
124
+DEF_IMOPH(umopa, d)
272
+void armv7m_nvic_get_pending_irq_info(NVICState *s,
125
+DEF_IMOPH(sumopa, d)
273
int *pirq, bool *ptargets_secure)
126
+DEF_IMOPH(usmopa, d)
274
{
127
diff --git a/tests/tcg/aarch64/sme-smopa-1.c b/tests/tcg/aarch64/sme-smopa-1.c
275
- NVICState *s = (NVICState *)opaque;
128
new file mode 100644
276
const int pending = s->vectpending;
129
index XXXXXXX..XXXXXXX
277
bool targets_secure;
130
--- /dev/null
278
131
+++ b/tests/tcg/aarch64/sme-smopa-1.c
279
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_get_pending_irq_info(void *opaque,
132
@@ -XXX,XX +XXX,XX @@
280
*pirq = pending;
133
+#include <stdio.h>
281
}
134
+#include <string.h>
282
135
+
283
-int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
136
+int main()
284
+int armv7m_nvic_complete_irq(NVICState *s, int irq, bool secure)
137
+{
285
{
138
+ static const int cmp[4][4] = {
286
- NVICState *s = (NVICState *)opaque;
139
+ { 110, 134, 158, 182 },
287
VecInfo *vec = NULL;
140
+ { 390, 478, 566, 654 },
288
int ret = 0;
141
+ { 670, 822, 974, 1126 },
289
142
+ { 950, 1166, 1382, 1598 }
290
@@ -XXX,XX +XXX,XX @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
143
+ };
291
return ret;
144
+ int dst[4][4];
292
}
145
+ int *tmp = &dst[0][0];
293
146
+
294
-bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
147
+ asm volatile(
295
+bool armv7m_nvic_get_ready_status(NVICState *s, int irq, bool secure)
148
+ ".arch armv8-r+sme\n\t"
296
{
149
+ "smstart\n\t"
297
/*
150
+ "index z0.b, #0, #1\n\t"
298
* Return whether an exception is "ready", i.e. it is enabled and is
151
+ "movprfx z1, z0\n\t"
299
@@ -XXX,XX +XXX,XX @@ bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
152
+ "add z1.b, z1.b, #16\n\t"
300
* for non-banked exceptions secure is always false; for banked exceptions
153
+ "ptrue p0.b\n\t"
301
* it indicates which of the exceptions is required.
154
+ "smopa za0.s, p0/m, p0/m, z0.b, z1.b\n\t"
302
*/
155
+ "ptrue p0.s, vl4\n\t"
303
- NVICState *s = (NVICState *)opaque;
156
+ "mov w12, #0\n\t"
304
bool banked = exc_is_banked(irq);
157
+ "st1w { za0h.s[w12, #0] }, p0, [%0]\n\t"
305
VecInfo *vec;
158
+ "add %0, %0, #16\n\t"
306
int running = nvic_exec_prio(s);
159
+ "st1w { za0h.s[w12, #1] }, p0, [%0]\n\t"
307
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
160
+ "add %0, %0, #16\n\t"
161
+ "st1w { za0h.s[w12, #2] }, p0, [%0]\n\t"
162
+ "add %0, %0, #16\n\t"
163
+ "st1w { za0h.s[w12, #3] }, p0, [%0]\n\t"
164
+ "smstop"
165
+ : "+r"(tmp) : : "memory");
166
+
167
+ if (memcmp(cmp, dst, sizeof(dst)) == 0) {
168
+ return 0;
169
+ }
170
+
171
+ /* See above for correct results. */
172
+ for (int i = 0; i < 4; ++i) {
173
+ for (int j = 0; j < 4; ++j) {
174
+ printf("%6d", dst[i][j]);
175
+ }
176
+ printf("\n");
177
+ }
178
+ return 1;
179
+}
180
diff --git a/tests/tcg/aarch64/sme-smopa-2.c b/tests/tcg/aarch64/sme-smopa-2.c
181
new file mode 100644
182
index XXXXXXX..XXXXXXX
183
--- /dev/null
184
+++ b/tests/tcg/aarch64/sme-smopa-2.c
185
@@ -XXX,XX +XXX,XX @@
186
+#include <stdio.h>
187
+#include <string.h>
188
+
189
+int main()
190
+{
191
+ static const long cmp[4][4] = {
192
+ { 110, 134, 158, 182 },
193
+ { 390, 478, 566, 654 },
194
+ { 670, 822, 974, 1126 },
195
+ { 950, 1166, 1382, 1598 }
196
+ };
197
+ long dst[4][4];
198
+ long *tmp = &dst[0][0];
199
+ long svl;
200
+
201
+ /* Validate that we have a wide enough vector for 4 elements. */
202
+ asm(".arch armv8-r+sme-i64\n\trdsvl %0, #1" : "=r"(svl));
203
+ if (svl < 32) {
204
+ return 0;
205
+ }
206
+
207
+ asm volatile(
208
+ "smstart\n\t"
209
+ "index z0.h, #0, #1\n\t"
210
+ "movprfx z1, z0\n\t"
211
+ "add z1.h, z1.h, #16\n\t"
212
+ "ptrue p0.b\n\t"
213
+ "smopa za0.d, p0/m, p0/m, z0.h, z1.h\n\t"
214
+ "ptrue p0.d, vl4\n\t"
215
+ "mov w12, #0\n\t"
216
+ "st1d { za0h.d[w12, #0] }, p0, [%0]\n\t"
217
+ "add %0, %0, #32\n\t"
218
+ "st1d { za0h.d[w12, #1] }, p0, [%0]\n\t"
219
+ "mov w12, #2\n\t"
220
+ "add %0, %0, #32\n\t"
221
+ "st1d { za0h.d[w12, #0] }, p0, [%0]\n\t"
222
+ "add %0, %0, #32\n\t"
223
+ "st1d { za0h.d[w12, #1] }, p0, [%0]\n\t"
224
+ "smstop"
225
+ : "+r"(tmp) : : "memory");
226
+
227
+ if (memcmp(cmp, dst, sizeof(dst)) == 0) {
228
+ return 0;
229
+ }
230
+
231
+ /* See above for correct results. */
232
+ for (int i = 0; i < 4; ++i) {
233
+ for (int j = 0; j < 4; ++j) {
234
+ printf("%6ld", dst[i][j]);
235
+ }
236
+ printf("\n");
237
+ }
238
+ return 1;
239
+}
240
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
308
index XXXXXXX..XXXXXXX 100644
241
index XXXXXXX..XXXXXXX 100644
309
--- a/target/arm/cpu.c
242
--- a/tests/tcg/aarch64/Makefile.target
310
+++ b/target/arm/cpu.c
243
+++ b/tests/tcg/aarch64/Makefile.target
311
@@ -XXX,XX +XXX,XX @@
244
@@ -XXX,XX +XXX,XX @@ endif
312
#if !defined(CONFIG_USER_ONLY)
245
313
#include "hw/loader.h"
246
# SME Tests
314
#include "hw/boards.h"
247
ifneq ($(CROSS_AS_HAS_ARMV9_SME),)
315
+#include "hw/intc/armv7m_nvic.h"
248
-AARCH64_TESTS += sme-outprod1
316
#endif
249
+AARCH64_TESTS += sme-outprod1 sme-smopa-1 sme-smopa-2
317
#include "sysemu/tcg.h"
250
endif
318
#include "sysemu/qtest.h"
251
319
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
252
# System Registers Tests
320
index XXXXXXX..XXXXXXX 100644
321
--- a/target/arm/m_helper.c
322
+++ b/target/arm/m_helper.c
323
@@ -XXX,XX +XXX,XX @@ static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
324
* that we will need later in order to do lazy FP reg stacking.
325
*/
326
bool is_secure = env->v7m.secure;
327
- void *nvic = env->nvic;
328
+ NVICState *nvic = env->nvic;
329
/*
330
* Some bits are unbanked and live always in fpccr[M_REG_S]; some bits
331
* are banked and we want to update the bit in the bank for the
332
--
253
--
333
2.34.1
254
2.34.1
334
255
335
256
diff view generated by jsdifflib
1
From: Fabiano Rosas <farosas@suse.de>
1
The sun4v RTC device model added under commit a0e893039cf2ce0 in 2016
2
was unfortunately added with a license of GPL-v3-or-later, which is
3
not compatible with other QEMU code which has a GPL-v2-only license.
2
4
3
If a test was tagged with the "accel" tag and the specified
5
Relicense the code in the .c and the .h file to GPL-v2-or-later,
4
accelerator it not present in the qemu binary, cancel the test.
6
to make it compatible with the rest of QEMU.
5
7
6
We can now write tests without explicit calls to require_accelerator,
8
Cc: qemu-stable@nongnu.org
7
just the tag is enough.
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
10
Signed-off-by: Paolo Bonzini (for Red Hat) <pbonzini@redhat.com>
9
Signed-off-by: Fabiano Rosas <farosas@suse.de>
11
Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Signed-off-by: Markus Armbruster <armbru@redhat.com>
11
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
14
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
15
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
16
Acked-by: Alex Bennée <alex.bennee@linaro.org>
17
Message-id: 20240223161300.938542-1-peter.maydell@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
19
---
14
tests/avocado/avocado_qemu/__init__.py | 4 ++++
20
include/hw/rtc/sun4v-rtc.h | 2 +-
15
1 file changed, 4 insertions(+)
21
hw/rtc/sun4v-rtc.c | 2 +-
22
2 files changed, 2 insertions(+), 2 deletions(-)
16
23
17
diff --git a/tests/avocado/avocado_qemu/__init__.py b/tests/avocado/avocado_qemu/__init__.py
24
diff --git a/include/hw/rtc/sun4v-rtc.h b/include/hw/rtc/sun4v-rtc.h
18
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/avocado/avocado_qemu/__init__.py
26
--- a/include/hw/rtc/sun4v-rtc.h
20
+++ b/tests/avocado/avocado_qemu/__init__.py
27
+++ b/include/hw/rtc/sun4v-rtc.h
21
@@ -XXX,XX +XXX,XX @@ def setUp(self):
28
@@ -XXX,XX +XXX,XX @@
22
29
*
23
super().setUp('qemu-system-')
30
* Copyright (c) 2016 Artyom Tarasenko
24
31
*
25
+ accel_required = self._get_unique_tag_val('accel')
32
- * This code is licensed under the GNU GPL v3 or (at your option) any later
26
+ if accel_required:
33
+ * This code is licensed under the GNU GPL v2 or (at your option) any later
27
+ self.require_accelerator(accel_required)
34
* version.
28
+
35
*/
29
self.machine = self.params.get('machine',
36
30
default=self._get_unique_tag_val('machine'))
37
diff --git a/hw/rtc/sun4v-rtc.c b/hw/rtc/sun4v-rtc.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/rtc/sun4v-rtc.c
40
+++ b/hw/rtc/sun4v-rtc.c
41
@@ -XXX,XX +XXX,XX @@
42
*
43
* Copyright (c) 2016 Artyom Tarasenko
44
*
45
- * This code is licensed under the GNU GPL v3 or (at your option) any later
46
+ * This code is licensed under the GNU GPL v2 or (at your option) any later
47
* version.
48
*/
31
49
32
--
50
--
33
2.34.1
51
2.34.1
34
52
35
53
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
While dozens of files include "cpu.h", only 3 files require
3
Move the code to a separate file so that we do not have to compile
4
these NVIC helper declarations.
4
it anymore if CONFIG_ARM_V7M is not set.
5
5
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Thomas Huth <thuth@redhat.com>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20240308141051.536599-2-thuth@redhat.com
8
Message-id: 20230206223502.25122-12-philmd@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
include/hw/intc/armv7m_nvic.h | 123 ++++++++++++++++++++++++++++++++++
11
target/arm/tcg/cpu-v7m.c | 290 +++++++++++++++++++++++++++++++++++++
12
target/arm/cpu.h | 123 ----------------------------------
12
target/arm/tcg/cpu32.c | 261 ---------------------------------
13
target/arm/cpu.c | 4 +-
13
target/arm/meson.build | 3 +
14
target/arm/cpu_tcg.c | 3 +
14
target/arm/tcg/meson.build | 3 +
15
target/arm/m_helper.c | 3 +
15
4 files changed, 296 insertions(+), 261 deletions(-)
16
5 files changed, 132 insertions(+), 124 deletions(-)
16
create mode 100644 target/arm/tcg/cpu-v7m.c
17
17
18
diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
18
diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c
19
new file mode 100644
20
index XXXXXXX..XXXXXXX
21
--- /dev/null
22
+++ b/target/arm/tcg/cpu-v7m.c
23
@@ -XXX,XX +XXX,XX @@
24
+/*
25
+ * QEMU ARMv7-M TCG-only CPUs.
26
+ *
27
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
28
+ *
29
+ * This code is licensed under the GNU GPL v2 or later.
30
+ *
31
+ * SPDX-License-Identifier: GPL-2.0-or-later
32
+ */
33
+
34
+#include "qemu/osdep.h"
35
+#include "cpu.h"
36
+#include "hw/core/tcg-cpu-ops.h"
37
+#include "internals.h"
38
+
39
+#if !defined(CONFIG_USER_ONLY)
40
+
41
+#include "hw/intc/armv7m_nvic.h"
42
+
43
+static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
44
+{
45
+ CPUClass *cc = CPU_GET_CLASS(cs);
46
+ ARMCPU *cpu = ARM_CPU(cs);
47
+ CPUARMState *env = &cpu->env;
48
+ bool ret = false;
49
+
50
+ /*
51
+ * ARMv7-M interrupt masking works differently than -A or -R.
52
+ * There is no FIQ/IRQ distinction. Instead of I and F bits
53
+ * masking FIQ and IRQ interrupts, an exception is taken only
54
+ * if it is higher priority than the current execution priority
55
+ * (which depends on state like BASEPRI, FAULTMASK and the
56
+ * currently active exception).
57
+ */
58
+ if (interrupt_request & CPU_INTERRUPT_HARD
59
+ && (armv7m_nvic_can_take_pending_exception(env->nvic))) {
60
+ cs->exception_index = EXCP_IRQ;
61
+ cc->tcg_ops->do_interrupt(cs);
62
+ ret = true;
63
+ }
64
+ return ret;
65
+}
66
+
67
+#endif /* !CONFIG_USER_ONLY */
68
+
69
+static void cortex_m0_initfn(Object *obj)
70
+{
71
+ ARMCPU *cpu = ARM_CPU(obj);
72
+ set_feature(&cpu->env, ARM_FEATURE_V6);
73
+ set_feature(&cpu->env, ARM_FEATURE_M);
74
+
75
+ cpu->midr = 0x410cc200;
76
+
77
+ /*
78
+ * These ID register values are not guest visible, because
79
+ * we do not implement the Main Extension. They must be set
80
+ * to values corresponding to the Cortex-M0's implemented
81
+ * features, because QEMU generally controls its emulation
82
+ * by looking at ID register fields. We use the same values as
83
+ * for the M3.
84
+ */
85
+ cpu->isar.id_pfr0 = 0x00000030;
86
+ cpu->isar.id_pfr1 = 0x00000200;
87
+ cpu->isar.id_dfr0 = 0x00100000;
88
+ cpu->id_afr0 = 0x00000000;
89
+ cpu->isar.id_mmfr0 = 0x00000030;
90
+ cpu->isar.id_mmfr1 = 0x00000000;
91
+ cpu->isar.id_mmfr2 = 0x00000000;
92
+ cpu->isar.id_mmfr3 = 0x00000000;
93
+ cpu->isar.id_isar0 = 0x01141110;
94
+ cpu->isar.id_isar1 = 0x02111000;
95
+ cpu->isar.id_isar2 = 0x21112231;
96
+ cpu->isar.id_isar3 = 0x01111110;
97
+ cpu->isar.id_isar4 = 0x01310102;
98
+ cpu->isar.id_isar5 = 0x00000000;
99
+ cpu->isar.id_isar6 = 0x00000000;
100
+}
101
+
102
+static void cortex_m3_initfn(Object *obj)
103
+{
104
+ ARMCPU *cpu = ARM_CPU(obj);
105
+ set_feature(&cpu->env, ARM_FEATURE_V7);
106
+ set_feature(&cpu->env, ARM_FEATURE_M);
107
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
108
+ cpu->midr = 0x410fc231;
109
+ cpu->pmsav7_dregion = 8;
110
+ cpu->isar.id_pfr0 = 0x00000030;
111
+ cpu->isar.id_pfr1 = 0x00000200;
112
+ cpu->isar.id_dfr0 = 0x00100000;
113
+ cpu->id_afr0 = 0x00000000;
114
+ cpu->isar.id_mmfr0 = 0x00000030;
115
+ cpu->isar.id_mmfr1 = 0x00000000;
116
+ cpu->isar.id_mmfr2 = 0x00000000;
117
+ cpu->isar.id_mmfr3 = 0x00000000;
118
+ cpu->isar.id_isar0 = 0x01141110;
119
+ cpu->isar.id_isar1 = 0x02111000;
120
+ cpu->isar.id_isar2 = 0x21112231;
121
+ cpu->isar.id_isar3 = 0x01111110;
122
+ cpu->isar.id_isar4 = 0x01310102;
123
+ cpu->isar.id_isar5 = 0x00000000;
124
+ cpu->isar.id_isar6 = 0x00000000;
125
+}
126
+
127
+static void cortex_m4_initfn(Object *obj)
128
+{
129
+ ARMCPU *cpu = ARM_CPU(obj);
130
+
131
+ set_feature(&cpu->env, ARM_FEATURE_V7);
132
+ set_feature(&cpu->env, ARM_FEATURE_M);
133
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
134
+ set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
135
+ cpu->midr = 0x410fc240; /* r0p0 */
136
+ cpu->pmsav7_dregion = 8;
137
+ cpu->isar.mvfr0 = 0x10110021;
138
+ cpu->isar.mvfr1 = 0x11000011;
139
+ cpu->isar.mvfr2 = 0x00000000;
140
+ cpu->isar.id_pfr0 = 0x00000030;
141
+ cpu->isar.id_pfr1 = 0x00000200;
142
+ cpu->isar.id_dfr0 = 0x00100000;
143
+ cpu->id_afr0 = 0x00000000;
144
+ cpu->isar.id_mmfr0 = 0x00000030;
145
+ cpu->isar.id_mmfr1 = 0x00000000;
146
+ cpu->isar.id_mmfr2 = 0x00000000;
147
+ cpu->isar.id_mmfr3 = 0x00000000;
148
+ cpu->isar.id_isar0 = 0x01141110;
149
+ cpu->isar.id_isar1 = 0x02111000;
150
+ cpu->isar.id_isar2 = 0x21112231;
151
+ cpu->isar.id_isar3 = 0x01111110;
152
+ cpu->isar.id_isar4 = 0x01310102;
153
+ cpu->isar.id_isar5 = 0x00000000;
154
+ cpu->isar.id_isar6 = 0x00000000;
155
+}
156
+
157
+static void cortex_m7_initfn(Object *obj)
158
+{
159
+ ARMCPU *cpu = ARM_CPU(obj);
160
+
161
+ set_feature(&cpu->env, ARM_FEATURE_V7);
162
+ set_feature(&cpu->env, ARM_FEATURE_M);
163
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
164
+ set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
165
+ cpu->midr = 0x411fc272; /* r1p2 */
166
+ cpu->pmsav7_dregion = 8;
167
+ cpu->isar.mvfr0 = 0x10110221;
168
+ cpu->isar.mvfr1 = 0x12000011;
169
+ cpu->isar.mvfr2 = 0x00000040;
170
+ cpu->isar.id_pfr0 = 0x00000030;
171
+ cpu->isar.id_pfr1 = 0x00000200;
172
+ cpu->isar.id_dfr0 = 0x00100000;
173
+ cpu->id_afr0 = 0x00000000;
174
+ cpu->isar.id_mmfr0 = 0x00100030;
175
+ cpu->isar.id_mmfr1 = 0x00000000;
176
+ cpu->isar.id_mmfr2 = 0x01000000;
177
+ cpu->isar.id_mmfr3 = 0x00000000;
178
+ cpu->isar.id_isar0 = 0x01101110;
179
+ cpu->isar.id_isar1 = 0x02112000;
180
+ cpu->isar.id_isar2 = 0x20232231;
181
+ cpu->isar.id_isar3 = 0x01111131;
182
+ cpu->isar.id_isar4 = 0x01310132;
183
+ cpu->isar.id_isar5 = 0x00000000;
184
+ cpu->isar.id_isar6 = 0x00000000;
185
+}
186
+
187
+static void cortex_m33_initfn(Object *obj)
188
+{
189
+ ARMCPU *cpu = ARM_CPU(obj);
190
+
191
+ set_feature(&cpu->env, ARM_FEATURE_V8);
192
+ set_feature(&cpu->env, ARM_FEATURE_M);
193
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
194
+ set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
195
+ set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
196
+ cpu->midr = 0x410fd213; /* r0p3 */
197
+ cpu->pmsav7_dregion = 16;
198
+ cpu->sau_sregion = 8;
199
+ cpu->isar.mvfr0 = 0x10110021;
200
+ cpu->isar.mvfr1 = 0x11000011;
201
+ cpu->isar.mvfr2 = 0x00000040;
202
+ cpu->isar.id_pfr0 = 0x00000030;
203
+ cpu->isar.id_pfr1 = 0x00000210;
204
+ cpu->isar.id_dfr0 = 0x00200000;
205
+ cpu->id_afr0 = 0x00000000;
206
+ cpu->isar.id_mmfr0 = 0x00101F40;
207
+ cpu->isar.id_mmfr1 = 0x00000000;
208
+ cpu->isar.id_mmfr2 = 0x01000000;
209
+ cpu->isar.id_mmfr3 = 0x00000000;
210
+ cpu->isar.id_isar0 = 0x01101110;
211
+ cpu->isar.id_isar1 = 0x02212000;
212
+ cpu->isar.id_isar2 = 0x20232232;
213
+ cpu->isar.id_isar3 = 0x01111131;
214
+ cpu->isar.id_isar4 = 0x01310132;
215
+ cpu->isar.id_isar5 = 0x00000000;
216
+ cpu->isar.id_isar6 = 0x00000000;
217
+ cpu->clidr = 0x00000000;
218
+ cpu->ctr = 0x8000c000;
219
+}
220
+
221
+static void cortex_m55_initfn(Object *obj)
222
+{
223
+ ARMCPU *cpu = ARM_CPU(obj);
224
+
225
+ set_feature(&cpu->env, ARM_FEATURE_V8);
226
+ set_feature(&cpu->env, ARM_FEATURE_V8_1M);
227
+ set_feature(&cpu->env, ARM_FEATURE_M);
228
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
229
+ set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
230
+ set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
231
+ cpu->midr = 0x410fd221; /* r0p1 */
232
+ cpu->revidr = 0;
233
+ cpu->pmsav7_dregion = 16;
234
+ cpu->sau_sregion = 8;
235
+ /* These are the MVFR* values for the FPU + full MVE configuration */
236
+ cpu->isar.mvfr0 = 0x10110221;
237
+ cpu->isar.mvfr1 = 0x12100211;
238
+ cpu->isar.mvfr2 = 0x00000040;
239
+ cpu->isar.id_pfr0 = 0x20000030;
240
+ cpu->isar.id_pfr1 = 0x00000230;
241
+ cpu->isar.id_dfr0 = 0x10200000;
242
+ cpu->id_afr0 = 0x00000000;
243
+ cpu->isar.id_mmfr0 = 0x00111040;
244
+ cpu->isar.id_mmfr1 = 0x00000000;
245
+ cpu->isar.id_mmfr2 = 0x01000000;
246
+ cpu->isar.id_mmfr3 = 0x00000011;
247
+ cpu->isar.id_isar0 = 0x01103110;
248
+ cpu->isar.id_isar1 = 0x02212000;
249
+ cpu->isar.id_isar2 = 0x20232232;
250
+ cpu->isar.id_isar3 = 0x01111131;
251
+ cpu->isar.id_isar4 = 0x01310132;
252
+ cpu->isar.id_isar5 = 0x00000000;
253
+ cpu->isar.id_isar6 = 0x00000000;
254
+ cpu->clidr = 0x00000000; /* caches not implemented */
255
+ cpu->ctr = 0x8303c003;
256
+}
257
+
258
+static const TCGCPUOps arm_v7m_tcg_ops = {
259
+ .initialize = arm_translate_init,
260
+ .synchronize_from_tb = arm_cpu_synchronize_from_tb,
261
+ .debug_excp_handler = arm_debug_excp_handler,
262
+ .restore_state_to_opc = arm_restore_state_to_opc,
263
+
264
+#ifdef CONFIG_USER_ONLY
265
+ .record_sigsegv = arm_cpu_record_sigsegv,
266
+ .record_sigbus = arm_cpu_record_sigbus,
267
+#else
268
+ .tlb_fill = arm_cpu_tlb_fill,
269
+ .cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt,
270
+ .do_interrupt = arm_v7m_cpu_do_interrupt,
271
+ .do_transaction_failed = arm_cpu_do_transaction_failed,
272
+ .do_unaligned_access = arm_cpu_do_unaligned_access,
273
+ .adjust_watchpoint_address = arm_adjust_watchpoint_address,
274
+ .debug_check_watchpoint = arm_debug_check_watchpoint,
275
+ .debug_check_breakpoint = arm_debug_check_breakpoint,
276
+#endif /* !CONFIG_USER_ONLY */
277
+};
278
+
279
+static void arm_v7m_class_init(ObjectClass *oc, void *data)
280
+{
281
+ ARMCPUClass *acc = ARM_CPU_CLASS(oc);
282
+ CPUClass *cc = CPU_CLASS(oc);
283
+
284
+ acc->info = data;
285
+ cc->tcg_ops = &arm_v7m_tcg_ops;
286
+ cc->gdb_core_xml_file = "arm-m-profile.xml";
287
+}
288
+
289
+static const ARMCPUInfo arm_v7m_cpus[] = {
290
+ { .name = "cortex-m0", .initfn = cortex_m0_initfn,
291
+ .class_init = arm_v7m_class_init },
292
+ { .name = "cortex-m3", .initfn = cortex_m3_initfn,
293
+ .class_init = arm_v7m_class_init },
294
+ { .name = "cortex-m4", .initfn = cortex_m4_initfn,
295
+ .class_init = arm_v7m_class_init },
296
+ { .name = "cortex-m7", .initfn = cortex_m7_initfn,
297
+ .class_init = arm_v7m_class_init },
298
+ { .name = "cortex-m33", .initfn = cortex_m33_initfn,
299
+ .class_init = arm_v7m_class_init },
300
+ { .name = "cortex-m55", .initfn = cortex_m55_initfn,
301
+ .class_init = arm_v7m_class_init },
302
+};
303
+
304
+static void arm_v7m_cpu_register_types(void)
305
+{
306
+ size_t i;
307
+
308
+ for (i = 0; i < ARRAY_SIZE(arm_v7m_cpus); ++i) {
309
+ arm_cpu_register(&arm_v7m_cpus[i]);
310
+ }
311
+}
312
+
313
+type_init(arm_v7m_cpu_register_types)
314
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
19
index XXXXXXX..XXXXXXX 100644
315
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/intc/armv7m_nvic.h
316
--- a/target/arm/tcg/cpu32.c
21
+++ b/include/hw/intc/armv7m_nvic.h
317
+++ b/target/arm/tcg/cpu32.c
22
@@ -XXX,XX +XXX,XX @@ struct NVICState {
23
qemu_irq sysresetreq;
24
};
25
26
+/* Interface between CPU and Interrupt controller. */
27
+/**
28
+ * armv7m_nvic_set_pending: mark the specified exception as pending
29
+ * @s: the NVIC
30
+ * @irq: the exception number to mark pending
31
+ * @secure: false for non-banked exceptions or for the nonsecure
32
+ * version of a banked exception, true for the secure version of a banked
33
+ * exception.
34
+ *
35
+ * Marks the specified exception as pending. Note that we will assert()
36
+ * if @secure is true and @irq does not specify one of the fixed set
37
+ * of architecturally banked exceptions.
38
+ */
39
+void armv7m_nvic_set_pending(NVICState *s, int irq, bool secure);
40
+/**
41
+ * armv7m_nvic_set_pending_derived: mark this derived exception as pending
42
+ * @s: the NVIC
43
+ * @irq: the exception number to mark pending
44
+ * @secure: false for non-banked exceptions or for the nonsecure
45
+ * version of a banked exception, true for the secure version of a banked
46
+ * exception.
47
+ *
48
+ * Similar to armv7m_nvic_set_pending(), but specifically for derived
49
+ * exceptions (exceptions generated in the course of trying to take
50
+ * a different exception).
51
+ */
52
+void armv7m_nvic_set_pending_derived(NVICState *s, int irq, bool secure);
53
+/**
54
+ * armv7m_nvic_set_pending_lazyfp: mark this lazy FP exception as pending
55
+ * @s: the NVIC
56
+ * @irq: the exception number to mark pending
57
+ * @secure: false for non-banked exceptions or for the nonsecure
58
+ * version of a banked exception, true for the secure version of a banked
59
+ * exception.
60
+ *
61
+ * Similar to armv7m_nvic_set_pending(), but specifically for exceptions
62
+ * generated in the course of lazy stacking of FP registers.
63
+ */
64
+void armv7m_nvic_set_pending_lazyfp(NVICState *s, int irq, bool secure);
65
+/**
66
+ * armv7m_nvic_get_pending_irq_info: return highest priority pending
67
+ * exception, and whether it targets Secure state
68
+ * @s: the NVIC
69
+ * @pirq: set to pending exception number
70
+ * @ptargets_secure: set to whether pending exception targets Secure
71
+ *
72
+ * This function writes the number of the highest priority pending
73
+ * exception (the one which would be made active by
74
+ * armv7m_nvic_acknowledge_irq()) to @pirq, and sets @ptargets_secure
75
+ * to true if the current highest priority pending exception should
76
+ * be taken to Secure state, false for NS.
77
+ */
78
+void armv7m_nvic_get_pending_irq_info(NVICState *s, int *pirq,
79
+ bool *ptargets_secure);
80
+/**
81
+ * armv7m_nvic_acknowledge_irq: make highest priority pending exception active
82
+ * @s: the NVIC
83
+ *
84
+ * Move the current highest priority pending exception from the pending
85
+ * state to the active state, and update v7m.exception to indicate that
86
+ * it is the exception currently being handled.
87
+ */
88
+void armv7m_nvic_acknowledge_irq(NVICState *s);
89
+/**
90
+ * armv7m_nvic_complete_irq: complete specified interrupt or exception
91
+ * @s: the NVIC
92
+ * @irq: the exception number to complete
93
+ * @secure: true if this exception was secure
94
+ *
95
+ * Returns: -1 if the irq was not active
96
+ * 1 if completing this irq brought us back to base (no active irqs)
97
+ * 0 if there is still an irq active after this one was completed
98
+ * (Ignoring -1, this is the same as the RETTOBASE value before completion.)
99
+ */
100
+int armv7m_nvic_complete_irq(NVICState *s, int irq, bool secure);
101
+/**
102
+ * armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
103
+ * @s: the NVIC
104
+ * @irq: the exception number to mark pending
105
+ * @secure: false for non-banked exceptions or for the nonsecure
106
+ * version of a banked exception, true for the secure version of a banked
107
+ * exception.
108
+ *
109
+ * Return whether an exception is "ready", i.e. whether the exception is
110
+ * enabled and is configured at a priority which would allow it to
111
+ * interrupt the current execution priority. This controls whether the
112
+ * RDY bit for it in the FPCCR is set.
113
+ */
114
+bool armv7m_nvic_get_ready_status(NVICState *s, int irq, bool secure);
115
+/**
116
+ * armv7m_nvic_raw_execution_priority: return the raw execution priority
117
+ * @s: the NVIC
118
+ *
119
+ * Returns: the raw execution priority as defined by the v8M architecture.
120
+ * This is the execution priority minus the effects of AIRCR.PRIS,
121
+ * and minus any PRIMASK/FAULTMASK/BASEPRI priority boosting.
122
+ * (v8M ARM ARM I_PKLD.)
123
+ */
124
+int armv7m_nvic_raw_execution_priority(NVICState *s);
125
+/**
126
+ * armv7m_nvic_neg_prio_requested: return true if the requested execution
127
+ * priority is negative for the specified security state.
128
+ * @s: the NVIC
129
+ * @secure: the security state to test
130
+ * This corresponds to the pseudocode IsReqExecPriNeg().
131
+ */
132
+#ifndef CONFIG_USER_ONLY
133
+bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure);
134
+#else
135
+static inline bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure)
136
+{
137
+ return false;
138
+}
139
+#endif
140
+#ifndef CONFIG_USER_ONLY
141
+bool armv7m_nvic_can_take_pending_exception(NVICState *s);
142
+#else
143
+static inline bool armv7m_nvic_can_take_pending_exception(NVICState *s)
144
+{
145
+ return true;
146
+}
147
+#endif
148
+
149
#endif
150
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
151
index XXXXXXX..XXXXXXX 100644
152
--- a/target/arm/cpu.h
153
+++ b/target/arm/cpu.h
154
@@ -XXX,XX +XXX,XX @@ void arm_cpu_list(void);
155
uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
156
uint32_t cur_el, bool secure);
157
158
-/* Interface between CPU and Interrupt controller. */
159
-#ifndef CONFIG_USER_ONLY
160
-bool armv7m_nvic_can_take_pending_exception(NVICState *s);
161
-#else
162
-static inline bool armv7m_nvic_can_take_pending_exception(NVICState *s)
163
-{
164
- return true;
165
-}
166
-#endif
167
-/**
168
- * armv7m_nvic_set_pending: mark the specified exception as pending
169
- * @s: the NVIC
170
- * @irq: the exception number to mark pending
171
- * @secure: false for non-banked exceptions or for the nonsecure
172
- * version of a banked exception, true for the secure version of a banked
173
- * exception.
174
- *
175
- * Marks the specified exception as pending. Note that we will assert()
176
- * if @secure is true and @irq does not specify one of the fixed set
177
- * of architecturally banked exceptions.
178
- */
179
-void armv7m_nvic_set_pending(NVICState *s, int irq, bool secure);
180
-/**
181
- * armv7m_nvic_set_pending_derived: mark this derived exception as pending
182
- * @s: the NVIC
183
- * @irq: the exception number to mark pending
184
- * @secure: false for non-banked exceptions or for the nonsecure
185
- * version of a banked exception, true for the secure version of a banked
186
- * exception.
187
- *
188
- * Similar to armv7m_nvic_set_pending(), but specifically for derived
189
- * exceptions (exceptions generated in the course of trying to take
190
- * a different exception).
191
- */
192
-void armv7m_nvic_set_pending_derived(NVICState *s, int irq, bool secure);
193
-/**
194
- * armv7m_nvic_set_pending_lazyfp: mark this lazy FP exception as pending
195
- * @s: the NVIC
196
- * @irq: the exception number to mark pending
197
- * @secure: false for non-banked exceptions or for the nonsecure
198
- * version of a banked exception, true for the secure version of a banked
199
- * exception.
200
- *
201
- * Similar to armv7m_nvic_set_pending(), but specifically for exceptions
202
- * generated in the course of lazy stacking of FP registers.
203
- */
204
-void armv7m_nvic_set_pending_lazyfp(NVICState *s, int irq, bool secure);
205
-/**
206
- * armv7m_nvic_get_pending_irq_info: return highest priority pending
207
- * exception, and whether it targets Secure state
208
- * @s: the NVIC
209
- * @pirq: set to pending exception number
210
- * @ptargets_secure: set to whether pending exception targets Secure
211
- *
212
- * This function writes the number of the highest priority pending
213
- * exception (the one which would be made active by
214
- * armv7m_nvic_acknowledge_irq()) to @pirq, and sets @ptargets_secure
215
- * to true if the current highest priority pending exception should
216
- * be taken to Secure state, false for NS.
217
- */
218
-void armv7m_nvic_get_pending_irq_info(NVICState *s, int *pirq,
219
- bool *ptargets_secure);
220
-/**
221
- * armv7m_nvic_acknowledge_irq: make highest priority pending exception active
222
- * @s: the NVIC
223
- *
224
- * Move the current highest priority pending exception from the pending
225
- * state to the active state, and update v7m.exception to indicate that
226
- * it is the exception currently being handled.
227
- */
228
-void armv7m_nvic_acknowledge_irq(NVICState *s);
229
-/**
230
- * armv7m_nvic_complete_irq: complete specified interrupt or exception
231
- * @s: the NVIC
232
- * @irq: the exception number to complete
233
- * @secure: true if this exception was secure
234
- *
235
- * Returns: -1 if the irq was not active
236
- * 1 if completing this irq brought us back to base (no active irqs)
237
- * 0 if there is still an irq active after this one was completed
238
- * (Ignoring -1, this is the same as the RETTOBASE value before completion.)
239
- */
240
-int armv7m_nvic_complete_irq(NVICState *s, int irq, bool secure);
241
-/**
242
- * armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
243
- * @s: the NVIC
244
- * @irq: the exception number to mark pending
245
- * @secure: false for non-banked exceptions or for the nonsecure
246
- * version of a banked exception, true for the secure version of a banked
247
- * exception.
248
- *
249
- * Return whether an exception is "ready", i.e. whether the exception is
250
- * enabled and is configured at a priority which would allow it to
251
- * interrupt the current execution priority. This controls whether the
252
- * RDY bit for it in the FPCCR is set.
253
- */
254
-bool armv7m_nvic_get_ready_status(NVICState *s, int irq, bool secure);
255
-/**
256
- * armv7m_nvic_raw_execution_priority: return the raw execution priority
257
- * @s: the NVIC
258
- *
259
- * Returns: the raw execution priority as defined by the v8M architecture.
260
- * This is the execution priority minus the effects of AIRCR.PRIS,
261
- * and minus any PRIMASK/FAULTMASK/BASEPRI priority boosting.
262
- * (v8M ARM ARM I_PKLD.)
263
- */
264
-int armv7m_nvic_raw_execution_priority(NVICState *s);
265
-/**
266
- * armv7m_nvic_neg_prio_requested: return true if the requested execution
267
- * priority is negative for the specified security state.
268
- * @s: the NVIC
269
- * @secure: the security state to test
270
- * This corresponds to the pseudocode IsReqExecPriNeg().
271
- */
272
-#ifndef CONFIG_USER_ONLY
273
-bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure);
274
-#else
275
-static inline bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure)
276
-{
277
- return false;
278
-}
279
-#endif
280
-
281
/* Interface for defining coprocessor registers.
282
* Registers are defined in tables of arm_cp_reginfo structs
283
* which are passed to define_arm_cp_regs().
284
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
285
index XXXXXXX..XXXXXXX 100644
286
--- a/target/arm/cpu.c
287
+++ b/target/arm/cpu.c
288
@@ -XXX,XX +XXX,XX @@
289
#if !defined(CONFIG_USER_ONLY)
290
#include "hw/loader.h"
291
#include "hw/boards.h"
292
+#ifdef CONFIG_TCG
293
#include "hw/intc/armv7m_nvic.h"
294
-#endif
295
+#endif /* CONFIG_TCG */
296
+#endif /* !CONFIG_USER_ONLY */
297
#include "sysemu/tcg.h"
298
#include "sysemu/qtest.h"
299
#include "sysemu/hw_accel.h"
300
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
301
index XXXXXXX..XXXXXXX 100644
302
--- a/target/arm/cpu_tcg.c
303
+++ b/target/arm/cpu_tcg.c
304
@@ -XXX,XX +XXX,XX @@
318
@@ -XXX,XX +XXX,XX @@
305
#include "hw/boards.h"
319
#include "hw/boards.h"
306
#endif
320
#endif
307
#include "cpregs.h"
321
#include "cpregs.h"
308
+#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG)
322
-#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG)
309
+#include "hw/intc/armv7m_nvic.h"
323
-#include "hw/intc/armv7m_nvic.h"
310
+#endif
324
-#endif
311
325
312
326
313
/* Share AArch32 -cpu max features with AArch64. */
327
/* Share AArch32 -cpu max features with AArch64. */
314
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
328
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
329
/* CPU models. These are not needed for the AArch64 linux-user build. */
330
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
331
332
-#if !defined(CONFIG_USER_ONLY)
333
-static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
334
-{
335
- CPUClass *cc = CPU_GET_CLASS(cs);
336
- ARMCPU *cpu = ARM_CPU(cs);
337
- CPUARMState *env = &cpu->env;
338
- bool ret = false;
339
-
340
- /*
341
- * ARMv7-M interrupt masking works differently than -A or -R.
342
- * There is no FIQ/IRQ distinction. Instead of I and F bits
343
- * masking FIQ and IRQ interrupts, an exception is taken only
344
- * if it is higher priority than the current execution priority
345
- * (which depends on state like BASEPRI, FAULTMASK and the
346
- * currently active exception).
347
- */
348
- if (interrupt_request & CPU_INTERRUPT_HARD
349
- && (armv7m_nvic_can_take_pending_exception(env->nvic))) {
350
- cs->exception_index = EXCP_IRQ;
351
- cc->tcg_ops->do_interrupt(cs);
352
- ret = true;
353
- }
354
- return ret;
355
-}
356
-#endif /* !CONFIG_USER_ONLY */
357
-
358
static void arm926_initfn(Object *obj)
359
{
360
ARMCPU *cpu = ARM_CPU(obj);
361
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
362
define_arm_cp_regs(cpu, cortexa15_cp_reginfo);
363
}
364
365
-static void cortex_m0_initfn(Object *obj)
366
-{
367
- ARMCPU *cpu = ARM_CPU(obj);
368
- set_feature(&cpu->env, ARM_FEATURE_V6);
369
- set_feature(&cpu->env, ARM_FEATURE_M);
370
-
371
- cpu->midr = 0x410cc200;
372
-
373
- /*
374
- * These ID register values are not guest visible, because
375
- * we do not implement the Main Extension. They must be set
376
- * to values corresponding to the Cortex-M0's implemented
377
- * features, because QEMU generally controls its emulation
378
- * by looking at ID register fields. We use the same values as
379
- * for the M3.
380
- */
381
- cpu->isar.id_pfr0 = 0x00000030;
382
- cpu->isar.id_pfr1 = 0x00000200;
383
- cpu->isar.id_dfr0 = 0x00100000;
384
- cpu->id_afr0 = 0x00000000;
385
- cpu->isar.id_mmfr0 = 0x00000030;
386
- cpu->isar.id_mmfr1 = 0x00000000;
387
- cpu->isar.id_mmfr2 = 0x00000000;
388
- cpu->isar.id_mmfr3 = 0x00000000;
389
- cpu->isar.id_isar0 = 0x01141110;
390
- cpu->isar.id_isar1 = 0x02111000;
391
- cpu->isar.id_isar2 = 0x21112231;
392
- cpu->isar.id_isar3 = 0x01111110;
393
- cpu->isar.id_isar4 = 0x01310102;
394
- cpu->isar.id_isar5 = 0x00000000;
395
- cpu->isar.id_isar6 = 0x00000000;
396
-}
397
-
398
-static void cortex_m3_initfn(Object *obj)
399
-{
400
- ARMCPU *cpu = ARM_CPU(obj);
401
- set_feature(&cpu->env, ARM_FEATURE_V7);
402
- set_feature(&cpu->env, ARM_FEATURE_M);
403
- set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
404
- cpu->midr = 0x410fc231;
405
- cpu->pmsav7_dregion = 8;
406
- cpu->isar.id_pfr0 = 0x00000030;
407
- cpu->isar.id_pfr1 = 0x00000200;
408
- cpu->isar.id_dfr0 = 0x00100000;
409
- cpu->id_afr0 = 0x00000000;
410
- cpu->isar.id_mmfr0 = 0x00000030;
411
- cpu->isar.id_mmfr1 = 0x00000000;
412
- cpu->isar.id_mmfr2 = 0x00000000;
413
- cpu->isar.id_mmfr3 = 0x00000000;
414
- cpu->isar.id_isar0 = 0x01141110;
415
- cpu->isar.id_isar1 = 0x02111000;
416
- cpu->isar.id_isar2 = 0x21112231;
417
- cpu->isar.id_isar3 = 0x01111110;
418
- cpu->isar.id_isar4 = 0x01310102;
419
- cpu->isar.id_isar5 = 0x00000000;
420
- cpu->isar.id_isar6 = 0x00000000;
421
-}
422
-
423
-static void cortex_m4_initfn(Object *obj)
424
-{
425
- ARMCPU *cpu = ARM_CPU(obj);
426
-
427
- set_feature(&cpu->env, ARM_FEATURE_V7);
428
- set_feature(&cpu->env, ARM_FEATURE_M);
429
- set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
430
- set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
431
- cpu->midr = 0x410fc240; /* r0p0 */
432
- cpu->pmsav7_dregion = 8;
433
- cpu->isar.mvfr0 = 0x10110021;
434
- cpu->isar.mvfr1 = 0x11000011;
435
- cpu->isar.mvfr2 = 0x00000000;
436
- cpu->isar.id_pfr0 = 0x00000030;
437
- cpu->isar.id_pfr1 = 0x00000200;
438
- cpu->isar.id_dfr0 = 0x00100000;
439
- cpu->id_afr0 = 0x00000000;
440
- cpu->isar.id_mmfr0 = 0x00000030;
441
- cpu->isar.id_mmfr1 = 0x00000000;
442
- cpu->isar.id_mmfr2 = 0x00000000;
443
- cpu->isar.id_mmfr3 = 0x00000000;
444
- cpu->isar.id_isar0 = 0x01141110;
445
- cpu->isar.id_isar1 = 0x02111000;
446
- cpu->isar.id_isar2 = 0x21112231;
447
- cpu->isar.id_isar3 = 0x01111110;
448
- cpu->isar.id_isar4 = 0x01310102;
449
- cpu->isar.id_isar5 = 0x00000000;
450
- cpu->isar.id_isar6 = 0x00000000;
451
-}
452
-
453
-static void cortex_m7_initfn(Object *obj)
454
-{
455
- ARMCPU *cpu = ARM_CPU(obj);
456
-
457
- set_feature(&cpu->env, ARM_FEATURE_V7);
458
- set_feature(&cpu->env, ARM_FEATURE_M);
459
- set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
460
- set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
461
- cpu->midr = 0x411fc272; /* r1p2 */
462
- cpu->pmsav7_dregion = 8;
463
- cpu->isar.mvfr0 = 0x10110221;
464
- cpu->isar.mvfr1 = 0x12000011;
465
- cpu->isar.mvfr2 = 0x00000040;
466
- cpu->isar.id_pfr0 = 0x00000030;
467
- cpu->isar.id_pfr1 = 0x00000200;
468
- cpu->isar.id_dfr0 = 0x00100000;
469
- cpu->id_afr0 = 0x00000000;
470
- cpu->isar.id_mmfr0 = 0x00100030;
471
- cpu->isar.id_mmfr1 = 0x00000000;
472
- cpu->isar.id_mmfr2 = 0x01000000;
473
- cpu->isar.id_mmfr3 = 0x00000000;
474
- cpu->isar.id_isar0 = 0x01101110;
475
- cpu->isar.id_isar1 = 0x02112000;
476
- cpu->isar.id_isar2 = 0x20232231;
477
- cpu->isar.id_isar3 = 0x01111131;
478
- cpu->isar.id_isar4 = 0x01310132;
479
- cpu->isar.id_isar5 = 0x00000000;
480
- cpu->isar.id_isar6 = 0x00000000;
481
-}
482
-
483
-static void cortex_m33_initfn(Object *obj)
484
-{
485
- ARMCPU *cpu = ARM_CPU(obj);
486
-
487
- set_feature(&cpu->env, ARM_FEATURE_V8);
488
- set_feature(&cpu->env, ARM_FEATURE_M);
489
- set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
490
- set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
491
- set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
492
- cpu->midr = 0x410fd213; /* r0p3 */
493
- cpu->pmsav7_dregion = 16;
494
- cpu->sau_sregion = 8;
495
- cpu->isar.mvfr0 = 0x10110021;
496
- cpu->isar.mvfr1 = 0x11000011;
497
- cpu->isar.mvfr2 = 0x00000040;
498
- cpu->isar.id_pfr0 = 0x00000030;
499
- cpu->isar.id_pfr1 = 0x00000210;
500
- cpu->isar.id_dfr0 = 0x00200000;
501
- cpu->id_afr0 = 0x00000000;
502
- cpu->isar.id_mmfr0 = 0x00101F40;
503
- cpu->isar.id_mmfr1 = 0x00000000;
504
- cpu->isar.id_mmfr2 = 0x01000000;
505
- cpu->isar.id_mmfr3 = 0x00000000;
506
- cpu->isar.id_isar0 = 0x01101110;
507
- cpu->isar.id_isar1 = 0x02212000;
508
- cpu->isar.id_isar2 = 0x20232232;
509
- cpu->isar.id_isar3 = 0x01111131;
510
- cpu->isar.id_isar4 = 0x01310132;
511
- cpu->isar.id_isar5 = 0x00000000;
512
- cpu->isar.id_isar6 = 0x00000000;
513
- cpu->clidr = 0x00000000;
514
- cpu->ctr = 0x8000c000;
515
-}
516
-
517
-static void cortex_m55_initfn(Object *obj)
518
-{
519
- ARMCPU *cpu = ARM_CPU(obj);
520
-
521
- set_feature(&cpu->env, ARM_FEATURE_V8);
522
- set_feature(&cpu->env, ARM_FEATURE_V8_1M);
523
- set_feature(&cpu->env, ARM_FEATURE_M);
524
- set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
525
- set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
526
- set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
527
- cpu->midr = 0x410fd221; /* r0p1 */
528
- cpu->revidr = 0;
529
- cpu->pmsav7_dregion = 16;
530
- cpu->sau_sregion = 8;
531
- /* These are the MVFR* values for the FPU + full MVE configuration */
532
- cpu->isar.mvfr0 = 0x10110221;
533
- cpu->isar.mvfr1 = 0x12100211;
534
- cpu->isar.mvfr2 = 0x00000040;
535
- cpu->isar.id_pfr0 = 0x20000030;
536
- cpu->isar.id_pfr1 = 0x00000230;
537
- cpu->isar.id_dfr0 = 0x10200000;
538
- cpu->id_afr0 = 0x00000000;
539
- cpu->isar.id_mmfr0 = 0x00111040;
540
- cpu->isar.id_mmfr1 = 0x00000000;
541
- cpu->isar.id_mmfr2 = 0x01000000;
542
- cpu->isar.id_mmfr3 = 0x00000011;
543
- cpu->isar.id_isar0 = 0x01103110;
544
- cpu->isar.id_isar1 = 0x02212000;
545
- cpu->isar.id_isar2 = 0x20232232;
546
- cpu->isar.id_isar3 = 0x01111131;
547
- cpu->isar.id_isar4 = 0x01310132;
548
- cpu->isar.id_isar5 = 0x00000000;
549
- cpu->isar.id_isar6 = 0x00000000;
550
- cpu->clidr = 0x00000000; /* caches not implemented */
551
- cpu->ctr = 0x8303c003;
552
-}
553
-
554
static const ARMCPRegInfo cortexr5_cp_reginfo[] = {
555
/* Dummy the TCM region regs for the moment */
556
{ .name = "ATCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
557
@@ -XXX,XX +XXX,XX @@ static void pxa270c5_initfn(Object *obj)
558
cpu->reset_sctlr = 0x00000078;
559
}
560
561
-static const TCGCPUOps arm_v7m_tcg_ops = {
562
- .initialize = arm_translate_init,
563
- .synchronize_from_tb = arm_cpu_synchronize_from_tb,
564
- .debug_excp_handler = arm_debug_excp_handler,
565
- .restore_state_to_opc = arm_restore_state_to_opc,
566
-
567
-#ifdef CONFIG_USER_ONLY
568
- .record_sigsegv = arm_cpu_record_sigsegv,
569
- .record_sigbus = arm_cpu_record_sigbus,
570
-#else
571
- .tlb_fill = arm_cpu_tlb_fill,
572
- .cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt,
573
- .do_interrupt = arm_v7m_cpu_do_interrupt,
574
- .do_transaction_failed = arm_cpu_do_transaction_failed,
575
- .do_unaligned_access = arm_cpu_do_unaligned_access,
576
- .adjust_watchpoint_address = arm_adjust_watchpoint_address,
577
- .debug_check_watchpoint = arm_debug_check_watchpoint,
578
- .debug_check_breakpoint = arm_debug_check_breakpoint,
579
-#endif /* !CONFIG_USER_ONLY */
580
-};
581
-
582
-static void arm_v7m_class_init(ObjectClass *oc, void *data)
583
-{
584
- ARMCPUClass *acc = ARM_CPU_CLASS(oc);
585
- CPUClass *cc = CPU_CLASS(oc);
586
-
587
- acc->info = data;
588
- cc->tcg_ops = &arm_v7m_tcg_ops;
589
- cc->gdb_core_xml_file = "arm-m-profile.xml";
590
-}
591
-
592
#ifndef TARGET_AARCH64
593
/*
594
* -cpu max: a CPU with as many features enabled as our emulation supports.
595
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_tcg_cpus[] = {
596
{ .name = "cortex-a8", .initfn = cortex_a8_initfn },
597
{ .name = "cortex-a9", .initfn = cortex_a9_initfn },
598
{ .name = "cortex-a15", .initfn = cortex_a15_initfn },
599
- { .name = "cortex-m0", .initfn = cortex_m0_initfn,
600
- .class_init = arm_v7m_class_init },
601
- { .name = "cortex-m3", .initfn = cortex_m3_initfn,
602
- .class_init = arm_v7m_class_init },
603
- { .name = "cortex-m4", .initfn = cortex_m4_initfn,
604
- .class_init = arm_v7m_class_init },
605
- { .name = "cortex-m7", .initfn = cortex_m7_initfn,
606
- .class_init = arm_v7m_class_init },
607
- { .name = "cortex-m33", .initfn = cortex_m33_initfn,
608
- .class_init = arm_v7m_class_init },
609
- { .name = "cortex-m55", .initfn = cortex_m55_initfn,
610
- .class_init = arm_v7m_class_init },
611
{ .name = "cortex-r5", .initfn = cortex_r5_initfn },
612
{ .name = "cortex-r5f", .initfn = cortex_r5f_initfn },
613
{ .name = "cortex-r52", .initfn = cortex_r52_initfn },
614
diff --git a/target/arm/meson.build b/target/arm/meson.build
315
index XXXXXXX..XXXXXXX 100644
615
index XXXXXXX..XXXXXXX 100644
316
--- a/target/arm/m_helper.c
616
--- a/target/arm/meson.build
317
+++ b/target/arm/m_helper.c
617
+++ b/target/arm/meson.build
318
@@ -XXX,XX +XXX,XX @@
618
@@ -XXX,XX +XXX,XX @@ arm_system_ss.add(files(
319
#include "exec/cpu_ldst.h"
619
'ptw.c',
320
#include "semihosting/common-semi.h"
620
))
321
#endif
621
322
+#if !defined(CONFIG_USER_ONLY)
622
+arm_user_ss = ss.source_set()
323
+#include "hw/intc/armv7m_nvic.h"
623
+
324
+#endif
624
subdir('hvf')
325
625
326
static void v7m_msr_xpsr(CPUARMState *env, uint32_t mask,
626
if 'CONFIG_TCG' in config_all_accel
327
uint32_t reg, uint32_t val)
627
@@ -XXX,XX +XXX,XX @@ endif
628
629
target_arch += {'arm': arm_ss}
630
target_system_arch += {'arm': arm_system_ss}
631
+target_user_arch += {'arm': arm_user_ss}
632
diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build
633
index XXXXXXX..XXXXXXX 100644
634
--- a/target/arm/tcg/meson.build
635
+++ b/target/arm/tcg/meson.build
636
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
637
arm_system_ss.add(files(
638
'psci.c',
639
))
640
+
641
+arm_system_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('cpu-v7m.c'))
642
+arm_user_ss.add(when: 'TARGET_AARCH64', if_false: files('cpu-v7m.c'))
328
--
643
--
329
2.34.1
644
2.34.1
330
331
diff view generated by jsdifflib
Deleted patch
1
From: Alex Bennée <alex.bennee@linaro.org>
2
1
3
The two TCG tests for GICv2 and GICv3 are very heavy weight distros
4
that take a long time to boot up, especially for an --enable-debug
5
build. The total code coverage they give is:
6
7
Overall coverage rate:
8
lines......: 11.2% (59584 of 530123 lines)
9
functions..: 15.0% (7436 of 49443 functions)
10
branches...: 6.3% (19273 of 303933 branches)
11
12
We already get pretty close to that with the machine_aarch64_virt
13
tests which only does one full boot (~120s vs ~600s) of alpine. We
14
expand the kernel+initrd boot (~8s) to test both GICs and also add an
15
RNG device and a block device to generate a few IRQs and exercise the
16
storage layer. With that we get to a coverage of:
17
18
Overall coverage rate:
19
lines......: 11.0% (58121 of 530123 lines)
20
functions..: 14.9% (7343 of 49443 functions)
21
branches...: 6.0% (18269 of 303933 branches)
22
23
which I feel is close enough given the massive time saving. If we want
24
to target any more sub-systems we can use lighter weight more directed
25
tests.
26
27
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
28
Reviewed-by: Fabiano Rosas <farosas@suse.de>
29
Acked-by: Richard Henderson <richard.henderson@linaro.org>
30
Message-id: 20230203181632.2919715-1-alex.bennee@linaro.org
31
Cc: Peter Maydell <peter.maydell@linaro.org>
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
---
34
tests/avocado/boot_linux.py | 48 ++++----------------
35
tests/avocado/machine_aarch64_virt.py | 63 ++++++++++++++++++++++++---
36
2 files changed, 65 insertions(+), 46 deletions(-)
37
38
diff --git a/tests/avocado/boot_linux.py b/tests/avocado/boot_linux.py
39
index XXXXXXX..XXXXXXX 100644
40
--- a/tests/avocado/boot_linux.py
41
+++ b/tests/avocado/boot_linux.py
42
@@ -XXX,XX +XXX,XX @@ def test_pc_q35_kvm(self):
43
self.launch_and_wait(set_up_ssh_connection=False)
44
45
46
-# For Aarch64 we only boot KVM tests in CI as the TCG tests are very
47
-# heavyweight. There are lighter weight distros which we use in the
48
-# machine_aarch64_virt.py tests.
49
+# For Aarch64 we only boot KVM tests in CI as booting the current
50
+# Fedora OS in TCG tests is very heavyweight. There are lighter weight
51
+# distros which we use in the machine_aarch64_virt.py tests.
52
class BootLinuxAarch64(LinuxTest):
53
"""
54
:avocado: tags=arch:aarch64
55
:avocado: tags=machine:virt
56
- :avocado: tags=machine:gic-version=2
57
"""
58
timeout = 720
59
60
- def add_common_args(self):
61
- self.vm.add_args('-bios',
62
- os.path.join(BUILD_DIR, 'pc-bios',
63
- 'edk2-aarch64-code.fd'))
64
- self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0')
65
- self.vm.add_args('-object', 'rng-random,id=rng0,filename=/dev/urandom')
66
-
67
- @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab')
68
- def test_fedora_cloud_tcg_gicv2(self):
69
- """
70
- :avocado: tags=accel:tcg
71
- :avocado: tags=cpu:max
72
- :avocado: tags=device:gicv2
73
- """
74
- self.require_accelerator("tcg")
75
- self.vm.add_args("-accel", "tcg")
76
- self.vm.add_args("-cpu", "max,lpa2=off")
77
- self.vm.add_args("-machine", "virt,gic-version=2")
78
- self.add_common_args()
79
- self.launch_and_wait(set_up_ssh_connection=False)
80
-
81
- @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab')
82
- def test_fedora_cloud_tcg_gicv3(self):
83
- """
84
- :avocado: tags=accel:tcg
85
- :avocado: tags=cpu:max
86
- :avocado: tags=device:gicv3
87
- """
88
- self.require_accelerator("tcg")
89
- self.vm.add_args("-accel", "tcg")
90
- self.vm.add_args("-cpu", "max,lpa2=off")
91
- self.vm.add_args("-machine", "virt,gic-version=3")
92
- self.add_common_args()
93
- self.launch_and_wait(set_up_ssh_connection=False)
94
-
95
def test_virt_kvm(self):
96
"""
97
:avocado: tags=accel:kvm
98
@@ -XXX,XX +XXX,XX @@ def test_virt_kvm(self):
99
self.require_accelerator("kvm")
100
self.vm.add_args("-accel", "kvm")
101
self.vm.add_args("-machine", "virt,gic-version=host")
102
- self.add_common_args()
103
+ self.vm.add_args('-bios',
104
+ os.path.join(BUILD_DIR, 'pc-bios',
105
+ 'edk2-aarch64-code.fd'))
106
+ self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0')
107
+ self.vm.add_args('-object', 'rng-random,id=rng0,filename=/dev/urandom')
108
self.launch_and_wait(set_up_ssh_connection=False)
109
110
111
diff --git a/tests/avocado/machine_aarch64_virt.py b/tests/avocado/machine_aarch64_virt.py
112
index XXXXXXX..XXXXXXX 100644
113
--- a/tests/avocado/machine_aarch64_virt.py
114
+++ b/tests/avocado/machine_aarch64_virt.py
115
@@ -XXX,XX +XXX,XX @@
116
117
import time
118
import os
119
+import logging
120
121
from avocado_qemu import QemuSystemTest
122
from avocado_qemu import wait_for_console_pattern
123
from avocado_qemu import exec_command
124
from avocado_qemu import BUILD_DIR
125
+from avocado.utils import process
126
+from avocado.utils.path import find_command
127
128
class Aarch64VirtMachine(QemuSystemTest):
129
KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
130
@@ -XXX,XX +XXX,XX @@ def test_alpine_virt_tcg_gic_max(self):
131
self.wait_for_console_pattern('Welcome to Alpine Linux 3.16')
132
133
134
- def test_aarch64_virt(self):
135
+ def common_aarch64_virt(self, machine):
136
"""
137
- :avocado: tags=arch:aarch64
138
- :avocado: tags=machine:virt
139
- :avocado: tags=accel:tcg
140
- :avocado: tags=cpu:max
141
+ Common code to launch basic virt machine with kernel+initrd
142
+ and a scratch disk.
143
"""
144
+ logger = logging.getLogger('aarch64_virt')
145
+
146
kernel_url = ('https://fileserver.linaro.org/s/'
147
'z6B2ARM7DQT3HWN/download')
148
-
149
kernel_hash = 'ed11daab50c151dde0e1e9c9cb8b2d9bd3215347'
150
kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
151
152
@@ -XXX,XX +XXX,XX @@ def test_aarch64_virt(self):
153
'console=ttyAMA0')
154
self.require_accelerator("tcg")
155
self.vm.add_args('-cpu', 'max,pauth-impdef=on',
156
+ '-machine', machine,
157
'-accel', 'tcg',
158
'-kernel', kernel_path,
159
'-append', kernel_command_line)
160
+
161
+ # A RNG offers an easy way to generate a few IRQs
162
+ self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0')
163
+ self.vm.add_args('-object',
164
+ 'rng-random,id=rng0,filename=/dev/urandom')
165
+
166
+ # Also add a scratch block device
167
+ logger.info('creating scratch qcow2 image')
168
+ image_path = os.path.join(self.workdir, 'scratch.qcow2')
169
+ qemu_img = os.path.join(BUILD_DIR, 'qemu-img')
170
+ if not os.path.exists(qemu_img):
171
+ qemu_img = find_command('qemu-img', False)
172
+ if qemu_img is False:
173
+ self.cancel('Could not find "qemu-img", which is required to '
174
+ 'create the temporary qcow2 image')
175
+ cmd = '%s create -f qcow2 %s 8M' % (qemu_img, image_path)
176
+ process.run(cmd)
177
+
178
+ # Add the device
179
+ self.vm.add_args('-blockdev',
180
+ f"driver=qcow2,file.driver=file,file.filename={image_path},node-name=scratch")
181
+ self.vm.add_args('-device',
182
+ 'virtio-blk-device,drive=scratch')
183
+
184
self.vm.launch()
185
self.wait_for_console_pattern('Welcome to Buildroot')
186
time.sleep(0.1)
187
exec_command(self, 'root')
188
time.sleep(0.1)
189
+ exec_command(self, 'dd if=/dev/hwrng of=/dev/vda bs=512 count=4')
190
+ time.sleep(0.1)
191
+ exec_command(self, 'md5sum /dev/vda')
192
+ time.sleep(0.1)
193
+ exec_command(self, 'cat /proc/interrupts')
194
+ time.sleep(0.1)
195
exec_command(self, 'cat /proc/self/maps')
196
time.sleep(0.1)
197
+
198
+ def test_aarch64_virt_gicv3(self):
199
+ """
200
+ :avocado: tags=arch:aarch64
201
+ :avocado: tags=machine:virt
202
+ :avocado: tags=accel:tcg
203
+ :avocado: tags=cpu:max
204
+ """
205
+ self.common_aarch64_virt("virt,gic_version=3")
206
+
207
+ def test_aarch64_virt_gicv2(self):
208
+ """
209
+ :avocado: tags=arch:aarch64
210
+ :avocado: tags=machine:virt
211
+ :avocado: tags=accel:tcg
212
+ :avocado: tags=cpu:max
213
+ """
214
+ self.common_aarch64_virt("virt,gic-version=2")
215
--
216
2.34.1
217
218
diff view generated by jsdifflib
Deleted patch
1
From: Cornelia Huck <cohuck@redhat.com>
2
1
3
Just use current_accel_name() directly.
4
5
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
6
Reviewed-by: Eric Auger <eric.auger@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
hw/arm/virt.c | 6 +++---
11
1 file changed, 3 insertions(+), 3 deletions(-)
12
13
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/virt.c
16
+++ b/hw/arm/virt.c
17
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
18
if (vms->secure && (kvm_enabled() || hvf_enabled())) {
19
error_report("mach-virt: %s does not support providing "
20
"Security extensions (TrustZone) to the guest CPU",
21
- kvm_enabled() ? "KVM" : "HVF");
22
+ current_accel_name());
23
exit(1);
24
}
25
26
if (vms->virt && (kvm_enabled() || hvf_enabled())) {
27
error_report("mach-virt: %s does not support providing "
28
"Virtualization extensions to the guest CPU",
29
- kvm_enabled() ? "KVM" : "HVF");
30
+ current_accel_name());
31
exit(1);
32
}
33
34
if (vms->mte && (kvm_enabled() || hvf_enabled())) {
35
error_report("mach-virt: %s does not support providing "
36
"MTE to the guest CPU",
37
- kvm_enabled() ? "KVM" : "HVF");
38
+ current_accel_name());
39
exit(1);
40
}
41
42
--
43
2.34.1
diff view generated by jsdifflib
Deleted patch
1
From: Hao Wu <wuhaotsh@google.com>
2
1
3
Havard is no longer working on the Nuvoton systems for a while
4
and won't be able to do any work on it in the future. So I'll
5
take over maintaining the Nuvoton system from him.
6
7
Signed-off-by: Hao Wu <wuhaotsh@google.com>
8
Acked-by: Havard Skinnemoen <hskinnemoen@google.com>
9
Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org>
10
Message-id: 20230208235433.3989937-2-wuhaotsh@google.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
MAINTAINERS | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
diff --git a/MAINTAINERS b/MAINTAINERS
17
index XXXXXXX..XXXXXXX 100644
18
--- a/MAINTAINERS
19
+++ b/MAINTAINERS
20
@@ -XXX,XX +XXX,XX @@ F: include/hw/net/mv88w8618_eth.h
21
F: docs/system/arm/musicpal.rst
22
23
Nuvoton NPCM7xx
24
-M: Havard Skinnemoen <hskinnemoen@google.com>
25
M: Tyrone Ting <kfting@nuvoton.com>
26
+M: Hao Wu <wuhaotsh@google.com>
27
L: qemu-arm@nongnu.org
28
S: Supported
29
F: hw/*/npcm7xx*
30
--
31
2.34.1
diff view generated by jsdifflib
Deleted patch
1
From: Hao Wu <wuhaotsh@google.com>
2
1
3
Signed-off-by: Hao Wu <wuhaotsh@google.com>
4
Reviewed-by: Titus Rwantare <titusr@google.com>
5
Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org>
6
Message-id: 20230208235433.3989937-4-wuhaotsh@google.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
docs/system/arm/nuvoton.rst | 2 +-
10
include/hw/arm/npcm7xx.h | 2 ++
11
hw/arm/npcm7xx.c | 25 +++++++++++++++++++++++--
12
3 files changed, 26 insertions(+), 3 deletions(-)
13
14
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
15
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/nuvoton.rst
17
+++ b/docs/system/arm/nuvoton.rst
18
@@ -XXX,XX +XXX,XX @@ Supported devices
19
* SMBus controller (SMBF)
20
* Ethernet controller (EMC)
21
* Tachometer
22
+ * Peripheral SPI controller (PSPI)
23
24
Missing devices
25
---------------
26
@@ -XXX,XX +XXX,XX @@ Missing devices
27
28
* Ethernet controller (GMAC)
29
* USB device (USBD)
30
- * Peripheral SPI controller (PSPI)
31
* SD/MMC host
32
* PECI interface
33
* PCI and PCIe root complex and bridges
34
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/arm/npcm7xx.h
37
+++ b/include/hw/arm/npcm7xx.h
38
@@ -XXX,XX +XXX,XX @@
39
#include "hw/nvram/npcm7xx_otp.h"
40
#include "hw/timer/npcm7xx_timer.h"
41
#include "hw/ssi/npcm7xx_fiu.h"
42
+#include "hw/ssi/npcm_pspi.h"
43
#include "hw/usb/hcd-ehci.h"
44
#include "hw/usb/hcd-ohci.h"
45
#include "target/arm/cpu.h"
46
@@ -XXX,XX +XXX,XX @@ struct NPCM7xxState {
47
NPCM7xxFIUState fiu[2];
48
NPCM7xxEMCState emc[2];
49
NPCM7xxSDHCIState mmc;
50
+ NPCMPSPIState pspi[2];
51
};
52
53
#define TYPE_NPCM7XX "npcm7xx"
54
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/arm/npcm7xx.c
57
+++ b/hw/arm/npcm7xx.c
58
@@ -XXX,XX +XXX,XX @@ enum NPCM7xxInterrupt {
59
NPCM7XX_EMC1RX_IRQ = 15,
60
NPCM7XX_EMC1TX_IRQ,
61
NPCM7XX_MMC_IRQ = 26,
62
+ NPCM7XX_PSPI2_IRQ = 28,
63
+ NPCM7XX_PSPI1_IRQ = 31,
64
NPCM7XX_TIMER0_IRQ = 32, /* Timer Module 0 */
65
NPCM7XX_TIMER1_IRQ,
66
NPCM7XX_TIMER2_IRQ,
67
@@ -XXX,XX +XXX,XX @@ static const hwaddr npcm7xx_emc_addr[] = {
68
0xf0826000,
69
};
70
71
+/* Register base address for each PSPI Module */
72
+static const hwaddr npcm7xx_pspi_addr[] = {
73
+ 0xf0200000,
74
+ 0xf0201000,
75
+};
76
+
77
static const struct {
78
hwaddr regs_addr;
79
uint32_t unconnected_pins;
80
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_init(Object *obj)
81
object_initialize_child(obj, "emc[*]", &s->emc[i], TYPE_NPCM7XX_EMC);
82
}
83
84
+ for (i = 0; i < ARRAY_SIZE(s->pspi); i++) {
85
+ object_initialize_child(obj, "pspi[*]", &s->pspi[i], TYPE_NPCM_PSPI);
86
+ }
87
+
88
object_initialize_child(obj, "mmc", &s->mmc, TYPE_NPCM7XX_SDHCI);
89
}
90
91
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
92
sysbus_connect_irq(SYS_BUS_DEVICE(&s->mmc), 0,
93
npcm7xx_irq(s, NPCM7XX_MMC_IRQ));
94
95
+ /* PSPI */
96
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_pspi_addr) != ARRAY_SIZE(s->pspi));
97
+ for (i = 0; i < ARRAY_SIZE(s->pspi); i++) {
98
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->pspi[i]);
99
+ int irq = (i == 0) ? NPCM7XX_PSPI1_IRQ : NPCM7XX_PSPI2_IRQ;
100
+
101
+ sysbus_realize(sbd, &error_abort);
102
+ sysbus_mmio_map(sbd, 0, npcm7xx_pspi_addr[i]);
103
+ sysbus_connect_irq(sbd, 0, npcm7xx_irq(s, irq));
104
+ }
105
+
106
create_unimplemented_device("npcm7xx.shm", 0xc0001000, 4 * KiB);
107
create_unimplemented_device("npcm7xx.vdmx", 0xe0800000, 4 * KiB);
108
create_unimplemented_device("npcm7xx.pcierc", 0xe1000000, 64 * KiB);
109
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
110
create_unimplemented_device("npcm7xx.peci", 0xf0100000, 4 * KiB);
111
create_unimplemented_device("npcm7xx.siox[1]", 0xf0101000, 4 * KiB);
112
create_unimplemented_device("npcm7xx.siox[2]", 0xf0102000, 4 * KiB);
113
- create_unimplemented_device("npcm7xx.pspi1", 0xf0200000, 4 * KiB);
114
- create_unimplemented_device("npcm7xx.pspi2", 0xf0201000, 4 * KiB);
115
create_unimplemented_device("npcm7xx.ahbpci", 0xf0400000, 1 * MiB);
116
create_unimplemented_device("npcm7xx.mcphy", 0xf05f0000, 64 * KiB);
117
create_unimplemented_device("npcm7xx.gmac1", 0xf0802000, 8 * KiB);
118
--
119
2.34.1
diff view generated by jsdifflib
Deleted patch
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
1
3
Addresses targeting the second translation table (TTB1) in the SMMU have
4
all upper bits set. Ensure the IOMMU region covers all 64 bits.
5
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Message-id: 20230214171921.1917916-2-jean-philippe@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/arm/smmu-common.h | 2 --
13
hw/arm/smmu-common.c | 2 +-
14
2 files changed, 1 insertion(+), 3 deletions(-)
15
16
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/smmu-common.h
19
+++ b/include/hw/arm/smmu-common.h
20
@@ -XXX,XX +XXX,XX @@
21
#define SMMU_PCI_DEVFN_MAX 256
22
#define SMMU_PCI_DEVFN(sid) (sid & 0xFF)
23
24
-#define SMMU_MAX_VA_BITS 48
25
-
26
/*
27
* Page table walk error types
28
*/
29
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/smmu-common.c
32
+++ b/hw/arm/smmu-common.c
33
@@ -XXX,XX +XXX,XX @@ static AddressSpace *smmu_find_add_as(PCIBus *bus, void *opaque, int devfn)
34
35
memory_region_init_iommu(&sdev->iommu, sizeof(sdev->iommu),
36
s->mrtypename,
37
- OBJECT(s), name, 1ULL << SMMU_MAX_VA_BITS);
38
+ OBJECT(s), name, UINT64_MAX);
39
address_space_init(&sdev->as,
40
MEMORY_REGION(&sdev->iommu), name);
41
trace_smmu_add_mr(name);
42
--
43
2.34.1
diff view generated by jsdifflib
Deleted patch
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
1
3
Addresses targeting the second translation table (TTB1) in the SMMU have
4
all upper bits set (except for the top byte when TBI is enabled). Fix
5
the TTB1 check.
6
7
Reported-by: Ola Hugosson <ola.hugosson@arm.com>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
11
Message-id: 20230214171921.1917916-3-jean-philippe@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/arm/smmu-common.c | 2 +-
15
1 file changed, 1 insertion(+), 1 deletion(-)
16
17
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/smmu-common.c
20
+++ b/hw/arm/smmu-common.c
21
@@ -XXX,XX +XXX,XX @@ SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova)
22
/* there is a ttbr0 region and we are in it (high bits all zero) */
23
return &cfg->tt[0];
24
} else if (cfg->tt[1].tsz &&
25
- !extract64(iova, 64 - cfg->tt[1].tsz, cfg->tt[1].tsz - tbi_byte)) {
26
+ sextract64(iova, 64 - cfg->tt[1].tsz, cfg->tt[1].tsz - tbi_byte) == -1) {
27
/* there is a ttbr1 region and we are in it (high bits all one) */
28
return &cfg->tt[1];
29
} else if (!cfg->tt[0].tsz) {
30
--
31
2.34.1
diff view generated by jsdifflib
Deleted patch
1
From: Fabiano Rosas <farosas@suse.de>
2
1
3
Move this earlier to make the next patch diff cleaner. While here
4
update the comment slightly to not give the impression that the
5
misalignment affects only TCG.
6
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Signed-off-by: Fabiano Rosas <farosas@suse.de>
10
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/machine.c | 18 +++++++++---------
14
1 file changed, 9 insertions(+), 9 deletions(-)
15
16
diff --git a/target/arm/machine.c b/target/arm/machine.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/machine.c
19
+++ b/target/arm/machine.c
20
@@ -XXX,XX +XXX,XX @@ static int cpu_post_load(void *opaque, int version_id)
21
}
22
}
23
24
+ /*
25
+ * Misaligned thumb pc is architecturally impossible. Fail the
26
+ * incoming migration. For TCG it would trigger the assert in
27
+ * thumb_tr_translate_insn().
28
+ */
29
+ if (!is_a64(env) && env->thumb && (env->regs[15] & 1)) {
30
+ return -1;
31
+ }
32
+
33
hw_breakpoint_update_all(cpu);
34
hw_watchpoint_update_all(cpu);
35
36
@@ -XXX,XX +XXX,XX @@ static int cpu_post_load(void *opaque, int version_id)
37
}
38
}
39
40
- /*
41
- * Misaligned thumb pc is architecturally impossible.
42
- * We have an assert in thumb_tr_translate_insn to verify this.
43
- * Fail an incoming migrate to avoid this assert.
44
- */
45
- if (!is_a64(env) && env->thumb && (env->regs[15] & 1)) {
46
- return -1;
47
- }
48
-
49
if (!kvm_enabled()) {
50
pmu_op_finish(&cpu->env);
51
}
52
--
53
2.34.1
54
55
diff view generated by jsdifflib
Deleted patch
1
From: Fabiano Rosas <farosas@suse.de>
2
1
3
Since commit cf7c6d1004 ("target/arm: Split out cpregs.h") we now have
4
a cpregs.h header which is more suitable for this code.
5
6
Code moved verbatim.
7
8
Signed-off-by: Fabiano Rosas <farosas@suse.de>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/cpregs.h | 98 +++++++++++++++++++++++++++++++++++++++++++++
15
target/arm/cpu.h | 91 -----------------------------------------
16
2 files changed, 98 insertions(+), 91 deletions(-)
17
18
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpregs.h
21
+++ b/target/arm/cpregs.h
22
@@ -XXX,XX +XXX,XX @@ enum {
23
ARM_CP_SME = 1 << 19,
24
};
25
26
+/*
27
+ * Interface for defining coprocessor registers.
28
+ * Registers are defined in tables of arm_cp_reginfo structs
29
+ * which are passed to define_arm_cp_regs().
30
+ */
31
+
32
+/*
33
+ * When looking up a coprocessor register we look for it
34
+ * via an integer which encodes all of:
35
+ * coprocessor number
36
+ * Crn, Crm, opc1, opc2 fields
37
+ * 32 or 64 bit register (ie is it accessed via MRC/MCR
38
+ * or via MRRC/MCRR?)
39
+ * non-secure/secure bank (AArch32 only)
40
+ * We allow 4 bits for opc1 because MRRC/MCRR have a 4 bit field.
41
+ * (In this case crn and opc2 should be zero.)
42
+ * For AArch64, there is no 32/64 bit size distinction;
43
+ * instead all registers have a 2 bit op0, 3 bit op1 and op2,
44
+ * and 4 bit CRn and CRm. The encoding patterns are chosen
45
+ * to be easy to convert to and from the KVM encodings, and also
46
+ * so that the hashtable can contain both AArch32 and AArch64
47
+ * registers (to allow for interprocessing where we might run
48
+ * 32 bit code on a 64 bit core).
49
+ */
50
+/*
51
+ * This bit is private to our hashtable cpreg; in KVM register
52
+ * IDs the AArch64/32 distinction is the KVM_REG_ARM/ARM64
53
+ * in the upper bits of the 64 bit ID.
54
+ */
55
+#define CP_REG_AA64_SHIFT 28
56
+#define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT)
57
+
58
+/*
59
+ * To enable banking of coprocessor registers depending on ns-bit we
60
+ * add a bit to distinguish between secure and non-secure cpregs in the
61
+ * hashtable.
62
+ */
63
+#define CP_REG_NS_SHIFT 29
64
+#define CP_REG_NS_MASK (1 << CP_REG_NS_SHIFT)
65
+
66
+#define ENCODE_CP_REG(cp, is64, ns, crn, crm, opc1, opc2) \
67
+ ((ns) << CP_REG_NS_SHIFT | ((cp) << 16) | ((is64) << 15) | \
68
+ ((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2))
69
+
70
+#define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \
71
+ (CP_REG_AA64_MASK | \
72
+ ((cp) << CP_REG_ARM_COPROC_SHIFT) | \
73
+ ((op0) << CP_REG_ARM64_SYSREG_OP0_SHIFT) | \
74
+ ((op1) << CP_REG_ARM64_SYSREG_OP1_SHIFT) | \
75
+ ((crn) << CP_REG_ARM64_SYSREG_CRN_SHIFT) | \
76
+ ((crm) << CP_REG_ARM64_SYSREG_CRM_SHIFT) | \
77
+ ((op2) << CP_REG_ARM64_SYSREG_OP2_SHIFT))
78
+
79
+/*
80
+ * Convert a full 64 bit KVM register ID to the truncated 32 bit
81
+ * version used as a key for the coprocessor register hashtable
82
+ */
83
+static inline uint32_t kvm_to_cpreg_id(uint64_t kvmid)
84
+{
85
+ uint32_t cpregid = kvmid;
86
+ if ((kvmid & CP_REG_ARCH_MASK) == CP_REG_ARM64) {
87
+ cpregid |= CP_REG_AA64_MASK;
88
+ } else {
89
+ if ((kvmid & CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) {
90
+ cpregid |= (1 << 15);
91
+ }
92
+
93
+ /*
94
+ * KVM is always non-secure so add the NS flag on AArch32 register
95
+ * entries.
96
+ */
97
+ cpregid |= 1 << CP_REG_NS_SHIFT;
98
+ }
99
+ return cpregid;
100
+}
101
+
102
+/*
103
+ * Convert a truncated 32 bit hashtable key into the full
104
+ * 64 bit KVM register ID.
105
+ */
106
+static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
107
+{
108
+ uint64_t kvmid;
109
+
110
+ if (cpregid & CP_REG_AA64_MASK) {
111
+ kvmid = cpregid & ~CP_REG_AA64_MASK;
112
+ kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM64;
113
+ } else {
114
+ kvmid = cpregid & ~(1 << 15);
115
+ if (cpregid & (1 << 15)) {
116
+ kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM;
117
+ } else {
118
+ kvmid |= CP_REG_SIZE_U32 | CP_REG_ARM;
119
+ }
120
+ }
121
+ return kvmid;
122
+}
123
+
124
/*
125
* Valid values for ARMCPRegInfo state field, indicating which of
126
* the AArch32 and AArch64 execution states this register is visible in.
127
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
128
index XXXXXXX..XXXXXXX 100644
129
--- a/target/arm/cpu.h
130
+++ b/target/arm/cpu.h
131
@@ -XXX,XX +XXX,XX @@ void arm_cpu_list(void);
132
uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
133
uint32_t cur_el, bool secure);
134
135
-/* Interface for defining coprocessor registers.
136
- * Registers are defined in tables of arm_cp_reginfo structs
137
- * which are passed to define_arm_cp_regs().
138
- */
139
-
140
-/* When looking up a coprocessor register we look for it
141
- * via an integer which encodes all of:
142
- * coprocessor number
143
- * Crn, Crm, opc1, opc2 fields
144
- * 32 or 64 bit register (ie is it accessed via MRC/MCR
145
- * or via MRRC/MCRR?)
146
- * non-secure/secure bank (AArch32 only)
147
- * We allow 4 bits for opc1 because MRRC/MCRR have a 4 bit field.
148
- * (In this case crn and opc2 should be zero.)
149
- * For AArch64, there is no 32/64 bit size distinction;
150
- * instead all registers have a 2 bit op0, 3 bit op1 and op2,
151
- * and 4 bit CRn and CRm. The encoding patterns are chosen
152
- * to be easy to convert to and from the KVM encodings, and also
153
- * so that the hashtable can contain both AArch32 and AArch64
154
- * registers (to allow for interprocessing where we might run
155
- * 32 bit code on a 64 bit core).
156
- */
157
-/* This bit is private to our hashtable cpreg; in KVM register
158
- * IDs the AArch64/32 distinction is the KVM_REG_ARM/ARM64
159
- * in the upper bits of the 64 bit ID.
160
- */
161
-#define CP_REG_AA64_SHIFT 28
162
-#define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT)
163
-
164
-/* To enable banking of coprocessor registers depending on ns-bit we
165
- * add a bit to distinguish between secure and non-secure cpregs in the
166
- * hashtable.
167
- */
168
-#define CP_REG_NS_SHIFT 29
169
-#define CP_REG_NS_MASK (1 << CP_REG_NS_SHIFT)
170
-
171
-#define ENCODE_CP_REG(cp, is64, ns, crn, crm, opc1, opc2) \
172
- ((ns) << CP_REG_NS_SHIFT | ((cp) << 16) | ((is64) << 15) | \
173
- ((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2))
174
-
175
-#define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \
176
- (CP_REG_AA64_MASK | \
177
- ((cp) << CP_REG_ARM_COPROC_SHIFT) | \
178
- ((op0) << CP_REG_ARM64_SYSREG_OP0_SHIFT) | \
179
- ((op1) << CP_REG_ARM64_SYSREG_OP1_SHIFT) | \
180
- ((crn) << CP_REG_ARM64_SYSREG_CRN_SHIFT) | \
181
- ((crm) << CP_REG_ARM64_SYSREG_CRM_SHIFT) | \
182
- ((op2) << CP_REG_ARM64_SYSREG_OP2_SHIFT))
183
-
184
-/* Convert a full 64 bit KVM register ID to the truncated 32 bit
185
- * version used as a key for the coprocessor register hashtable
186
- */
187
-static inline uint32_t kvm_to_cpreg_id(uint64_t kvmid)
188
-{
189
- uint32_t cpregid = kvmid;
190
- if ((kvmid & CP_REG_ARCH_MASK) == CP_REG_ARM64) {
191
- cpregid |= CP_REG_AA64_MASK;
192
- } else {
193
- if ((kvmid & CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) {
194
- cpregid |= (1 << 15);
195
- }
196
-
197
- /* KVM is always non-secure so add the NS flag on AArch32 register
198
- * entries.
199
- */
200
- cpregid |= 1 << CP_REG_NS_SHIFT;
201
- }
202
- return cpregid;
203
-}
204
-
205
-/* Convert a truncated 32 bit hashtable key into the full
206
- * 64 bit KVM register ID.
207
- */
208
-static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
209
-{
210
- uint64_t kvmid;
211
-
212
- if (cpregid & CP_REG_AA64_MASK) {
213
- kvmid = cpregid & ~CP_REG_AA64_MASK;
214
- kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM64;
215
- } else {
216
- kvmid = cpregid & ~(1 << 15);
217
- if (cpregid & (1 << 15)) {
218
- kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM;
219
- } else {
220
- kvmid |= CP_REG_SIZE_U32 | CP_REG_ARM;
221
- }
222
- }
223
- return kvmid;
224
-}
225
-
226
/* Return the highest implemented Exception Level */
227
static inline int arm_highest_el(CPUARMState *env)
228
{
229
--
230
2.34.1
231
232
diff view generated by jsdifflib
Deleted patch
1
From: Fabiano Rosas <farosas@suse.de>
2
1
3
Now that the cortex-a15 is under CONFIG_TCG, use as default CPU for a
4
KVM-only build the 'max' cpu.
5
6
Note that we cannot use 'host' here because the qtests can run without
7
any other accelerator (than qtest) and 'host' depends on KVM being
8
enabled.
9
10
Signed-off-by: Fabiano Rosas <farosas@suse.de>
11
Acked-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Thomas Huth <thuth@redhat.com>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/arm/virt.c | 4 ++++
16
1 file changed, 4 insertions(+)
17
18
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/virt.c
21
+++ b/hw/arm/virt.c
22
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
23
mc->minimum_page_bits = 12;
24
mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids;
25
mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
26
+#ifdef CONFIG_TCG
27
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
28
+#else
29
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("max");
30
+#endif
31
mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
32
mc->kvm_type = virt_kvm_type;
33
assert(!mc->get_hotplug_handler);
34
--
35
2.34.1
diff view generated by jsdifflib
Deleted patch
1
From: Fabiano Rosas <farosas@suse.de>
2
1
3
Signed-off-by: Fabiano Rosas <farosas@suse.de>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Acked-by: Thomas Huth <thuth@redhat.com>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
tests/qtest/arm-cpu-features.c | 28 ++++++++++++++++++----------
9
1 file changed, 18 insertions(+), 10 deletions(-)
10
11
diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/tests/qtest/arm-cpu-features.c
14
+++ b/tests/qtest/arm-cpu-features.c
15
@@ -XXX,XX +XXX,XX @@
16
#define SVE_MAX_VQ 16
17
18
#define MACHINE "-machine virt,gic-version=max -accel tcg "
19
-#define MACHINE_KVM "-machine virt,gic-version=max -accel kvm -accel tcg "
20
+#define MACHINE_KVM "-machine virt,gic-version=max -accel kvm "
21
#define QUERY_HEAD "{ 'execute': 'query-cpu-model-expansion', " \
22
" 'arguments': { 'type': 'full', "
23
#define QUERY_TAIL "}}"
24
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
25
{
26
g_test_init(&argc, &argv, NULL);
27
28
- qtest_add_data_func("/arm/query-cpu-model-expansion",
29
- NULL, test_query_cpu_model_expansion);
30
+ if (qtest_has_accel("tcg")) {
31
+ qtest_add_data_func("/arm/query-cpu-model-expansion",
32
+ NULL, test_query_cpu_model_expansion);
33
+ }
34
+
35
+ if (!g_str_equal(qtest_get_arch(), "aarch64")) {
36
+ goto out;
37
+ }
38
39
/*
40
* For now we only run KVM specific tests with AArch64 QEMU in
41
* order avoid attempting to run an AArch32 QEMU with KVM on
42
* AArch64 hosts. That won't work and isn't easy to detect.
43
*/
44
- if (g_str_equal(qtest_get_arch(), "aarch64") && qtest_has_accel("kvm")) {
45
+ if (qtest_has_accel("kvm")) {
46
/*
47
* This tests target the 'host' CPU type, so register it only if
48
* KVM is available.
49
*/
50
qtest_add_data_func("/arm/kvm/query-cpu-model-expansion",
51
NULL, test_query_cpu_model_expansion_kvm);
52
- }
53
54
- if (g_str_equal(qtest_get_arch(), "aarch64")) {
55
- qtest_add_data_func("/arm/max/query-cpu-model-expansion/sve-max-vq-8",
56
- NULL, sve_tests_sve_max_vq_8);
57
- qtest_add_data_func("/arm/max/query-cpu-model-expansion/sve-off",
58
- NULL, sve_tests_sve_off);
59
qtest_add_data_func("/arm/kvm/query-cpu-model-expansion/sve-off",
60
NULL, sve_tests_sve_off_kvm);
61
}
62
63
+ if (qtest_has_accel("tcg")) {
64
+ qtest_add_data_func("/arm/max/query-cpu-model-expansion/sve-max-vq-8",
65
+ NULL, sve_tests_sve_max_vq_8);
66
+ qtest_add_data_func("/arm/max/query-cpu-model-expansion/sve-off",
67
+ NULL, sve_tests_sve_off);
68
+ }
69
+
70
+out:
71
return g_test_run();
72
}
73
--
74
2.34.1
diff view generated by jsdifflib