1
Handful of bugfixes for rc2. None of these are particularly critical
1
Arm changes for before softfreeze: mostly my PL061/GPIO patches,
2
or exciting.
2
but also a new M-profile board and various other things.
3
3
4
thanks
4
-- PMM
5
-- PMM
5
6
6
The following changes since commit 45a150aa2b3492acf6691c7bdbeb25a8545d8345:
7
The following changes since commit 05de778b5b8ab0b402996769117b88c7ea5c7c61:
7
8
8
Merge remote-tracking branch 'remotes/ericb/tags/pull-bitmaps-2020-08-03' into staging (2020-08-03 15:13:49 +0100)
9
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging (2021-07-09 14:30:01 +0100)
9
10
10
are available in the Git repository at:
11
are available in the Git repository at:
11
12
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200803
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210709
13
14
14
for you to fetch changes up to 13557fd392890cbd985bceba7f717e01efd674b8:
15
for you to fetch changes up to 05449abb1d4c5f0c69ceb3d8d03cbc75de39b646:
15
16
16
hw/timer/imx_epit: Avoid assertion when CR.SWR is written (2020-08-03 17:56:11 +0100)
17
hw/intc: Improve formatting of MEMTX_ERROR guest error message (2021-07-09 16:09:12 +0100)
17
18
18
----------------------------------------------------------------
19
----------------------------------------------------------------
19
target-arm queue:
20
target-arm queue:
20
* hw/timer/imx_epit: Avoid assertion when CR.SWR is written
21
* New machine type: stm32vldiscovery
21
* netduino2, netduinoplus2, microbit: set system_clock_scale so that
22
* hw/intc/arm_gicv3_cpuif: Fix virtual irq number check in icv_[dir|eoir]_write
22
SysTick running on the CPU clock works
23
* hw/gpio/pl061: Honour Luminary PL061 PUR and PDR registers
23
* target/arm: Avoid maybe-uninitialized warning with gcc 4.9
24
* virt: Fix implementation of GPIO-based powerdown/shutdown mechanism
24
* target/arm: Fix AddPAC error indication
25
* Correct the encoding of MDCCSR_EL0 and DBGDSCRint
25
* Make AIRCR.SYSRESETREQ actually reset the system for the
26
* hw/intc: Improve formatting of MEMTX_ERROR guest error message
26
microbit, mps2-*, musca-*, netduino* boards
27
27
28
----------------------------------------------------------------
28
----------------------------------------------------------------
29
Kaige Li (1):
29
Alexandre Iooss (4):
30
target/arm: Avoid maybe-uninitialized warning with gcc 4.9
30
stm32f100: Add the stm32f100 SoC
31
stm32vldiscovery: Add the STM32VLDISCOVERY Machine
32
docs/system: arm: Add stm32 boards description
33
tests/boot-serial-test: Add STM32VLDISCOVERY board testcase
31
34
32
Peter Maydell (6):
35
Peter Maydell (10):
33
hw/arm/netduino2, netduinoplus2: Set system_clock_scale
36
hw/gpio/pl061: Convert DPRINTF to tracepoints
34
include/hw/irq.h: New function qemu_irq_is_connected()
37
hw/gpio/pl061: Clean up read/write offset handling logic
35
hw/intc/armv7m_nvic: Provide default "reset the system" behaviour for SYSRESETREQ
38
hw/gpio/pl061: Add tracepoints for register read and write
36
msf2-soc, stellaris: Don't wire up SYSRESETREQ
39
hw/gpio/pl061: Document the interface of this device
37
hw/arm/nrf51_soc: Set system_clock_scale
40
hw/gpio/pl061: Honour Luminary PL061 PUR and PDR registers
38
hw/timer/imx_epit: Avoid assertion when CR.SWR is written
41
hw/gpio/pl061: Make pullup/pulldown of outputs configurable
42
hw/arm/virt: Make PL061 GPIO lines pulled low, not high
43
hw/gpio/pl061: Convert to 3-phase reset and assert GPIO lines correctly on reset
44
hw/gpio/pl061: Document a shortcoming in our implementation
45
hw/arm/stellaris: Expand comment about handling of OLED chipselect
39
46
40
Richard Henderson (1):
47
Rebecca Cran (1):
41
target/arm: Fix AddPAC error indication
48
hw/intc: Improve formatting of MEMTX_ERROR guest error message
42
49
43
include/hw/arm/armv7m.h | 4 +++-
50
Ricardo Koller (1):
44
include/hw/irq.h | 18 ++++++++++++++++++
51
hw/intc/arm_gicv3_cpuif: Fix virtual irq number check in icv_[dir|eoir]_write
45
hw/arm/msf2-soc.c | 11 -----------
46
hw/arm/netduino2.c | 10 ++++++++++
47
hw/arm/netduinoplus2.c | 10 ++++++++++
48
hw/arm/nrf51_soc.c | 5 +++++
49
hw/arm/stellaris.c | 12 ------------
50
hw/intc/armv7m_nvic.c | 17 ++++++++++++++++-
51
hw/timer/imx_epit.c | 13 ++++++++++---
52
target/arm/pauth_helper.c | 6 +++++-
53
target/arm/translate-a64.c | 2 +-
54
tests/tcg/aarch64/pauth-5.c | 33 +++++++++++++++++++++++++++++++++
55
tests/tcg/aarch64/Makefile.target | 2 +-
56
13 files changed, 112 insertions(+), 31 deletions(-)
57
create mode 100644 tests/tcg/aarch64/pauth-5.c
58
52
53
hnick@vmware.com (1):
54
target/arm: Correct the encoding of MDCCSR_EL0 and DBGDSCRint
55
56
docs/system/arm/stm32.rst | 66 +++++++
57
docs/system/target-arm.rst | 1 +
58
default-configs/devices/arm-softmmu.mak | 1 +
59
include/hw/arm/stm32f100_soc.h | 57 ++++++
60
hw/arm/stellaris.c | 56 +++++-
61
hw/arm/stm32f100_soc.c | 182 +++++++++++++++++
62
hw/arm/stm32vldiscovery.c | 66 +++++++
63
hw/arm/virt.c | 3 +
64
hw/gpio/pl061.c | 341 +++++++++++++++++++++++++-------
65
hw/intc/arm_gicv3_cpuif.c | 4 +-
66
hw/intc/arm_gicv3_redist.c | 4 +-
67
target/arm/helper.c | 16 +-
68
tests/qtest/boot-serial-test.c | 37 ++++
69
MAINTAINERS | 13 ++
70
hw/arm/Kconfig | 10 +
71
hw/arm/meson.build | 2 +
72
hw/gpio/trace-events | 9 +
73
17 files changed, 790 insertions(+), 78 deletions(-)
74
create mode 100644 docs/system/arm/stm32.rst
75
create mode 100644 include/hw/arm/stm32f100_soc.h
76
create mode 100644 hw/arm/stm32f100_soc.c
77
create mode 100644 hw/arm/stm32vldiscovery.c
78
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Alexandre Iooss <erdnaxe@crans.org>
2
2
3
The definition of top_bit used in this function is one higher
3
This SoC is similar to stm32f205 SoC.
4
than that used in the Arm ARM psuedo-code, which put the error
4
This will be used by the STM32VLDISCOVERY to create a machine.
5
indication at top_bit - 1 at the wrong place, which meant that
5
6
it wasn't visible to Auth.
6
Signed-off-by: Alexandre Iooss <erdnaxe@crans.org>
7
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Fixing the definition of top_bit requires more changes, because
8
Message-id: 20210617165647.2575955-2-erdnaxe@crans.org
9
its most common use is for the count of bits in top_bit:bot_bit,
10
which would then need to be computed as top_bit - bot_bit + 1.
11
12
For now, prefer the minimal fix to the error indication alone.
13
14
Fixes: 63ff0ca94cb
15
Reported-by: Derrick McKee <derrick.mckee@gmail.com>
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20200728195706.11087-1-richard.henderson@linaro.org
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
[PMM: added comment about the divergence from the pseudocode]
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
10
---
22
target/arm/pauth_helper.c | 6 +++++-
11
include/hw/arm/stm32f100_soc.h | 57 +++++++++++
23
tests/tcg/aarch64/pauth-5.c | 33 +++++++++++++++++++++++++++++++
12
hw/arm/stm32f100_soc.c | 182 +++++++++++++++++++++++++++++++++
24
tests/tcg/aarch64/Makefile.target | 2 +-
13
MAINTAINERS | 6 ++
25
3 files changed, 39 insertions(+), 2 deletions(-)
14
hw/arm/Kconfig | 6 ++
26
create mode 100644 tests/tcg/aarch64/pauth-5.c
15
hw/arm/meson.build | 1 +
27
16
5 files changed, 252 insertions(+)
28
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
17
create mode 100644 include/hw/arm/stm32f100_soc.h
29
index XXXXXXX..XXXXXXX 100644
18
create mode 100644 hw/arm/stm32f100_soc.c
30
--- a/target/arm/pauth_helper.c
19
31
+++ b/target/arm/pauth_helper.c
20
diff --git a/include/hw/arm/stm32f100_soc.h b/include/hw/arm/stm32f100_soc.h
32
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
33
*/
34
test = sextract64(ptr, bot_bit, top_bit - bot_bit);
35
if (test != 0 && test != -1) {
36
- pac ^= MAKE_64BIT_MASK(top_bit - 1, 1);
37
+ /*
38
+ * Note that our top_bit is one greater than the pseudocode's
39
+ * version, hence "- 2" here.
40
+ */
41
+ pac ^= MAKE_64BIT_MASK(top_bit - 2, 1);
42
}
43
44
/*
45
diff --git a/tests/tcg/aarch64/pauth-5.c b/tests/tcg/aarch64/pauth-5.c
46
new file mode 100644
21
new file mode 100644
47
index XXXXXXX..XXXXXXX
22
index XXXXXXX..XXXXXXX
48
--- /dev/null
23
--- /dev/null
49
+++ b/tests/tcg/aarch64/pauth-5.c
24
+++ b/include/hw/arm/stm32f100_soc.h
50
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@
51
+#include <assert.h>
26
+/*
52
+
27
+ * STM32F100 SoC
53
+static int x;
28
+ *
54
+
29
+ * Copyright (c) 2021 Alexandre Iooss <erdnaxe@crans.org>
55
+int main()
30
+ *
31
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
32
+ * of this software and associated documentation files (the "Software"), to deal
33
+ * in the Software without restriction, including without limitation the rights
34
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
35
+ * copies of the Software, and to permit persons to whom the Software is
36
+ * furnished to do so, subject to the following conditions:
37
+ *
38
+ * The above copyright notice and this permission notice shall be included in
39
+ * all copies or substantial portions of the Software.
40
+ *
41
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
44
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
46
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
47
+ * THE SOFTWARE.
48
+ */
49
+
50
+#ifndef HW_ARM_STM32F100_SOC_H
51
+#define HW_ARM_STM32F100_SOC_H
52
+
53
+#include "hw/char/stm32f2xx_usart.h"
54
+#include "hw/ssi/stm32f2xx_spi.h"
55
+#include "hw/arm/armv7m.h"
56
+#include "qom/object.h"
57
+
58
+#define TYPE_STM32F100_SOC "stm32f100-soc"
59
+OBJECT_DECLARE_SIMPLE_TYPE(STM32F100State, STM32F100_SOC)
60
+
61
+#define STM_NUM_USARTS 3
62
+#define STM_NUM_SPIS 2
63
+
64
+#define FLASH_BASE_ADDRESS 0x08000000
65
+#define FLASH_SIZE (128 * 1024)
66
+#define SRAM_BASE_ADDRESS 0x20000000
67
+#define SRAM_SIZE (8 * 1024)
68
+
69
+struct STM32F100State {
70
+ /*< private >*/
71
+ SysBusDevice parent_obj;
72
+
73
+ /*< public >*/
74
+ char *cpu_type;
75
+
76
+ ARMv7MState armv7m;
77
+
78
+ STM32F2XXUsartState usart[STM_NUM_USARTS];
79
+ STM32F2XXSPIState spi[STM_NUM_SPIS];
80
+};
81
+
82
+#endif
83
diff --git a/hw/arm/stm32f100_soc.c b/hw/arm/stm32f100_soc.c
84
new file mode 100644
85
index XXXXXXX..XXXXXXX
86
--- /dev/null
87
+++ b/hw/arm/stm32f100_soc.c
88
@@ -XXX,XX +XXX,XX @@
89
+/*
90
+ * STM32F100 SoC
91
+ *
92
+ * Copyright (c) 2021 Alexandre Iooss <erdnaxe@crans.org>
93
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
94
+ *
95
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
96
+ * of this software and associated documentation files (the "Software"), to deal
97
+ * in the Software without restriction, including without limitation the rights
98
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
99
+ * copies of the Software, and to permit persons to whom the Software is
100
+ * furnished to do so, subject to the following conditions:
101
+ *
102
+ * The above copyright notice and this permission notice shall be included in
103
+ * all copies or substantial portions of the Software.
104
+ *
105
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
106
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
107
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
108
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
109
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
110
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
111
+ * THE SOFTWARE.
112
+ */
113
+
114
+#include "qemu/osdep.h"
115
+#include "qapi/error.h"
116
+#include "qemu/module.h"
117
+#include "hw/arm/boot.h"
118
+#include "exec/address-spaces.h"
119
+#include "hw/arm/stm32f100_soc.h"
120
+#include "hw/qdev-properties.h"
121
+#include "hw/misc/unimp.h"
122
+#include "sysemu/sysemu.h"
123
+
124
+/* stm32f100_soc implementation is derived from stm32f205_soc */
125
+
126
+static const uint32_t usart_addr[STM_NUM_USARTS] = { 0x40013800, 0x40004400,
127
+ 0x40004800 };
128
+static const uint32_t spi_addr[STM_NUM_SPIS] = { 0x40013000, 0x40003800 };
129
+
130
+static const int usart_irq[STM_NUM_USARTS] = {37, 38, 39};
131
+static const int spi_irq[STM_NUM_SPIS] = {35, 36};
132
+
133
+static void stm32f100_soc_initfn(Object *obj)
56
+{
134
+{
57
+ int *p0 = &x, *p1, *p2, *p3;
135
+ STM32F100State *s = STM32F100_SOC(obj);
58
+ unsigned long salt = 0;
136
+ int i;
137
+
138
+ object_initialize_child(obj, "armv7m", &s->armv7m, TYPE_ARMV7M);
139
+
140
+ for (i = 0; i < STM_NUM_USARTS; i++) {
141
+ object_initialize_child(obj, "usart[*]", &s->usart[i],
142
+ TYPE_STM32F2XX_USART);
143
+ }
144
+
145
+ for (i = 0; i < STM_NUM_SPIS; i++) {
146
+ object_initialize_child(obj, "spi[*]", &s->spi[i], TYPE_STM32F2XX_SPI);
147
+ }
148
+}
149
+
150
+static void stm32f100_soc_realize(DeviceState *dev_soc, Error **errp)
151
+{
152
+ STM32F100State *s = STM32F100_SOC(dev_soc);
153
+ DeviceState *dev, *armv7m;
154
+ SysBusDevice *busdev;
155
+ int i;
156
+
157
+ MemoryRegion *system_memory = get_system_memory();
158
+ MemoryRegion *sram = g_new(MemoryRegion, 1);
159
+ MemoryRegion *flash = g_new(MemoryRegion, 1);
160
+ MemoryRegion *flash_alias = g_new(MemoryRegion, 1);
59
+
161
+
60
+ /*
162
+ /*
61
+ * With TBI enabled and a 48-bit VA, there are 7 bits of auth, and so
163
+ * Init flash region
62
+ * a 1/128 chance of auth = pac(ptr,key,salt) producing zero.
164
+ * Flash starts at 0x08000000 and then is aliased to boot memory at 0x0
63
+ * Find a salt that creates auth != 0.
64
+ */
165
+ */
65
+ do {
166
+ memory_region_init_rom(flash, OBJECT(dev_soc), "STM32F100.flash",
66
+ salt++;
167
+ FLASH_SIZE, &error_fatal);
67
+ asm("pacda %0, %1" : "=r"(p1) : "r"(salt), "0"(p0));
168
+ memory_region_init_alias(flash_alias, OBJECT(dev_soc),
68
+ } while (p0 == p1);
169
+ "STM32F100.flash.alias", flash, 0, FLASH_SIZE);
69
+
170
+ memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, flash);
70
+ /*
171
+ memory_region_add_subregion(system_memory, 0, flash_alias);
71
+ * This pac must fail, because the input pointer bears an encryption,
172
+
72
+ * and so is not properly extended within bits [55:47]. This will
173
+ /* Init SRAM region */
73
+ * toggle bit 54 in the output...
174
+ memory_region_init_ram(sram, NULL, "STM32F100.sram", SRAM_SIZE,
74
+ */
175
+ &error_fatal);
75
+ asm("pacda %0, %1" : "=r"(p2) : "r"(salt), "0"(p1));
176
+ memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, sram);
76
+
177
+
77
+ /* ... so that the aut must fail, setting bit 53 in the output ... */
178
+ /* Init ARMv7m */
78
+ asm("autda %0, %1" : "=r"(p3) : "r"(salt), "0"(p2));
179
+ armv7m = DEVICE(&s->armv7m);
79
+
180
+ qdev_prop_set_uint32(armv7m, "num-irq", 61);
80
+ /* ... which means this equality must not hold. */
181
+ qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type);
81
+ assert(p3 != p0);
182
+ qdev_prop_set_bit(armv7m, "enable-bitband", true);
82
+ return 0;
183
+ object_property_set_link(OBJECT(&s->armv7m), "memory",
184
+ OBJECT(get_system_memory()), &error_abort);
185
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->armv7m), errp)) {
186
+ return;
187
+ }
188
+
189
+ /* Attach UART (uses USART registers) and USART controllers */
190
+ for (i = 0; i < STM_NUM_USARTS; i++) {
191
+ dev = DEVICE(&(s->usart[i]));
192
+ qdev_prop_set_chr(dev, "chardev", serial_hd(i));
193
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->usart[i]), errp)) {
194
+ return;
195
+ }
196
+ busdev = SYS_BUS_DEVICE(dev);
197
+ sysbus_mmio_map(busdev, 0, usart_addr[i]);
198
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, usart_irq[i]));
199
+ }
200
+
201
+ /* SPI 1 and 2 */
202
+ for (i = 0; i < STM_NUM_SPIS; i++) {
203
+ dev = DEVICE(&(s->spi[i]));
204
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), errp)) {
205
+ return;
206
+ }
207
+ busdev = SYS_BUS_DEVICE(dev);
208
+ sysbus_mmio_map(busdev, 0, spi_addr[i]);
209
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, spi_irq[i]));
210
+ }
211
+
212
+ create_unimplemented_device("timer[2]", 0x40000000, 0x400);
213
+ create_unimplemented_device("timer[3]", 0x40000400, 0x400);
214
+ create_unimplemented_device("timer[4]", 0x40000800, 0x400);
215
+ create_unimplemented_device("timer[6]", 0x40001000, 0x400);
216
+ create_unimplemented_device("timer[7]", 0x40001400, 0x400);
217
+ create_unimplemented_device("RTC", 0x40002800, 0x400);
218
+ create_unimplemented_device("WWDG", 0x40002C00, 0x400);
219
+ create_unimplemented_device("IWDG", 0x40003000, 0x400);
220
+ create_unimplemented_device("I2C1", 0x40005400, 0x400);
221
+ create_unimplemented_device("I2C2", 0x40005800, 0x400);
222
+ create_unimplemented_device("BKP", 0x40006C00, 0x400);
223
+ create_unimplemented_device("PWR", 0x40007000, 0x400);
224
+ create_unimplemented_device("DAC", 0x40007400, 0x400);
225
+ create_unimplemented_device("CEC", 0x40007800, 0x400);
226
+ create_unimplemented_device("AFIO", 0x40010000, 0x400);
227
+ create_unimplemented_device("EXTI", 0x40010400, 0x400);
228
+ create_unimplemented_device("GPIOA", 0x40010800, 0x400);
229
+ create_unimplemented_device("GPIOB", 0x40010C00, 0x400);
230
+ create_unimplemented_device("GPIOC", 0x40011000, 0x400);
231
+ create_unimplemented_device("GPIOD", 0x40011400, 0x400);
232
+ create_unimplemented_device("GPIOE", 0x40011800, 0x400);
233
+ create_unimplemented_device("ADC1", 0x40012400, 0x400);
234
+ create_unimplemented_device("timer[1]", 0x40012C00, 0x400);
235
+ create_unimplemented_device("timer[15]", 0x40014000, 0x400);
236
+ create_unimplemented_device("timer[16]", 0x40014400, 0x400);
237
+ create_unimplemented_device("timer[17]", 0x40014800, 0x400);
238
+ create_unimplemented_device("DMA", 0x40020000, 0x400);
239
+ create_unimplemented_device("RCC", 0x40021000, 0x400);
240
+ create_unimplemented_device("Flash Int", 0x40022000, 0x400);
241
+ create_unimplemented_device("CRC", 0x40023000, 0x400);
83
+}
242
+}
84
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
243
+
244
+static Property stm32f100_soc_properties[] = {
245
+ DEFINE_PROP_STRING("cpu-type", STM32F100State, cpu_type),
246
+ DEFINE_PROP_END_OF_LIST(),
247
+};
248
+
249
+static void stm32f100_soc_class_init(ObjectClass *klass, void *data)
250
+{
251
+ DeviceClass *dc = DEVICE_CLASS(klass);
252
+
253
+ dc->realize = stm32f100_soc_realize;
254
+ device_class_set_props(dc, stm32f100_soc_properties);
255
+}
256
+
257
+static const TypeInfo stm32f100_soc_info = {
258
+ .name = TYPE_STM32F100_SOC,
259
+ .parent = TYPE_SYS_BUS_DEVICE,
260
+ .instance_size = sizeof(STM32F100State),
261
+ .instance_init = stm32f100_soc_initfn,
262
+ .class_init = stm32f100_soc_class_init,
263
+};
264
+
265
+static void stm32f100_soc_types(void)
266
+{
267
+ type_register_static(&stm32f100_soc_info);
268
+}
269
+
270
+type_init(stm32f100_soc_types)
271
diff --git a/MAINTAINERS b/MAINTAINERS
85
index XXXXXXX..XXXXXXX 100644
272
index XXXXXXX..XXXXXXX 100644
86
--- a/tests/tcg/aarch64/Makefile.target
273
--- a/MAINTAINERS
87
+++ b/tests/tcg/aarch64/Makefile.target
274
+++ b/MAINTAINERS
88
@@ -XXX,XX +XXX,XX @@ run-fcvt: fcvt
275
@@ -XXX,XX +XXX,XX @@ L: qemu-arm@nongnu.org
89
276
S: Maintained
90
# Pauth Tests
277
F: hw/arm/virt-acpi-build.c
91
ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_ARMV8_3),)
278
92
-AARCH64_TESTS += pauth-1 pauth-2 pauth-4
279
+STM32F100
93
+AARCH64_TESTS += pauth-1 pauth-2 pauth-4 pauth-5
280
+M: Alexandre Iooss <erdnaxe@crans.org>
94
pauth-%: CFLAGS += -march=armv8.3-a
281
+L: qemu-arm@nongnu.org
95
run-pauth-%: QEMU_OPTS += -cpu max
282
+S: Maintained
96
run-plugin-pauth-%: QEMU_OPTS += -cpu max
283
+F: hw/arm/stm32f100_soc.c
284
+
285
STM32F205
286
M: Alistair Francis <alistair@alistair23.me>
287
M: Peter Maydell <peter.maydell@linaro.org>
288
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
289
index XXXXXXX..XXXXXXX 100644
290
--- a/hw/arm/Kconfig
291
+++ b/hw/arm/Kconfig
292
@@ -XXX,XX +XXX,XX @@ config RASPI
293
select SDHCI
294
select USB_DWC2
295
296
+config STM32F100_SOC
297
+ bool
298
+ select ARM_V7M
299
+ select STM32F2XX_USART
300
+ select STM32F2XX_SPI
301
+
302
config STM32F205_SOC
303
bool
304
select ARM_V7M
305
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
306
index XXXXXXX..XXXXXXX 100644
307
--- a/hw/arm/meson.build
308
+++ b/hw/arm/meson.build
309
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_STRONGARM', if_true: files('strongarm.c'))
310
arm_ss.add(when: 'CONFIG_ALLWINNER_A10', if_true: files('allwinner-a10.c', 'cubieboard.c'))
311
arm_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3.c', 'orangepi.c'))
312
arm_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_peripherals.c', 'bcm2836.c', 'raspi.c'))
313
+arm_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_soc.c'))
314
arm_ss.add(when: 'CONFIG_STM32F205_SOC', if_true: files('stm32f205_soc.c'))
315
arm_ss.add(when: 'CONFIG_STM32F405_SOC', if_true: files('stm32f405_soc.c'))
316
arm_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp.c', 'xlnx-zcu102.c'))
97
--
317
--
98
2.20.1
318
2.20.1
99
319
100
320
diff view generated by jsdifflib
1
The netduino2 and netduinoplus2 boards forgot to set the system_clock_scale
1
From: Alexandre Iooss <erdnaxe@crans.org>
2
global, which meant that if guest code used the systick timer in "use
3
the processor clock" mode it would hang because time never advances.
4
2
5
Set the global to match the documented CPU clock speed of these boards.
3
This is a Cortex-M3 based machine. Information can be found at:
6
Judging by the data sheet this is slightly simplistic because the
4
https://www.st.com/en/evaluation-tools/stm32vldiscovery.html
7
SoC allows configuration of the SYSCLK source and frequency via the
8
RCC (reset and clock control) module, but we don't model that.
9
5
10
Fixes: https://bugs.launchpad.net/qemu/+bug/1876187
6
Signed-off-by: Alexandre Iooss <erdnaxe@crans.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20210617165647.2575955-3-erdnaxe@crans.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-id: 20200727162617.26227-1-peter.maydell@linaro.org
14
---
10
---
15
hw/arm/netduino2.c | 10 ++++++++++
11
default-configs/devices/arm-softmmu.mak | 1 +
16
hw/arm/netduinoplus2.c | 10 ++++++++++
12
hw/arm/stm32vldiscovery.c | 66 +++++++++++++++++++++++++
17
2 files changed, 20 insertions(+)
13
MAINTAINERS | 6 +++
14
hw/arm/Kconfig | 4 ++
15
hw/arm/meson.build | 1 +
16
5 files changed, 78 insertions(+)
17
create mode 100644 hw/arm/stm32vldiscovery.c
18
18
19
diff --git a/hw/arm/netduino2.c b/hw/arm/netduino2.c
19
diff --git a/default-configs/devices/arm-softmmu.mak b/default-configs/devices/arm-softmmu.mak
20
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/netduino2.c
21
--- a/default-configs/devices/arm-softmmu.mak
22
+++ b/hw/arm/netduino2.c
22
+++ b/default-configs/devices/arm-softmmu.mak
23
@@ -XXX,XX +XXX,XX @@ CONFIG_CHEETAH=y
24
CONFIG_SX1=y
25
CONFIG_NSERIES=y
26
CONFIG_STELLARIS=y
27
+CONFIG_STM32VLDISCOVERY=y
28
CONFIG_REALVIEW=y
29
CONFIG_VERSATILE=y
30
CONFIG_VEXPRESS=y
31
diff --git a/hw/arm/stm32vldiscovery.c b/hw/arm/stm32vldiscovery.c
32
new file mode 100644
33
index XXXXXXX..XXXXXXX
34
--- /dev/null
35
+++ b/hw/arm/stm32vldiscovery.c
23
@@ -XXX,XX +XXX,XX @@
36
@@ -XXX,XX +XXX,XX @@
24
#include "hw/arm/stm32f205_soc.h"
37
+/*
25
#include "hw/arm/boot.h"
38
+ * ST STM32VLDISCOVERY machine
26
39
+ *
27
+/* Main SYSCLK frequency in Hz (120MHz) */
40
+ * Copyright (c) 2021 Alexandre Iooss <erdnaxe@crans.org>
28
+#define SYSCLK_FRQ 120000000ULL
41
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
42
+ *
43
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
44
+ * of this software and associated documentation files (the "Software"), to deal
45
+ * in the Software without restriction, including without limitation the rights
46
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
47
+ * copies of the Software, and to permit persons to whom the Software is
48
+ * furnished to do so, subject to the following conditions:
49
+ *
50
+ * The above copyright notice and this permission notice shall be included in
51
+ * all copies or substantial portions of the Software.
52
+ *
53
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
54
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
55
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
56
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
57
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
58
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
59
+ * THE SOFTWARE.
60
+ */
29
+
61
+
30
static void netduino2_init(MachineState *machine)
62
+#include "qemu/osdep.h"
31
{
63
+#include "qapi/error.h"
32
DeviceState *dev;
64
+#include "hw/boards.h"
33
65
+#include "hw/qdev-properties.h"
66
+#include "qemu/error-report.h"
67
+#include "hw/arm/stm32f100_soc.h"
68
+#include "hw/arm/boot.h"
69
+
70
+/* stm32vldiscovery implementation is derived from netduinoplus2 */
71
+
72
+/* Main SYSCLK frequency in Hz (24MHz) */
73
+#define SYSCLK_FRQ 24000000ULL
74
+
75
+static void stm32vldiscovery_init(MachineState *machine)
76
+{
77
+ DeviceState *dev;
78
+
34
+ /*
79
+ /*
35
+ * TODO: ideally we would model the SoC RCC and let it handle
80
+ * TODO: ideally we would model the SoC RCC and let it handle
36
+ * system_clock_scale, including its ability to define different
81
+ * system_clock_scale, including its ability to define different
37
+ * possible SYSCLK sources.
82
+ * possible SYSCLK sources.
38
+ */
83
+ */
39
+ system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
84
+ system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
40
+
85
+
41
dev = qdev_new(TYPE_STM32F205_SOC);
86
+ dev = qdev_new(TYPE_STM32F100_SOC);
42
qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m3"));
87
+ qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m3"));
43
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
88
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
44
diff --git a/hw/arm/netduinoplus2.c b/hw/arm/netduinoplus2.c
89
+
90
+ armv7m_load_kernel(ARM_CPU(first_cpu),
91
+ machine->kernel_filename,
92
+ FLASH_SIZE);
93
+}
94
+
95
+static void stm32vldiscovery_machine_init(MachineClass *mc)
96
+{
97
+ mc->desc = "ST STM32VLDISCOVERY (Cortex-M3)";
98
+ mc->init = stm32vldiscovery_init;
99
+}
100
+
101
+DEFINE_MACHINE("stm32vldiscovery", stm32vldiscovery_machine_init)
102
+
103
diff --git a/MAINTAINERS b/MAINTAINERS
45
index XXXXXXX..XXXXXXX 100644
104
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/arm/netduinoplus2.c
105
--- a/MAINTAINERS
47
+++ b/hw/arm/netduinoplus2.c
106
+++ b/MAINTAINERS
48
@@ -XXX,XX +XXX,XX @@
107
@@ -XXX,XX +XXX,XX @@ F: hw/*/stellaris*
49
#include "hw/arm/stm32f405_soc.h"
108
F: include/hw/input/gamepad.h
50
#include "hw/arm/boot.h"
109
F: docs/system/arm/stellaris.rst
51
110
52
+/* Main SYSCLK frequency in Hz (168MHz) */
111
+STM32VLDISCOVERY
53
+#define SYSCLK_FRQ 168000000ULL
112
+M: Alexandre Iooss <erdnaxe@crans.org>
113
+L: qemu-arm@nongnu.org
114
+S: Maintained
115
+F: hw/arm/stm32vldiscovery.c
54
+
116
+
55
static void netduinoplus2_init(MachineState *machine)
117
Versatile Express
56
{
118
M: Peter Maydell <peter.maydell@linaro.org>
57
DeviceState *dev;
119
L: qemu-arm@nongnu.org
58
120
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
59
+ /*
121
index XXXXXXX..XXXXXXX 100644
60
+ * TODO: ideally we would model the SoC RCC and let it handle
122
--- a/hw/arm/Kconfig
61
+ * system_clock_scale, including its ability to define different
123
+++ b/hw/arm/Kconfig
62
+ * possible SYSCLK sources.
124
@@ -XXX,XX +XXX,XX @@ config STELLARIS
63
+ */
125
select STELLARIS_ENET # ethernet
64
+ system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
126
select UNIMP
127
128
+config STM32VLDISCOVERY
129
+ bool
130
+ select STM32F100_SOC
65
+
131
+
66
dev = qdev_new(TYPE_STM32F405_SOC);
132
config STRONGARM
67
qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
133
bool
68
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
134
select PXA2XX
135
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
136
index XXXXXXX..XXXXXXX 100644
137
--- a/hw/arm/meson.build
138
+++ b/hw/arm/meson.build
139
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_Z2', if_true: files('z2.c'))
140
arm_ss.add(when: 'CONFIG_REALVIEW', if_true: files('realview.c'))
141
arm_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa-ref.c'))
142
arm_ss.add(when: 'CONFIG_STELLARIS', if_true: files('stellaris.c'))
143
+arm_ss.add(when: 'CONFIG_STM32VLDISCOVERY', if_true: files('stm32vldiscovery.c'))
144
arm_ss.add(when: 'CONFIG_COLLIE', if_true: files('collie.c'))
145
arm_ss.add(when: 'CONFIG_VERSATILE', if_true: files('versatilepb.c'))
146
arm_ss.add(when: 'CONFIG_VEXPRESS', if_true: files('vexpress.c'))
69
--
147
--
70
2.20.1
148
2.20.1
71
149
72
150
diff view generated by jsdifflib
New patch
1
From: Alexandre Iooss <erdnaxe@crans.org>
1
2
3
This adds the target guide for Netduino 2, Netduino Plus 2 and STM32VLDISCOVERY.
4
5
Signed-off-by: Alexandre Iooss <erdnaxe@crans.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-id: 20210617165647.2575955-4-erdnaxe@crans.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
docs/system/arm/stm32.rst | 66 ++++++++++++++++++++++++++++++++++++++
11
docs/system/target-arm.rst | 1 +
12
MAINTAINERS | 1 +
13
3 files changed, 68 insertions(+)
14
create mode 100644 docs/system/arm/stm32.rst
15
16
diff --git a/docs/system/arm/stm32.rst b/docs/system/arm/stm32.rst
17
new file mode 100644
18
index XXXXXXX..XXXXXXX
19
--- /dev/null
20
+++ b/docs/system/arm/stm32.rst
21
@@ -XXX,XX +XXX,XX @@
22
+STMicroelectronics STM32 boards (``netduino2``, ``netduinoplus2``, ``stm32vldiscovery``)
23
+========================================================================================
24
+
25
+The `STM32`_ chips are a family of 32-bit ARM-based microcontroller by
26
+STMicroelectronics.
27
+
28
+.. _STM32: https://www.st.com/en/microcontrollers-microprocessors/stm32-32-bit-arm-cortex-mcus.html
29
+
30
+The STM32F1 series is based on ARM Cortex-M3 core. The following machines are
31
+based on this chip :
32
+
33
+- ``stm32vldiscovery`` STM32VLDISCOVERY board with STM32F100RBT6 microcontroller
34
+
35
+The STM32F2 series is based on ARM Cortex-M3 core. The following machines are
36
+based on this chip :
37
+
38
+- ``netduino2`` Netduino 2 board with STM32F205RFT6 microcontroller
39
+
40
+The STM32F4 series is based on ARM Cortex-M4F core. This series is pin-to-pin
41
+compatible with STM32F2 series. The following machines are based on this chip :
42
+
43
+- ``netduinoplus2`` Netduino Plus 2 board with STM32F405RGT6 microcontroller
44
+
45
+There are many other STM32 series that are currently not supported by QEMU.
46
+
47
+Supported devices
48
+-----------------
49
+
50
+ * ARM Cortex-M3, Cortex M4F
51
+ * Analog to Digital Converter (ADC)
52
+ * EXTI interrupt
53
+ * Serial ports (USART)
54
+ * SPI controller
55
+ * System configuration (SYSCFG)
56
+ * Timer controller (TIMER)
57
+
58
+Missing devices
59
+---------------
60
+
61
+ * Camera interface (DCMI)
62
+ * Controller Area Network (CAN)
63
+ * Cycle Redundancy Check (CRC) calculation unit
64
+ * Digital to Analog Converter (DAC)
65
+ * DMA controller
66
+ * Ethernet controller
67
+ * Flash Interface Unit
68
+ * GPIO controller
69
+ * I2C controller
70
+ * Inter-Integrated Sound (I2S) controller
71
+ * Power supply configuration (PWR)
72
+ * Random Number Generator (RNG)
73
+ * Real-Time Clock (RTC) controller
74
+ * Reset and Clock Controller (RCC)
75
+ * Secure Digital Input/Output (SDIO) interface
76
+ * USB OTG
77
+ * Watchdog controller (IWDG, WWDG)
78
+
79
+Boot options
80
+------------
81
+
82
+The STM32 machines can be started using the ``-kernel`` option to load a
83
+firmware. Example:
84
+
85
+.. code-block:: bash
86
+
87
+ $ qemu-system-arm -M stm32vldiscovery -kernel firmware.bin
88
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
89
index XXXXXXX..XXXXXXX 100644
90
--- a/docs/system/target-arm.rst
91
+++ b/docs/system/target-arm.rst
92
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
93
arm/collie
94
arm/sx1
95
arm/stellaris
96
+ arm/stm32
97
arm/virt
98
arm/xlnx-versal-virt
99
100
diff --git a/MAINTAINERS b/MAINTAINERS
101
index XXXXXXX..XXXXXXX 100644
102
--- a/MAINTAINERS
103
+++ b/MAINTAINERS
104
@@ -XXX,XX +XXX,XX @@ M: Alexandre Iooss <erdnaxe@crans.org>
105
L: qemu-arm@nongnu.org
106
S: Maintained
107
F: hw/arm/stm32vldiscovery.c
108
+F: docs/system/arm/stm32.rst
109
110
Versatile Express
111
M: Peter Maydell <peter.maydell@linaro.org>
112
--
113
2.20.1
114
115
diff view generated by jsdifflib
New patch
1
From: Alexandre Iooss <erdnaxe@crans.org>
1
2
3
New mini-kernel test for STM32VLDISCOVERY USART1.
4
5
Signed-off-by: Alexandre Iooss <erdnaxe@crans.org>
6
Acked-by: Thomas Huth <thuth@redhat.com>
7
Acked-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20210617165647.2575955-5-erdnaxe@crans.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
tests/qtest/boot-serial-test.c | 37 ++++++++++++++++++++++++++++++++++
12
1 file changed, 37 insertions(+)
13
14
diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/qtest/boot-serial-test.c
17
+++ b/tests/qtest/boot-serial-test.c
18
@@ -XXX,XX +XXX,XX @@ static const uint8_t kernel_nrf51[] = {
19
0x1c, 0x25, 0x00, 0x40 /* 0x4000251c = UART TXD */
20
};
21
22
+static const uint8_t kernel_stm32vldiscovery[] = {
23
+ 0x00, 0x00, 0x00, 0x00, /* Stack top address */
24
+ 0x1d, 0x00, 0x00, 0x00, /* Reset handler address */
25
+ 0x00, 0x00, 0x00, 0x00, /* NMI */
26
+ 0x00, 0x00, 0x00, 0x00, /* Hard fault */
27
+ 0x00, 0x00, 0x00, 0x00, /* Memory management fault */
28
+ 0x00, 0x00, 0x00, 0x00, /* Bus fault */
29
+ 0x00, 0x00, 0x00, 0x00, /* Usage fault */
30
+ 0x0b, 0x4b, /* ldr r3, [pc, #44] Get RCC */
31
+ 0x44, 0xf2, 0x04, 0x02, /* movw r2, #16388 */
32
+ 0x1a, 0x60, /* str r2, [r3] */
33
+ 0x0a, 0x4b, /* ldr r3, [pc, #40] Get GPIOA */
34
+ 0x1a, 0x68, /* ldr r2, [r3] */
35
+ 0x22, 0xf0, 0xf0, 0x02, /* bic r2, r2, #240 */
36
+ 0x1a, 0x60, /* str r2, [r3] */
37
+ 0x1a, 0x68, /* ldr r2, [r3] */
38
+ 0x42, 0xf0, 0xb0, 0x02, /* orr r2, r2, #176 */
39
+ 0x1a, 0x60, /* str r2, [r3] */
40
+ 0x07, 0x4b, /* ldr r3, [pc, #26] Get BAUD */
41
+ 0x45, 0x22, /* movs r2, #69 */
42
+ 0x1a, 0x60, /* str r2, [r3] */
43
+ 0x06, 0x4b, /* ldr r3, [pc, #24] Get ENABLE */
44
+ 0x42, 0xf2, 0x08, 0x02, /* movw r2, #8200 */
45
+ 0x1a, 0x60, /* str r2, [r3] */
46
+ 0x05, 0x4b, /* ldr r3, [pc, #20] Get TXD */
47
+ 0x54, 0x22, /* movs r2, 'T' */
48
+ 0x1a, 0x60, /* str r2, [r3] */
49
+ 0xfe, 0xe7, /* b . */
50
+ 0x18, 0x10, 0x02, 0x40, /* 0x40021018 = RCC */
51
+ 0x04, 0x08, 0x01, 0x40, /* 0x40010804 = GPIOA */
52
+ 0x08, 0x38, 0x01, 0x40, /* 0x40013808 = USART1 BAUD */
53
+ 0x0c, 0x38, 0x01, 0x40, /* 0x4001380c = USART1 ENABLE */
54
+ 0x04, 0x38, 0x01, 0x40 /* 0x40013804 = USART1 TXD */
55
+};
56
+
57
typedef struct testdef {
58
const char *arch; /* Target architecture */
59
const char *machine; /* Name of the machine */
60
@@ -XXX,XX +XXX,XX @@ static testdef_t tests[] = {
61
{ "aarch64", "virt", "-cpu max", "TT", sizeof(kernel_aarch64),
62
kernel_aarch64 },
63
{ "arm", "microbit", "", "T", sizeof(kernel_nrf51), kernel_nrf51 },
64
+ { "arm", "stm32vldiscovery", "", "T",
65
+ sizeof(kernel_stm32vldiscovery), kernel_stm32vldiscovery },
66
67
{ NULL }
68
};
69
--
70
2.20.1
71
72
diff view generated by jsdifflib
New patch
1
From: Ricardo Koller <ricarkol@google.com>
1
2
3
icv_eoir_write() and icv_dir_write() ignore invalid virtual IRQ numbers
4
(like LPIs). The issue is that these functions check against the number
5
of implemented IRQs (QEMU's default is num_irq=288) which can be lower
6
than the maximum virtual IRQ number (1020 - 1). The consequence is that
7
if a hypervisor creates an LR for an IRQ between 288 and 1020, then the
8
guest is unable to deactivate the resulting IRQ. Note that other
9
functions that deal with large IRQ numbers, like icv_iar_read, check
10
against 1020 and not against num_irq.
11
12
Fix the checks by using GICV3_MAXIRQ (1020) instead of the number of
13
implemented IRQs.
14
15
Signed-off-by: Ricardo Koller <ricarkol@google.com>
16
Message-id: 20210702233701.3369-1-ricarkol@google.com
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
20
hw/intc/arm_gicv3_cpuif.c | 4 ++--
21
1 file changed, 2 insertions(+), 2 deletions(-)
22
23
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/intc/arm_gicv3_cpuif.c
26
+++ b/hw/intc/arm_gicv3_cpuif.c
27
@@ -XXX,XX +XXX,XX @@ static void icv_dir_write(CPUARMState *env, const ARMCPRegInfo *ri,
28
29
trace_gicv3_icv_dir_write(gicv3_redist_affid(cs), value);
30
31
- if (irq >= cs->gic->num_irq) {
32
+ if (irq >= GICV3_MAXIRQ) {
33
/* Also catches special interrupt numbers and LPIs */
34
return;
35
}
36
@@ -XXX,XX +XXX,XX @@ static void icv_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri,
37
trace_gicv3_icv_eoir_write(ri->crm == 8 ? 0 : 1,
38
gicv3_redist_affid(cs), value);
39
40
- if (irq >= cs->gic->num_irq) {
41
+ if (irq >= GICV3_MAXIRQ) {
42
/* Also catches special interrupt numbers and LPIs */
43
return;
44
}
45
--
46
2.20.1
47
48
diff view generated by jsdifflib
New patch
1
Convert the use of the DPRINTF debug macro in the PL061 model to
2
use tracepoints.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
hw/gpio/pl061.c | 27 +++++++++------------------
9
hw/gpio/trace-events | 6 ++++++
10
2 files changed, 15 insertions(+), 18 deletions(-)
11
12
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/gpio/pl061.c
15
+++ b/hw/gpio/pl061.c
16
@@ -XXX,XX +XXX,XX @@
17
#include "qemu/log.h"
18
#include "qemu/module.h"
19
#include "qom/object.h"
20
-
21
-//#define DEBUG_PL061 1
22
-
23
-#ifdef DEBUG_PL061
24
-#define DPRINTF(fmt, ...) \
25
-do { printf("pl061: " fmt , ## __VA_ARGS__); } while (0)
26
-#define BADF(fmt, ...) \
27
-do { fprintf(stderr, "pl061: error: " fmt , ## __VA_ARGS__); exit(1);} while (0)
28
-#else
29
-#define DPRINTF(fmt, ...) do {} while(0)
30
-#define BADF(fmt, ...) \
31
-do { fprintf(stderr, "pl061: error: " fmt , ## __VA_ARGS__);} while (0)
32
-#endif
33
+#include "trace.h"
34
35
static const uint8_t pl061_id[12] =
36
{ 0x00, 0x00, 0x00, 0x00, 0x61, 0x10, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
37
@@ -XXX,XX +XXX,XX @@ static void pl061_update(PL061State *s)
38
uint8_t out;
39
int i;
40
41
- DPRINTF("dir = %d, data = %d\n", s->dir, s->data);
42
+ trace_pl061_update(DEVICE(s)->canonical_path, s->dir, s->data);
43
44
/* Outputs float high. */
45
/* FIXME: This is board dependent. */
46
@@ -XXX,XX +XXX,XX @@ static void pl061_update(PL061State *s)
47
for (i = 0; i < N_GPIOS; i++) {
48
mask = 1 << i;
49
if (changed & mask) {
50
- DPRINTF("Set output %d = %d\n", i, (out & mask) != 0);
51
- qemu_set_irq(s->out[i], (out & mask) != 0);
52
+ int level = (out & mask) != 0;
53
+ trace_pl061_set_output(DEVICE(s)->canonical_path, i, level);
54
+ qemu_set_irq(s->out[i], level);
55
}
56
}
57
}
58
@@ -XXX,XX +XXX,XX @@ static void pl061_update(PL061State *s)
59
for (i = 0; i < N_GPIOS; i++) {
60
mask = 1 << i;
61
if (changed & mask) {
62
- DPRINTF("Changed input %d = %d\n", i, (s->data & mask) != 0);
63
+ trace_pl061_input_change(DEVICE(s)->canonical_path, i,
64
+ (s->data & mask) != 0);
65
66
if (!(s->isense & mask)) {
67
/* Edge interrupt */
68
@@ -XXX,XX +XXX,XX @@ static void pl061_update(PL061State *s)
69
/* Level interrupt */
70
s->istate |= ~(s->data ^ s->iev) & s->isense;
71
72
- DPRINTF("istate = %02X\n", s->istate);
73
+ trace_pl061_update_istate(DEVICE(s)->canonical_path,
74
+ s->istate, s->im, (s->istate & s->im) != 0);
75
76
qemu_set_irq(s->irq, (s->istate & s->im) != 0);
77
}
78
diff --git a/hw/gpio/trace-events b/hw/gpio/trace-events
79
index XXXXXXX..XXXXXXX 100644
80
--- a/hw/gpio/trace-events
81
+++ b/hw/gpio/trace-events
82
@@ -XXX,XX +XXX,XX @@ nrf51_gpio_write(uint64_t offset, uint64_t value) "offset 0x%" PRIx64 " value 0x
83
nrf51_gpio_set(int64_t line, int64_t value) "line %" PRIi64 " value %" PRIi64
84
nrf51_gpio_update_output_irq(int64_t line, int64_t value) "line %" PRIi64 " value %" PRIi64
85
86
+# pl061.c
87
+pl061_update(const char *id, uint32_t dir, uint32_t data) "%s GPIODIR 0x%x GPIODATA 0x%x"
88
+pl061_set_output(const char *id, int gpio, int level) "%s setting output %d to %d"
89
+pl061_input_change(const char *id, int gpio, int level) "%s input %d changed to %d"
90
+pl061_update_istate(const char *id, uint32_t istate, uint32_t im, int level) "%s GPIORIS 0x%x GPIOIE 0x%x interrupt level %d"
91
+
92
# sifive_gpio.c
93
sifive_gpio_read(uint64_t offset, uint64_t r) "offset 0x%" PRIx64 " value 0x%" PRIx64
94
sifive_gpio_write(uint64_t offset, uint64_t value) "offset 0x%" PRIx64 " value 0x%" PRIx64
95
--
96
2.20.1
97
98
diff view generated by jsdifflib
New patch
1
1
Currently the pl061_read() and pl061_write() functions handle offsets
2
using a combination of three if() statements and a switch(). Clean
3
this up to use just a switch, using case ranges.
4
5
This requires that instead of catching accesses to the luminary-only
6
registers on a stock PL061 via a check on s->rsvd_start we use
7
an "is this luminary?" check in the cases for each luminary-only
8
register.
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
---
13
hw/gpio/pl061.c | 104 ++++++++++++++++++++++++++++++++++++------------
14
1 file changed, 79 insertions(+), 25 deletions(-)
15
16
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/gpio/pl061.c
19
+++ b/hw/gpio/pl061.c
20
@@ -XXX,XX +XXX,XX @@ struct PL061State {
21
qemu_irq irq;
22
qemu_irq out[N_GPIOS];
23
const unsigned char *id;
24
- uint32_t rsvd_start; /* reserved area: [rsvd_start, 0xfcc] */
25
};
26
27
static const VMStateDescription vmstate_pl061 = {
28
@@ -XXX,XX +XXX,XX @@ static uint64_t pl061_read(void *opaque, hwaddr offset,
29
{
30
PL061State *s = (PL061State *)opaque;
31
32
- if (offset < 0x400) {
33
- return s->data & (offset >> 2);
34
- }
35
- if (offset >= s->rsvd_start && offset <= 0xfcc) {
36
- goto err_out;
37
- }
38
- if (offset >= 0xfd0 && offset < 0x1000) {
39
- return s->id[(offset - 0xfd0) >> 2];
40
- }
41
switch (offset) {
42
+ case 0x0 ... 0x3ff: /* Data */
43
+ return s->data & (offset >> 2);
44
case 0x400: /* Direction */
45
return s->dir;
46
case 0x404: /* Interrupt sense */
47
@@ -XXX,XX +XXX,XX @@ static uint64_t pl061_read(void *opaque, hwaddr offset,
48
case 0x420: /* Alternate function select */
49
return s->afsel;
50
case 0x500: /* 2mA drive */
51
+ if (s->id != pl061_id_luminary) {
52
+ goto bad_offset;
53
+ }
54
return s->dr2r;
55
case 0x504: /* 4mA drive */
56
+ if (s->id != pl061_id_luminary) {
57
+ goto bad_offset;
58
+ }
59
return s->dr4r;
60
case 0x508: /* 8mA drive */
61
+ if (s->id != pl061_id_luminary) {
62
+ goto bad_offset;
63
+ }
64
return s->dr8r;
65
case 0x50c: /* Open drain */
66
+ if (s->id != pl061_id_luminary) {
67
+ goto bad_offset;
68
+ }
69
return s->odr;
70
case 0x510: /* Pull-up */
71
+ if (s->id != pl061_id_luminary) {
72
+ goto bad_offset;
73
+ }
74
return s->pur;
75
case 0x514: /* Pull-down */
76
+ if (s->id != pl061_id_luminary) {
77
+ goto bad_offset;
78
+ }
79
return s->pdr;
80
case 0x518: /* Slew rate control */
81
+ if (s->id != pl061_id_luminary) {
82
+ goto bad_offset;
83
+ }
84
return s->slr;
85
case 0x51c: /* Digital enable */
86
+ if (s->id != pl061_id_luminary) {
87
+ goto bad_offset;
88
+ }
89
return s->den;
90
case 0x520: /* Lock */
91
+ if (s->id != pl061_id_luminary) {
92
+ goto bad_offset;
93
+ }
94
return s->locked;
95
case 0x524: /* Commit */
96
+ if (s->id != pl061_id_luminary) {
97
+ goto bad_offset;
98
+ }
99
return s->cr;
100
case 0x528: /* Analog mode select */
101
+ if (s->id != pl061_id_luminary) {
102
+ goto bad_offset;
103
+ }
104
return s->amsel;
105
+ case 0xfd0 ... 0xfff: /* ID registers */
106
+ return s->id[(offset - 0xfd0) >> 2];
107
default:
108
+ bad_offset:
109
+ qemu_log_mask(LOG_GUEST_ERROR,
110
+ "pl061_read: Bad offset %x\n", (int)offset);
111
break;
112
}
113
-err_out:
114
- qemu_log_mask(LOG_GUEST_ERROR,
115
- "pl061_read: Bad offset %x\n", (int)offset);
116
return 0;
117
}
118
119
@@ -XXX,XX +XXX,XX @@ static void pl061_write(void *opaque, hwaddr offset,
120
PL061State *s = (PL061State *)opaque;
121
uint8_t mask;
122
123
- if (offset < 0x400) {
124
+ switch (offset) {
125
+ case 0 ... 0x3ff:
126
mask = (offset >> 2) & s->dir;
127
s->data = (s->data & ~mask) | (value & mask);
128
pl061_update(s);
129
return;
130
- }
131
- if (offset >= s->rsvd_start) {
132
- goto err_out;
133
- }
134
- switch (offset) {
135
case 0x400: /* Direction */
136
s->dir = value & 0xff;
137
break;
138
@@ -XXX,XX +XXX,XX @@ static void pl061_write(void *opaque, hwaddr offset,
139
s->afsel = (s->afsel & ~mask) | (value & mask);
140
break;
141
case 0x500: /* 2mA drive */
142
+ if (s->id != pl061_id_luminary) {
143
+ goto bad_offset;
144
+ }
145
s->dr2r = value & 0xff;
146
break;
147
case 0x504: /* 4mA drive */
148
+ if (s->id != pl061_id_luminary) {
149
+ goto bad_offset;
150
+ }
151
s->dr4r = value & 0xff;
152
break;
153
case 0x508: /* 8mA drive */
154
+ if (s->id != pl061_id_luminary) {
155
+ goto bad_offset;
156
+ }
157
s->dr8r = value & 0xff;
158
break;
159
case 0x50c: /* Open drain */
160
+ if (s->id != pl061_id_luminary) {
161
+ goto bad_offset;
162
+ }
163
s->odr = value & 0xff;
164
break;
165
case 0x510: /* Pull-up */
166
+ if (s->id != pl061_id_luminary) {
167
+ goto bad_offset;
168
+ }
169
s->pur = value & 0xff;
170
break;
171
case 0x514: /* Pull-down */
172
+ if (s->id != pl061_id_luminary) {
173
+ goto bad_offset;
174
+ }
175
s->pdr = value & 0xff;
176
break;
177
case 0x518: /* Slew rate control */
178
+ if (s->id != pl061_id_luminary) {
179
+ goto bad_offset;
180
+ }
181
s->slr = value & 0xff;
182
break;
183
case 0x51c: /* Digital enable */
184
+ if (s->id != pl061_id_luminary) {
185
+ goto bad_offset;
186
+ }
187
s->den = value & 0xff;
188
break;
189
case 0x520: /* Lock */
190
+ if (s->id != pl061_id_luminary) {
191
+ goto bad_offset;
192
+ }
193
s->locked = (value != 0xacce551);
194
break;
195
case 0x524: /* Commit */
196
+ if (s->id != pl061_id_luminary) {
197
+ goto bad_offset;
198
+ }
199
if (!s->locked)
200
s->cr = value & 0xff;
201
break;
202
case 0x528:
203
+ if (s->id != pl061_id_luminary) {
204
+ goto bad_offset;
205
+ }
206
s->amsel = value & 0xff;
207
break;
208
default:
209
- goto err_out;
210
+ bad_offset:
211
+ qemu_log_mask(LOG_GUEST_ERROR,
212
+ "pl061_write: Bad offset %x\n", (int)offset);
213
+ return;
214
}
215
pl061_update(s);
216
return;
217
-err_out:
218
- qemu_log_mask(LOG_GUEST_ERROR,
219
- "pl061_write: Bad offset %x\n", (int)offset);
220
}
221
222
static void pl061_reset(DeviceState *dev)
223
@@ -XXX,XX +XXX,XX @@ static void pl061_luminary_init(Object *obj)
224
PL061State *s = PL061(obj);
225
226
s->id = pl061_id_luminary;
227
- s->rsvd_start = 0x52c;
228
}
229
230
static void pl061_init(Object *obj)
231
@@ -XXX,XX +XXX,XX @@ static void pl061_init(Object *obj)
232
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
233
234
s->id = pl061_id;
235
- s->rsvd_start = 0x424;
236
237
memory_region_init_io(&s->iomem, obj, &pl061_ops, s, "pl061", 0x1000);
238
sysbus_init_mmio(sbd, &s->iomem);
239
--
240
2.20.1
241
242
diff view generated by jsdifflib
1
The imx_epit device has a software-controllable reset triggered by
1
Add tracepoints for reads and writes to the PL061 registers. This requires
2
setting the SWR bit in the CR register. An error in commit cc2722ec83ad9
2
restructuring pl061_read() to only return after the tracepoint, rather
3
means that we will end up assert()ing if the guest does this, because
3
than having lots of early-returns.
4
the code in imx_epit_write() starts ptimer transactions, and then
5
imx_epit_reset() also starts ptimer transactions, triggering
6
"ptimer_transaction_begin: Assertion `!s->in_transaction' failed".
7
4
8
The cleanest way to avoid this double-transaction is to move the
9
start-transaction for the CR write handling down below the check of
10
the SWR bit.
11
12
Fixes: https://bugs.launchpad.net/qemu/+bug/1880424
13
Fixes: cc2722ec83ad944505fe
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Message-id: 20200727154550.3409-1-peter.maydell@linaro.org
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
---
8
---
18
hw/timer/imx_epit.c | 13 ++++++++++---
9
hw/gpio/pl061.c | 70 ++++++++++++++++++++++++++++++--------------
19
1 file changed, 10 insertions(+), 3 deletions(-)
10
hw/gpio/trace-events | 2 ++
11
2 files changed, 50 insertions(+), 22 deletions(-)
20
12
21
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
13
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
22
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/timer/imx_epit.c
15
--- a/hw/gpio/pl061.c
24
+++ b/hw/timer/imx_epit.c
16
+++ b/hw/gpio/pl061.c
25
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
17
@@ -XXX,XX +XXX,XX @@ static uint64_t pl061_read(void *opaque, hwaddr offset,
26
18
unsigned size)
27
switch (offset >> 2) {
19
{
28
case 0: /* CR */
20
PL061State *s = (PL061State *)opaque;
29
- ptimer_transaction_begin(s->timer_cmp);
21
+ uint64_t r = 0;
30
- ptimer_transaction_begin(s->timer_reload);
22
31
23
switch (offset) {
32
oldcr = s->cr;
24
case 0x0 ... 0x3ff: /* Data */
33
s->cr = value & 0x03ffffff;
25
- return s->data & (offset >> 2);
34
if (s->cr & CR_SWR) {
26
+ r = s->data & (offset >> 2);
35
/* handle the reset */
27
+ break;
36
imx_epit_reset(DEVICE(s));
28
case 0x400: /* Direction */
37
- } else {
29
- return s->dir;
38
+ /*
30
+ r = s->dir;
39
+ * TODO: could we 'break' here? following operations appear
31
+ break;
40
+ * to duplicate the work imx_epit_reset() already did.
32
case 0x404: /* Interrupt sense */
41
+ */
33
- return s->isense;
42
+ }
34
+ r = s->isense;
35
+ break;
36
case 0x408: /* Interrupt both edges */
37
- return s->ibe;
38
+ r = s->ibe;
39
+ break;
40
case 0x40c: /* Interrupt event */
41
- return s->iev;
42
+ r = s->iev;
43
+ break;
44
case 0x410: /* Interrupt mask */
45
- return s->im;
46
+ r = s->im;
47
+ break;
48
case 0x414: /* Raw interrupt status */
49
- return s->istate;
50
+ r = s->istate;
51
+ break;
52
case 0x418: /* Masked interrupt status */
53
- return s->istate & s->im;
54
+ r = s->istate & s->im;
55
+ break;
56
case 0x420: /* Alternate function select */
57
- return s->afsel;
58
+ r = s->afsel;
59
+ break;
60
case 0x500: /* 2mA drive */
61
if (s->id != pl061_id_luminary) {
62
goto bad_offset;
63
}
64
- return s->dr2r;
65
+ r = s->dr2r;
66
+ break;
67
case 0x504: /* 4mA drive */
68
if (s->id != pl061_id_luminary) {
69
goto bad_offset;
70
}
71
- return s->dr4r;
72
+ r = s->dr4r;
73
+ break;
74
case 0x508: /* 8mA drive */
75
if (s->id != pl061_id_luminary) {
76
goto bad_offset;
77
}
78
- return s->dr8r;
79
+ r = s->dr8r;
80
+ break;
81
case 0x50c: /* Open drain */
82
if (s->id != pl061_id_luminary) {
83
goto bad_offset;
84
}
85
- return s->odr;
86
+ r = s->odr;
87
+ break;
88
case 0x510: /* Pull-up */
89
if (s->id != pl061_id_luminary) {
90
goto bad_offset;
91
}
92
- return s->pur;
93
+ r = s->pur;
94
+ break;
95
case 0x514: /* Pull-down */
96
if (s->id != pl061_id_luminary) {
97
goto bad_offset;
98
}
99
- return s->pdr;
100
+ r = s->pdr;
101
+ break;
102
case 0x518: /* Slew rate control */
103
if (s->id != pl061_id_luminary) {
104
goto bad_offset;
105
}
106
- return s->slr;
107
+ r = s->slr;
108
+ break;
109
case 0x51c: /* Digital enable */
110
if (s->id != pl061_id_luminary) {
111
goto bad_offset;
112
}
113
- return s->den;
114
+ r = s->den;
115
+ break;
116
case 0x520: /* Lock */
117
if (s->id != pl061_id_luminary) {
118
goto bad_offset;
119
}
120
- return s->locked;
121
+ r = s->locked;
122
+ break;
123
case 0x524: /* Commit */
124
if (s->id != pl061_id_luminary) {
125
goto bad_offset;
126
}
127
- return s->cr;
128
+ r = s->cr;
129
+ break;
130
case 0x528: /* Analog mode select */
131
if (s->id != pl061_id_luminary) {
132
goto bad_offset;
133
}
134
- return s->amsel;
135
+ r = s->amsel;
136
+ break;
137
case 0xfd0 ... 0xfff: /* ID registers */
138
- return s->id[(offset - 0xfd0) >> 2];
139
+ r = s->id[(offset - 0xfd0) >> 2];
140
+ break;
141
default:
142
bad_offset:
143
qemu_log_mask(LOG_GUEST_ERROR,
144
"pl061_read: Bad offset %x\n", (int)offset);
145
break;
146
}
147
- return 0;
43
+
148
+
44
+ ptimer_transaction_begin(s->timer_cmp);
149
+ trace_pl061_read(DEVICE(s)->canonical_path, offset, r);
45
+ ptimer_transaction_begin(s->timer_reload);
150
+ return r;
151
}
152
153
static void pl061_write(void *opaque, hwaddr offset,
154
@@ -XXX,XX +XXX,XX @@ static void pl061_write(void *opaque, hwaddr offset,
155
PL061State *s = (PL061State *)opaque;
156
uint8_t mask;
157
158
+ trace_pl061_write(DEVICE(s)->canonical_path, offset, value);
46
+
159
+
47
+ if (!(s->cr & CR_SWR)) {
160
switch (offset) {
48
imx_epit_set_freq(s);
161
case 0 ... 0x3ff:
49
}
162
mask = (offset >> 2) & s->dir;
50
163
diff --git a/hw/gpio/trace-events b/hw/gpio/trace-events
164
index XXXXXXX..XXXXXXX 100644
165
--- a/hw/gpio/trace-events
166
+++ b/hw/gpio/trace-events
167
@@ -XXX,XX +XXX,XX @@ pl061_update(const char *id, uint32_t dir, uint32_t data) "%s GPIODIR 0x%x GPIOD
168
pl061_set_output(const char *id, int gpio, int level) "%s setting output %d to %d"
169
pl061_input_change(const char *id, int gpio, int level) "%s input %d changed to %d"
170
pl061_update_istate(const char *id, uint32_t istate, uint32_t im, int level) "%s GPIORIS 0x%x GPIOIE 0x%x interrupt level %d"
171
+pl061_read(const char *id, uint64_t offset, uint64_t r) "%s offset 0x%" PRIx64 " value 0x%" PRIx64
172
+pl061_write(const char *id, uint64_t offset, uint64_t value) "%s offset 0x%" PRIx64 " value 0x%" PRIx64
173
174
# sifive_gpio.c
175
sifive_gpio_read(uint64_t offset, uint64_t r) "offset 0x%" PRIx64 " value 0x%" PRIx64
51
--
176
--
52
2.20.1
177
2.20.1
53
178
54
179
diff view generated by jsdifflib
New patch
1
Add a comment documenting the "QEMU interface" of this device:
2
which MMIO regions, IRQ lines, GPIO lines, etc it exposes.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
hw/gpio/pl061.c | 7 +++++++
8
1 file changed, 7 insertions(+)
9
10
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/gpio/pl061.c
13
+++ b/hw/gpio/pl061.c
14
@@ -XXX,XX +XXX,XX @@
15
* Written by Paul Brook
16
*
17
* This code is licensed under the GPL.
18
+ *
19
+ * QEMU interface:
20
+ * + sysbus MMIO region 0: the device registers
21
+ * + sysbus IRQ: the GPIOINTR interrupt line
22
+ * + unnamed GPIO inputs 0..7: inputs to connect to the emulated GPIO lines
23
+ * + unnamed GPIO outputs 0..7: the emulated GPIO lines, considered as
24
+ * outputs
25
*/
26
27
#include "qemu/osdep.h"
28
--
29
2.20.1
30
31
diff view generated by jsdifflib
New patch
1
The Luminary variant of the PL061 has registers GPIOPUR and GPIOPDR
2
which lets the guest configure whether the GPIO lines are pull-up,
3
pull-down, or truly floating. Instead of assuming all lines are pulled
4
high, honour the PUR and PDR registers.
1
5
6
For the plain PL061, continue to assume that lines have an external
7
pull-up resistor, as we did before.
8
9
The stellaris board actually relies on this behaviour -- the CD line
10
of the ssd0323 display device is connected to GPIO output C7, and it
11
is only because of a different bug which we're about to fix that we
12
weren't incorrectly driving this line high on reset and putting the
13
ssd0323 into data mode.
14
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
---
18
hw/gpio/pl061.c | 58 +++++++++++++++++++++++++++++++++++++++++---
19
hw/gpio/trace-events | 2 +-
20
2 files changed, 55 insertions(+), 5 deletions(-)
21
22
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/gpio/pl061.c
25
+++ b/hw/gpio/pl061.c
26
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pl061 = {
27
}
28
};
29
30
+static uint8_t pl061_floating(PL061State *s)
31
+{
32
+ /*
33
+ * Return mask of bits which correspond to pins configured as inputs
34
+ * and which are floating (neither pulled up to 1 nor down to 0).
35
+ */
36
+ uint8_t floating;
37
+
38
+ if (s->id == pl061_id_luminary) {
39
+ /*
40
+ * If both PUR and PDR bits are clear, there is neither a pullup
41
+ * nor a pulldown in place, and the output truly floats.
42
+ */
43
+ floating = ~(s->pur | s->pdr);
44
+ } else {
45
+ /* Assume outputs are pulled high. FIXME: this is board dependent. */
46
+ floating = 0;
47
+ }
48
+ return floating & ~s->dir;
49
+}
50
+
51
+static uint8_t pl061_pullups(PL061State *s)
52
+{
53
+ /*
54
+ * Return mask of bits which correspond to pins configured as inputs
55
+ * and which are pulled up to 1.
56
+ */
57
+ uint8_t pullups;
58
+
59
+ if (s->id == pl061_id_luminary) {
60
+ /*
61
+ * The Luminary variant of the PL061 has an extra registers which
62
+ * the guest can use to configure whether lines should be pullup
63
+ * or pulldown.
64
+ */
65
+ pullups = s->pur;
66
+ } else {
67
+ /* Assume outputs are pulled high. FIXME: this is board dependent. */
68
+ pullups = 0xff;
69
+ }
70
+ return pullups & ~s->dir;
71
+}
72
+
73
static void pl061_update(PL061State *s)
74
{
75
uint8_t changed;
76
uint8_t mask;
77
uint8_t out;
78
int i;
79
+ uint8_t pullups = pl061_pullups(s);
80
+ uint8_t floating = pl061_floating(s);
81
82
- trace_pl061_update(DEVICE(s)->canonical_path, s->dir, s->data);
83
+ trace_pl061_update(DEVICE(s)->canonical_path, s->dir, s->data,
84
+ pullups, floating);
85
86
- /* Outputs float high. */
87
- /* FIXME: This is board dependent. */
88
- out = (s->data & s->dir) | ~s->dir;
89
+ /*
90
+ * Pins configured as output are driven from the data register;
91
+ * otherwise if they're pulled up they're 1, and if they're floating
92
+ * then we give them the same value they had previously, so we don't
93
+ * report any change to the other end.
94
+ */
95
+ out = (s->data & s->dir) | pullups | (s->old_out_data & floating);
96
changed = s->old_out_data ^ out;
97
if (changed) {
98
s->old_out_data = out;
99
diff --git a/hw/gpio/trace-events b/hw/gpio/trace-events
100
index XXXXXXX..XXXXXXX 100644
101
--- a/hw/gpio/trace-events
102
+++ b/hw/gpio/trace-events
103
@@ -XXX,XX +XXX,XX @@ nrf51_gpio_set(int64_t line, int64_t value) "line %" PRIi64 " value %" PRIi64
104
nrf51_gpio_update_output_irq(int64_t line, int64_t value) "line %" PRIi64 " value %" PRIi64
105
106
# pl061.c
107
-pl061_update(const char *id, uint32_t dir, uint32_t data) "%s GPIODIR 0x%x GPIODATA 0x%x"
108
+pl061_update(const char *id, uint32_t dir, uint32_t data, uint32_t pullups, uint32_t floating) "%s GPIODIR 0x%x GPIODATA 0x%x pullups 0x%x floating 0x%x"
109
pl061_set_output(const char *id, int gpio, int level) "%s setting output %d to %d"
110
pl061_input_change(const char *id, int gpio, int level) "%s input %d changed to %d"
111
pl061_update_istate(const char *id, uint32_t istate, uint32_t im, int level) "%s GPIORIS 0x%x GPIOIE 0x%x interrupt level %d"
112
--
113
2.20.1
114
115
diff view generated by jsdifflib
1
The NVIC provides an outbound qemu_irq "SYSRESETREQ" which it signals
1
The PL061 GPIO does not itself include pullup or pulldown resistors
2
when the guest sets the SYSRESETREQ bit in the AIRCR register. This
2
to set the value of a GPIO line treated as an output when it is
3
matches the hardware design (where the CPU has a signal of this name
3
configured as an input (ie when the PL061 itself is not driving it).
4
and it is up to the SoC to connect that up to an actual reset
4
In real hardware it is up to the board to add suitable pullups or
5
mechanism), but in QEMU it mostly results in duplicated code in SoC
5
pulldowns. Currently our implementation hardwires this to "outputs
6
objects and bugs where SoC model implementors forget to wire up the
6
pulled high", which is correct for some boards (eg the realview ones:
7
SYSRESETREQ line.
7
see figure 3-29 in the "RealView Platform Baseboard for ARM926EJ-S
8
User Guide" DUI0224I), but wrong for others.
8
9
9
Provide a default behaviour for the case where SYSRESETREQ is not
10
In particular, the wiring in the 'virt' board and the gpio-pwr device
10
actually connected to anything: use qemu_system_reset_request() to
11
assumes that wires should be pulled low, because otherwise the
11
perform a system reset. This will allow us to remove the
12
pull-to-high will trigger a shutdown or reset action. (The only
12
implementations of SYSRESETREQ handling from the boards where that's
13
reason this doesn't happen immediately on startup is due to another
13
exactly what it does, and also fixes the bugs in the board models
14
bug in the PL061, where we don't assert the GPIOs to the correct
14
which forgot to wire up the signal:
15
value on reset, but will do so as soon as the guest touches a
16
register and pl061_update() gets called.)
15
17
16
* microbit
18
Add properties to the pl061 so the board can configure whether it
17
* mps2-an385
19
wants GPIO lines to have pullup, pulldown, or neither.
18
* mps2-an505
19
* mps2-an511
20
* mps2-an521
21
* musca-a
22
* musca-b1
23
* netduino
24
* netduinoplus2
25
26
We still allow the board to wire up the signal if it needs to, in case
27
we need to model more complicated reset controller logic or to model
28
buggy SoC hardware which forgot to wire up the line itself. But
29
defaulting to "reset the system" is more often going to be correct
30
than defaulting to "do nothing".
31
20
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
34
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
35
Message-id: 20200728103744.6909-3-peter.maydell@linaro.org
36
---
23
---
37
include/hw/arm/armv7m.h | 4 +++-
24
hw/gpio/pl061.c | 51 +++++++++++++++++++++++++++++++++++++++++++++----
38
hw/intc/armv7m_nvic.c | 17 ++++++++++++++++-
25
1 file changed, 47 insertions(+), 4 deletions(-)
39
2 files changed, 19 insertions(+), 2 deletions(-)
40
26
41
diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
27
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
42
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
43
--- a/include/hw/arm/armv7m.h
29
--- a/hw/gpio/pl061.c
44
+++ b/include/hw/arm/armv7m.h
30
+++ b/hw/gpio/pl061.c
45
@@ -XXX,XX +XXX,XX @@ typedef struct {
46
47
/* ARMv7M container object.
48
* + Unnamed GPIO input lines: external IRQ lines for the NVIC
49
- * + Named GPIO output SYSRESETREQ: signalled for guest AIRCR.SYSRESETREQ
50
+ * + Named GPIO output SYSRESETREQ: signalled for guest AIRCR.SYSRESETREQ.
51
+ * If this GPIO is not wired up then the NVIC will default to performing
52
+ * a qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET).
53
* + Property "cpu-type": CPU type to instantiate
54
* + Property "num-irq": number of external IRQ lines
55
* + Property "memory": MemoryRegion defining the physical address space
56
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/intc/armv7m_nvic.c
59
+++ b/hw/intc/armv7m_nvic.c
60
@@ -XXX,XX +XXX,XX @@
31
@@ -XXX,XX +XXX,XX @@
61
#include "hw/intc/armv7m_nvic.h"
32
* + unnamed GPIO inputs 0..7: inputs to connect to the emulated GPIO lines
33
* + unnamed GPIO outputs 0..7: the emulated GPIO lines, considered as
34
* outputs
35
+ * + QOM property "pullups": an integer defining whether non-floating lines
36
+ * configured as inputs should be pulled up to logical 1 (ie whether in
37
+ * real hardware they have a pullup resistor on the line out of the PL061).
38
+ * This should be an 8-bit value, where bit 0 is 1 if GPIO line 0 should
39
+ * be pulled high, bit 1 configures line 1, and so on. The default is 0xff,
40
+ * indicating that all GPIO lines are pulled up to logical 1.
41
+ * + QOM property "pulldowns": an integer defining whether non-floating lines
42
+ * configured as inputs should be pulled down to logical 0 (ie whether in
43
+ * real hardware they have a pulldown resistor on the line out of the PL061).
44
+ * This should be an 8-bit value, where bit 0 is 1 if GPIO line 0 should
45
+ * be pulled low, bit 1 configures line 1, and so on. The default is 0x0.
46
+ * It is an error to set a bit in both "pullups" and "pulldowns". If a bit
47
+ * is 0 in both, then the line is considered to be floating, and it will
48
+ * not have qemu_set_irq() called on it when it is configured as an input.
49
*/
50
51
#include "qemu/osdep.h"
62
#include "hw/irq.h"
52
#include "hw/irq.h"
63
#include "hw/qdev-properties.h"
53
#include "hw/sysbus.h"
64
+#include "sysemu/runstate.h"
54
+#include "hw/qdev-properties.h"
65
#include "target/arm/cpu.h"
55
#include "migration/vmstate.h"
66
#include "exec/exec-all.h"
56
+#include "qapi/error.h"
67
#include "exec/memop.h"
57
#include "qemu/log.h"
68
@@ -XXX,XX +XXX,XX @@ static const uint8_t nvic_id[] = {
58
#include "qemu/module.h"
69
0x00, 0xb0, 0x1b, 0x00, 0x0d, 0xe0, 0x05, 0xb1
59
#include "qom/object.h"
60
@@ -XXX,XX +XXX,XX @@ struct PL061State {
61
qemu_irq irq;
62
qemu_irq out[N_GPIOS];
63
const unsigned char *id;
64
+ /* Properties, for non-Luminary PL061 */
65
+ uint32_t pullups;
66
+ uint32_t pulldowns;
70
};
67
};
71
68
72
+static void signal_sysresetreq(NVICState *s)
69
static const VMStateDescription vmstate_pl061 = {
70
@@ -XXX,XX +XXX,XX @@ static uint8_t pl061_floating(PL061State *s)
71
*/
72
floating = ~(s->pur | s->pdr);
73
} else {
74
- /* Assume outputs are pulled high. FIXME: this is board dependent. */
75
- floating = 0;
76
+ floating = ~(s->pullups | s->pulldowns);
77
}
78
return floating & ~s->dir;
79
}
80
@@ -XXX,XX +XXX,XX @@ static uint8_t pl061_pullups(PL061State *s)
81
*/
82
pullups = s->pur;
83
} else {
84
- /* Assume outputs are pulled high. FIXME: this is board dependent. */
85
- pullups = 0xff;
86
+ pullups = s->pullups;
87
}
88
return pullups & ~s->dir;
89
}
90
@@ -XXX,XX +XXX,XX @@ static void pl061_init(Object *obj)
91
qdev_init_gpio_out(dev, s->out, N_GPIOS);
92
}
93
94
+static void pl061_realize(DeviceState *dev, Error **errp)
73
+{
95
+{
74
+ if (qemu_irq_is_connected(s->sysresetreq)) {
96
+ PL061State *s = PL061(dev);
75
+ qemu_irq_pulse(s->sysresetreq);
97
+
76
+ } else {
98
+ if (s->pullups > 0xff) {
77
+ /*
99
+ error_setg(errp, "pullups property must be between 0 and 0xff");
78
+ * Default behaviour if the SoC doesn't need to wire up
100
+ return;
79
+ * SYSRESETREQ (eg to a system reset controller of some kind):
101
+ }
80
+ * perform a system reset via the usual QEMU API.
102
+ if (s->pulldowns > 0xff) {
81
+ */
103
+ error_setg(errp, "pulldowns property must be between 0 and 0xff");
82
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
104
+ return;
105
+ }
106
+ if (s->pullups & s->pulldowns) {
107
+ error_setg(errp, "no bit may be set both in pullups and pulldowns");
108
+ return;
83
+ }
109
+ }
84
+}
110
+}
85
+
111
+
86
static int nvic_pending_prio(NVICState *s)
112
+static Property pl061_props[] = {
113
+ DEFINE_PROP_UINT32("pullups", PL061State, pullups, 0xff),
114
+ DEFINE_PROP_UINT32("pulldowns", PL061State, pulldowns, 0x0),
115
+ DEFINE_PROP_END_OF_LIST()
116
+};
117
+
118
static void pl061_class_init(ObjectClass *klass, void *data)
87
{
119
{
88
/* return the group priority of the current pending interrupt,
120
DeviceClass *dc = DEVICE_CLASS(klass);
89
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
121
90
if (value & R_V7M_AIRCR_SYSRESETREQ_MASK) {
122
dc->vmsd = &vmstate_pl061;
91
if (attrs.secure ||
123
dc->reset = &pl061_reset;
92
!(cpu->env.v7m.aircr & R_V7M_AIRCR_SYSRESETREQS_MASK)) {
124
+ dc->realize = pl061_realize;
93
- qemu_irq_pulse(s->sysresetreq);
125
+ device_class_set_props(dc, pl061_props);
94
+ signal_sysresetreq(s);
126
}
95
}
127
96
}
128
static const TypeInfo pl061_info = {
97
if (value & R_V7M_AIRCR_VECTCLRACTIVE_MASK) {
98
--
129
--
99
2.20.1
130
2.20.1
100
131
101
132
diff view generated by jsdifflib
New patch
1
For the virt board we have two PL061 devices -- one for NonSecure which
2
is inputs only, and one for Secure which is outputs only. For the former,
3
we don't care whether its outputs are pulled low or high when the line is
4
configured as an input, because we don't connect them. For the latter,
5
we do care, because we wire the lines up to the gpio-pwr device, which
6
assumes that level 1 means "do the action" and 1 means "do nothing".
7
For consistency in case we add more outputs in future, configure both
8
PL061s to pull GPIO lines down to 0.
1
9
10
Reported-by: Maxim Uvarov <maxim.uvarov@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
---
14
hw/arm/virt.c | 3 +++
15
1 file changed, 3 insertions(+)
16
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/virt.c
20
+++ b/hw/arm/virt.c
21
@@ -XXX,XX +XXX,XX @@ static void create_gpio_devices(const VirtMachineState *vms, int gpio,
22
MachineState *ms = MACHINE(vms);
23
24
pl061_dev = qdev_new("pl061");
25
+ /* Pull lines down to 0 if not driven by the PL061 */
26
+ qdev_prop_set_uint32(pl061_dev, "pullups", 0);
27
+ qdev_prop_set_uint32(pl061_dev, "pulldowns", 0xff);
28
s = SYS_BUS_DEVICE(pl061_dev);
29
sysbus_realize_and_unref(s, &error_fatal);
30
memory_region_add_subregion(mem, base, sysbus_mmio_get_region(s, 0));
31
--
32
2.20.1
33
34
diff view generated by jsdifflib
1
Mostly devices don't need to care whether one of their output
1
The PL061 comes out of reset with all its lines configured as input,
2
qemu_irq lines is connected, because functions like qemu_set_irq()
2
which means they might need to be pulled to 0 or 1 depending on the
3
silently do nothing if there is nothing on the other end. However
3
'pullups' and 'pulldowns' properties. Currently we do not assert
4
sometimes a device might want to implement default behaviour for the
4
these lines on reset; they will only be set whenever the guest first
5
case where the machine hasn't wired the line up to anywhere.
5
touches a register that triggers a call to pl061_update().
6
6
7
Provide a function qemu_irq_is_connected() that devices can use for
7
Convert the device to three-phase reset so we have a place where we
8
this purpose. (The test is trivial but encapsulating it in a
8
can safely call qemu_set_irq() to set the floating lines to their
9
function makes it easier to see where we're doing it in case we need
9
correct values.
10
to change the implementation later.)
11
10
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20200728103744.6909-2-peter.maydell@linaro.org
16
---
14
---
17
include/hw/irq.h | 18 ++++++++++++++++++
15
hw/gpio/pl061.c | 29 +++++++++++++++++++++++++----
18
1 file changed, 18 insertions(+)
16
hw/gpio/trace-events | 1 +
17
2 files changed, 26 insertions(+), 4 deletions(-)
19
18
20
diff --git a/include/hw/irq.h b/include/hw/irq.h
19
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
21
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/irq.h
21
--- a/hw/gpio/pl061.c
23
+++ b/include/hw/irq.h
22
+++ b/hw/gpio/pl061.c
24
@@ -XXX,XX +XXX,XX @@ qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2);
23
@@ -XXX,XX +XXX,XX @@ static void pl061_write(void *opaque, hwaddr offset,
25
on an existing vector of qemu_irq. */
24
return;
26
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n);
25
}
27
26
28
+/**
27
-static void pl061_reset(DeviceState *dev)
29
+ * qemu_irq_is_connected: Return true if IRQ line is wired up
28
+static void pl061_enter_reset(Object *obj, ResetType type)
30
+ *
29
{
31
+ * If a qemu_irq has a device on the other (receiving) end of it,
30
- PL061State *s = PL061(dev);
32
+ * return true; otherwise return false.
31
+ PL061State *s = PL061(obj);
33
+ *
32
+
34
+ * Usually device models don't need to care whether the machine model
33
+ trace_pl061_reset(DEVICE(s)->canonical_path);
35
+ * has wired up their outbound qemu_irq lines, because functions like
34
36
+ * qemu_set_irq() silently do nothing if there is nothing on the other
35
/* reset values from PL061 TRM, Stellaris LM3S5P31 & LM3S8962 Data Sheet */
37
+ * end of the line. However occasionally a device model will want to
36
s->data = 0;
38
+ * provide default behaviour if its output is left floating, and
37
- s->old_out_data = 0;
39
+ * it can use this function to identify when that is the case.
38
s->old_in_data = 0;
40
+ */
39
s->dir = 0;
41
+static inline bool qemu_irq_is_connected(qemu_irq irq)
40
s->isense = 0;
41
@@ -XXX,XX +XXX,XX @@ static void pl061_reset(DeviceState *dev)
42
s->amsel = 0;
43
}
44
45
+static void pl061_hold_reset(Object *obj)
42
+{
46
+{
43
+ return irq != NULL;
47
+ PL061State *s = PL061(obj);
48
+ int i, level;
49
+ uint8_t floating = pl061_floating(s);
50
+ uint8_t pullups = pl061_pullups(s);
51
+
52
+ for (i = 0; i < N_GPIOS; i++) {
53
+ if (extract32(floating, i, 1)) {
54
+ continue;
55
+ }
56
+ level = extract32(pullups, i, 1);
57
+ trace_pl061_set_output(DEVICE(s)->canonical_path, i, level);
58
+ qemu_set_irq(s->out[i], level);
59
+ }
60
+ s->old_out_data = pullups;
44
+}
61
+}
45
+
62
+
46
#endif
63
static void pl061_set_irq(void * opaque, int irq, int level)
64
{
65
PL061State *s = (PL061State *)opaque;
66
@@ -XXX,XX +XXX,XX @@ static Property pl061_props[] = {
67
static void pl061_class_init(ObjectClass *klass, void *data)
68
{
69
DeviceClass *dc = DEVICE_CLASS(klass);
70
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
71
72
dc->vmsd = &vmstate_pl061;
73
- dc->reset = &pl061_reset;
74
dc->realize = pl061_realize;
75
device_class_set_props(dc, pl061_props);
76
+ rc->phases.enter = pl061_enter_reset;
77
+ rc->phases.hold = pl061_hold_reset;
78
}
79
80
static const TypeInfo pl061_info = {
81
diff --git a/hw/gpio/trace-events b/hw/gpio/trace-events
82
index XXXXXXX..XXXXXXX 100644
83
--- a/hw/gpio/trace-events
84
+++ b/hw/gpio/trace-events
85
@@ -XXX,XX +XXX,XX @@ pl061_input_change(const char *id, int gpio, int level) "%s input %d changed to
86
pl061_update_istate(const char *id, uint32_t istate, uint32_t im, int level) "%s GPIORIS 0x%x GPIOIE 0x%x interrupt level %d"
87
pl061_read(const char *id, uint64_t offset, uint64_t r) "%s offset 0x%" PRIx64 " value 0x%" PRIx64
88
pl061_write(const char *id, uint64_t offset, uint64_t value) "%s offset 0x%" PRIx64 " value 0x%" PRIx64
89
+pl061_reset(const char *id) "%s reset"
90
91
# sifive_gpio.c
92
sifive_gpio_read(uint64_t offset, uint64_t r) "offset 0x%" PRIx64 " value 0x%" PRIx64
47
--
93
--
48
2.20.1
94
2.20.1
49
95
50
96
diff view generated by jsdifflib
1
The nrf51 SoC model wasn't setting the system_clock_scale
1
The Luminary PL061s in the Stellaris LM3S9695 don't all have the same
2
global.which meant that if guest code used the systick timer in "use
2
reset value for GPIOPUR. We can get away with not letting the board
3
the processor clock" mode it would hang because time never advances.
3
configure the PUR reset value because we don't actually wire anything
4
4
up to the lines which should reset to pull-up. Add a comment noting
5
Set the global to match the documented CPU clock speed for this SoC.
5
this omission.
6
7
This SoC in fact doesn't have a SysTick timer (which is the only thing
8
currently that cares about the system_clock_scale), because it's
9
a configurable option in the Cortex-M0. However our Cortex-M0 and
10
thus our nrf51 and our micro:bit board do provide a SysTick, so
11
we ought to provide a functional one rather than a broken one.
12
6
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Message-id: 20200727193458.31250-1-peter.maydell@linaro.org
16
---
9
---
17
hw/arm/nrf51_soc.c | 5 +++++
10
hw/gpio/pl061.c | 9 +++++++++
18
1 file changed, 5 insertions(+)
11
1 file changed, 9 insertions(+)
19
12
20
diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c
13
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
21
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/nrf51_soc.c
15
--- a/hw/gpio/pl061.c
23
+++ b/hw/arm/nrf51_soc.c
16
+++ b/hw/gpio/pl061.c
24
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static void pl061_enter_reset(Object *obj, ResetType type)
25
18
trace_pl061_reset(DEVICE(s)->canonical_path);
26
#define BASE_TO_IRQ(base) ((base >> 12) & 0x1F)
19
27
20
/* reset values from PL061 TRM, Stellaris LM3S5P31 & LM3S8962 Data Sheet */
28
+/* HCLK (the main CPU clock) on this SoC is always 16MHz */
29
+#define HCLK_FRQ 16000000
30
+
21
+
31
static uint64_t clock_read(void *opaque, hwaddr addr, unsigned int size)
22
+ /*
32
{
23
+ * FIXME: For the LM3S6965, not all of the PL061 instances have the
33
qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n",
24
+ * same reset values for GPIOPUR, GPIOAFSEL and GPIODEN, so in theory
34
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
25
+ * we should allow the board to configure these via properties.
35
return;
26
+ * In practice, we don't wire anything up to the affected GPIO lines
36
}
27
+ * (PB7, PC0, PC1, PC2, PC3 -- they're used for JTAG), so we can
37
28
+ * get away with this inaccuracy.
38
+ system_clock_scale = NANOSECONDS_PER_SECOND / HCLK_FRQ;
29
+ */
39
+
30
s->data = 0;
40
object_property_set_link(OBJECT(&s->cpu), "memory", OBJECT(&s->container),
31
s->old_in_data = 0;
41
&error_abort);
32
s->dir = 0;
42
if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpu), errp)) {
43
--
33
--
44
2.20.1
34
2.20.1
45
35
46
36
diff view generated by jsdifflib
1
The MSF2 SoC model and the Stellaris board code both wire
1
The stellaris board doesn't emulate the handling of the OLED
2
SYSRESETREQ up to a function that just invokes
2
chipselect line correctly. Expand the comment describing this,
3
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
3
including a sketch of the theoretical correct way to do it.
4
This is now the default action that the NVIC does if the line is
5
not connected, so we can delete the handling code.
6
4
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20200728103744.6909-4-peter.maydell@linaro.org
11
---
6
---
12
hw/arm/msf2-soc.c | 11 -----------
7
hw/arm/stellaris.c | 56 +++++++++++++++++++++++++++++++++++++++++++++-
13
hw/arm/stellaris.c | 12 ------------
8
1 file changed, 55 insertions(+), 1 deletion(-)
14
2 files changed, 23 deletions(-)
15
9
16
diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/msf2-soc.c
19
+++ b/hw/arm/msf2-soc.c
20
@@ -XXX,XX +XXX,XX @@
21
#include "hw/irq.h"
22
#include "hw/arm/msf2-soc.h"
23
#include "hw/misc/unimp.h"
24
-#include "sysemu/runstate.h"
25
#include "sysemu/sysemu.h"
26
27
#define MSF2_TIMER_BASE 0x40004000
28
@@ -XXX,XX +XXX,XX @@ static const int spi_irq[MSF2_NUM_SPIS] = { 2, 3 };
29
static const int uart_irq[MSF2_NUM_UARTS] = { 10, 11 };
30
static const int timer_irq[MSF2_NUM_TIMERS] = { 14, 15 };
31
32
-static void do_sys_reset(void *opaque, int n, int level)
33
-{
34
- if (level) {
35
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
36
- }
37
-}
38
-
39
static void m2sxxx_soc_initfn(Object *obj)
40
{
41
MSF2State *s = MSF2_SOC(obj);
42
@@ -XXX,XX +XXX,XX @@ static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp)
43
return;
44
}
45
46
- qdev_connect_gpio_out_named(DEVICE(&s->armv7m.nvic), "SYSRESETREQ", 0,
47
- qemu_allocate_irq(&do_sys_reset, NULL, 0));
48
-
49
system_clock_scale = NANOSECONDS_PER_SECOND / s->m3clk;
50
51
for (i = 0; i < MSF2_NUM_UARTS; i++) {
52
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
10
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
53
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/arm/stellaris.c
12
--- a/hw/arm/stellaris.c
55
+++ b/hw/arm/stellaris.c
13
+++ b/hw/arm/stellaris.c
56
@@ -XXX,XX +XXX,XX @@
57
#include "hw/boards.h"
58
#include "qemu/log.h"
59
#include "exec/address-spaces.h"
60
-#include "sysemu/runstate.h"
61
#include "sysemu/sysemu.h"
62
#include "hw/arm/armv7m.h"
63
#include "hw/char/pl011.h"
64
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_init(Object *obj)
65
qdev_init_gpio_in(dev, stellaris_adc_trigger, 1);
66
}
67
68
-static
69
-void do_sys_reset(void *opaque, int n, int level)
70
-{
71
- if (level) {
72
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
73
- }
74
-}
75
-
76
/* Board init. */
77
static stellaris_board_info stellaris_boards[] = {
78
{ "LM3S811EVB",
79
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
14
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
80
/* This will exit with an error if the user passed us a bad cpu_type */
15
DeviceState *sddev;
81
sysbus_realize_and_unref(SYS_BUS_DEVICE(nvic), &error_fatal);
16
DeviceState *ssddev;
82
17
83
- qdev_connect_gpio_out_named(nvic, "SYSRESETREQ", 0,
18
- /* Some boards have both an OLED controller and SD card connected to
84
- qemu_allocate_irq(&do_sys_reset, NULL, 0));
19
+ /*
85
-
20
+ * Some boards have both an OLED controller and SD card connected to
86
if (board->dc1 & (1 << 16)) {
21
* the same SSI port, with the SD card chip select connected to a
87
dev = sysbus_create_varargs(TYPE_STELLARIS_ADC, 0x40038000,
22
* GPIO pin. Technically the OLED chip select is connected to the
88
qdev_get_gpio_in(nvic, 14),
23
* SSI Fss pin. We do not bother emulating that as both devices
24
* should never be selected simultaneously, and our OLED controller
25
* ignores stray 0xff commands that occur when deselecting the SD
26
* card.
27
+ *
28
+ * The h/w wiring is:
29
+ * - GPIO pin D0 is wired to the active-low SD card chip select
30
+ * - GPIO pin A3 is wired to the active-low OLED chip select
31
+ * - The SoC wiring of the PL061 "auxiliary function" for A3 is
32
+ * SSI0Fss ("frame signal"), which is an output from the SoC's
33
+ * SSI controller. The SSI controller takes SSI0Fss low when it
34
+ * transmits a frame, so it can work as a chip-select signal.
35
+ * - GPIO A4 is aux-function SSI0Rx, and wired to the SD card Tx
36
+ * (the OLED never sends data to the CPU, so no wiring needed)
37
+ * - GPIO A5 is aux-function SSI0Tx, and wired to the SD card Rx
38
+ * and the OLED display-data-in
39
+ * - GPIO A2 is aux-function SSI0Clk, wired to SD card and OLED
40
+ * serial-clock input
41
+ * So a guest that wants to use the OLED can configure the PL061
42
+ * to make pins A2, A3, A5 aux-function, so they are connected
43
+ * directly to the SSI controller. When the SSI controller sends
44
+ * data it asserts SSI0Fss which selects the OLED.
45
+ * A guest that wants to use the SD card configures A2, A4 and A5
46
+ * as aux-function, but leaves A3 as a software-controlled GPIO
47
+ * line. It asserts the SD card chip-select by using the PL061
48
+ * to control pin D0, and lets the SSI controller handle Clk, Tx
49
+ * and Rx. (The SSI controller asserts Fss during tx cycles as
50
+ * usual, but because A3 is not set to aux-function this is not
51
+ * forwarded to the OLED, and so the OLED stays unselected.)
52
+ *
53
+ * The QEMU implementation instead is:
54
+ * - GPIO pin D0 is wired to the active-low SD card chip select,
55
+ * and also to the OLED chip-select which is implemented
56
+ * as *active-high*
57
+ * - SSI controller signals go to the devices regardless of
58
+ * whether the guest programs A2, A4, A5 as aux-function or not
59
+ *
60
+ * The problem with this implementation is if the guest doesn't
61
+ * care about the SD card and only uses the OLED. In that case it
62
+ * may choose never to do anything with D0 (leaving it in its
63
+ * default floating state, which reliably leaves the card disabled
64
+ * because an SD card has a pullup on CS within the card itself),
65
+ * and only set up A2, A3, A5. This for us would mean the OLED
66
+ * never gets the chip-select assert it needs. We work around
67
+ * this with a manual raise of D0 here (despite board creation
68
+ * code being the wrong place to raise IRQ lines) to put the OLED
69
+ * into an initially selected state.
70
+ *
71
+ * In theory the right way to model this would be:
72
+ * - Implement aux-function support in the PL061, with an
73
+ * extra set of AFIN and AFOUT GPIO lines (set up so that
74
+ * if a GPIO line is in auxfn mode the main GPIO in and out
75
+ * track the AFIN and AFOUT lines)
76
+ * - Wire the AFOUT for D0 up to either a line from the
77
+ * SSI controller that's pulled low around every transmit,
78
+ * or at least to an always-0 line here on the board
79
+ * - Make the ssd0323 OLED controller chipselect active-low
80
*/
81
bus = qdev_get_child_bus(dev, "ssi");
82
89
--
83
--
90
2.20.1
84
2.20.1
91
85
92
86
diff view generated by jsdifflib
New patch
1
From: "hnick@vmware.com" <hnick@vmware.com>
1
2
3
Signed-off-by: Nick Hudson <hnick@vmware.com>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
---
7
target/arm/helper.c | 16 +++++++++++++---
8
1 file changed, 13 insertions(+), 3 deletions(-)
9
10
diff --git a/target/arm/helper.c b/target/arm/helper.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/arm/helper.c
13
+++ b/target/arm/helper.c
14
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
15
.access = PL1_RW, .accessfn = access_tda,
16
.fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1),
17
.resetvalue = 0 },
18
- /* MDCCSR_EL0, aka DBGDSCRint. This is a read-only mirror of MDSCR_EL1.
19
+ /*
20
+ * MDCCSR_EL0[30:29] map to EDSCR[30:29]. Simply RAZ as the external
21
+ * Debug Communication Channel is not implemented.
22
+ */
23
+ { .name = "MDCCSR_EL0", .state = ARM_CP_STATE_AA64,
24
+ .opc0 = 2, .opc1 = 3, .crn = 0, .crm = 1, .opc2 = 0,
25
+ .access = PL0_R, .accessfn = access_tda,
26
+ .type = ARM_CP_CONST, .resetvalue = 0 },
27
+ /*
28
+ * DBGDSCRint[15,12,5:2] map to MDSCR_EL1[15,12,5:2]. Map all bits as
29
+ * it is unlikely a guest will care.
30
* We don't implement the configurable EL0 access.
31
*/
32
- { .name = "MDCCSR_EL0", .state = ARM_CP_STATE_BOTH,
33
- .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0,
34
+ { .name = "DBGDSCRint", .state = ARM_CP_STATE_AA32,
35
+ .cp = 14, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0,
36
.type = ARM_CP_ALIAS,
37
.access = PL1_R, .accessfn = access_tda,
38
.fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), },
39
--
40
2.20.1
41
42
diff view generated by jsdifflib
1
From: Kaige Li <likaige@loongson.cn>
1
From: Rebecca Cran <rebecca@nuviainc.com>
2
2
3
GCC version 4.9.4 isn't clever enough to figure out that all
3
Add a space in the message printed when gicr_read*/gicr_write* returns
4
execution paths in disas_ldst() that use 'fn' will have initialized
4
MEMTX_ERROR in arm_gicv3_redist.c.
5
it first, and so it warns:
6
5
7
/home/LiKaige/qemu/target/arm/translate-a64.c: In function ‘disas_ldst’:
6
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
8
/home/LiKaige/qemu/target/arm/translate-a64.c:3392:5: error: ‘fn’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
fn(cpu_reg(s, rt), clean_addr, tcg_rs, get_mem_index(s),
8
Message-id: 20210706211432.31902-1-rebecca@nuviainc.com
10
^
11
/home/LiKaige/qemu/target/arm/translate-a64.c:3318:22: note: ‘fn’ was declared here
12
AtomicThreeOpFn *fn;
13
^
14
15
Make it happy by initializing the variable to NULL.
16
17
Signed-off-by: Kaige Li <likaige@loongson.cn>
18
Message-id: 1596110248-7366-2-git-send-email-likaige@loongson.cn
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
[PMM: Clean up commit message and note which gcc version this was]
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
10
---
23
target/arm/translate-a64.c | 2 +-
11
hw/intc/arm_gicv3_redist.c | 4 ++--
24
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 2 insertions(+), 2 deletions(-)
25
13
26
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
27
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/translate-a64.c
16
--- a/hw/intc/arm_gicv3_redist.c
29
+++ b/target/arm/translate-a64.c
17
+++ b/hw/intc/arm_gicv3_redist.c
30
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
18
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data,
31
bool r = extract32(insn, 22, 1);
19
if (r == MEMTX_ERROR) {
32
bool a = extract32(insn, 23, 1);
20
qemu_log_mask(LOG_GUEST_ERROR,
33
TCGv_i64 tcg_rs, clean_addr;
21
"%s: invalid guest read at offset " TARGET_FMT_plx
34
- AtomicThreeOpFn *fn;
22
- "size %u\n", __func__, offset, size);
35
+ AtomicThreeOpFn *fn = NULL;
23
+ " size %u\n", __func__, offset, size);
36
24
trace_gicv3_redist_badread(gicv3_redist_affid(cs), offset,
37
if (is_vector || !dc_isar_feature(aa64_atomics, s)) {
25
size, attrs.secure);
38
unallocated_encoding(s);
26
/* The spec requires that reserved registers are RAZ/WI;
27
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
28
if (r == MEMTX_ERROR) {
29
qemu_log_mask(LOG_GUEST_ERROR,
30
"%s: invalid guest write at offset " TARGET_FMT_plx
31
- "size %u\n", __func__, offset, size);
32
+ " size %u\n", __func__, offset, size);
33
trace_gicv3_redist_badwrite(gicv3_redist_affid(cs), offset, data,
34
size, attrs.secure);
35
/* The spec requires that reserved registers are RAZ/WI;
39
--
36
--
40
2.20.1
37
2.20.1
41
38
42
39
diff view generated by jsdifflib