1
Almost nothing in here is arm-related, but the target-arm
1
The following changes since commit 8f6330a807f2642dc2a3cdf33347aa28a4c00a87:
2
queue was convenient for these last minute bits and pieces
3
for 5.0...
4
2
5
thanks
3
Merge tag 'pull-maintainer-updates-060324-1' of https://gitlab.com/stsquad/qemu into staging (2024-03-06 16:56:20 +0000)
6
-- PMM
7
8
The following changes since commit 14e5526b51910efd62cd31cd95b49baca975c83f:
9
10
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging (2020-04-13 15:42:51 +0100)
11
4
12
are available in the Git repository at:
5
are available in the Git repository at:
13
6
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200414
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240308
15
8
16
for you to fetch changes up to 84f82ddcbb4ac4ed04c8675e85155329f23184f0:
9
for you to fetch changes up to bbf6c6dbead82292a20951eb1204442a6b838de9:
17
10
18
Deprecate KVM support for AArch32 (2020-04-14 17:20:22 +0100)
11
target/arm: Move v7m-related code from cpu32.c into a separate file (2024-03-08 14:45:03 +0000)
19
12
20
----------------------------------------------------------------
13
----------------------------------------------------------------
21
patch queue:
14
target-arm queue:
22
* Fix some problems that trip up Coverity's scanner
15
* Implement FEAT_ECV
23
* run-coverity-scan: New script automating the scan-and-upload process
16
* STM32L4x5: Implement GPIO device
24
* docs: Improve our gdbstub documentation
17
* Fix 32-bit SMOPA
25
* configure: Honour --disable-werror for Sphinx
18
* Refactor v7m related code from cpu32.c into its own file
26
* docs: Fix errors produced when building with Sphinx 3.0
19
* hw/rtc/sun4v-rtc: Relicense to GPLv2-or-later
27
* docs: Require Sphinx 1.6 or better
28
* Add deprecation notice for KVM support on AArch32 hosts
29
20
30
----------------------------------------------------------------
21
----------------------------------------------------------------
31
Peter Maydell (12):
22
Inès Varhol (3):
32
osdep.h: Drop no-longer-needed Coverity workarounds
23
hw/gpio: Implement STM32L4x5 GPIO
33
thread.h: Fix Coverity version of qemu_cond_timedwait()
24
hw/arm: Connect STM32L4x5 GPIO to STM32L4x5 SoC
34
thread.h: Remove trailing semicolons from Coverity qemu_mutex_lock() etc
25
tests/qtest: Add STM32L4x5 GPIO QTest testcase
35
linux-user/flatload.c: Use "" for include of QEMU header target_flat.h
36
scripts/run-coverity-scan: Script to run Coverity Scan build
37
scripts/coverity-scan: Add Docker support
38
docs: Improve our gdbstub documentation
39
configure: Honour --disable-werror for Sphinx
40
scripts/kernel-doc: Add missing close-paren in c:function directives
41
kernel-doc: Use c:struct for Sphinx 3.0 and later
42
docs: Require Sphinx 1.6 or better
43
Deprecate KVM support for AArch32
44
26
45
configure | 9 +-
27
Peter Maydell (9):
46
Makefile | 2 +-
28
target/arm: Move some register related defines to internals.h
47
include/qemu/osdep.h | 14 -
29
target/arm: Timer _EL02 registers UNDEF for E2H == 0
48
include/qemu/thread.h | 12 +-
30
target/arm: use FIELD macro for CNTHCTL bit definitions
49
linux-user/flatload.c | 2 +-
31
target/arm: Don't allow RES0 CNTHCTL_EL2 bits to be written
50
MAINTAINERS | 5 +
32
target/arm: Implement new FEAT_ECV trap bits
51
docs/conf.py | 6 +-
33
target/arm: Define CNTPCTSS_EL0 and CNTVCTSS_EL0
52
docs/sphinx/kerneldoc.py | 1 +
34
target/arm: Implement FEAT_ECV CNTPOFF_EL2 handling
53
docs/system/deprecated.rst | 8 +
35
target/arm: Enable FEAT_ECV for 'max' CPU
54
docs/system/gdb.rst | 22 +-
36
hw/rtc/sun4v-rtc: Relicense to GPLv2-or-later
55
qemu-options.hx | 24 +-
56
scripts/coverity-scan/coverity-scan.docker | 131 ++++++++++
57
scripts/coverity-scan/run-coverity-scan | 401 +++++++++++++++++++++++++++++
58
scripts/kernel-doc | 18 +-
59
14 files changed, 615 insertions(+), 40 deletions(-)
60
create mode 100644 scripts/coverity-scan/coverity-scan.docker
61
create mode 100755 scripts/coverity-scan/run-coverity-scan
62
37
38
Richard Henderson (1):
39
target/arm: Fix 32-bit SMOPA
40
41
Thomas Huth (1):
42
target/arm: Move v7m-related code from cpu32.c into a separate file
43
44
MAINTAINERS | 1 +
45
docs/system/arm/b-l475e-iot01a.rst | 2 +-
46
docs/system/arm/emulation.rst | 1 +
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
82
diff view generated by jsdifflib
1
When kernel-doc generates a 'c:function' directive for a function
1
cpu.h has a lot of #defines relating to CPU register fields.
2
one of whose arguments is a function pointer, it fails to print
2
Most of these aren't actually used outside target/arm code,
3
the close-paren after the argument list of the function pointer
3
so there's no point in cluttering up the cpu.h file with them.
4
argument, for instance in the memory API documentation:
4
Move some easy ones to internals.h.
5
.. c:function:: void memory_region_init_resizeable_ram (MemoryRegion * mr, struct Object * owner, const char * name, uint64_t size, uint64_t max_size, void (*resized) (const char*, uint64_t length, void *host, Error ** errp)
6
7
which should have a ')' after the 'void *host' which is the
8
last argument to 'resized'.
9
10
Older versions of Sphinx don't try to parse the argumnet
11
to c:function, but Sphinx 3.0 does do this and will complain:
12
13
/home/petmay01/linaro/qemu-from-laptop/qemu/docs/../include/exec/memory.h:834: WARNING: Error in declarator or parameters
14
Invalid C declaration: Expecting "," or ")" in parameters, got "EOF". [error at 208]
15
void memory_region_init_resizeable_ram (MemoryRegion * mr, struct Object * owner, const char * name, uint64_t size, uint64_t max_size, void (*resized) (const char*, uint64_t length, void *host, Error ** errp)
16
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------^
17
18
Add the missing close-paren.
19
5
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Message-id: 20200411182934.28678-3-peter.maydell@linaro.org
9
Message-id: 20240301183219.2424889-2-peter.maydell@linaro.org
23
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
24
---
10
---
25
scripts/kernel-doc | 2 +-
11
target/arm/cpu.h | 128 -----------------------------------------
26
1 file changed, 1 insertion(+), 1 deletion(-)
12
target/arm/internals.h | 128 +++++++++++++++++++++++++++++++++++++++++
13
2 files changed, 128 insertions(+), 128 deletions(-)
27
14
28
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
29
index XXXXXXX..XXXXXXX 100755
16
index XXXXXXX..XXXXXXX 100644
30
--- a/scripts/kernel-doc
17
--- a/target/arm/cpu.h
31
+++ b/scripts/kernel-doc
18
+++ b/target/arm/cpu.h
32
@@ -XXX,XX +XXX,XX @@ sub output_function_rst(%) {
19
@@ -XXX,XX +XXX,XX @@ typedef struct ARMGenericTimer {
33
20
uint64_t ctl; /* Timer Control register */
34
    if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
21
} ARMGenericTimer;
35
     # pointer-to-function
22
36
-     print $1 . $parameter . ") (" . $2;
23
-#define VTCR_NSW (1u << 29)
37
+     print $1 . $parameter . ") (" . $2 . ")";
24
-#define VTCR_NSA (1u << 30)
38
    } else {
25
-#define VSTCR_SW VTCR_NSW
39
     print $type . " " . $parameter;
26
-#define VSTCR_SA VTCR_NSA
40
    }
27
-
28
/* Define a maximum sized vector register.
29
* For 32-bit, this is a 128-bit NEON/AdvSIMD register.
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
41
--
321
--
42
2.20.1
322
2.34.1
43
323
44
324
diff view generated by jsdifflib
1
The target_flat.h file is a QEMU header, so we should include it using
1
The timer _EL02 registers should UNDEF for invalid accesses from EL2
2
quotes, not angle brackets.
2
or EL3 when HCR_EL2.E2H == 0, not take a cp access trap. We were
3
3
delivering the exception to EL2 with the wrong syndrome.
4
Coverity otherwise is unable to find the header:
5
6
"../linux-user/flatload.c", line 40: error #1712: cannot open source file
7
"target_flat.h"
8
#include <target_flat.h>
9
^
10
11
because the relevant directory is only on the -iquote path, not the -I path.
12
4
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Message-id: 20240301183219.2424889-3-peter.maydell@linaro.org
16
Message-id: 20200319193323.2038-5-peter.maydell@linaro.org
17
---
8
---
18
linux-user/flatload.c | 2 +-
9
target/arm/helper.c | 2 +-
19
1 file changed, 1 insertion(+), 1 deletion(-)
10
1 file changed, 1 insertion(+), 1 deletion(-)
20
11
21
diff --git a/linux-user/flatload.c b/linux-user/flatload.c
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
22
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
23
--- a/linux-user/flatload.c
14
--- a/target/arm/helper.c
24
+++ b/linux-user/flatload.c
15
+++ b/target/arm/helper.c
25
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static CPAccessResult e2h_access(CPUARMState *env, const ARMCPRegInfo *ri,
26
17
return CP_ACCESS_OK;
27
#include "qemu.h"
18
}
28
#include "flat.h"
19
if (!(arm_hcr_el2_eff(env) & HCR_E2H)) {
29
-#include <target_flat.h>
20
- return CP_ACCESS_TRAP;
30
+#include "target_flat.h"
21
+ return CP_ACCESS_TRAP_UNCATEGORIZED;
31
22
}
32
//#define DEBUG
23
return CP_ACCESS_OK;
33
24
}
34
--
25
--
35
2.20.1
26
2.34.1
36
37
diff view generated by jsdifflib
1
The Linux kernel has dropped support for allowing 32-bit Arm systems
1
We prefer the FIELD macro over ad-hoc #defines for register bits;
2
to host KVM guests (kernel commit 541ad0150ca4aa663a2, which just
2
switch CNTHCTL to that style before we add any more bits.
3
landed upstream in the 5.7 merge window). Mark QEMU's support for
4
this configuration as deprecated, so that we can delete that support
5
code in 5.2.
6
3
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Andrew Jones <drjones@redhat.com>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20240301183219.2424889-4-peter.maydell@linaro.org
9
---
8
---
10
docs/system/deprecated.rst | 8 ++++++++
9
target/arm/internals.h | 27 +++++++++++++++++++++++++--
11
1 file changed, 8 insertions(+)
10
target/arm/helper.c | 9 ++++-----
11
2 files changed, 29 insertions(+), 7 deletions(-)
12
12
13
diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst
13
diff --git a/target/arm/internals.h b/target/arm/internals.h
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/docs/system/deprecated.rst
15
--- a/target/arm/internals.h
16
+++ b/docs/system/deprecated.rst
16
+++ b/target/arm/internals.h
17
@@ -XXX,XX +XXX,XX @@ The ``compat`` property used to set backwards compatibility modes for
17
@@ -XXX,XX +XXX,XX @@ FIELD(VTCR, SL2, 33, 1)
18
the processor has been deprecated. The ``max-cpu-compat`` property of
18
#define HSTR_TTEE (1 << 16)
19
the ``pseries`` machine type should be used instead.
19
#define HSTR_TJDBX (1 << 17)
20
20
21
+KVM guest support on 32-bit Arm hosts (since 5.0)
21
-#define CNTHCTL_CNTVMASK (1 << 18)
22
+'''''''''''''''''''''''''''''''''''''''''''''''''
22
-#define CNTHCTL_CNTPMASK (1 << 19)
23
+
23
+/*
24
+The Linux kernel has dropped support for allowing 32-bit Arm systems
24
+ * Depending on the value of HCR_EL2.E2H, bits 0 and 1
25
+to host KVM guests as of the 5.7 kernel. Accordingly, QEMU is deprecating
25
+ * have different bit definitions, and EL1PCTEN might be
26
+its support for this configuration and will remove it in a future version.
26
+ * bit 0 or bit 10. We use _E2H1 and _E2H0 suffixes to
27
+Running 32-bit guests on a 64-bit Arm host remains supported.
27
+ * disambiguate if necessary.
28
+
28
+ */
29
System emulator devices
29
+FIELD(CNTHCTL, EL0PCTEN_E2H1, 0, 1)
30
-----------------------
30
+FIELD(CNTHCTL, EL0VCTEN_E2H1, 1, 1)
31
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;
70
-
71
raw_write(env, ri, value);
72
73
- if ((oldval ^ value) & CNTHCTL_CNTVMASK) {
74
+ if ((oldval ^ value) & R_CNTHCTL_CNTVMASK_MASK) {
75
gt_update_irq(cpu, GTIMER_VIRT);
76
- } else if ((oldval ^ value) & CNTHCTL_CNTPMASK) {
77
+ } else if ((oldval ^ value) & R_CNTHCTL_CNTPMASK_MASK) {
78
gt_update_irq(cpu, GTIMER_PHYS);
79
}
80
}
32
--
81
--
33
2.20.1
82
2.34.1
34
83
35
84
diff view generated by jsdifflib
1
Versions of Sphinx older than 1.6 can't build all of our documentation,
1
Don't allow the guest to write CNTHCTL_EL2 bits which don't exist.
2
because they are too picky about the syntax of the argument to the
2
This is not strictly architecturally required, but it is how we've
3
option:: directive; see Sphinx bugs #646, #3366:
3
tended to implement registers more recently.
4
4
5
https://github.com/sphinx-doc/sphinx/issues/646
5
In particular, bits [19:18] are only present with FEAT_RME,
6
https://github.com/sphinx-doc/sphinx/issues/3366
6
and bits [17:12] will only be present with FEAT_ECV.
7
8
Trying to build with a 1.4.x Sphinx fails with
9
docs/system/images.rst:4: SEVERE: Duplicate ID: "cmdoption-qcow2-arg-encrypt"
10
and a 1.5.x Sphinx fails with
11
docs/system/invocation.rst:544: WARNING: Malformed option description '[enable=]PATTERN', should look like "opt", "-opt
12
args", "--opt args", "/opt args" or "+opt args"
13
14
Update our needs_sphinx setting to indicate that we require at least
15
1.6. This will allow configure to fall back to "don't build the
16
docs" rather than causing the build to fail entirely, which is
17
probably what most users building on a host old enough to have such
18
an old Sphinx would want; if they do want the docs then they'll have
19
a useful indication of what they need to do (upgrade Sphinx!) rather
20
than a confusing error message.
21
22
In theory our distro support policy would suggest that we should
23
support building on the Sphinx shipped in those distros, but:
24
* EPEL7 has Sphinx 1.2.3 (which we've never supported!)
25
* Debian Stretch has Sphinx 1.4.8
26
27
Trying to get our docs to work with Sphinx 1.4 is not tractable
28
for the 5.0 release and I'm not sure it's worthwhile effort anyway;
29
at least with this change the build as a whole now succeeds.
30
31
Thanks to John Snow for doing the investigation and testing to
32
confirm what Sphinx versions fail in what ways and what distros
33
shipped what.
34
7
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
36
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20240301183219.2424889-5-peter.maydell@linaro.org
37
---
11
---
38
docs/conf.py | 6 ++++--
12
target/arm/helper.c | 18 ++++++++++++++++++
39
1 file changed, 4 insertions(+), 2 deletions(-)
13
1 file changed, 18 insertions(+)
40
14
41
diff --git a/docs/conf.py b/docs/conf.py
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
42
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
43
--- a/docs/conf.py
17
--- a/target/arm/helper.c
44
+++ b/docs/conf.py
18
+++ b/target/arm/helper.c
45
@@ -XXX,XX +XXX,XX @@ sys.path.insert(0, os.path.join(qemu_docdir, "sphinx"))
19
@@ -XXX,XX +XXX,XX @@ static void gt_cnthctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
46
20
{
47
# If your documentation needs a minimal Sphinx version, state it here.
21
ARMCPU *cpu = env_archcpu(env);
48
#
22
uint32_t oldval = env->cp15.cnthctl_el2;
49
-# 1.3 is where the 'alabaster' theme was shipped with Sphinx.
23
+ uint32_t valid_mask =
50
-needs_sphinx = '1.3'
24
+ R_CNTHCTL_EL0PCTEN_E2H1_MASK |
51
+# Sphinx 1.5 and earlier can't build our docs because they are too
25
+ R_CNTHCTL_EL0VCTEN_E2H1_MASK |
52
+# picky about the syntax of the argument to the option:: directive
26
+ R_CNTHCTL_EVNTEN_MASK |
53
+# (see Sphinx bugs #646, #3366).
27
+ R_CNTHCTL_EVNTDIR_MASK |
54
+needs_sphinx = '1.6'
28
+ R_CNTHCTL_EVNTI_MASK |
55
29
+ R_CNTHCTL_EL0VTEN_MASK |
56
# Add any Sphinx extension module names here, as strings. They can be
30
+ R_CNTHCTL_EL0PTEN_MASK |
57
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
31
+ R_CNTHCTL_EL1PCTEN_E2H1_MASK |
32
+ R_CNTHCTL_EL1PTEN_MASK;
33
+
34
+ if (cpu_isar_feature(aa64_rme, cpu)) {
35
+ valid_mask |= R_CNTHCTL_CNTVMASK_MASK | R_CNTHCTL_CNTPMASK_MASK;
36
+ }
37
+
38
+ /* Clear RES0 bits */
39
+ value &= valid_mask;
40
+
41
raw_write(env, ri, value);
42
43
if ((oldval ^ value) & R_CNTHCTL_CNTVMASK_MASK) {
58
--
44
--
59
2.20.1
45
2.34.1
60
61
diff view generated by jsdifflib
1
All the Coverity-specific definitions of qemu_mutex_lock() and friends
1
The functionality defined by ID_AA64MMFR0_EL1.ECV == 1 is:
2
have a trailing semicolon. This works fine almost everywhere because
2
* four new trap bits for various counter and timer registers
3
of QEMU's mandatory-braces coding style and because most callsites are
3
* the CNTHCTL_EL2.EVNTIS and CNTKCTL_EL1.EVNTIS bits which control
4
simple, but target/s390x/sigp.c has a use of qemu_mutex_trylock() as
4
scaling of the event stream. This is a no-op for us, because we don't
5
an if() statement, which makes the ';' a syntax error:
5
implement the event stream (our WFE is a NOP): all we need to do is
6
"../target/s390x/sigp.c", line 461: warning #18: expected a ")"
6
allow CNTHCTL_EL2.ENVTIS to be read and written.
7
if (qemu_mutex_trylock(&qemu_sigp_mutex)) {
7
* extensions to PMSCR_EL1.PCT, PMSCR_EL2.PCT, TRFCR_EL1.TS and
8
^
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.
9
15
10
Remove the bogus semicolons from the macro definitions.
16
In this commit we implement the trap handling and permit the new
17
CNTHCTL_EL2 bits to be written.
11
18
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
21
Message-id: 20240301183219.2424889-6-peter.maydell@linaro.org
15
Message-id: 20200319193323.2038-4-peter.maydell@linaro.org
16
---
22
---
17
include/qemu/thread.h | 12 ++++++------
23
target/arm/cpu-features.h | 5 ++++
18
1 file changed, 6 insertions(+), 6 deletions(-)
24
target/arm/helper.c | 51 +++++++++++++++++++++++++++++++++++----
25
2 files changed, 51 insertions(+), 5 deletions(-)
19
26
20
diff --git a/include/qemu/thread.h b/include/qemu/thread.h
27
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
21
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
22
--- a/include/qemu/thread.h
29
--- a/target/arm/cpu-features.h
23
+++ b/include/qemu/thread.h
30
+++ b/target/arm/cpu-features.h
24
@@ -XXX,XX +XXX,XX @@ extern QemuCondTimedWaitFunc qemu_cond_timedwait_func;
31
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_fgt(const ARMISARegisters *id)
25
* hide them.
32
return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, FGT) != 0;
26
*/
33
}
27
#define qemu_mutex_lock(m) \
34
28
- qemu_mutex_lock_impl(m, __FILE__, __LINE__);
35
+static inline bool isar_feature_aa64_ecv_traps(const ARMISARegisters *id)
29
+ qemu_mutex_lock_impl(m, __FILE__, __LINE__)
36
+{
30
#define qemu_mutex_trylock(m) \
37
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, ECV) > 0;
31
- qemu_mutex_trylock_impl(m, __FILE__, __LINE__);
38
+}
32
+ qemu_mutex_trylock_impl(m, __FILE__, __LINE__)
39
+
33
#define qemu_rec_mutex_lock(m) \
40
static inline bool isar_feature_aa64_vh(const ARMISARegisters *id)
34
- qemu_rec_mutex_lock_impl(m, __FILE__, __LINE__);
41
{
35
+ qemu_rec_mutex_lock_impl(m, __FILE__, __LINE__)
42
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0;
36
#define qemu_rec_mutex_trylock(m) \
43
diff --git a/target/arm/helper.c b/target/arm/helper.c
37
- qemu_rec_mutex_trylock_impl(m, __FILE__, __LINE__);
44
index XXXXXXX..XXXXXXX 100644
38
+ qemu_rec_mutex_trylock_impl(m, __FILE__, __LINE__)
45
--- a/target/arm/helper.c
39
#define qemu_cond_wait(c, m) \
46
+++ b/target/arm/helper.c
40
- qemu_cond_wait_impl(c, m, __FILE__, __LINE__);
47
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx,
41
+ qemu_cond_wait_impl(c, m, __FILE__, __LINE__)
48
: !extract32(env->cp15.cnthctl_el2, 0, 1))) {
42
#define qemu_cond_timedwait(c, m, ms) \
49
return CP_ACCESS_TRAP_EL2;
43
- qemu_cond_timedwait_impl(c, m, ms, __FILE__, __LINE__);
50
}
44
+ qemu_cond_timedwait_impl(c, m, ms, __FILE__, __LINE__)
51
+ if (has_el2 && timeridx == GTIMER_VIRT) {
45
#else
52
+ if (FIELD_EX64(env->cp15.cnthctl_el2, CNTHCTL, EL1TVCT)) {
46
#define qemu_mutex_lock(m) ({ \
53
+ return CP_ACCESS_TRAP_EL2;
47
QemuMutexLockFunc _f = atomic_read(&qemu_mutex_lock_func); \
54
+ }
55
+ }
56
break;
57
}
58
return CP_ACCESS_OK;
59
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gt_timer_access(CPUARMState *env, int timeridx,
60
}
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;
82
+ }
83
84
/* Clear RES0 bits */
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
};
48
--
159
--
49
2.20.1
160
2.34.1
50
51
diff view generated by jsdifflib
1
For Coverity's benefit, we provide simpler versions of functions like
1
For FEAT_ECV, new registers CNTPCTSS_EL0 and CNTVCTSS_EL0 are
2
qemu_mutex_lock(), qemu_cond_wait() and qemu_cond_timedwait(). When
2
defined, which are "self-synchronized" views of the physical and
3
we added qemu_cond_timedwait() in commit 3dcc9c6ec4ea, a cut and
3
virtual counts as seen in the CNTPCT_EL0 and CNTVCT_EL0 registers
4
paste error meant that the Coverity version of qemu_cond_timedwait()
4
(meaning that no barriers are needed around accesses to them to
5
was using the wrong _impl function, which makes the Coverity parser
5
ensure that reads of them do not occur speculatively and out-of-order
6
complain:
6
with other instructions).
7
7
8
"/qemu/include/qemu/thread.h", line 159: warning #140: too many arguments in
8
For QEMU, all our system registers are self-synchronized, so we can
9
function call
9
simply copy the existing implementation of CNTPCT_EL0 and CNTVCT_EL0
10
return qemu_cond_timedwait(cond, mutex, ms);
10
to the new register encodings.
11
^
12
11
13
"/qemu/include/qemu/thread.h", line 159: warning #120: return value type does
12
This means we now implement all the functionality required for
14
not match the function type
13
ID_AA64MMFR0_EL1.ECV == 0b0001.
15
return qemu_cond_timedwait(cond, mutex, ms);
16
^
17
18
"/qemu/include/qemu/thread.h", line 156: warning #1563: function
19
"qemu_cond_timedwait" not emitted, consider modeling it or review
20
parse diagnostics to improve fidelity
21
static inline bool (qemu_cond_timedwait)(QemuCond *cond, QemuMutex *mutex,
22
^
23
24
These aren't fatal, but reduce the scope of the analysis. Fix the error.
25
14
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
28
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
17
Message-id: 20240301183219.2424889-7-peter.maydell@linaro.org
29
Message-id: 20200319193323.2038-3-peter.maydell@linaro.org
30
---
18
---
31
include/qemu/thread.h | 2 +-
19
target/arm/helper.c | 43 +++++++++++++++++++++++++++++++++++++++++++
32
1 file changed, 1 insertion(+), 1 deletion(-)
20
1 file changed, 43 insertions(+)
33
21
34
diff --git a/include/qemu/thread.h b/include/qemu/thread.h
22
diff --git a/target/arm/helper.c b/target/arm/helper.c
35
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
36
--- a/include/qemu/thread.h
24
--- a/target/arm/helper.c
37
+++ b/include/qemu/thread.h
25
+++ b/target/arm/helper.c
38
@@ -XXX,XX +XXX,XX @@ extern QemuCondTimedWaitFunc qemu_cond_timedwait_func;
26
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
39
#define qemu_cond_wait(c, m) \
27
},
40
qemu_cond_wait_impl(c, m, __FILE__, __LINE__);
28
};
41
#define qemu_cond_timedwait(c, m, ms) \
29
42
- qemu_cond_wait_impl(c, m, ms, __FILE__, __LINE__);
30
+/*
43
+ qemu_cond_timedwait_impl(c, m, ms, __FILE__, __LINE__);
31
+ * FEAT_ECV adds extra views of CNTVCT_EL0 and CNTPCT_EL0 which
32
+ * are "self-synchronizing". For QEMU all sysregs are self-synchronizing,
33
+ * so our implementations here are identical to the normal registers.
34
+ */
35
+static const ARMCPRegInfo gen_timer_ecv_cp_reginfo[] = {
36
+ { .name = "CNTVCTSS", .cp = 15, .crm = 14, .opc1 = 9,
37
+ .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_RAW | ARM_CP_IO,
38
+ .accessfn = gt_vct_access,
39
+ .readfn = gt_virt_cnt_read, .resetfn = arm_cp_reset_ignore,
40
+ },
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
+
44
#else
58
#else
45
#define qemu_mutex_lock(m) ({ \
59
46
QemuMutexLockFunc _f = atomic_read(&qemu_mutex_lock_func); \
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);
83
}
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,
47
--
90
--
48
2.20.1
91
2.34.1
49
50
diff view generated by jsdifflib
1
If we are not making warnings fatal for compilation, make them
1
When ID_AA64MMFR0_EL1.ECV is 0b0010, a new register CNTPOFF_EL2 is
2
non-fatal when building the Sphinx documentation also. (For instance
2
implemented. This is similar to the existing CNTVOFF_EL2, except
3
Sphinx 3.0 warns about some constructs that older versions were happy
3
that it controls a hypervisor-adjustable offset made to the physical
4
with, which is a build failure if we use the warnings-as-errors
4
counter and timer.
5
flag.)
6
5
7
This provides a workaround at least for LP:1872113.
6
Implement the handling for this register, which includes control/trap
7
bits in SCR_EL3 and CNTHCTL_EL2.
8
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20200411182934.28678-2-peter.maydell@linaro.org
11
Message-id: 20240301183219.2424889-8-peter.maydell@linaro.org
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
---
12
---
14
configure | 9 ++++++++-
13
target/arm/cpu-features.h | 5 +++
15
Makefile | 2 +-
14
target/arm/cpu.h | 1 +
16
2 files changed, 9 insertions(+), 2 deletions(-)
15
target/arm/helper.c | 68 +++++++++++++++++++++++++++++++++++++--
16
target/arm/trace-events | 1 +
17
4 files changed, 73 insertions(+), 2 deletions(-)
17
18
18
diff --git a/configure b/configure
19
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
19
index XXXXXXX..XXXXXXX 100755
20
index XXXXXXX..XXXXXXX 100644
20
--- a/configure
21
--- a/target/arm/cpu-features.h
21
+++ b/configure
22
+++ b/target/arm/cpu-features.h
22
@@ -XXX,XX +XXX,XX @@ if check_include sys/kcov.h ; then
23
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ecv_traps(const ARMISARegisters *id)
23
kcov=yes
24
return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, ECV) > 0;
24
fi
25
}
25
26
26
+# If we're making warnings fatal, apply this to Sphinx runs as well
27
+static inline bool isar_feature_aa64_ecv(const ARMISARegisters *id)
27
+sphinx_werror=""
28
+{
28
+if test "$werror" = "yes"; then
29
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, ECV) > 1;
29
+ sphinx_werror="-W"
30
+}
30
+fi
31
+
31
+
32
# Check we have a new enough version of sphinx-build
32
static inline bool isar_feature_aa64_vh(const ARMISARegisters *id)
33
has_sphinx_build() {
33
{
34
# This is a bit awkward but works: create a trivial document and
34
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0;
35
@@ -XXX,XX +XXX,XX @@ has_sphinx_build() {
35
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
36
# sphinx-build doesn't exist at all or if it is too old.
36
index XXXXXXX..XXXXXXX 100644
37
mkdir -p "$TMPDIR1/sphinx"
37
--- a/target/arm/cpu.h
38
touch "$TMPDIR1/sphinx/index.rst"
38
+++ b/target/arm/cpu.h
39
- "$sphinx_build" -c "$source_path/docs" -b html "$TMPDIR1/sphinx" "$TMPDIR1/sphinx/out" >/dev/null 2>&1
39
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
40
+ "$sphinx_build" $sphinx_werror -c "$source_path/docs" -b html "$TMPDIR1/sphinx" "$TMPDIR1/sphinx/out" >/dev/null 2>&1
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);
41
}
63
}
42
64
43
# Check if tools are available to build documentation.
65
+static uint64_t gt_phys_raw_cnt_offset(CPUARMState *env)
44
@@ -XXX,XX +XXX,XX @@ echo "INSTALL_PROG=$install -c -m 0755" >> $config_host_mak
66
+{
45
echo "INSTALL_LIB=$install -c -m 0644" >> $config_host_mak
67
+ if ((env->cp15.scr_el3 & SCR_ECVEN) &&
46
echo "PYTHON=$python" >> $config_host_mak
68
+ FIELD_EX64(env->cp15.cnthctl_el2, CNTHCTL, ECV) &&
47
echo "SPHINX_BUILD=$sphinx_build" >> $config_host_mak
69
+ arm_is_el2_enabled(env) &&
48
+echo "SPHINX_WERROR=$sphinx_werror" >> $config_host_mak
70
+ (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
49
echo "GENISOIMAGE=$genisoimage" >> $config_host_mak
71
+ return env->cp15.cntpoff_el2;
50
echo "CC=$cc" >> $config_host_mak
72
+ }
51
if $iasl -h > /dev/null 2>&1; then
73
+ return 0;
52
diff --git a/Makefile b/Makefile
74
+}
75
+
76
+static uint64_t gt_phys_cnt_offset(CPUARMState *env)
77
+{
78
+ if (arm_current_el(env) >= 2) {
79
+ return 0;
80
+ }
81
+ return gt_phys_raw_cnt_offset(env);
82
+}
83
+
84
static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
85
{
86
ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx];
87
@@ -XXX,XX +XXX,XX @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
88
* reset timer to when ISTATUS next has to change
89
*/
90
uint64_t offset = timeridx == GTIMER_VIRT ?
91
- cpu->env.cp15.cntvoff_el2 : 0;
92
+ cpu->env.cp15.cntvoff_el2 : gt_phys_raw_cnt_offset(&cpu->env);
93
uint64_t count = gt_get_countervalue(&cpu->env);
94
/* Note that this must be unsigned 64 bit arithmetic: */
95
int istatus = count - offset >= gt->cval;
96
@@ -XXX,XX +XXX,XX @@ static void gt_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri,
97
98
static uint64_t gt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
99
{
100
- return gt_get_countervalue(env);
101
+ return gt_get_countervalue(env) - gt_phys_cnt_offset(env);
102
}
103
104
static uint64_t gt_virt_cnt_offset(CPUARMState *env)
105
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
106
case GTIMER_HYPVIRT:
107
offset = gt_virt_cnt_offset(env);
108
break;
109
+ case GTIMER_PHYS:
110
+ offset = gt_phys_cnt_offset(env);
111
+ break;
112
}
113
114
return (uint32_t)(env->cp15.c14_timer[timeridx].cval -
115
@@ -XXX,XX +XXX,XX @@ static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
116
case GTIMER_HYPVIRT:
117
offset = gt_virt_cnt_offset(env);
118
break;
119
+ case GTIMER_PHYS:
120
+ offset = gt_phys_cnt_offset(env);
121
+ break;
122
}
123
124
trace_arm_gt_tval_write(timeridx, value);
125
@@ -XXX,XX +XXX,XX @@ static void gt_cnthctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
126
R_CNTHCTL_EL1NVVCT_MASK |
127
R_CNTHCTL_EVNTIS_MASK;
128
}
129
+ if (cpu_isar_feature(aa64_ecv, cpu)) {
130
+ valid_mask |= R_CNTHCTL_ECV_MASK;
131
+ }
132
133
/* Clear RES0 bits */
134
value &= valid_mask;
135
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gen_timer_ecv_cp_reginfo[] = {
136
},
137
};
138
139
+static CPAccessResult gt_cntpoff_access(CPUARMState *env,
140
+ const ARMCPRegInfo *ri,
141
+ bool isread)
142
+{
143
+ if (arm_current_el(env) == 2 && !(env->cp15.scr_el3 & SCR_ECVEN)) {
144
+ return CP_ACCESS_TRAP_EL3;
145
+ }
146
+ return CP_ACCESS_OK;
147
+}
148
+
149
+static void gt_cntpoff_write(CPUARMState *env, const ARMCPRegInfo *ri,
150
+ uint64_t value)
151
+{
152
+ ARMCPU *cpu = env_archcpu(env);
153
+
154
+ trace_arm_gt_cntpoff_write(value);
155
+ raw_write(env, ri, value);
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);
177
+ }
178
+#endif
179
if (arm_feature(env, ARM_FEATURE_VAPA)) {
180
ARMCPRegInfo vapa_cp_reginfo[] = {
181
{ .name = "PAR", .cp = 15, .crn = 7, .crm = 4, .opc1 = 0, .opc2 = 0,
182
diff --git a/target/arm/trace-events b/target/arm/trace-events
53
index XXXXXXX..XXXXXXX 100644
183
index XXXXXXX..XXXXXXX 100644
54
--- a/Makefile
184
--- a/target/arm/trace-events
55
+++ b/Makefile
185
+++ b/target/arm/trace-events
56
@@ -XXX,XX +XXX,XX @@ sphinxdocs: $(MANUAL_BUILDDIR)/devel/index.html \
186
@@ -XXX,XX +XXX,XX @@ arm_gt_tval_write(int timer, uint64_t value) "gt_tval_write: timer %d value 0x%"
57
# Note the use of different doctree for each (manual, builder) tuple;
187
arm_gt_ctl_write(int timer, uint64_t value) "gt_ctl_write: timer %d value 0x%" PRIx64
58
# this works around Sphinx not handling parallel invocation on
188
arm_gt_imask_toggle(int timer) "gt_ctl_write: timer %d IMASK toggle"
59
# a single doctree: https://github.com/sphinx-doc/sphinx/issues/2946
189
arm_gt_cntvoff_write(uint64_t value) "gt_cntvoff_write: value 0x%" PRIx64
60
-build-manual = $(call quiet-command,CONFDIR="$(qemu_confdir)" $(SPHINX_BUILD) $(if $(V),,-q) -W -b $2 -D version=$(VERSION) -D release="$(FULL_VERSION)" -d .doctrees/$1-$2 $(SRC_PATH)/docs/$1 $(MANUAL_BUILDDIR)/$1 ,"SPHINX","$(MANUAL_BUILDDIR)/$1")
190
+arm_gt_cntpoff_write(uint64_t value) "gt_cntpoff_write: value 0x%" PRIx64
61
+build-manual = $(call quiet-command,CONFDIR="$(qemu_confdir)" $(SPHINX_BUILD) $(if $(V),,-q) $(SPHINX_WERROR) -b $2 -D version=$(VERSION) -D release="$(FULL_VERSION)" -d .doctrees/$1-$2 $(SRC_PATH)/docs/$1 $(MANUAL_BUILDDIR)/$1 ,"SPHINX","$(MANUAL_BUILDDIR)/$1")
191
arm_gt_update_irq(int timer, int irqstate) "gt_update_irq: timer %d irqstate %d"
62
# We assume all RST files in the manual's directory are used in it
192
63
manual-deps = $(wildcard $(SRC_PATH)/docs/$1/*.rst $(SRC_PATH)/docs/$1/*/*.rst) \
193
# kvm.c
64
$(SRC_PATH)/docs/defs.rst.inc \
65
--
194
--
66
2.20.1
195
2.34.1
67
68
diff view generated by jsdifflib
1
The kernel-doc Sphinx plugin and associated script currently emit
1
Enable all FEAT_ECV features on the 'max' CPU.
2
'c:type' directives for "struct foo" documentation.
3
2
4
Sphinx 3.0 warns about this:
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
/home/petmay01/linaro/qemu-from-laptop/qemu/docs/../include/exec/memory.h:3: WARNING: Type must be either just a name or a typedef-like declaration.
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
If just a name:
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Error in declarator or parameters
6
Message-id: 20240301183219.2424889-9-peter.maydell@linaro.org
8
Invalid C declaration: Expected identifier in nested name, got keyword: struct [error at 6]
7
---
9
struct MemoryListener
8
docs/system/arm/emulation.rst | 1 +
10
------^
9
target/arm/tcg/cpu64.c | 1 +
11
If typedef-like declaration:
10
2 files changed, 2 insertions(+)
12
Error in declarator or parameters
13
Invalid C declaration: Expected identifier in nested name. [error at 21]
14
struct MemoryListener
15
---------------------^
16
11
17
because it wants us to use the new-in-3.0 'c:struct' instead.
12
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
18
19
Plumb the Sphinx version through to the kernel-doc script
20
and use it to select 'c:struct' for newer versions than 3.0.
21
22
Fixes: LP:1872113
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
25
---
26
docs/sphinx/kerneldoc.py | 1 +
27
scripts/kernel-doc | 16 +++++++++++++++-
28
2 files changed, 16 insertions(+), 1 deletion(-)
29
30
diff --git a/docs/sphinx/kerneldoc.py b/docs/sphinx/kerneldoc.py
31
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
32
--- a/docs/sphinx/kerneldoc.py
14
--- a/docs/system/arm/emulation.rst
33
+++ b/docs/sphinx/kerneldoc.py
15
+++ b/docs/system/arm/emulation.rst
34
@@ -XXX,XX +XXX,XX @@ class KernelDocDirective(Directive):
16
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
35
env.note_dependency(os.path.abspath(f))
17
- FEAT_DotProd (Advanced SIMD dot product instructions)
36
cmd += ['-export-file', f]
18
- FEAT_DoubleFault (Double Fault Extension)
37
19
- FEAT_E0PD (Preventing EL0 access to halves of address maps)
38
+ cmd += ['-sphinx-version', sphinx.__version__]
20
+- FEAT_ECV (Enhanced Counter Virtualization)
39
cmd += [filename]
21
- FEAT_EPAC (Enhanced pointer authentication)
40
22
- FEAT_ETS (Enhanced Translation Synchronization)
41
try:
23
- FEAT_EVT (Enhanced Virtualization Traps)
42
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
24
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
43
index XXXXXXX..XXXXXXX 100755
25
index XXXXXXX..XXXXXXX 100644
44
--- a/scripts/kernel-doc
26
--- a/target/arm/tcg/cpu64.c
45
+++ b/scripts/kernel-doc
27
+++ b/target/arm/tcg/cpu64.c
46
@@ -XXX,XX +XXX,XX @@ Output selection (mutually exclusive):
28
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
47
            DOC: sections. May be specified multiple times.
29
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN64_2, 2); /* 64k stage2 supported */
48
30
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 2); /* 4k stage2 supported */
49
Output selection modifiers:
31
t = FIELD_DP64(t, ID_AA64MMFR0, FGT, 1); /* FEAT_FGT */
50
+ -sphinx-version VER Generate rST syntax for the specified Sphinx version.
32
+ t = FIELD_DP64(t, ID_AA64MMFR0, ECV, 2); /* FEAT_ECV */
51
+ Only works with reStructuredTextFormat.
33
cpu->isar.id_aa64mmfr0 = t;
52
-no-doc-sections    Do not output DOC: sections.
34
53
-enable-lineno Enable output of #define LINENO lines. Only works with
35
t = cpu->isar.id_aa64mmfr1;
54
reStructuredText format.
55
@@ -XXX,XX +XXX,XX @@ use constant {
56
};
57
my $output_selection = OUTPUT_ALL;
58
my $show_not_found = 0;    # No longer used
59
+my $sphinx_version = "0.0"; # if not specified, assume old
60
61
my @export_file_list;
62
63
@@ -XXX,XX +XXX,XX @@ while ($ARGV[0] =~ m/^--?(.*)/) {
64
     $enable_lineno = 1;
65
} elsif ($cmd eq 'show-not-found') {
66
    $show_not_found = 1; # A no-op but don't fail
67
+ } elsif ($cmd eq 'sphinx-version') {
68
+ $sphinx_version = shift @ARGV;
69
} else {
70
    # Unknown argument
71
usage();
72
@@ -XXX,XX +XXX,XX @@ sub output_struct_rst(%) {
73
my $oldprefix = $lineprefix;
74
my $name = $args{'type'} . " " . $args{'struct'};
75
76
- print "\n\n.. c:type:: " . $name . "\n\n";
77
+ # Sphinx 3.0 and up will emit warnings for "c:type:: struct Foo".
78
+ # It wants to see "c:struct:: Foo" (and will add the word 'struct' in
79
+ # the rendered output).
80
+ if ((split(/\./, $sphinx_version))[0] >= 3) {
81
+ my $sname = $name;
82
+ $sname =~ s/^struct //;
83
+ print "\n\n.. c:struct:: " . $sname . "\n\n";
84
+ } else {
85
+ print "\n\n.. c:type:: " . $name . "\n\n";
86
+ }
87
print_lineno($declaration_start_line);
88
$lineprefix = " ";
89
output_highlight_rst($args{'purpose'});
90
--
36
--
91
2.20.1
37
2.34.1
92
38
93
39
diff view generated by jsdifflib
1
Add a new script to automate the process of running the Coverity
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
Scan build tools and uploading the resulting tarball to the
3
website.
4
2
5
This is intended eventually to be driven from Travis,
3
Features supported :
6
but it can be run locally, if you are a maintainer of the
4
- the 8 STM32L4x5 GPIOs are initialized with their reset values
7
QEMU project on the Coverity Scan website and have the secret
5
(except IDR, see below)
8
upload token.
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
9
12
10
The script must be run on a Fedora 30 system. Support for using a
13
Difference with the real GPIOs :
11
Docker container is added in a following commit.
14
- Alternate Function and Analog mode aren't implemented :
15
pins in AF/Analog behave like pins in input mode
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
12
25
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
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
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Message-id: 20200319193323.2038-6-peter.maydell@linaro.org
16
---
32
---
17
MAINTAINERS | 5 +
33
MAINTAINERS | 1 +
18
scripts/coverity-scan/run-coverity-scan | 311 ++++++++++++++++++++++++
34
docs/system/arm/b-l475e-iot01a.rst | 2 +-
19
2 files changed, 316 insertions(+)
35
include/hw/gpio/stm32l4x5_gpio.h | 70 +++++
20
create mode 100755 scripts/coverity-scan/run-coverity-scan
36
hw/gpio/stm32l4x5_gpio.c | 477 +++++++++++++++++++++++++++++
37
hw/gpio/Kconfig | 3 +
38
hw/gpio/meson.build | 1 +
39
hw/gpio/trace-events | 6 +
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
21
43
22
diff --git a/MAINTAINERS b/MAINTAINERS
44
diff --git a/MAINTAINERS b/MAINTAINERS
23
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
24
--- a/MAINTAINERS
46
--- a/MAINTAINERS
25
+++ b/MAINTAINERS
47
+++ b/MAINTAINERS
26
@@ -XXX,XX +XXX,XX @@ M: Markus Armbruster <armbru@redhat.com>
48
@@ -XXX,XX +XXX,XX @@ F: hw/arm/stm32l4x5_soc.c
27
S: Supported
49
F: hw/misc/stm32l4x5_exti.c
28
F: scripts/coverity-model.c
50
F: hw/misc/stm32l4x5_syscfg.c
29
51
F: hw/misc/stm32l4x5_rcc.c
30
+Coverity Scan integration
52
+F: hw/gpio/stm32l4x5_gpio.c
31
+M: Peter Maydell <peter.maydell@linaro.org>
53
F: include/hw/*/stm32l4x5_*.h
32
+S: Maintained
54
33
+F: scripts/coverity-scan/
55
B-L475E-IOT01A IoT Node
34
+
56
diff --git a/docs/system/arm/b-l475e-iot01a.rst b/docs/system/arm/b-l475e-iot01a.rst
35
Device Tree
57
index XXXXXXX..XXXXXXX 100644
36
M: Alistair Francis <alistair.francis@wdc.com>
58
--- a/docs/system/arm/b-l475e-iot01a.rst
37
R: David Gibson <david@gibson.dropbear.id.au>
59
+++ b/docs/system/arm/b-l475e-iot01a.rst
38
diff --git a/scripts/coverity-scan/run-coverity-scan b/scripts/coverity-scan/run-coverity-scan
60
@@ -XXX,XX +XXX,XX @@ Currently B-L475E-IOT01A machine's only supports the following devices:
39
new file mode 100755
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
77
new file mode 100644
40
index XXXXXXX..XXXXXXX
78
index XXXXXXX..XXXXXXX
41
--- /dev/null
79
--- /dev/null
42
+++ b/scripts/coverity-scan/run-coverity-scan
80
+++ b/include/hw/gpio/stm32l4x5_gpio.h
43
@@ -XXX,XX +XXX,XX @@
81
@@ -XXX,XX +XXX,XX @@
44
+#!/bin/sh -e
82
+/*
45
+
83
+ * STM32L4x5 GPIO (General Purpose Input/Ouput)
46
+# Upload a created tarball to Coverity Scan, as per
84
+ *
47
+# https://scan.coverity.com/projects/qemu/builds/new
85
+ * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
48
+
86
+ * Copyright (c) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
49
+# This work is licensed under the terms of the GNU GPL version 2,
87
+ *
50
+# or (at your option) any later version.
88
+ * SPDX-License-Identifier: GPL-2.0-or-later
51
+# See the COPYING file in the top-level directory.
89
+ *
52
+#
90
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
53
+# Copyright (c) 2017-2020 Linaro Limited
91
+ * See the COPYING file in the top-level directory.
54
+# Written by Peter Maydell
92
+ */
55
+
93
+
56
+# Note that this script will automatically download and
94
+/*
57
+# run the (closed-source) coverity build tools, so don't
95
+ * The reference used is the STMicroElectronics RM0351 Reference manual
58
+# use it if you don't trust them!
96
+ * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
59
+
97
+ * https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html
60
+# This script assumes that you're running it from a QEMU source
98
+ */
61
+# tree, and that tree is a fresh clean one, because we do an in-tree
99
+
62
+# build. (This is necessary so that the filenames that the Coverity
100
+#ifndef HW_STM32L4X5_GPIO_H
63
+# Scan server sees are relative paths that match up with the component
101
+#define HW_STM32L4X5_GPIO_H
64
+# regular expressions it uses; an out-of-tree build won't work for this.)
102
+
65
+# The host machine should have as many of QEMU's dependencies
103
+#include "hw/sysbus.h"
66
+# installed as possible, for maximum coverity coverage.
104
+#include "qom/object.h"
67
+
105
+
68
+# To do an upload you need to be a maintainer in the Coverity online
106
+#define TYPE_STM32L4X5_GPIO "stm32l4x5-gpio"
69
+# service, and you will need to know the "Coverity token", which is a
107
+OBJECT_DECLARE_SIMPLE_TYPE(Stm32l4x5GpioState, STM32L4X5_GPIO)
70
+# secret 8 digit hex string. You can find that from the web UI in the
108
+
71
+# project settings, if you have maintainer access there.
109
+#define GPIO_NUM_PINS 16
72
+
110
+
73
+# Command line options:
111
+struct Stm32l4x5GpioState {
74
+# --dry-run : run the tools, but don't actually do the upload
112
+ SysBusDevice parent_obj;
75
+# --update-tools-only : update the cached copy of the tools, but don't run them
113
+
76
+# --tokenfile : file to read Coverity token from
114
+ MemoryRegion mmio;
77
+# --version ver : specify version being analyzed (default: ask git)
115
+
78
+# --description desc : specify description of this version (default: ask git)
116
+ /* GPIO registers */
79
+# --srcdir : QEMU source tree to analyze (default: current working dir)
117
+ uint32_t moder;
80
+# --results-tarball : path to copy the results tarball to (default: don't
118
+ uint32_t otyper;
81
+# copy it anywhere, just upload it)
119
+ uint32_t ospeedr;
82
+#
120
+ uint32_t pupdr;
83
+# User-specifiable environment variables:
121
+ uint32_t idr;
84
+# COVERITY_TOKEN -- Coverity token
122
+ uint32_t odr;
85
+# COVERITY_EMAIL -- the email address to use for uploads (default:
123
+ uint32_t lckr;
86
+# looks at your git user.email config)
124
+ uint32_t afrl;
87
+# COVERITY_BUILD_CMD -- make command (default: 'make -jN' where N is
125
+ uint32_t afrh;
88
+# number of CPUs as determined by 'nproc')
126
+ uint32_t ascr;
89
+# COVERITY_TOOL_BASE -- set to directory to put coverity tools
127
+
90
+# (default: /tmp/coverity-tools)
128
+ /* GPIO registers reset values */
91
+#
129
+ uint32_t moder_reset;
92
+# You must specify the token, either by environment variable or by
130
+ uint32_t ospeedr_reset;
93
+# putting it in a file and using --tokenfile. Everything else has
131
+ uint32_t pupdr_reset;
94
+# a reasonable default if this is run from a git tree.
132
+
95
+
133
+ /*
96
+check_upload_permissions() {
134
+ * External driving of pins.
97
+ # Check whether we can do an upload to the server; will exit the script
135
+ * The pins can be set externally through the device
98
+ # with status 1 if the check failed (usually a bad token);
136
+ * anonymous input GPIOs lines under certain conditions.
99
+ # will exit the script with status 0 if the check indicated that we
137
+ * The pin must not be in push-pull output mode,
100
+ # can't upload yet (ie we are at quota)
138
+ * and can't be set high in open-drain mode.
101
+ # Assumes that PROJTOKEN, PROJNAME and DRYRUN have been initialized.
139
+ * Pins driven externally and configured to
102
+
140
+ * output mode will in general be "disconnected"
103
+ echo "Checking upload permissions..."
141
+ * (see `get_gpio_pinmask_to_disconnect()`)
104
+
142
+ */
105
+ if ! up_perm="$(wget https://scan.coverity.com/api/upload_permitted --post-data "token=$PROJTOKEN&project=$PROJNAME" -q -O -)"; then
143
+ uint16_t disconnected_pins;
106
+ echo "Coverity Scan API access denied: bad token?"
144
+ uint16_t pins_connected_high;
107
+ exit 1
145
+
108
+ fi
146
+ char *name;
109
+
147
+ Clock *clk;
110
+ # Really up_perm is a JSON response with either
148
+ qemu_irq pin[GPIO_NUM_PINS];
111
+ # {upload_permitted:true} or {next_upload_permitted_at:<date>}
149
+};
112
+ # We do some hacky string parsing instead of properly parsing it.
150
+
113
+ case "$up_perm" in
151
+#endif
114
+ *upload_permitted*true*)
152
diff --git a/hw/gpio/stm32l4x5_gpio.c b/hw/gpio/stm32l4x5_gpio.c
115
+ echo "Coverity Scan: upload permitted"
153
new file mode 100644
116
+ ;;
154
index XXXXXXX..XXXXXXX
117
+ *next_upload_permitted_at*)
155
--- /dev/null
118
+ if [ "$DRYRUN" = yes ]; then
156
+++ b/hw/gpio/stm32l4x5_gpio.c
119
+ echo "Coverity Scan: upload quota reached, continuing dry run"
157
@@ -XXX,XX +XXX,XX @@
120
+ else
158
+/*
121
+ echo "Coverity Scan: upload quota reached; stopping here"
159
+ * STM32L4x5 GPIO (General Purpose Input/Ouput)
122
+ # Exit success as this isn't a build error.
160
+ *
123
+ exit 0
161
+ * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
124
+ fi
162
+ * Copyright (c) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
125
+ ;;
163
+ *
126
+ *)
164
+ * SPDX-License-Identifier: GPL-2.0-or-later
127
+ echo "Coverity Scan upload check: unexpected result $up_perm"
165
+ *
128
+ exit 1
166
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
129
+ ;;
167
+ * See the COPYING file in the top-level directory.
130
+ esac
168
+ */
131
+}
169
+
132
+
170
+/*
133
+
171
+ * The reference used is the STMicroElectronics RM0351 Reference manual
134
+update_coverity_tools () {
172
+ * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
135
+ # Check for whether we need to download the Coverity tools
173
+ * https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html
136
+ # (either because we don't have a copy, or because it's out of date)
174
+ */
137
+ # Assumes that COVERITY_TOOL_BASE, PROJTOKEN and PROJNAME are set.
175
+
138
+
176
+#include "qemu/osdep.h"
139
+ mkdir -p "$COVERITY_TOOL_BASE"
177
+#include "qemu/log.h"
140
+ cd "$COVERITY_TOOL_BASE"
178
+#include "hw/gpio/stm32l4x5_gpio.h"
141
+
179
+#include "hw/irq.h"
142
+ echo "Checking for new version of coverity build tools..."
180
+#include "hw/qdev-clock.h"
143
+ wget https://scan.coverity.com/download/linux64 --post-data "token=$PROJTOKEN&project=$PROJNAME&md5=1" -O coverity_tool.md5.new
181
+#include "hw/qdev-properties.h"
144
+
182
+#include "qapi/visitor.h"
145
+ if ! cmp -s coverity_tool.md5 coverity_tool.md5.new; then
183
+#include "qapi/error.h"
146
+ # out of date md5 or no md5: download new build tool
184
+#include "migration/vmstate.h"
147
+ # blow away the old build tool
185
+#include "trace.h"
148
+ echo "Downloading coverity build tools..."
186
+
149
+ rm -rf coverity_tool coverity_tool.tgz
187
+#define GPIO_MODER 0x00
150
+ wget https://scan.coverity.com/download/linux64 --post-data "token=$PROJTOKEN&project=$PROJNAME" -O coverity_tool.tgz
188
+#define GPIO_OTYPER 0x04
151
+ if ! (cat coverity_tool.md5.new; echo " coverity_tool.tgz") | md5sum -c --status; then
189
+#define GPIO_OSPEEDR 0x08
152
+ echo "Downloaded tarball didn't match md5sum!"
190
+#define GPIO_PUPDR 0x0C
153
+ exit 1
191
+#define GPIO_IDR 0x10
154
+ fi
192
+#define GPIO_ODR 0x14
155
+ # extract the new one, keeping it corralled in a 'coverity_tool' directory
193
+#define GPIO_BSRR 0x18
156
+ echo "Unpacking coverity build tools..."
194
+#define GPIO_LCKR 0x1C
157
+ mkdir -p coverity_tool
195
+#define GPIO_AFRL 0x20
158
+ cd coverity_tool
196
+#define GPIO_AFRH 0x24
159
+ tar xf ../coverity_tool.tgz
197
+#define GPIO_BRR 0x28
160
+ cd ..
198
+#define GPIO_ASCR 0x2C
161
+ mv coverity_tool.md5.new coverity_tool.md5
199
+
162
+ fi
200
+/* 0b11111111_11111111_00000000_00000000 */
163
+
201
+#define RESERVED_BITS_MASK 0xFFFF0000
164
+ rm -f coverity_tool.md5.new
202
+
165
+}
203
+static void update_gpio_idr(Stm32l4x5GpioState *s);
166
+
204
+
167
+
205
+static bool is_pull_up(Stm32l4x5GpioState *s, unsigned pin)
168
+# Check user-provided environment variables and arguments
206
+{
169
+DRYRUN=no
207
+ return extract32(s->pupdr, 2 * pin, 2) == 1;
170
+UPDATE_ONLY=no
208
+}
171
+
209
+
172
+while [ "$#" -ge 1 ]; do
210
+static bool is_pull_down(Stm32l4x5GpioState *s, unsigned pin)
173
+ case "$1" in
211
+{
174
+ --dry-run)
212
+ return extract32(s->pupdr, 2 * pin, 2) == 2;
175
+ shift
213
+}
176
+ DRYRUN=yes
214
+
177
+ ;;
215
+static bool is_output(Stm32l4x5GpioState *s, unsigned pin)
178
+ --update-tools-only)
216
+{
179
+ shift
217
+ return extract32(s->moder, 2 * pin, 2) == 1;
180
+ UPDATE_ONLY=yes
218
+}
181
+ ;;
219
+
182
+ --version)
220
+static bool is_open_drain(Stm32l4x5GpioState *s, unsigned pin)
183
+ shift
221
+{
184
+ if [ $# -eq 0 ]; then
222
+ return extract32(s->otyper, pin, 1) == 1;
185
+ echo "--version needs an argument"
223
+}
186
+ exit 1
224
+
187
+ fi
225
+static bool is_push_pull(Stm32l4x5GpioState *s, unsigned pin)
188
+ VERSION="$1"
226
+{
189
+ shift
227
+ return extract32(s->otyper, pin, 1) == 0;
190
+ ;;
228
+}
191
+ --description)
229
+
192
+ shift
230
+static void stm32l4x5_gpio_reset_hold(Object *obj)
193
+ if [ $# -eq 0 ]; then
231
+{
194
+ echo "--description needs an argument"
232
+ Stm32l4x5GpioState *s = STM32L4X5_GPIO(obj);
195
+ exit 1
233
+
196
+ fi
234
+ s->moder = s->moder_reset;
197
+ DESCRIPTION="$1"
235
+ s->otyper = 0x00000000;
198
+ shift
236
+ s->ospeedr = s->ospeedr_reset;
199
+ ;;
237
+ s->pupdr = s->pupdr_reset;
200
+ --tokenfile)
238
+ s->idr = 0x00000000;
201
+ shift
239
+ s->odr = 0x00000000;
202
+ if [ $# -eq 0 ]; then
240
+ s->lckr = 0x00000000;
203
+ echo "--tokenfile needs an argument"
241
+ s->afrl = 0x00000000;
204
+ exit 1
242
+ s->afrh = 0x00000000;
205
+ fi
243
+ s->ascr = 0x00000000;
206
+ COVERITY_TOKEN="$(cat "$1")"
244
+
207
+ shift
245
+ s->disconnected_pins = 0xFFFF;
208
+ ;;
246
+ s->pins_connected_high = 0x0000;
209
+ --srcdir)
247
+ update_gpio_idr(s);
210
+ shift
248
+}
211
+ if [ $# -eq 0 ]; then
249
+
212
+ echo "--srcdir needs an argument"
250
+static void stm32l4x5_gpio_set(void *opaque, int line, int level)
213
+ exit 1
251
+{
214
+ fi
252
+ Stm32l4x5GpioState *s = opaque;
215
+ SRCDIR="$1"
253
+ /*
216
+ shift
254
+ * The pin isn't set if line is configured in output mode
217
+ ;;
255
+ * except if level is 0 and the output is open-drain.
218
+ --results-tarball)
256
+ * This way there will be no short-circuit prone situations.
219
+ shift
257
+ */
220
+ if [ $# -eq 0 ]; then
258
+ if (is_output(s, line) && !(is_open_drain(s, line) && (level == 0))) {
221
+ echo "--results-tarball needs an argument"
259
+ qemu_log_mask(LOG_GUEST_ERROR, "Line %d can't be driven externally\n",
222
+ exit 1
260
+ line);
223
+ fi
261
+ return;
224
+ RESULTSTARBALL="$1"
262
+ }
225
+ shift
263
+
226
+ ;;
264
+ s->disconnected_pins &= ~(1 << line);
227
+ *)
265
+ if (level) {
228
+ echo "Unexpected argument '$1'"
266
+ s->pins_connected_high |= (1 << line);
229
+ exit 1
267
+ } else {
230
+ ;;
268
+ s->pins_connected_high &= ~(1 << line);
231
+ esac
269
+ }
232
+done
270
+ trace_stm32l4x5_gpio_pins(s->name, s->disconnected_pins,
233
+
271
+ s->pins_connected_high);
234
+if [ -z "$COVERITY_TOKEN" ]; then
272
+ update_gpio_idr(s);
235
+ echo "COVERITY_TOKEN environment variable not set"
273
+}
236
+ exit 1
274
+
237
+fi
275
+
238
+
276
+static void update_gpio_idr(Stm32l4x5GpioState *s)
239
+if [ -z "$COVERITY_BUILD_CMD" ]; then
277
+{
240
+ NPROC=$(nproc)
278
+ uint32_t new_idr_mask = 0;
241
+ COVERITY_BUILD_CMD="make -j$NPROC"
279
+ uint32_t new_idr = s->odr;
242
+ echo "COVERITY_BUILD_CMD: using default '$COVERITY_BUILD_CMD'"
280
+ uint32_t old_idr = s->idr;
243
+fi
281
+ int new_pin_state, old_pin_state;
244
+
282
+
245
+if [ -z "$COVERITY_TOOL_BASE" ]; then
283
+ for (int i = 0; i < GPIO_NUM_PINS; i++) {
246
+ echo "COVERITY_TOOL_BASE: using default /tmp/coverity-tools"
284
+ if (is_output(s, i)) {
247
+ COVERITY_TOOL_BASE=/tmp/coverity-tools
285
+ if (is_push_pull(s, i)) {
248
+fi
286
+ new_idr_mask |= (1 << i);
249
+
287
+ } else if (!(s->odr & (1 << i))) {
250
+if [ -z "$SRCDIR" ]; then
288
+ /* open-drain ODR 0 */
251
+ SRCDIR="$PWD"
289
+ new_idr_mask |= (1 << i);
252
+fi
290
+ /* open-drain ODR 1 */
253
+
291
+ } else if (!(s->disconnected_pins & (1 << i)) &&
254
+PROJTOKEN="$COVERITY_TOKEN"
292
+ !(s->pins_connected_high & (1 << i))) {
255
+PROJNAME=QEMU
293
+ /* open-drain ODR 1 with pin connected low */
256
+TARBALL=cov-int.tar.xz
294
+ new_idr_mask |= (1 << i);
257
+
295
+ new_idr &= ~(1 << i);
258
+
296
+ /* open-drain ODR 1 with unactive pin */
259
+if [ "$UPDATE_ONLY" = yes ]; then
297
+ } else if (is_pull_up(s, i)) {
260
+ # Just do the tools update; we don't need to check whether
298
+ new_idr_mask |= (1 << i);
261
+ # we are in a source tree or have upload rights for this,
299
+ } else if (is_pull_down(s, i)) {
262
+ # so do it before some of the command line and source tree checks.
300
+ new_idr_mask |= (1 << i);
263
+ update_coverity_tools
301
+ new_idr &= ~(1 << i);
264
+ exit 0
302
+ }
265
+fi
303
+ /*
266
+
304
+ * The only case left is for open-drain ODR 1
267
+cd "$SRCDIR"
305
+ * with unactive pin without pull-up or pull-down :
268
+
306
+ * the value is floating.
269
+echo "Checking this is a QEMU source tree..."
307
+ */
270
+if ! [ -e "$SRCDIR/VERSION" ]; then
308
+ /* input or analog mode with connected pin */
271
+ echo "Not in a QEMU source tree?"
309
+ } else if (!(s->disconnected_pins & (1 << i))) {
272
+ exit 1
310
+ if (s->pins_connected_high & (1 << i)) {
273
+fi
311
+ /* pin high */
274
+
312
+ new_idr_mask |= (1 << i);
275
+# Fill in defaults used by the non-update-only process
313
+ new_idr |= (1 << i);
276
+if [ -z "$VERSION" ]; then
314
+ } else {
277
+ VERSION="$(git describe --always HEAD)"
315
+ /* pin low */
278
+fi
316
+ new_idr_mask |= (1 << i);
279
+
317
+ new_idr &= ~(1 << i);
280
+if [ -z "$DESCRIPTION" ]; then
318
+ }
281
+ DESCRIPTION="$(git rev-parse HEAD)"
319
+ /* input or analog mode with disconnected pin */
282
+fi
320
+ } else {
283
+
321
+ if (is_pull_up(s, i)) {
284
+if [ -z "$COVERITY_EMAIL" ]; then
322
+ /* pull-up */
285
+ COVERITY_EMAIL="$(git config user.email)"
323
+ new_idr_mask |= (1 << i);
286
+fi
324
+ new_idr |= (1 << i);
287
+
325
+ } else if (is_pull_down(s, i)) {
288
+check_upload_permissions
326
+ /* pull-down */
289
+
327
+ new_idr_mask |= (1 << i);
290
+update_coverity_tools
328
+ new_idr &= ~(1 << i);
291
+
329
+ }
292
+TOOLBIN="$(cd "$COVERITY_TOOL_BASE" && echo $PWD/coverity_tool/cov-analysis-*/bin)"
330
+ /*
293
+
331
+ * The only case left is for a disconnected pin
294
+if ! test -x "$TOOLBIN/cov-build"; then
332
+ * without pull-up or pull-down :
295
+ echo "Couldn't find cov-build in the coverity build-tool directory??"
333
+ * the value is floating.
296
+ exit 1
334
+ */
297
+fi
335
+ }
298
+
336
+ }
299
+export PATH="$TOOLBIN:$PATH"
337
+
300
+
338
+ s->idr = (old_idr & ~new_idr_mask) | (new_idr & new_idr_mask);
301
+cd "$SRCDIR"
339
+ trace_stm32l4x5_gpio_update_idr(s->name, old_idr, s->idr);
302
+
340
+
303
+echo "Doing make distclean..."
341
+ for (int i = 0; i < GPIO_NUM_PINS; i++) {
304
+make distclean
342
+ if (new_idr_mask & (1 << i)) {
305
+
343
+ new_pin_state = (new_idr & (1 << i)) > 0;
306
+echo "Configuring..."
344
+ old_pin_state = (old_idr & (1 << i)) > 0;
307
+# We configure with a fixed set of enables here to ensure that we don't
345
+ if (new_pin_state > old_pin_state) {
308
+# accidentally reduce the scope of the analysis by doing the build on
346
+ qemu_irq_raise(s->pin[i]);
309
+# the system that's missing a dependency that we need to build part of
347
+ } else if (new_pin_state < old_pin_state) {
310
+# the codebase.
348
+ qemu_irq_lower(s->pin[i]);
311
+./configure --disable-modules --enable-sdl --enable-gtk \
349
+ }
312
+ --enable-opengl --enable-vte --enable-gnutls \
350
+ }
313
+ --enable-nettle --enable-curses --enable-curl \
351
+ }
314
+ --audio-drv-list=oss,alsa,sdl,pa --enable-virtfs \
352
+}
315
+ --enable-vnc --enable-vnc-sasl --enable-vnc-jpeg --enable-vnc-png \
353
+
316
+ --enable-xen --enable-brlapi \
354
+/*
317
+ --enable-linux-aio --enable-attr \
355
+ * Return mask of pins that are both configured in output
318
+ --enable-cap-ng --enable-trace-backends=log --enable-spice --enable-rbd \
356
+ * mode and externally driven (except pins in open-drain
319
+ --enable-xfsctl --enable-libusb --enable-usb-redir \
357
+ * mode externally set to 0).
320
+ --enable-libiscsi --enable-libnfs --enable-seccomp \
358
+ */
321
+ --enable-tpm --enable-libssh --enable-lzo --enable-snappy --enable-bzip2 \
359
+static uint32_t get_gpio_pinmask_to_disconnect(Stm32l4x5GpioState *s)
322
+ --enable-numa --enable-rdma --enable-smartcard --enable-virglrenderer \
360
+{
323
+ --enable-mpath --enable-libxml2 --enable-glusterfs \
361
+ uint32_t pins_to_disconnect = 0;
324
+ --enable-virtfs --enable-zstd
362
+ for (int i = 0; i < GPIO_NUM_PINS; i++) {
325
+
363
+ /* for each connected pin in output mode */
326
+echo "Making libqemustub.a..."
364
+ if (!(s->disconnected_pins & (1 << i)) && is_output(s, i)) {
327
+make libqemustub.a
365
+ /* if either push-pull or high level */
328
+
366
+ if (is_push_pull(s, i) || s->pins_connected_high & (1 << i)) {
329
+echo "Running cov-build..."
367
+ pins_to_disconnect |= (1 << i);
330
+rm -rf cov-int
368
+ qemu_log_mask(LOG_GUEST_ERROR,
331
+mkdir cov-int
369
+ "Line %d can't be driven externally\n",
332
+cov-build --dir cov-int $COVERITY_BUILD_CMD
370
+ i);
333
+
371
+ }
334
+echo "Creating results tarball..."
372
+ }
335
+tar cvf - cov-int | xz > "$TARBALL"
373
+ }
336
+
374
+ return pins_to_disconnect;
337
+if [ ! -z "$RESULTSTARBALL" ]; then
375
+}
338
+ echo "Copying results tarball to $RESULTSTARBALL..."
376
+
339
+ cp "$TARBALL" "$RESULTSTARBALL"
377
+/*
340
+fi
378
+ * Set field `disconnected_pins` and call `update_gpio_idr()`
341
+
379
+ */
342
+echo "Uploading results tarball..."
380
+static void disconnect_gpio_pins(Stm32l4x5GpioState *s, uint16_t lines)
343
+
381
+{
344
+if [ "$DRYRUN" = yes ]; then
382
+ s->disconnected_pins |= lines;
345
+ echo "Dry run only, not uploading $TARBALL"
383
+ trace_stm32l4x5_gpio_pins(s->name, s->disconnected_pins,
346
+ exit 0
384
+ s->pins_connected_high);
347
+fi
385
+ update_gpio_idr(s);
348
+
386
+}
349
+curl --form token="$PROJTOKEN" --form email="$COVERITY_EMAIL" \
387
+
350
+ --form file=@"$TARBALL" --form version="$VERSION" \
388
+static void disconnected_pins_set(Object *obj, Visitor *v,
351
+ --form description="$DESCRIPTION" \
389
+ const char *name, void *opaque, Error **errp)
352
+ https://scan.coverity.com/builds?project="$PROJNAME"
390
+{
353
+
391
+ Stm32l4x5GpioState *s = STM32L4X5_GPIO(obj);
354
+echo "Done."
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);
420
+
421
+ switch (addr) {
422
+ case GPIO_MODER:
423
+ s->moder = value;
424
+ disconnect_gpio_pins(s, get_gpio_pinmask_to_disconnect(s));
425
+ qemu_log_mask(LOG_UNIMP,
426
+ "%s: Analog and AF modes aren't supported\n\
427
+ Analog and AF mode behave like input mode\n",
428
+ __func__);
429
+ return;
430
+ case GPIO_OTYPER:
431
+ s->otyper = value & ~RESERVED_BITS_MASK;
432
+ disconnect_gpio_pins(s, get_gpio_pinmask_to_disconnect(s));
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;
493
+ default:
494
+ qemu_log_mask(LOG_GUEST_ERROR,
495
+ "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, 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:
520
+ return 0;
521
+ case GPIO_LCKR:
522
+ return s->lckr;
523
+ case GPIO_AFRL:
524
+ return s->afrl;
525
+ case GPIO_AFRH:
526
+ return s->afrh;
527
+ case GPIO_BRR:
528
+ return 0;
529
+ case GPIO_ASCR:
530
+ return s->ascr;
531
+ default:
532
+ qemu_log_mask(LOG_GUEST_ERROR,
533
+ "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, addr);
534
+ return 0;
535
+ }
536
+}
537
+
538
+static const MemoryRegionOps stm32l4x5_gpio_ops = {
539
+ .read = stm32l4x5_gpio_read,
540
+ .write = stm32l4x5_gpio_write,
541
+ .endianness = DEVICE_NATIVE_ENDIAN,
542
+ .impl = {
543
+ .min_access_size = 4,
544
+ .max_access_size = 4,
545
+ .unaligned = false,
546
+ },
547
+ .valid = {
548
+ .min_access_size = 4,
549
+ .max_access_size = 4,
550
+ .unaligned = false,
551
+ },
552
+};
553
+
554
+static void stm32l4x5_gpio_init(Object *obj)
555
+{
556
+ Stm32l4x5GpioState *s = STM32L4X5_GPIO(obj);
557
+
558
+ memory_region_init_io(&s->mmio, obj, &stm32l4x5_gpio_ops, s,
559
+ TYPE_STM32L4X5_GPIO, 0x400);
560
+
561
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
562
+
563
+ qdev_init_gpio_out(DEVICE(obj), s->pin, GPIO_NUM_PINS);
564
+ qdev_init_gpio_in(DEVICE(obj), stm32l4x5_gpio_set, GPIO_NUM_PINS);
565
+
566
+ s->clk = qdev_init_clock_in(DEVICE(s), "clk", NULL, s, 0);
567
+
568
+ object_property_add(obj, "disconnected-pins", "uint16",
569
+ disconnected_pins_get, disconnected_pins_set,
570
+ NULL, &s->disconnected_pins);
571
+ object_property_add(obj, "clock-freq-hz", "uint32",
572
+ clock_freq_get, NULL, NULL, NULL);
573
+}
574
+
575
+static void stm32l4x5_gpio_realize(DeviceState *dev, Error **errp)
576
+{
577
+ Stm32l4x5GpioState *s = STM32L4X5_GPIO(dev);
578
+ if (!clock_has_source(s->clk)) {
579
+ error_setg(errp, "GPIO: clk input must be connected");
580
+ return;
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,
631
+ },
632
+};
633
+
634
+DEFINE_TYPES(stm32l4x5_gpio_types)
635
diff --git a/hw/gpio/Kconfig b/hw/gpio/Kconfig
636
index XXXXXXX..XXXXXXX 100644
637
--- a/hw/gpio/Kconfig
638
+++ b/hw/gpio/Kconfig
639
@@ -XXX,XX +XXX,XX @@ config GPIO_PWR
640
641
config SIFIVE_GPIO
642
bool
643
+
644
+config STM32L4X5_GPIO
645
+ bool
646
diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build
647
index XXXXXXX..XXXXXXX 100644
648
--- a/hw/gpio/meson.build
649
+++ b/hw/gpio/meson.build
650
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_RASPI', if_true: files(
651
'bcm2835_gpio.c',
652
'bcm2838_gpio.c'
653
))
654
+system_ss.add(when: 'CONFIG_STM32L4X5_SOC', if_true: files('stm32l4x5_gpio.c'))
655
system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_gpio.c'))
656
system_ss.add(when: 'CONFIG_SIFIVE_GPIO', if_true: files('sifive_gpio.c'))
657
diff --git a/hw/gpio/trace-events b/hw/gpio/trace-events
658
index XXXXXXX..XXXXXXX 100644
659
--- a/hw/gpio/trace-events
660
+++ b/hw/gpio/trace-events
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"
355
--
671
--
356
2.20.1
672
2.34.1
357
673
358
674
diff view generated by jsdifflib
New patch
1
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
3
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
4
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-id: 20240305210444.310665-3-ines.varhol@telecom-paris.fr
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
include/hw/arm/stm32l4x5_soc.h | 2 +
11
include/hw/gpio/stm32l4x5_gpio.h | 1 +
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
211
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
212
index XXXXXXX..XXXXXXX 100644
213
--- a/hw/arm/Kconfig
214
+++ b/hw/arm/Kconfig
215
@@ -XXX,XX +XXX,XX @@ config STM32L4X5_SOC
216
bool
217
select ARM_V7M
218
select OR_IRQ
219
- select STM32L4X5_SYSCFG
220
select STM32L4X5_EXTI
221
+ select STM32L4X5_SYSCFG
222
select STM32L4X5_RCC
223
+ select STM32L4X5_GPIO
224
225
config XLNX_ZYNQMP_ARM
226
bool
227
--
228
2.34.1
229
230
diff view generated by jsdifflib
1
Add support for running the Coverity Scan tools inside a Docker
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
container rather than directly on the host system.
3
2
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
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.
24
25
Acked-by: Thomas Huth <thuth@redhat.com>
26
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
27
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
28
Message-id: 20240305210444.310665-4-ines.varhol@telecom-paris.fr
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Message-id: 20200319193323.2038-7-peter.maydell@linaro.org
7
---
30
---
8
scripts/coverity-scan/coverity-scan.docker | 131 +++++++++++++++++++++
31
tests/qtest/stm32l4x5_gpio-test.c | 551 ++++++++++++++++++++++++++++++
9
scripts/coverity-scan/run-coverity-scan | 90 ++++++++++++++
32
tests/qtest/meson.build | 3 +-
10
2 files changed, 221 insertions(+)
33
2 files changed, 553 insertions(+), 1 deletion(-)
11
create mode 100644 scripts/coverity-scan/coverity-scan.docker
34
create mode 100644 tests/qtest/stm32l4x5_gpio-test.c
12
35
13
diff --git a/scripts/coverity-scan/coverity-scan.docker b/scripts/coverity-scan/coverity-scan.docker
36
diff --git a/tests/qtest/stm32l4x5_gpio-test.c b/tests/qtest/stm32l4x5_gpio-test.c
14
new file mode 100644
37
new file mode 100644
15
index XXXXXXX..XXXXXXX
38
index XXXXXXX..XXXXXXX
16
--- /dev/null
39
--- /dev/null
17
+++ b/scripts/coverity-scan/coverity-scan.docker
40
+++ b/tests/qtest/stm32l4x5_gpio-test.c
18
@@ -XXX,XX +XXX,XX @@
41
@@ -XXX,XX +XXX,XX @@
19
+# syntax=docker/dockerfile:1.0.0-experimental
42
+/*
20
+#
43
+ * QTest testcase for STM32L4x5_GPIO
21
+# Docker setup for running the "Coverity Scan" tools over the source
44
+ *
22
+# tree and uploading them to the website, as per
45
+ * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
23
+# https://scan.coverity.com/projects/qemu/builds/new
46
+ * Copyright (c) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
24
+# We do this on a fixed config (currently Fedora 30 with a known
47
+ *
25
+# set of dependencies and a configure command that enables a specific
48
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
26
+# set of options) so that random changes don't result in our accidentally
49
+ * See the COPYING file in the top-level directory.
27
+# dropping some files from the scan.
50
+ */
28
+#
51
+
29
+# We don't build on top of the fedora.docker file because we don't
52
+#include "qemu/osdep.h"
30
+# want to accidentally change or break the scan config when that
53
+#include "libqtest-single.h"
31
+# is updated.
54
+
32
+
55
+#define GPIO_BASE_ADDR 0x48000000
33
+# The work of actually doing the build is handled by the
56
+#define GPIO_SIZE 0x400
34
+# run-coverity-scan script.
57
+#define NUM_GPIOS 8
35
+
58
+#define NUM_GPIO_PINS 16
36
+FROM fedora:30
59
+
37
+ENV PACKAGES \
60
+#define GPIO_A 0x48000000
38
+ alsa-lib-devel \
61
+#define GPIO_B 0x48000400
39
+ bc \
62
+#define GPIO_C 0x48000800
40
+ bison \
63
+#define GPIO_D 0x48000C00
41
+ brlapi-devel \
64
+#define GPIO_E 0x48001000
42
+ bzip2 \
65
+#define GPIO_F 0x48001400
43
+ bzip2-devel \
66
+#define GPIO_G 0x48001800
44
+ ccache \
67
+#define GPIO_H 0x48001C00
45
+ clang \
68
+
46
+ curl \
69
+#define MODER 0x00
47
+ cyrus-sasl-devel \
70
+#define OTYPER 0x04
48
+ dbus-daemon \
71
+#define PUPDR 0x0C
49
+ device-mapper-multipath-devel \
72
+#define IDR 0x10
50
+ findutils \
73
+#define ODR 0x14
51
+ flex \
74
+#define BSRR 0x18
52
+ gcc \
75
+#define BRR 0x28
53
+ gcc-c++ \
76
+
54
+ gettext \
77
+#define MODER_INPUT 0
55
+ git \
78
+#define MODER_OUTPUT 1
56
+ glib2-devel \
79
+
57
+ glusterfs-api-devel \
80
+#define PUPDR_NONE 0
58
+ gnutls-devel \
81
+#define PUPDR_PULLUP 1
59
+ gtk3-devel \
82
+#define PUPDR_PULLDOWN 2
60
+ hostname \
83
+
61
+ libaio-devel \
84
+#define OTYPER_PUSH_PULL 0
62
+ libasan \
85
+#define OTYPER_OPEN_DRAIN 1
63
+ libattr-devel \
86
+
64
+ libblockdev-mpath-devel \
87
+const uint32_t moder_reset[NUM_GPIOS] = {
65
+ libcap-devel \
88
+ 0xABFFFFFF,
66
+ libcap-ng-devel \
89
+ 0xFFFFFEBF,
67
+ libcurl-devel \
90
+ 0xFFFFFFFF,
68
+ libepoxy-devel \
91
+ 0xFFFFFFFF,
69
+ libfdt-devel \
92
+ 0xFFFFFFFF,
70
+ libgbm-devel \
93
+ 0xFFFFFFFF,
71
+ libiscsi-devel \
94
+ 0xFFFFFFFF,
72
+ libjpeg-devel \
95
+ 0x0000000F
73
+ libpmem-devel \
96
+};
74
+ libnfs-devel \
97
+
75
+ libpng-devel \
98
+const uint32_t pupdr_reset[NUM_GPIOS] = {
76
+ librbd-devel \
99
+ 0x64000000,
77
+ libseccomp-devel \
100
+ 0x00000100,
78
+ libssh-devel \
101
+ 0x00000000,
79
+ libubsan \
102
+ 0x00000000,
80
+ libudev-devel \
103
+ 0x00000000,
81
+ libusbx-devel \
104
+ 0x00000000,
82
+ libxml2-devel \
105
+ 0x00000000,
83
+ libzstd-devel \
106
+ 0x00000000
84
+ llvm \
107
+};
85
+ lzo-devel \
108
+
86
+ make \
109
+const uint32_t idr_reset[NUM_GPIOS] = {
87
+ mingw32-bzip2 \
110
+ 0x0000A000,
88
+ mingw32-curl \
111
+ 0x00000010,
89
+ mingw32-glib2 \
112
+ 0x00000000,
90
+ mingw32-gmp \
113
+ 0x00000000,
91
+ mingw32-gnutls \
114
+ 0x00000000,
92
+ mingw32-gtk3 \
115
+ 0x00000000,
93
+ mingw32-libjpeg-turbo \
116
+ 0x00000000,
94
+ mingw32-libpng \
117
+ 0x00000000
95
+ mingw32-libtasn1 \
118
+};
96
+ mingw32-nettle \
119
+
97
+ mingw32-nsis \
120
+static uint32_t gpio_readl(unsigned int gpio, unsigned int offset)
98
+ mingw32-pixman \
121
+{
99
+ mingw32-pkg-config \
122
+ return readl(gpio + offset);
100
+ mingw32-SDL2 \
123
+}
101
+ mingw64-bzip2 \
124
+
102
+ mingw64-curl \
125
+static void gpio_writel(unsigned int gpio, unsigned int offset, uint32_t value)
103
+ mingw64-glib2 \
126
+{
104
+ mingw64-gmp \
127
+ writel(gpio + offset, value);
105
+ mingw64-gnutls \
128
+}
106
+ mingw64-gtk3 \
129
+
107
+ mingw64-libjpeg-turbo \
130
+static void gpio_set_bit(unsigned int gpio, unsigned int reg,
108
+ mingw64-libpng \
131
+ unsigned int pin, uint32_t value)
109
+ mingw64-libtasn1 \
132
+{
110
+ mingw64-nettle \
133
+ uint32_t mask = 0xFFFFFFFF & ~(0x1 << pin);
111
+ mingw64-pixman \
134
+ gpio_writel(gpio, reg, (gpio_readl(gpio, reg) & mask) | value << pin);
112
+ mingw64-pkg-config \
135
+}
113
+ mingw64-SDL2 \
136
+
114
+ ncurses-devel \
137
+static void gpio_set_2bits(unsigned int gpio, unsigned int reg,
115
+ nettle-devel \
138
+ unsigned int pin, uint32_t value)
116
+ nss-devel \
139
+{
117
+ numactl-devel \
140
+ uint32_t offset = 2 * pin;
118
+ perl \
141
+ uint32_t mask = 0xFFFFFFFF & ~(0x3 << offset);
119
+ perl-Test-Harness \
142
+ gpio_writel(gpio, reg, (gpio_readl(gpio, reg) & mask) | value << offset);
120
+ pixman-devel \
143
+}
121
+ pulseaudio-libs-devel \
144
+
122
+ python3 \
145
+static unsigned int get_gpio_id(uint32_t gpio_addr)
123
+ python3-sphinx \
146
+{
124
+ PyYAML \
147
+ return (gpio_addr - GPIO_BASE_ADDR) / GPIO_SIZE;
125
+ rdma-core-devel \
148
+}
126
+ SDL2-devel \
149
+
127
+ snappy-devel \
150
+static void gpio_set_irq(unsigned int gpio, int num, int level)
128
+ sparse \
151
+{
129
+ spice-server-devel \
152
+ g_autofree char *name = g_strdup_printf("/machine/soc/gpio%c",
130
+ systemd-devel \
153
+ get_gpio_id(gpio) + 'a');
131
+ systemtap-sdt-devel \
154
+ qtest_set_irq_in(global_qtest, name, NULL, num, level);
132
+ tar \
155
+}
133
+ texinfo \
156
+
134
+ usbredir-devel \
157
+static void disconnect_all_pins(unsigned int gpio)
135
+ virglrenderer-devel \
158
+{
136
+ vte291-devel \
159
+ g_autofree char *path = g_strdup_printf("/machine/soc/gpio%c",
137
+ wget \
160
+ get_gpio_id(gpio) + 'a');
138
+ which \
161
+ QDict *r;
139
+ xen-devel \
162
+
140
+ xfsprogs-devel \
163
+ r = qtest_qmp(global_qtest, "{ 'execute': 'qom-set', 'arguments': "
141
+ zlib-devel
164
+ "{ 'path': %s, 'property': 'disconnected-pins', 'value': %d } }",
142
+ENV QEMU_CONFIGURE_OPTS --python=/usr/bin/python3
165
+ path, 0xFFFF);
143
+
166
+ g_assert_false(qdict_haskey(r, "error"));
144
+RUN dnf install -y $PACKAGES
167
+ qobject_unref(r);
145
+RUN rpm -q $PACKAGES | sort > /packages.txt
168
+}
146
+ENV PATH $PATH:/usr/libexec/python3-sphinx/
169
+
147
+ENV COVERITY_TOOL_BASE=/coverity-tools
170
+static uint32_t get_disconnected_pins(unsigned int gpio)
148
+COPY run-coverity-scan run-coverity-scan
171
+{
149
+RUN --mount=type=secret,id=coverity.token,required ./run-coverity-scan --update-tools-only --tokenfile /run/secrets/coverity.token
172
+ g_autofree char *path = g_strdup_printf("/machine/soc/gpio%c",
150
diff --git a/scripts/coverity-scan/run-coverity-scan b/scripts/coverity-scan/run-coverity-scan
173
+ get_gpio_id(gpio) + 'a');
151
index XXXXXXX..XXXXXXX 100755
174
+ uint32_t disconnected_pins = 0;
152
--- a/scripts/coverity-scan/run-coverity-scan
175
+ QDict *r;
153
+++ b/scripts/coverity-scan/run-coverity-scan
176
+
154
@@ -XXX,XX +XXX,XX @@
177
+ r = qtest_qmp(global_qtest, "{ 'execute': 'qom-get', 'arguments':"
155
178
+ " { 'path': %s, 'property': 'disconnected-pins'} }", path);
156
# Command line options:
179
+ g_assert_false(qdict_haskey(r, "error"));
157
# --dry-run : run the tools, but don't actually do the upload
180
+ disconnected_pins = qdict_get_int(r, "return");
158
+# --docker : create and work inside a docker container
181
+ qobject_unref(r);
159
# --update-tools-only : update the cached copy of the tools, but don't run them
182
+ return disconnected_pins;
160
# --tokenfile : file to read Coverity token from
183
+}
161
# --version ver : specify version being analyzed (default: ask git)
184
+
162
@@ -XXX,XX +XXX,XX @@
185
+static uint32_t reset(uint32_t gpio, unsigned int offset)
163
# --srcdir : QEMU source tree to analyze (default: current working dir)
186
+{
164
# --results-tarball : path to copy the results tarball to (default: don't
187
+ switch (offset) {
165
# copy it anywhere, just upload it)
188
+ case MODER:
166
+# --src-tarball : tarball to untar into src dir (default: none); this
189
+ return moder_reset[get_gpio_id(gpio)];
167
+# is intended mainly for internal use by the Docker support
190
+ case PUPDR:
168
#
191
+ return pupdr_reset[get_gpio_id(gpio)];
169
# User-specifiable environment variables:
192
+ case IDR:
170
# COVERITY_TOKEN -- Coverity token
193
+ return idr_reset[get_gpio_id(gpio)];
171
@@ -XXX,XX +XXX,XX @@ update_coverity_tools () {
194
+ }
172
# Check user-provided environment variables and arguments
195
+ return 0x0;
173
DRYRUN=no
196
+}
174
UPDATE_ONLY=no
197
+
175
+DOCKER=no
198
+static void system_reset(void)
176
199
+{
177
while [ "$#" -ge 1 ]; do
200
+ QDict *r;
178
case "$1" in
201
+ r = qtest_qmp(global_qtest, "{'execute': 'system_reset'}");
179
@@ -XXX,XX +XXX,XX @@ while [ "$#" -ge 1 ]; do
202
+ g_assert_false(qdict_haskey(r, "error"));
180
RESULTSTARBALL="$1"
203
+ qobject_unref(r);
181
shift
204
+}
182
;;
205
+
183
+ --src-tarball)
206
+static void test_idr_reset_value(void)
184
+ shift
207
+{
185
+ if [ $# -eq 0 ]; then
208
+ /*
186
+ echo "--src-tarball needs an argument"
209
+ * Checks that the values in MODER, OTYPER, PUPDR and ODR
187
+ exit 1
210
+ * after reset are correct, and that the value in IDR is
188
+ fi
211
+ * coherent.
189
+ SRCTARBALL="$1"
212
+ * Since AF and analog modes aren't implemented, IDR reset
190
+ shift
213
+ * values aren't the same as with a real board.
191
+ ;;
214
+ *
192
+ --docker)
215
+ * Register IDR contains the actual values of all GPIO pins.
193
+ DOCKER=yes
216
+ * Its value depends on the pins' configuration
194
+ shift
217
+ * (intput/output/analog : register MODER, push-pull/open-drain :
195
+ ;;
218
+ * register OTYPER, pull-up/pull-down/none : register PUPDR)
196
*)
219
+ * and on the values stored in register ODR
197
echo "Unexpected argument '$1'"
220
+ * (in case the pin is in output mode).
198
exit 1
221
+ */
199
@@ -XXX,XX +XXX,XX @@ PROJTOKEN="$COVERITY_TOKEN"
222
+
200
PROJNAME=QEMU
223
+ gpio_writel(GPIO_A, MODER, 0xDEADBEEF);
201
TARBALL=cov-int.tar.xz
224
+ gpio_writel(GPIO_A, ODR, 0xDEADBEEF);
202
225
+ gpio_writel(GPIO_A, OTYPER, 0xDEADBEEF);
203
+if [ "$UPDATE_ONLY" = yes ] && [ "$DOCKER" = yes ]; then
226
+ gpio_writel(GPIO_A, PUPDR, 0xDEADBEEF);
204
+ echo "Combining --docker and --update-only is not supported"
227
+
205
+ exit 1
228
+ gpio_writel(GPIO_B, MODER, 0xDEADBEEF);
206
+fi
229
+ gpio_writel(GPIO_B, ODR, 0xDEADBEEF);
207
230
+ gpio_writel(GPIO_B, OTYPER, 0xDEADBEEF);
208
if [ "$UPDATE_ONLY" = yes ]; then
231
+ gpio_writel(GPIO_B, PUPDR, 0xDEADBEEF);
209
# Just do the tools update; we don't need to check whether
232
+
210
@@ -XXX,XX +XXX,XX @@ if [ "$UPDATE_ONLY" = yes ]; then
233
+ gpio_writel(GPIO_C, MODER, 0xDEADBEEF);
211
exit 0
234
+ gpio_writel(GPIO_C, ODR, 0xDEADBEEF);
212
fi
235
+ gpio_writel(GPIO_C, OTYPER, 0xDEADBEEF);
213
236
+ gpio_writel(GPIO_C, PUPDR, 0xDEADBEEF);
214
+if [ ! -e "$SRCDIR" ]; then
237
+
215
+ mkdir "$SRCDIR"
238
+ gpio_writel(GPIO_H, MODER, 0xDEADBEEF);
216
+fi
239
+ gpio_writel(GPIO_H, ODR, 0xDEADBEEF);
217
+
240
+ gpio_writel(GPIO_H, OTYPER, 0xDEADBEEF);
218
cd "$SRCDIR"
241
+ gpio_writel(GPIO_H, PUPDR, 0xDEADBEEF);
219
242
+
220
+if [ ! -z "$SRCTARBALL" ]; then
243
+ system_reset();
221
+ echo "Untarring source tarball into $SRCDIR..."
244
+
222
+ tar xvf "$SRCTARBALL"
245
+ uint32_t moder = gpio_readl(GPIO_A, MODER);
223
+fi
246
+ uint32_t odr = gpio_readl(GPIO_A, ODR);
224
+
247
+ uint32_t otyper = gpio_readl(GPIO_A, OTYPER);
225
echo "Checking this is a QEMU source tree..."
248
+ uint32_t pupdr = gpio_readl(GPIO_A, PUPDR);
226
if ! [ -e "$SRCDIR/VERSION" ]; then
249
+ uint32_t idr = gpio_readl(GPIO_A, IDR);
227
echo "Not in a QEMU source tree?"
250
+ /* 15: AF, 14: AF, 13: AF, 12: Analog ... */
228
@@ -XXX,XX +XXX,XX @@ if [ -z "$COVERITY_EMAIL" ]; then
251
+ /* here AF is the same as Analog and Input mode */
229
COVERITY_EMAIL="$(git config user.email)"
252
+ g_assert_cmphex(moder, ==, reset(GPIO_A, MODER));
230
fi
253
+ g_assert_cmphex(odr, ==, reset(GPIO_A, ODR));
231
254
+ g_assert_cmphex(otyper, ==, reset(GPIO_A, OTYPER));
232
+# Run ourselves inside docker if that's what the user wants
255
+ /* 15: pull-up, 14: pull-down, 13: pull-up, 12: neither ... */
233
+if [ "$DOCKER" = yes ]; then
256
+ g_assert_cmphex(pupdr, ==, reset(GPIO_A, PUPDR));
234
+ # build docker container including the coverity-scan tools
257
+ /* 15 : 1, 14: 0, 13: 1, 12 : reset value ... */
235
+ # Put the Coverity token into a temporary file that only
258
+ g_assert_cmphex(idr, ==, reset(GPIO_A, IDR));
236
+ # we have read access to, and then pass it to docker build
259
+
237
+ # using --secret. This requires at least Docker 18.09.
260
+ moder = gpio_readl(GPIO_B, MODER);
238
+ # Mostly what we are trying to do here is ensure we don't leak
261
+ odr = gpio_readl(GPIO_B, ODR);
239
+ # the token into the Docker image.
262
+ otyper = gpio_readl(GPIO_B, OTYPER);
240
+ umask 077
263
+ pupdr = gpio_readl(GPIO_B, PUPDR);
241
+ SECRETDIR=$(mktemp -d)
264
+ idr = gpio_readl(GPIO_B, IDR);
242
+ if [ -z "$SECRETDIR" ]; then
265
+ /* ... 5: Analog, 4: AF, 3: AF, 2: Analog ... */
243
+ echo "Failed to create temporary directory"
266
+ /* here AF is the same as Analog and Input mode */
244
+ exit 1
267
+ g_assert_cmphex(moder, ==, reset(GPIO_B, MODER));
245
+ fi
268
+ g_assert_cmphex(odr, ==, reset(GPIO_B, ODR));
246
+ trap 'rm -rf "$SECRETDIR"' INT TERM EXIT
269
+ g_assert_cmphex(otyper, ==, reset(GPIO_B, OTYPER));
247
+ echo "Created temporary directory $SECRETDIR"
270
+ /* ... 5: neither, 4: pull-up, 3: neither ... */
248
+ SECRET="$SECRETDIR/token"
271
+ g_assert_cmphex(pupdr, ==, reset(GPIO_B, PUPDR));
249
+ echo "$COVERITY_TOKEN" > "$SECRET"
272
+ /* ... 5 : reset value, 4 : 1, 3 : reset value ... */
250
+ echo "Building docker container..."
273
+ g_assert_cmphex(idr, ==, reset(GPIO_B, IDR));
251
+ # TODO: This re-downloads the tools every time, rather than
274
+
252
+ # caching and reusing the image produced with the downloaded tools.
275
+ moder = gpio_readl(GPIO_C, MODER);
253
+ # Not sure why.
276
+ odr = gpio_readl(GPIO_C, ODR);
254
+ # TODO: how do you get 'docker build' to print the output of the
277
+ otyper = gpio_readl(GPIO_C, OTYPER);
255
+ # commands it is running to its stdout? This would be useful for debug.
278
+ pupdr = gpio_readl(GPIO_C, PUPDR);
256
+ DOCKER_BUILDKIT=1 docker build -t coverity-scanner \
279
+ idr = gpio_readl(GPIO_C, IDR);
257
+ --secret id=coverity.token,src="$SECRET" \
280
+ /* Analog, same as Input mode*/
258
+ -f scripts/coverity-scan/coverity-scan.docker \
281
+ g_assert_cmphex(moder, ==, reset(GPIO_C, MODER));
259
+ scripts/coverity-scan
282
+ g_assert_cmphex(odr, ==, reset(GPIO_C, ODR));
260
+ echo "Archiving sources to be analyzed..."
283
+ g_assert_cmphex(otyper, ==, reset(GPIO_C, OTYPER));
261
+ ./scripts/archive-source.sh "$SECRETDIR/qemu-sources.tgz"
284
+ /* no pull-up or pull-down */
262
+ if [ "$DRYRUN" = yes ]; then
285
+ g_assert_cmphex(pupdr, ==, reset(GPIO_C, PUPDR));
263
+ DRYRUNARG=--dry-run
286
+ /* reset value */
264
+ fi
287
+ g_assert_cmphex(idr, ==, reset(GPIO_C, IDR));
265
+ echo "Running scanner..."
288
+
266
+ # If we need to capture the output tarball, get the inner run to
289
+ moder = gpio_readl(GPIO_H, MODER);
267
+ # save it to the secrets directory so we can copy it out before the
290
+ odr = gpio_readl(GPIO_H, ODR);
268
+ # directory is cleaned up.
291
+ otyper = gpio_readl(GPIO_H, OTYPER);
269
+ if [ ! -z "$RESULTSTARBALL" ]; then
292
+ pupdr = gpio_readl(GPIO_H, PUPDR);
270
+ RTARGS="--results-tarball /work/cov-int.tar.xz"
293
+ idr = gpio_readl(GPIO_H, IDR);
271
+ else
294
+ /* Analog, same as Input mode */
272
+ RTARGS=""
295
+ g_assert_cmphex(moder, ==, reset(GPIO_H, MODER));
273
+ fi
296
+ g_assert_cmphex(odr, ==, reset(GPIO_H, ODR));
274
+ # Arrange for this docker run to get access to the sources with -v.
297
+ g_assert_cmphex(otyper, ==, reset(GPIO_H, OTYPER));
275
+ # We pass through all the configuration from the outer script to the inner.
298
+ /* no pull-up or pull-down */
276
+ export COVERITY_EMAIL COVERITY_BUILD_CMD
299
+ g_assert_cmphex(pupdr, ==, reset(GPIO_H, PUPDR));
277
+ docker run -it --env COVERITY_EMAIL --env COVERITY_BUILD_CMD \
300
+ /* reset value */
278
+ -v "$SECRETDIR:/work" coverity-scanner \
301
+ g_assert_cmphex(idr, ==, reset(GPIO_H, IDR));
279
+ ./run-coverity-scan --version "$VERSION" \
302
+}
280
+ --description "$DESCRIPTION" $DRYRUNARG --tokenfile /work/token \
303
+
281
+ --srcdir /qemu --src-tarball /work/qemu-sources.tgz $RTARGS
304
+static void test_gpio_output_mode(const void *data)
282
+ if [ ! -z "$RESULTSTARBALL" ]; then
305
+{
283
+ echo "Copying results tarball to $RESULTSTARBALL..."
306
+ /*
284
+ cp "$SECRETDIR/cov-int.tar.xz" "$RESULTSTARBALL"
307
+ * Checks that setting a bit in ODR sets the corresponding
285
+ fi
308
+ * GPIO line high : it should set the right bit in IDR
286
+ echo "Docker work complete."
309
+ * and send an irq to syscfg.
287
+ exit 0
310
+ * Additionally, it checks that values written to ODR
288
+fi
311
+ * when not in output mode are stored and not discarded.
289
+
312
+ */
290
+# Otherwise, continue with the full build and upload process.
313
+ unsigned int pin = ((uint64_t)data) & 0xF;
291
+
314
+ uint32_t gpio = ((uint64_t)data) >> 32;
292
check_upload_permissions
315
+ unsigned int gpio_id = get_gpio_id(gpio);
293
316
+
294
update_coverity_tools
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
+}
593
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
594
index XXXXXXX..XXXXXXX 100644
595
--- a/tests/qtest/meson.build
596
+++ b/tests/qtest/meson.build
597
@@ -XXX,XX +XXX,XX @@ qtests_aspeed = \
598
qtests_stm32l4x5 = \
599
['stm32l4x5_exti-test',
600
'stm32l4x5_syscfg-test',
601
- 'stm32l4x5_rcc-test']
602
+ 'stm32l4x5_rcc-test',
603
+ 'stm32l4x5_gpio-test']
604
605
qtests_arm = \
606
(config_all_devices.has_key('CONFIG_MPS2') ? ['sse-timer-test'] : []) + \
295
--
607
--
296
2.20.1
608
2.34.1
297
609
298
610
diff view generated by jsdifflib
New patch
1
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
While the 8-bit input elements are sequential in the input vector,
4
the 32-bit output elements are not sequential in the output matrix.
5
Do not attempt to compute 2 32-bit outputs at the same time.
6
7
Cc: qemu-stable@nongnu.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
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
target/arm/tcg/sme_helper.c | 77 ++++++++++++++++++-------------
16
tests/tcg/aarch64/sme-smopa-1.c | 47 +++++++++++++++++++
17
tests/tcg/aarch64/sme-smopa-2.c | 54 ++++++++++++++++++++++
18
tests/tcg/aarch64/Makefile.target | 2 +-
19
4 files changed, 147 insertions(+), 33 deletions(-)
20
create mode 100644 tests/tcg/aarch64/sme-smopa-1.c
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
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/tcg/sme_helper.c
26
+++ b/target/arm/tcg/sme_helper.c
27
@@ -XXX,XX +XXX,XX @@ void HELPER(sme_bfmopa)(void *vza, void *vzn, void *vzm, void *vpn,
28
}
29
}
30
31
-typedef uint64_t IMOPFn(uint64_t, uint64_t, uint64_t, uint8_t, bool);
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)
61
{
62
intptr_t row, col, oprsz = simd_oprsz(desc) / 8;
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,
65
}
66
67
#define DEF_IMOP_32(NAME, NTYPE, MTYPE) \
68
-static uint64_t NAME(uint64_t n, uint64_t m, uint64_t a, uint8_t p, bool neg) \
69
+static uint32_t NAME(uint32_t n, uint32_t m, uint32_t a, uint8_t p, bool neg) \
70
{ \
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; \
94
}
95
96
#define DEF_IMOP_64(NAME, NTYPE, MTYPE) \
97
@@ -XXX,XX +XXX,XX @@ DEF_IMOP_64(umopa_d, uint16_t, uint16_t)
98
DEF_IMOP_64(sumopa_d, int16_t, uint16_t)
99
DEF_IMOP_64(usmopa_d, uint16_t, int16_t)
100
101
-#define DEF_IMOPH(NAME) \
102
- void HELPER(sme_##NAME)(void *vza, void *vzn, void *vzm, void *vpn, \
103
- void *vpm, uint32_t desc) \
104
- { do_imopa(vza, vzn, vzm, vpn, vpm, desc, NAME); }
105
+#define DEF_IMOPH(NAME, S) \
106
+ void HELPER(sme_##NAME##_##S)(void *vza, void *vzn, void *vzm, \
107
+ void *vpn, void *vpm, uint32_t desc) \
108
+ { do_imopa_##S(vza, vzn, vzm, vpn, vpm, desc, NAME##_##S); }
109
110
-DEF_IMOPH(smopa_s)
111
-DEF_IMOPH(umopa_s)
112
-DEF_IMOPH(sumopa_s)
113
-DEF_IMOPH(usmopa_s)
114
-DEF_IMOPH(smopa_d)
115
-DEF_IMOPH(umopa_d)
116
-DEF_IMOPH(sumopa_d)
117
-DEF_IMOPH(usmopa_d)
118
+DEF_IMOPH(smopa, s)
119
+DEF_IMOPH(umopa, s)
120
+DEF_IMOPH(sumopa, s)
121
+DEF_IMOPH(usmopa, s)
122
+
123
+DEF_IMOPH(smopa, d)
124
+DEF_IMOPH(umopa, d)
125
+DEF_IMOPH(sumopa, d)
126
+DEF_IMOPH(usmopa, d)
127
diff --git a/tests/tcg/aarch64/sme-smopa-1.c b/tests/tcg/aarch64/sme-smopa-1.c
128
new file mode 100644
129
index XXXXXXX..XXXXXXX
130
--- /dev/null
131
+++ b/tests/tcg/aarch64/sme-smopa-1.c
132
@@ -XXX,XX +XXX,XX @@
133
+#include <stdio.h>
134
+#include <string.h>
135
+
136
+int main()
137
+{
138
+ static const int cmp[4][4] = {
139
+ { 110, 134, 158, 182 },
140
+ { 390, 478, 566, 654 },
141
+ { 670, 822, 974, 1126 },
142
+ { 950, 1166, 1382, 1598 }
143
+ };
144
+ int dst[4][4];
145
+ int *tmp = &dst[0][0];
146
+
147
+ asm volatile(
148
+ ".arch armv8-r+sme\n\t"
149
+ "smstart\n\t"
150
+ "index z0.b, #0, #1\n\t"
151
+ "movprfx z1, z0\n\t"
152
+ "add z1.b, z1.b, #16\n\t"
153
+ "ptrue p0.b\n\t"
154
+ "smopa za0.s, p0/m, p0/m, z0.b, z1.b\n\t"
155
+ "ptrue p0.s, vl4\n\t"
156
+ "mov w12, #0\n\t"
157
+ "st1w { za0h.s[w12, #0] }, p0, [%0]\n\t"
158
+ "add %0, %0, #16\n\t"
159
+ "st1w { za0h.s[w12, #1] }, p0, [%0]\n\t"
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
241
index XXXXXXX..XXXXXXX 100644
242
--- a/tests/tcg/aarch64/Makefile.target
243
+++ b/tests/tcg/aarch64/Makefile.target
244
@@ -XXX,XX +XXX,XX @@ endif
245
246
# SME Tests
247
ifneq ($(CROSS_AS_HAS_ARMV9_SME),)
248
-AARCH64_TESTS += sme-outprod1
249
+AARCH64_TESTS += sme-outprod1 sme-smopa-1 sme-smopa-2
250
endif
251
252
# System Registers Tests
253
--
254
2.34.1
255
256
diff view generated by jsdifflib
1
The documentation of our -s and -gdb options is quite old; in
1
The sun4v RTC device model added under commit a0e893039cf2ce0 in 2016
2
particular it still claims that it will cause QEMU to stop and wait
2
was unfortunately added with a license of GPL-v3-or-later, which is
3
for the gdb connection, when this has not been true for some time:
3
not compatible with other QEMU code which has a GPL-v2-only license.
4
you also need to pass -S if you want to make QEMU not launch the
5
guest on startup.
6
4
7
Improve the documentation to mention this requirement in the
5
Relicense the code in the .c and the .h file to GPL-v2-or-later,
8
executable's --help output, the documentation of the -gdb option in
6
to make it compatible with the rest of QEMU.
9
the manual, and in the "GDB usage" chapter.
10
7
11
Includes some minor tweaks to these paragraphs of documentation
8
Cc: qemu-stable@nongnu.org
12
since I was editing them anyway (such as dropping the description
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
of our gdb support as "primitive").
10
Signed-off-by: Paolo Bonzini (for Red Hat) <pbonzini@redhat.com>
11
Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
12
Signed-off-by: Markus Armbruster <armbru@redhat.com>
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
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
20
include/hw/rtc/sun4v-rtc.h | 2 +-
21
hw/rtc/sun4v-rtc.c | 2 +-
22
2 files changed, 2 insertions(+), 2 deletions(-)
14
23
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
diff --git a/include/hw/rtc/sun4v-rtc.h b/include/hw/rtc/sun4v-rtc.h
16
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
19
Message-id: 20200403094014.9589-1-peter.maydell@linaro.org
20
---
21
docs/system/gdb.rst | 22 +++++++++++++++-------
22
qemu-options.hx | 24 ++++++++++++++++++------
23
2 files changed, 33 insertions(+), 13 deletions(-)
24
25
diff --git a/docs/system/gdb.rst b/docs/system/gdb.rst
26
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
27
--- a/docs/system/gdb.rst
26
--- a/include/hw/rtc/sun4v-rtc.h
28
+++ b/docs/system/gdb.rst
27
+++ b/include/hw/rtc/sun4v-rtc.h
29
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@
30
GDB usage
29
*
31
---------
30
* Copyright (c) 2016 Artyom Tarasenko
32
31
*
33
-QEMU has a primitive support to work with gdb, so that you can do
32
- * This code is licensed under the GNU GPL v3 or (at your option) any later
34
-'Ctrl-C' while the virtual machine is running and inspect its state.
33
+ * This code is licensed under the GNU GPL v2 or (at your option) any later
35
+QEMU supports working with gdb via gdb's remote-connection facility
34
* version.
36
+(the "gdbstub"). This allows you to debug guest code in the same
35
*/
37
+way that you might with a low-level debug facility like JTAG
36
38
+on real hardware. You can stop and start the virtual machine,
37
diff --git a/hw/rtc/sun4v-rtc.c b/hw/rtc/sun4v-rtc.c
39
+examine state like registers and memory, and set breakpoints and
40
+watchpoints.
41
42
-In order to use gdb, launch QEMU with the '-s' option. It will wait for
43
-a gdb connection:
44
+In order to use gdb, launch QEMU with the ``-s`` and ``-S`` options.
45
+The ``-s`` option will make QEMU listen for an incoming connection
46
+from gdb on TCP port 1234, and ``-S`` will make QEMU not start the
47
+guest until you tell it to from gdb. (If you want to specify which
48
+TCP port to use or to use something other than TCP for the gdbstub
49
+connection, use the ``-gdb dev`` option instead of ``-s``.)
50
51
.. parsed-literal::
52
53
- |qemu_system| -s -kernel bzImage -hda rootdisk.img -append "root=/dev/hda"
54
- Connected to host network interface: tun0
55
- Waiting gdb connection on port 1234
56
+ |qemu_system| -s -S -kernel bzImage -hda rootdisk.img -append "root=/dev/hda"
57
+
58
+QEMU will launch but will silently wait for gdb to connect.
59
60
Then launch gdb on the 'vmlinux' executable::
61
62
diff --git a/qemu-options.hx b/qemu-options.hx
63
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
64
--- a/qemu-options.hx
39
--- a/hw/rtc/sun4v-rtc.c
65
+++ b/qemu-options.hx
40
+++ b/hw/rtc/sun4v-rtc.c
66
@@ -XXX,XX +XXX,XX @@ SRST
41
@@ -XXX,XX +XXX,XX @@
67
ERST
42
*
68
43
* Copyright (c) 2016 Artyom Tarasenko
69
DEF("gdb", HAS_ARG, QEMU_OPTION_gdb, \
44
*
70
- "-gdb dev wait for gdb connection on 'dev'\n", QEMU_ARCH_ALL)
45
- * This code is licensed under the GNU GPL v3 or (at your option) any later
71
+ "-gdb dev accept gdb connection on 'dev'. (QEMU defaults to starting\n"
46
+ * This code is licensed under the GNU GPL v2 or (at your option) any later
72
+ " the guest without waiting for gdb to connect; use -S too\n"
47
* version.
73
+ " if you want it to not start execution.)\n",
48
*/
74
+ QEMU_ARCH_ALL)
75
SRST
76
``-gdb dev``
77
- Wait for gdb connection on device dev (see
78
- :ref:`gdb_005fusage`). Typical connections will likely be
79
- TCP-based, but also UDP, pseudo TTY, or even stdio are reasonable
80
- use case. The latter is allowing to start QEMU from within gdb and
81
- establish the connection via a pipe:
82
+ Accept a gdb connection on device dev (see
83
+ :ref:`gdb_005fusage`). Note that this option does not pause QEMU
84
+ execution -- if you want QEMU to not start the guest until you
85
+ connect with gdb and issue a ``continue`` command, you will need to
86
+ also pass the ``-S`` option to QEMU.
87
+
88
+ The most usual configuration is to listen on a local TCP socket::
89
+
90
+ -gdb tcp::3117
91
+
92
+ but you can specify other backends; UDP, pseudo TTY, or even stdio
93
+ are all reasonable use cases. For example, a stdio connection
94
+ allows you to start QEMU from within gdb and establish the
95
+ connection via a pipe:
96
97
.. parsed-literal::
98
49
99
--
50
--
100
2.20.1
51
2.34.1
101
52
102
53
diff view generated by jsdifflib
1
In commit a1a98357e3fd in 2018 we added some workarounds for Coverity
1
From: Thomas Huth <thuth@redhat.com>
2
not being able to handle the _Float* types introduced by recent
3
glibc. Newer versions of the Coverity scan tools have support for
4
these types, and will fail with errors about duplicate typedefs if we
5
have our workaround. Remove our copy of the typedefs.
6
2
3
Move the code to a separate file so that we do not have to compile
4
it anymore if CONFIG_ARM_V7M is not set.
5
6
Signed-off-by: Thomas Huth <thuth@redhat.com>
7
Message-id: 20240308141051.536599-2-thuth@redhat.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200319193323.2038-2-peter.maydell@linaro.org
10
---
10
---
11
include/qemu/osdep.h | 14 --------------
11
target/arm/tcg/cpu-v7m.c | 290 +++++++++++++++++++++++++++++++++++++
12
1 file changed, 14 deletions(-)
12
target/arm/tcg/cpu32.c | 261 ---------------------------------
13
target/arm/meson.build | 3 +
14
target/arm/tcg/meson.build | 3 +
15
4 files changed, 296 insertions(+), 261 deletions(-)
16
create mode 100644 target/arm/tcg/cpu-v7m.c
13
17
14
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.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
15
index XXXXXXX..XXXXXXX 100644
315
index XXXXXXX..XXXXXXX 100644
16
--- a/include/qemu/osdep.h
316
--- a/target/arm/tcg/cpu32.c
17
+++ b/include/qemu/osdep.h
317
+++ b/target/arm/tcg/cpu32.c
18
@@ -XXX,XX +XXX,XX @@
318
@@ -XXX,XX +XXX,XX @@
19
#else
319
#include "hw/boards.h"
20
#include "exec/poison.h"
21
#endif
320
#endif
22
-#ifdef __COVERITY__
321
#include "cpregs.h"
23
-/* Coverity does not like the new _Float* types that are used by
322
-#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG)
24
- * recent glibc, and croaks on every single file that includes
323
-#include "hw/intc/armv7m_nvic.h"
25
- * stdlib.h. These typedefs are enough to please it.
26
- *
27
- * Note that these fix parse errors so they cannot be placed in
28
- * scripts/coverity-model.c.
29
- */
30
-typedef float _Float32;
31
-typedef double _Float32x;
32
-typedef double _Float64;
33
-typedef __float80 _Float64x;
34
-typedef __float128 _Float128;
35
-#endif
324
-#endif
36
325
37
#include "qemu/compiler.h"
326
38
327
/* Share AArch32 -cpu max features with AArch64. */
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
615
index XXXXXXX..XXXXXXX 100644
616
--- a/target/arm/meson.build
617
+++ b/target/arm/meson.build
618
@@ -XXX,XX +XXX,XX @@ arm_system_ss.add(files(
619
'ptw.c',
620
))
621
622
+arm_user_ss = ss.source_set()
623
+
624
subdir('hvf')
625
626
if 'CONFIG_TCG' in config_all_accel
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'))
39
--
643
--
40
2.20.1
644
2.34.1
41
42
diff view generated by jsdifflib