1
Arm patch queue -- these are all bug fix patches but we might
1
Arm changes for before softfreeze: mostly my PL061/GPIO patches,
2
as well put them in to rc0...
2
but also a new M-profile board and various other things.
3
3
4
thanks
4
thanks
5
-- PMM
5
-- PMM
6
6
7
The following changes since commit 2c8cfc0b52b5a4d123c26c0b5fdf941be24805be:
7
The following changes since commit 05de778b5b8ab0b402996769117b88c7ea5c7c61:
8
8
9
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2018-03-19 11:44:26 +0000)
9
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging (2021-07-09 14:30:01 +0100)
10
10
11
are available in the Git repository at:
11
are available in the Git repository at:
12
12
13
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180319
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210709
14
14
15
for you to fetch changes up to ff72cb6b46b95bb530787add5277c211af3d31c6:
15
for you to fetch changes up to 05449abb1d4c5f0c69ceb3d8d03cbc75de39b646:
16
16
17
hw/arm/raspi: Provide spin-loop code for AArch64 CPUs (2018-03-19 18:23:24 +0000)
17
hw/intc: Improve formatting of MEMTX_ERROR guest error message (2021-07-09 16:09:12 +0100)
18
18
19
----------------------------------------------------------------
19
----------------------------------------------------------------
20
target-arm queue:
20
target-arm queue:
21
* fsl-imx6: Fix incorrect Ethernet interrupt defines
21
* New machine type: stm32vldiscovery
22
* dump: Update correct kdump phys_base field for AArch64
22
* hw/intc/arm_gicv3_cpuif: Fix virtual irq number check in icv_[dir|eoir]_write
23
* char: i.MX: Add support for "TX complete" interrupt
23
* hw/gpio/pl061: Honour Luminary PL061 PUR and PDR registers
24
* bcm2836/raspi: Fix various bugs resulting in panics trying
24
* virt: Fix implementation of GPIO-based powerdown/shutdown mechanism
25
to boot a Debian Linux kernel on raspi3
25
* Correct the encoding of MDCCSR_EL0 and DBGDSCRint
26
* hw/intc: Improve formatting of MEMTX_ERROR guest error message
26
27
27
----------------------------------------------------------------
28
----------------------------------------------------------------
28
Andrey Smirnov (2):
29
Alexandre Iooss (4):
29
char: i.MX: Simplify imx_update()
30
stm32f100: Add the stm32f100 SoC
30
char: i.MX: Add support for "TX complete" interrupt
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
Guenter Roeck (1):
35
Peter Maydell (10):
33
fsl-imx6: Swap Ethernet interrupt defines
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
34
46
35
Peter Maydell (9):
47
Rebecca Cran (1):
36
hw/arm/raspi: Don't do board-setup or secure-boot for raspi3
48
hw/intc: Improve formatting of MEMTX_ERROR guest error message
37
hw/arm/boot: assert that secure_boot and secure_board_setup are false for AArch64
38
hw/arm/boot: If booting a kernel in EL2, set SCR_EL3.HCE
39
hw/arm/bcm2386: Fix parent type of bcm2386
40
hw/arm/bcm2836: Rename bcm2836 type/struct to bcm283x
41
hw/arm/bcm2836: Create proper bcm2837 device
42
hw/arm/bcm2836: Use correct affinity values for BCM2837
43
hw/arm/bcm2836: Hardcode correct CPU type
44
hw/arm/raspi: Provide spin-loop code for AArch64 CPUs
45
49
46
Wei Huang (1):
50
Ricardo Koller (1):
47
dump: Update correct kdump phys_base field for AArch64
51
hw/intc/arm_gicv3_cpuif: Fix virtual irq number check in icv_[dir|eoir]_write
48
52
49
include/hw/arm/bcm2836.h | 31 +++++++++++++---
53
hnick@vmware.com (1):
50
include/hw/arm/fsl-imx6.h | 4 +-
54
target/arm: Correct the encoding of MDCCSR_EL0 and DBGDSCRint
51
include/hw/char/imx_serial.h | 3 ++
52
dump.c | 14 +++++--
53
hw/arm/bcm2836.c | 87 +++++++++++++++++++++++++++++++-------------
54
hw/arm/boot.c | 12 ++++++
55
hw/arm/raspi.c | 77 +++++++++++++++++++++++++++++++--------
56
hw/char/imx_serial.c | 44 ++++++++++++++++------
57
hw/net/imx_fec.c | 28 +++++++++++++-
58
9 files changed, 237 insertions(+), 63 deletions(-)
59
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
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
New patch
1
From: Alexandre Iooss <erdnaxe@crans.org>
1
2
3
This is a Cortex-M3 based machine. Information can be found at:
4
https://www.st.com/en/evaluation-tools/stm32vldiscovery.html
5
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
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
default-configs/devices/arm-softmmu.mak | 1 +
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
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
120
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
121
index XXXXXXX..XXXXXXX 100644
122
--- a/hw/arm/Kconfig
123
+++ b/hw/arm/Kconfig
124
@@ -XXX,XX +XXX,XX @@ config STELLARIS
125
select STELLARIS_ENET # ethernet
126
select UNIMP
127
128
+config STM32VLDISCOVERY
129
+ bool
130
+ select STM32F100_SOC
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'))
147
--
148
2.20.1
149
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
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Alexandre Iooss <erdnaxe@crans.org>
2
2
3
Code of imx_update() is slightly confusing since the "flags" variable
3
New mini-kernel test for STM32VLDISCOVERY USART1.
4
doesn't really corespond to anything in real hardware and server as a
5
kitchensink accumulating events normally reported via USR1 and USR2
6
registers.
7
4
8
Change the code to explicitly evaluate state of interrupts reported
5
Signed-off-by: Alexandre Iooss <erdnaxe@crans.org>
9
via USR1 and USR2 against corresponding masking bits and use the to
6
Acked-by: Thomas Huth <thuth@redhat.com>
10
detemine if IRQ line should be asserted or not.
7
Acked-by: Alistair Francis <alistair.francis@wdc.com>
11
8
Message-id: 20210617165647.2575955-5-erdnaxe@crans.org
12
NOTE: Check for UTS1_TXEMPTY being set has been dropped for two
13
reasons:
14
15
1. Emulation code implements a single character FIFO, so this flag
16
will always be set since characters are trasmitted as a part of
17
the code emulating "push" into the FIFO
18
19
2. imx_update() is really just a function doing ORing and maksing
20
of reported events, so checking for UTS1_TXEMPTY should happen,
21
if it's ever really needed should probably happen outside of
22
it.
23
24
Cc: qemu-devel@nongnu.org
25
Cc: qemu-arm@nongnu.org
26
Cc: Bill Paul <wpaul@windriver.com>
27
Cc: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
29
Message-id: 20180315191141.6789-1-andrew.smirnov@gmail.com
30
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
31
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
---
10
---
33
hw/char/imx_serial.c | 24 ++++++++++++++++--------
11
tests/qtest/boot-serial-test.c | 37 ++++++++++++++++++++++++++++++++++
34
1 file changed, 16 insertions(+), 8 deletions(-)
12
1 file changed, 37 insertions(+)
35
13
36
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
14
diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c
37
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/char/imx_serial.c
16
--- a/tests/qtest/boot-serial-test.c
39
+++ b/hw/char/imx_serial.c
17
+++ b/tests/qtest/boot-serial-test.c
40
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_serial = {
18
@@ -XXX,XX +XXX,XX @@ static const uint8_t kernel_nrf51[] = {
41
19
0x1c, 0x25, 0x00, 0x40 /* 0x4000251c = UART TXD */
42
static void imx_update(IMXSerialState *s)
20
};
43
{
21
44
- uint32_t flags;
22
+static const uint8_t kernel_stm32vldiscovery[] = {
45
+ uint32_t usr1;
23
+ 0x00, 0x00, 0x00, 0x00, /* Stack top address */
46
+ uint32_t usr2;
24
+ 0x1d, 0x00, 0x00, 0x00, /* Reset handler address */
47
+ uint32_t mask;
25
+ 0x00, 0x00, 0x00, 0x00, /* NMI */
48
26
+ 0x00, 0x00, 0x00, 0x00, /* Hard fault */
49
- flags = (s->usr1 & s->ucr1) & (USR1_TRDY|USR1_RRDY);
27
+ 0x00, 0x00, 0x00, 0x00, /* Memory management fault */
50
- if (s->ucr1 & UCR1_TXMPTYEN) {
28
+ 0x00, 0x00, 0x00, 0x00, /* Bus fault */
51
- flags |= (s->uts1 & UTS1_TXEMPTY);
29
+ 0x00, 0x00, 0x00, 0x00, /* Usage fault */
52
- } else {
30
+ 0x0b, 0x4b, /* ldr r3, [pc, #44] Get RCC */
53
- flags &= ~USR1_TRDY;
31
+ 0x44, 0xf2, 0x04, 0x02, /* movw r2, #16388 */
54
- }
32
+ 0x1a, 0x60, /* str r2, [r3] */
55
+ /*
33
+ 0x0a, 0x4b, /* ldr r3, [pc, #40] Get GPIOA */
56
+ * Lucky for us TRDY and RRDY has the same offset in both USR1 and
34
+ 0x1a, 0x68, /* ldr r2, [r3] */
57
+ * UCR1, so we can get away with something as simple as the
35
+ 0x22, 0xf0, 0xf0, 0x02, /* bic r2, r2, #240 */
58
+ * following:
36
+ 0x1a, 0x60, /* str r2, [r3] */
59
+ */
37
+ 0x1a, 0x68, /* ldr r2, [r3] */
60
+ usr1 = s->usr1 & s->ucr1 & (USR1_TRDY | USR1_RRDY);
38
+ 0x42, 0xf0, 0xb0, 0x02, /* orr r2, r2, #176 */
61
+ /*
39
+ 0x1a, 0x60, /* str r2, [r3] */
62
+ * Bits that we want in USR2 are not as conveniently laid out,
40
+ 0x07, 0x4b, /* ldr r3, [pc, #26] Get BAUD */
63
+ * unfortunately.
41
+ 0x45, 0x22, /* movs r2, #69 */
64
+ */
42
+ 0x1a, 0x60, /* str r2, [r3] */
65
+ mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
43
+ 0x06, 0x4b, /* ldr r3, [pc, #24] Get ENABLE */
66
+ usr2 = s->usr2 & mask;
44
+ 0x42, 0xf2, 0x08, 0x02, /* movw r2, #8200 */
67
45
+ 0x1a, 0x60, /* str r2, [r3] */
68
- qemu_set_irq(s->irq, !!flags);
46
+ 0x05, 0x4b, /* ldr r3, [pc, #20] Get TXD */
69
+ qemu_set_irq(s->irq, usr1 || usr2);
47
+ 0x54, 0x22, /* movs r2, 'T' */
70
}
48
+ 0x1a, 0x60, /* str r2, [r3] */
71
49
+ 0xfe, 0xe7, /* b . */
72
static void imx_serial_reset(IMXSerialState *s)
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
};
73
--
69
--
74
2.16.2
70
2.20.1
75
71
76
72
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Ricardo Koller <ricarkol@google.com>
2
2
3
Add support for "TX complete"/TXDC interrupt generate by real HW since
3
icv_eoir_write() and icv_dir_write() ignore invalid virtual IRQ numbers
4
it is needed to support guests other than Linux.
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.
5
11
6
Based on the patch by Bill Paul as found here:
12
Fix the checks by using GICV3_MAXIRQ (1020) instead of the number of
7
https://bugs.launchpad.net/qemu/+bug/1753314
13
implemented IRQs.
8
14
9
Cc: qemu-devel@nongnu.org
15
Signed-off-by: Ricardo Koller <ricarkol@google.com>
10
Cc: qemu-arm@nongnu.org
16
Message-id: 20210702233701.3369-1-ricarkol@google.com
11
Cc: Bill Paul <wpaul@windriver.com>
12
Cc: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Bill Paul <wpaul@windriver.com>
14
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
15
Message-id: 20180315191141.6789-2-andrew.smirnov@gmail.com
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
---
19
include/hw/char/imx_serial.h | 3 +++
20
hw/intc/arm_gicv3_cpuif.c | 4 ++--
20
hw/char/imx_serial.c | 20 +++++++++++++++++---
21
1 file changed, 2 insertions(+), 2 deletions(-)
21
2 files changed, 20 insertions(+), 3 deletions(-)
22
22
23
diff --git a/include/hw/char/imx_serial.h b/include/hw/char/imx_serial.h
23
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
24
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/char/imx_serial.h
25
--- a/hw/intc/arm_gicv3_cpuif.c
26
+++ b/include/hw/char/imx_serial.h
26
+++ b/hw/intc/arm_gicv3_cpuif.c
27
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@ static void icv_dir_write(CPUARMState *env, const ARMCPRegInfo *ri,
28
#define UCR2_RXEN (1<<1) /* Receiver enable */
28
29
#define UCR2_SRST (1<<0) /* Reset complete */
29
trace_gicv3_icv_dir_write(gicv3_redist_affid(cs), value);
30
30
31
+#define UCR4_TCEN BIT(3) /* TX complete interrupt enable */
31
- if (irq >= cs->gic->num_irq) {
32
+
32
+ if (irq >= GICV3_MAXIRQ) {
33
#define UTS1_TXEMPTY (1<<6)
33
/* Also catches special interrupt numbers and LPIs */
34
#define UTS1_RXEMPTY (1<<5)
34
return;
35
#define UTS1_TXFULL (1<<4)
35
}
36
@@ -XXX,XX +XXX,XX @@ typedef struct IMXSerialState {
36
@@ -XXX,XX +XXX,XX @@ static void icv_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri,
37
uint32_t ubmr;
37
trace_gicv3_icv_eoir_write(ri->crm == 8 ? 0 : 1,
38
uint32_t ubrc;
38
gicv3_redist_affid(cs), value);
39
uint32_t ucr3;
39
40
+ uint32_t ucr4;
40
- if (irq >= cs->gic->num_irq) {
41
41
+ if (irq >= GICV3_MAXIRQ) {
42
qemu_irq irq;
42
/* Also catches special interrupt numbers and LPIs */
43
CharBackend chr;
43
return;
44
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
44
}
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/char/imx_serial.c
47
+++ b/hw/char/imx_serial.c
48
@@ -XXX,XX +XXX,XX @@
49
50
static const VMStateDescription vmstate_imx_serial = {
51
.name = TYPE_IMX_SERIAL,
52
- .version_id = 1,
53
- .minimum_version_id = 1,
54
+ .version_id = 2,
55
+ .minimum_version_id = 2,
56
.fields = (VMStateField[]) {
57
VMSTATE_INT32(readbuff, IMXSerialState),
58
VMSTATE_UINT32(usr1, IMXSerialState),
59
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_serial = {
60
VMSTATE_UINT32(ubmr, IMXSerialState),
61
VMSTATE_UINT32(ubrc, IMXSerialState),
62
VMSTATE_UINT32(ucr3, IMXSerialState),
63
+ VMSTATE_UINT32(ucr4, IMXSerialState),
64
VMSTATE_END_OF_LIST()
65
},
66
};
67
@@ -XXX,XX +XXX,XX @@ static void imx_update(IMXSerialState *s)
68
* unfortunately.
69
*/
70
mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
71
+ /*
72
+ * TCEN and TXDC are both bit 3
73
+ */
74
+ mask |= s->ucr4 & UCR4_TCEN;
75
+
76
usr2 = s->usr2 & mask;
77
78
qemu_set_irq(s->irq, usr1 || usr2);
79
@@ -XXX,XX +XXX,XX @@ static uint64_t imx_serial_read(void *opaque, hwaddr offset,
80
return s->ucr3;
81
82
case 0x23: /* UCR4 */
83
+ return s->ucr4;
84
+
85
case 0x29: /* BRM Incremental */
86
return 0x0; /* TODO */
87
88
@@ -XXX,XX +XXX,XX @@ static void imx_serial_write(void *opaque, hwaddr offset,
89
* qemu_chr_fe_write and background I/O callbacks */
90
qemu_chr_fe_write_all(&s->chr, &ch, 1);
91
s->usr1 &= ~USR1_TRDY;
92
+ s->usr2 &= ~USR2_TXDC;
93
imx_update(s);
94
s->usr1 |= USR1_TRDY;
95
+ s->usr2 |= USR2_TXDC;
96
imx_update(s);
97
}
98
break;
99
@@ -XXX,XX +XXX,XX @@ static void imx_serial_write(void *opaque, hwaddr offset,
100
s->ucr3 = value & 0xffff;
101
break;
102
103
- case 0x2d: /* UTS1 */
104
case 0x23: /* UCR4 */
105
+ s->ucr4 = value & 0xffff;
106
+ imx_update(s);
107
+ break;
108
+
109
+ case 0x2d: /* UTS1 */
110
qemu_log_mask(LOG_UNIMP, "[%s]%s: Unimplemented reg 0x%"
111
HWADDR_PRIx "\n", TYPE_IMX_SERIAL, __func__, offset);
112
/* TODO */
113
--
45
--
114
2.16.2
46
2.20.1
115
47
116
48
diff view generated by jsdifflib
1
The TypeInfo and state struct for bcm2386 disagree about what the
1
Convert the use of the DPRINTF debug macro in the PL061 model to
2
parent class is -- the TypeInfo says it's TYPE_SYS_BUS_DEVICE,
2
use tracepoints.
3
but the BCM2386State struct only defines the parent_obj field
4
as DeviceState. This would have caused problems if anything
5
actually tried to treat the object as a TYPE_SYS_BUS_DEVICE.
6
Fix the TypeInfo to use TYPE_DEVICE as the parent, since we don't
7
need any of the additional functionality TYPE_SYS_BUS_DEVICE
8
provides.
9
3
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20180313153458.26822-5-peter.maydell@linaro.org
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
---
7
---
15
hw/arm/bcm2836.c | 2 +-
8
hw/gpio/pl061.c | 27 +++++++++------------------
16
1 file changed, 1 insertion(+), 1 deletion(-)
9
hw/gpio/trace-events | 6 ++++++
10
2 files changed, 15 insertions(+), 18 deletions(-)
17
11
18
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
12
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
19
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/bcm2836.c
14
--- a/hw/gpio/pl061.c
21
+++ b/hw/arm/bcm2836.c
15
+++ b/hw/gpio/pl061.c
22
@@ -XXX,XX +XXX,XX @@ static void bcm2836_class_init(ObjectClass *oc, void *data)
16
@@ -XXX,XX +XXX,XX @@
23
17
#include "qemu/log.h"
24
static const TypeInfo bcm2836_type_info = {
18
#include "qemu/module.h"
25
.name = TYPE_BCM2836,
19
#include "qom/object.h"
26
- .parent = TYPE_SYS_BUS_DEVICE,
20
-
27
+ .parent = TYPE_DEVICE,
21
-//#define DEBUG_PL061 1
28
.instance_size = sizeof(BCM2836State),
22
-
29
.instance_init = bcm2836_init,
23
-#ifdef DEBUG_PL061
30
.class_init = bcm2836_class_init,
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
31
--
95
--
32
2.16.2
96
2.20.1
33
97
34
98
diff view generated by jsdifflib
1
Our BCM2836 type is really a generic one that can be any of
1
Currently the pl061_read() and pl061_write() functions handle offsets
2
the bcm283x family. Rename it accordingly. We change only
2
using a combination of three if() statements and a switch(). Clean
3
the names which are visible via the header file to the
3
this up to use just a switch, using case ranges.
4
rest of the QEMU code, leaving private function names
4
5
in bcm2836.c as they are.
5
This requires that instead of catching accesses to the luminary-only
6
6
registers on a stock PL061 via a check on s->rsvd_start we use
7
This is a preliminary to making bcm283x be an abstract
7
an "is this luminary?" check in the cases for each luminary-only
8
parent class to specific types for the bcm2836 and bcm2837.
8
register.
9
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20180313153458.26822-6-peter.maydell@linaro.org
14
---
12
---
15
include/hw/arm/bcm2836.h | 12 ++++++------
13
hw/gpio/pl061.c | 104 ++++++++++++++++++++++++++++++++++++------------
16
hw/arm/bcm2836.c | 17 +++++++++--------
14
1 file changed, 79 insertions(+), 25 deletions(-)
17
hw/arm/raspi.c | 16 ++++++++--------
15
18
3 files changed, 23 insertions(+), 22 deletions(-)
16
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
19
20
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/arm/bcm2836.h
18
--- a/hw/gpio/pl061.c
23
+++ b/include/hw/arm/bcm2836.h
19
+++ b/hw/gpio/pl061.c
24
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ struct PL061State {
25
#include "hw/arm/bcm2835_peripherals.h"
21
qemu_irq irq;
26
#include "hw/intc/bcm2836_control.h"
22
qemu_irq out[N_GPIOS];
27
23
const unsigned char *id;
28
-#define TYPE_BCM2836 "bcm2836"
24
- uint32_t rsvd_start; /* reserved area: [rsvd_start, 0xfcc] */
29
-#define BCM2836(obj) OBJECT_CHECK(BCM2836State, (obj), TYPE_BCM2836)
25
};
30
+#define TYPE_BCM283X "bcm283x"
26
31
+#define BCM283X(obj) OBJECT_CHECK(BCM283XState, (obj), TYPE_BCM283X)
27
static const VMStateDescription vmstate_pl061 = {
32
28
@@ -XXX,XX +XXX,XX @@ static uint64_t pl061_read(void *opaque, hwaddr offset,
33
-#define BCM2836_NCPUS 4
34
+#define BCM283X_NCPUS 4
35
36
-typedef struct BCM2836State {
37
+typedef struct BCM283XState {
38
/*< private >*/
39
DeviceState parent_obj;
40
/*< public >*/
41
@@ -XXX,XX +XXX,XX @@ typedef struct BCM2836State {
42
char *cpu_type;
43
uint32_t enabled_cpus;
44
45
- ARMCPU cpus[BCM2836_NCPUS];
46
+ ARMCPU cpus[BCM283X_NCPUS];
47
BCM2836ControlState control;
48
BCM2835PeripheralState peripherals;
49
-} BCM2836State;
50
+} BCM283XState;
51
52
#endif /* BCM2836_H */
53
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/arm/bcm2836.c
56
+++ b/hw/arm/bcm2836.c
57
@@ -XXX,XX +XXX,XX @@
58
59
static void bcm2836_init(Object *obj)
60
{
29
{
61
- BCM2836State *s = BCM2836(obj);
30
PL061State *s = (PL061State *)opaque;
62
+ BCM283XState *s = BCM283X(obj);
31
63
32
- if (offset < 0x400) {
64
object_initialize(&s->control, sizeof(s->control), TYPE_BCM2836_CONTROL);
33
- return s->data & (offset >> 2);
65
object_property_add_child(obj, "control", OBJECT(&s->control), NULL);
34
- }
66
@@ -XXX,XX +XXX,XX @@ static void bcm2836_init(Object *obj)
35
- if (offset >= s->rsvd_start && offset <= 0xfcc) {
67
36
- goto err_out;
68
static void bcm2836_realize(DeviceState *dev, Error **errp)
37
- }
69
{
38
- if (offset >= 0xfd0 && offset < 0x1000) {
70
- BCM2836State *s = BCM2836(dev);
39
- return s->id[(offset - 0xfd0) >> 2];
71
+ BCM283XState *s = BCM283X(dev);
40
- }
72
Object *obj;
41
switch (offset) {
73
Error *err = NULL;
42
+ case 0x0 ... 0x3ff: /* Data */
74
int n;
43
+ return s->data & (offset >> 2);
75
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
44
case 0x400: /* Direction */
76
/* common peripherals from bcm2835 */
45
return s->dir;
77
46
case 0x404: /* Interrupt sense */
78
obj = OBJECT(dev);
47
@@ -XXX,XX +XXX,XX @@ static uint64_t pl061_read(void *opaque, hwaddr offset,
79
- for (n = 0; n < BCM2836_NCPUS; n++) {
48
case 0x420: /* Alternate function select */
80
+ for (n = 0; n < BCM283X_NCPUS; n++) {
49
return s->afsel;
81
object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
50
case 0x500: /* 2mA drive */
82
s->cpu_type);
51
+ if (s->id != pl061_id_luminary) {
83
object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
52
+ goto bad_offset;
84
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
53
+ }
85
sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 1,
54
return s->dr2r;
86
qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-fiq", 0));
55
case 0x504: /* 4mA drive */
87
56
+ if (s->id != pl061_id_luminary) {
88
- for (n = 0; n < BCM2836_NCPUS; n++) {
57
+ goto bad_offset;
89
+ for (n = 0; n < BCM283X_NCPUS; n++) {
58
+ }
90
/* Mirror bcm2836, which has clusterid set to 0xf
59
return s->dr4r;
91
* TODO: this should be converted to a property of ARM_CPU
60
case 0x508: /* 8mA drive */
92
*/
61
+ if (s->id != pl061_id_luminary) {
93
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
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;
94
}
117
}
95
118
96
static Property bcm2836_props[] = {
119
@@ -XXX,XX +XXX,XX @@ static void pl061_write(void *opaque, hwaddr offset,
97
- DEFINE_PROP_STRING("cpu-type", BCM2836State, cpu_type),
120
PL061State *s = (PL061State *)opaque;
98
- DEFINE_PROP_UINT32("enabled-cpus", BCM2836State, enabled_cpus, BCM2836_NCPUS),
121
uint8_t mask;
99
+ DEFINE_PROP_STRING("cpu-type", BCM283XState, cpu_type),
122
100
+ DEFINE_PROP_UINT32("enabled-cpus", BCM283XState, enabled_cpus,
123
- if (offset < 0x400) {
101
+ BCM283X_NCPUS),
124
+ switch (offset) {
102
DEFINE_PROP_END_OF_LIST()
125
+ case 0 ... 0x3ff:
103
};
126
mask = (offset >> 2) & s->dir;
104
127
s->data = (s->data & ~mask) | (value & mask);
105
@@ -XXX,XX +XXX,XX @@ static void bcm2836_class_init(ObjectClass *oc, void *data)
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);
106
}
220
}
107
221
108
static const TypeInfo bcm2836_type_info = {
222
static void pl061_reset(DeviceState *dev)
109
- .name = TYPE_BCM2836,
223
@@ -XXX,XX +XXX,XX @@ static void pl061_luminary_init(Object *obj)
110
+ .name = TYPE_BCM283X,
224
PL061State *s = PL061(obj);
111
.parent = TYPE_DEVICE,
225
112
- .instance_size = sizeof(BCM2836State),
226
s->id = pl061_id_luminary;
113
+ .instance_size = sizeof(BCM283XState),
227
- s->rsvd_start = 0x52c;
114
.instance_init = bcm2836_init,
115
.class_init = bcm2836_class_init,
116
};
117
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/hw/arm/raspi.c
120
+++ b/hw/arm/raspi.c
121
@@ -XXX,XX +XXX,XX @@
122
static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44};
123
124
typedef struct RasPiState {
125
- BCM2836State soc;
126
+ BCM283XState soc;
127
MemoryRegion ram;
128
} RasPiState;
129
130
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
131
BusState *bus;
132
DeviceState *carddev;
133
134
- object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM2836);
135
+ object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM283X);
136
object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
137
&error_abort);
138
139
@@ -XXX,XX +XXX,XX @@ static void raspi2_machine_init(MachineClass *mc)
140
mc->no_floppy = 1;
141
mc->no_cdrom = 1;
142
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
143
- mc->max_cpus = BCM2836_NCPUS;
144
- mc->min_cpus = BCM2836_NCPUS;
145
- mc->default_cpus = BCM2836_NCPUS;
146
+ mc->max_cpus = BCM283X_NCPUS;
147
+ mc->min_cpus = BCM283X_NCPUS;
148
+ mc->default_cpus = BCM283X_NCPUS;
149
mc->default_ram_size = 1024 * 1024 * 1024;
150
mc->ignore_memory_transaction_failures = true;
151
};
152
@@ -XXX,XX +XXX,XX @@ static void raspi3_machine_init(MachineClass *mc)
153
mc->no_floppy = 1;
154
mc->no_cdrom = 1;
155
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a53");
156
- mc->max_cpus = BCM2836_NCPUS;
157
- mc->min_cpus = BCM2836_NCPUS;
158
- mc->default_cpus = BCM2836_NCPUS;
159
+ mc->max_cpus = BCM283X_NCPUS;
160
+ mc->min_cpus = BCM283X_NCPUS;
161
+ mc->default_cpus = BCM283X_NCPUS;
162
mc->default_ram_size = 1024 * 1024 * 1024;
163
}
228
}
164
DEFINE_MACHINE("raspi3", raspi3_machine_init)
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);
165
--
239
--
166
2.16.2
240
2.20.1
167
241
168
242
diff view generated by jsdifflib
1
If we're directly booting a Linux kernel and the CPU supports both
1
Add tracepoints for reads and writes to the PL061 registers. This requires
2
EL3 and EL2, we start the kernel in EL2, as it expects. We must also
2
restructuring pl061_read() to only return after the tracepoint, rather
3
set the SCR_EL3.HCE bit in this situation, so that the HVC
3
than having lots of early-returns.
4
instruction is enabled rather than UNDEFing. Otherwise at least some
5
kernels will panic when trying to initialize KVM in the guest.
6
4
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20180313153458.26822-4-peter.maydell@linaro.org
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
---
8
---
10
hw/arm/boot.c | 5 +++++
9
hw/gpio/pl061.c | 70 ++++++++++++++++++++++++++++++--------------
11
1 file changed, 5 insertions(+)
10
hw/gpio/trace-events | 2 ++
11
2 files changed, 50 insertions(+), 22 deletions(-)
12
12
13
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
13
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/boot.c
15
--- a/hw/gpio/pl061.c
16
+++ b/hw/arm/boot.c
16
+++ b/hw/gpio/pl061.c
17
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
17
@@ -XXX,XX +XXX,XX @@ static uint64_t pl061_read(void *opaque, hwaddr offset,
18
assert(!info->secure_board_setup);
18
unsigned size)
19
}
19
{
20
20
PL061State *s = (PL061State *)opaque;
21
+ if (arm_feature(env, ARM_FEATURE_EL2)) {
21
+ uint64_t r = 0;
22
+ /* If we have EL2 then Linux expects the HVC insn to work */
22
23
+ env->cp15.scr_el3 |= SCR_HCE;
23
switch (offset) {
24
+ }
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;
25
+
148
+
26
/* Set to non-secure if not a secure boot */
149
+ trace_pl061_read(DEVICE(s)->canonical_path, offset, r);
27
if (!info->secure_boot &&
150
+ return r;
28
(cs != first_cpu || !info->secure_board_setup)) {
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
29
--
176
--
30
2.16.2
177
2.20.1
31
178
32
179
diff view generated by jsdifflib
1
Add some assertions that if we're about to boot an AArch64 kernel,
1
Add a comment documenting the "QEMU interface" of this device:
2
the board code has not mistakenly set either secure_boot or
2
which MMIO regions, IRQ lines, GPIO lines, etc it exposes.
3
secure_board_setup. It doesn't make sense to set secure_boot,
4
because all AArch64 kernels must be booted in non-secure mode.
5
6
It might in theory make sense to set secure_board_setup, but
7
we don't currently support that, because only the AArch32
8
bootloader[] code calls this hook; bootloader_aarch64[] does not.
9
Since we don't have a current need for this functionality, just
10
assert that we don't try to use it. If it's needed we'll add
11
it later.
12
3
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20180313153458.26822-3-peter.maydell@linaro.org
16
---
6
---
17
hw/arm/boot.c | 7 +++++++
7
hw/gpio/pl061.c | 7 +++++++
18
1 file changed, 7 insertions(+)
8
1 file changed, 7 insertions(+)
19
9
20
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
10
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
21
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/boot.c
12
--- a/hw/gpio/pl061.c
23
+++ b/hw/arm/boot.c
13
+++ b/hw/gpio/pl061.c
24
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
14
@@ -XXX,XX +XXX,XX @@
25
} else {
15
* Written by Paul Brook
26
env->pstate = PSTATE_MODE_EL1h;
16
*
27
}
17
* This code is licensed under the GPL.
28
+ /* AArch64 kernels never boot in secure mode */
18
+ *
29
+ assert(!info->secure_boot);
19
+ * QEMU interface:
30
+ /* This hook is only supported for AArch32 currently:
20
+ * + sysbus MMIO region 0: the device registers
31
+ * bootloader_aarch64[] will not call the hook, and
21
+ * + sysbus IRQ: the GPIOINTR interrupt line
32
+ * the code above has already dropped us into EL2 or EL1.
22
+ * + unnamed GPIO inputs 0..7: inputs to connect to the emulated GPIO lines
33
+ */
23
+ * + unnamed GPIO outputs 0..7: the emulated GPIO lines, considered as
34
+ assert(!info->secure_board_setup);
24
+ * outputs
35
}
25
*/
36
26
37
/* Set to non-secure if not a secure boot */
27
#include "qemu/osdep.h"
38
--
28
--
39
2.16.2
29
2.20.1
40
30
41
31
diff view generated by jsdifflib
1
The BCM2837 sets the Aff1 field of the MPIDR affinity values for the
1
The Luminary variant of the PL061 has registers GPIOPUR and GPIOPDR
2
CPUs to 0, whereas the BCM2836 uses 0xf. Set this correctly, as it
2
which lets the guest configure whether the GPIO lines are pull-up,
3
is required for Linux to boot.
3
pull-down, or truly floating. Instead of assuming all lines are pulled
4
high, honour the PUR and PDR registers.
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.
4
14
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20180313153458.26822-8-peter.maydell@linaro.org
9
---
17
---
10
hw/arm/bcm2836.c | 11 +++++++----
18
hw/gpio/pl061.c | 58 +++++++++++++++++++++++++++++++++++++++++---
11
1 file changed, 7 insertions(+), 4 deletions(-)
19
hw/gpio/trace-events | 2 +-
20
2 files changed, 55 insertions(+), 5 deletions(-)
12
21
13
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
22
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
14
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/bcm2836.c
24
--- a/hw/gpio/pl061.c
16
+++ b/hw/arm/bcm2836.c
25
+++ b/hw/gpio/pl061.c
17
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pl061 = {
18
27
}
19
struct BCM283XInfo {
20
const char *name;
21
+ int clusterid;
22
};
28
};
23
29
24
static const BCM283XInfo bcm283x_socs[] = {
30
+static uint8_t pl061_floating(PL061State *s)
25
{
31
+{
26
.name = TYPE_BCM2836,
32
+ /*
27
+ .clusterid = 0xf,
33
+ * Return mask of bits which correspond to pins configured as inputs
28
},
34
+ * and which are floating (neither pulled up to 1 nor down to 0).
29
{
35
+ */
30
.name = TYPE_BCM2837,
36
+ uint8_t floating;
31
+ .clusterid = 0x0,
37
+
32
},
38
+ if (s->id == pl061_id_luminary) {
33
};
39
+ /*
34
40
+ * If both PUR and PDR bits are clear, there is neither a pullup
35
@@ -XXX,XX +XXX,XX @@ static void bcm2836_init(Object *obj)
41
+ * nor a pulldown in place, and the output truly floats.
36
static void bcm2836_realize(DeviceState *dev, Error **errp)
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)
37
{
74
{
38
BCM283XState *s = BCM283X(dev);
75
uint8_t changed;
39
+ BCM283XClass *bc = BCM283X_GET_CLASS(dev);
76
uint8_t mask;
40
+ const BCM283XInfo *info = bc->info;
77
uint8_t out;
41
Object *obj;
78
int i;
42
Error *err = NULL;
79
+ uint8_t pullups = pl061_pullups(s);
43
int n;
80
+ uint8_t floating = pl061_floating(s);
44
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
81
45
qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-fiq", 0));
82
- trace_pl061_update(DEVICE(s)->canonical_path, s->dir, s->data);
46
83
+ trace_pl061_update(DEVICE(s)->canonical_path, s->dir, s->data,
47
for (n = 0; n < BCM283X_NCPUS; n++) {
84
+ pullups, floating);
48
- /* Mirror bcm2836, which has clusterid set to 0xf
85
49
- * TODO: this should be converted to a property of ARM_CPU
86
- /* Outputs float high. */
50
- */
87
- /* FIXME: This is board dependent. */
51
- s->cpus[n].mp_affinity = 0xF00 | n;
88
- out = (s->data & s->dir) | ~s->dir;
52
+ /* TODO: this should be converted to a property of ARM_CPU */
89
+ /*
53
+ s->cpus[n].mp_affinity = (info->clusterid << 8) | n;
90
+ * Pins configured as output are driven from the data register;
54
91
+ * otherwise if they're pulled up they're 1, and if they're floating
55
/* set periphbase/CBAR value for CPU-local registers */
92
+ * then we give them the same value they had previously, so we don't
56
object_property_set_int(OBJECT(&s->cpus[n]),
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"
57
--
112
--
58
2.16.2
113
2.20.1
59
114
60
115
diff view generated by jsdifflib
1
Now we have separate types for BCM2386 and BCM2387, we might as well
1
The PL061 GPIO does not itself include pullup or pulldown resistors
2
just hard-code the CPU type they use rather than having it passed
2
to set the value of a GPIO line treated as an output when it is
3
through as an object property. This then lets us put the initialization
3
configured as an input (ie when the PL061 itself is not driving it).
4
of the CPU object in init rather than realize.
4
In real hardware it is up to the board to add suitable pullups or
5
pulldowns. Currently our implementation hardwires this to "outputs
6
pulled high", which is correct for some boards (eg the realview ones:
7
see figure 3-29 in the "RealView Platform Baseboard for ARM926EJ-S
8
User Guide" DUI0224I), but wrong for others.
5
9
6
Note that this change means that it's no longer possible on
10
In particular, the wiring in the 'virt' board and the gpio-pwr device
7
the command line to use -cpu to ask for a different kind of
11
assumes that wires should be pulled low, because otherwise the
8
CPU than the SoC supports. This was never a supported thing to
12
pull-to-high will trigger a shutdown or reset action. (The only
9
do anyway; we were just not sanity-checking the command line.
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.)
10
17
11
This does require us to only build the bcm2837 object on
18
Add properties to the pl061 so the board can configure whether it
12
TARGET_AARCH64 configs, since otherwise it won't instantiate
19
wants GPIO lines to have pullup, pulldown, or neither.
13
due to the missing cortex-a53 device and "make check" will fail.
14
20
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Message-id: 20180313153458.26822-9-peter.maydell@linaro.org
19
---
23
---
20
hw/arm/bcm2836.c | 24 +++++++++++++++---------
24
hw/gpio/pl061.c | 51 +++++++++++++++++++++++++++++++++++++++++++++----
21
hw/arm/raspi.c | 2 --
25
1 file changed, 47 insertions(+), 4 deletions(-)
22
2 files changed, 15 insertions(+), 11 deletions(-)
23
26
24
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
27
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
25
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/bcm2836.c
29
--- a/hw/gpio/pl061.c
27
+++ b/hw/arm/bcm2836.c
30
+++ b/hw/gpio/pl061.c
28
@@ -XXX,XX +XXX,XX @@
31
@@ -XXX,XX +XXX,XX @@
29
32
* + unnamed GPIO inputs 0..7: inputs to connect to the emulated GPIO lines
30
struct BCM283XInfo {
33
* + unnamed GPIO outputs 0..7: the emulated GPIO lines, considered as
31
const char *name;
34
* outputs
32
+ const char *cpu_type;
35
+ * + QOM property "pullups": an integer defining whether non-floating lines
33
int clusterid;
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"
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;
34
};
67
};
35
68
36
static const BCM283XInfo bcm283x_socs[] = {
69
static const VMStateDescription vmstate_pl061 = {
37
{
70
@@ -XXX,XX +XXX,XX @@ static uint8_t pl061_floating(PL061State *s)
38
.name = TYPE_BCM2836,
71
*/
39
+ .cpu_type = ARM_CPU_TYPE_NAME("cortex-a15"),
72
floating = ~(s->pur | s->pdr);
40
.clusterid = 0xf,
73
} else {
41
},
74
- /* Assume outputs are pulled high. FIXME: this is board dependent. */
42
+#ifdef TARGET_AARCH64
75
- floating = 0;
43
{
76
+ floating = ~(s->pullups | s->pulldowns);
44
.name = TYPE_BCM2837,
77
}
45
+ .cpu_type = ARM_CPU_TYPE_NAME("cortex-a53"),
78
return floating & ~s->dir;
46
.clusterid = 0x0,
79
}
47
},
80
@@ -XXX,XX +XXX,XX @@ static uint8_t pl061_pullups(PL061State *s)
48
+#endif
81
*/
49
};
82
pullups = s->pur;
50
83
} else {
51
static void bcm2836_init(Object *obj)
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)
95
+{
96
+ PL061State *s = PL061(dev);
97
+
98
+ if (s->pullups > 0xff) {
99
+ error_setg(errp, "pullups property must be between 0 and 0xff");
100
+ return;
101
+ }
102
+ if (s->pulldowns > 0xff) {
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
+ }
110
+}
111
+
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)
52
{
119
{
53
BCM283XState *s = BCM283X(obj);
120
DeviceClass *dc = DEVICE_CLASS(klass);
54
+ BCM283XClass *bc = BCM283X_GET_CLASS(obj);
121
55
+ const BCM283XInfo *info = bc->info;
122
dc->vmsd = &vmstate_pl061;
56
+ int n;
123
dc->reset = &pl061_reset;
57
+
124
+ dc->realize = pl061_realize;
58
+ for (n = 0; n < BCM283X_NCPUS; n++) {
125
+ device_class_set_props(dc, pl061_props);
59
+ object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
60
+ info->cpu_type);
61
+ object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
62
+ &error_abort);
63
+ }
64
65
object_initialize(&s->control, sizeof(s->control), TYPE_BCM2836_CONTROL);
66
object_property_add_child(obj, "control", OBJECT(&s->control), NULL);
67
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
68
69
/* common peripherals from bcm2835 */
70
71
- obj = OBJECT(dev);
72
- for (n = 0; n < BCM283X_NCPUS; n++) {
73
- object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
74
- s->cpu_type);
75
- object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
76
- &error_abort);
77
- }
78
-
79
obj = object_property_get_link(OBJECT(dev), "ram", &err);
80
if (obj == NULL) {
81
error_setg(errp, "%s: required ram link not found: %s",
82
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
83
}
126
}
84
127
85
static Property bcm2836_props[] = {
128
static const TypeInfo pl061_info = {
86
- DEFINE_PROP_STRING("cpu-type", BCM283XState, cpu_type),
87
DEFINE_PROP_UINT32("enabled-cpus", BCM283XState, enabled_cpus,
88
BCM283X_NCPUS),
89
DEFINE_PROP_END_OF_LIST()
90
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/hw/arm/raspi.c
93
+++ b/hw/arm/raspi.c
94
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
95
/* Setup the SOC */
96
object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(&s->ram),
97
&error_abort);
98
- object_property_set_str(OBJECT(&s->soc), machine->cpu_type, "cpu-type",
99
- &error_abort);
100
object_property_set_int(OBJECT(&s->soc), smp_cpus, "enabled-cpus",
101
&error_abort);
102
int board_rev = version == 3 ? 0xa02082 : 0xa21041;
103
--
129
--
104
2.16.2
130
2.20.1
105
131
106
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
The raspi3 has AArch64 CPUs, which means that our smpboot
1
The PL061 comes out of reset with all its lines configured as input,
2
code for keeping the secondary CPUs in a pen needs to have
2
which means they might need to be pulled to 0 or 1 depending on the
3
a version for A64 as well as A32. Without this, the
3
'pullups' and 'pulldowns' properties. Currently we do not assert
4
secondary CPUs go into an infinite loop of taking undefined
4
these lines on reset; they will only be set whenever the guest first
5
instruction exceptions.
5
touches a register that triggers a call to pl061_update().
6
7
Convert the device to three-phase reset so we have a place where we
8
can safely call qemu_set_irq() to set the floating lines to their
9
correct values.
6
10
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20180313153458.26822-10-peter.maydell@linaro.org
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
---
14
---
11
hw/arm/raspi.c | 41 ++++++++++++++++++++++++++++++++++++++++-
15
hw/gpio/pl061.c | 29 +++++++++++++++++++++++++----
12
1 file changed, 40 insertions(+), 1 deletion(-)
16
hw/gpio/trace-events | 1 +
17
2 files changed, 26 insertions(+), 4 deletions(-)
13
18
14
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
19
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/raspi.c
21
--- a/hw/gpio/pl061.c
17
+++ b/hw/arm/raspi.c
22
+++ b/hw/gpio/pl061.c
18
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ static void pl061_write(void *opaque, hwaddr offset,
19
#define BOARDSETUP_ADDR (MVBAR_ADDR + 0x20) /* board setup code */
24
return;
20
#define FIRMWARE_ADDR_2 0x8000 /* Pi 2 loads kernel.img here by default */
21
#define FIRMWARE_ADDR_3 0x80000 /* Pi 3 loads kernel.img here by default */
22
+#define SPINTABLE_ADDR 0xd8 /* Pi 3 bootloader spintable */
23
24
/* Table of Linux board IDs for different Pi versions */
25
static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44};
26
@@ -XXX,XX +XXX,XX @@ static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
27
info->smp_loader_start);
28
}
25
}
29
26
30
+static void write_smpboot64(ARMCPU *cpu, const struct arm_boot_info *info)
27
-static void pl061_reset(DeviceState *dev)
28
+static void pl061_enter_reset(Object *obj, ResetType type)
29
{
30
- PL061State *s = PL061(dev);
31
+ PL061State *s = PL061(obj);
32
+
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;
43
}
44
45
+static void pl061_hold_reset(Object *obj)
31
+{
46
+{
32
+ /* Unlike the AArch32 version we don't need to call the board setup hook.
47
+ PL061State *s = PL061(obj);
33
+ * The mechanism for doing the spin-table is also entirely different.
48
+ int i, level;
34
+ * We must have four 64-bit fields at absolute addresses
49
+ uint8_t floating = pl061_floating(s);
35
+ * 0xd8, 0xe0, 0xe8, 0xf0 in RAM, which are the flag variables for
50
+ uint8_t pullups = pl061_pullups(s);
36
+ * our CPUs, and which we must ensure are zero initialized before
37
+ * the primary CPU goes into the kernel. We put these variables inside
38
+ * a rom blob, so that the reset for ROM contents zeroes them for us.
39
+ */
40
+ static const uint32_t smpboot[] = {
41
+ 0xd2801b05, /* mov x5, 0xd8 */
42
+ 0xd53800a6, /* mrs x6, mpidr_el1 */
43
+ 0x924004c6, /* and x6, x6, #0x3 */
44
+ 0xd503205f, /* spin: wfe */
45
+ 0xf86678a4, /* ldr x4, [x5,x6,lsl #3] */
46
+ 0xb4ffffc4, /* cbz x4, spin */
47
+ 0xd2800000, /* mov x0, #0x0 */
48
+ 0xd2800001, /* mov x1, #0x0 */
49
+ 0xd2800002, /* mov x2, #0x0 */
50
+ 0xd2800003, /* mov x3, #0x0 */
51
+ 0xd61f0080, /* br x4 */
52
+ };
53
+
51
+
54
+ static const uint64_t spintables[] = {
52
+ for (i = 0; i < N_GPIOS; i++) {
55
+ 0, 0, 0, 0
53
+ if (extract32(floating, i, 1)) {
56
+ };
54
+ continue;
57
+
55
+ }
58
+ rom_add_blob_fixed("raspi_smpboot", smpboot, sizeof(smpboot),
56
+ level = extract32(pullups, i, 1);
59
+ info->smp_loader_start);
57
+ trace_pl061_set_output(DEVICE(s)->canonical_path, i, level);
60
+ rom_add_blob_fixed("raspi_spintables", spintables, sizeof(spintables),
58
+ qemu_set_irq(s->out[i], level);
61
+ SPINTABLE_ADDR);
59
+ }
60
+ s->old_out_data = pullups;
62
+}
61
+}
63
+
62
+
64
static void write_board_setup(ARMCPU *cpu, const struct arm_boot_info *info)
63
static void pl061_set_irq(void * opaque, int irq, int level)
65
{
64
{
66
arm_write_secure_board_setup_dummy_smc(cpu, info, MVBAR_ADDR);
65
PL061State *s = (PL061State *)opaque;
67
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
66
@@ -XXX,XX +XXX,XX @@ static Property pl061_props[] = {
68
/* Pi2 and Pi3 requires SMP setup */
67
static void pl061_class_init(ObjectClass *klass, void *data)
69
if (version >= 2) {
68
{
70
binfo.smp_loader_start = SMPBOOT_ADDR;
69
DeviceClass *dc = DEVICE_CLASS(klass);
71
- binfo.write_secondary_boot = write_smpboot;
70
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
72
+ if (version == 2) {
71
73
+ binfo.write_secondary_boot = write_smpboot;
72
dc->vmsd = &vmstate_pl061;
74
+ } else {
73
- dc->reset = &pl061_reset;
75
+ binfo.write_secondary_boot = write_smpboot64;
74
dc->realize = pl061_realize;
76
+ }
75
device_class_set_props(dc, pl061_props);
77
binfo.secondary_cpu_reset_hook = reset_secondary;
76
+ rc->phases.enter = pl061_enter_reset;
78
}
77
+ rc->phases.hold = pl061_hold_reset;
79
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
80
--
93
--
81
2.16.2
94
2.20.1
82
95
83
96
diff view generated by jsdifflib
1
For the rpi1 and 2 we want to boot the Linux kernel via some
1
The Luminary PL061s in the Stellaris LM3S9695 don't all have the same
2
custom setup code that makes sure that the SMC instruction
2
reset value for GPIOPUR. We can get away with not letting the board
3
acts as a no-op, because it's used for cache maintenance.
3
configure the PUR reset value because we don't actually wire anything
4
The rpi3 boots AArch64 kernels, which don't need SMC for
4
up to the lines which should reset to pull-up. Add a comment noting
5
cache maintenance and always expect to be booted non-secure.
5
this omission.
6
Don't fill in the aarch32-specific parts of the binfo struct.
7
6
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20180313153458.26822-2-peter.maydell@linaro.org
12
---
9
---
13
hw/arm/raspi.c | 17 +++++++++++++----
10
hw/gpio/pl061.c | 9 +++++++++
14
1 file changed, 13 insertions(+), 4 deletions(-)
11
1 file changed, 9 insertions(+)
15
12
16
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
13
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/raspi.c
15
--- a/hw/gpio/pl061.c
19
+++ b/hw/arm/raspi.c
16
+++ b/hw/gpio/pl061.c
20
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
17
@@ -XXX,XX +XXX,XX @@ static void pl061_enter_reset(Object *obj, ResetType type)
21
binfo.board_id = raspi_boardid[version];
18
trace_pl061_reset(DEVICE(s)->canonical_path);
22
binfo.ram_size = ram_size;
19
23
binfo.nb_cpus = smp_cpus;
20
/* reset values from PL061 TRM, Stellaris LM3S5P31 & LM3S8962 Data Sheet */
24
- binfo.board_setup_addr = BOARDSETUP_ADDR;
25
- binfo.write_board_setup = write_board_setup;
26
- binfo.secure_board_setup = true;
27
- binfo.secure_boot = true;
28
+
21
+
29
+ if (version <= 2) {
22
+ /*
30
+ /* The rpi1 and 2 require some custom setup code to run in Secure
23
+ * FIXME: For the LM3S6965, not all of the PL061 instances have the
31
+ * mode before booting a kernel (to set up the SMC vectors so
24
+ * same reset values for GPIOPUR, GPIOAFSEL and GPIODEN, so in theory
32
+ * that we get a no-op SMC; this is used by Linux to call the
25
+ * we should allow the board to configure these via properties.
33
+ * firmware for some cache maintenance operations.
26
+ * In practice, we don't wire anything up to the affected GPIO lines
34
+ * The rpi3 doesn't need this.
27
+ * (PB7, PC0, PC1, PC2, PC3 -- they're used for JTAG), so we can
35
+ */
28
+ * get away with this inaccuracy.
36
+ binfo.board_setup_addr = BOARDSETUP_ADDR;
29
+ */
37
+ binfo.write_board_setup = write_board_setup;
30
s->data = 0;
38
+ binfo.secure_board_setup = true;
31
s->old_in_data = 0;
39
+ binfo.secure_boot = true;
32
s->dir = 0;
40
+ }
41
42
/* Pi2 and Pi3 requires SMP setup */
43
if (version >= 2) {
44
--
33
--
45
2.16.2
34
2.20.1
46
35
47
36
diff view generated by jsdifflib
1
The bcm2837 is pretty similar to the bcm2836, but it does have
1
The stellaris board doesn't emulate the handling of the OLED
2
some differences. Notably, the MPIDR affinity aff1 values it
2
chipselect line correctly. Expand the comment describing this,
3
sets for the CPUs are 0x0, rather than the 0xf that the bcm2836
3
including a sketch of the theoretical correct way to do it.
4
uses, and if this is wrong Linux will not boot.
5
6
Rather than trying to have one device with properties that
7
configure it differently for the two cases, create two
8
separate QOM devices for the two SoCs. We use the same approach
9
as hw/arm/aspeed_soc.c and share code and have a data table
10
that might differ per-SoC. For the moment the two types don't
11
actually have different behaviour.
12
4
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Message-id: 20180313153458.26822-7-peter.maydell@linaro.org
16
---
6
---
17
include/hw/arm/bcm2836.h | 19 +++++++++++++++++++
7
hw/arm/stellaris.c | 56 +++++++++++++++++++++++++++++++++++++++++++++-
18
hw/arm/bcm2836.c | 37 ++++++++++++++++++++++++++++++++-----
8
1 file changed, 55 insertions(+), 1 deletion(-)
19
hw/arm/raspi.c | 3 ++-
20
3 files changed, 53 insertions(+), 6 deletions(-)
21
9
22
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
10
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
23
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/arm/bcm2836.h
12
--- a/hw/arm/stellaris.c
25
+++ b/include/hw/arm/bcm2836.h
13
+++ b/hw/arm/stellaris.c
26
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
27
15
DeviceState *sddev;
28
#define BCM283X_NCPUS 4
16
DeviceState *ssddev;
29
17
30
+/* These type names are for specific SoCs; other than instantiating
18
- /* Some boards have both an OLED controller and SD card connected to
31
+ * them, code using these devices should always handle them via the
19
+ /*
32
+ * BCM283x base class, so they have no BCM2836(obj) etc macros.
20
+ * Some boards have both an OLED controller and SD card connected to
33
+ */
21
* the same SSI port, with the SD card chip select connected to a
34
+#define TYPE_BCM2836 "bcm2836"
22
* GPIO pin. Technically the OLED chip select is connected to the
35
+#define TYPE_BCM2837 "bcm2837"
23
* SSI Fss pin. We do not bother emulating that as both devices
36
+
24
* should never be selected simultaneously, and our OLED controller
37
typedef struct BCM283XState {
25
* ignores stray 0xff commands that occur when deselecting the SD
38
/*< private >*/
26
* card.
39
DeviceState parent_obj;
27
+ *
40
@@ -XXX,XX +XXX,XX @@ typedef struct BCM283XState {
28
+ * The h/w wiring is:
41
BCM2835PeripheralState peripherals;
29
+ * - GPIO pin D0 is wired to the active-low SD card chip select
42
} BCM283XState;
30
+ * - GPIO pin A3 is wired to the active-low OLED chip select
43
31
+ * - The SoC wiring of the PL061 "auxiliary function" for A3 is
44
+typedef struct BCM283XInfo BCM283XInfo;
32
+ * SSI0Fss ("frame signal"), which is an output from the SoC's
45
+
33
+ * SSI controller. The SSI controller takes SSI0Fss low when it
46
+typedef struct BCM283XClass {
34
+ * transmits a frame, so it can work as a chip-select signal.
47
+ DeviceClass parent_class;
35
+ * - GPIO A4 is aux-function SSI0Rx, and wired to the SD card Tx
48
+ const BCM283XInfo *info;
36
+ * (the OLED never sends data to the CPU, so no wiring needed)
49
+} BCM283XClass;
37
+ * - GPIO A5 is aux-function SSI0Tx, and wired to the SD card Rx
50
+
38
+ * and the OLED display-data-in
51
+#define BCM283X_CLASS(klass) \
39
+ * - GPIO A2 is aux-function SSI0Clk, wired to SD card and OLED
52
+ OBJECT_CLASS_CHECK(BCM283XClass, (klass), TYPE_BCM283X)
40
+ * serial-clock input
53
+#define BCM283X_GET_CLASS(obj) \
41
+ * So a guest that wants to use the OLED can configure the PL061
54
+ OBJECT_GET_CLASS(BCM283XClass, (obj), TYPE_BCM283X)
42
+ * to make pins A2, A3, A5 aux-function, so they are connected
55
+
43
+ * directly to the SSI controller. When the SSI controller sends
56
#endif /* BCM2836_H */
44
+ * data it asserts SSI0Fss which selects the OLED.
57
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
45
+ * A guest that wants to use the SD card configures A2, A4 and A5
58
index XXXXXXX..XXXXXXX 100644
46
+ * as aux-function, but leaves A3 as a software-controlled GPIO
59
--- a/hw/arm/bcm2836.c
47
+ * line. It asserts the SD card chip-select by using the PL061
60
+++ b/hw/arm/bcm2836.c
48
+ * to control pin D0, and lets the SSI controller handle Clk, Tx
61
@@ -XXX,XX +XXX,XX @@
49
+ * and Rx. (The SSI controller asserts Fss during tx cycles as
62
/* "QA7" (Pi2) interrupt controller and mailboxes etc. */
50
+ * usual, but because A3 is not set to aux-function this is not
63
#define BCM2836_CONTROL_BASE 0x40000000
51
+ * forwarded to the OLED, and so the OLED stays unselected.)
64
52
+ *
65
+struct BCM283XInfo {
53
+ * The QEMU implementation instead is:
66
+ const char *name;
54
+ * - GPIO pin D0 is wired to the active-low SD card chip select,
67
+};
55
+ * and also to the OLED chip-select which is implemented
68
+
56
+ * as *active-high*
69
+static const BCM283XInfo bcm283x_socs[] = {
57
+ * - SSI controller signals go to the devices regardless of
70
+ {
58
+ * whether the guest programs A2, A4, A5 as aux-function or not
71
+ .name = TYPE_BCM2836,
59
+ *
72
+ },
60
+ * The problem with this implementation is if the guest doesn't
73
+ {
61
+ * care about the SD card and only uses the OLED. In that case it
74
+ .name = TYPE_BCM2837,
62
+ * may choose never to do anything with D0 (leaving it in its
75
+ },
63
+ * default floating state, which reliably leaves the card disabled
76
+};
64
+ * because an SD card has a pullup on CS within the card itself),
77
+
65
+ * and only set up A2, A3, A5. This for us would mean the OLED
78
static void bcm2836_init(Object *obj)
66
+ * never gets the chip-select assert it needs. We work around
79
{
67
+ * this with a manual raise of D0 here (despite board creation
80
BCM283XState *s = BCM283X(obj);
68
+ * code being the wrong place to raise IRQ lines) to put the OLED
81
@@ -XXX,XX +XXX,XX @@ static Property bcm2836_props[] = {
69
+ * into an initially selected state.
82
DEFINE_PROP_END_OF_LIST()
70
+ *
83
};
71
+ * In theory the right way to model this would be:
84
72
+ * - Implement aux-function support in the PL061, with an
85
-static void bcm2836_class_init(ObjectClass *oc, void *data)
73
+ * extra set of AFIN and AFOUT GPIO lines (set up so that
86
+static void bcm283x_class_init(ObjectClass *oc, void *data)
74
+ * if a GPIO line is in auxfn mode the main GPIO in and out
87
{
75
+ * track the AFIN and AFOUT lines)
88
DeviceClass *dc = DEVICE_CLASS(oc);
76
+ * - Wire the AFOUT for D0 up to either a line from the
89
+ BCM283XClass *bc = BCM283X_CLASS(oc);
77
+ * SSI controller that's pulled low around every transmit,
90
78
+ * or at least to an always-0 line here on the board
91
- dc->props = bcm2836_props;
79
+ * - Make the ssd0323 OLED controller chipselect active-low
92
+ bc->info = data;
80
*/
93
dc->realize = bcm2836_realize;
81
bus = qdev_get_child_bus(dev, "ssi");
94
+ dc->props = bcm2836_props;
95
}
96
97
-static const TypeInfo bcm2836_type_info = {
98
+static const TypeInfo bcm283x_type_info = {
99
.name = TYPE_BCM283X,
100
.parent = TYPE_DEVICE,
101
.instance_size = sizeof(BCM283XState),
102
.instance_init = bcm2836_init,
103
- .class_init = bcm2836_class_init,
104
+ .class_size = sizeof(BCM283XClass),
105
+ .abstract = true,
106
};
107
108
static void bcm2836_register_types(void)
109
{
110
- type_register_static(&bcm2836_type_info);
111
+ int i;
112
+
113
+ type_register_static(&bcm283x_type_info);
114
+ for (i = 0; i < ARRAY_SIZE(bcm283x_socs); i++) {
115
+ TypeInfo ti = {
116
+ .name = bcm283x_socs[i].name,
117
+ .parent = TYPE_BCM283X,
118
+ .class_init = bcm283x_class_init,
119
+ .class_data = (void *) &bcm283x_socs[i],
120
+ };
121
+ type_register(&ti);
122
+ }
123
}
124
125
type_init(bcm2836_register_types)
126
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/hw/arm/raspi.c
129
+++ b/hw/arm/raspi.c
130
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
131
BusState *bus;
132
DeviceState *carddev;
133
134
- object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM283X);
135
+ object_initialize(&s->soc, sizeof(s->soc),
136
+ version == 3 ? TYPE_BCM2837 : TYPE_BCM2836);
137
object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
138
&error_abort);
139
82
140
--
83
--
141
2.16.2
84
2.20.1
142
85
143
86
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
From: "hnick@vmware.com" <hnick@vmware.com>
2
2
3
The sabrelite machine model used by qemu-system-arm is based on the
3
Signed-off-by: Nick Hudson <hnick@vmware.com>
4
Freescale/NXP i.MX6Q processor. This SoC has an on-board ethernet
5
controller which is supported in QEMU using the imx_fec.c module
6
(actually called imx.enet for this model.)
7
8
The include/hw/arm/fsm-imx6.h file defines the interrupt vectors for the
9
imx.enet device like this:
10
11
#define FSL_IMX6_ENET_MAC_1588_IRQ 118
12
#define FSL_IMX6_ENET_MAC_IRQ 119
13
14
According to https://www.nxp.com/docs/en/reference-manual/IMX6DQRM.pdf,
15
page 225, in Table 3-1. ARM Cortex A9 domain interrupt summary,
16
interrupts are as follows.
17
18
150 ENET MAC 0 IRQ
19
151 ENET MAC 0 1588 Timer interrupt
20
21
where
22
23
150 - 32 == 118
24
151 - 32 == 119
25
26
In other words, the vector definitions in the fsl-imx6.h file are reversed.
27
28
Fixing the interrupts alone causes problems with older Linux kernels:
29
The Ethernet interface will fail to probe with Linux v4.9 and earlier.
30
Linux v4.1 and earlier will crash due to a bug in Ethernet driver probe
31
error handling. This is a Linux kernel problem, not a qemu problem:
32
the Linux kernel only worked by accident since it requested both interrupts.
33
34
For backward compatibility, generate the Ethernet interrupt on both interrupt
35
lines. This was shown to work from all Linux kernel releases starting with
36
v3.16.
37
38
Link: https://bugs.launchpad.net/qemu/+bug/1753309
39
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
40
Message-id: 1520723090-22130-1-git-send-email-linux@roeck-us.net
41
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
42
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
43
---
6
---
44
include/hw/arm/fsl-imx6.h | 4 ++--
7
target/arm/helper.c | 16 +++++++++++++---
45
hw/net/imx_fec.c | 28 +++++++++++++++++++++++++++-
8
1 file changed, 13 insertions(+), 3 deletions(-)
46
2 files changed, 29 insertions(+), 3 deletions(-)
47
9
48
diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h
10
diff --git a/target/arm/helper.c b/target/arm/helper.c
49
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
50
--- a/include/hw/arm/fsl-imx6.h
12
--- a/target/arm/helper.c
51
+++ b/include/hw/arm/fsl-imx6.h
13
+++ b/target/arm/helper.c
52
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX6State {
14
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
53
#define FSL_IMX6_HDMI_MASTER_IRQ 115
15
.access = PL1_RW, .accessfn = access_tda,
54
#define FSL_IMX6_HDMI_CEC_IRQ 116
16
.fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1),
55
#define FSL_IMX6_MLB150_LOW_IRQ 117
17
.resetvalue = 0 },
56
-#define FSL_IMX6_ENET_MAC_1588_IRQ 118
18
- /* MDCCSR_EL0, aka DBGDSCRint. This is a read-only mirror of MDSCR_EL1.
57
-#define FSL_IMX6_ENET_MAC_IRQ 119
58
+#define FSL_IMX6_ENET_MAC_IRQ 118
59
+#define FSL_IMX6_ENET_MAC_1588_IRQ 119
60
#define FSL_IMX6_PCIE1_IRQ 120
61
#define FSL_IMX6_PCIE2_IRQ 121
62
#define FSL_IMX6_PCIE3_IRQ 122
63
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/net/imx_fec.c
66
+++ b/hw/net/imx_fec.c
67
@@ -XXX,XX +XXX,XX @@ static void imx_enet_write_bd(IMXENETBufDesc *bd, dma_addr_t addr)
68
69
static void imx_eth_update(IMXFECState *s)
70
{
71
- if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] & ENET_INT_TS_TIMER) {
72
+ /*
19
+ /*
73
+ * Previous versions of qemu had the ENET_INT_MAC and ENET_INT_TS_TIMER
20
+ * MDCCSR_EL0[30:29] map to EDSCR[30:29]. Simply RAZ as the external
74
+ * interrupts swapped. This worked with older versions of Linux (4.14
21
+ * Debug Communication Channel is not implemented.
75
+ * and older) since Linux associated both interrupt lines with Ethernet
76
+ * MAC interrupts. Specifically,
77
+ * - Linux 4.15 and later have separate interrupt handlers for the MAC and
78
+ * timer interrupts. Those versions of Linux fail with versions of QEMU
79
+ * with swapped interrupt assignments.
80
+ * - In linux 4.14, both interrupt lines were registered with the Ethernet
81
+ * MAC interrupt handler. As a result, all versions of qemu happen to
82
+ * work, though that is accidental.
83
+ * - In Linux 4.9 and older, the timer interrupt was registered directly
84
+ * with the Ethernet MAC interrupt handler. The MAC interrupt was
85
+ * redirected to a GPIO interrupt to work around erratum ERR006687.
86
+ * This was implemented using the SOC's IOMUX block. In qemu, this GPIO
87
+ * interrupt never fired since IOMUX is currently not supported in qemu.
88
+ * Linux instead received MAC interrupts on the timer interrupt.
89
+ * As a result, qemu versions with the swapped interrupt assignment work,
90
+ * albeit accidentally, but qemu versions with the correct interrupt
91
+ * assignment fail.
92
+ *
93
+ * To ensure that all versions of Linux work, generate ENET_INT_MAC
94
+ * interrrupts on both interrupt lines. This should be changed if and when
95
+ * qemu supports IOMUX.
96
+ */
22
+ */
97
+ if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] &
23
+ { .name = "MDCCSR_EL0", .state = ARM_CP_STATE_AA64,
98
+ (ENET_INT_MAC | ENET_INT_TS_TIMER)) {
24
+ .opc0 = 2, .opc1 = 3, .crn = 0, .crm = 1, .opc2 = 0,
99
qemu_set_irq(s->irq[1], 1);
25
+ .access = PL0_R, .accessfn = access_tda,
100
} else {
26
+ .type = ARM_CP_CONST, .resetvalue = 0 },
101
qemu_set_irq(s->irq[1], 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), },
102
--
39
--
103
2.16.2
40
2.20.1
104
41
105
42
diff view generated by jsdifflib
1
From: Wei Huang <wei@redhat.com>
1
From: Rebecca Cran <rebecca@nuviainc.com>
2
2
3
For guest kernel that supports KASLR, the load address can change every
3
Add a space in the message printed when gicr_read*/gicr_write* returns
4
time when guest VM runs. To find the physical base address correctly,
4
MEMTX_ERROR in arm_gicv3_redist.c.
5
current QEMU dump searches VMCOREINFO for the string "NUMBER(phys_base)=".
6
However this string pattern is only available on x86_64. AArch64 uses a
7
different field, called "NUMBER(PHYS_OFFSET)=". This patch makes sure
8
QEMU dump uses the correct string on AArch64.
9
5
10
Signed-off-by: Wei Huang <wei@redhat.com>
6
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
11
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Message-id: 1520615003-20869-1-git-send-email-wei@redhat.com
8
Message-id: 20210706211432.31902-1-rebecca@nuviainc.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
10
---
15
dump.c | 14 +++++++++++---
11
hw/intc/arm_gicv3_redist.c | 4 ++--
16
1 file changed, 11 insertions(+), 3 deletions(-)
12
1 file changed, 2 insertions(+), 2 deletions(-)
17
13
18
diff --git a/dump.c b/dump.c
14
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/dump.c
16
--- a/hw/intc/arm_gicv3_redist.c
21
+++ b/dump.c
17
+++ b/hw/intc/arm_gicv3_redist.c
22
@@ -XXX,XX +XXX,XX @@ static void vmcoreinfo_update_phys_base(DumpState *s)
18
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data,
23
19
if (r == MEMTX_ERROR) {
24
lines = g_strsplit((char *)vmci, "\n", -1);
20
qemu_log_mask(LOG_GUEST_ERROR,
25
for (i = 0; lines[i]; i++) {
21
"%s: invalid guest read at offset " TARGET_FMT_plx
26
- if (g_str_has_prefix(lines[i], "NUMBER(phys_base)=")) {
22
- "size %u\n", __func__, offset, size);
27
- if (qemu_strtou64(lines[i] + 18, NULL, 16,
23
+ " size %u\n", __func__, offset, size);
28
+ const char *prefix = NULL;
24
trace_gicv3_redist_badread(gicv3_redist_affid(cs), offset,
29
+
25
size, attrs.secure);
30
+ if (s->dump_info.d_machine == EM_X86_64) {
26
/* The spec requires that reserved registers are RAZ/WI;
31
+ prefix = "NUMBER(phys_base)=";
27
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
32
+ } else if (s->dump_info.d_machine == EM_AARCH64) {
28
if (r == MEMTX_ERROR) {
33
+ prefix = "NUMBER(PHYS_OFFSET)=";
29
qemu_log_mask(LOG_GUEST_ERROR,
34
+ }
30
"%s: invalid guest write at offset " TARGET_FMT_plx
35
+
31
- "size %u\n", __func__, offset, size);
36
+ if (prefix && g_str_has_prefix(lines[i], prefix)) {
32
+ " size %u\n", __func__, offset, size);
37
+ if (qemu_strtou64(lines[i] + strlen(prefix), NULL, 16,
33
trace_gicv3_redist_badwrite(gicv3_redist_affid(cs), offset, data,
38
&phys_base) < 0) {
34
size, attrs.secure);
39
- warn_report("Failed to read NUMBER(phys_base)=");
35
/* The spec requires that reserved registers are RAZ/WI;
40
+ warn_report("Failed to read %s", prefix);
41
} else {
42
s->dump_info.phys_base = phys_base;
43
}
44
--
36
--
45
2.16.2
37
2.20.1
46
38
47
39
diff view generated by jsdifflib