1
Latest arm queue, a mixed bag of features and bug fixes.
1
The following changes since commit 8f6330a807f2642dc2a3cdf33347aa28a4c00a87:
2
2
3
thanks
3
Merge tag 'pull-maintainer-updates-060324-1' of https://gitlab.com/stsquad/qemu into staging (2024-03-06 16:56:20 +0000)
4
-- PMM
5
6
The following changes since commit cbf01142b2aef0c0b4e995cecd7e79d342bbc47e:
7
8
Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20200115' into staging (2020-01-17 12:13:17 +0000)
9
4
10
are available in the Git repository at:
5
are available in the Git repository at:
11
6
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200117-1
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240308
13
8
14
for you to fetch changes up to 1a1fbc6cbb34c26d43d8360c66c1d21681af14a9:
9
for you to fetch changes up to bbf6c6dbead82292a20951eb1204442a6b838de9:
15
10
16
target/arm: Set ISSIs16Bit in make_issinfo (2020-01-17 14:27:16 +0000)
11
target/arm: Move v7m-related code from cpu32.c into a separate file (2024-03-08 14:45:03 +0000)
17
12
18
----------------------------------------------------------------
13
----------------------------------------------------------------
19
Add model of the Netduino Plus 2 board
14
target-arm queue:
20
Some allwinner-a10 code cleanup
15
* Implement FEAT_ECV
21
New test cases for cubieboard
16
* STM32L4x5: Implement GPIO device
22
target/arm/arm-semi: fix SYS_OPEN to return nonzero filehandle
17
* Fix 32-bit SMOPA
23
i.MX: add an emulation for RNGC device
18
* Refactor v7m related code from cpu32.c into its own file
24
target/arm: adjust program counter for wfi exception in AArch32
19
* hw/rtc/sun4v-rtc: Relicense to GPLv2-or-later
25
arm/gicv3: update virtual irq state after IAR register read
26
Set IL bit correctly for syndrome information for data aborts
27
20
28
----------------------------------------------------------------
21
----------------------------------------------------------------
29
Alistair Francis (4):
22
Inès Varhol (3):
30
hw/misc: Add the STM32F4xx Sysconfig device
23
hw/gpio: Implement STM32L4x5 GPIO
31
hw/misc: Add the STM32F4xx EXTI device
24
hw/arm: Connect STM32L4x5 GPIO to STM32L4x5 SoC
32
hw/arm: Add the STM32F4xx SoC
25
tests/qtest: Add STM32L4x5 GPIO QTest testcase
33
hw/arm: Add the Netduino Plus 2
34
26
35
Jeff Kubascik (3):
27
Peter Maydell (9):
36
target/arm: adjust program counter for wfi exception in AArch32
28
target/arm: Move some register related defines to internals.h
37
arm/gicv3: update virtual irq state after IAR register read
29
target/arm: Timer _EL02 registers UNDEF for E2H == 0
38
target/arm: Return correct IL bit in merge_syn_data_abort
30
target/arm: use FIELD macro for CNTHCTL bit definitions
39
31
target/arm: Don't allow RES0 CNTHCTL_EL2 bits to be written
40
Martin Kaiser (1):
32
target/arm: Implement new FEAT_ECV trap bits
41
i.MX: add an emulation for RNGC
33
target/arm: Define CNTPCTSS_EL0 and CNTVCTSS_EL0
42
34
target/arm: Implement FEAT_ECV CNTPOFF_EL2 handling
43
Masahiro Yamada (1):
35
target/arm: Enable FEAT_ECV for 'max' CPU
44
target/arm/arm-semi: fix SYS_OPEN to return nonzero filehandle
36
hw/rtc/sun4v-rtc: Relicense to GPLv2-or-later
45
46
Philippe Mathieu-Daudé (5):
47
tests/boot_linux_console: Add initrd test for the CubieBoard
48
tests/boot_linux_console: Add a SD card test for the CubieBoard
49
hw/arm/allwinner-a10: Move SoC definitions out of header
50
hw/arm/allwinner-a10: Simplify by passing IRQs with qdev_pass_gpios()
51
hw/arm/allwinner-a10: Remove local qemu_irq variables
52
37
53
Richard Henderson (1):
38
Richard Henderson (1):
54
target/arm: Set ISSIs16Bit in make_issinfo
39
target/arm: Fix 32-bit SMOPA
55
40
56
hw/arm/Makefile.objs | 2 +
41
Thomas Huth (1):
57
hw/misc/Makefile.objs | 3 +
42
target/arm: Move v7m-related code from cpu32.c into a separate file
58
include/hw/arm/allwinner-a10.h | 7 -
59
include/hw/arm/fsl-imx25.h | 5 +
60
include/hw/arm/stm32f405_soc.h | 73 ++++++++
61
include/hw/misc/imx_rngc.h | 35 ++++
62
include/hw/misc/stm32f4xx_exti.h | 60 +++++++
63
include/hw/misc/stm32f4xx_syscfg.h | 61 +++++++
64
hw/arm/allwinner-a10.c | 39 +++--
65
hw/arm/fsl-imx25.c | 11 ++
66
hw/arm/netduinoplus2.c | 52 ++++++
67
hw/arm/stm32f405_soc.c | 302 +++++++++++++++++++++++++++++++++
68
hw/intc/arm_gicv3_cpuif.c | 3 +
69
hw/misc/imx_rngc.c | 278 ++++++++++++++++++++++++++++++
70
hw/misc/stm32f4xx_exti.c | 188 ++++++++++++++++++++
71
hw/misc/stm32f4xx_syscfg.c | 171 +++++++++++++++++++
72
target/arm/arm-semi.c | 5 +-
73
target/arm/op_helper.c | 7 +-
74
target/arm/tlb_helper.c | 2 +-
75
target/arm/translate.c | 3 +
76
MAINTAINERS | 14 ++
77
default-configs/arm-softmmu.mak | 1 +
78
hw/arm/Kconfig | 10 ++
79
hw/misc/Kconfig | 6 +
80
hw/misc/trace-events | 11 ++
81
tests/acceptance/boot_linux_console.py | 85 ++++++++++
82
26 files changed, 1405 insertions(+), 29 deletions(-)
83
create mode 100644 include/hw/arm/stm32f405_soc.h
84
create mode 100644 include/hw/misc/imx_rngc.h
85
create mode 100644 include/hw/misc/stm32f4xx_exti.h
86
create mode 100644 include/hw/misc/stm32f4xx_syscfg.h
87
create mode 100644 hw/arm/netduinoplus2.c
88
create mode 100644 hw/arm/stm32f405_soc.c
89
create mode 100644 hw/misc/imx_rngc.c
90
create mode 100644 hw/misc/stm32f4xx_exti.c
91
create mode 100644 hw/misc/stm32f4xx_syscfg.c
92
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
From: Jeff Kubascik <jeff.kubascik@dornerworks.com>
1
cpu.h has a lot of #defines relating to CPU register fields.
2
Most of these aren't actually used outside target/arm code,
3
so there's no point in cluttering up the cpu.h file with them.
4
Move some easy ones to internals.h.
2
5
3
The IAR0/IAR1 register is used to acknowledge an interrupt - a read of the
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
register activates the highest priority pending interrupt and provides its
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
interrupt ID. Activating an interrupt can change the CPU's virtual interrupt
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
state - this change makes sure the virtual irq state is updated.
9
Message-id: 20240301183219.2424889-2-peter.maydell@linaro.org
10
---
11
target/arm/cpu.h | 128 -----------------------------------------
12
target/arm/internals.h | 128 +++++++++++++++++++++++++++++++++++++++++
13
2 files changed, 128 insertions(+), 128 deletions(-)
7
14
8
Signed-off-by: Jeff Kubascik <jeff.kubascik@dornerworks.com>
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Message-id: 20200113154607.97032-1-jeff.kubascik@dornerworks.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/intc/arm_gicv3_cpuif.c | 3 +++
14
1 file changed, 3 insertions(+)
15
16
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/intc/arm_gicv3_cpuif.c
17
--- a/target/arm/cpu.h
19
+++ b/hw/intc/arm_gicv3_cpuif.c
18
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ static uint64_t icv_iar_read(CPUARMState *env, const ARMCPRegInfo *ri)
19
@@ -XXX,XX +XXX,XX @@ typedef struct ARMGenericTimer {
21
20
uint64_t ctl; /* Timer Control register */
22
trace_gicv3_icv_iar_read(ri->crm == 8 ? 0 : 1,
21
} ARMGenericTimer;
23
gicv3_redist_affid(cs), intid);
22
24
+
23
-#define VTCR_NSW (1u << 29)
25
+ gicv3_cpuif_virt_update(cs);
24
-#define VTCR_NSA (1u << 30)
26
+
25
-#define VSTCR_SW VTCR_NSW
27
return intid;
26
-#define VSTCR_SA VTCR_NSA
28
}
27
-
29
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
30
--
321
--
31
2.20.1
322
2.34.1
32
323
33
324
diff view generated by jsdifflib
1
From: Jeff Kubascik <jeff.kubascik@dornerworks.com>
1
The timer _EL02 registers should UNDEF for invalid accesses from EL2
2
or EL3 when HCR_EL2.E2H == 0, not take a cp access trap. We were
3
delivering the exception to EL2 with the wrong syndrome.
2
4
3
The IL bit is set for 32-bit instructions, thus passing false
4
with the is_16bit parameter to syn_data_abort_with_iss() makes
5
a syn mask that always has the IL bit set.
6
7
Pass is_16bit as true to make the initial syn mask have IL=0,
8
so that the final IL value comes from or'ing template_syn.
9
10
Cc: qemu-stable@nongnu.org
11
Fixes: aaa1f954d4ca ("target-arm: A64: Create Instruction Syndromes for Data Aborts")
12
Signed-off-by: Jeff Kubascik <jeff.kubascik@dornerworks.com>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20200117004618.2742-2-richard.henderson@linaro.org
15
[rth: Extracted this as a self-contained bug fix from a larger patch]
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20240301183219.2424889-3-peter.maydell@linaro.org
19
---
8
---
20
target/arm/tlb_helper.c | 2 +-
9
target/arm/helper.c | 2 +-
21
1 file changed, 1 insertion(+), 1 deletion(-)
10
1 file changed, 1 insertion(+), 1 deletion(-)
22
11
23
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
24
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/tlb_helper.c
14
--- a/target/arm/helper.c
26
+++ b/target/arm/tlb_helper.c
15
+++ b/target/arm/helper.c
27
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
16
@@ -XXX,XX +XXX,XX @@ static CPAccessResult e2h_access(CPUARMState *env, const ARMCPRegInfo *ri,
28
syn = syn_data_abort_with_iss(same_el,
17
return CP_ACCESS_OK;
29
0, 0, 0, 0, 0,
30
ea, 0, s1ptw, is_write, fsc,
31
- false);
32
+ true);
33
/* Merge the runtime syndrome with the template syndrome. */
34
syn |= template_syn;
35
}
18
}
19
if (!(arm_hcr_el2_eff(env) & HCR_E2H)) {
20
- return CP_ACCESS_TRAP;
21
+ return CP_ACCESS_TRAP_UNCATEGORIZED;
22
}
23
return CP_ACCESS_OK;
24
}
36
--
25
--
37
2.20.1
26
2.34.1
38
39
diff view generated by jsdifflib
1
From: Jeff Kubascik <jeff.kubascik@dornerworks.com>
1
We prefer the FIELD macro over ad-hoc #defines for register bits;
2
switch CNTHCTL to that style before we add any more bits.
2
3
3
The wfi instruction can be configured to be trapped by a higher exception
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
level, such as the EL2 hypervisor. When the instruction is trapped, the
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
program counter should contain the address of the wfi instruction that
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
caused the exception. The program counter is adjusted for this in the wfi op
7
Message-id: 20240301183219.2424889-4-peter.maydell@linaro.org
7
helper function.
8
---
9
target/arm/internals.h | 27 +++++++++++++++++++++++++--
10
target/arm/helper.c | 9 ++++-----
11
2 files changed, 29 insertions(+), 7 deletions(-)
8
12
9
However, this correction is done to env->pc, which only applies to AArch64
13
diff --git a/target/arm/internals.h b/target/arm/internals.h
10
mode. For AArch32, the program counter is stored in env->regs[15]. This
11
adds an if-else statement to modify the correct program counter location
12
based on the the current CPU mode.
13
14
Signed-off-by: Jeff Kubascik <jeff.kubascik@dornerworks.com>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
target/arm/op_helper.c | 7 ++++++-
19
1 file changed, 6 insertions(+), 1 deletion(-)
20
21
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
22
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/op_helper.c
15
--- a/target/arm/internals.h
24
+++ b/target/arm/op_helper.c
16
+++ b/target/arm/internals.h
25
@@ -XXX,XX +XXX,XX @@ void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
17
@@ -XXX,XX +XXX,XX @@ FIELD(VTCR, SL2, 33, 1)
18
#define HSTR_TTEE (1 << 16)
19
#define HSTR_TJDBX (1 << 17)
20
21
-#define CNTHCTL_CNTVMASK (1 << 18)
22
-#define CNTHCTL_CNTPMASK (1 << 19)
23
+/*
24
+ * Depending on the value of HCR_EL2.E2H, bits 0 and 1
25
+ * have different bit definitions, and EL1PCTEN might be
26
+ * bit 0 or bit 10. We use _E2H1 and _E2H0 suffixes to
27
+ * disambiguate if necessary.
28
+ */
29
+FIELD(CNTHCTL, EL0PCTEN_E2H1, 0, 1)
30
+FIELD(CNTHCTL, EL0VCTEN_E2H1, 1, 1)
31
+FIELD(CNTHCTL, EL1PCTEN_E2H0, 0, 1)
32
+FIELD(CNTHCTL, EL1PCEN_E2H0, 1, 1)
33
+FIELD(CNTHCTL, EVNTEN, 2, 1)
34
+FIELD(CNTHCTL, EVNTDIR, 3, 1)
35
+FIELD(CNTHCTL, EVNTI, 4, 4)
36
+FIELD(CNTHCTL, EL0VTEN, 8, 1)
37
+FIELD(CNTHCTL, EL0PTEN, 9, 1)
38
+FIELD(CNTHCTL, EL1PCTEN_E2H1, 10, 1)
39
+FIELD(CNTHCTL, EL1PTEN, 11, 1)
40
+FIELD(CNTHCTL, ECV, 12, 1)
41
+FIELD(CNTHCTL, EL1TVT, 13, 1)
42
+FIELD(CNTHCTL, EL1TVCT, 14, 1)
43
+FIELD(CNTHCTL, EL1NVPCT, 15, 1)
44
+FIELD(CNTHCTL, EL1NVVCT, 16, 1)
45
+FIELD(CNTHCTL, EVNTIS, 17, 1)
46
+FIELD(CNTHCTL, CNTVMASK, 18, 1)
47
+FIELD(CNTHCTL, CNTPMASK, 19, 1)
48
49
/* We use a few fake FSR values for internal purposes in M profile.
50
* M profile cores don't have A/R format FSRs, but currently our
51
diff --git a/target/arm/helper.c b/target/arm/helper.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/helper.c
54
+++ b/target/arm/helper.c
55
@@ -XXX,XX +XXX,XX @@ static void gt_update_irq(ARMCPU *cpu, int timeridx)
56
* It is RES0 in Secure and NonSecure state.
57
*/
58
if ((ss == ARMSS_Root || ss == ARMSS_Realm) &&
59
- ((timeridx == GTIMER_VIRT && (cnthctl & CNTHCTL_CNTVMASK)) ||
60
- (timeridx == GTIMER_PHYS && (cnthctl & CNTHCTL_CNTPMASK)))) {
61
+ ((timeridx == GTIMER_VIRT && (cnthctl & R_CNTHCTL_CNTVMASK_MASK)) ||
62
+ (timeridx == GTIMER_PHYS && (cnthctl & R_CNTHCTL_CNTPMASK_MASK)))) {
63
irqstate = 0;
26
}
64
}
27
65
28
if (target_el) {
66
@@ -XXX,XX +XXX,XX @@ static void gt_cnthctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
29
- env->pc -= insn_len;
67
{
30
+ if (env->aarch64) {
68
ARMCPU *cpu = env_archcpu(env);
31
+ env->pc -= insn_len;
69
uint32_t oldval = env->cp15.cnthctl_el2;
32
+ } else {
70
-
33
+ env->regs[15] -= insn_len;
71
raw_write(env, ri, value);
34
+ }
72
35
+
73
- if ((oldval ^ value) & CNTHCTL_CNTVMASK) {
36
raise_exception(env, EXCP_UDEF, syn_wfx(1, 0xe, 0, insn_len == 2),
74
+ if ((oldval ^ value) & R_CNTHCTL_CNTVMASK_MASK) {
37
target_el);
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);
38
}
79
}
80
}
39
--
81
--
40
2.20.1
82
2.34.1
41
83
42
84
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
Don't allow the guest to write CNTHCTL_EL2 bits which don't exist.
2
This is not strictly architecturally required, but it is how we've
3
tended to implement registers more recently.
2
4
3
We won't reuse the CPU IRQ/FIQ variables. Simplify by calling
5
In particular, bits [19:18] are only present with FEAT_RME,
4
qdev_get_gpio_in() in place.
6
and bits [17:12] will only be present with FEAT_ECV.
5
7
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20191230110953.25496-6-f4bug@amsat.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20240301183219.2424889-5-peter.maydell@linaro.org
10
---
11
---
11
hw/arm/allwinner-a10.c | 9 ++++-----
12
target/arm/helper.c | 18 ++++++++++++++++++
12
1 file changed, 4 insertions(+), 5 deletions(-)
13
1 file changed, 18 insertions(+)
13
14
14
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/allwinner-a10.c
17
--- a/target/arm/helper.c
17
+++ b/hw/arm/allwinner-a10.c
18
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
19
@@ -XXX,XX +XXX,XX @@ static void gt_cnthctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
19
{
20
{
20
AwA10State *s = AW_A10(dev);
21
ARMCPU *cpu = env_archcpu(env);
21
SysBusDevice *sysbusdev;
22
uint32_t oldval = env->cp15.cnthctl_el2;
22
- qemu_irq fiq, irq;
23
+ uint32_t valid_mask =
23
Error *err = NULL;
24
+ R_CNTHCTL_EL0PCTEN_E2H1_MASK |
24
25
+ R_CNTHCTL_EL0VCTEN_E2H1_MASK |
25
object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);
26
+ R_CNTHCTL_EVNTEN_MASK |
26
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
27
+ R_CNTHCTL_EVNTDIR_MASK |
27
error_propagate(errp, err);
28
+ R_CNTHCTL_EVNTI_MASK |
28
return;
29
+ R_CNTHCTL_EL0VTEN_MASK |
29
}
30
+ R_CNTHCTL_EL0PTEN_MASK |
30
- irq = qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ);
31
+ R_CNTHCTL_EL1PCTEN_E2H1_MASK |
31
- fiq = qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ);
32
+ R_CNTHCTL_EL1PTEN_MASK;
32
33
+
33
object_property_set_bool(OBJECT(&s->intc), true, "realized", &err);
34
+ if (cpu_isar_feature(aa64_rme, cpu)) {
34
if (err != NULL) {
35
+ valid_mask |= R_CNTHCTL_CNTVMASK_MASK | R_CNTHCTL_CNTPMASK_MASK;
35
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
36
+ }
36
}
37
+
37
sysbusdev = SYS_BUS_DEVICE(&s->intc);
38
+ /* Clear RES0 bits */
38
sysbus_mmio_map(sysbusdev, 0, AW_A10_PIC_REG_BASE);
39
+ value &= valid_mask;
39
- sysbus_connect_irq(sysbusdev, 0, irq);
40
+
40
- sysbus_connect_irq(sysbusdev, 1, fiq);
41
raw_write(env, ri, value);
41
+ sysbus_connect_irq(sysbusdev, 0,
42
42
+ qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ));
43
if ((oldval ^ value) & R_CNTHCTL_CNTVMASK_MASK) {
43
+ sysbus_connect_irq(sysbusdev, 1,
44
+ qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ));
45
qdev_pass_gpios(DEVICE(&s->intc), dev, NULL);
46
47
object_property_set_bool(OBJECT(&s->timer), true, "realized", &err);
48
--
44
--
49
2.20.1
45
2.34.1
50
51
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
The functionality defined by ID_AA64MMFR0_EL1.ECV == 1 is:
2
* four new trap bits for various counter and timer registers
3
* the CNTHCTL_EL2.EVNTIS and CNTKCTL_EL1.EVNTIS bits which control
4
scaling of the event stream. This is a no-op for us, because we don't
5
implement the event stream (our WFE is a NOP): all we need to do is
6
allow CNTHCTL_EL2.ENVTIS to be read and written.
7
* extensions to PMSCR_EL1.PCT, PMSCR_EL2.PCT, TRFCR_EL1.TS and
8
TRFCR_EL2.TS: these are all no-ops for us, because we don't implement
9
FEAT_SPE or FEAT_TRF.
10
* new registers CNTPCTSS_EL0 and NCTVCTSS_EL0 which are
11
"self-sychronizing" views of the CNTPCT_EL0 and CNTVCT_EL0, meaning
12
that no barriers are needed around their accesses. For us these
13
are just the same as the normal views, because all our sysregs are
14
inherently self-sychronizing.
2
15
3
By calling qdev_pass_gpios() we don't need to hold a copy of the
16
In this commit we implement the trap handling and permit the new
4
IRQs from the INTC into the SoC state.
17
CNTHCTL_EL2 bits to be written.
5
Instead of filling an array of qemu_irq and passing it around, we
6
can now directly call qdev_get_gpio_in() on the SoC.
7
18
8
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20191230110953.25496-5-f4bug@amsat.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Message-id: 20240301183219.2424889-6-peter.maydell@linaro.org
12
---
22
---
13
include/hw/arm/allwinner-a10.h | 1 -
23
target/arm/cpu-features.h | 5 ++++
14
hw/arm/allwinner-a10.c | 24 +++++++++++-------------
24
target/arm/helper.c | 51 +++++++++++++++++++++++++++++++++++----
15
2 files changed, 11 insertions(+), 14 deletions(-)
25
2 files changed, 51 insertions(+), 5 deletions(-)
16
26
17
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
27
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
18
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/allwinner-a10.h
29
--- a/target/arm/cpu-features.h
20
+++ b/include/hw/arm/allwinner-a10.h
30
+++ b/target/arm/cpu-features.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct AwA10State {
31
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_fgt(const ARMISARegisters *id)
22
/*< public >*/
32
return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, FGT) != 0;
23
33
}
24
ARMCPU cpu;
34
25
- qemu_irq irq[AW_A10_PIC_INT_NR];
35
+static inline bool isar_feature_aa64_ecv_traps(const ARMISARegisters *id)
26
AwA10PITState timer;
36
+{
27
AwA10PICState intc;
37
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, ECV) > 0;
28
AwEmacState emac;
38
+}
29
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
39
+
40
static inline bool isar_feature_aa64_vh(const ARMISARegisters *id)
41
{
42
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0;
43
diff --git a/target/arm/helper.c b/target/arm/helper.c
30
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/allwinner-a10.c
45
--- a/target/arm/helper.c
32
+++ b/hw/arm/allwinner-a10.c
46
+++ b/target/arm/helper.c
33
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
47
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx,
48
: !extract32(env->cp15.cnthctl_el2, 0, 1))) {
49
return CP_ACCESS_TRAP_EL2;
50
}
51
+ if (has_el2 && timeridx == GTIMER_VIRT) {
52
+ if (FIELD_EX64(env->cp15.cnthctl_el2, CNTHCTL, EL1TVCT)) {
53
+ return CP_ACCESS_TRAP_EL2;
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,
34
{
87
{
35
AwA10State *s = AW_A10(dev);
88
if (arm_current_el(env) == 1) {
36
SysBusDevice *sysbusdev;
89
/* This must be a FEAT_NV access */
37
- uint8_t i;
90
- /* TODO: FEAT_ECV will need to check CNTHCTL_EL2 here */
38
qemu_irq fiq, irq;
91
return CP_ACCESS_OK;
39
Error *err = NULL;
40
41
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
42
sysbus_mmio_map(sysbusdev, 0, AW_A10_PIC_REG_BASE);
43
sysbus_connect_irq(sysbusdev, 0, irq);
44
sysbus_connect_irq(sysbusdev, 1, fiq);
45
- for (i = 0; i < AW_A10_PIC_INT_NR; i++) {
46
- s->irq[i] = qdev_get_gpio_in(DEVICE(&s->intc), i);
47
- }
48
+ qdev_pass_gpios(DEVICE(&s->intc), dev, NULL);
49
50
object_property_set_bool(OBJECT(&s->timer), true, "realized", &err);
51
if (err != NULL) {
52
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
53
}
92
}
54
sysbusdev = SYS_BUS_DEVICE(&s->timer);
93
if (!(arm_hcr_el2_eff(env) & HCR_E2H)) {
55
sysbus_mmio_map(sysbusdev, 0, AW_A10_PIT_REG_BASE);
94
@@ -XXX,XX +XXX,XX @@ static CPAccessResult e2h_access(CPUARMState *env, const ARMCPRegInfo *ri,
56
- sysbus_connect_irq(sysbusdev, 0, s->irq[22]);
95
return CP_ACCESS_OK;
57
- sysbus_connect_irq(sysbusdev, 1, s->irq[23]);
58
- sysbus_connect_irq(sysbusdev, 2, s->irq[24]);
59
- sysbus_connect_irq(sysbusdev, 3, s->irq[25]);
60
- sysbus_connect_irq(sysbusdev, 4, s->irq[67]);
61
- sysbus_connect_irq(sysbusdev, 5, s->irq[68]);
62
+ sysbus_connect_irq(sysbusdev, 0, qdev_get_gpio_in(dev, 22));
63
+ sysbus_connect_irq(sysbusdev, 1, qdev_get_gpio_in(dev, 23));
64
+ sysbus_connect_irq(sysbusdev, 2, qdev_get_gpio_in(dev, 24));
65
+ sysbus_connect_irq(sysbusdev, 3, qdev_get_gpio_in(dev, 25));
66
+ sysbus_connect_irq(sysbusdev, 4, qdev_get_gpio_in(dev, 67));
67
+ sysbus_connect_irq(sysbusdev, 5, qdev_get_gpio_in(dev, 68));
68
69
memory_region_init_ram(&s->sram_a, OBJECT(dev), "sram A", 48 * KiB,
70
&error_fatal);
71
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
72
}
73
sysbusdev = SYS_BUS_DEVICE(&s->emac);
74
sysbus_mmio_map(sysbusdev, 0, AW_A10_EMAC_BASE);
75
- sysbus_connect_irq(sysbusdev, 0, s->irq[55]);
76
+ sysbus_connect_irq(sysbusdev, 0, qdev_get_gpio_in(dev, 55));
77
78
object_property_set_bool(OBJECT(&s->sata), true, "realized", &err);
79
if (err) {
80
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
81
return;
82
}
83
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sata), 0, AW_A10_SATA_BASE);
84
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->sata), 0, s->irq[56]);
85
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->sata), 0, qdev_get_gpio_in(dev, 56));
86
87
/* FIXME use a qdev chardev prop instead of serial_hd() */
88
- serial_mm_init(get_system_memory(), AW_A10_UART0_REG_BASE, 2, s->irq[1],
89
+ serial_mm_init(get_system_memory(), AW_A10_UART0_REG_BASE, 2,
90
+ qdev_get_gpio_in(dev, 1),
91
115200, serial_hd(0), DEVICE_NATIVE_ENDIAN);
92
}
96
}
93
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
};
94
--
159
--
95
2.20.1
160
2.34.1
96
97
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
For FEAT_ECV, new registers CNTPCTSS_EL0 and CNTVCTSS_EL0 are
2
defined, which are "self-synchronized" views of the physical and
3
virtual counts as seen in the CNTPCT_EL0 and CNTVCT_EL0 registers
4
(meaning that no barriers are needed around accesses to them to
5
ensure that reads of them do not occur speculatively and out-of-order
6
with other instructions).
2
7
3
These definitions are specific to the A10 SoC and don't need
8
For QEMU, all our system registers are self-synchronized, so we can
4
to be exported to the different Allwinner peripherals.
9
simply copy the existing implementation of CNTPCT_EL0 and CNTVCT_EL0
10
to the new register encodings.
5
11
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
This means we now implement all the functionality required for
7
Message-id: 20191230110953.25496-4-f4bug@amsat.org
13
ID_AA64MMFR0_EL1.ECV == 0b0001.
14
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20240301183219.2424889-7-peter.maydell@linaro.org
10
---
18
---
11
include/hw/arm/allwinner-a10.h | 6 ------
19
target/arm/helper.c | 43 +++++++++++++++++++++++++++++++++++++++++++
12
hw/arm/allwinner-a10.c | 6 ++++++
20
1 file changed, 43 insertions(+)
13
2 files changed, 6 insertions(+), 6 deletions(-)
14
21
15
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
22
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/allwinner-a10.h
24
--- a/target/arm/helper.c
18
+++ b/include/hw/arm/allwinner-a10.h
25
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
20
#include "target/arm/cpu.h"
27
},
21
28
};
22
29
23
-#define AW_A10_PIC_REG_BASE 0x01c20400
30
+/*
24
-#define AW_A10_PIT_REG_BASE 0x01c20c00
31
+ * FEAT_ECV adds extra views of CNTVCT_EL0 and CNTPCT_EL0 which
25
-#define AW_A10_UART0_REG_BASE 0x01c28000
32
+ * are "self-synchronizing". For QEMU all sysregs are self-synchronizing,
26
-#define AW_A10_EMAC_BASE 0x01c0b000
33
+ * so our implementations here are identical to the normal registers.
27
-#define AW_A10_SATA_BASE 0x01c18000
34
+ */
28
-
35
+static const ARMCPRegInfo gen_timer_ecv_cp_reginfo[] = {
29
#define AW_A10_SDRAM_BASE 0x40000000
36
+ { .name = "CNTVCTSS", .cp = 15, .crm = 14, .opc1 = 9,
30
37
+ .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_RAW | ARM_CP_IO,
31
#define TYPE_AW_A10 "allwinner-a10"
38
+ .accessfn = gt_vct_access,
32
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
39
+ .readfn = gt_virt_cnt_read, .resetfn = arm_cp_reset_ignore,
33
index XXXXXXX..XXXXXXX 100644
40
+ },
34
--- a/hw/arm/allwinner-a10.c
41
+ { .name = "CNTVCTSS_EL0", .state = ARM_CP_STATE_AA64,
35
+++ b/hw/arm/allwinner-a10.c
42
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 6,
36
@@ -XXX,XX +XXX,XX @@
43
+ .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO,
37
#include "hw/misc/unimp.h"
44
+ .accessfn = gt_vct_access, .readfn = gt_virt_cnt_read,
38
#include "sysemu/sysemu.h"
45
+ },
39
46
+ { .name = "CNTPCTSS", .cp = 15, .crm = 14, .opc1 = 8,
40
+#define AW_A10_PIC_REG_BASE 0x01c20400
47
+ .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_RAW | ARM_CP_IO,
41
+#define AW_A10_PIT_REG_BASE 0x01c20c00
48
+ .accessfn = gt_pct_access,
42
+#define AW_A10_UART0_REG_BASE 0x01c28000
49
+ .readfn = gt_cnt_read, .resetfn = arm_cp_reset_ignore,
43
+#define AW_A10_EMAC_BASE 0x01c0b000
50
+ },
44
+#define AW_A10_SATA_BASE 0x01c18000
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
+};
45
+
57
+
46
static void aw_a10_init(Object *obj)
58
#else
47
{
59
48
AwA10State *s = AW_A10(obj);
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,
49
--
90
--
50
2.20.1
91
2.34.1
51
52
diff view generated by jsdifflib
1
From: Alistair Francis <alistair@alistair23.me>
1
When ID_AA64MMFR0_EL1.ECV is 0b0010, a new register CNTPOFF_EL2 is
2
implemented. This is similar to the existing CNTVOFF_EL2, except
3
that it controls a hypervisor-adjustable offset made to the physical
4
counter and timer.
2
5
3
Signed-off-by: Alistair Francis <alistair@alistair23.me>
6
Implement the handling for this register, which includes control/trap
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
bits in SCR_EL3 and CNTHCTL_EL2.
5
Message-id: 1d145c4c13e5fa140caf131232a6f524c88fcd72.1576658572.git.alistair@alistair23.me
8
6
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>
11
Message-id: 20240301183219.2424889-8-peter.maydell@linaro.org
7
---
12
---
8
hw/arm/Makefile.objs | 1 +
13
target/arm/cpu-features.h | 5 +++
9
include/hw/arm/stm32f405_soc.h | 73 ++++++++
14
target/arm/cpu.h | 1 +
10
hw/arm/stm32f405_soc.c | 302 +++++++++++++++++++++++++++++++++
15
target/arm/helper.c | 68 +++++++++++++++++++++++++++++++++++++--
11
MAINTAINERS | 8 +
16
target/arm/trace-events | 1 +
12
4 files changed, 384 insertions(+)
17
4 files changed, 73 insertions(+), 2 deletions(-)
13
create mode 100644 include/hw/arm/stm32f405_soc.h
14
create mode 100644 hw/arm/stm32f405_soc.c
15
18
16
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
19
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
17
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/Makefile.objs
21
--- a/target/arm/cpu-features.h
19
+++ b/hw/arm/Makefile.objs
22
+++ b/target/arm/cpu-features.h
20
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_STRONGARM) += strongarm.o
23
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ecv_traps(const ARMISARegisters *id)
21
obj-$(CONFIG_ALLWINNER_A10) += allwinner-a10.o cubieboard.o
24
return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, ECV) > 0;
22
obj-$(CONFIG_RASPI) += bcm2835_peripherals.o bcm2836.o raspi.o
25
}
23
obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
26
24
+obj-$(CONFIG_STM32F405_SOC) += stm32f405_soc.o
27
+static inline bool isar_feature_aa64_ecv(const ARMISARegisters *id)
25
obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zynqmp.o xlnx-zcu102.o
26
obj-$(CONFIG_XLNX_VERSAL) += xlnx-versal.o xlnx-versal-virt.o
27
obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
28
diff --git a/include/hw/arm/stm32f405_soc.h b/include/hw/arm/stm32f405_soc.h
29
new file mode 100644
30
index XXXXXXX..XXXXXXX
31
--- /dev/null
32
+++ b/include/hw/arm/stm32f405_soc.h
33
@@ -XXX,XX +XXX,XX @@
34
+/*
35
+ * STM32F405 SoC
36
+ *
37
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
38
+ *
39
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
40
+ * of this software and associated documentation files (the "Software"), to deal
41
+ * in the Software without restriction, including without limitation the rights
42
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
43
+ * copies of the Software, and to permit persons to whom the Software is
44
+ * furnished to do so, subject to the following conditions:
45
+ *
46
+ * The above copyright notice and this permission notice shall be included in
47
+ * all copies or substantial portions of the Software.
48
+ *
49
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
50
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
51
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
52
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
53
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
54
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
55
+ * THE SOFTWARE.
56
+ */
57
+
58
+#ifndef HW_ARM_STM32F405_SOC_H
59
+#define HW_ARM_STM32F405_SOC_H
60
+
61
+#include "hw/misc/stm32f4xx_syscfg.h"
62
+#include "hw/timer/stm32f2xx_timer.h"
63
+#include "hw/char/stm32f2xx_usart.h"
64
+#include "hw/adc/stm32f2xx_adc.h"
65
+#include "hw/misc/stm32f4xx_exti.h"
66
+#include "hw/or-irq.h"
67
+#include "hw/ssi/stm32f2xx_spi.h"
68
+#include "hw/arm/armv7m.h"
69
+
70
+#define TYPE_STM32F405_SOC "stm32f405-soc"
71
+#define STM32F405_SOC(obj) \
72
+ OBJECT_CHECK(STM32F405State, (obj), TYPE_STM32F405_SOC)
73
+
74
+#define STM_NUM_USARTS 7
75
+#define STM_NUM_TIMERS 4
76
+#define STM_NUM_ADCS 6
77
+#define STM_NUM_SPIS 6
78
+
79
+#define FLASH_BASE_ADDRESS 0x08000000
80
+#define FLASH_SIZE (1024 * 1024)
81
+#define SRAM_BASE_ADDRESS 0x20000000
82
+#define SRAM_SIZE (192 * 1024)
83
+
84
+typedef struct STM32F405State {
85
+ /*< private >*/
86
+ SysBusDevice parent_obj;
87
+ /*< public >*/
88
+
89
+ char *cpu_type;
90
+
91
+ ARMv7MState armv7m;
92
+
93
+ STM32F4xxSyscfgState syscfg;
94
+ STM32F4xxExtiState exti;
95
+ STM32F2XXUsartState usart[STM_NUM_USARTS];
96
+ STM32F2XXTimerState timer[STM_NUM_TIMERS];
97
+ qemu_or_irq adc_irqs;
98
+ STM32F2XXADCState adc[STM_NUM_ADCS];
99
+ STM32F2XXSPIState spi[STM_NUM_SPIS];
100
+
101
+ MemoryRegion sram;
102
+ MemoryRegion flash;
103
+ MemoryRegion flash_alias;
104
+} STM32F405State;
105
+
106
+#endif
107
diff --git a/hw/arm/stm32f405_soc.c b/hw/arm/stm32f405_soc.c
108
new file mode 100644
109
index XXXXXXX..XXXXXXX
110
--- /dev/null
111
+++ b/hw/arm/stm32f405_soc.c
112
@@ -XXX,XX +XXX,XX @@
113
+/*
114
+ * STM32F405 SoC
115
+ *
116
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
117
+ *
118
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
119
+ * of this software and associated documentation files (the "Software"), to deal
120
+ * in the Software without restriction, including without limitation the rights
121
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
122
+ * copies of the Software, and to permit persons to whom the Software is
123
+ * furnished to do so, subject to the following conditions:
124
+ *
125
+ * The above copyright notice and this permission notice shall be included in
126
+ * all copies or substantial portions of the Software.
127
+ *
128
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
129
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
130
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
131
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
132
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
133
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
134
+ * THE SOFTWARE.
135
+ */
136
+
137
+#include "qemu/osdep.h"
138
+#include "qapi/error.h"
139
+#include "qemu-common.h"
140
+#include "exec/address-spaces.h"
141
+#include "sysemu/sysemu.h"
142
+#include "hw/arm/stm32f405_soc.h"
143
+#include "hw/misc/unimp.h"
144
+
145
+#define SYSCFG_ADD 0x40013800
146
+static const uint32_t usart_addr[] = { 0x40011000, 0x40004400, 0x40004800,
147
+ 0x40004C00, 0x40005000, 0x40011400,
148
+ 0x40007800, 0x40007C00 };
149
+/* At the moment only Timer 2 to 5 are modelled */
150
+static const uint32_t timer_addr[] = { 0x40000000, 0x40000400,
151
+ 0x40000800, 0x40000C00 };
152
+#define ADC_ADDR 0x40012000
153
+static const uint32_t spi_addr[] = { 0x40013000, 0x40003800, 0x40003C00,
154
+ 0x40013400, 0x40015000, 0x40015400 };
155
+#define EXTI_ADDR 0x40013C00
156
+
157
+#define SYSCFG_IRQ 71
158
+static const int usart_irq[] = { 37, 38, 39, 52, 53, 71, 82, 83 };
159
+static const int timer_irq[] = { 28, 29, 30, 50 };
160
+#define ADC_IRQ 18
161
+static const int spi_irq[] = { 35, 36, 51, 0, 0, 0 };
162
+static const int exti_irq[] = { 6, 7, 8, 9, 10, 23, 23, 23, 23, 23, 40,
163
+ 40, 40, 40, 40, 40} ;
164
+
165
+
166
+static void stm32f405_soc_initfn(Object *obj)
167
+{
28
+{
168
+ STM32F405State *s = STM32F405_SOC(obj);
29
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, ECV) > 1;
169
+ int i;
170
+
171
+ sysbus_init_child_obj(obj, "armv7m", &s->armv7m, sizeof(s->armv7m),
172
+ TYPE_ARMV7M);
173
+
174
+ sysbus_init_child_obj(obj, "syscfg", &s->syscfg, sizeof(s->syscfg),
175
+ TYPE_STM32F4XX_SYSCFG);
176
+
177
+ for (i = 0; i < STM_NUM_USARTS; i++) {
178
+ sysbus_init_child_obj(obj, "usart[*]", &s->usart[i],
179
+ sizeof(s->usart[i]), TYPE_STM32F2XX_USART);
180
+ }
181
+
182
+ for (i = 0; i < STM_NUM_TIMERS; i++) {
183
+ sysbus_init_child_obj(obj, "timer[*]", &s->timer[i],
184
+ sizeof(s->timer[i]), TYPE_STM32F2XX_TIMER);
185
+ }
186
+
187
+ for (i = 0; i < STM_NUM_ADCS; i++) {
188
+ sysbus_init_child_obj(obj, "adc[*]", &s->adc[i], sizeof(s->adc[i]),
189
+ TYPE_STM32F2XX_ADC);
190
+ }
191
+
192
+ for (i = 0; i < STM_NUM_SPIS; i++) {
193
+ sysbus_init_child_obj(obj, "spi[*]", &s->spi[i], sizeof(s->spi[i]),
194
+ TYPE_STM32F2XX_SPI);
195
+ }
196
+
197
+ sysbus_init_child_obj(obj, "exti", &s->exti, sizeof(s->exti),
198
+ TYPE_STM32F4XX_EXTI);
199
+}
30
+}
200
+
31
+
201
+static void stm32f405_soc_realize(DeviceState *dev_soc, Error **errp)
32
static inline bool isar_feature_aa64_vh(const ARMISARegisters *id)
33
{
34
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0;
35
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/cpu.h
38
+++ b/target/arm/cpu.h
39
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
40
uint64_t c14_cntkctl; /* Timer Control register */
41
uint64_t cnthctl_el2; /* Counter/Timer Hyp Control register */
42
uint64_t cntvoff_el2; /* Counter Virtual Offset register */
43
+ uint64_t cntpoff_el2; /* Counter Physical Offset register */
44
ARMGenericTimer c14_timer[NUM_GTIMERS];
45
uint32_t c15_cpar; /* XScale Coprocessor Access Register */
46
uint32_t c15_ticonfig; /* TI925T configuration byte. */
47
diff --git a/target/arm/helper.c b/target/arm/helper.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/helper.c
50
+++ b/target/arm/helper.c
51
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
52
if (cpu_isar_feature(aa64_rme, cpu)) {
53
valid_mask |= SCR_NSE | SCR_GPF;
54
}
55
+ if (cpu_isar_feature(aa64_ecv, cpu)) {
56
+ valid_mask |= SCR_ECVEN;
57
+ }
58
} else {
59
valid_mask &= ~(SCR_RW | SCR_ST);
60
if (cpu_isar_feature(aa32_ras, cpu)) {
61
@@ -XXX,XX +XXX,XX @@ void gt_rme_post_el_change(ARMCPU *cpu, void *ignored)
62
gt_update_irq(cpu, GTIMER_PHYS);
63
}
64
65
+static uint64_t gt_phys_raw_cnt_offset(CPUARMState *env)
202
+{
66
+{
203
+ STM32F405State *s = STM32F405_SOC(dev_soc);
67
+ if ((env->cp15.scr_el3 & SCR_ECVEN) &&
204
+ MemoryRegion *system_memory = get_system_memory();
68
+ FIELD_EX64(env->cp15.cnthctl_el2, CNTHCTL, ECV) &&
205
+ DeviceState *dev, *armv7m;
69
+ arm_is_el2_enabled(env) &&
206
+ SysBusDevice *busdev;
70
+ (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
207
+ Error *err = NULL;
71
+ return env->cp15.cntpoff_el2;
208
+ int i;
209
+
210
+ memory_region_init_ram(&s->flash, NULL, "STM32F405.flash", FLASH_SIZE,
211
+ &err);
212
+ if (err != NULL) {
213
+ error_propagate(errp, err);
214
+ return;
215
+ }
72
+ }
216
+ memory_region_init_alias(&s->flash_alias, NULL, "STM32F405.flash.alias",
73
+ return 0;
217
+ &s->flash, 0, FLASH_SIZE);
218
+
219
+ memory_region_set_readonly(&s->flash, true);
220
+ memory_region_set_readonly(&s->flash_alias, true);
221
+
222
+ memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, &s->flash);
223
+ memory_region_add_subregion(system_memory, 0, &s->flash_alias);
224
+
225
+ memory_region_init_ram(&s->sram, NULL, "STM32F405.sram", SRAM_SIZE,
226
+ &err);
227
+ if (err != NULL) {
228
+ error_propagate(errp, err);
229
+ return;
230
+ }
231
+ memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, &s->sram);
232
+
233
+ armv7m = DEVICE(&s->armv7m);
234
+ qdev_prop_set_uint32(armv7m, "num-irq", 96);
235
+ qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type);
236
+ qdev_prop_set_bit(armv7m, "enable-bitband", true);
237
+ object_property_set_link(OBJECT(&s->armv7m), OBJECT(system_memory),
238
+ "memory", &error_abort);
239
+ object_property_set_bool(OBJECT(&s->armv7m), true, "realized", &err);
240
+ if (err != NULL) {
241
+ error_propagate(errp, err);
242
+ return;
243
+ }
244
+
245
+ /* System configuration controller */
246
+ dev = DEVICE(&s->syscfg);
247
+ object_property_set_bool(OBJECT(&s->syscfg), true, "realized", &err);
248
+ if (err != NULL) {
249
+ error_propagate(errp, err);
250
+ return;
251
+ }
252
+ busdev = SYS_BUS_DEVICE(dev);
253
+ sysbus_mmio_map(busdev, 0, SYSCFG_ADD);
254
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, SYSCFG_IRQ));
255
+
256
+ /* Attach UART (uses USART registers) and USART controllers */
257
+ for (i = 0; i < STM_NUM_USARTS; i++) {
258
+ dev = DEVICE(&(s->usart[i]));
259
+ qdev_prop_set_chr(dev, "chardev", serial_hd(i));
260
+ object_property_set_bool(OBJECT(&s->usart[i]), true, "realized", &err);
261
+ if (err != NULL) {
262
+ error_propagate(errp, err);
263
+ return;
264
+ }
265
+ busdev = SYS_BUS_DEVICE(dev);
266
+ sysbus_mmio_map(busdev, 0, usart_addr[i]);
267
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, usart_irq[i]));
268
+ }
269
+
270
+ /* Timer 2 to 5 */
271
+ for (i = 0; i < STM_NUM_TIMERS; i++) {
272
+ dev = DEVICE(&(s->timer[i]));
273
+ qdev_prop_set_uint64(dev, "clock-frequency", 1000000000);
274
+ object_property_set_bool(OBJECT(&s->timer[i]), true, "realized", &err);
275
+ if (err != NULL) {
276
+ error_propagate(errp, err);
277
+ return;
278
+ }
279
+ busdev = SYS_BUS_DEVICE(dev);
280
+ sysbus_mmio_map(busdev, 0, timer_addr[i]);
281
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, timer_irq[i]));
282
+ }
283
+
284
+ /* ADC device, the IRQs are ORed together */
285
+ object_initialize_child(OBJECT(s), "adc-orirq", &s->adc_irqs,
286
+ sizeof(s->adc_irqs), TYPE_OR_IRQ,
287
+ &err, NULL);
288
+ if (err != NULL) {
289
+ error_propagate(errp, err);
290
+ return;
291
+ }
292
+ object_property_set_int(OBJECT(&s->adc_irqs), STM_NUM_ADCS,
293
+ "num-lines", &err);
294
+ object_property_set_bool(OBJECT(&s->adc_irqs), true, "realized", &err);
295
+ if (err != NULL) {
296
+ error_propagate(errp, err);
297
+ return;
298
+ }
299
+ qdev_connect_gpio_out(DEVICE(&s->adc_irqs), 0,
300
+ qdev_get_gpio_in(armv7m, ADC_IRQ));
301
+
302
+ dev = DEVICE(&(s->adc[i]));
303
+ object_property_set_bool(OBJECT(&s->adc[i]), true, "realized", &err);
304
+ if (err != NULL) {
305
+ error_propagate(errp, err);
306
+ return;
307
+ }
308
+ busdev = SYS_BUS_DEVICE(dev);
309
+ sysbus_mmio_map(busdev, 0, ADC_ADDR);
310
+ sysbus_connect_irq(busdev, 0,
311
+ qdev_get_gpio_in(DEVICE(&s->adc_irqs), i));
312
+
313
+ /* SPI devices */
314
+ for (i = 0; i < STM_NUM_SPIS; i++) {
315
+ dev = DEVICE(&(s->spi[i]));
316
+ object_property_set_bool(OBJECT(&s->spi[i]), true, "realized", &err);
317
+ if (err != NULL) {
318
+ error_propagate(errp, err);
319
+ return;
320
+ }
321
+ busdev = SYS_BUS_DEVICE(dev);
322
+ sysbus_mmio_map(busdev, 0, spi_addr[i]);
323
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, spi_irq[i]));
324
+ }
325
+
326
+ /* EXTI device */
327
+ dev = DEVICE(&s->exti);
328
+ object_property_set_bool(OBJECT(&s->exti), true, "realized", &err);
329
+ if (err != NULL) {
330
+ error_propagate(errp, err);
331
+ return;
332
+ }
333
+ busdev = SYS_BUS_DEVICE(dev);
334
+ sysbus_mmio_map(busdev, 0, EXTI_ADDR);
335
+ for (i = 0; i < 16; i++) {
336
+ sysbus_connect_irq(busdev, i, qdev_get_gpio_in(armv7m, exti_irq[i]));
337
+ }
338
+ for (i = 0; i < 16; i++) {
339
+ qdev_connect_gpio_out(DEVICE(&s->syscfg), i, qdev_get_gpio_in(dev, i));
340
+ }
341
+
342
+ create_unimplemented_device("timer[7]", 0x40001400, 0x400);
343
+ create_unimplemented_device("timer[12]", 0x40001800, 0x400);
344
+ create_unimplemented_device("timer[6]", 0x40001000, 0x400);
345
+ create_unimplemented_device("timer[13]", 0x40001C00, 0x400);
346
+ create_unimplemented_device("timer[14]", 0x40002000, 0x400);
347
+ create_unimplemented_device("RTC and BKP", 0x40002800, 0x400);
348
+ create_unimplemented_device("WWDG", 0x40002C00, 0x400);
349
+ create_unimplemented_device("IWDG", 0x40003000, 0x400);
350
+ create_unimplemented_device("I2S2ext", 0x40003000, 0x400);
351
+ create_unimplemented_device("I2S3ext", 0x40004000, 0x400);
352
+ create_unimplemented_device("I2C1", 0x40005400, 0x400);
353
+ create_unimplemented_device("I2C2", 0x40005800, 0x400);
354
+ create_unimplemented_device("I2C3", 0x40005C00, 0x400);
355
+ create_unimplemented_device("CAN1", 0x40006400, 0x400);
356
+ create_unimplemented_device("CAN2", 0x40006800, 0x400);
357
+ create_unimplemented_device("PWR", 0x40007000, 0x400);
358
+ create_unimplemented_device("DAC", 0x40007400, 0x400);
359
+ create_unimplemented_device("timer[1]", 0x40010000, 0x400);
360
+ create_unimplemented_device("timer[8]", 0x40010400, 0x400);
361
+ create_unimplemented_device("SDIO", 0x40012C00, 0x400);
362
+ create_unimplemented_device("timer[9]", 0x40014000, 0x400);
363
+ create_unimplemented_device("timer[10]", 0x40014400, 0x400);
364
+ create_unimplemented_device("timer[11]", 0x40014800, 0x400);
365
+ create_unimplemented_device("GPIOA", 0x40020000, 0x400);
366
+ create_unimplemented_device("GPIOB", 0x40020400, 0x400);
367
+ create_unimplemented_device("GPIOC", 0x40020800, 0x400);
368
+ create_unimplemented_device("GPIOD", 0x40020C00, 0x400);
369
+ create_unimplemented_device("GPIOE", 0x40021000, 0x400);
370
+ create_unimplemented_device("GPIOF", 0x40021400, 0x400);
371
+ create_unimplemented_device("GPIOG", 0x40021800, 0x400);
372
+ create_unimplemented_device("GPIOH", 0x40021C00, 0x400);
373
+ create_unimplemented_device("GPIOI", 0x40022000, 0x400);
374
+ create_unimplemented_device("CRC", 0x40023000, 0x400);
375
+ create_unimplemented_device("RCC", 0x40023800, 0x400);
376
+ create_unimplemented_device("Flash Int", 0x40023C00, 0x400);
377
+ create_unimplemented_device("BKPSRAM", 0x40024000, 0x400);
378
+ create_unimplemented_device("DMA1", 0x40026000, 0x400);
379
+ create_unimplemented_device("DMA2", 0x40026400, 0x400);
380
+ create_unimplemented_device("Ethernet", 0x40028000, 0x1400);
381
+ create_unimplemented_device("USB OTG HS", 0x40040000, 0x30000);
382
+ create_unimplemented_device("USB OTG FS", 0x50000000, 0x31000);
383
+ create_unimplemented_device("DCMI", 0x50050000, 0x400);
384
+ create_unimplemented_device("RNG", 0x50060800, 0x400);
385
+}
74
+}
386
+
75
+
387
+static Property stm32f405_soc_properties[] = {
76
+static uint64_t gt_phys_cnt_offset(CPUARMState *env)
388
+ DEFINE_PROP_STRING("cpu-type", STM32F405State, cpu_type),
389
+ DEFINE_PROP_END_OF_LIST(),
390
+};
391
+
392
+static void stm32f405_soc_class_init(ObjectClass *klass, void *data)
393
+{
77
+{
394
+ DeviceClass *dc = DEVICE_CLASS(klass);
78
+ if (arm_current_el(env) >= 2) {
395
+
79
+ return 0;
396
+ dc->realize = stm32f405_soc_realize;
80
+ }
397
+ dc->props = stm32f405_soc_properties;
81
+ return gt_phys_raw_cnt_offset(env);
398
+ /* No vmstate or reset required: device has no internal state */
399
+}
82
+}
400
+
83
+
401
+static const TypeInfo stm32f405_soc_info = {
84
static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
402
+ .name = TYPE_STM32F405_SOC,
85
{
403
+ .parent = TYPE_SYS_BUS_DEVICE,
86
ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx];
404
+ .instance_size = sizeof(STM32F405State),
87
@@ -XXX,XX +XXX,XX @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
405
+ .instance_init = stm32f405_soc_initfn,
88
* reset timer to when ISTATUS next has to change
406
+ .class_init = stm32f405_soc_class_init,
89
*/
407
+};
90
uint64_t offset = timeridx == GTIMER_VIRT ?
408
+
91
- cpu->env.cp15.cntvoff_el2 : 0;
409
+static void stm32f405_soc_types(void)
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)
410
+{
142
+{
411
+ type_register_static(&stm32f405_soc_info);
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;
412
+}
147
+}
413
+
148
+
414
+type_init(stm32f405_soc_types)
149
+static void gt_cntpoff_write(CPUARMState *env, const ARMCPRegInfo *ri,
415
diff --git a/MAINTAINERS b/MAINTAINERS
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
416
index XXXXXXX..XXXXXXX 100644
183
index XXXXXXX..XXXXXXX 100644
417
--- a/MAINTAINERS
184
--- a/target/arm/trace-events
418
+++ b/MAINTAINERS
185
+++ b/target/arm/trace-events
419
@@ -XXX,XX +XXX,XX @@ F: hw/adc/*
186
@@ -XXX,XX +XXX,XX @@ arm_gt_tval_write(int timer, uint64_t value) "gt_tval_write: timer %d value 0x%"
420
F: hw/ssi/stm32f2xx_spi.c
187
arm_gt_ctl_write(int timer, uint64_t value) "gt_ctl_write: timer %d value 0x%" PRIx64
421
F: include/hw/*/stm32*.h
188
arm_gt_imask_toggle(int timer) "gt_ctl_write: timer %d IMASK toggle"
422
189
arm_gt_cntvoff_write(uint64_t value) "gt_cntvoff_write: value 0x%" PRIx64
423
+STM32F405
190
+arm_gt_cntpoff_write(uint64_t value) "gt_cntpoff_write: value 0x%" PRIx64
424
+M: Alistair Francis <alistair@alistair23.me>
191
arm_gt_update_irq(int timer, int irqstate) "gt_update_irq: timer %d irqstate %d"
425
+M: Peter Maydell <peter.maydell@linaro.org>
192
426
+S: Maintained
193
# kvm.c
427
+F: hw/arm/stm32f405_soc.c
428
+F: hw/misc/stm32f4xx_syscfg.c
429
+F: hw/misc/stm32f4xx_exti.c
430
+
431
Netduino 2
432
M: Alistair Francis <alistair@alistair23.me>
433
M: Peter Maydell <peter.maydell@linaro.org>
434
--
194
--
435
2.20.1
195
2.34.1
436
437
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
Enable all FEAT_ECV features on the 'max' CPU.
2
2
3
The kernel image and DeviceTree blob are built by the Armbian
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
project (based on Debian):
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
https://docs.armbian.com/Developer-Guide_Build-Preparation/
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20240301183219.2424889-9-peter.maydell@linaro.org
7
---
8
docs/system/arm/emulation.rst | 1 +
9
target/arm/tcg/cpu64.c | 1 +
10
2 files changed, 2 insertions(+)
6
11
7
The cpio image used comes from the linux-build-test project:
12
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
8
https://github.com/groeck/linux-build-test
9
10
If ARM is a target being built, "make check-acceptance" will
11
automatically include this test by the use of the "arch:arm" tags.
12
13
Alternatively, this test can be run using:
14
15
$ avocado --show=console run -t machine:cubieboard tests/acceptance/boot_linux_console.py
16
console: Uncompressing Linux... done, booting the kernel.
17
console: Booting Linux on physical CPU 0x0
18
console: Linux version 4.20.7-sunxi (root@armbian.com) (gcc version 7.2.1 20171011 (Linaro GCC 7.2-2017.11)) #5.75 SMP Fri Feb 8 09:02:10 CET 2019
19
[...]
20
console: ahci-sunxi 1c18000.sata: Linked as a consumer to regulator.4
21
console: ahci-sunxi 1c18000.sata: controller can't do 64bit DMA, forcing 32bit
22
console: ahci-sunxi 1c18000.sata: AHCI 0001.0000 32 slots 1 ports 1.5 Gbps 0x1 impl platform mode
23
console: ahci-sunxi 1c18000.sata: flags: ncq only
24
console: scsi host0: ahci-sunxi
25
console: ata1: SATA max UDMA/133 mmio [mem 0x01c18000-0x01c18fff] port 0x100 irq 27
26
console: of_cfs_init
27
console: of_cfs_init: OK
28
console: vcc3v0: disabling
29
console: vcc5v0: disabling
30
console: usb1-vbus: disabling
31
console: usb2-vbus: disabling
32
console: ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
33
console: ata1.00: ATA-7: QEMU HARDDISK, 2.5+, max UDMA/100
34
console: ata1.00: 40960 sectors, multi 16: LBA48 NCQ (depth 32)
35
console: ata1.00: applying bridge limits
36
console: ata1.00: configured for UDMA/100
37
console: scsi 0:0:0:0: Direct-Access ATA QEMU HARDDISK 2.5+ PQ: 0 ANSI: 5
38
console: sd 0:0:0:0: Attached scsi generic sg0 type 0
39
console: sd 0:0:0:0: [sda] 40960 512-byte logical blocks: (21.0 MB/20.0 MiB)
40
console: sd 0:0:0:0: [sda] Write Protect is off
41
console: sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
42
console: sd 0:0:0:0: [sda] Attached SCSI disk
43
console: EXT4-fs (sda): mounting ext2 file system using the ext4 subsystem
44
console: EXT4-fs (sda): mounted filesystem without journal. Opts: (null)
45
console: VFS: Mounted root (ext2 filesystem) readonly on device 8:0.
46
[...]
47
console: cat /proc/partitions
48
console: / # cat /proc/partitions
49
console: major minor #blocks name
50
console: 1 0 4096 ram0
51
console: 1 1 4096 ram1
52
console: 1 2 4096 ram2
53
console: 1 3 4096 ram3
54
console: 8 0 20480 sda
55
console: reboot
56
console: / # reboot
57
[...]
58
console: sd 0:0:0:0: [sda] Synchronizing SCSI cache
59
console: reboot: Restarting system
60
PASS (48.39 s)
61
62
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
63
Message-id: 20191230110953.25496-3-f4bug@amsat.org
64
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
65
---
66
tests/acceptance/boot_linux_console.py | 44 ++++++++++++++++++++++++++
67
1 file changed, 44 insertions(+)
68
69
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
70
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
71
--- a/tests/acceptance/boot_linux_console.py
14
--- a/docs/system/arm/emulation.rst
72
+++ b/tests/acceptance/boot_linux_console.py
15
+++ b/docs/system/arm/emulation.rst
73
@@ -XXX,XX +XXX,XX @@ class BootLinuxConsole(Test):
16
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
74
exec_command_and_wait_for_pattern(self, 'reboot',
17
- FEAT_DotProd (Advanced SIMD dot product instructions)
75
'reboot: Restarting system')
18
- FEAT_DoubleFault (Double Fault Extension)
76
19
- FEAT_E0PD (Preventing EL0 access to halves of address maps)
77
+ def test_arm_cubieboard_sata(self):
20
+- FEAT_ECV (Enhanced Counter Virtualization)
78
+ """
21
- FEAT_EPAC (Enhanced pointer authentication)
79
+ :avocado: tags=arch:arm
22
- FEAT_ETS (Enhanced Translation Synchronization)
80
+ :avocado: tags=machine:cubieboard
23
- FEAT_EVT (Enhanced Virtualization Traps)
81
+ """
24
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
82
+ deb_url = ('https://apt.armbian.com/pool/main/l/'
25
index XXXXXXX..XXXXXXX 100644
83
+ 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
26
--- a/target/arm/tcg/cpu64.c
84
+ deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
27
+++ b/target/arm/tcg/cpu64.c
85
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
28
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
86
+ kernel_path = self.extract_from_deb(deb_path,
29
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN64_2, 2); /* 64k stage2 supported */
87
+ '/boot/vmlinuz-4.20.7-sunxi')
30
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 2); /* 4k stage2 supported */
88
+ dtb_path = '/usr/lib/linux-image-dev-sunxi/sun4i-a10-cubieboard.dtb'
31
t = FIELD_DP64(t, ID_AA64MMFR0, FGT, 1); /* FEAT_FGT */
89
+ dtb_path = self.extract_from_deb(deb_path, dtb_path)
32
+ t = FIELD_DP64(t, ID_AA64MMFR0, ECV, 2); /* FEAT_ECV */
90
+ rootfs_url = ('https://github.com/groeck/linux-build-test/raw/'
33
cpu->isar.id_aa64mmfr0 = t;
91
+ '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
34
92
+ 'arm/rootfs-armv5.ext2.gz')
35
t = cpu->isar.id_aa64mmfr1;
93
+ rootfs_hash = '093e89d2b4d982234bf528bc9fb2f2f17a9d1f93'
94
+ rootfs_path_gz = self.fetch_asset(rootfs_url, asset_hash=rootfs_hash)
95
+ rootfs_path = os.path.join(self.workdir, 'rootfs.cpio')
96
+ archive.gzip_uncompress(rootfs_path_gz, rootfs_path)
97
+
98
+ self.vm.set_console()
99
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
100
+ 'console=ttyS0,115200 '
101
+ 'usbcore.nousb '
102
+ 'root=/dev/sda ro '
103
+ 'panic=-1 noreboot')
104
+ self.vm.add_args('-kernel', kernel_path,
105
+ '-dtb', dtb_path,
106
+ '-drive', 'if=none,format=raw,id=disk0,file='
107
+ + rootfs_path,
108
+ '-device', 'ide-hd,bus=ide.0,drive=disk0',
109
+ '-append', kernel_command_line,
110
+ '-no-reboot')
111
+ self.vm.launch()
112
+ self.wait_for_console_pattern('Boot successful.')
113
+
114
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
115
+ 'Allwinner sun4i/sun5i')
116
+ exec_command_and_wait_for_pattern(self, 'cat /proc/partitions',
117
+ 'sda')
118
+ exec_command_and_wait_for_pattern(self, 'reboot',
119
+ 'reboot: Restarting system')
120
+
121
def test_s390x_s390_ccw_virtio(self):
122
"""
123
:avocado: tags=arch:s390x
124
--
36
--
125
2.20.1
37
2.34.1
126
38
127
39
diff view generated by jsdifflib
1
From: Alistair Francis <alistair@alistair23.me>
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
2
3
Signed-off-by: Alistair Francis <alistair@alistair23.me>
3
Features supported :
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
- the 8 STM32L4x5 GPIOs are initialized with their reset values
5
Message-id: 49b01423a09cef2ca832ff73a84a996568f1a8fc.1576658572.git.alistair@alistair23.me
5
(except IDR, see below)
6
- input mode : setting a pin in input mode "externally" (using input
7
irqs) results in an out irq (transmitted to SYSCFG)
8
- output mode : setting a bit in ODR sets the corresponding out irq
9
(if this line is configured in output mode)
10
- pull-up, pull-down
11
- push-pull, open-drain
12
13
Difference with the real GPIOs :
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
25
26
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
27
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
28
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
29
Acked-by: Alistair Francis <alistair.francis@wdc.com>
30
Message-id: 20240305210444.310665-2-ines.varhol@telecom-paris.fr
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
32
---
8
hw/misc/Makefile.objs | 1 +
33
MAINTAINERS | 1 +
9
include/hw/misc/stm32f4xx_syscfg.h | 61 ++++++++++
34
docs/system/arm/b-l475e-iot01a.rst | 2 +-
10
hw/misc/stm32f4xx_syscfg.c | 171 +++++++++++++++++++++++++++++
35
include/hw/gpio/stm32l4x5_gpio.h | 70 +++++
11
default-configs/arm-softmmu.mak | 1 +
36
hw/gpio/stm32l4x5_gpio.c | 477 +++++++++++++++++++++++++++++
12
hw/arm/Kconfig | 9 ++
37
hw/gpio/Kconfig | 3 +
13
hw/misc/Kconfig | 3 +
38
hw/gpio/meson.build | 1 +
14
hw/misc/trace-events | 6 +
39
hw/gpio/trace-events | 6 +
15
7 files changed, 252 insertions(+)
40
7 files changed, 559 insertions(+), 1 deletion(-)
16
create mode 100644 include/hw/misc/stm32f4xx_syscfg.h
41
create mode 100644 include/hw/gpio/stm32l4x5_gpio.h
17
create mode 100644 hw/misc/stm32f4xx_syscfg.c
42
create mode 100644 hw/gpio/stm32l4x5_gpio.c
18
43
19
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
44
diff --git a/MAINTAINERS b/MAINTAINERS
20
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/misc/Makefile.objs
46
--- a/MAINTAINERS
22
+++ b/hw/misc/Makefile.objs
47
+++ b/MAINTAINERS
23
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_SLAVIO) += slavio_misc.o
48
@@ -XXX,XX +XXX,XX @@ F: hw/arm/stm32l4x5_soc.c
24
common-obj-$(CONFIG_ZYNQ) += zynq_slcr.o
49
F: hw/misc/stm32l4x5_exti.c
25
common-obj-$(CONFIG_ZYNQ) += zynq-xadc.o
50
F: hw/misc/stm32l4x5_syscfg.c
26
common-obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
51
F: hw/misc/stm32l4x5_rcc.c
27
+common-obj-$(CONFIG_STM32F4XX_SYSCFG) += stm32f4xx_syscfg.o
52
+F: hw/gpio/stm32l4x5_gpio.c
28
obj-$(CONFIG_MIPS_CPS) += mips_cmgcr.o
53
F: include/hw/*/stm32l4x5_*.h
29
obj-$(CONFIG_MIPS_CPS) += mips_cpc.o
54
30
obj-$(CONFIG_MIPS_ITU) += mips_itu.o
55
B-L475E-IOT01A IoT Node
31
diff --git a/include/hw/misc/stm32f4xx_syscfg.h b/include/hw/misc/stm32f4xx_syscfg.h
56
diff --git a/docs/system/arm/b-l475e-iot01a.rst b/docs/system/arm/b-l475e-iot01a.rst
57
index XXXXXXX..XXXXXXX 100644
58
--- a/docs/system/arm/b-l475e-iot01a.rst
59
+++ b/docs/system/arm/b-l475e-iot01a.rst
60
@@ -XXX,XX +XXX,XX @@ Currently B-L475E-IOT01A machine's only supports the following devices:
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
32
new file mode 100644
77
new file mode 100644
33
index XXXXXXX..XXXXXXX
78
index XXXXXXX..XXXXXXX
34
--- /dev/null
79
--- /dev/null
35
+++ b/include/hw/misc/stm32f4xx_syscfg.h
80
+++ b/include/hw/gpio/stm32l4x5_gpio.h
36
@@ -XXX,XX +XXX,XX @@
81
@@ -XXX,XX +XXX,XX @@
37
+/*
82
+/*
38
+ * STM32F4xx SYSCFG
83
+ * STM32L4x5 GPIO (General Purpose Input/Ouput)
39
+ *
84
+ *
40
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
85
+ * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
86
+ * Copyright (c) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
41
+ *
87
+ *
42
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
88
+ * SPDX-License-Identifier: GPL-2.0-or-later
43
+ * of this software and associated documentation files (the "Software"), to deal
44
+ * in the Software without restriction, including without limitation the rights
45
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
46
+ * copies of the Software, and to permit persons to whom the Software is
47
+ * furnished to do so, subject to the following conditions:
48
+ *
89
+ *
49
+ * The above copyright notice and this permission notice shall be included in
90
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
50
+ * all copies or substantial portions of the Software.
91
+ * See the COPYING file in the top-level directory.
51
+ *
52
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
53
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
54
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
55
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
56
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
57
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
58
+ * THE SOFTWARE.
59
+ */
92
+ */
60
+
93
+
61
+#ifndef HW_STM_SYSCFG_H
94
+/*
62
+#define HW_STM_SYSCFG_H
95
+ * The reference used is the STMicroElectronics RM0351 Reference manual
96
+ * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
97
+ * https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html
98
+ */
99
+
100
+#ifndef HW_STM32L4X5_GPIO_H
101
+#define HW_STM32L4X5_GPIO_H
63
+
102
+
64
+#include "hw/sysbus.h"
103
+#include "hw/sysbus.h"
65
+#include "hw/hw.h"
104
+#include "qom/object.h"
66
+
105
+
67
+#define SYSCFG_MEMRMP 0x00
106
+#define TYPE_STM32L4X5_GPIO "stm32l4x5-gpio"
68
+#define SYSCFG_PMC 0x04
107
+OBJECT_DECLARE_SIMPLE_TYPE(Stm32l4x5GpioState, STM32L4X5_GPIO)
69
+#define SYSCFG_EXTICR1 0x08
108
+
70
+#define SYSCFG_EXTICR2 0x0C
109
+#define GPIO_NUM_PINS 16
71
+#define SYSCFG_EXTICR3 0x10
110
+
72
+#define SYSCFG_EXTICR4 0x14
111
+struct Stm32l4x5GpioState {
73
+#define SYSCFG_CMPCR 0x20
74
+
75
+#define TYPE_STM32F4XX_SYSCFG "stm32f4xx-syscfg"
76
+#define STM32F4XX_SYSCFG(obj) \
77
+ OBJECT_CHECK(STM32F4xxSyscfgState, (obj), TYPE_STM32F4XX_SYSCFG)
78
+
79
+#define SYSCFG_NUM_EXTICR 4
80
+
81
+typedef struct {
82
+ /* <private> */
83
+ SysBusDevice parent_obj;
112
+ SysBusDevice parent_obj;
84
+
113
+
85
+ /* <public> */
86
+ MemoryRegion mmio;
114
+ MemoryRegion mmio;
87
+
115
+
88
+ uint32_t syscfg_memrmp;
116
+ /* GPIO registers */
89
+ uint32_t syscfg_pmc;
117
+ uint32_t moder;
90
+ uint32_t syscfg_exticr[SYSCFG_NUM_EXTICR];
118
+ uint32_t otyper;
91
+ uint32_t syscfg_cmpcr;
119
+ uint32_t ospeedr;
92
+
120
+ uint32_t pupdr;
93
+ qemu_irq irq;
121
+ uint32_t idr;
94
+ qemu_irq gpio_out[16];
122
+ uint32_t odr;
95
+} STM32F4xxSyscfgState;
123
+ uint32_t lckr;
124
+ uint32_t afrl;
125
+ uint32_t afrh;
126
+ uint32_t ascr;
127
+
128
+ /* GPIO registers reset values */
129
+ uint32_t moder_reset;
130
+ uint32_t ospeedr_reset;
131
+ uint32_t pupdr_reset;
132
+
133
+ /*
134
+ * External driving of pins.
135
+ * The pins can be set externally through the device
136
+ * anonymous input GPIOs lines under certain conditions.
137
+ * The pin must not be in push-pull output mode,
138
+ * and can't be set high in open-drain mode.
139
+ * Pins driven externally and configured to
140
+ * output mode will in general be "disconnected"
141
+ * (see `get_gpio_pinmask_to_disconnect()`)
142
+ */
143
+ uint16_t disconnected_pins;
144
+ uint16_t pins_connected_high;
145
+
146
+ char *name;
147
+ Clock *clk;
148
+ qemu_irq pin[GPIO_NUM_PINS];
149
+};
96
+
150
+
97
+#endif
151
+#endif
98
diff --git a/hw/misc/stm32f4xx_syscfg.c b/hw/misc/stm32f4xx_syscfg.c
152
diff --git a/hw/gpio/stm32l4x5_gpio.c b/hw/gpio/stm32l4x5_gpio.c
99
new file mode 100644
153
new file mode 100644
100
index XXXXXXX..XXXXXXX
154
index XXXXXXX..XXXXXXX
101
--- /dev/null
155
--- /dev/null
102
+++ b/hw/misc/stm32f4xx_syscfg.c
156
+++ b/hw/gpio/stm32l4x5_gpio.c
103
@@ -XXX,XX +XXX,XX @@
157
@@ -XXX,XX +XXX,XX @@
104
+/*
158
+/*
105
+ * STM32F4xx SYSCFG
159
+ * STM32L4x5 GPIO (General Purpose Input/Ouput)
106
+ *
160
+ *
107
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
161
+ * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
162
+ * Copyright (c) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
108
+ *
163
+ *
109
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
164
+ * SPDX-License-Identifier: GPL-2.0-or-later
110
+ * of this software and associated documentation files (the "Software"), to deal
111
+ * in the Software without restriction, including without limitation the rights
112
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
113
+ * copies of the Software, and to permit persons to whom the Software is
114
+ * furnished to do so, subject to the following conditions:
115
+ *
165
+ *
116
+ * The above copyright notice and this permission notice shall be included in
166
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
117
+ * all copies or substantial portions of the Software.
167
+ * See the COPYING file in the top-level directory.
118
+ *
168
+ */
119
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
169
+
120
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
170
+/*
121
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
171
+ * The reference used is the STMicroElectronics RM0351 Reference manual
122
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
172
+ * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
123
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
173
+ * https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html
124
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
125
+ * THE SOFTWARE.
126
+ */
174
+ */
127
+
175
+
128
+#include "qemu/osdep.h"
176
+#include "qemu/osdep.h"
129
+#include "qemu/log.h"
177
+#include "qemu/log.h"
178
+#include "hw/gpio/stm32l4x5_gpio.h"
179
+#include "hw/irq.h"
180
+#include "hw/qdev-clock.h"
181
+#include "hw/qdev-properties.h"
182
+#include "qapi/visitor.h"
183
+#include "qapi/error.h"
184
+#include "migration/vmstate.h"
130
+#include "trace.h"
185
+#include "trace.h"
131
+#include "hw/irq.h"
186
+
132
+#include "migration/vmstate.h"
187
+#define GPIO_MODER 0x00
133
+#include "hw/misc/stm32f4xx_syscfg.h"
188
+#define GPIO_OTYPER 0x04
134
+
189
+#define GPIO_OSPEEDR 0x08
135
+static void stm32f4xx_syscfg_reset(DeviceState *dev)
190
+#define GPIO_PUPDR 0x0C
136
+{
191
+#define GPIO_IDR 0x10
137
+ STM32F4xxSyscfgState *s = STM32F4XX_SYSCFG(dev);
192
+#define GPIO_ODR 0x14
138
+
193
+#define GPIO_BSRR 0x18
139
+ s->syscfg_memrmp = 0x00000000;
194
+#define GPIO_LCKR 0x1C
140
+ s->syscfg_pmc = 0x00000000;
195
+#define GPIO_AFRL 0x20
141
+ s->syscfg_exticr[0] = 0x00000000;
196
+#define GPIO_AFRH 0x24
142
+ s->syscfg_exticr[1] = 0x00000000;
197
+#define GPIO_BRR 0x28
143
+ s->syscfg_exticr[2] = 0x00000000;
198
+#define GPIO_ASCR 0x2C
144
+ s->syscfg_exticr[3] = 0x00000000;
199
+
145
+ s->syscfg_cmpcr = 0x00000000;
200
+/* 0b11111111_11111111_00000000_00000000 */
146
+}
201
+#define RESERVED_BITS_MASK 0xFFFF0000
147
+
202
+
148
+static void stm32f4xx_syscfg_set_irq(void *opaque, int irq, int level)
203
+static void update_gpio_idr(Stm32l4x5GpioState *s);
149
+{
204
+
150
+ STM32F4xxSyscfgState *s = opaque;
205
+static bool is_pull_up(Stm32l4x5GpioState *s, unsigned pin)
151
+ int icrreg = irq / 4;
206
+{
152
+ int startbit = (irq & 3) * 4;
207
+ return extract32(s->pupdr, 2 * pin, 2) == 1;
153
+ uint8_t config = config = irq / 16;
208
+}
154
+
209
+
155
+ trace_stm32f4xx_syscfg_set_irq(irq / 16, irq % 16, level);
210
+static bool is_pull_down(Stm32l4x5GpioState *s, unsigned pin)
156
+
211
+{
157
+ g_assert(icrreg < SYSCFG_NUM_EXTICR);
212
+ return extract32(s->pupdr, 2 * pin, 2) == 2;
158
+
213
+}
159
+ if (extract32(s->syscfg_exticr[icrreg], startbit, 4) == config) {
214
+
160
+ qemu_set_irq(s->gpio_out[irq], level);
215
+static bool is_output(Stm32l4x5GpioState *s, unsigned pin)
161
+ trace_stm32f4xx_pulse_exti(irq);
216
+{
162
+ }
217
+ return extract32(s->moder, 2 * pin, 2) == 1;
163
+}
218
+}
164
+
219
+
165
+static uint64_t stm32f4xx_syscfg_read(void *opaque, hwaddr addr,
220
+static bool is_open_drain(Stm32l4x5GpioState *s, unsigned pin)
166
+ unsigned int size)
221
+{
167
+{
222
+ return extract32(s->otyper, pin, 1) == 1;
168
+ STM32F4xxSyscfgState *s = opaque;
223
+}
169
+
224
+
170
+ trace_stm32f4xx_syscfg_read(addr);
225
+static bool is_push_pull(Stm32l4x5GpioState *s, unsigned pin)
226
+{
227
+ return extract32(s->otyper, pin, 1) == 0;
228
+}
229
+
230
+static void stm32l4x5_gpio_reset_hold(Object *obj)
231
+{
232
+ Stm32l4x5GpioState *s = STM32L4X5_GPIO(obj);
233
+
234
+ s->moder = s->moder_reset;
235
+ s->otyper = 0x00000000;
236
+ s->ospeedr = s->ospeedr_reset;
237
+ s->pupdr = s->pupdr_reset;
238
+ s->idr = 0x00000000;
239
+ s->odr = 0x00000000;
240
+ s->lckr = 0x00000000;
241
+ s->afrl = 0x00000000;
242
+ s->afrh = 0x00000000;
243
+ s->ascr = 0x00000000;
244
+
245
+ s->disconnected_pins = 0xFFFF;
246
+ s->pins_connected_high = 0x0000;
247
+ update_gpio_idr(s);
248
+}
249
+
250
+static void stm32l4x5_gpio_set(void *opaque, int line, int level)
251
+{
252
+ Stm32l4x5GpioState *s = opaque;
253
+ /*
254
+ * The pin isn't set if line is configured in output mode
255
+ * except if level is 0 and the output is open-drain.
256
+ * This way there will be no short-circuit prone situations.
257
+ */
258
+ if (is_output(s, line) && !(is_open_drain(s, line) && (level == 0))) {
259
+ qemu_log_mask(LOG_GUEST_ERROR, "Line %d can't be driven externally\n",
260
+ line);
261
+ return;
262
+ }
263
+
264
+ s->disconnected_pins &= ~(1 << line);
265
+ if (level) {
266
+ s->pins_connected_high |= (1 << line);
267
+ } else {
268
+ s->pins_connected_high &= ~(1 << line);
269
+ }
270
+ trace_stm32l4x5_gpio_pins(s->name, s->disconnected_pins,
271
+ s->pins_connected_high);
272
+ update_gpio_idr(s);
273
+}
274
+
275
+
276
+static void update_gpio_idr(Stm32l4x5GpioState *s)
277
+{
278
+ uint32_t new_idr_mask = 0;
279
+ uint32_t new_idr = s->odr;
280
+ uint32_t old_idr = s->idr;
281
+ int new_pin_state, old_pin_state;
282
+
283
+ for (int i = 0; i < GPIO_NUM_PINS; i++) {
284
+ if (is_output(s, i)) {
285
+ if (is_push_pull(s, i)) {
286
+ new_idr_mask |= (1 << i);
287
+ } else if (!(s->odr & (1 << i))) {
288
+ /* open-drain ODR 0 */
289
+ new_idr_mask |= (1 << i);
290
+ /* open-drain ODR 1 */
291
+ } else if (!(s->disconnected_pins & (1 << i)) &&
292
+ !(s->pins_connected_high & (1 << i))) {
293
+ /* open-drain ODR 1 with pin connected low */
294
+ new_idr_mask |= (1 << i);
295
+ new_idr &= ~(1 << i);
296
+ /* open-drain ODR 1 with unactive pin */
297
+ } else if (is_pull_up(s, i)) {
298
+ new_idr_mask |= (1 << i);
299
+ } else if (is_pull_down(s, i)) {
300
+ new_idr_mask |= (1 << i);
301
+ new_idr &= ~(1 << i);
302
+ }
303
+ /*
304
+ * The only case left is for open-drain ODR 1
305
+ * with unactive pin without pull-up or pull-down :
306
+ * the value is floating.
307
+ */
308
+ /* input or analog mode with connected pin */
309
+ } else if (!(s->disconnected_pins & (1 << i))) {
310
+ if (s->pins_connected_high & (1 << i)) {
311
+ /* pin high */
312
+ new_idr_mask |= (1 << i);
313
+ new_idr |= (1 << i);
314
+ } else {
315
+ /* pin low */
316
+ new_idr_mask |= (1 << i);
317
+ new_idr &= ~(1 << i);
318
+ }
319
+ /* input or analog mode with disconnected pin */
320
+ } else {
321
+ if (is_pull_up(s, i)) {
322
+ /* pull-up */
323
+ new_idr_mask |= (1 << i);
324
+ new_idr |= (1 << i);
325
+ } else if (is_pull_down(s, i)) {
326
+ /* pull-down */
327
+ new_idr_mask |= (1 << i);
328
+ new_idr &= ~(1 << i);
329
+ }
330
+ /*
331
+ * The only case left is for a disconnected pin
332
+ * without pull-up or pull-down :
333
+ * the value is floating.
334
+ */
335
+ }
336
+ }
337
+
338
+ s->idr = (old_idr & ~new_idr_mask) | (new_idr & new_idr_mask);
339
+ trace_stm32l4x5_gpio_update_idr(s->name, old_idr, s->idr);
340
+
341
+ for (int i = 0; i < GPIO_NUM_PINS; i++) {
342
+ if (new_idr_mask & (1 << i)) {
343
+ new_pin_state = (new_idr & (1 << i)) > 0;
344
+ old_pin_state = (old_idr & (1 << i)) > 0;
345
+ if (new_pin_state > old_pin_state) {
346
+ qemu_irq_raise(s->pin[i]);
347
+ } else if (new_pin_state < old_pin_state) {
348
+ qemu_irq_lower(s->pin[i]);
349
+ }
350
+ }
351
+ }
352
+}
353
+
354
+/*
355
+ * Return mask of pins that are both configured in output
356
+ * mode and externally driven (except pins in open-drain
357
+ * mode externally set to 0).
358
+ */
359
+static uint32_t get_gpio_pinmask_to_disconnect(Stm32l4x5GpioState *s)
360
+{
361
+ uint32_t pins_to_disconnect = 0;
362
+ for (int i = 0; i < GPIO_NUM_PINS; i++) {
363
+ /* for each connected pin in output mode */
364
+ if (!(s->disconnected_pins & (1 << i)) && is_output(s, i)) {
365
+ /* if either push-pull or high level */
366
+ if (is_push_pull(s, i) || s->pins_connected_high & (1 << i)) {
367
+ pins_to_disconnect |= (1 << i);
368
+ qemu_log_mask(LOG_GUEST_ERROR,
369
+ "Line %d can't be driven externally\n",
370
+ i);
371
+ }
372
+ }
373
+ }
374
+ return pins_to_disconnect;
375
+}
376
+
377
+/*
378
+ * Set field `disconnected_pins` and call `update_gpio_idr()`
379
+ */
380
+static void disconnect_gpio_pins(Stm32l4x5GpioState *s, uint16_t lines)
381
+{
382
+ s->disconnected_pins |= lines;
383
+ trace_stm32l4x5_gpio_pins(s->name, s->disconnected_pins,
384
+ s->pins_connected_high);
385
+ update_gpio_idr(s);
386
+}
387
+
388
+static void disconnected_pins_set(Object *obj, Visitor *v,
389
+ const char *name, void *opaque, Error **errp)
390
+{
391
+ Stm32l4x5GpioState *s = STM32L4X5_GPIO(obj);
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);
171
+
420
+
172
+ switch (addr) {
421
+ switch (addr) {
173
+ case SYSCFG_MEMRMP:
422
+ case GPIO_MODER:
174
+ return s->syscfg_memrmp;
423
+ s->moder = value;
175
+ case SYSCFG_PMC:
424
+ disconnect_gpio_pins(s, get_gpio_pinmask_to_disconnect(s));
176
+ return s->syscfg_pmc;
425
+ qemu_log_mask(LOG_UNIMP,
177
+ case SYSCFG_EXTICR1...SYSCFG_EXTICR4:
426
+ "%s: Analog and AF modes aren't supported\n\
178
+ return s->syscfg_exticr[addr / 4 - SYSCFG_EXTICR1 / 4];
427
+ Analog and AF mode behave like input mode\n",
179
+ case SYSCFG_CMPCR:
428
+ __func__);
180
+ return s->syscfg_cmpcr;
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;
181
+ default:
493
+ default:
182
+ qemu_log_mask(LOG_GUEST_ERROR,
494
+ qemu_log_mask(LOG_GUEST_ERROR,
183
+ "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
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:
184
+ return 0;
520
+ return 0;
185
+ }
521
+ case GPIO_LCKR:
186
+}
522
+ return s->lckr;
187
+
523
+ case GPIO_AFRL:
188
+static void stm32f4xx_syscfg_write(void *opaque, hwaddr addr,
524
+ return s->afrl;
189
+ uint64_t val64, unsigned int size)
525
+ case GPIO_AFRH:
190
+{
526
+ return s->afrh;
191
+ STM32F4xxSyscfgState *s = opaque;
527
+ case GPIO_BRR:
192
+ uint32_t value = val64;
528
+ return 0;
193
+
529
+ case GPIO_ASCR:
194
+ trace_stm32f4xx_syscfg_write(value, addr);
530
+ return s->ascr;
195
+
196
+ switch (addr) {
197
+ case SYSCFG_MEMRMP:
198
+ qemu_log_mask(LOG_UNIMP,
199
+ "%s: Changing the memory mapping isn't supported " \
200
+ "in QEMU\n", __func__);
201
+ return;
202
+ case SYSCFG_PMC:
203
+ qemu_log_mask(LOG_UNIMP,
204
+ "%s: Changing the memory mapping isn't supported " \
205
+ "in QEMU\n", __func__);
206
+ return;
207
+ case SYSCFG_EXTICR1...SYSCFG_EXTICR4:
208
+ s->syscfg_exticr[addr / 4 - SYSCFG_EXTICR1 / 4] = (value & 0xFFFF);
209
+ return;
210
+ case SYSCFG_CMPCR:
211
+ s->syscfg_cmpcr = value;
212
+ return;
213
+ default:
531
+ default:
214
+ qemu_log_mask(LOG_GUEST_ERROR,
532
+ qemu_log_mask(LOG_GUEST_ERROR,
215
+ "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
533
+ "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, addr);
216
+ }
534
+ return 0;
217
+}
535
+ }
218
+
536
+}
219
+static const MemoryRegionOps stm32f4xx_syscfg_ops = {
537
+
220
+ .read = stm32f4xx_syscfg_read,
538
+static const MemoryRegionOps stm32l4x5_gpio_ops = {
221
+ .write = stm32f4xx_syscfg_write,
539
+ .read = stm32l4x5_gpio_read,
540
+ .write = stm32l4x5_gpio_write,
222
+ .endianness = DEVICE_NATIVE_ENDIAN,
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
+ },
223
+};
552
+};
224
+
553
+
225
+static void stm32f4xx_syscfg_init(Object *obj)
554
+static void stm32l4x5_gpio_init(Object *obj)
226
+{
555
+{
227
+ STM32F4xxSyscfgState *s = STM32F4XX_SYSCFG(obj);
556
+ Stm32l4x5GpioState *s = STM32L4X5_GPIO(obj);
228
+
557
+
229
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
558
+ memory_region_init_io(&s->mmio, obj, &stm32l4x5_gpio_ops, s,
230
+
559
+ TYPE_STM32L4X5_GPIO, 0x400);
231
+ memory_region_init_io(&s->mmio, obj, &stm32f4xx_syscfg_ops, s,
560
+
232
+ TYPE_STM32F4XX_SYSCFG, 0x400);
233
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
561
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
234
+
562
+
235
+ qdev_init_gpio_in(DEVICE(obj), stm32f4xx_syscfg_set_irq, 16 * 9);
563
+ qdev_init_gpio_out(DEVICE(obj), s->pin, GPIO_NUM_PINS);
236
+ qdev_init_gpio_out(DEVICE(obj), s->gpio_out, 16);
564
+ qdev_init_gpio_in(DEVICE(obj), stm32l4x5_gpio_set, GPIO_NUM_PINS);
237
+}
565
+
238
+
566
+ s->clk = qdev_init_clock_in(DEVICE(s), "clk", NULL, s, 0);
239
+static const VMStateDescription vmstate_stm32f4xx_syscfg = {
567
+
240
+ .name = TYPE_STM32F4XX_SYSCFG,
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,
241
+ .version_id = 1,
586
+ .version_id = 1,
242
+ .minimum_version_id = 1,
587
+ .minimum_version_id = 1,
243
+ .fields = (VMStateField[]) {
588
+ .fields = (VMStateField[]){
244
+ VMSTATE_UINT32(syscfg_memrmp, STM32F4xxSyscfgState),
589
+ VMSTATE_UINT32(moder, Stm32l4x5GpioState),
245
+ VMSTATE_UINT32(syscfg_pmc, STM32F4xxSyscfgState),
590
+ VMSTATE_UINT32(otyper, Stm32l4x5GpioState),
246
+ VMSTATE_UINT32_ARRAY(syscfg_exticr, STM32F4xxSyscfgState,
591
+ VMSTATE_UINT32(ospeedr, Stm32l4x5GpioState),
247
+ SYSCFG_NUM_EXTICR),
592
+ VMSTATE_UINT32(pupdr, Stm32l4x5GpioState),
248
+ VMSTATE_UINT32(syscfg_cmpcr, STM32F4xxSyscfgState),
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),
249
+ VMSTATE_END_OF_LIST()
601
+ VMSTATE_END_OF_LIST()
250
+ }
602
+ }
251
+};
603
+};
252
+
604
+
253
+static void stm32f4xx_syscfg_class_init(ObjectClass *klass, void *data)
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)
254
+{
614
+{
255
+ DeviceClass *dc = DEVICE_CLASS(klass);
615
+ DeviceClass *dc = DEVICE_CLASS(klass);
256
+
616
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
257
+ dc->reset = stm32f4xx_syscfg_reset;
617
+
258
+ dc->vmsd = &vmstate_stm32f4xx_syscfg;
618
+ device_class_set_props(dc, stm32l4x5_gpio_properties);
259
+}
619
+ dc->vmsd = &vmstate_stm32l4x5_gpio;
260
+
620
+ dc->realize = stm32l4x5_gpio_realize;
261
+static const TypeInfo stm32f4xx_syscfg_info = {
621
+ rc->phases.hold = stm32l4x5_gpio_reset_hold;
262
+ .name = TYPE_STM32F4XX_SYSCFG,
622
+}
263
+ .parent = TYPE_SYS_BUS_DEVICE,
623
+
264
+ .instance_size = sizeof(STM32F4xxSyscfgState),
624
+static const TypeInfo stm32l4x5_gpio_types[] = {
265
+ .instance_init = stm32f4xx_syscfg_init,
625
+ {
266
+ .class_init = stm32f4xx_syscfg_class_init,
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
+ },
267
+};
632
+};
268
+
633
+
269
+static void stm32f4xx_syscfg_register_types(void)
634
+DEFINE_TYPES(stm32l4x5_gpio_types)
270
+{
635
diff --git a/hw/gpio/Kconfig b/hw/gpio/Kconfig
271
+ type_register_static(&stm32f4xx_syscfg_info);
272
+}
273
+
274
+type_init(stm32f4xx_syscfg_register_types)
275
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
276
index XXXXXXX..XXXXXXX 100644
636
index XXXXXXX..XXXXXXX 100644
277
--- a/default-configs/arm-softmmu.mak
637
--- a/hw/gpio/Kconfig
278
+++ b/default-configs/arm-softmmu.mak
638
+++ b/hw/gpio/Kconfig
279
@@ -XXX,XX +XXX,XX @@ CONFIG_Z2=y
639
@@ -XXX,XX +XXX,XX @@ config GPIO_PWR
280
CONFIG_COLLIE=y
640
281
CONFIG_ASPEED_SOC=y
641
config SIFIVE_GPIO
282
CONFIG_NETDUINO2=y
642
bool
283
+CONFIG_NETDUINOPLUS2=y
643
+
284
CONFIG_MPS2=y
644
+config STM32L4X5_GPIO
285
CONFIG_RASPI=y
645
+ bool
286
CONFIG_DIGIC=y
646
diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build
287
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
288
index XXXXXXX..XXXXXXX 100644
647
index XXXXXXX..XXXXXXX 100644
289
--- a/hw/arm/Kconfig
648
--- a/hw/gpio/meson.build
290
+++ b/hw/arm/Kconfig
649
+++ b/hw/gpio/meson.build
291
@@ -XXX,XX +XXX,XX @@ config NETDUINO2
650
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_RASPI', if_true: files(
292
bool
651
'bcm2835_gpio.c',
293
select STM32F205_SOC
652
'bcm2838_gpio.c'
294
653
))
295
+config NETDUINOPLUS2
654
+system_ss.add(when: 'CONFIG_STM32L4X5_SOC', if_true: files('stm32l4x5_gpio.c'))
296
+ bool
655
system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_gpio.c'))
297
+ select STM32F405_SOC
656
system_ss.add(when: 'CONFIG_SIFIVE_GPIO', if_true: files('sifive_gpio.c'))
298
+
657
diff --git a/hw/gpio/trace-events b/hw/gpio/trace-events
299
config NSERIES
300
bool
301
select OMAP
302
@@ -XXX,XX +XXX,XX @@ config STM32F205_SOC
303
select STM32F2XX_ADC
304
select STM32F2XX_SPI
305
306
+config STM32F405_SOC
307
+ bool
308
+ select ARM_V7M
309
+ select STM32F4XX_SYSCFG
310
+
311
config XLNX_ZYNQMP_ARM
312
bool
313
select AHCI
314
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
315
index XXXXXXX..XXXXXXX 100644
658
index XXXXXXX..XXXXXXX 100644
316
--- a/hw/misc/Kconfig
659
--- a/hw/gpio/trace-events
317
+++ b/hw/misc/Kconfig
660
+++ b/hw/gpio/trace-events
318
@@ -XXX,XX +XXX,XX @@ config IMX
661
@@ -XXX,XX +XXX,XX @@ sifive_gpio_update_output_irq(int64_t line, int64_t value) "line %" PRIi64 " val
319
config STM32F2XX_SYSCFG
662
# aspeed_gpio.c
320
bool
663
aspeed_gpio_read(uint64_t offset, uint64_t value) "offset: 0x%" PRIx64 " value 0x%" PRIx64
321
664
aspeed_gpio_write(uint64_t offset, uint64_t value) "offset: 0x%" PRIx64 " value 0x%" PRIx64
322
+config STM32F4XX_SYSCFG
665
+
323
+ bool
666
+# stm32l4x5_gpio.c
324
+
667
+stm32l4x5_gpio_read(char *gpio, uint64_t addr) "GPIO%s addr: 0x%" PRIx64 " "
325
config MIPS_ITU
668
+stm32l4x5_gpio_write(char *gpio, uint64_t addr, uint64_t data) "GPIO%s addr: 0x%" PRIx64 " val: 0x%" PRIx64 ""
326
bool
669
+stm32l4x5_gpio_update_idr(char *gpio, uint32_t old_idr, uint32_t new_idr) "GPIO%s from: 0x%x to: 0x%x"
327
670
+stm32l4x5_gpio_pins(char *gpio, uint16_t disconnected, uint16_t high) "GPIO%s disconnected pins: 0x%x levels: 0x%x"
328
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
329
index XXXXXXX..XXXXXXX 100644
330
--- a/hw/misc/trace-events
331
+++ b/hw/misc/trace-events
332
@@ -XXX,XX +XXX,XX @@ mos6522_set_sr_int(void) "set sr_int"
333
mos6522_write(uint64_t addr, uint64_t val) "reg=0x%"PRIx64 " val=0x%"PRIx64
334
mos6522_read(uint64_t addr, unsigned val) "reg=0x%"PRIx64 " val=0x%x"
335
336
+# stm32f4xx_syscfg
337
+stm32f4xx_syscfg_set_irq(int gpio, int line, int level) "Interupt: GPIO: %d, Line: %d; Level: %d"
338
+stm32f4xx_pulse_exti(int irq) "Pulse EXTI: %d"
339
+stm32f4xx_syscfg_read(uint64_t addr) "reg read: addr: 0x%" PRIx64 " "
340
+stm32f4xx_syscfg_write(uint64_t addr, uint64_t data) "reg write: addr: 0x%" PRIx64 " val: 0x%" PRIx64 ""
341
+
342
# tz-mpc.c
343
tz_mpc_reg_read(uint32_t offset, uint64_t data, unsigned size) "TZ MPC regs read: offset 0x%x data 0x%" PRIx64 " size %u"
344
tz_mpc_reg_write(uint32_t offset, uint64_t data, unsigned size) "TZ MPC regs write: offset 0x%x data 0x%" PRIx64 " size %u"
345
--
671
--
346
2.20.1
672
2.34.1
347
673
348
674
diff view generated by jsdifflib
1
From: Alistair Francis <alistair@alistair23.me>
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
2
3
Signed-off-by: Alistair Francis <alistair@alistair23.me>
3
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
5
Message-id: ef941d59fd8658589d34ed432e1d6dfdcf7fb1d0.1576658572.git.alistair@alistair23.me
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-id: 20240305210444.310665-3-ines.varhol@telecom-paris.fr
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
---
9
hw/misc/Makefile.objs | 1 +
10
include/hw/arm/stm32l4x5_soc.h | 2 +
10
include/hw/misc/stm32f4xx_exti.h | 60 ++++++++++
11
include/hw/gpio/stm32l4x5_gpio.h | 1 +
11
hw/misc/stm32f4xx_exti.c | 188 +++++++++++++++++++++++++++++++
12
include/hw/misc/stm32l4x5_syscfg.h | 3 +-
12
hw/arm/Kconfig | 1 +
13
hw/arm/stm32l4x5_soc.c | 71 +++++++++++++++++++++++-------
13
hw/misc/Kconfig | 3 +
14
hw/misc/stm32l4x5_syscfg.c | 1 +
14
hw/misc/trace-events | 5 +
15
hw/arm/Kconfig | 3 +-
15
6 files changed, 258 insertions(+)
16
6 files changed, 63 insertions(+), 18 deletions(-)
16
create mode 100644 include/hw/misc/stm32f4xx_exti.h
17
17
create mode 100644 hw/misc/stm32f4xx_exti.c
18
diff --git a/include/hw/arm/stm32l4x5_soc.h b/include/hw/arm/stm32l4x5_soc.h
18
19
index XXXXXXX..XXXXXXX 100644
19
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
20
--- a/include/hw/arm/stm32l4x5_soc.h
20
index XXXXXXX..XXXXXXX 100644
21
+++ b/include/hw/arm/stm32l4x5_soc.h
21
--- a/hw/misc/Makefile.objs
22
@@ -XXX,XX +XXX,XX @@
22
+++ b/hw/misc/Makefile.objs
23
#include "hw/misc/stm32l4x5_syscfg.h"
23
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_ZYNQ) += zynq_slcr.o
24
#include "hw/misc/stm32l4x5_exti.h"
24
common-obj-$(CONFIG_ZYNQ) += zynq-xadc.o
25
#include "hw/misc/stm32l4x5_rcc.h"
25
common-obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
26
+#include "hw/gpio/stm32l4x5_gpio.h"
26
common-obj-$(CONFIG_STM32F4XX_SYSCFG) += stm32f4xx_syscfg.o
27
#include "qom/object.h"
27
+common-obj-$(CONFIG_STM32F4XX_EXTI) += stm32f4xx_exti.o
28
28
obj-$(CONFIG_MIPS_CPS) += mips_cmgcr.o
29
#define TYPE_STM32L4X5_SOC "stm32l4x5-soc"
29
obj-$(CONFIG_MIPS_CPS) += mips_cpc.o
30
@@ -XXX,XX +XXX,XX @@ struct Stm32l4x5SocState {
30
obj-$(CONFIG_MIPS_ITU) += mips_itu.o
31
OrIRQState exti_or_gates[NUM_EXTI_OR_GATES];
31
diff --git a/include/hw/misc/stm32f4xx_exti.h b/include/hw/misc/stm32f4xx_exti.h
32
Stm32l4x5SyscfgState syscfg;
32
new file mode 100644
33
Stm32l4x5RccState rcc;
33
index XXXXXXX..XXXXXXX
34
+ Stm32l4x5GpioState gpio[NUM_GPIOS];
34
--- /dev/null
35
35
+++ b/include/hw/misc/stm32f4xx_exti.h
36
MemoryRegion sram1;
36
@@ -XXX,XX +XXX,XX @@
37
MemoryRegion sram2;
37
+/*
38
diff --git a/include/hw/gpio/stm32l4x5_gpio.h b/include/hw/gpio/stm32l4x5_gpio.h
38
+ * STM32F4XX EXTI
39
index XXXXXXX..XXXXXXX 100644
39
+ *
40
--- a/include/hw/gpio/stm32l4x5_gpio.h
40
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
41
+++ b/include/hw/gpio/stm32l4x5_gpio.h
41
+ *
42
@@ -XXX,XX +XXX,XX @@
42
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
43
#define TYPE_STM32L4X5_GPIO "stm32l4x5-gpio"
43
+ * of this software and associated documentation files (the "Software"), to deal
44
OBJECT_DECLARE_SIMPLE_TYPE(Stm32l4x5GpioState, STM32L4X5_GPIO)
44
+ * in the Software without restriction, including without limitation the rights
45
45
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
46
+#define NUM_GPIOS 8
46
+ * copies of the Software, and to permit persons to whom the Software is
47
#define GPIO_NUM_PINS 16
47
+ * furnished to do so, subject to the following conditions:
48
48
+ *
49
struct Stm32l4x5GpioState {
49
+ * The above copyright notice and this permission notice shall be included in
50
diff --git a/include/hw/misc/stm32l4x5_syscfg.h b/include/hw/misc/stm32l4x5_syscfg.h
50
+ * all copies or substantial portions of the Software.
51
index XXXXXXX..XXXXXXX 100644
51
+ *
52
--- a/include/hw/misc/stm32l4x5_syscfg.h
52
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
53
+++ b/include/hw/misc/stm32l4x5_syscfg.h
53
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
54
@@ -XXX,XX +XXX,XX @@
54
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
55
55
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
56
#include "hw/sysbus.h"
56
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
57
#include "qom/object.h"
57
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
58
+#include "hw/gpio/stm32l4x5_gpio.h"
58
+ * THE SOFTWARE.
59
59
+ */
60
#define TYPE_STM32L4X5_SYSCFG "stm32l4x5-syscfg"
60
+
61
OBJECT_DECLARE_SIMPLE_TYPE(Stm32l4x5SyscfgState, STM32L4X5_SYSCFG)
61
+#ifndef HW_STM_EXTI_H
62
62
+#define HW_STM_EXTI_H
63
-#define NUM_GPIOS 8
63
+
64
-#define GPIO_NUM_PINS 16
64
+#include "hw/sysbus.h"
65
#define SYSCFG_NUM_EXTICR 4
65
+#include "hw/hw.h"
66
66
+
67
struct Stm32l4x5SyscfgState {
67
+#define EXTI_IMR 0x00
68
diff --git a/hw/arm/stm32l4x5_soc.c b/hw/arm/stm32l4x5_soc.c
68
+#define EXTI_EMR 0x04
69
index XXXXXXX..XXXXXXX 100644
69
+#define EXTI_RTSR 0x08
70
--- a/hw/arm/stm32l4x5_soc.c
70
+#define EXTI_FTSR 0x0C
71
+++ b/hw/arm/stm32l4x5_soc.c
71
+#define EXTI_SWIER 0x10
72
@@ -XXX,XX +XXX,XX @@
72
+#define EXTI_PR 0x14
73
#include "sysemu/sysemu.h"
73
+
74
#include "hw/or-irq.h"
74
+#define TYPE_STM32F4XX_EXTI "stm32f4xx-exti"
75
#include "hw/arm/stm32l4x5_soc.h"
75
+#define STM32F4XX_EXTI(obj) \
76
+#include "hw/gpio/stm32l4x5_gpio.h"
76
+ OBJECT_CHECK(STM32F4xxExtiState, (obj), TYPE_STM32F4XX_EXTI)
77
#include "hw/qdev-clock.h"
77
+
78
#include "hw/misc/unimp.h"
78
+#define NUM_GPIO_EVENT_IN_LINES 16
79
79
+#define NUM_INTERRUPT_OUT_LINES 16
80
@@ -XXX,XX +XXX,XX @@ static const int exti_or_gate1_lines_in[EXTI_OR_GATE1_NUM_LINES_IN] = {
80
+
81
16, 35, 36, 37, 38,
81
+typedef struct {
82
};
82
+ SysBusDevice parent_obj;
83
83
+
84
+static const struct {
84
+ MemoryRegion mmio;
85
+ uint32_t addr;
85
+
86
+ uint32_t moder_reset;
86
+ uint32_t exti_imr;
87
+ uint32_t ospeedr_reset;
87
+ uint32_t exti_emr;
88
+ uint32_t pupdr_reset;
88
+ uint32_t exti_rtsr;
89
+} stm32l4x5_gpio_cfg[NUM_GPIOS] = {
89
+ uint32_t exti_ftsr;
90
+ { 0x48000000, 0xABFFFFFF, 0x0C000000, 0x64000000 },
90
+ uint32_t exti_swier;
91
+ { 0x48000400, 0xFFFFFEBF, 0x00000000, 0x00000100 },
91
+ uint32_t exti_pr;
92
+ { 0x48000800, 0xFFFFFFFF, 0x00000000, 0x00000000 },
92
+
93
+ { 0x48000C00, 0xFFFFFFFF, 0x00000000, 0x00000000 },
93
+ qemu_irq irq[NUM_INTERRUPT_OUT_LINES];
94
+ { 0x48001000, 0xFFFFFFFF, 0x00000000, 0x00000000 },
94
+} STM32F4xxExtiState;
95
+ { 0x48001400, 0xFFFFFFFF, 0x00000000, 0x00000000 },
95
+
96
+ { 0x48001800, 0xFFFFFFFF, 0x00000000, 0x00000000 },
96
+#endif
97
+ { 0x48001C00, 0x0000000F, 0x00000000, 0x00000000 },
97
diff --git a/hw/misc/stm32f4xx_exti.c b/hw/misc/stm32f4xx_exti.c
98
+};
98
new file mode 100644
99
+
99
index XXXXXXX..XXXXXXX
100
static void stm32l4x5_soc_initfn(Object *obj)
100
--- /dev/null
101
{
101
+++ b/hw/misc/stm32f4xx_exti.c
102
Stm32l4x5SocState *s = STM32L4X5_SOC(obj);
102
@@ -XXX,XX +XXX,XX @@
103
@@ -XXX,XX +XXX,XX @@ static void stm32l4x5_soc_initfn(Object *obj)
103
+/*
104
}
104
+ * STM32F4XX EXTI
105
object_initialize_child(obj, "syscfg", &s->syscfg, TYPE_STM32L4X5_SYSCFG);
105
+ *
106
object_initialize_child(obj, "rcc", &s->rcc, TYPE_STM32L4X5_RCC);
106
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
107
+
107
+ *
108
+ for (unsigned i = 0; i < NUM_GPIOS; i++) {
108
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
109
+ g_autofree char *name = g_strdup_printf("gpio%c", 'a' + i);
109
+ * of this software and associated documentation files (the "Software"), to deal
110
+ object_initialize_child(obj, name, &s->gpio[i], TYPE_STM32L4X5_GPIO);
110
+ * in the Software without restriction, including without limitation the rights
111
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
112
+ * copies of the Software, and to permit persons to whom the Software is
113
+ * furnished to do so, subject to the following conditions:
114
+ *
115
+ * The above copyright notice and this permission notice shall be included in
116
+ * all copies or substantial portions of the Software.
117
+ *
118
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
119
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
120
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
121
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
122
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
123
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
124
+ * THE SOFTWARE.
125
+ */
126
+
127
+#include "qemu/osdep.h"
128
+#include "qemu/log.h"
129
+#include "trace.h"
130
+#include "hw/irq.h"
131
+#include "migration/vmstate.h"
132
+#include "hw/misc/stm32f4xx_exti.h"
133
+
134
+static void stm32f4xx_exti_reset(DeviceState *dev)
135
+{
136
+ STM32F4xxExtiState *s = STM32F4XX_EXTI(dev);
137
+
138
+ s->exti_imr = 0x00000000;
139
+ s->exti_emr = 0x00000000;
140
+ s->exti_rtsr = 0x00000000;
141
+ s->exti_ftsr = 0x00000000;
142
+ s->exti_swier = 0x00000000;
143
+ s->exti_pr = 0x00000000;
144
+}
145
+
146
+static void stm32f4xx_exti_set_irq(void *opaque, int irq, int level)
147
+{
148
+ STM32F4xxExtiState *s = opaque;
149
+
150
+ trace_stm32f4xx_exti_set_irq(irq, level);
151
+
152
+ if (((1 << irq) & s->exti_rtsr) && level) {
153
+ /* Rising Edge */
154
+ s->exti_pr |= 1 << irq;
155
+ }
111
+ }
156
+
112
}
157
+ if (((1 << irq) & s->exti_ftsr) && !level) {
113
158
+ /* Falling Edge */
114
static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
159
+ s->exti_pr |= 1 << irq;
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);
160
+ }
150
+ }
161
+
151
+
162
+ if (!((1 << irq) & s->exti_imr)) {
152
/* System configuration controller */
163
+ /* Interrupt is masked */
153
busdev = SYS_BUS_DEVICE(&s->syscfg);
164
+ return;
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
+ }
165
+ }
171
+ }
166
+ qemu_irq_pulse(s->irq[irq]);
172
167
+}
173
/* EXTI device */
168
+
174
busdev = SYS_BUS_DEVICE(&s->exti);
169
+static uint64_t stm32f4xx_exti_read(void *opaque, hwaddr addr,
175
@@ -XXX,XX +XXX,XX @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
170
+ unsigned int size)
176
}
171
+{
177
}
172
+ STM32F4xxExtiState *s = opaque;
178
173
+
179
- for (unsigned i = 0; i < 16; i++) {
174
+ trace_stm32f4xx_exti_read(addr);
180
+ for (unsigned i = 0; i < GPIO_NUM_PINS; i++) {
175
+
181
qdev_connect_gpio_out(DEVICE(&s->syscfg), i,
176
+ switch (addr) {
182
qdev_get_gpio_in(DEVICE(&s->exti), i));
177
+ case EXTI_IMR:
183
}
178
+ return s->exti_imr;
184
@@ -XXX,XX +XXX,XX @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
179
+ case EXTI_EMR:
185
/* RESERVED: 0x40024400, 0x7FDBC00 */
180
+ return s->exti_emr;
186
181
+ case EXTI_RTSR:
187
/* AHB2 BUS */
182
+ return s->exti_rtsr;
188
- create_unimplemented_device("GPIOA", 0x48000000, 0x400);
183
+ case EXTI_FTSR:
189
- create_unimplemented_device("GPIOB", 0x48000400, 0x400);
184
+ return s->exti_ftsr;
190
- create_unimplemented_device("GPIOC", 0x48000800, 0x400);
185
+ case EXTI_SWIER:
191
- create_unimplemented_device("GPIOD", 0x48000C00, 0x400);
186
+ return s->exti_swier;
192
- create_unimplemented_device("GPIOE", 0x48001000, 0x400);
187
+ case EXTI_PR:
193
- create_unimplemented_device("GPIOF", 0x48001400, 0x400);
188
+ return s->exti_pr;
194
- create_unimplemented_device("GPIOG", 0x48001800, 0x400);
189
+ default:
195
- create_unimplemented_device("GPIOH", 0x48001C00, 0x400);
190
+ qemu_log_mask(LOG_GUEST_ERROR,
196
/* RESERVED: 0x48002000, 0x7FDBC00 */
191
+ "STM32F4XX_exti_read: Bad offset %x\n", (int)addr);
197
create_unimplemented_device("OTG_FS", 0x50000000, 0x40000);
192
+ return 0;
198
create_unimplemented_device("ADC", 0x50040000, 0x400);
193
+ }
199
diff --git a/hw/misc/stm32l4x5_syscfg.c b/hw/misc/stm32l4x5_syscfg.c
194
+ return 0;
200
index XXXXXXX..XXXXXXX 100644
195
+}
201
--- a/hw/misc/stm32l4x5_syscfg.c
196
+
202
+++ b/hw/misc/stm32l4x5_syscfg.c
197
+static void stm32f4xx_exti_write(void *opaque, hwaddr addr,
203
@@ -XXX,XX +XXX,XX @@
198
+ uint64_t val64, unsigned int size)
204
#include "hw/irq.h"
199
+{
205
#include "migration/vmstate.h"
200
+ STM32F4xxExtiState *s = opaque;
206
#include "hw/misc/stm32l4x5_syscfg.h"
201
+ uint32_t value = (uint32_t) val64;
207
+#include "hw/gpio/stm32l4x5_gpio.h"
202
+
208
203
+ trace_stm32f4xx_exti_write(addr, value);
209
#define SYSCFG_MEMRMP 0x00
204
+
210
#define SYSCFG_CFGR1 0x04
205
+ switch (addr) {
206
+ case EXTI_IMR:
207
+ s->exti_imr = value;
208
+ return;
209
+ case EXTI_EMR:
210
+ s->exti_emr = value;
211
+ return;
212
+ case EXTI_RTSR:
213
+ s->exti_rtsr = value;
214
+ return;
215
+ case EXTI_FTSR:
216
+ s->exti_ftsr = value;
217
+ return;
218
+ case EXTI_SWIER:
219
+ s->exti_swier = value;
220
+ return;
221
+ case EXTI_PR:
222
+ /* This bit is cleared by writing a 1 to it */
223
+ s->exti_pr &= ~value;
224
+ return;
225
+ default:
226
+ qemu_log_mask(LOG_GUEST_ERROR,
227
+ "STM32F4XX_exti_write: Bad offset %x\n", (int)addr);
228
+ }
229
+}
230
+
231
+static const MemoryRegionOps stm32f4xx_exti_ops = {
232
+ .read = stm32f4xx_exti_read,
233
+ .write = stm32f4xx_exti_write,
234
+ .endianness = DEVICE_NATIVE_ENDIAN,
235
+};
236
+
237
+static void stm32f4xx_exti_init(Object *obj)
238
+{
239
+ STM32F4xxExtiState *s = STM32F4XX_EXTI(obj);
240
+ int i;
241
+
242
+ for (i = 0; i < NUM_INTERRUPT_OUT_LINES; i++) {
243
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq[i]);
244
+ }
245
+
246
+ memory_region_init_io(&s->mmio, obj, &stm32f4xx_exti_ops, s,
247
+ TYPE_STM32F4XX_EXTI, 0x400);
248
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
249
+
250
+ qdev_init_gpio_in(DEVICE(obj), stm32f4xx_exti_set_irq,
251
+ NUM_GPIO_EVENT_IN_LINES);
252
+}
253
+
254
+static const VMStateDescription vmstate_stm32f4xx_exti = {
255
+ .name = TYPE_STM32F4XX_EXTI,
256
+ .version_id = 1,
257
+ .minimum_version_id = 1,
258
+ .fields = (VMStateField[]) {
259
+ VMSTATE_UINT32(exti_imr, STM32F4xxExtiState),
260
+ VMSTATE_UINT32(exti_emr, STM32F4xxExtiState),
261
+ VMSTATE_UINT32(exti_rtsr, STM32F4xxExtiState),
262
+ VMSTATE_UINT32(exti_ftsr, STM32F4xxExtiState),
263
+ VMSTATE_UINT32(exti_swier, STM32F4xxExtiState),
264
+ VMSTATE_UINT32(exti_pr, STM32F4xxExtiState),
265
+ VMSTATE_END_OF_LIST()
266
+ }
267
+};
268
+
269
+static void stm32f4xx_exti_class_init(ObjectClass *klass, void *data)
270
+{
271
+ DeviceClass *dc = DEVICE_CLASS(klass);
272
+
273
+ dc->reset = stm32f4xx_exti_reset;
274
+ dc->vmsd = &vmstate_stm32f4xx_exti;
275
+}
276
+
277
+static const TypeInfo stm32f4xx_exti_info = {
278
+ .name = TYPE_STM32F4XX_EXTI,
279
+ .parent = TYPE_SYS_BUS_DEVICE,
280
+ .instance_size = sizeof(STM32F4xxExtiState),
281
+ .instance_init = stm32f4xx_exti_init,
282
+ .class_init = stm32f4xx_exti_class_init,
283
+};
284
+
285
+static void stm32f4xx_exti_register_types(void)
286
+{
287
+ type_register_static(&stm32f4xx_exti_info);
288
+}
289
+
290
+type_init(stm32f4xx_exti_register_types)
291
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
211
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
292
index XXXXXXX..XXXXXXX 100644
212
index XXXXXXX..XXXXXXX 100644
293
--- a/hw/arm/Kconfig
213
--- a/hw/arm/Kconfig
294
+++ b/hw/arm/Kconfig
214
+++ b/hw/arm/Kconfig
295
@@ -XXX,XX +XXX,XX @@ config STM32F405_SOC
215
@@ -XXX,XX +XXX,XX @@ config STM32L4X5_SOC
296
bool
216
bool
297
select ARM_V7M
217
select ARM_V7M
298
select STM32F4XX_SYSCFG
218
select OR_IRQ
299
+ select STM32F4XX_EXTI
219
- select STM32L4X5_SYSCFG
220
select STM32L4X5_EXTI
221
+ select STM32L4X5_SYSCFG
222
select STM32L4X5_RCC
223
+ select STM32L4X5_GPIO
300
224
301
config XLNX_ZYNQMP_ARM
225
config XLNX_ZYNQMP_ARM
302
bool
226
bool
303
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
304
index XXXXXXX..XXXXXXX 100644
305
--- a/hw/misc/Kconfig
306
+++ b/hw/misc/Kconfig
307
@@ -XXX,XX +XXX,XX @@ config STM32F2XX_SYSCFG
308
config STM32F4XX_SYSCFG
309
bool
310
311
+config STM32F4XX_EXTI
312
+ bool
313
+
314
config MIPS_ITU
315
bool
316
317
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
318
index XXXXXXX..XXXXXXX 100644
319
--- a/hw/misc/trace-events
320
+++ b/hw/misc/trace-events
321
@@ -XXX,XX +XXX,XX @@ stm32f4xx_pulse_exti(int irq) "Pulse EXTI: %d"
322
stm32f4xx_syscfg_read(uint64_t addr) "reg read: addr: 0x%" PRIx64 " "
323
stm32f4xx_syscfg_write(uint64_t addr, uint64_t data) "reg write: addr: 0x%" PRIx64 " val: 0x%" PRIx64 ""
324
325
+# stm32f4xx_exti
326
+stm32f4xx_exti_set_irq(int irq, int leve) "Set EXTI: %d to %d"
327
+stm32f4xx_exti_read(uint64_t addr) "reg read: addr: 0x%" PRIx64 " "
328
+stm32f4xx_exti_write(uint64_t addr, uint64_t data) "reg write: addr: 0x%" PRIx64 " val: 0x%" PRIx64 ""
329
+
330
# tz-mpc.c
331
tz_mpc_reg_read(uint32_t offset, uint64_t data, unsigned size) "TZ MPC regs read: offset 0x%x data 0x%" PRIx64 " size %u"
332
tz_mpc_reg_write(uint32_t offset, uint64_t data, unsigned size) "TZ MPC regs write: offset 0x%x data 0x%" PRIx64 " size %u"
333
--
227
--
334
2.20.1
228
2.34.1
335
229
336
230
diff view generated by jsdifflib
1
From: Martin Kaiser <martin@kaiser.cx>
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
2
3
Add an emulation for the RNGC random number generator and the compatible
3
The testcase contains :
4
RNGB variant. These peripherals are included (at least) in imx25 and
4
- `test_idr_reset_value()` :
5
imx35 chipsets.
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.
6
24
7
The emulation supports the initial self test, reseeding the prng and
25
Acked-by: Thomas Huth <thuth@redhat.com>
8
reading random numbers.
26
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
9
27
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
10
Signed-off-by: Martin Kaiser <martin@kaiser.cx>
28
Message-id: 20240305210444.310665-4-ines.varhol@telecom-paris.fr
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
30
---
14
hw/misc/Makefile.objs | 1 +
31
tests/qtest/stm32l4x5_gpio-test.c | 551 ++++++++++++++++++++++++++++++
15
include/hw/arm/fsl-imx25.h | 5 +
32
tests/qtest/meson.build | 3 +-
16
include/hw/misc/imx_rngc.h | 35 +++++
33
2 files changed, 553 insertions(+), 1 deletion(-)
17
hw/arm/fsl-imx25.c | 11 ++
34
create mode 100644 tests/qtest/stm32l4x5_gpio-test.c
18
hw/misc/imx_rngc.c | 278 +++++++++++++++++++++++++++++++++++++
19
5 files changed, 330 insertions(+)
20
create mode 100644 include/hw/misc/imx_rngc.h
21
create mode 100644 hw/misc/imx_rngc.c
22
35
23
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
36
diff --git a/tests/qtest/stm32l4x5_gpio-test.c b/tests/qtest/stm32l4x5_gpio-test.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/misc/Makefile.objs
26
+++ b/hw/misc/Makefile.objs
27
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_IMX) += imx7_ccm.o
28
common-obj-$(CONFIG_IMX) += imx2_wdt.o
29
common-obj-$(CONFIG_IMX) += imx7_snvs.o
30
common-obj-$(CONFIG_IMX) += imx7_gpr.o
31
+common-obj-$(CONFIG_IMX) += imx_rngc.o
32
common-obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
33
common-obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
34
common-obj-$(CONFIG_MAINSTONE) += mst_fpga.o
35
diff --git a/include/hw/arm/fsl-imx25.h b/include/hw/arm/fsl-imx25.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/include/hw/arm/fsl-imx25.h
38
+++ b/include/hw/arm/fsl-imx25.h
39
@@ -XXX,XX +XXX,XX @@
40
#include "hw/timer/imx_gpt.h"
41
#include "hw/timer/imx_epit.h"
42
#include "hw/net/imx_fec.h"
43
+#include "hw/misc/imx_rngc.h"
44
#include "hw/i2c/imx_i2c.h"
45
#include "hw/gpio/imx_gpio.h"
46
#include "exec/memory.h"
47
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX25State {
48
IMXGPTState gpt[FSL_IMX25_NUM_GPTS];
49
IMXEPITState epit[FSL_IMX25_NUM_EPITS];
50
IMXFECState fec;
51
+ IMXRNGCState rngc;
52
IMXI2CState i2c[FSL_IMX25_NUM_I2CS];
53
IMXGPIOState gpio[FSL_IMX25_NUM_GPIOS];
54
MemoryRegion rom[2];
55
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX25State {
56
#define FSL_IMX25_GPIO4_SIZE 0x4000
57
#define FSL_IMX25_GPIO3_ADDR 0x53FA4000
58
#define FSL_IMX25_GPIO3_SIZE 0x4000
59
+#define FSL_IMX25_RNGC_ADDR 0x53FB0000
60
+#define FSL_IMX25_RNGC_SIZE 0x4000
61
#define FSL_IMX25_GPIO1_ADDR 0x53FCC000
62
#define FSL_IMX25_GPIO1_SIZE 0x4000
63
#define FSL_IMX25_GPIO2_ADDR 0x53FD0000
64
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX25State {
65
#define FSL_IMX25_EPIT1_IRQ 28
66
#define FSL_IMX25_EPIT2_IRQ 27
67
#define FSL_IMX25_FEC_IRQ 57
68
+#define FSL_IMX25_RNGC_IRQ 22
69
#define FSL_IMX25_I2C1_IRQ 3
70
#define FSL_IMX25_I2C2_IRQ 4
71
#define FSL_IMX25_I2C3_IRQ 10
72
diff --git a/include/hw/misc/imx_rngc.h b/include/hw/misc/imx_rngc.h
73
new file mode 100644
37
new file mode 100644
74
index XXXXXXX..XXXXXXX
38
index XXXXXXX..XXXXXXX
75
--- /dev/null
39
--- /dev/null
76
+++ b/include/hw/misc/imx_rngc.h
40
+++ b/tests/qtest/stm32l4x5_gpio-test.c
77
@@ -XXX,XX +XXX,XX @@
41
@@ -XXX,XX +XXX,XX @@
78
+/*
42
+/*
79
+ * Freescale i.MX RNGC emulation
43
+ * QTest testcase for STM32L4x5_GPIO
80
+ *
44
+ *
81
+ * Copyright (C) 2020 Martin Kaiser <martin@kaiser.cx>
45
+ * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
46
+ * Copyright (c) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
82
+ *
47
+ *
83
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
48
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
84
+ * See the COPYING file in the top-level directory.
49
+ * See the COPYING file in the top-level directory.
85
+ */
50
+ */
86
+
51
+
87
+#ifndef IMX_RNGC_H
52
+#include "qemu/osdep.h"
88
+#define IMX_RNGC_H
53
+#include "libqtest-single.h"
89
+
54
+
90
+#include "hw/sysbus.h"
55
+#define GPIO_BASE_ADDR 0x48000000
91
+
56
+#define GPIO_SIZE 0x400
92
+#define TYPE_IMX_RNGC "imx.rngc"
57
+#define NUM_GPIOS 8
93
+#define IMX_RNGC(obj) OBJECT_CHECK(IMXRNGCState, (obj), TYPE_IMX_RNGC)
58
+#define NUM_GPIO_PINS 16
94
+
59
+
95
+typedef struct IMXRNGCState {
60
+#define GPIO_A 0x48000000
96
+ /*< private >*/
61
+#define GPIO_B 0x48000400
97
+ SysBusDevice parent_obj;
62
+#define GPIO_C 0x48000800
98
+
63
+#define GPIO_D 0x48000C00
99
+ /*< public >*/
64
+#define GPIO_E 0x48001000
100
+ MemoryRegion iomem;
65
+#define GPIO_F 0x48001400
101
+
66
+#define GPIO_G 0x48001800
102
+ uint8_t op_self_test;
67
+#define GPIO_H 0x48001C00
103
+ uint8_t op_seed;
68
+
104
+ uint8_t mask;
69
+#define MODER 0x00
105
+ bool auto_seed;
70
+#define OTYPER 0x04
106
+
71
+#define PUPDR 0x0C
107
+ QEMUBH *self_test_bh;
72
+#define IDR 0x10
108
+ QEMUBH *seed_bh;
73
+#define ODR 0x14
109
+ qemu_irq irq;
74
+#define BSRR 0x18
110
+} IMXRNGCState;
75
+#define BRR 0x28
111
+
76
+
112
+#endif /* IMX_RNGC_H */
77
+#define MODER_INPUT 0
113
diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
78
+#define MODER_OUTPUT 1
79
+
80
+#define PUPDR_NONE 0
81
+#define PUPDR_PULLUP 1
82
+#define PUPDR_PULLDOWN 2
83
+
84
+#define OTYPER_PUSH_PULL 0
85
+#define OTYPER_OPEN_DRAIN 1
86
+
87
+const uint32_t moder_reset[NUM_GPIOS] = {
88
+ 0xABFFFFFF,
89
+ 0xFFFFFEBF,
90
+ 0xFFFFFFFF,
91
+ 0xFFFFFFFF,
92
+ 0xFFFFFFFF,
93
+ 0xFFFFFFFF,
94
+ 0xFFFFFFFF,
95
+ 0x0000000F
96
+};
97
+
98
+const uint32_t pupdr_reset[NUM_GPIOS] = {
99
+ 0x64000000,
100
+ 0x00000100,
101
+ 0x00000000,
102
+ 0x00000000,
103
+ 0x00000000,
104
+ 0x00000000,
105
+ 0x00000000,
106
+ 0x00000000
107
+};
108
+
109
+const uint32_t idr_reset[NUM_GPIOS] = {
110
+ 0x0000A000,
111
+ 0x00000010,
112
+ 0x00000000,
113
+ 0x00000000,
114
+ 0x00000000,
115
+ 0x00000000,
116
+ 0x00000000,
117
+ 0x00000000
118
+};
119
+
120
+static uint32_t gpio_readl(unsigned int gpio, unsigned int offset)
121
+{
122
+ return readl(gpio + offset);
123
+}
124
+
125
+static void gpio_writel(unsigned int gpio, unsigned int offset, uint32_t value)
126
+{
127
+ writel(gpio + offset, value);
128
+}
129
+
130
+static void gpio_set_bit(unsigned int gpio, unsigned int reg,
131
+ unsigned int pin, uint32_t value)
132
+{
133
+ uint32_t mask = 0xFFFFFFFF & ~(0x1 << pin);
134
+ gpio_writel(gpio, reg, (gpio_readl(gpio, reg) & mask) | value << pin);
135
+}
136
+
137
+static void gpio_set_2bits(unsigned int gpio, unsigned int reg,
138
+ unsigned int pin, uint32_t value)
139
+{
140
+ uint32_t offset = 2 * pin;
141
+ uint32_t mask = 0xFFFFFFFF & ~(0x3 << offset);
142
+ gpio_writel(gpio, reg, (gpio_readl(gpio, reg) & mask) | value << offset);
143
+}
144
+
145
+static unsigned int get_gpio_id(uint32_t gpio_addr)
146
+{
147
+ return (gpio_addr - GPIO_BASE_ADDR) / GPIO_SIZE;
148
+}
149
+
150
+static void gpio_set_irq(unsigned int gpio, int num, int level)
151
+{
152
+ g_autofree char *name = g_strdup_printf("/machine/soc/gpio%c",
153
+ get_gpio_id(gpio) + 'a');
154
+ qtest_set_irq_in(global_qtest, name, NULL, num, level);
155
+}
156
+
157
+static void disconnect_all_pins(unsigned int gpio)
158
+{
159
+ g_autofree char *path = g_strdup_printf("/machine/soc/gpio%c",
160
+ get_gpio_id(gpio) + 'a');
161
+ QDict *r;
162
+
163
+ r = qtest_qmp(global_qtest, "{ 'execute': 'qom-set', 'arguments': "
164
+ "{ 'path': %s, 'property': 'disconnected-pins', 'value': %d } }",
165
+ path, 0xFFFF);
166
+ g_assert_false(qdict_haskey(r, "error"));
167
+ qobject_unref(r);
168
+}
169
+
170
+static uint32_t get_disconnected_pins(unsigned int gpio)
171
+{
172
+ g_autofree char *path = g_strdup_printf("/machine/soc/gpio%c",
173
+ get_gpio_id(gpio) + 'a');
174
+ uint32_t disconnected_pins = 0;
175
+ QDict *r;
176
+
177
+ r = qtest_qmp(global_qtest, "{ 'execute': 'qom-get', 'arguments':"
178
+ " { 'path': %s, 'property': 'disconnected-pins'} }", path);
179
+ g_assert_false(qdict_haskey(r, "error"));
180
+ disconnected_pins = qdict_get_int(r, "return");
181
+ qobject_unref(r);
182
+ return disconnected_pins;
183
+}
184
+
185
+static uint32_t reset(uint32_t gpio, unsigned int offset)
186
+{
187
+ switch (offset) {
188
+ case MODER:
189
+ return moder_reset[get_gpio_id(gpio)];
190
+ case PUPDR:
191
+ return pupdr_reset[get_gpio_id(gpio)];
192
+ case IDR:
193
+ return idr_reset[get_gpio_id(gpio)];
194
+ }
195
+ return 0x0;
196
+}
197
+
198
+static void system_reset(void)
199
+{
200
+ QDict *r;
201
+ r = qtest_qmp(global_qtest, "{'execute': 'system_reset'}");
202
+ g_assert_false(qdict_haskey(r, "error"));
203
+ qobject_unref(r);
204
+}
205
+
206
+static void test_idr_reset_value(void)
207
+{
208
+ /*
209
+ * Checks that the values in MODER, OTYPER, PUPDR and ODR
210
+ * after reset are correct, and that the value in IDR is
211
+ * coherent.
212
+ * Since AF and analog modes aren't implemented, IDR reset
213
+ * values aren't the same as with a real board.
214
+ *
215
+ * Register IDR contains the actual values of all GPIO pins.
216
+ * Its value depends on the pins' configuration
217
+ * (intput/output/analog : register MODER, push-pull/open-drain :
218
+ * register OTYPER, pull-up/pull-down/none : register PUPDR)
219
+ * and on the values stored in register ODR
220
+ * (in case the pin is in output mode).
221
+ */
222
+
223
+ gpio_writel(GPIO_A, MODER, 0xDEADBEEF);
224
+ gpio_writel(GPIO_A, ODR, 0xDEADBEEF);
225
+ gpio_writel(GPIO_A, OTYPER, 0xDEADBEEF);
226
+ gpio_writel(GPIO_A, PUPDR, 0xDEADBEEF);
227
+
228
+ gpio_writel(GPIO_B, MODER, 0xDEADBEEF);
229
+ gpio_writel(GPIO_B, ODR, 0xDEADBEEF);
230
+ gpio_writel(GPIO_B, OTYPER, 0xDEADBEEF);
231
+ gpio_writel(GPIO_B, PUPDR, 0xDEADBEEF);
232
+
233
+ gpio_writel(GPIO_C, MODER, 0xDEADBEEF);
234
+ gpio_writel(GPIO_C, ODR, 0xDEADBEEF);
235
+ gpio_writel(GPIO_C, OTYPER, 0xDEADBEEF);
236
+ gpio_writel(GPIO_C, PUPDR, 0xDEADBEEF);
237
+
238
+ gpio_writel(GPIO_H, MODER, 0xDEADBEEF);
239
+ gpio_writel(GPIO_H, ODR, 0xDEADBEEF);
240
+ gpio_writel(GPIO_H, OTYPER, 0xDEADBEEF);
241
+ gpio_writel(GPIO_H, PUPDR, 0xDEADBEEF);
242
+
243
+ system_reset();
244
+
245
+ uint32_t moder = gpio_readl(GPIO_A, MODER);
246
+ uint32_t odr = gpio_readl(GPIO_A, ODR);
247
+ uint32_t otyper = gpio_readl(GPIO_A, OTYPER);
248
+ uint32_t pupdr = gpio_readl(GPIO_A, PUPDR);
249
+ uint32_t idr = gpio_readl(GPIO_A, IDR);
250
+ /* 15: AF, 14: AF, 13: AF, 12: Analog ... */
251
+ /* here AF is the same as Analog and Input mode */
252
+ g_assert_cmphex(moder, ==, reset(GPIO_A, MODER));
253
+ g_assert_cmphex(odr, ==, reset(GPIO_A, ODR));
254
+ g_assert_cmphex(otyper, ==, reset(GPIO_A, OTYPER));
255
+ /* 15: pull-up, 14: pull-down, 13: pull-up, 12: neither ... */
256
+ g_assert_cmphex(pupdr, ==, reset(GPIO_A, PUPDR));
257
+ /* 15 : 1, 14: 0, 13: 1, 12 : reset value ... */
258
+ g_assert_cmphex(idr, ==, reset(GPIO_A, IDR));
259
+
260
+ moder = gpio_readl(GPIO_B, MODER);
261
+ odr = gpio_readl(GPIO_B, ODR);
262
+ otyper = gpio_readl(GPIO_B, OTYPER);
263
+ pupdr = gpio_readl(GPIO_B, PUPDR);
264
+ idr = gpio_readl(GPIO_B, IDR);
265
+ /* ... 5: Analog, 4: AF, 3: AF, 2: Analog ... */
266
+ /* here AF is the same as Analog and Input mode */
267
+ g_assert_cmphex(moder, ==, reset(GPIO_B, MODER));
268
+ g_assert_cmphex(odr, ==, reset(GPIO_B, ODR));
269
+ g_assert_cmphex(otyper, ==, reset(GPIO_B, OTYPER));
270
+ /* ... 5: neither, 4: pull-up, 3: neither ... */
271
+ g_assert_cmphex(pupdr, ==, reset(GPIO_B, PUPDR));
272
+ /* ... 5 : reset value, 4 : 1, 3 : reset value ... */
273
+ g_assert_cmphex(idr, ==, reset(GPIO_B, IDR));
274
+
275
+ moder = gpio_readl(GPIO_C, MODER);
276
+ odr = gpio_readl(GPIO_C, ODR);
277
+ otyper = gpio_readl(GPIO_C, OTYPER);
278
+ pupdr = gpio_readl(GPIO_C, PUPDR);
279
+ idr = gpio_readl(GPIO_C, IDR);
280
+ /* Analog, same as Input mode*/
281
+ g_assert_cmphex(moder, ==, reset(GPIO_C, MODER));
282
+ g_assert_cmphex(odr, ==, reset(GPIO_C, ODR));
283
+ g_assert_cmphex(otyper, ==, reset(GPIO_C, OTYPER));
284
+ /* no pull-up or pull-down */
285
+ g_assert_cmphex(pupdr, ==, reset(GPIO_C, PUPDR));
286
+ /* reset value */
287
+ g_assert_cmphex(idr, ==, reset(GPIO_C, IDR));
288
+
289
+ moder = gpio_readl(GPIO_H, MODER);
290
+ odr = gpio_readl(GPIO_H, ODR);
291
+ otyper = gpio_readl(GPIO_H, OTYPER);
292
+ pupdr = gpio_readl(GPIO_H, PUPDR);
293
+ idr = gpio_readl(GPIO_H, IDR);
294
+ /* Analog, same as Input mode */
295
+ g_assert_cmphex(moder, ==, reset(GPIO_H, MODER));
296
+ g_assert_cmphex(odr, ==, reset(GPIO_H, ODR));
297
+ g_assert_cmphex(otyper, ==, reset(GPIO_H, OTYPER));
298
+ /* no pull-up or pull-down */
299
+ g_assert_cmphex(pupdr, ==, reset(GPIO_H, PUPDR));
300
+ /* reset value */
301
+ g_assert_cmphex(idr, ==, reset(GPIO_H, IDR));
302
+}
303
+
304
+static void test_gpio_output_mode(const void *data)
305
+{
306
+ /*
307
+ * Checks that setting a bit in ODR sets the corresponding
308
+ * GPIO line high : it should set the right bit in IDR
309
+ * and send an irq to syscfg.
310
+ * Additionally, it checks that values written to ODR
311
+ * when not in output mode are stored and not discarded.
312
+ */
313
+ unsigned int pin = ((uint64_t)data) & 0xF;
314
+ uint32_t gpio = ((uint64_t)data) >> 32;
315
+ unsigned int gpio_id = get_gpio_id(gpio);
316
+
317
+ qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
318
+
319
+ /* Set a bit in ODR and check nothing happens */
320
+ gpio_set_bit(gpio, ODR, pin, 1);
321
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR));
322
+ g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin));
323
+
324
+ /* Configure the relevant line as output and check the pin is high */
325
+ gpio_set_2bits(gpio, MODER, pin, MODER_OUTPUT);
326
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) | (1 << pin));
327
+ g_assert_true(get_irq(gpio_id * NUM_GPIO_PINS + pin));
328
+
329
+ /* Reset the bit in ODR and check the pin is low */
330
+ gpio_set_bit(gpio, ODR, pin, 0);
331
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin));
332
+ g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin));
333
+
334
+ /* Clean the test */
335
+ gpio_writel(gpio, ODR, reset(gpio, ODR));
336
+ gpio_writel(gpio, MODER, reset(gpio, MODER));
337
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR));
338
+ g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin));
339
+}
340
+
341
+static void test_gpio_input_mode(const void *data)
342
+{
343
+ /*
344
+ * Test that setting a line high/low externally sets the
345
+ * corresponding GPIO line high/low : it should set the
346
+ * right bit in IDR and send an irq to syscfg.
347
+ */
348
+ unsigned int pin = ((uint64_t)data) & 0xF;
349
+ uint32_t gpio = ((uint64_t)data) >> 32;
350
+ unsigned int gpio_id = get_gpio_id(gpio);
351
+
352
+ qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
353
+
354
+ /* Configure a line as input, raise it, and check that the pin is high */
355
+ gpio_set_2bits(gpio, MODER, pin, MODER_INPUT);
356
+ gpio_set_irq(gpio, pin, 1);
357
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) | (1 << pin));
358
+ g_assert_true(get_irq(gpio_id * NUM_GPIO_PINS + pin));
359
+
360
+ /* Lower the line and check that the pin is low */
361
+ gpio_set_irq(gpio, pin, 0);
362
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin));
363
+ g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin));
364
+
365
+ /* Clean the test */
366
+ gpio_writel(gpio, MODER, reset(gpio, MODER));
367
+ disconnect_all_pins(gpio);
368
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR));
369
+}
370
+
371
+static void test_pull_up_pull_down(const void *data)
372
+{
373
+ /*
374
+ * Test that a floating pin with pull-up sets the pin
375
+ * high and vice-versa.
376
+ */
377
+ unsigned int pin = ((uint64_t)data) & 0xF;
378
+ uint32_t gpio = ((uint64_t)data) >> 32;
379
+ unsigned int gpio_id = get_gpio_id(gpio);
380
+
381
+ qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
382
+
383
+ /* Configure a line as input with pull-up, check the line is set high */
384
+ gpio_set_2bits(gpio, MODER, pin, MODER_INPUT);
385
+ gpio_set_2bits(gpio, PUPDR, pin, PUPDR_PULLUP);
386
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) | (1 << pin));
387
+ g_assert_true(get_irq(gpio_id * NUM_GPIO_PINS + pin));
388
+
389
+ /* Configure the line with pull-down, check the line is low */
390
+ gpio_set_2bits(gpio, PUPDR, pin, PUPDR_PULLDOWN);
391
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin));
392
+ g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin));
393
+
394
+ /* Clean the test */
395
+ gpio_writel(gpio, MODER, reset(gpio, MODER));
396
+ gpio_writel(gpio, PUPDR, reset(gpio, PUPDR));
397
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR));
398
+}
399
+
400
+static void test_push_pull(const void *data)
401
+{
402
+ /*
403
+ * Test that configuring a line in push-pull output mode
404
+ * disconnects the pin, that the pin can't be set or reset
405
+ * externally afterwards.
406
+ */
407
+ unsigned int pin = ((uint64_t)data) & 0xF;
408
+ uint32_t gpio = ((uint64_t)data) >> 32;
409
+ uint32_t gpio2 = GPIO_BASE_ADDR + (GPIO_H - gpio);
410
+
411
+ qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
412
+
413
+ /* Setting a line high externally, configuring it in push-pull output */
414
+ /* And checking the pin was disconnected */
415
+ gpio_set_irq(gpio, pin, 1);
416
+ gpio_set_2bits(gpio, MODER, pin, MODER_OUTPUT);
417
+ g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF);
418
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin));
419
+
420
+ /* Setting a line low externally, configuring it in push-pull output */
421
+ /* And checking the pin was disconnected */
422
+ gpio_set_irq(gpio2, pin, 0);
423
+ gpio_set_bit(gpio2, ODR, pin, 1);
424
+ gpio_set_2bits(gpio2, MODER, pin, MODER_OUTPUT);
425
+ g_assert_cmphex(get_disconnected_pins(gpio2), ==, 0xFFFF);
426
+ g_assert_cmphex(gpio_readl(gpio2, IDR), ==, reset(gpio2, IDR) | (1 << pin));
427
+
428
+ /* Trying to set a push-pull output pin, checking it doesn't work */
429
+ gpio_set_irq(gpio, pin, 1);
430
+ g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF);
431
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin));
432
+
433
+ /* Trying to reset a push-pull output pin, checking it doesn't work */
434
+ gpio_set_irq(gpio2, pin, 0);
435
+ g_assert_cmphex(get_disconnected_pins(gpio2), ==, 0xFFFF);
436
+ g_assert_cmphex(gpio_readl(gpio2, IDR), ==, reset(gpio2, IDR) | (1 << pin));
437
+
438
+ /* Clean the test */
439
+ gpio_writel(gpio, MODER, reset(gpio, MODER));
440
+ gpio_writel(gpio2, ODR, reset(gpio2, ODR));
441
+ gpio_writel(gpio2, MODER, reset(gpio2, MODER));
442
+}
443
+
444
+static void test_open_drain(const void *data)
445
+{
446
+ /*
447
+ * Test that configuring a line in open-drain output mode
448
+ * disconnects a pin set high externally and that the pin
449
+ * can't be set high externally while configured in open-drain.
450
+ *
451
+ * However a pin set low externally shouldn't be disconnected,
452
+ * and it can be set low externally when in open-drain mode.
453
+ */
454
+ unsigned int pin = ((uint64_t)data) & 0xF;
455
+ uint32_t gpio = ((uint64_t)data) >> 32;
456
+ uint32_t gpio2 = GPIO_BASE_ADDR + (GPIO_H - gpio);
457
+
458
+ qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
459
+
460
+ /* Setting a line high externally, configuring it in open-drain output */
461
+ /* And checking the pin was disconnected */
462
+ gpio_set_irq(gpio, pin, 1);
463
+ gpio_set_bit(gpio, OTYPER, pin, OTYPER_OPEN_DRAIN);
464
+ gpio_set_2bits(gpio, MODER, pin, MODER_OUTPUT);
465
+ g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF);
466
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin));
467
+
468
+ /* Setting a line low externally, configuring it in open-drain output */
469
+ /* And checking the pin wasn't disconnected */
470
+ gpio_set_irq(gpio2, pin, 0);
471
+ gpio_set_bit(gpio2, ODR, pin, 1);
472
+ gpio_set_bit(gpio2, OTYPER, pin, OTYPER_OPEN_DRAIN);
473
+ gpio_set_2bits(gpio2, MODER, pin, MODER_OUTPUT);
474
+ g_assert_cmphex(get_disconnected_pins(gpio2), ==, 0xFFFF & ~(1 << pin));
475
+ g_assert_cmphex(gpio_readl(gpio2, IDR), ==,
476
+ reset(gpio2, IDR) & ~(1 << pin));
477
+
478
+ /* Trying to set a open-drain output pin, checking it doesn't work */
479
+ gpio_set_irq(gpio, pin, 1);
480
+ g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF);
481
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin));
482
+
483
+ /* Trying to reset a open-drain output pin, checking it works */
484
+ gpio_set_bit(gpio, ODR, pin, 1);
485
+ gpio_set_irq(gpio, pin, 0);
486
+ g_assert_cmphex(get_disconnected_pins(gpio2), ==, 0xFFFF & ~(1 << pin));
487
+ g_assert_cmphex(gpio_readl(gpio2, IDR), ==,
488
+ reset(gpio2, IDR) & ~(1 << pin));
489
+
490
+ /* Clean the test */
491
+ disconnect_all_pins(gpio2);
492
+ gpio_writel(gpio2, OTYPER, reset(gpio2, OTYPER));
493
+ gpio_writel(gpio2, ODR, reset(gpio2, ODR));
494
+ gpio_writel(gpio2, MODER, reset(gpio2, MODER));
495
+ g_assert_cmphex(gpio_readl(gpio2, IDR), ==, reset(gpio2, IDR));
496
+ disconnect_all_pins(gpio);
497
+ gpio_writel(gpio, OTYPER, reset(gpio, OTYPER));
498
+ gpio_writel(gpio, ODR, reset(gpio, ODR));
499
+ gpio_writel(gpio, MODER, reset(gpio, MODER));
500
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR));
501
+}
502
+
503
+static void test_bsrr_brr(const void *data)
504
+{
505
+ /*
506
+ * Test that writing a '1' in BSS and BSRR
507
+ * has the desired effect on ODR.
508
+ * In BSRR, BSx has priority over BRx.
509
+ */
510
+ unsigned int pin = ((uint64_t)data) & 0xF;
511
+ uint32_t gpio = ((uint64_t)data) >> 32;
512
+
513
+ gpio_writel(gpio, BSRR, (1 << pin));
514
+ g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR) | (1 << pin));
515
+
516
+ gpio_writel(gpio, BSRR, (1 << (pin + NUM_GPIO_PINS)));
517
+ g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR));
518
+
519
+ gpio_writel(gpio, BSRR, (1 << pin));
520
+ g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR) | (1 << pin));
521
+
522
+ gpio_writel(gpio, BRR, (1 << pin));
523
+ g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR));
524
+
525
+ /* BSx should have priority over BRx */
526
+ gpio_writel(gpio, BSRR, (1 << pin) | (1 << (pin + NUM_GPIO_PINS)));
527
+ g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR) | (1 << pin));
528
+
529
+ gpio_writel(gpio, BRR, (1 << pin));
530
+ g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR));
531
+
532
+ gpio_writel(gpio, ODR, reset(gpio, ODR));
533
+}
534
+
535
+int main(int argc, char **argv)
536
+{
537
+ int ret;
538
+
539
+ g_test_init(&argc, &argv, NULL);
540
+ g_test_set_nonfatal_assertions();
541
+ qtest_add_func("stm32l4x5/gpio/test_idr_reset_value",
542
+ test_idr_reset_value);
543
+ /*
544
+ * The inputs for the tests (gpio and pin) can be changed,
545
+ * but the tests don't work for pins that are high at reset
546
+ * (GPIOA15, GPIO13 and GPIOB5).
547
+ * Specifically, rising the pin then checking `get_irq()`
548
+ * is problematic since the pin was already high.
549
+ */
550
+ qtest_add_data_func("stm32l4x5/gpio/test_gpioc5_output_mode",
551
+ (void *)((uint64_t)GPIO_C << 32 | 5),
552
+ test_gpio_output_mode);
553
+ qtest_add_data_func("stm32l4x5/gpio/test_gpioh3_output_mode",
554
+ (void *)((uint64_t)GPIO_H << 32 | 3),
555
+ test_gpio_output_mode);
556
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_input_mode1",
557
+ (void *)((uint64_t)GPIO_D << 32 | 6),
558
+ test_gpio_input_mode);
559
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_input_mode2",
560
+ (void *)((uint64_t)GPIO_C << 32 | 10),
561
+ test_gpio_input_mode);
562
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_pull_up_pull_down1",
563
+ (void *)((uint64_t)GPIO_B << 32 | 5),
564
+ test_pull_up_pull_down);
565
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_pull_up_pull_down2",
566
+ (void *)((uint64_t)GPIO_F << 32 | 1),
567
+ test_pull_up_pull_down);
568
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_push_pull1",
569
+ (void *)((uint64_t)GPIO_G << 32 | 6),
570
+ test_push_pull);
571
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_push_pull2",
572
+ (void *)((uint64_t)GPIO_H << 32 | 3),
573
+ test_push_pull);
574
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_open_drain1",
575
+ (void *)((uint64_t)GPIO_C << 32 | 4),
576
+ test_open_drain);
577
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_open_drain2",
578
+ (void *)((uint64_t)GPIO_E << 32 | 11),
579
+ test_open_drain);
580
+ qtest_add_data_func("stm32l4x5/gpio/test_bsrr_brr1",
581
+ (void *)((uint64_t)GPIO_A << 32 | 12),
582
+ test_bsrr_brr);
583
+ qtest_add_data_func("stm32l4x5/gpio/test_bsrr_brr2",
584
+ (void *)((uint64_t)GPIO_D << 32 | 0),
585
+ test_bsrr_brr);
586
+
587
+ qtest_start("-machine b-l475e-iot01a");
588
+ ret = g_test_run();
589
+ qtest_end();
590
+
591
+ return ret;
592
+}
593
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
114
index XXXXXXX..XXXXXXX 100644
594
index XXXXXXX..XXXXXXX 100644
115
--- a/hw/arm/fsl-imx25.c
595
--- a/tests/qtest/meson.build
116
+++ b/hw/arm/fsl-imx25.c
596
+++ b/tests/qtest/meson.build
117
@@ -XXX,XX +XXX,XX @@ static void fsl_imx25_init(Object *obj)
597
@@ -XXX,XX +XXX,XX @@ qtests_aspeed = \
118
598
qtests_stm32l4x5 = \
119
sysbus_init_child_obj(obj, "fec", &s->fec, sizeof(s->fec), TYPE_IMX_FEC);
599
['stm32l4x5_exti-test',
120
600
'stm32l4x5_syscfg-test',
121
+ sysbus_init_child_obj(obj, "rngc", &s->rngc, sizeof(s->rngc),
601
- 'stm32l4x5_rcc-test']
122
+ TYPE_IMX_RNGC);
602
+ 'stm32l4x5_rcc-test',
123
+
603
+ 'stm32l4x5_gpio-test']
124
for (i = 0; i < FSL_IMX25_NUM_I2CS; i++) {
604
125
sysbus_init_child_obj(obj, "i2c[*]", &s->i2c[i], sizeof(s->i2c[i]),
605
qtests_arm = \
126
TYPE_IMX_I2C);
606
(config_all_devices.has_key('CONFIG_MPS2') ? ['sse-timer-test'] : []) + \
127
@@ -XXX,XX +XXX,XX @@ static void fsl_imx25_realize(DeviceState *dev, Error **errp)
128
sysbus_connect_irq(SYS_BUS_DEVICE(&s->fec), 0,
129
qdev_get_gpio_in(DEVICE(&s->avic), FSL_IMX25_FEC_IRQ));
130
131
+ object_property_set_bool(OBJECT(&s->rngc), true, "realized", &err);
132
+ if (err) {
133
+ error_propagate(errp, err);
134
+ return;
135
+ }
136
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->rngc), 0, FSL_IMX25_RNGC_ADDR);
137
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->rngc), 0,
138
+ qdev_get_gpio_in(DEVICE(&s->avic), FSL_IMX25_RNGC_IRQ));
139
140
/* Initialize all I2C */
141
for (i = 0; i < FSL_IMX25_NUM_I2CS; i++) {
142
diff --git a/hw/misc/imx_rngc.c b/hw/misc/imx_rngc.c
143
new file mode 100644
144
index XXXXXXX..XXXXXXX
145
--- /dev/null
146
+++ b/hw/misc/imx_rngc.c
147
@@ -XXX,XX +XXX,XX @@
148
+/*
149
+ * Freescale i.MX RNGC emulation
150
+ *
151
+ * Copyright (C) 2020 Martin Kaiser <martin@kaiser.cx>
152
+ *
153
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
154
+ * See the COPYING file in the top-level directory.
155
+ *
156
+ * This driver provides the minimum functionality to initialize and seed
157
+ * an rngc and to read random numbers. The rngb that is found in imx25
158
+ * chipsets is also supported.
159
+ */
160
+
161
+#include "qemu/osdep.h"
162
+#include "qemu/main-loop.h"
163
+#include "qemu/module.h"
164
+#include "qemu/log.h"
165
+#include "qemu/guest-random.h"
166
+#include "hw/irq.h"
167
+#include "hw/misc/imx_rngc.h"
168
+#include "migration/vmstate.h"
169
+
170
+#define RNGC_NAME "i.MX RNGC"
171
+
172
+#define RNGC_VER_ID 0x00
173
+#define RNGC_COMMAND 0x04
174
+#define RNGC_CONTROL 0x08
175
+#define RNGC_STATUS 0x0C
176
+#define RNGC_FIFO 0x14
177
+
178
+/* These version info are reported by the rngb in an imx258 chip. */
179
+#define RNG_TYPE_RNGB 0x1
180
+#define V_MAJ 0x2
181
+#define V_MIN 0x40
182
+
183
+#define RNGC_CMD_BIT_SW_RST 0x40
184
+#define RNGC_CMD_BIT_CLR_ERR 0x20
185
+#define RNGC_CMD_BIT_CLR_INT 0x10
186
+#define RNGC_CMD_BIT_SEED 0x02
187
+#define RNGC_CMD_BIT_SELF_TEST 0x01
188
+
189
+#define RNGC_CTRL_BIT_MASK_ERR 0x40
190
+#define RNGC_CTRL_BIT_MASK_DONE 0x20
191
+#define RNGC_CTRL_BIT_AUTO_SEED 0x10
192
+
193
+/* the current status for self-test and seed operations */
194
+#define OP_IDLE 0
195
+#define OP_RUN 1
196
+#define OP_DONE 2
197
+
198
+static uint64_t imx_rngc_read(void *opaque, hwaddr offset, unsigned size)
199
+{
200
+ IMXRNGCState *s = IMX_RNGC(opaque);
201
+ uint64_t val = 0;
202
+
203
+ switch (offset) {
204
+ case RNGC_VER_ID:
205
+ val |= RNG_TYPE_RNGB << 28 | V_MAJ << 8 | V_MIN;
206
+ break;
207
+
208
+ case RNGC_COMMAND:
209
+ if (s->op_seed == OP_RUN) {
210
+ val |= RNGC_CMD_BIT_SEED;
211
+ }
212
+ if (s->op_self_test == OP_RUN) {
213
+ val |= RNGC_CMD_BIT_SELF_TEST;
214
+ }
215
+ break;
216
+
217
+ case RNGC_CONTROL:
218
+ /*
219
+ * The CTL_ACC and VERIF_MODE bits are not supported yet.
220
+ * They read as 0.
221
+ */
222
+ val |= s->mask;
223
+ if (s->auto_seed) {
224
+ val |= RNGC_CTRL_BIT_AUTO_SEED;
225
+ }
226
+ /*
227
+ * We don't have an internal fifo like the real hardware.
228
+ * There's no need for strategy to handle fifo underflows.
229
+ * We return the FIFO_UFLOW_RESPONSE bits as 0.
230
+ */
231
+ break;
232
+
233
+ case RNGC_STATUS:
234
+ /*
235
+ * We never report any statistics test or self-test errors or any
236
+ * other errors. STAT_TEST_PF, ST_PF and ERROR are always 0.
237
+ */
238
+
239
+ /*
240
+ * We don't have an internal fifo, see above. Therefore, we
241
+ * report back the default fifo size (5 32-bit words) and
242
+ * indicate that our fifo is always full.
243
+ */
244
+ val |= 5 << 12 | 5 << 8;
245
+
246
+ /* We always have a new seed available. */
247
+ val |= 1 << 6;
248
+
249
+ if (s->op_seed == OP_DONE) {
250
+ val |= 1 << 5;
251
+ }
252
+ if (s->op_self_test == OP_DONE) {
253
+ val |= 1 << 4;
254
+ }
255
+ if (s->op_seed == OP_RUN || s->op_self_test == OP_RUN) {
256
+ /*
257
+ * We're busy if self-test is running or if we're
258
+ * seeding the prng.
259
+ */
260
+ val |= 1 << 1;
261
+ } else {
262
+ /*
263
+ * We're ready to provide secure random numbers whenever
264
+ * we're not busy.
265
+ */
266
+ val |= 1;
267
+ }
268
+ break;
269
+
270
+ case RNGC_FIFO:
271
+ qemu_guest_getrandom_nofail(&val, sizeof(val));
272
+ break;
273
+ }
274
+
275
+ return val;
276
+}
277
+
278
+static void imx_rngc_do_reset(IMXRNGCState *s)
279
+{
280
+ s->op_self_test = OP_IDLE;
281
+ s->op_seed = OP_IDLE;
282
+ s->mask = 0;
283
+ s->auto_seed = false;
284
+}
285
+
286
+static void imx_rngc_write(void *opaque, hwaddr offset, uint64_t value,
287
+ unsigned size)
288
+{
289
+ IMXRNGCState *s = IMX_RNGC(opaque);
290
+
291
+ switch (offset) {
292
+ case RNGC_COMMAND:
293
+ if (value & RNGC_CMD_BIT_SW_RST) {
294
+ imx_rngc_do_reset(s);
295
+ }
296
+
297
+ /*
298
+ * For now, both CLR_ERR and CLR_INT clear the interrupt. We
299
+ * don't report any errors yet.
300
+ */
301
+ if (value & (RNGC_CMD_BIT_CLR_ERR | RNGC_CMD_BIT_CLR_INT)) {
302
+ qemu_irq_lower(s->irq);
303
+ }
304
+
305
+ if (value & RNGC_CMD_BIT_SEED) {
306
+ s->op_seed = OP_RUN;
307
+ qemu_bh_schedule(s->seed_bh);
308
+ }
309
+
310
+ if (value & RNGC_CMD_BIT_SELF_TEST) {
311
+ s->op_self_test = OP_RUN;
312
+ qemu_bh_schedule(s->self_test_bh);
313
+ }
314
+ break;
315
+
316
+ case RNGC_CONTROL:
317
+ /*
318
+ * The CTL_ACC and VERIF_MODE bits are not supported yet.
319
+ * We ignore them if they're set by the caller.
320
+ */
321
+
322
+ if (value & RNGC_CTRL_BIT_MASK_ERR) {
323
+ s->mask |= RNGC_CTRL_BIT_MASK_ERR;
324
+ } else {
325
+ s->mask &= ~RNGC_CTRL_BIT_MASK_ERR;
326
+ }
327
+
328
+ if (value & RNGC_CTRL_BIT_MASK_DONE) {
329
+ s->mask |= RNGC_CTRL_BIT_MASK_DONE;
330
+ } else {
331
+ s->mask &= ~RNGC_CTRL_BIT_MASK_DONE;
332
+ }
333
+
334
+ if (value & RNGC_CTRL_BIT_AUTO_SEED) {
335
+ s->auto_seed = true;
336
+ } else {
337
+ s->auto_seed = false;
338
+ }
339
+ break;
340
+ }
341
+}
342
+
343
+static const MemoryRegionOps imx_rngc_ops = {
344
+ .read = imx_rngc_read,
345
+ .write = imx_rngc_write,
346
+ .endianness = DEVICE_NATIVE_ENDIAN,
347
+};
348
+
349
+static void imx_rngc_self_test(void *opaque)
350
+{
351
+ IMXRNGCState *s = IMX_RNGC(opaque);
352
+
353
+ s->op_self_test = OP_DONE;
354
+ if (!(s->mask & RNGC_CTRL_BIT_MASK_DONE)) {
355
+ qemu_irq_raise(s->irq);
356
+ }
357
+}
358
+
359
+static void imx_rngc_seed(void *opaque)
360
+{
361
+ IMXRNGCState *s = IMX_RNGC(opaque);
362
+
363
+ s->op_seed = OP_DONE;
364
+ if (!(s->mask & RNGC_CTRL_BIT_MASK_DONE)) {
365
+ qemu_irq_raise(s->irq);
366
+ }
367
+}
368
+
369
+static void imx_rngc_realize(DeviceState *dev, Error **errp)
370
+{
371
+ IMXRNGCState *s = IMX_RNGC(dev);
372
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
373
+
374
+ memory_region_init_io(&s->iomem, OBJECT(s), &imx_rngc_ops, s,
375
+ TYPE_IMX_RNGC, 0x1000);
376
+ sysbus_init_mmio(sbd, &s->iomem);
377
+
378
+ sysbus_init_irq(sbd, &s->irq);
379
+ s->self_test_bh = qemu_bh_new(imx_rngc_self_test, s);
380
+ s->seed_bh = qemu_bh_new(imx_rngc_seed, s);
381
+}
382
+
383
+static void imx_rngc_reset(DeviceState *dev)
384
+{
385
+ IMXRNGCState *s = IMX_RNGC(dev);
386
+
387
+ imx_rngc_do_reset(s);
388
+}
389
+
390
+static const VMStateDescription vmstate_imx_rngc = {
391
+ .name = RNGC_NAME,
392
+ .version_id = 1,
393
+ .minimum_version_id = 1,
394
+ .fields = (VMStateField[]) {
395
+ VMSTATE_UINT8(op_self_test, IMXRNGCState),
396
+ VMSTATE_UINT8(op_seed, IMXRNGCState),
397
+ VMSTATE_UINT8(mask, IMXRNGCState),
398
+ VMSTATE_BOOL(auto_seed, IMXRNGCState),
399
+ VMSTATE_END_OF_LIST()
400
+ }
401
+};
402
+
403
+static void imx_rngc_class_init(ObjectClass *klass, void *data)
404
+{
405
+ DeviceClass *dc = DEVICE_CLASS(klass);
406
+
407
+ dc->realize = imx_rngc_realize;
408
+ dc->reset = imx_rngc_reset;
409
+ dc->desc = RNGC_NAME,
410
+ dc->vmsd = &vmstate_imx_rngc;
411
+}
412
+
413
+static const TypeInfo imx_rngc_info = {
414
+ .name = TYPE_IMX_RNGC,
415
+ .parent = TYPE_SYS_BUS_DEVICE,
416
+ .instance_size = sizeof(IMXRNGCState),
417
+ .class_init = imx_rngc_class_init,
418
+};
419
+
420
+static void imx_rngc_register_types(void)
421
+{
422
+ type_register_static(&imx_rngc_info);
423
+}
424
+
425
+type_init(imx_rngc_register_types)
426
--
607
--
427
2.20.1
608
2.34.1
428
609
429
610
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
During the conversion to decodetree, the setting of
3
While the 8-bit input elements are sequential in the input vector,
4
ISSIs16Bit got lost. This causes the guest os to
4
the 32-bit output elements are not sequential in the output matrix.
5
incorrectly adjust trapping memory operations.
5
Do not attempt to compute 2 32-bit outputs at the same time.
6
6
7
Cc: qemu-stable@nongnu.org
7
Cc: qemu-stable@nongnu.org
8
Fixes: 46beb58efbb8a2a32 ("target/arm: Convert T16, load (literal)")
8
Fixes: 23a5e3859f5 ("target/arm: Implement SME integer outer product")
9
Reported-by: Jeff Kubascik <jeff.kubascik@dornerworks.com>
9
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2083
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20200117004618.2742-3-richard.henderson@linaro.org
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20240305163931.242795-1-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
14
---
15
target/arm/translate.c | 3 +++
15
target/arm/tcg/sme_helper.c | 77 ++++++++++++++++++-------------
16
1 file changed, 3 insertions(+)
16
tests/tcg/aarch64/sme-smopa-1.c | 47 +++++++++++++++++++
17
17
tests/tcg/aarch64/sme-smopa-2.c | 54 ++++++++++++++++++++++
18
diff --git a/target/arm/translate.c b/target/arm/translate.c
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
19
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate.c
25
--- a/target/arm/tcg/sme_helper.c
21
+++ b/target/arm/translate.c
26
+++ b/target/arm/tcg/sme_helper.c
22
@@ -XXX,XX +XXX,XX @@ static ISSInfo make_issinfo(DisasContext *s, int rd, bool p, bool w)
27
@@ -XXX,XX +XXX,XX @@ void HELPER(sme_bfmopa)(void *vza, void *vzn, void *vzm, void *vpn,
23
/* ISS not valid if writeback */
28
}
24
if (p && !w) {
29
}
25
ret = rd;
30
26
+ if (s->base.pc_next - s->pc_curr == 2) {
31
-typedef uint64_t IMOPFn(uint64_t, uint64_t, uint64_t, uint8_t, bool);
27
+ ret |= ISSIs16Bit;
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);
28
+ }
53
+ }
29
} else {
54
+ }
30
ret = ISSInvalid;
55
+}
31
}
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
32
--
253
--
33
2.20.1
254
2.34.1
34
255
35
256
diff view generated by jsdifflib
1
From: Masahiro Yamada <masahiroy@kernel.org>
1
The sun4v RTC device model added under commit a0e893039cf2ce0 in 2016
2
was unfortunately added with a license of GPL-v3-or-later, which is
3
not compatible with other QEMU code which has a GPL-v2-only license.
2
4
3
According to the specification "Semihosting for AArch32 and Aarch64",
5
Relicense the code in the .c and the .h file to GPL-v2-or-later,
4
the SYS_OPEN operation should return:
6
to make it compatible with the rest of QEMU.
5
7
6
- A nonzero handle if the call is successful
7
- -1 if the call is not successful
8
9
So, it should never return 0.
10
11
Prior to commit 35e9a0a8ce4b ("target/arm/arm-semi: Make semihosting
12
code hand out its own file descriptors"), the guest fd matched to the
13
host fd. It returned a nonzero handle on success since the fd 0 is
14
already used for stdin.
15
16
Now that the guest fd is the index of guestfd_array, it starts from 0.
17
18
I noticed this issue particularly because Trusted Firmware-A built with
19
PLAT=qemu is no longer working. Its io_semihosting driver only handles
20
a positive return value as a valid filehandle.
21
22
Basically, there are two ways to fix this:
23
24
- Use (guestfd - 1) as the index of guestfs_arrary. We need to insert
25
increment/decrement to convert the guestfd and the array index back
26
and forth.
27
28
- Keep using guestfd as the index of guestfs_array. The first entry
29
of guestfs_array is left unused.
30
31
I thought the latter is simpler. We end up with wasting a small piece
32
of memory for the unused first entry of guestfd_array, but this is
33
probably not a big deal.
34
35
Fixes: 35e9a0a8ce4b ("target/arm/arm-semi: Make semihosting code hand out its own file descriptors")
36
Cc: qemu-stable@nongnu.org
8
Cc: qemu-stable@nongnu.org
37
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
38
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Paolo Bonzini (for Red Hat) <pbonzini@redhat.com>
39
Message-id: 20200109041228.10131-1-masahiroy@kernel.org
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
40
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
41
---
19
---
42
target/arm/arm-semi.c | 5 +++--
20
include/hw/rtc/sun4v-rtc.h | 2 +-
43
1 file changed, 3 insertions(+), 2 deletions(-)
21
hw/rtc/sun4v-rtc.c | 2 +-
22
2 files changed, 2 insertions(+), 2 deletions(-)
44
23
45
diff --git a/target/arm/arm-semi.c b/target/arm/arm-semi.c
24
diff --git a/include/hw/rtc/sun4v-rtc.h b/include/hw/rtc/sun4v-rtc.h
46
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/arm-semi.c
26
--- a/include/hw/rtc/sun4v-rtc.h
48
+++ b/target/arm/arm-semi.c
27
+++ b/include/hw/rtc/sun4v-rtc.h
49
@@ -XXX,XX +XXX,XX @@ static int alloc_guestfd(void)
28
@@ -XXX,XX +XXX,XX @@
50
guestfd_array = g_array_new(FALSE, TRUE, sizeof(GuestFD));
29
*
51
}
30
* Copyright (c) 2016 Artyom Tarasenko
52
31
*
53
- for (i = 0; i < guestfd_array->len; i++) {
32
- * This code is licensed under the GNU GPL v3 or (at your option) any later
54
+ /* SYS_OPEN should return nonzero handle on success. Start guestfd from 1 */
33
+ * This code is licensed under the GNU GPL v2 or (at your option) any later
55
+ for (i = 1; i < guestfd_array->len; i++) {
34
* version.
56
GuestFD *gf = &g_array_index(guestfd_array, GuestFD, i);
35
*/
57
36
58
if (gf->type == GuestFDUnused) {
37
diff --git a/hw/rtc/sun4v-rtc.c b/hw/rtc/sun4v-rtc.c
59
@@ -XXX,XX +XXX,XX @@ static GuestFD *do_get_guestfd(int guestfd)
38
index XXXXXXX..XXXXXXX 100644
60
return NULL;
39
--- a/hw/rtc/sun4v-rtc.c
61
}
40
+++ b/hw/rtc/sun4v-rtc.c
62
41
@@ -XXX,XX +XXX,XX @@
63
- if (guestfd < 0 || guestfd >= guestfd_array->len) {
42
*
64
+ if (guestfd <= 0 || guestfd >= guestfd_array->len) {
43
* Copyright (c) 2016 Artyom Tarasenko
65
return NULL;
44
*
66
}
45
- * This code is licensed under the GNU GPL v3 or (at your option) any later
46
+ * This code is licensed under the GNU GPL v2 or (at your option) any later
47
* version.
48
*/
67
49
68
--
50
--
69
2.20.1
51
2.34.1
70
52
71
53
diff view generated by jsdifflib
1
From: Alistair Francis <alistair@alistair23.me>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
Signed-off-by: Alistair Francis <alistair@alistair23.me>
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
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: dad8d8d47f7625913e35e27a1c00f603a6b08f9a.1576658572.git.alistair@alistair23.me
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
hw/arm/Makefile.objs | 1 +
11
target/arm/tcg/cpu-v7m.c | 290 +++++++++++++++++++++++++++++++++++++
9
hw/arm/netduinoplus2.c | 52 ++++++++++++++++++++++++++++++++++++++++++
12
target/arm/tcg/cpu32.c | 261 ---------------------------------
10
MAINTAINERS | 6 +++++
13
target/arm/meson.build | 3 +
11
3 files changed, 59 insertions(+)
14
target/arm/tcg/meson.build | 3 +
12
create mode 100644 hw/arm/netduinoplus2.c
15
4 files changed, 296 insertions(+), 261 deletions(-)
16
create mode 100644 target/arm/tcg/cpu-v7m.c
13
17
14
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
18
diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/Makefile.objs
17
+++ b/hw/arm/Makefile.objs
18
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MAINSTONE) += mainstone.o
19
obj-$(CONFIG_MICROBIT) += microbit.o
20
obj-$(CONFIG_MUSICPAL) += musicpal.o
21
obj-$(CONFIG_NETDUINO2) += netduino2.o
22
+obj-$(CONFIG_NETDUINOPLUS2) += netduinoplus2.o
23
obj-$(CONFIG_NSERIES) += nseries.o
24
obj-$(CONFIG_SX1) += omap_sx1.o
25
obj-$(CONFIG_CHEETAH) += palm.o
26
diff --git a/hw/arm/netduinoplus2.c b/hw/arm/netduinoplus2.c
27
new file mode 100644
19
new file mode 100644
28
index XXXXXXX..XXXXXXX
20
index XXXXXXX..XXXXXXX
29
--- /dev/null
21
--- /dev/null
30
+++ b/hw/arm/netduinoplus2.c
22
+++ b/target/arm/tcg/cpu-v7m.c
31
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@
32
+/*
24
+/*
33
+ * Netduino Plus 2 Machine Model
25
+ * QEMU ARMv7-M TCG-only CPUs.
34
+ *
26
+ *
35
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
27
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
36
+ *
28
+ *
37
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
29
+ * This code is licensed under the GNU GPL v2 or later.
38
+ * of this software and associated documentation files (the "Software"), to deal
39
+ * in the Software without restriction, including without limitation the rights
40
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
41
+ * copies of the Software, and to permit persons to whom the Software is
42
+ * furnished to do so, subject to the following conditions:
43
+ *
30
+ *
44
+ * The above copyright notice and this permission notice shall be included in
31
+ * SPDX-License-Identifier: GPL-2.0-or-later
45
+ * all copies or substantial portions of the Software.
46
+ *
47
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
48
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
49
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
50
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
51
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
52
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
53
+ * THE SOFTWARE.
54
+ */
32
+ */
55
+
33
+
56
+#include "qemu/osdep.h"
34
+#include "qemu/osdep.h"
57
+#include "qapi/error.h"
35
+#include "cpu.h"
58
+#include "hw/boards.h"
36
+#include "hw/core/tcg-cpu-ops.h"
59
+#include "hw/qdev-properties.h"
37
+#include "internals.h"
60
+#include "qemu/error-report.h"
38
+
61
+#include "hw/arm/stm32f405_soc.h"
39
+#if !defined(CONFIG_USER_ONLY)
62
+#include "hw/arm/boot.h"
40
+
63
+
41
+#include "hw/intc/armv7m_nvic.h"
64
+static void netduinoplus2_init(MachineState *machine)
42
+
65
+{
43
+static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
66
+ DeviceState *dev;
44
+{
67
+
45
+ CPUClass *cc = CPU_GET_CLASS(cs);
68
+ dev = qdev_create(NULL, TYPE_STM32F405_SOC);
46
+ ARMCPU *cpu = ARM_CPU(cs);
69
+ qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
47
+ CPUARMState *env = &cpu->env;
70
+ object_property_set_bool(OBJECT(dev), true, "realized", &error_fatal);
48
+ bool ret = false;
71
+
49
+
72
+ armv7m_load_kernel(ARM_CPU(first_cpu),
50
+ /*
73
+ machine->kernel_filename,
51
+ * ARMv7-M interrupt masking works differently than -A or -R.
74
+ FLASH_SIZE);
52
+ * There is no FIQ/IRQ distinction. Instead of I and F bits
75
+}
53
+ * masking FIQ and IRQ interrupts, an exception is taken only
76
+
54
+ * if it is higher priority than the current execution priority
77
+static void netduinoplus2_machine_init(MachineClass *mc)
55
+ * (which depends on state like BASEPRI, FAULTMASK and the
78
+{
56
+ * currently active exception).
79
+ mc->desc = "Netduino Plus 2 Machine";
57
+ */
80
+ mc->init = netduinoplus2_init;
58
+ if (interrupt_request & CPU_INTERRUPT_HARD
81
+}
59
+ && (armv7m_nvic_can_take_pending_exception(env->nvic))) {
82
+
60
+ cs->exception_index = EXCP_IRQ;
83
+DEFINE_MACHINE("netduinoplus2", netduinoplus2_machine_init)
61
+ cc->tcg_ops->do_interrupt(cs);
84
diff --git a/MAINTAINERS b/MAINTAINERS
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
85
index XXXXXXX..XXXXXXX 100644
315
index XXXXXXX..XXXXXXX 100644
86
--- a/MAINTAINERS
316
--- a/target/arm/tcg/cpu32.c
87
+++ b/MAINTAINERS
317
+++ b/target/arm/tcg/cpu32.c
88
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
318
@@ -XXX,XX +XXX,XX @@
89
S: Maintained
319
#include "hw/boards.h"
90
F: hw/arm/netduino2.c
320
#endif
91
321
#include "cpregs.h"
92
+Netduino Plus 2
322
-#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG)
93
+M: Alistair Francis <alistair@alistair23.me>
323
-#include "hw/intc/armv7m_nvic.h"
94
+M: Peter Maydell <peter.maydell@linaro.org>
324
-#endif
95
+S: Maintained
325
96
+F: hw/arm/netduinoplus2.c
326
97
+
327
/* Share AArch32 -cpu max features with AArch64. */
98
SmartFusion2
328
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
99
M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
329
/* CPU models. These are not needed for the AArch64 linux-user build. */
100
M: Peter Maydell <peter.maydell@linaro.org>
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'))
101
--
643
--
102
2.20.1
644
2.34.1
103
104
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
This test boots a Linux kernel on a CubieBoard and verify
4
the serial output is working.
5
6
The kernel image and DeviceTree blob are built by the Armbian
7
project (based on Debian):
8
https://docs.armbian.com/Developer-Guide_Build-Preparation/
9
10
The cpio image used comes from the linux-build-test project:
11
https://github.com/groeck/linux-build-test
12
13
If ARM is a target being built, "make check-acceptance" will
14
automatically include this test by the use of the "arch:arm" tags.
15
16
Alternatively, this test can be run using:
17
18
$ avocado --show=console run -t machine:cubieboard tests/acceptance/boot_linux_console.py
19
console: Uncompressing Linux... done, booting the kernel.
20
console: Booting Linux on physical CPU 0x0
21
console: Linux version 4.20.7-sunxi (root@armbian.com) (gcc version 7.2.1 20171011 (Linaro GCC 7.2-2017.11)) #5.75 SMP Fri Feb 8 09:02:10 CET 2019
22
console: CPU: ARMv7 Processor [410fc080] revision 0 (ARMv7), cr=50c5387d
23
console: CPU: PIPT / VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
24
console: OF: fdt: Machine model: Cubietech Cubieboard
25
[...]
26
console: Boot successful.
27
console: cat /proc/cpuinfo
28
console: / # cat /proc/cpuinfo
29
console: processor : 0
30
console: model name : ARMv7 Processor rev 0 (v7l)
31
console: BogoMIPS : 832.51
32
[...]
33
console: Hardware : Allwinner sun4i/sun5i Families
34
console: Revision : 0000
35
console: Serial : 0000000000000000
36
console: cat /proc/iomem
37
console: / # cat /proc/iomem
38
console: 01c00000-01c0002f : system-control@1c00000
39
console: 01c02000-01c02fff : dma-controller@1c02000
40
console: 01c05000-01c05fff : spi@1c05000
41
console: 01c0b080-01c0b093 : mdio@1c0b080
42
console: 01c0c000-01c0cfff : lcd-controller@1c0c000
43
console: 01c0d000-01c0dfff : lcd-controller@1c0d000
44
console: 01c0f000-01c0ffff : mmc@1c0f000
45
[...]
46
PASS (54.35 s)
47
48
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
49
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
50
Tested-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
51
Message-id: 20191230110953.25496-2-f4bug@amsat.org
52
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
53
---
54
tests/acceptance/boot_linux_console.py | 41 ++++++++++++++++++++++++++
55
1 file changed, 41 insertions(+)
56
57
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
58
index XXXXXXX..XXXXXXX 100644
59
--- a/tests/acceptance/boot_linux_console.py
60
+++ b/tests/acceptance/boot_linux_console.py
61
@@ -XXX,XX +XXX,XX @@ class BootLinuxConsole(Test):
62
self.wait_for_console_pattern('Boot successful.')
63
# TODO user command, for now the uart is stuck
64
65
+ def test_arm_cubieboard_initrd(self):
66
+ """
67
+ :avocado: tags=arch:arm
68
+ :avocado: tags=machine:cubieboard
69
+ """
70
+ deb_url = ('https://apt.armbian.com/pool/main/l/'
71
+ 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
72
+ deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
73
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
74
+ kernel_path = self.extract_from_deb(deb_path,
75
+ '/boot/vmlinuz-4.20.7-sunxi')
76
+ dtb_path = '/usr/lib/linux-image-dev-sunxi/sun4i-a10-cubieboard.dtb'
77
+ dtb_path = self.extract_from_deb(deb_path, dtb_path)
78
+ initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
79
+ '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
80
+ 'arm/rootfs-armv5.cpio.gz')
81
+ initrd_hash = '2b50f1873e113523967806f4da2afe385462ff9b'
82
+ initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
83
+ initrd_path = os.path.join(self.workdir, 'rootfs.cpio')
84
+ archive.gzip_uncompress(initrd_path_gz, initrd_path)
85
+
86
+ self.vm.set_console()
87
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
88
+ 'console=ttyS0,115200 '
89
+ 'usbcore.nousb '
90
+ 'panic=-1 noreboot')
91
+ self.vm.add_args('-kernel', kernel_path,
92
+ '-dtb', dtb_path,
93
+ '-initrd', initrd_path,
94
+ '-append', kernel_command_line,
95
+ '-no-reboot')
96
+ self.vm.launch()
97
+ self.wait_for_console_pattern('Boot successful.')
98
+
99
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
100
+ 'Allwinner sun4i/sun5i')
101
+ exec_command_and_wait_for_pattern(self, 'cat /proc/iomem',
102
+ 'system-control@1c00000')
103
+ exec_command_and_wait_for_pattern(self, 'reboot',
104
+ 'reboot: Restarting system')
105
+
106
def test_s390x_s390_ccw_virtio(self):
107
"""
108
:avocado: tags=arch:s390x
109
--
110
2.20.1
111
112
diff view generated by jsdifflib