1
Arm queue; bugfixes only.
1
Arm changes for before softfreeze: mostly my PL061/GPIO patches,
2
but also a new M-profile board and various other things.
2
3
3
thanks
4
thanks
4
-- PMM
5
-- PMM
5
6
6
The following changes since commit 48aa8f0ac536db3550a35c295ff7de94e4c33739:
7
The following changes since commit 05de778b5b8ab0b402996769117b88c7ea5c7c61:
7
8
8
Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2020-11-16' into staging (2020-11-17 11:07:00 +0000)
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-20201117
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 ab135622cf478585bdfcb68b85e4a817d74a0c42:
15
for you to fetch changes up to 05449abb1d4c5f0c69ceb3d8d03cbc75de39b646:
15
16
16
tmp105: Correct handling of temperature limit checks (2020-11-17 12:56:33 +0000)
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/arm/virt: ARM_VIRT must select ARM_GIC
21
* New machine type: stm32vldiscovery
21
* exynos: Fix bad printf format specifiers
22
* hw/intc/arm_gicv3_cpuif: Fix virtual irq number check in icv_[dir|eoir]_write
22
* hw/input/ps2.c: Remove remnants of printf debug
23
* hw/gpio/pl061: Honour Luminary PL061 PUR and PDR registers
23
* target/openrisc: Remove dead code attempting to check "is timer disabled"
24
* virt: Fix implementation of GPIO-based powerdown/shutdown mechanism
24
* register: Remove unnecessary NULL check
25
* Correct the encoding of MDCCSR_EL0 and DBGDSCRint
25
* util/cutils: Fix Coverity array overrun in freq_to_str()
26
* hw/intc: Improve formatting of MEMTX_ERROR guest error message
26
* configure: Make "does libgio work" test pull in some actual functions
27
* tmp105: reset the T_low and T_High registers
28
* tmp105: Correct handling of temperature limit checks
29
27
30
----------------------------------------------------------------
28
----------------------------------------------------------------
31
Alex Chen (1):
29
Alexandre Iooss (4):
32
exynos: Fix bad printf format specifiers
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
33
34
34
Alistair Francis (1):
35
Peter Maydell (10):
35
register: Remove unnecessary NULL check
36
hw/gpio/pl061: Convert DPRINTF to tracepoints
37
hw/gpio/pl061: Clean up read/write offset handling logic
38
hw/gpio/pl061: Add tracepoints for register read and write
39
hw/gpio/pl061: Document the interface of this device
40
hw/gpio/pl061: Honour Luminary PL061 PUR and PDR registers
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
36
46
37
Andrew Jones (1):
47
Rebecca Cran (1):
38
hw/arm/virt: ARM_VIRT must select ARM_GIC
48
hw/intc: Improve formatting of MEMTX_ERROR guest error message
39
49
40
Peter Maydell (5):
50
Ricardo Koller (1):
41
hw/input/ps2.c: Remove remnants of printf debug
51
hw/intc/arm_gicv3_cpuif: Fix virtual irq number check in icv_[dir|eoir]_write
42
target/openrisc: Remove dead code attempting to check "is timer disabled"
43
configure: Make "does libgio work" test pull in some actual functions
44
hw/misc/tmp105: reset the T_low and T_High registers
45
tmp105: Correct handling of temperature limit checks
46
52
47
Philippe Mathieu-Daudé (1):
53
hnick@vmware.com (1):
48
util/cutils: Fix Coverity array overrun in freq_to_str()
54
target/arm: Correct the encoding of MDCCSR_EL0 and DBGDSCRint
49
55
50
configure | 11 +++++--
56
docs/system/arm/stm32.rst | 66 +++++++
51
hw/misc/tmp105.h | 7 +++++
57
docs/system/target-arm.rst | 1 +
52
hw/core/register.c | 4 ---
58
default-configs/devices/arm-softmmu.mak | 1 +
53
hw/input/ps2.c | 9 ------
59
include/hw/arm/stm32f100_soc.h | 57 ++++++
54
hw/misc/tmp105.c | 73 ++++++++++++++++++++++++++++++++++++++------
60
hw/arm/stellaris.c | 56 +++++-
55
hw/timer/exynos4210_mct.c | 4 +--
61
hw/arm/stm32f100_soc.c | 182 +++++++++++++++++
56
hw/timer/exynos4210_pwm.c | 8 ++---
62
hw/arm/stm32vldiscovery.c | 66 +++++++
57
target/openrisc/sys_helper.c | 3 --
63
hw/arm/virt.c | 3 +
58
util/cutils.c | 3 +-
64
hw/gpio/pl061.c | 341 +++++++++++++++++++++++++-------
59
hw/arm/Kconfig | 1 +
65
hw/intc/arm_gicv3_cpuif.c | 4 +-
60
10 files changed, 89 insertions(+), 34 deletions(-)
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
61
78
diff view generated by jsdifflib
New patch
1
1
From: Alexandre Iooss <erdnaxe@crans.org>
2
3
This SoC is similar to stm32f205 SoC.
4
This will be used by the STM32VLDISCOVERY to create a machine.
5
6
Signed-off-by: Alexandre Iooss <erdnaxe@crans.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20210617165647.2575955-2-erdnaxe@crans.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/stm32f100_soc.h | 57 +++++++++++
12
hw/arm/stm32f100_soc.c | 182 +++++++++++++++++++++++++++++++++
13
MAINTAINERS | 6 ++
14
hw/arm/Kconfig | 6 ++
15
hw/arm/meson.build | 1 +
16
5 files changed, 252 insertions(+)
17
create mode 100644 include/hw/arm/stm32f100_soc.h
18
create mode 100644 hw/arm/stm32f100_soc.c
19
20
diff --git a/include/hw/arm/stm32f100_soc.h b/include/hw/arm/stm32f100_soc.h
21
new file mode 100644
22
index XXXXXXX..XXXXXXX
23
--- /dev/null
24
+++ b/include/hw/arm/stm32f100_soc.h
25
@@ -XXX,XX +XXX,XX @@
26
+/*
27
+ * STM32F100 SoC
28
+ *
29
+ * Copyright (c) 2021 Alexandre Iooss <erdnaxe@crans.org>
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)
134
+{
135
+ STM32F100State *s = STM32F100_SOC(obj);
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);
161
+
162
+ /*
163
+ * Init flash region
164
+ * Flash starts at 0x08000000 and then is aliased to boot memory at 0x0
165
+ */
166
+ memory_region_init_rom(flash, OBJECT(dev_soc), "STM32F100.flash",
167
+ FLASH_SIZE, &error_fatal);
168
+ memory_region_init_alias(flash_alias, OBJECT(dev_soc),
169
+ "STM32F100.flash.alias", flash, 0, FLASH_SIZE);
170
+ memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, flash);
171
+ memory_region_add_subregion(system_memory, 0, flash_alias);
172
+
173
+ /* Init SRAM region */
174
+ memory_region_init_ram(sram, NULL, "STM32F100.sram", SRAM_SIZE,
175
+ &error_fatal);
176
+ memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, sram);
177
+
178
+ /* Init ARMv7m */
179
+ armv7m = DEVICE(&s->armv7m);
180
+ qdev_prop_set_uint32(armv7m, "num-irq", 61);
181
+ qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type);
182
+ qdev_prop_set_bit(armv7m, "enable-bitband", true);
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);
242
+}
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
272
index XXXXXXX..XXXXXXX 100644
273
--- a/MAINTAINERS
274
+++ b/MAINTAINERS
275
@@ -XXX,XX +XXX,XX @@ L: qemu-arm@nongnu.org
276
S: Maintained
277
F: hw/arm/virt-acpi-build.c
278
279
+STM32F100
280
+M: Alexandre Iooss <erdnaxe@crans.org>
281
+L: qemu-arm@nongnu.org
282
+S: Maintained
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'))
317
--
318
2.20.1
319
320
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
From: Alexandre Iooss <erdnaxe@crans.org>
2
2
3
The removal of the selection of A15MPCORE from ARM_VIRT also
3
This is a Cortex-M3 based machine. Information can be found at:
4
removed what A15MPCORE selects, ARM_GIC. We still need ARM_GIC.
4
https://www.st.com/en/evaluation-tools/stm32vldiscovery.html
5
5
6
Fixes: bec3c97e0cf9 ("hw/arm/virt: Remove dependency on Cortex-A15 MPCore peripherals")
6
Signed-off-by: Alexandre Iooss <erdnaxe@crans.org>
7
Reported-by: Miroslav Rezanina <mrezanin@redhat.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Andrew Jones <drjones@redhat.com>
8
Message-id: 20210617165647.2575955-3-erdnaxe@crans.org
9
Reviewed-by: Miroslav Rezanina <mrezanin@redhat.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Message-id: 20201111143440.112763-1-drjones@redhat.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
10
---
14
hw/arm/Kconfig | 1 +
11
default-configs/devices/arm-softmmu.mak | 1 +
15
1 file changed, 1 insertion(+)
12
hw/arm/stm32vldiscovery.c | 66 +++++++++++++++++++++++++
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
16
18
19
diff --git a/default-configs/devices/arm-softmmu.mak b/default-configs/devices/arm-softmmu.mak
20
index XXXXXXX..XXXXXXX 100644
21
--- a/default-configs/devices/arm-softmmu.mak
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
36
@@ -XXX,XX +XXX,XX @@
37
+/*
38
+ * ST STM32VLDISCOVERY machine
39
+ *
40
+ * Copyright (c) 2021 Alexandre Iooss <erdnaxe@crans.org>
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
+ */
61
+
62
+#include "qemu/osdep.h"
63
+#include "qapi/error.h"
64
+#include "hw/boards.h"
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
+
79
+ /*
80
+ * TODO: ideally we would model the SoC RCC and let it handle
81
+ * system_clock_scale, including its ability to define different
82
+ * possible SYSCLK sources.
83
+ */
84
+ system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
85
+
86
+ dev = qdev_new(TYPE_STM32F100_SOC);
87
+ qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m3"));
88
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
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
104
index XXXXXXX..XXXXXXX 100644
105
--- a/MAINTAINERS
106
+++ b/MAINTAINERS
107
@@ -XXX,XX +XXX,XX @@ F: hw/*/stellaris*
108
F: include/hw/input/gamepad.h
109
F: docs/system/arm/stellaris.rst
110
111
+STM32VLDISCOVERY
112
+M: Alexandre Iooss <erdnaxe@crans.org>
113
+L: qemu-arm@nongnu.org
114
+S: Maintained
115
+F: hw/arm/stm32vldiscovery.c
116
+
117
Versatile Express
118
M: Peter Maydell <peter.maydell@linaro.org>
119
L: qemu-arm@nongnu.org
17
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
120
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
18
index XXXXXXX..XXXXXXX 100644
121
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/Kconfig
122
--- a/hw/arm/Kconfig
20
+++ b/hw/arm/Kconfig
123
+++ b/hw/arm/Kconfig
21
@@ -XXX,XX +XXX,XX @@ config ARM_VIRT
124
@@ -XXX,XX +XXX,XX @@ config STELLARIS
22
imply VFIO_PLATFORM
125
select STELLARIS_ENET # ethernet
23
imply VFIO_XGMAC
126
select UNIMP
24
imply TPM_TIS_SYSBUS
127
25
+ select ARM_GIC
128
+config STM32VLDISCOVERY
26
select ACPI
129
+ bool
27
select ARM_SMMUV3
130
+ select STM32F100_SOC
28
select GPIO_KEY
131
+
132
config STRONGARM
133
bool
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'))
29
--
147
--
30
2.20.1
148
2.20.1
31
149
32
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
New patch
1
Add tracepoints for reads and writes to the PL061 registers. This requires
2
restructuring pl061_read() to only return after the tracepoint, rather
3
than having lots of early-returns.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
---
9
hw/gpio/pl061.c | 70 ++++++++++++++++++++++++++++++--------------
10
hw/gpio/trace-events | 2 ++
11
2 files changed, 50 insertions(+), 22 deletions(-)
12
13
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/gpio/pl061.c
16
+++ b/hw/gpio/pl061.c
17
@@ -XXX,XX +XXX,XX @@ static uint64_t pl061_read(void *opaque, hwaddr offset,
18
unsigned size)
19
{
20
PL061State *s = (PL061State *)opaque;
21
+ uint64_t r = 0;
22
23
switch (offset) {
24
case 0x0 ... 0x3ff: /* Data */
25
- return s->data & (offset >> 2);
26
+ r = s->data & (offset >> 2);
27
+ break;
28
case 0x400: /* Direction */
29
- return s->dir;
30
+ r = s->dir;
31
+ break;
32
case 0x404: /* Interrupt sense */
33
- return s->isense;
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;
148
+
149
+ trace_pl061_read(DEVICE(s)->canonical_path, offset, r);
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);
159
+
160
switch (offset) {
161
case 0 ... 0x3ff:
162
mask = (offset >> 2) & s->dir;
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
176
--
177
2.20.1
178
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
1
In commit 76346b6264a9b01979 we tried to add a configure check that
1
The Luminary variant of the PL061 has registers GPIOPUR and GPIOPDR
2
the libgio pkg-config data was correct, which builds an executable
2
which lets the guest configure whether the GPIO lines are pull-up,
3
linked against it. Unfortunately this doesn't catch the problem
3
pull-down, or truly floating. Instead of assuming all lines are pulled
4
(missing static library dependency info), because a "do nothing" test
4
high, honour the PUR and PDR registers.
5
source file doesn't have any symbol references that cause the linker
6
to pull in .o files from libgio.a, and so we don't see the "missing
7
symbols from libmount" error that a full QEMU link triggers.
8
5
9
(The ineffective test went unnoticed because of a typo that
6
For the plain PL061, continue to assume that lines have an external
10
effectively disabled libgio unconditionally, but after commit
7
pull-up resistor, as we did before.
11
3569a5dfc11f2 fixed that, a static link of the system emulator on
12
Ubuntu stopped working again.)
13
8
14
Improve the gio test by having the test source fragment reference a
9
The stellaris board actually relies on this behaviour -- the CD line
15
g_dbus function (which is what is indirectly causing us to end up
10
of the ssd0323 display device is connected to GPIO output C7, and it
16
wanting functions from libmount).
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.
17
14
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-id: 20201116104617.18333-1-peter.maydell@linaro.org
21
---
17
---
22
configure | 11 +++++++++--
18
hw/gpio/pl061.c | 58 +++++++++++++++++++++++++++++++++++++++++---
23
1 file changed, 9 insertions(+), 2 deletions(-)
19
hw/gpio/trace-events | 2 +-
20
2 files changed, 55 insertions(+), 5 deletions(-)
24
21
25
diff --git a/configure b/configure
22
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
26
index XXXXXXX..XXXXXXX 100755
23
index XXXXXXX..XXXXXXX 100644
27
--- a/configure
24
--- a/hw/gpio/pl061.c
28
+++ b/configure
25
+++ b/hw/gpio/pl061.c
29
@@ -XXX,XX +XXX,XX @@ if $pkg_config --atleast-version=$glib_req_ver gio-2.0; then
26
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pl061 = {
30
# Check that the libraries actually work -- Ubuntu 18.04 ships
27
}
31
# with pkg-config --static --libs data for gio-2.0 that is missing
28
};
32
# -lblkid and will give a link error.
29
33
- write_c_skeleton
30
+static uint8_t pl061_floating(PL061State *s)
34
- if compile_prog "" "$gio_libs" ; then
35
+ cat > $TMPC <<EOF
36
+#include <gio/gio.h>
37
+int main(void)
38
+{
31
+{
39
+ g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0);
32
+ /*
40
+ return 0;
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;
41
+}
49
+}
42
+EOF
50
+
43
+ if compile_prog "$gio_cflags" "$gio_libs" ; then
51
+static uint8_t pl061_pullups(PL061State *s)
44
gio=yes
52
+{
45
else
53
+ /*
46
gio=no
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"
47
--
112
--
48
2.20.1
113
2.20.1
49
114
50
115
diff view generated by jsdifflib
1
The TMP105 datasheet says that in Interrupt Mode (when TM==1) the device
1
The PL061 GPIO does not itself include pullup or pulldown resistors
2
signals an alert when the temperature equals or exceeds the T_high value and
2
to set the value of a GPIO line treated as an output when it is
3
then remains high until a device register is read or the device responds to
3
configured as an input (ie when the PL061 itself is not driving it).
4
the SMBUS Alert Response address, or the device is put into Shutdown Mode.
4
In real hardware it is up to the board to add suitable pullups or
5
Thereafter the Alert pin will only be re-signalled when temperature falls
5
pulldowns. Currently our implementation hardwires this to "outputs
6
below T_low; alert can then be cleared in the same set of ways, and the
6
pulled high", which is correct for some boards (eg the realview ones:
7
device returns to its initial "alert when temperature goes above T_high"
7
see figure 3-29 in the "RealView Platform Baseboard for ARM926EJ-S
8
mode. (If this textual description is confusing, see figure 3 in the
8
User Guide" DUI0224I), but wrong for others.
9
TI datasheet at https://www.ti.com/lit/gpn/tmp105 .)
10
9
11
We were misimplementing this as a simple "always alert if temperature is
10
In particular, the wiring in the 'virt' board and the gpio-pwr device
12
above T_high or below T_low" condition, which gives a spurious alert on
11
assumes that wires should be pulled low, because otherwise the
13
startup if using the "T_high = 80 degrees C, T_low = 75 degrees C" reset
12
pull-to-high will trigger a shutdown or reset action. (The only
14
limit values.
13
reason this doesn't happen immediately on startup is due to another
14
bug in the PL061, where we don't assert the GPIOs to the correct
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
Implement the correct (hysteresis) behaviour by tracking whether we
18
Add properties to the pl061 so the board can configure whether it
17
are currently looking for the temperature to rise over T_high or
19
wants GPIO lines to have pullup, pulldown, or neither.
18
for it to fall below T_low. Our implementation of the comparator
19
mode (TM==0) wasn't wrong, but rephrase it to match the way that
20
interrupt mode is now handled for clarity.
21
20
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Cédric Le Goater <clg@kaod.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Message-id: 20201110150023.25533-3-peter.maydell@linaro.org
25
---
23
---
26
hw/misc/tmp105.h | 7 +++++
24
hw/gpio/pl061.c | 51 +++++++++++++++++++++++++++++++++++++++++++++----
27
hw/misc/tmp105.c | 70 +++++++++++++++++++++++++++++++++++++++++-------
25
1 file changed, 47 insertions(+), 4 deletions(-)
28
2 files changed, 68 insertions(+), 9 deletions(-)
29
26
30
diff --git a/hw/misc/tmp105.h b/hw/misc/tmp105.h
27
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
31
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/misc/tmp105.h
29
--- a/hw/gpio/pl061.c
33
+++ b/hw/misc/tmp105.h
30
+++ b/hw/gpio/pl061.c
34
@@ -XXX,XX +XXX,XX @@ struct TMP105State {
31
@@ -XXX,XX +XXX,XX @@
35
int16_t limit[2];
32
* + unnamed GPIO inputs 0..7: inputs to connect to the emulated GPIO lines
36
int faults;
33
* + unnamed GPIO outputs 0..7: the emulated GPIO lines, considered as
37
uint8_t alarm;
34
* outputs
38
+ /*
35
+ * + QOM property "pullups": an integer defining whether non-floating lines
39
+ * The TMP105 initially looks for a temperature rising above T_high;
36
+ * configured as inputs should be pulled up to logical 1 (ie whether in
40
+ * once this is detected, the condition it looks for next is the
37
+ * real hardware they have a pullup resistor on the line out of the PL061).
41
+ * temperature falling below T_low. This flag is false when initially
38
+ * This should be an 8-bit value, where bit 0 is 1 if GPIO line 0 should
42
+ * looking for T_high, true when looking for T_low.
39
+ * be pulled high, bit 1 configures line 1, and so on. The default is 0xff,
43
+ */
40
+ * indicating that all GPIO lines are pulled up to logical 1.
44
+ bool detect_falling;
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"
52
#include "hw/irq.h"
53
#include "hw/sysbus.h"
54
+#include "hw/qdev-properties.h"
55
#include "migration/vmstate.h"
56
+#include "qapi/error.h"
57
#include "qemu/log.h"
58
#include "qemu/module.h"
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;
45
};
67
};
46
68
47
#endif
69
static const VMStateDescription vmstate_pl061 = {
48
diff --git a/hw/misc/tmp105.c b/hw/misc/tmp105.c
70
@@ -XXX,XX +XXX,XX @@ static uint8_t pl061_floating(PL061State *s)
49
index XXXXXXX..XXXXXXX 100644
71
*/
50
--- a/hw/misc/tmp105.c
72
floating = ~(s->pur | s->pdr);
51
+++ b/hw/misc/tmp105.c
73
} else {
52
@@ -XXX,XX +XXX,XX @@ static void tmp105_alarm_update(TMP105State *s)
74
- /* Assume outputs are pulled high. FIXME: this is board dependent. */
53
return;
75
- floating = 0;
76
+ floating = ~(s->pullups | s->pulldowns);
54
}
77
}
55
78
return floating & ~s->dir;
56
- if ((s->config >> 1) & 1) {                    /* TM */
79
}
57
- if (s->temperature >= s->limit[1])
80
@@ -XXX,XX +XXX,XX @@ static uint8_t pl061_pullups(PL061State *s)
58
- s->alarm = 1;
81
*/
59
- else if (s->temperature < s->limit[0])
82
pullups = s->pur;
60
- s->alarm = 1;
61
+ if (s->config >> 1 & 1) {
62
+ /*
63
+ * TM == 1 : Interrupt mode. We signal Alert when the
64
+ * temperature rises above T_high, and expect the guest to clear
65
+ * it (eg by reading a device register).
66
+ */
67
+ if (s->detect_falling) {
68
+ if (s->temperature < s->limit[0]) {
69
+ s->alarm = 1;
70
+ s->detect_falling = false;
71
+ }
72
+ } else {
73
+ if (s->temperature >= s->limit[1]) {
74
+ s->alarm = 1;
75
+ s->detect_falling = true;
76
+ }
77
+ }
78
} else {
83
} else {
79
- if (s->temperature >= s->limit[1])
84
- /* Assume outputs are pulled high. FIXME: this is board dependent. */
80
- s->alarm = 1;
85
- pullups = 0xff;
81
- else if (s->temperature < s->limit[0])
86
+ pullups = s->pullups;
82
- s->alarm = 0;
83
+ /*
84
+ * TM == 0 : Comparator mode. We signal Alert when the temperature
85
+ * rises above T_high, and stop signalling it when the temperature
86
+ * falls below T_low.
87
+ */
88
+ if (s->detect_falling) {
89
+ if (s->temperature < s->limit[0]) {
90
+ s->alarm = 0;
91
+ s->detect_falling = false;
92
+ }
93
+ } else {
94
+ if (s->temperature >= s->limit[1]) {
95
+ s->alarm = 1;
96
+ s->detect_falling = true;
97
+ }
98
+ }
99
}
87
}
100
88
return pullups & ~s->dir;
101
tmp105_interrupt_update(s);
102
@@ -XXX,XX +XXX,XX @@ static int tmp105_post_load(void *opaque, int version_id)
103
return 0;
104
}
89
}
105
90
@@ -XXX,XX +XXX,XX @@ static void pl061_init(Object *obj)
106
+static bool detect_falling_needed(void *opaque)
91
qdev_init_gpio_out(dev, s->out, N_GPIOS);
92
}
93
94
+static void pl061_realize(DeviceState *dev, Error **errp)
107
+{
95
+{
108
+ TMP105State *s = opaque;
96
+ PL061State *s = PL061(dev);
109
+
97
+
110
+ /*
98
+ if (s->pullups > 0xff) {
111
+ * We only need to migrate the detect_falling bool if it's set;
99
+ error_setg(errp, "pullups property must be between 0 and 0xff");
112
+ * for migration from older machines we assume that it is false
100
+ return;
113
+ * (ie temperature is not out of range).
101
+ }
114
+ */
102
+ if (s->pulldowns > 0xff) {
115
+ return s->detect_falling;
103
+ error_setg(errp, "pulldowns property must be between 0 and 0xff");
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;
109
+ }
116
+}
110
+}
117
+
111
+
118
+static const VMStateDescription vmstate_tmp105_detect_falling = {
112
+static Property pl061_props[] = {
119
+ .name = "TMP105/detect-falling",
113
+ DEFINE_PROP_UINT32("pullups", PL061State, pullups, 0xff),
120
+ .version_id = 1,
114
+ DEFINE_PROP_UINT32("pulldowns", PL061State, pulldowns, 0x0),
121
+ .minimum_version_id = 1,
115
+ DEFINE_PROP_END_OF_LIST()
122
+ .needed = detect_falling_needed,
123
+ .fields = (VMStateField[]) {
124
+ VMSTATE_BOOL(detect_falling, TMP105State),
125
+ VMSTATE_END_OF_LIST()
126
+ }
127
+};
116
+};
128
+
117
+
129
static const VMStateDescription vmstate_tmp105 = {
118
static void pl061_class_init(ObjectClass *klass, void *data)
130
.name = "TMP105",
119
{
131
.version_id = 0,
120
DeviceClass *dc = DEVICE_CLASS(klass);
132
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_tmp105 = {
121
133
VMSTATE_UINT8(alarm, TMP105State),
122
dc->vmsd = &vmstate_pl061;
134
VMSTATE_I2C_SLAVE(i2c, TMP105State),
123
dc->reset = &pl061_reset;
135
VMSTATE_END_OF_LIST()
124
+ dc->realize = pl061_realize;
136
+ },
125
+ device_class_set_props(dc, pl061_props);
137
+ .subsections = (const VMStateDescription*[]) {
126
}
138
+ &vmstate_tmp105_detect_falling,
127
139
+ NULL
128
static const TypeInfo pl061_info = {
140
}
141
};
142
143
@@ -XXX,XX +XXX,XX @@ static void tmp105_reset(I2CSlave *i2c)
144
s->config = 0;
145
s->faults = tmp105_faultq[(s->config >> 3) & 3];
146
s->alarm = 0;
147
+ s->detect_falling = false;
148
149
s->limit[0] = 0x4b00; /* T_LOW, 75 degrees C */
150
s->limit[1] = 0x5000; /* T_HIGH, 80 degrees C */
151
--
129
--
152
2.20.1
130
2.20.1
153
131
154
132
diff view generated by jsdifflib
1
In the mtspr helper we attempt to check for "is the timer disabled"
1
For the virt board we have two PL061 devices -- one for NonSecure which
2
with "if (env->ttmr & TIMER_NONE)". This is wrong because TIMER_NONE
2
is inputs only, and one for Secure which is outputs only. For the former,
3
is zero and the condition is always false (Coverity complains about
3
we don't care whether its outputs are pulled low or high when the line is
4
the dead code.)
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.
5
9
6
The correct check would be to test whether the TTMR_M field in the
10
Reported-by: Maxim Uvarov <maxim.uvarov@linaro.org>
7
register is equal to TIMER_NONE instead. However, the
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
cpu_openrisc_timer_update() function checks whether the timer is
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
enabled (it looks at cpu->env.is_counting, which is set to 0 via
13
---
10
cpu_openrisc_count_stop() when the TTMR_M field is set to
14
hw/arm/virt.c | 3 +++
11
TIMER_NONE), so there's no need to check for "timer disabled" in the
15
1 file changed, 3 insertions(+)
12
target/openrisc code. Instead, simply remove the dead code.
13
16
14
Fixes: Coverity CID 1005812
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Acked-by: Stafford Horne <shorne@gmail.com>
17
Message-id: 20201103114654.18540-1-peter.maydell@linaro.org
18
---
19
target/openrisc/sys_helper.c | 3 ---
20
1 file changed, 3 deletions(-)
21
22
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
23
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
24
--- a/target/openrisc/sys_helper.c
19
--- a/hw/arm/virt.c
25
+++ b/target/openrisc/sys_helper.c
20
+++ b/hw/arm/virt.c
26
@@ -XXX,XX +XXX,XX @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
21
@@ -XXX,XX +XXX,XX @@ static void create_gpio_devices(const VirtMachineState *vms, int gpio,
27
22
MachineState *ms = MACHINE(vms);
28
case TO_SPR(10, 1): /* TTCR */
23
29
cpu_openrisc_count_set(cpu, rb);
24
pl061_dev = qdev_new("pl061");
30
- if (env->ttmr & TIMER_NONE) {
25
+ /* Pull lines down to 0 if not driven by the PL061 */
31
- return;
26
+ qdev_prop_set_uint32(pl061_dev, "pullups", 0);
32
- }
27
+ qdev_prop_set_uint32(pl061_dev, "pulldowns", 0xff);
33
cpu_openrisc_timer_update(cpu);
28
s = SYS_BUS_DEVICE(pl061_dev);
34
break;
29
sysbus_realize_and_unref(s, &error_fatal);
35
#endif
30
memory_region_add_subregion(mem, base, sysbus_mmio_get_region(s, 0));
36
--
31
--
37
2.20.1
32
2.20.1
38
33
39
34
diff view generated by jsdifflib
1
The TMP105 datasheet (https://www.ti.com/lit/gpn/tmp105) says that the
1
The PL061 comes out of reset with all its lines configured as input,
2
power-up reset values for the T_low and T_high registers are 80 degrees C
2
which means they might need to be pulled to 0 or 1 depending on the
3
and 75 degrees C, which are 0x500 and 0x4B0 hex according to table 5. These
3
'pullups' and 'pulldowns' properties. Currently we do not assert
4
values are then shifted right by four bits to give the register reset
4
these lines on reset; they will only be set whenever the guest first
5
values, since both registers store the 12 bits of temperature data in bits
5
touches a register that triggers a call to pl061_update().
6
[15..4] of a 16 bit register.
7
6
8
We were resetting these registers to zero, which is problematic for Linux
7
Convert the device to three-phase reset so we have a place where we
9
guests which enable the alert interrupt and then immediately take an
8
can safely call qemu_set_irq() to set the floating lines to their
10
unexpected overtemperature alert because the current temperature is above
9
correct values.
11
freezing...
12
10
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Cédric Le Goater <clg@kaod.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Message-id: 20201110150023.25533-2-peter.maydell@linaro.org
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
---
14
---
17
hw/misc/tmp105.c | 3 +++
15
hw/gpio/pl061.c | 29 +++++++++++++++++++++++++----
18
1 file changed, 3 insertions(+)
16
hw/gpio/trace-events | 1 +
17
2 files changed, 26 insertions(+), 4 deletions(-)
19
18
20
diff --git a/hw/misc/tmp105.c b/hw/misc/tmp105.c
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/hw/misc/tmp105.c
21
--- a/hw/gpio/pl061.c
23
+++ b/hw/misc/tmp105.c
22
+++ b/hw/gpio/pl061.c
24
@@ -XXX,XX +XXX,XX @@ static void tmp105_reset(I2CSlave *i2c)
23
@@ -XXX,XX +XXX,XX @@ static void pl061_write(void *opaque, hwaddr offset,
25
s->faults = tmp105_faultq[(s->config >> 3) & 3];
24
return;
26
s->alarm = 0;
25
}
27
26
28
+ s->limit[0] = 0x4b00; /* T_LOW, 75 degrees C */
27
-static void pl061_reset(DeviceState *dev)
29
+ s->limit[1] = 0x5000; /* T_HIGH, 80 degrees C */
28
+static void pl061_enter_reset(Object *obj, ResetType type)
29
{
30
- PL061State *s = PL061(dev);
31
+ PL061State *s = PL061(obj);
30
+
32
+
31
tmp105_interrupt_update(s);
33
+ trace_pl061_reset(DEVICE(s)->canonical_path);
34
35
/* reset values from PL061 TRM, Stellaris LM3S5P31 & LM3S8962 Data Sheet */
36
s->data = 0;
37
- s->old_out_data = 0;
38
s->old_in_data = 0;
39
s->dir = 0;
40
s->isense = 0;
41
@@ -XXX,XX +XXX,XX @@ static void pl061_reset(DeviceState *dev)
42
s->amsel = 0;
32
}
43
}
33
44
45
+static void pl061_hold_reset(Object *obj)
46
+{
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;
61
+}
62
+
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
34
--
93
--
35
2.20.1
94
2.20.1
36
95
37
96
diff view generated by jsdifflib
1
In commit 5edab03d4040 we added tracepoints to the ps2 keyboard
1
The Luminary PL061s in the Stellaris LM3S9695 don't all have the same
2
and mouse emulation. However we didn't remove all the debug-by-printf
2
reset value for GPIOPUR. We can get away with not letting the board
3
support. In fact there is only one printf() remaining, and it is
3
configure the PUR reset value because we don't actually wire anything
4
redundant with the trace_ps2_write_mouse() event next to it.
4
up to the lines which should reset to pull-up. Add a comment noting
5
Remove the printf() and the now-unused DEBUG* macros.
5
this omission.
6
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
10
Message-id: 20201101133258.4240-1-peter.maydell@linaro.org
11
---
9
---
12
hw/input/ps2.c | 9 ---------
10
hw/gpio/pl061.c | 9 +++++++++
13
1 file changed, 9 deletions(-)
11
1 file changed, 9 insertions(+)
14
12
15
diff --git a/hw/input/ps2.c b/hw/input/ps2.c
13
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/input/ps2.c
15
--- a/hw/gpio/pl061.c
18
+++ b/hw/input/ps2.c
16
+++ b/hw/gpio/pl061.c
19
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static void pl061_enter_reset(Object *obj, ResetType type)
20
18
trace_pl061_reset(DEVICE(s)->canonical_path);
21
#include "trace.h"
19
22
20
/* reset values from PL061 TRM, Stellaris LM3S5P31 & LM3S8962 Data Sheet */
23
-/* debug PC keyboard */
21
+
24
-//#define DEBUG_KBD
22
+ /*
25
-
23
+ * FIXME: For the LM3S6965, not all of the PL061 instances have the
26
-/* debug PC keyboard : only mouse */
24
+ * same reset values for GPIOPUR, GPIOAFSEL and GPIODEN, so in theory
27
-//#define DEBUG_MOUSE
25
+ * we should allow the board to configure these via properties.
28
-
26
+ * In practice, we don't wire anything up to the affected GPIO lines
29
/* Keyboard Commands */
27
+ * (PB7, PC0, PC1, PC2, PC3 -- they're used for JTAG), so we can
30
#define KBD_CMD_SET_LEDS    0xED    /* Set keyboard leds */
28
+ * get away with this inaccuracy.
31
#define KBD_CMD_ECHO     0xEE
29
+ */
32
@@ -XXX,XX +XXX,XX @@ void ps2_write_mouse(void *opaque, int val)
30
s->data = 0;
33
PS2MouseState *s = (PS2MouseState *)opaque;
31
s->old_in_data = 0;
34
32
s->dir = 0;
35
trace_ps2_write_mouse(opaque, val);
36
-#ifdef DEBUG_MOUSE
37
- printf("kbd: write mouse 0x%02x\n", val);
38
-#endif
39
switch(s->common.write_cmd) {
40
default:
41
case -1:
42
--
33
--
43
2.20.1
34
2.20.1
44
35
45
36
diff view generated by jsdifflib
1
From: Alistair Francis <alistair.francis@wdc.com>
1
The stellaris board doesn't emulate the handling of the OLED
2
chipselect line correctly. Expand the comment describing this,
3
including a sketch of the theoretical correct way to do it.
2
4
3
This patch fixes CID 1432800 by removing an unnecessary check.
4
5
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
6
---
9
hw/core/register.c | 4 ----
7
hw/arm/stellaris.c | 56 +++++++++++++++++++++++++++++++++++++++++++++-
10
1 file changed, 4 deletions(-)
8
1 file changed, 55 insertions(+), 1 deletion(-)
11
9
12
diff --git a/hw/core/register.c b/hw/core/register.c
10
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
13
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/core/register.c
12
--- a/hw/arm/stellaris.c
15
+++ b/hw/core/register.c
13
+++ b/hw/arm/stellaris.c
16
@@ -XXX,XX +XXX,XX @@ static RegisterInfoArray *register_init_block(DeviceState *owner,
14
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
17
int index = rae[i].addr / data_size;
15
DeviceState *sddev;
18
RegisterInfo *r = &ri[index];
16
DeviceState *ssddev;
19
17
20
- if (data + data_size * index == 0 || !&rae[i]) {
18
- /* Some boards have both an OLED controller and SD card connected to
21
- continue;
19
+ /*
22
- }
20
+ * Some boards have both an OLED controller and SD card connected to
23
-
21
* the same SSI port, with the SD card chip select connected to a
24
/* Init the register, this will zero it. */
22
* GPIO pin. Technically the OLED chip select is connected to the
25
object_initialize((void *)r, sizeof(*r), TYPE_REGISTER);
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");
26
82
27
--
83
--
28
2.20.1
84
2.20.1
29
85
30
86
diff view generated by jsdifflib
1
From: Alex Chen <alex.chen@huawei.com>
1
From: "hnick@vmware.com" <hnick@vmware.com>
2
2
3
We should use printf format specifier "%u" instead of "%d" for
3
Signed-off-by: Nick Hudson <hnick@vmware.com>
4
argument of type "unsigned int".
5
6
Reported-by: Euler Robot <euler.robot@huawei.com>
7
Signed-off-by: Alex Chen <alex.chen@huawei.com>
8
Message-id: 20201111073651.72804-1-alex.chen@huawei.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
6
---
12
hw/timer/exynos4210_mct.c | 4 ++--
7
target/arm/helper.c | 16 +++++++++++++---
13
hw/timer/exynos4210_pwm.c | 8 ++++----
8
1 file changed, 13 insertions(+), 3 deletions(-)
14
2 files changed, 6 insertions(+), 6 deletions(-)
15
9
16
diff --git a/hw/timer/exynos4210_mct.c b/hw/timer/exynos4210_mct.c
10
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/timer/exynos4210_mct.c
12
--- a/target/arm/helper.c
19
+++ b/hw/timer/exynos4210_mct.c
13
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gcomp_raise_irq(void *opaque, uint32_t id)
14
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
21
/* If CSTAT is pending and IRQ is enabled */
15
.access = PL1_RW, .accessfn = access_tda,
22
if ((s->reg.int_cstat & G_INT_CSTAT_COMP(id)) &&
16
.fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1),
23
(s->reg.int_enb & G_INT_ENABLE(id))) {
17
.resetvalue = 0 },
24
- DPRINTF("gcmp timer[%d] IRQ\n", id);
18
- /* MDCCSR_EL0, aka DBGDSCRint. This is a read-only mirror of MDSCR_EL1.
25
+ DPRINTF("gcmp timer[%u] IRQ\n", id);
19
+ /*
26
qemu_irq_raise(s->irq[id]);
20
+ * MDCCSR_EL0[30:29] map to EDSCR[30:29]. Simply RAZ as the external
27
}
21
+ * Debug Communication Channel is not implemented.
28
}
22
+ */
29
@@ -XXX,XX +XXX,XX @@ static void exynos4210_mct_update_freq(Exynos4210MCTState *s)
23
+ { .name = "MDCCSR_EL0", .state = ARM_CP_STATE_AA64,
30
MCT_CFG_GET_DIVIDER(s->reg_mct_cfg));
24
+ .opc0 = 2, .opc1 = 3, .crn = 0, .crm = 1, .opc2 = 0,
31
25
+ .access = PL0_R, .accessfn = access_tda,
32
if (freq != s->freq) {
26
+ .type = ARM_CP_CONST, .resetvalue = 0 },
33
- DPRINTF("freq=%dHz\n", s->freq);
27
+ /*
34
+ DPRINTF("freq=%uHz\n", s->freq);
28
+ * DBGDSCRint[15,12,5:2] map to MDSCR_EL1[15,12,5:2]. Map all bits as
35
29
+ * it is unlikely a guest will care.
36
/* global timer */
30
* We don't implement the configurable EL0 access.
37
tx_ptimer_set_freq(s->g_timer.ptimer_frc, s->freq);
31
*/
38
diff --git a/hw/timer/exynos4210_pwm.c b/hw/timer/exynos4210_pwm.c
32
- { .name = "MDCCSR_EL0", .state = ARM_CP_STATE_BOTH,
39
index XXXXXXX..XXXXXXX 100644
33
- .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0,
40
--- a/hw/timer/exynos4210_pwm.c
34
+ { .name = "DBGDSCRint", .state = ARM_CP_STATE_AA32,
41
+++ b/hw/timer/exynos4210_pwm.c
35
+ .cp = 14, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0,
42
@@ -XXX,XX +XXX,XX @@ static void exynos4210_pwm_update_freq(Exynos4210PWMState *s, uint32_t id)
36
.type = ARM_CP_ALIAS,
43
37
.access = PL1_R, .accessfn = access_tda,
44
if (freq != s->timer[id].freq) {
38
.fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), },
45
ptimer_set_freq(s->timer[id].ptimer, s->timer[id].freq);
46
- DPRINTF("freq=%dHz\n", s->timer[id].freq);
47
+ DPRINTF("freq=%uHz\n", s->timer[id].freq);
48
}
49
}
50
51
@@ -XXX,XX +XXX,XX @@ static void exynos4210_pwm_tick(void *opaque)
52
uint32_t id = s->id;
53
bool cmp;
54
55
- DPRINTF("timer %d tick\n", id);
56
+ DPRINTF("timer %u tick\n", id);
57
58
/* set irq status */
59
p->reg_tint_cstat |= TINT_CSTAT_STATUS(id);
60
61
/* raise IRQ */
62
if (p->reg_tint_cstat & TINT_CSTAT_ENABLE(id)) {
63
- DPRINTF("timer %d IRQ\n", id);
64
+ DPRINTF("timer %u IRQ\n", id);
65
qemu_irq_raise(p->timer[id].irq);
66
}
67
68
@@ -XXX,XX +XXX,XX @@ static void exynos4210_pwm_tick(void *opaque)
69
}
70
71
if (cmp) {
72
- DPRINTF("auto reload timer %d count to %x\n", id,
73
+ DPRINTF("auto reload timer %u count to %x\n", id,
74
p->timer[id].reg_tcntb);
75
ptimer_set_count(p->timer[id].ptimer, p->timer[id].reg_tcntb);
76
ptimer_run(p->timer[id].ptimer, 1);
77
--
39
--
78
2.20.1
40
2.20.1
79
41
80
42
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Rebecca Cran <rebecca@nuviainc.com>
2
2
3
Fix Coverity CID 1435957: Memory - illegal accesses (OVERRUN):
3
Add a space in the message printed when gicr_read*/gicr_write* returns
4
MEMTX_ERROR in arm_gicv3_redist.c.
4
5
5
>>> Overrunning array "suffixes" of 7 8-byte elements at element
6
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
6
index 7 (byte offset 63) using index "idx" (which evaluates to 7).
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
8
Message-id: 20210706211432.31902-1-rebecca@nuviainc.com
8
Note, the biggest input value freq_to_str() can accept is UINT64_MAX,
9
which is ~18.446 EHz, less than 1000 EHz.
10
11
Reported-by: Eduardo Habkost <ehabkost@redhat.com>
12
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
15
Reviewed-by: Luc Michel <luc@lmichel.fr>
16
Message-id: 20201101215755.2021421-1-f4bug@amsat.org
17
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
10
---
21
util/cutils.c | 3 ++-
11
hw/intc/arm_gicv3_redist.c | 4 ++--
22
1 file changed, 2 insertions(+), 1 deletion(-)
12
1 file changed, 2 insertions(+), 2 deletions(-)
23
13
24
diff --git a/util/cutils.c b/util/cutils.c
14
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/util/cutils.c
16
--- a/hw/intc/arm_gicv3_redist.c
27
+++ b/util/cutils.c
17
+++ b/hw/intc/arm_gicv3_redist.c
28
@@ -XXX,XX +XXX,XX @@ char *freq_to_str(uint64_t freq_hz)
18
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data,
29
double freq = freq_hz;
19
if (r == MEMTX_ERROR) {
30
size_t idx = 0;
20
qemu_log_mask(LOG_GUEST_ERROR,
31
21
"%s: invalid guest read at offset " TARGET_FMT_plx
32
- while (freq >= 1000.0 && idx < ARRAY_SIZE(suffixes)) {
22
- "size %u\n", __func__, offset, size);
33
+ while (freq >= 1000.0) {
23
+ " size %u\n", __func__, offset, size);
34
freq /= 1000.0;
24
trace_gicv3_redist_badread(gicv3_redist_affid(cs), offset,
35
idx++;
25
size, attrs.secure);
36
}
26
/* The spec requires that reserved registers are RAZ/WI;
37
+ assert(idx < ARRAY_SIZE(suffixes));
27
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
38
28
if (r == MEMTX_ERROR) {
39
return g_strdup_printf("%0.3g %sHz", freq, suffixes[idx]);
29
qemu_log_mask(LOG_GUEST_ERROR,
40
}
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;
41
--
36
--
42
2.20.1
37
2.20.1
43
38
44
39
diff view generated by jsdifflib