1
Arm patch queue -- these are all bug fix patches but we might
1
A mixed bag, all bug fixes or similar small stuff.
2
as well put them in to rc0...
3
2
4
thanks
3
thanks
5
-- PMM
4
-- PMM
6
5
7
The following changes since commit 2c8cfc0b52b5a4d123c26c0b5fdf941be24805be:
8
6
9
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2018-03-19 11:44:26 +0000)
7
The following changes since commit 19eb2d4e736dc895f31fbd6b520e514f10cc08e0:
8
9
Merge remote-tracking branch 'remotes/thibault/tags/samuel-thibault' into staging (2019-05-07 10:43:32 +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-20190507
14
14
15
for you to fetch changes up to ff72cb6b46b95bb530787add5277c211af3d31c6:
15
for you to fetch changes up to 63159601fb3e396b28da14cbb71e50ed3f5a0331:
16
16
17
hw/arm/raspi: Provide spin-loop code for AArch64 CPUs (2018-03-19 18:23:24 +0000)
17
target/arm: Stop using variable length array in dc_zva (2019-05-07 12:55:04 +0100)
18
18
19
----------------------------------------------------------------
19
----------------------------------------------------------------
20
target-arm queue:
20
target-arm queue:
21
* fsl-imx6: Fix incorrect Ethernet interrupt defines
21
* Stop using variable length array in dc_zva
22
* dump: Update correct kdump phys_base field for AArch64
22
* Implement M-profile XPSR GE bits
23
* char: i.MX: Add support for "TX complete" interrupt
23
* Don't enable ARMV7M_EXCP_DEBUG from reset
24
* bcm2836/raspi: Fix various bugs resulting in panics trying
24
* armv7m_nvic: NS BFAR and BFSR are RAZ/WI if BFHFNMINS == 0
25
to boot a Debian Linux kernel on raspi3
25
* armv7m_nvic: Check subpriority in nvic_recompute_state_secure()
26
* fix various minor issues to allow building for Windows-on-ARM64
27
* aspeed: Set SDRAM size
28
* Allow system registers for KVM guests to be changed by QEMU code
29
* raspi: Diagnose requests for too much RAM
30
* virt: Support firmware configuration with -blockdev
26
31
27
----------------------------------------------------------------
32
----------------------------------------------------------------
28
Andrey Smirnov (2):
33
Cao Jiaxi (4):
29
char: i.MX: Simplify imx_update()
34
QEMU_PACKED: Remove gcc_struct attribute in Windows non x86 targets
30
char: i.MX: Add support for "TX complete" interrupt
35
qga: Fix mingw compilation warnings on enum conversion
36
util/cacheinfo: Use uint64_t on LLP64 model to satisfy Windows ARM64
37
osdep: Fix mingw compilation regarding stdio formats
31
38
32
Guenter Roeck (1):
39
Joel Stanley (1):
33
fsl-imx6: Swap Ethernet interrupt defines
40
arm: aspeed: Set SDRAM size
34
41
35
Peter Maydell (9):
42
Markus Armbruster (3):
36
hw/arm/raspi: Don't do board-setup or secure-boot for raspi3
43
pc: Rearrange pc_system_firmware_init()'s legacy -drive loop
37
hw/arm/boot: assert that secure_boot and secure_board_setup are false for AArch64
44
pflash_cfi01: New pflash_cfi01_legacy_drive()
38
hw/arm/boot: If booting a kernel in EL2, set SCR_EL3.HCE
45
hw/arm/virt: Support firmware configuration with -blockdev
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
46
46
Wei Huang (1):
47
Peter Maydell (7):
47
dump: Update correct kdump phys_base field for AArch64
48
hw/arm/raspi: Diagnose requests for too much RAM
49
arm: Allow system registers for KVM guests to be changed by QEMU code
50
hw/arm/armv7m_nvic: Check subpriority in nvic_recompute_state_secure()
51
hw/intc/armv7m_nvic: NS BFAR and BFSR are RAZ/WI if BFHFNMINS == 0
52
hw/intc/armv7m_nvic: Don't enable ARMV7M_EXCP_DEBUG from reset
53
target/arm: Implement XPSR GE bits
54
target/arm: Stop using variable length array in dc_zva
48
55
49
include/hw/arm/bcm2836.h | 31 +++++++++++++---
56
contrib/libvhost-user/libvhost-user.h | 2 +-
50
include/hw/arm/fsl-imx6.h | 4 +-
57
include/hw/arm/aspeed.h | 1 +
51
include/hw/char/imx_serial.h | 3 ++
58
include/hw/arm/virt.h | 2 +
52
dump.c | 14 +++++--
59
include/hw/block/flash.h | 1 +
53
hw/arm/bcm2836.c | 87 +++++++++++++++++++++++++++++++-------------
60
include/qemu/compiler.h | 2 +-
54
hw/arm/boot.c | 12 ++++++
61
include/qemu/osdep.h | 10 +-
55
hw/arm/raspi.c | 77 +++++++++++++++++++++++++++++++--------
62
scripts/cocci-macro-file.h | 7 +-
56
hw/char/imx_serial.c | 44 ++++++++++++++++------
63
target/arm/cpu.h | 13 ++-
57
hw/net/imx_fec.c | 28 +++++++++++++-
64
hw/arm/aspeed.c | 8 ++
58
9 files changed, 237 insertions(+), 63 deletions(-)
65
hw/arm/raspi.c | 7 ++
66
hw/arm/virt.c | 202 ++++++++++++++++++++++------------
67
hw/block/pflash_cfi01.c | 28 +++++
68
hw/i386/pc_sysfw.c | 18 +--
69
hw/intc/armv7m_nvic.c | 40 ++++++-
70
qga/commands-win32.c | 2 +-
71
target/arm/helper.c | 47 +++++++-
72
target/arm/kvm.c | 8 ++
73
target/arm/kvm32.c | 20 +---
74
target/arm/kvm64.c | 2 +
75
target/arm/machine.c | 2 +-
76
util/cacheinfo.c | 2 +-
77
21 files changed, 294 insertions(+), 130 deletions(-)
59
78
diff view generated by jsdifflib
New patch
1
From: Markus Armbruster <armbru@redhat.com>
1
2
3
The loop does two things: map legacy -drive to properties, and collect
4
all the backends for use after the loop. The next patch will factor
5
out the former for reuse in hw/arm/virt.c. To make that easier,
6
rearrange the loop so it does the first thing first, and the second
7
thing second.
8
9
Signed-off-by: Markus Armbruster <armbru@redhat.com>
10
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Message-id: 20190416091348.26075-2-armbru@redhat.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/i386/pc_sysfw.c | 24 +++++++++++-------------
16
1 file changed, 11 insertions(+), 13 deletions(-)
17
18
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/i386/pc_sysfw.c
21
+++ b/hw/i386/pc_sysfw.c
22
@@ -XXX,XX +XXX,XX @@ void pc_system_firmware_init(PCMachineState *pcms,
23
24
/* Map legacy -drive if=pflash to machine properties */
25
for (i = 0; i < ARRAY_SIZE(pcms->flash); i++) {
26
- pflash_blk[i] = pflash_cfi01_get_blk(pcms->flash[i]);
27
pflash_drv = drive_get(IF_PFLASH, 0, i);
28
- if (!pflash_drv) {
29
- continue;
30
+ if (pflash_drv) {
31
+ loc_push_none(&loc);
32
+ qemu_opts_loc_restore(pflash_drv->opts);
33
+ if (pflash_cfi01_get_blk(pcms->flash[i])) {
34
+ error_report("clashes with -machine");
35
+ exit(1);
36
+ }
37
+ qdev_prop_set_drive(DEVICE(pcms->flash[i]), "drive",
38
+ blk_by_legacy_dinfo(pflash_drv), &error_fatal);
39
+ loc_pop(&loc);
40
}
41
- loc_push_none(&loc);
42
- qemu_opts_loc_restore(pflash_drv->opts);
43
- if (pflash_blk[i]) {
44
- error_report("clashes with -machine");
45
- exit(1);
46
- }
47
- pflash_blk[i] = blk_by_legacy_dinfo(pflash_drv);
48
- qdev_prop_set_drive(DEVICE(pcms->flash[i]),
49
- "drive", pflash_blk[i], &error_fatal);
50
- loc_pop(&loc);
51
+ pflash_blk[i] = pflash_cfi01_get_blk(pcms->flash[i]);
52
}
53
54
/* Reject gaps */
55
--
56
2.20.1
57
58
diff view generated by jsdifflib
1
The raspi3 has AArch64 CPUs, which means that our smpboot
1
From: Markus Armbruster <armbru@redhat.com>
2
code for keeping the secondary CPUs in a pen needs to have
3
a version for A64 as well as A32. Without this, the
4
secondary CPUs go into an infinite loop of taking undefined
5
instruction exceptions.
6
2
3
Factored out of pc_system_firmware_init() so the next commit can reuse
4
it in hw/arm/virt.c.
5
6
Signed-off-by: Markus Armbruster <armbru@redhat.com>
7
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20190416091348.26075-3-armbru@redhat.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20180313153458.26822-10-peter.maydell@linaro.org
10
---
11
---
11
hw/arm/raspi.c | 41 ++++++++++++++++++++++++++++++++++++++++-
12
include/hw/block/flash.h | 1 +
12
1 file changed, 40 insertions(+), 1 deletion(-)
13
hw/block/pflash_cfi01.c | 28 ++++++++++++++++++++++++++++
14
hw/i386/pc_sysfw.c | 16 ++--------------
15
3 files changed, 31 insertions(+), 14 deletions(-)
13
16
14
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
17
diff --git a/include/hw/block/flash.h b/include/hw/block/flash.h
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/raspi.c
19
--- a/include/hw/block/flash.h
17
+++ b/hw/arm/raspi.c
20
+++ b/include/hw/block/flash.h
21
@@ -XXX,XX +XXX,XX @@ PFlashCFI01 *pflash_cfi01_register(hwaddr base,
22
int be);
23
BlockBackend *pflash_cfi01_get_blk(PFlashCFI01 *fl);
24
MemoryRegion *pflash_cfi01_get_memory(PFlashCFI01 *fl);
25
+void pflash_cfi01_legacy_drive(PFlashCFI01 *dev, DriveInfo *dinfo);
26
27
/* pflash_cfi02.c */
28
29
diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/block/pflash_cfi01.c
32
+++ b/hw/block/pflash_cfi01.c
18
@@ -XXX,XX +XXX,XX @@
33
@@ -XXX,XX +XXX,XX @@
19
#define BOARDSETUP_ADDR (MVBAR_ADDR + 0x20) /* board setup code */
34
#include "qapi/error.h"
20
#define FIRMWARE_ADDR_2 0x8000 /* Pi 2 loads kernel.img here by default */
35
#include "qemu/timer.h"
21
#define FIRMWARE_ADDR_3 0x80000 /* Pi 3 loads kernel.img here by default */
36
#include "qemu/bitops.h"
22
+#define SPINTABLE_ADDR 0xd8 /* Pi 3 bootloader spintable */
37
+#include "qemu/error-report.h"
23
38
#include "qemu/host-utils.h"
24
/* Table of Linux board IDs for different Pi versions */
39
#include "qemu/log.h"
25
static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44};
40
+#include "qemu/option.h"
26
@@ -XXX,XX +XXX,XX @@ static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
41
#include "hw/sysbus.h"
27
info->smp_loader_start);
42
+#include "sysemu/blockdev.h"
43
#include "sysemu/sysemu.h"
44
#include "trace.h"
45
46
@@ -XXX,XX +XXX,XX @@ MemoryRegion *pflash_cfi01_get_memory(PFlashCFI01 *fl)
47
return &fl->mem;
28
}
48
}
29
49
30
+static void write_smpboot64(ARMCPU *cpu, const struct arm_boot_info *info)
50
+/*
51
+ * Handle -drive if=pflash for machines that use properties.
52
+ * If @dinfo is null, do nothing.
53
+ * Else if @fl's property "drive" is already set, fatal error.
54
+ * Else set it to the BlockBackend with @dinfo.
55
+ */
56
+void pflash_cfi01_legacy_drive(PFlashCFI01 *fl, DriveInfo *dinfo)
31
+{
57
+{
32
+ /* Unlike the AArch32 version we don't need to call the board setup hook.
58
+ Location loc;
33
+ * The mechanism for doing the spin-table is also entirely different.
34
+ * We must have four 64-bit fields at absolute addresses
35
+ * 0xd8, 0xe0, 0xe8, 0xf0 in RAM, which are the flag variables for
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
+
59
+
54
+ static const uint64_t spintables[] = {
60
+ if (!dinfo) {
55
+ 0, 0, 0, 0
61
+ return;
56
+ };
62
+ }
57
+
63
+
58
+ rom_add_blob_fixed("raspi_smpboot", smpboot, sizeof(smpboot),
64
+ loc_push_none(&loc);
59
+ info->smp_loader_start);
65
+ qemu_opts_loc_restore(dinfo->opts);
60
+ rom_add_blob_fixed("raspi_spintables", spintables, sizeof(spintables),
66
+ if (fl->blk) {
61
+ SPINTABLE_ADDR);
67
+ error_report("clashes with -machine");
68
+ exit(1);
69
+ }
70
+ qdev_prop_set_drive(DEVICE(fl), "drive",
71
+ blk_by_legacy_dinfo(dinfo), &error_fatal);
72
+ loc_pop(&loc);
62
+}
73
+}
63
+
74
+
64
static void write_board_setup(ARMCPU *cpu, const struct arm_boot_info *info)
75
static void postload_update_cb(void *opaque, int running, RunState state)
65
{
76
{
66
arm_write_secure_board_setup_dummy_smc(cpu, info, MVBAR_ADDR);
77
PFlashCFI01 *pfl = opaque;
67
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
78
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
68
/* Pi2 and Pi3 requires SMP setup */
79
index XXXXXXX..XXXXXXX 100644
69
if (version >= 2) {
80
--- a/hw/i386/pc_sysfw.c
70
binfo.smp_loader_start = SMPBOOT_ADDR;
81
+++ b/hw/i386/pc_sysfw.c
71
- binfo.write_secondary_boot = write_smpboot;
82
@@ -XXX,XX +XXX,XX @@ void pc_system_firmware_init(PCMachineState *pcms,
72
+ if (version == 2) {
83
{
73
+ binfo.write_secondary_boot = write_smpboot;
84
PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
74
+ } else {
85
int i;
75
+ binfo.write_secondary_boot = write_smpboot64;
86
- DriveInfo *pflash_drv;
76
+ }
87
BlockBackend *pflash_blk[ARRAY_SIZE(pcms->flash)];
77
binfo.secondary_cpu_reset_hook = reset_secondary;
88
- Location loc;
89
90
if (!pcmc->pci_enabled) {
91
old_pc_system_rom_init(rom_memory, true);
92
@@ -XXX,XX +XXX,XX @@ void pc_system_firmware_init(PCMachineState *pcms,
93
94
/* Map legacy -drive if=pflash to machine properties */
95
for (i = 0; i < ARRAY_SIZE(pcms->flash); i++) {
96
- pflash_drv = drive_get(IF_PFLASH, 0, i);
97
- if (pflash_drv) {
98
- loc_push_none(&loc);
99
- qemu_opts_loc_restore(pflash_drv->opts);
100
- if (pflash_cfi01_get_blk(pcms->flash[i])) {
101
- error_report("clashes with -machine");
102
- exit(1);
103
- }
104
- qdev_prop_set_drive(DEVICE(pcms->flash[i]), "drive",
105
- blk_by_legacy_dinfo(pflash_drv), &error_fatal);
106
- loc_pop(&loc);
107
- }
108
+ pflash_cfi01_legacy_drive(pcms->flash[i],
109
+ drive_get(IF_PFLASH, 0, i));
110
pflash_blk[i] = pflash_cfi01_get_blk(pcms->flash[i]);
78
}
111
}
79
112
80
--
113
--
81
2.16.2
114
2.20.1
82
115
83
116
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Markus Armbruster <armbru@redhat.com>
2
2
3
Add support for "TX complete"/TXDC interrupt generate by real HW since
3
The ARM virt machines put firmware in flash memory. To configure it,
4
it is needed to support guests other than Linux.
4
you use -drive if=pflash,unit=0,... and optionally -drive
5
5
if=pflash,unit=1,...
6
Based on the patch by Bill Paul as found here:
6
7
https://bugs.launchpad.net/qemu/+bug/1753314
7
Why two -drive? This permits setting up one part of the flash memory
8
8
read-only, and the other part read/write. It also makes upgrading
9
Cc: qemu-devel@nongnu.org
9
firmware on the host easier. Below the hood, we get two separate
10
Cc: qemu-arm@nongnu.org
10
flash devices, because we were too lazy to improve our flash device
11
Cc: Bill Paul <wpaul@windriver.com>
11
models to support sector protection.
12
Cc: Peter Maydell <peter.maydell@linaro.org>
12
13
Signed-off-by: Bill Paul <wpaul@windriver.com>
13
The problem at hand is to do the same with -blockdev somehow, as one
14
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
14
more step towards deprecating -drive.
15
Message-id: 20180315191141.6789-2-andrew.smirnov@gmail.com
15
16
We recently solved this problem for x86 PC machines, in commit
17
ebc29e1beab. See the commit message for design rationale.
18
19
This commit solves it for ARM virt basically the same way: new machine
20
properties pflash0, pflash1 forward to the onboard flash devices'
21
properties. Requires creating the onboard devices in the
22
.instance_init() method virt_instance_init(). The existing code to
23
pick up drives defined with -drive if=pflash is replaced by code to
24
desugar into the machine properties.
25
26
There are a few behavioral differences, though:
27
28
* The flash devices are always present (x86: only present if
29
configured)
30
31
* Flash base addresses and sizes are fixed (x86: sizes depend on
32
images, mapped back to back below a fixed address)
33
34
* -bios configures contents of first pflash (x86: -bios configures ROM
35
contents)
36
37
* -bios is rejected when first pflash is also configured with -machine
38
pflash0=... (x86: bios is silently ignored then)
39
40
* -machine pflash1=... does not require -machine pflash0=... (x86: it
41
does).
42
43
The actual code is a bit simpler than for x86 mostly due to the first
44
two differences.
45
46
Before the patch, all the action is in create_flash(), called from the
47
machine's .init() method machvirt_init():
48
49
main()
50
machine_run_board_init()
51
machvirt_init()
52
create_flash()
53
create_one_flash() for flash[0]
54
create
55
configure
56
includes obeying -drive if=pflash,unit=0
57
realize
58
map
59
fall back to -bios
60
create_one_flash() for flash[1]
61
create
62
configure
63
includes obeying -drive if=pflash,unit=1
64
realize
65
map
66
update FDT
67
68
To make the machine properties work, we need to move device creation
69
to its .instance_init() method virt_instance_init().
70
71
Another complication is machvirt_init()'s computation of
72
@firmware_loaded: it predicts what create_flash() will do. Instead of
73
predicting what create_flash()'s replacement virt_firmware_init() will
74
do, I decided to have virt_firmware_init() return what it did.
75
Requires calling it a bit earlier.
76
77
Resulting call tree:
78
79
main()
80
current_machine = object_new()
81
...
82
virt_instance_init()
83
virt_flash_create()
84
virt_flash_create1() for flash[0]
85
create
86
configure: set defaults
87
become child of machine [NEW]
88
add machine prop pflash0 as alias for drive [NEW]
89
virt_flash_create1() for flash[1]
90
create
91
configure: set defaults
92
become child of machine [NEW]
93
add machine prop pflash1 as alias for drive [NEW]
94
for all machine props from the command line: machine_set_property()
95
...
96
property_set_alias() for machine props pflash0, pflash1
97
...
98
set_drive() for cfi.pflash01 prop drive
99
this is how -machine pflash0=... etc set
100
machine_run_board_init(current_machine);
101
virt_firmware_init()
102
pflash_cfi01_legacy_drive()
103
legacy -drive if=pflash,unit=0 and =1 [NEW]
104
virt_flash_map()
105
virt_flash_map1() for flash[0]
106
configure: num-blocks
107
realize
108
map
109
virt_flash_map1() for flash[1]
110
configure: num-blocks
111
realize
112
map
113
fall back to -bios
114
virt_flash_fdt()
115
update FDT
116
117
You have László to thank for making me explain this in detail.
118
119
Signed-off-by: Markus Armbruster <armbru@redhat.com>
120
Acked-by: Laszlo Ersek <lersek@redhat.com>
121
Message-id: 20190416091348.26075-4-armbru@redhat.com
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
122
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
123
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
124
---
19
include/hw/char/imx_serial.h | 3 +++
125
include/hw/arm/virt.h | 2 +
20
hw/char/imx_serial.c | 20 +++++++++++++++++---
126
hw/arm/virt.c | 202 +++++++++++++++++++++++++++---------------
21
2 files changed, 20 insertions(+), 3 deletions(-)
127
2 files changed, 132 insertions(+), 72 deletions(-)
22
128
23
diff --git a/include/hw/char/imx_serial.h b/include/hw/char/imx_serial.h
129
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
24
index XXXXXXX..XXXXXXX 100644
130
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/char/imx_serial.h
131
--- a/include/hw/arm/virt.h
26
+++ b/include/hw/char/imx_serial.h
132
+++ b/include/hw/arm/virt.h
27
@@ -XXX,XX +XXX,XX @@
133
@@ -XXX,XX +XXX,XX @@
28
#define UCR2_RXEN (1<<1) /* Receiver enable */
134
#include "qemu/notify.h"
29
#define UCR2_SRST (1<<0) /* Reset complete */
135
#include "hw/boards.h"
30
136
#include "hw/arm/arm.h"
31
+#define UCR4_TCEN BIT(3) /* TX complete interrupt enable */
137
+#include "hw/block/flash.h"
32
+
138
#include "sysemu/kvm.h"
33
#define UTS1_TXEMPTY (1<<6)
139
#include "hw/intc/arm_gicv3_common.h"
34
#define UTS1_RXEMPTY (1<<5)
140
35
#define UTS1_TXFULL (1<<4)
141
@@ -XXX,XX +XXX,XX @@ typedef struct {
36
@@ -XXX,XX +XXX,XX @@ typedef struct IMXSerialState {
142
Notifier machine_done;
37
uint32_t ubmr;
143
DeviceState *platform_bus_dev;
38
uint32_t ubrc;
144
FWCfgState *fw_cfg;
39
uint32_t ucr3;
145
+ PFlashCFI01 *flash[2];
40
+ uint32_t ucr4;
146
bool secure;
41
147
bool highmem;
42
qemu_irq irq;
148
bool highmem_ecam;
43
CharBackend chr;
149
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
44
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
45
index XXXXXXX..XXXXXXX 100644
150
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/char/imx_serial.c
151
--- a/hw/arm/virt.c
47
+++ b/hw/char/imx_serial.c
152
+++ b/hw/arm/virt.c
48
@@ -XXX,XX +XXX,XX @@
153
@@ -XXX,XX +XXX,XX @@
49
154
50
static const VMStateDescription vmstate_imx_serial = {
155
#include "qemu/osdep.h"
51
.name = TYPE_IMX_SERIAL,
156
#include "qemu/units.h"
52
- .version_id = 1,
157
+#include "qemu/option.h"
53
- .minimum_version_id = 1,
158
#include "qapi/error.h"
54
+ .version_id = 2,
159
#include "hw/sysbus.h"
55
+ .minimum_version_id = 2,
160
#include "hw/arm/arm.h"
56
.fields = (VMStateField[]) {
161
@@ -XXX,XX +XXX,XX @@ static void create_virtio_devices(const VirtMachineState *vms, qemu_irq *pic)
57
VMSTATE_INT32(readbuff, IMXSerialState),
162
}
58
VMSTATE_UINT32(usr1, IMXSerialState),
163
}
59
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_serial = {
164
60
VMSTATE_UINT32(ubmr, IMXSerialState),
165
-static void create_one_flash(const char *name, hwaddr flashbase,
61
VMSTATE_UINT32(ubrc, IMXSerialState),
166
- hwaddr flashsize, const char *file,
62
VMSTATE_UINT32(ucr3, IMXSerialState),
167
- MemoryRegion *sysmem)
63
+ VMSTATE_UINT32(ucr4, IMXSerialState),
168
+#define VIRT_FLASH_SECTOR_SIZE (256 * KiB)
64
VMSTATE_END_OF_LIST()
169
+
65
},
170
+static PFlashCFI01 *virt_flash_create1(VirtMachineState *vms,
66
};
171
+ const char *name,
67
@@ -XXX,XX +XXX,XX @@ static void imx_update(IMXSerialState *s)
172
+ const char *alias_prop_name)
68
* unfortunately.
173
{
174
- /* Create and map a single flash device. We use the same
175
- * parameters as the flash devices on the Versatile Express board.
176
+ /*
177
+ * Create a single flash device. We use the same parameters as
178
+ * the flash devices on the Versatile Express board.
69
*/
179
*/
70
mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
180
- DriveInfo *dinfo = drive_get_next(IF_PFLASH);
181
DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01);
182
- SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
183
- const uint64_t sectorlength = 256 * 1024;
184
185
- if (dinfo) {
186
- qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(dinfo),
187
- &error_abort);
188
- }
189
-
190
- qdev_prop_set_uint32(dev, "num-blocks", flashsize / sectorlength);
191
- qdev_prop_set_uint64(dev, "sector-length", sectorlength);
192
+ qdev_prop_set_uint64(dev, "sector-length", VIRT_FLASH_SECTOR_SIZE);
193
qdev_prop_set_uint8(dev, "width", 4);
194
qdev_prop_set_uint8(dev, "device-width", 2);
195
qdev_prop_set_bit(dev, "big-endian", false);
196
@@ -XXX,XX +XXX,XX @@ static void create_one_flash(const char *name, hwaddr flashbase,
197
qdev_prop_set_uint16(dev, "id2", 0x00);
198
qdev_prop_set_uint16(dev, "id3", 0x00);
199
qdev_prop_set_string(dev, "name", name);
200
- qdev_init_nofail(dev);
201
-
202
- memory_region_add_subregion(sysmem, flashbase,
203
- sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0));
204
-
205
- if (file) {
206
- char *fn;
207
- int image_size;
208
-
209
- if (drive_get(IF_PFLASH, 0, 0)) {
210
- error_report("The contents of the first flash device may be "
211
- "specified with -bios or with -drive if=pflash... "
212
- "but you cannot use both options at once");
213
- exit(1);
214
- }
215
- fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, file);
216
- if (!fn) {
217
- error_report("Could not find ROM image '%s'", file);
218
- exit(1);
219
- }
220
- image_size = load_image_mr(fn, sysbus_mmio_get_region(sbd, 0));
221
- g_free(fn);
222
- if (image_size < 0) {
223
- error_report("Could not load ROM image '%s'", file);
224
- exit(1);
225
- }
226
- }
227
+ object_property_add_child(OBJECT(vms), name, OBJECT(dev),
228
+ &error_abort);
229
+ object_property_add_alias(OBJECT(vms), alias_prop_name,
230
+ OBJECT(dev), "drive", &error_abort);
231
+ return PFLASH_CFI01(dev);
232
}
233
234
-static void create_flash(const VirtMachineState *vms,
235
- MemoryRegion *sysmem,
236
- MemoryRegion *secure_sysmem)
237
+static void virt_flash_create(VirtMachineState *vms)
238
{
239
- /* Create two flash devices to fill the VIRT_FLASH space in the memmap.
240
- * Any file passed via -bios goes in the first of these.
241
+ vms->flash[0] = virt_flash_create1(vms, "virt.flash0", "pflash0");
242
+ vms->flash[1] = virt_flash_create1(vms, "virt.flash1", "pflash1");
243
+}
244
+
245
+static void virt_flash_map1(PFlashCFI01 *flash,
246
+ hwaddr base, hwaddr size,
247
+ MemoryRegion *sysmem)
248
+{
249
+ DeviceState *dev = DEVICE(flash);
250
+
251
+ assert(size % VIRT_FLASH_SECTOR_SIZE == 0);
252
+ assert(size / VIRT_FLASH_SECTOR_SIZE <= UINT32_MAX);
253
+ qdev_prop_set_uint32(dev, "num-blocks", size / VIRT_FLASH_SECTOR_SIZE);
254
+ qdev_init_nofail(dev);
255
+
256
+ memory_region_add_subregion(sysmem, base,
257
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(dev),
258
+ 0));
259
+}
260
+
261
+static void virt_flash_map(VirtMachineState *vms,
262
+ MemoryRegion *sysmem,
263
+ MemoryRegion *secure_sysmem)
264
+{
71
+ /*
265
+ /*
72
+ * TCEN and TXDC are both bit 3
266
+ * Map two flash devices to fill the VIRT_FLASH space in the memmap.
73
+ */
267
* sysmem is the system memory space. secure_sysmem is the secure view
74
+ mask |= s->ucr4 & UCR4_TCEN;
268
* of the system, and the first flash device should be made visible only
75
+
269
* there. The second flash device is visible to both secure and nonsecure.
76
usr2 = s->usr2 & mask;
270
@@ -XXX,XX +XXX,XX @@ static void create_flash(const VirtMachineState *vms,
77
271
*/
78
qemu_set_irq(s->irq, usr1 || usr2);
272
hwaddr flashsize = vms->memmap[VIRT_FLASH].size / 2;
79
@@ -XXX,XX +XXX,XX @@ static uint64_t imx_serial_read(void *opaque, hwaddr offset,
273
hwaddr flashbase = vms->memmap[VIRT_FLASH].base;
80
return s->ucr3;
274
- char *nodename;
81
275
82
case 0x23: /* UCR4 */
276
- create_one_flash("virt.flash0", flashbase, flashsize,
83
+ return s->ucr4;
277
- bios_name, secure_sysmem);
84
+
278
- create_one_flash("virt.flash1", flashbase + flashsize, flashsize,
85
case 0x29: /* BRM Incremental */
279
- NULL, sysmem);
86
return 0x0; /* TODO */
280
+ virt_flash_map1(vms->flash[0], flashbase, flashsize,
87
281
+ secure_sysmem);
88
@@ -XXX,XX +XXX,XX @@ static void imx_serial_write(void *opaque, hwaddr offset,
282
+ virt_flash_map1(vms->flash[1], flashbase + flashsize, flashsize,
89
* qemu_chr_fe_write and background I/O callbacks */
283
+ sysmem);
90
qemu_chr_fe_write_all(&s->chr, &ch, 1);
284
+}
91
s->usr1 &= ~USR1_TRDY;
285
+
92
+ s->usr2 &= ~USR2_TXDC;
286
+static void virt_flash_fdt(VirtMachineState *vms,
93
imx_update(s);
287
+ MemoryRegion *sysmem,
94
s->usr1 |= USR1_TRDY;
288
+ MemoryRegion *secure_sysmem)
95
+ s->usr2 |= USR2_TXDC;
289
+{
96
imx_update(s);
290
+ hwaddr flashsize = vms->memmap[VIRT_FLASH].size / 2;
97
}
291
+ hwaddr flashbase = vms->memmap[VIRT_FLASH].base;
98
break;
292
+ char *nodename;
99
@@ -XXX,XX +XXX,XX @@ static void imx_serial_write(void *opaque, hwaddr offset,
293
100
s->ucr3 = value & 0xffff;
294
if (sysmem == secure_sysmem) {
101
break;
295
/* Report both flash devices as a single node in the DT */
102
296
@@ -XXX,XX +XXX,XX @@ static void create_flash(const VirtMachineState *vms,
103
- case 0x2d: /* UTS1 */
297
qemu_fdt_setprop_cell(vms->fdt, nodename, "bank-width", 4);
104
case 0x23: /* UCR4 */
298
g_free(nodename);
105
+ s->ucr4 = value & 0xffff;
299
} else {
106
+ imx_update(s);
300
- /* Report the devices as separate nodes so we can mark one as
107
+ break;
301
+ /*
108
+
302
+ * Report the devices as separate nodes so we can mark one as
109
+ case 0x2d: /* UTS1 */
303
* only visible to the secure world.
110
qemu_log_mask(LOG_UNIMP, "[%s]%s: Unimplemented reg 0x%"
304
*/
111
HWADDR_PRIx "\n", TYPE_IMX_SERIAL, __func__, offset);
305
nodename = g_strdup_printf("/secflash@%" PRIx64, flashbase);
112
/* TODO */
306
@@ -XXX,XX +XXX,XX @@ static void create_flash(const VirtMachineState *vms,
307
}
308
}
309
310
+static bool virt_firmware_init(VirtMachineState *vms,
311
+ MemoryRegion *sysmem,
312
+ MemoryRegion *secure_sysmem)
313
+{
314
+ int i;
315
+ BlockBackend *pflash_blk0;
316
+
317
+ /* Map legacy -drive if=pflash to machine properties */
318
+ for (i = 0; i < ARRAY_SIZE(vms->flash); i++) {
319
+ pflash_cfi01_legacy_drive(vms->flash[i],
320
+ drive_get(IF_PFLASH, 0, i));
321
+ }
322
+
323
+ virt_flash_map(vms, sysmem, secure_sysmem);
324
+
325
+ pflash_blk0 = pflash_cfi01_get_blk(vms->flash[0]);
326
+
327
+ if (bios_name) {
328
+ char *fname;
329
+ MemoryRegion *mr;
330
+ int image_size;
331
+
332
+ if (pflash_blk0) {
333
+ error_report("The contents of the first flash device may be "
334
+ "specified with -bios or with -drive if=pflash... "
335
+ "but you cannot use both options at once");
336
+ exit(1);
337
+ }
338
+
339
+ /* Fall back to -bios */
340
+
341
+ fname = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
342
+ if (!fname) {
343
+ error_report("Could not find ROM image '%s'", bios_name);
344
+ exit(1);
345
+ }
346
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(vms->flash[0]), 0);
347
+ image_size = load_image_mr(fname, mr);
348
+ g_free(fname);
349
+ if (image_size < 0) {
350
+ error_report("Could not load ROM image '%s'", bios_name);
351
+ exit(1);
352
+ }
353
+ }
354
+
355
+ return pflash_blk0 || bios_name;
356
+}
357
+
358
static FWCfgState *create_fw_cfg(const VirtMachineState *vms, AddressSpace *as)
359
{
360
hwaddr base = vms->memmap[VIRT_FW_CFG].base;
361
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
362
MemoryRegion *secure_sysmem = NULL;
363
int n, virt_max_cpus;
364
MemoryRegion *ram = g_new(MemoryRegion, 1);
365
- bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
366
+ bool firmware_loaded;
367
bool aarch64 = true;
368
369
/*
370
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
371
exit(1);
372
}
373
374
+ if (vms->secure) {
375
+ if (kvm_enabled()) {
376
+ error_report("mach-virt: KVM does not support Security extensions");
377
+ exit(1);
378
+ }
379
+
380
+ /*
381
+ * The Secure view of the world is the same as the NonSecure,
382
+ * but with a few extra devices. Create it as a container region
383
+ * containing the system memory at low priority; any secure-only
384
+ * devices go in at higher priority and take precedence.
385
+ */
386
+ secure_sysmem = g_new(MemoryRegion, 1);
387
+ memory_region_init(secure_sysmem, OBJECT(machine), "secure-memory",
388
+ UINT64_MAX);
389
+ memory_region_add_subregion_overlap(secure_sysmem, 0, sysmem, -1);
390
+ }
391
+
392
+ firmware_loaded = virt_firmware_init(vms, sysmem,
393
+ secure_sysmem ?: sysmem);
394
+
395
/* If we have an EL3 boot ROM then the assumption is that it will
396
* implement PSCI itself, so disable QEMU's internal implementation
397
* so it doesn't get in the way. Instead of starting secondary
398
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
399
exit(1);
400
}
401
402
- if (vms->secure) {
403
- if (kvm_enabled()) {
404
- error_report("mach-virt: KVM does not support Security extensions");
405
- exit(1);
406
- }
407
-
408
- /* The Secure view of the world is the same as the NonSecure,
409
- * but with a few extra devices. Create it as a container region
410
- * containing the system memory at low priority; any secure-only
411
- * devices go in at higher priority and take precedence.
412
- */
413
- secure_sysmem = g_new(MemoryRegion, 1);
414
- memory_region_init(secure_sysmem, OBJECT(machine), "secure-memory",
415
- UINT64_MAX);
416
- memory_region_add_subregion_overlap(secure_sysmem, 0, sysmem, -1);
417
- }
418
-
419
create_fdt(vms);
420
421
possible_cpus = mc->possible_cpu_arch_ids(machine);
422
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
423
&machine->device_memory->mr);
424
}
425
426
- create_flash(vms, sysmem, secure_sysmem ? secure_sysmem : sysmem);
427
+ virt_flash_fdt(vms, sysmem, secure_sysmem);
428
429
create_gic(vms, pic);
430
431
@@ -XXX,XX +XXX,XX @@ static void virt_instance_init(Object *obj)
432
NULL);
433
434
vms->irqmap = a15irqmap;
435
+
436
+ virt_flash_create(vms);
437
}
438
439
static const TypeInfo virt_machine_info = {
113
--
440
--
114
2.16.2
441
2.20.1
115
442
116
443
diff view generated by jsdifflib
1
The bcm2837 is pretty similar to the bcm2836, but it does have
1
The Raspberry Pi boards have a physical memory map which does
2
some differences. Notably, the MPIDR affinity aff1 values it
2
not allow for more than 1GB of RAM. Currently if the user tries
3
sets for the CPUs are 0x0, rather than the 0xf that the bcm2836
3
to ask for more then we fail in a confusing way:
4
uses, and if this is wrong Linux will not boot.
5
4
6
Rather than trying to have one device with properties that
5
$ qemu-system-aarch64 --machine raspi3 -m 8G
7
configure it differently for the two cases, create two
6
Unexpected error in visit_type_uintN() at qapi/qapi-visit-core.c:164:
8
separate QOM devices for the two SoCs. We use the same approach
7
qemu-system-aarch64: Parameter 'vcram-base' expects uint32_t
9
as hw/arm/aspeed_soc.c and share code and have a data table
8
Aborted (core dumped)
10
that might differ per-SoC. For the moment the two types don't
11
actually have different behaviour.
12
9
10
Catch this earlier and diagnose it with a more friendly message:
11
$ qemu-system-aarch64 --machine raspi3 -m 8G
12
qemu-system-aarch64: Requested ram size is too large for this machine: maximum is 1GB
13
14
Fixes: https://bugs.launchpad.net/qemu/+bug/1794187
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Message-id: 20180313153458.26822-7-peter.maydell@linaro.org
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
16
---
19
---
17
include/hw/arm/bcm2836.h | 19 +++++++++++++++++++
20
hw/arm/raspi.c | 7 +++++++
18
hw/arm/bcm2836.c | 37 ++++++++++++++++++++++++++++++++-----
21
1 file changed, 7 insertions(+)
19
hw/arm/raspi.c | 3 ++-
20
3 files changed, 53 insertions(+), 6 deletions(-)
21
22
22
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/arm/bcm2836.h
25
+++ b/include/hw/arm/bcm2836.h
26
@@ -XXX,XX +XXX,XX @@
27
28
#define BCM283X_NCPUS 4
29
30
+/* These type names are for specific SoCs; other than instantiating
31
+ * them, code using these devices should always handle them via the
32
+ * BCM283x base class, so they have no BCM2836(obj) etc macros.
33
+ */
34
+#define TYPE_BCM2836 "bcm2836"
35
+#define TYPE_BCM2837 "bcm2837"
36
+
37
typedef struct BCM283XState {
38
/*< private >*/
39
DeviceState parent_obj;
40
@@ -XXX,XX +XXX,XX @@ typedef struct BCM283XState {
41
BCM2835PeripheralState peripherals;
42
} BCM283XState;
43
44
+typedef struct BCM283XInfo BCM283XInfo;
45
+
46
+typedef struct BCM283XClass {
47
+ DeviceClass parent_class;
48
+ const BCM283XInfo *info;
49
+} BCM283XClass;
50
+
51
+#define BCM283X_CLASS(klass) \
52
+ OBJECT_CLASS_CHECK(BCM283XClass, (klass), TYPE_BCM283X)
53
+#define BCM283X_GET_CLASS(obj) \
54
+ OBJECT_GET_CLASS(BCM283XClass, (obj), TYPE_BCM283X)
55
+
56
#endif /* BCM2836_H */
57
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/arm/bcm2836.c
60
+++ b/hw/arm/bcm2836.c
61
@@ -XXX,XX +XXX,XX @@
62
/* "QA7" (Pi2) interrupt controller and mailboxes etc. */
63
#define BCM2836_CONTROL_BASE 0x40000000
64
65
+struct BCM283XInfo {
66
+ const char *name;
67
+};
68
+
69
+static const BCM283XInfo bcm283x_socs[] = {
70
+ {
71
+ .name = TYPE_BCM2836,
72
+ },
73
+ {
74
+ .name = TYPE_BCM2837,
75
+ },
76
+};
77
+
78
static void bcm2836_init(Object *obj)
79
{
80
BCM283XState *s = BCM283X(obj);
81
@@ -XXX,XX +XXX,XX @@ static Property bcm2836_props[] = {
82
DEFINE_PROP_END_OF_LIST()
83
};
84
85
-static void bcm2836_class_init(ObjectClass *oc, void *data)
86
+static void bcm283x_class_init(ObjectClass *oc, void *data)
87
{
88
DeviceClass *dc = DEVICE_CLASS(oc);
89
+ BCM283XClass *bc = BCM283X_CLASS(oc);
90
91
- dc->props = bcm2836_props;
92
+ bc->info = data;
93
dc->realize = bcm2836_realize;
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
23
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
127
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
128
--- a/hw/arm/raspi.c
25
--- a/hw/arm/raspi.c
129
+++ b/hw/arm/raspi.c
26
+++ b/hw/arm/raspi.c
27
@@ -XXX,XX +XXX,XX @@
28
*/
29
30
#include "qemu/osdep.h"
31
+#include "qemu/units.h"
32
#include "qapi/error.h"
33
#include "qemu-common.h"
34
#include "cpu.h"
130
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
35
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
131
BusState *bus;
36
BusState *bus;
132
DeviceState *carddev;
37
DeviceState *carddev;
133
38
134
- object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM283X);
39
+ if (machine->ram_size > 1 * GiB) {
135
+ object_initialize(&s->soc, sizeof(s->soc),
40
+ error_report("Requested ram size is too large for this machine: "
136
+ version == 3 ? TYPE_BCM2837 : TYPE_BCM2836);
41
+ "maximum is 1GB");
42
+ exit(1);
43
+ }
44
+
45
object_initialize(&s->soc, sizeof(s->soc),
46
version == 3 ? TYPE_BCM2837 : TYPE_BCM2836);
137
object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
47
object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
138
&error_abort);
139
140
--
48
--
141
2.16.2
49
2.20.1
142
50
143
51
diff view generated by jsdifflib
New patch
1
1
At the moment the Arm implementations of kvm_arch_{get,put}_registers()
2
don't support having QEMU change the values of system registers
3
(aka coprocessor registers for AArch32). This is because although
4
kvm_arch_get_registers() calls write_list_to_cpustate() to
5
update the CPU state struct fields (so QEMU code can read the
6
values in the usual way), kvm_arch_put_registers() does not
7
call write_cpustate_to_list(), meaning that any changes to
8
the CPU state struct fields will not be passed back to KVM.
9
10
The rationale for this design is documented in a comment in the
11
AArch32 kvm_arch_put_registers() -- writing the values in the
12
cpregs list into the CPU state struct is "lossy" because the
13
write of a register might not succeed, and so if we blindly
14
copy the CPU state values back again we will incorrectly
15
change register values for the guest. The assumption was that
16
no QEMU code would need to write to the registers.
17
18
However, when we implemented debug support for KVM guests, we
19
broke that assumption: the code to handle "set the guest up
20
to take a breakpoint exception" does so by updating various
21
guest registers including ESR_EL1.
22
23
Support this by making kvm_arch_put_registers() synchronize
24
CPU state back into the list. We sync only those registers
25
where the initial write succeeds, which should be sufficient.
26
27
This commit is the same as commit 823e1b3818f9b10b824ddc which we
28
had to revert in commit 942f99c825fc94c8b1a4, except that the bug
29
which was preventing EDK2 guest firmware running has been fixed:
30
kvm_arm_reset_vcpu() now calls write_list_to_cpustate().
31
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
34
Tested-by: Eric Auger <eric.auger@redhat.com>
35
---
36
target/arm/cpu.h | 9 ++++++++-
37
target/arm/helper.c | 27 +++++++++++++++++++++++++--
38
target/arm/kvm.c | 8 ++++++++
39
target/arm/kvm32.c | 20 ++------------------
40
target/arm/kvm64.c | 2 ++
41
target/arm/machine.c | 2 +-
42
6 files changed, 46 insertions(+), 22 deletions(-)
43
44
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/cpu.h
47
+++ b/target/arm/cpu.h
48
@@ -XXX,XX +XXX,XX @@ bool write_list_to_cpustate(ARMCPU *cpu);
49
/**
50
* write_cpustate_to_list:
51
* @cpu: ARMCPU
52
+ * @kvm_sync: true if this is for syncing back to KVM
53
*
54
* For each register listed in the ARMCPU cpreg_indexes list, write
55
* its value from the ARMCPUState structure into the cpreg_values list.
56
* This is used to copy info from TCG's working data structures into
57
* KVM or for outbound migration.
58
*
59
+ * @kvm_sync is true if we are doing this in order to sync the
60
+ * register state back to KVM. In this case we will only update
61
+ * values in the list if the previous list->cpustate sync actually
62
+ * successfully wrote the CPU state. Otherwise we will keep the value
63
+ * that is in the list.
64
+ *
65
* Returns: true if all register values were read correctly,
66
* false if some register was unknown or could not be read.
67
* Note that we do not stop early on failure -- we will attempt
68
* reading all registers in the list.
69
*/
70
-bool write_cpustate_to_list(ARMCPU *cpu);
71
+bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
72
73
#define ARM_CPUID_TI915T 0x54029152
74
#define ARM_CPUID_TI925T 0x54029252
75
diff --git a/target/arm/helper.c b/target/arm/helper.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/arm/helper.c
78
+++ b/target/arm/helper.c
79
@@ -XXX,XX +XXX,XX @@ static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
80
return true;
81
}
82
83
-bool write_cpustate_to_list(ARMCPU *cpu)
84
+bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
85
{
86
/* Write the coprocessor state from cpu->env to the (index,value) list. */
87
int i;
88
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu)
89
for (i = 0; i < cpu->cpreg_array_len; i++) {
90
uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
91
const ARMCPRegInfo *ri;
92
+ uint64_t newval;
93
94
ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
95
if (!ri) {
96
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu)
97
if (ri->type & ARM_CP_NO_RAW) {
98
continue;
99
}
100
- cpu->cpreg_values[i] = read_raw_cp_reg(&cpu->env, ri);
101
+
102
+ newval = read_raw_cp_reg(&cpu->env, ri);
103
+ if (kvm_sync) {
104
+ /*
105
+ * Only sync if the previous list->cpustate sync succeeded.
106
+ * Rather than tracking the success/failure state for every
107
+ * item in the list, we just recheck "does the raw write we must
108
+ * have made in write_list_to_cpustate() read back OK" here.
109
+ */
110
+ uint64_t oldval = cpu->cpreg_values[i];
111
+
112
+ if (oldval == newval) {
113
+ continue;
114
+ }
115
+
116
+ write_raw_cp_reg(&cpu->env, ri, oldval);
117
+ if (read_raw_cp_reg(&cpu->env, ri) != oldval) {
118
+ continue;
119
+ }
120
+
121
+ write_raw_cp_reg(&cpu->env, ri, newval);
122
+ }
123
+ cpu->cpreg_values[i] = newval;
124
}
125
return ok;
126
}
127
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
128
index XXXXXXX..XXXXXXX 100644
129
--- a/target/arm/kvm.c
130
+++ b/target/arm/kvm.c
131
@@ -XXX,XX +XXX,XX @@ void kvm_arm_reset_vcpu(ARMCPU *cpu)
132
fprintf(stderr, "write_kvmstate_to_list failed\n");
133
abort();
134
}
135
+ /*
136
+ * Sync the reset values also into the CPUState. This is necessary
137
+ * because the next thing we do will be a kvm_arch_put_registers()
138
+ * which will update the list values from the CPUState before copying
139
+ * the list values back to KVM. It's OK to ignore failure returns here
140
+ * for the same reason we do so in kvm_arch_get_registers().
141
+ */
142
+ write_list_to_cpustate(cpu);
143
}
144
145
/*
146
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
147
index XXXXXXX..XXXXXXX 100644
148
--- a/target/arm/kvm32.c
149
+++ b/target/arm/kvm32.c
150
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
151
return ret;
152
}
153
154
- /* Note that we do not call write_cpustate_to_list()
155
- * here, so we are only writing the tuple list back to
156
- * KVM. This is safe because nothing can change the
157
- * CPUARMState cp15 fields (in particular gdb accesses cannot)
158
- * and so there are no changes to sync. In fact syncing would
159
- * be wrong at this point: for a constant register where TCG and
160
- * KVM disagree about its value, the preceding write_list_to_cpustate()
161
- * would not have had any effect on the CPUARMState value (since the
162
- * register is read-only), and a write_cpustate_to_list() here would
163
- * then try to write the TCG value back into KVM -- this would either
164
- * fail or incorrectly change the value the guest sees.
165
- *
166
- * If we ever want to allow the user to modify cp15 registers via
167
- * the gdb stub, we would need to be more clever here (for instance
168
- * tracking the set of registers kvm_arch_get_registers() successfully
169
- * managed to update the CPUARMState with, and only allowing those
170
- * to be written back up into the kernel).
171
- */
172
+ write_cpustate_to_list(cpu, true);
173
+
174
if (!write_list_to_kvmstate(cpu, level)) {
175
return EINVAL;
176
}
177
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
178
index XXXXXXX..XXXXXXX 100644
179
--- a/target/arm/kvm64.c
180
+++ b/target/arm/kvm64.c
181
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
182
return ret;
183
}
184
185
+ write_cpustate_to_list(cpu, true);
186
+
187
if (!write_list_to_kvmstate(cpu, level)) {
188
return EINVAL;
189
}
190
diff --git a/target/arm/machine.c b/target/arm/machine.c
191
index XXXXXXX..XXXXXXX 100644
192
--- a/target/arm/machine.c
193
+++ b/target/arm/machine.c
194
@@ -XXX,XX +XXX,XX @@ static int cpu_pre_save(void *opaque)
195
abort();
196
}
197
} else {
198
- if (!write_cpustate_to_list(cpu)) {
199
+ if (!write_cpustate_to_list(cpu, false)) {
200
/* This should never fail. */
201
abort();
202
}
203
--
204
2.20.1
205
206
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Joel Stanley <joel@jms.id.au>
2
2
3
Code of imx_update() is slightly confusing since the "flags" variable
3
We currently use Qemu's default of 128MB. As we know how much ram each
4
doesn't really corespond to anything in real hardware and server as a
4
machine ships with, make it easier on users by setting a default.
5
kitchensink accumulating events normally reported via USR1 and USR2
6
registers.
7
5
8
Change the code to explicitly evaluate state of interrupts reported
6
It can still be overridden with -m on the command line.
9
via USR1 and USR2 against corresponding masking bits and use the to
10
detemine if IRQ line should be asserted or not.
11
7
12
NOTE: Check for UTS1_TXEMPTY being set has been dropped for two
8
Signed-off-by: Joel Stanley <joel@jms.id.au>
13
reasons:
9
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
14
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
1. Emulation code implements a single character FIFO, so this flag
11
Message-id: 20190503022958.1394-1-joel@jms.id.au
16
will always be set since characters are trasmitted as a part of
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
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>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
---
14
---
33
hw/char/imx_serial.c | 24 ++++++++++++++++--------
15
include/hw/arm/aspeed.h | 1 +
34
1 file changed, 16 insertions(+), 8 deletions(-)
16
hw/arm/aspeed.c | 8 ++++++++
17
2 files changed, 9 insertions(+)
35
18
36
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
19
diff --git a/include/hw/arm/aspeed.h b/include/hw/arm/aspeed.h
37
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/char/imx_serial.c
21
--- a/include/hw/arm/aspeed.h
39
+++ b/hw/char/imx_serial.c
22
+++ b/include/hw/arm/aspeed.h
40
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_serial = {
23
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedBoardConfig {
41
24
const char *spi_model;
42
static void imx_update(IMXSerialState *s)
25
uint32_t num_cs;
43
{
26
void (*i2c_init)(AspeedBoardState *bmc);
44
- uint32_t flags;
27
+ uint32_t ram;
45
+ uint32_t usr1;
28
} AspeedBoardConfig;
46
+ uint32_t usr2;
29
47
+ uint32_t mask;
30
#define TYPE_ASPEED_MACHINE MACHINE_TYPE_NAME("aspeed")
48
31
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
49
- flags = (s->usr1 & s->ucr1) & (USR1_TRDY|USR1_RRDY);
32
index XXXXXXX..XXXXXXX 100644
50
- if (s->ucr1 & UCR1_TXMPTYEN) {
33
--- a/hw/arm/aspeed.c
51
- flags |= (s->uts1 & UTS1_TXEMPTY);
34
+++ b/hw/arm/aspeed.c
52
- } else {
35
@@ -XXX,XX +XXX,XX @@
53
- flags &= ~USR1_TRDY;
36
#include "sysemu/block-backend.h"
54
- }
37
#include "hw/loader.h"
55
+ /*
38
#include "qemu/error-report.h"
56
+ * Lucky for us TRDY and RRDY has the same offset in both USR1 and
39
+#include "qemu/units.h"
57
+ * UCR1, so we can get away with something as simple as the
40
58
+ * following:
41
static struct arm_boot_info aspeed_board_binfo = {
59
+ */
42
.board_id = -1, /* device-tree-only board */
60
+ usr1 = s->usr1 & s->ucr1 & (USR1_TRDY | USR1_RRDY);
43
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_class_init(ObjectClass *oc, void *data)
61
+ /*
44
mc->no_floppy = 1;
62
+ * Bits that we want in USR2 are not as conveniently laid out,
45
mc->no_cdrom = 1;
63
+ * unfortunately.
46
mc->no_parallel = 1;
64
+ */
47
+ if (board->ram) {
65
+ mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
48
+ mc->default_ram_size = board->ram;
66
+ usr2 = s->usr2 & mask;
49
+ }
67
50
amc->board = board;
68
- qemu_set_irq(s->irq, !!flags);
69
+ qemu_set_irq(s->irq, usr1 || usr2);
70
}
51
}
71
52
72
static void imx_serial_reset(IMXSerialState *s)
53
@@ -XXX,XX +XXX,XX @@ static const AspeedBoardConfig aspeed_boards[] = {
54
.spi_model = "mx25l25635e",
55
.num_cs = 1,
56
.i2c_init = palmetto_bmc_i2c_init,
57
+ .ram = 256 * MiB,
58
}, {
59
.name = MACHINE_TYPE_NAME("ast2500-evb"),
60
.desc = "Aspeed AST2500 EVB (ARM1176)",
61
@@ -XXX,XX +XXX,XX @@ static const AspeedBoardConfig aspeed_boards[] = {
62
.spi_model = "mx25l25635e",
63
.num_cs = 1,
64
.i2c_init = ast2500_evb_i2c_init,
65
+ .ram = 512 * MiB,
66
}, {
67
.name = MACHINE_TYPE_NAME("romulus-bmc"),
68
.desc = "OpenPOWER Romulus BMC (ARM1176)",
69
@@ -XXX,XX +XXX,XX @@ static const AspeedBoardConfig aspeed_boards[] = {
70
.spi_model = "mx66l1g45g",
71
.num_cs = 2,
72
.i2c_init = romulus_bmc_i2c_init,
73
+ .ram = 512 * MiB,
74
}, {
75
.name = MACHINE_TYPE_NAME("witherspoon-bmc"),
76
.desc = "OpenPOWER Witherspoon BMC (ARM1176)",
77
@@ -XXX,XX +XXX,XX @@ static const AspeedBoardConfig aspeed_boards[] = {
78
.spi_model = "mx66l1g45g",
79
.num_cs = 2,
80
.i2c_init = witherspoon_bmc_i2c_init,
81
+ .ram = 512 * MiB,
82
},
83
};
84
73
--
85
--
74
2.16.2
86
2.20.1
75
87
76
88
diff view generated by jsdifflib
1
Now we have separate types for BCM2386 and BCM2387, we might as well
1
From: Cao Jiaxi <driver1998@foxmail.com>
2
just hard-code the CPU type they use rather than having it passed
3
through as an object property. This then lets us put the initialization
4
of the CPU object in init rather than realize.
5
2
6
Note that this change means that it's no longer possible on
3
gcc_struct is for x86 only, and it generates an warning on ARM64 Clang/MinGW targets.
7
the command line to use -cpu to ask for a different kind of
8
CPU than the SoC supports. This was never a supported thing to
9
do anyway; we were just not sanity-checking the command line.
10
4
11
This does require us to only build the bcm2837 object on
5
Signed-off-by: Cao Jiaxi <driver1998@foxmail.com>
12
TARGET_AARCH64 configs, since otherwise it won't instantiate
6
Reviewed-by: Thomas Huth <thuth@redhat.com>
13
due to the missing cortex-a53 device and "make check" will fail.
7
Message-id: 20190503003618.10089-1-driver1998@foxmail.com
8
[PMM: dropped the slirp change as slirp is now a submodule]
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
contrib/libvhost-user/libvhost-user.h | 2 +-
12
include/qemu/compiler.h | 2 +-
13
scripts/cocci-macro-file.h | 7 ++++++-
14
3 files changed, 8 insertions(+), 3 deletions(-)
14
15
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
diff --git a/contrib/libvhost-user/libvhost-user.h b/contrib/libvhost-user/libvhost-user.h
16
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
17
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Message-id: 20180313153458.26822-9-peter.maydell@linaro.org
19
---
20
hw/arm/bcm2836.c | 24 +++++++++++++++---------
21
hw/arm/raspi.c | 2 --
22
2 files changed, 15 insertions(+), 11 deletions(-)
23
24
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
25
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/bcm2836.c
18
--- a/contrib/libvhost-user/libvhost-user.h
27
+++ b/hw/arm/bcm2836.c
19
+++ b/contrib/libvhost-user/libvhost-user.h
20
@@ -XXX,XX +XXX,XX @@ typedef struct VhostUserInflight {
21
uint16_t queue_size;
22
} VhostUserInflight;
23
24
-#if defined(_WIN32)
25
+#if defined(_WIN32) && (defined(__x86_64__) || defined(__i386__))
26
# define VU_PACKED __attribute__((gcc_struct, packed))
27
#else
28
# define VU_PACKED __attribute__((packed))
29
diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/include/qemu/compiler.h
32
+++ b/include/qemu/compiler.h
28
@@ -XXX,XX +XXX,XX @@
33
@@ -XXX,XX +XXX,XX @@
29
34
30
struct BCM283XInfo {
35
#define QEMU_SENTINEL __attribute__((sentinel))
31
const char *name;
36
32
+ const char *cpu_type;
37
-#if defined(_WIN32)
33
int clusterid;
38
+#if defined(_WIN32) && (defined(__x86_64__) || defined(__i386__))
34
};
39
# define QEMU_PACKED __attribute__((gcc_struct, packed))
35
40
#else
36
static const BCM283XInfo bcm283x_socs[] = {
41
# define QEMU_PACKED __attribute__((packed))
37
{
42
diff --git a/scripts/cocci-macro-file.h b/scripts/cocci-macro-file.h
38
.name = TYPE_BCM2836,
43
index XXXXXXX..XXXXXXX 100644
39
+ .cpu_type = ARM_CPU_TYPE_NAME("cortex-a15"),
44
--- a/scripts/cocci-macro-file.h
40
.clusterid = 0xf,
45
+++ b/scripts/cocci-macro-file.h
41
},
46
@@ -XXX,XX +XXX,XX @@
42
+#ifdef TARGET_AARCH64
47
#define QEMU_NORETURN __attribute__ ((__noreturn__))
43
{
48
#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
44
.name = TYPE_BCM2837,
49
#define QEMU_SENTINEL __attribute__((sentinel))
45
+ .cpu_type = ARM_CPU_TYPE_NAME("cortex-a53"),
50
-#define QEMU_PACKED __attribute__((gcc_struct, packed))
46
.clusterid = 0x0,
51
+
47
},
52
+#if defined(_WIN32) && (defined(__x86_64__) || defined(__i386__))
53
+# define QEMU_PACKED __attribute__((gcc_struct, packed))
54
+#else
55
+# define QEMU_PACKED __attribute__((packed))
48
+#endif
56
+#endif
49
};
57
50
58
#define cat(x,y) x ## y
51
static void bcm2836_init(Object *obj)
59
#define cat2(x,y) cat(x,y)
52
{
53
BCM283XState *s = BCM283X(obj);
54
+ BCM283XClass *bc = BCM283X_GET_CLASS(obj);
55
+ const BCM283XInfo *info = bc->info;
56
+ int n;
57
+
58
+ for (n = 0; n < BCM283X_NCPUS; n++) {
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
}
84
85
static Property bcm2836_props[] = {
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
--
60
--
104
2.16.2
61
2.20.1
105
62
106
63
diff view generated by jsdifflib
1
The TypeInfo and state struct for bcm2386 disagree about what the
1
From: Cao Jiaxi <driver1998@foxmail.com>
2
parent class is -- the TypeInfo says it's TYPE_SYS_BUS_DEVICE,
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
2
3
The win2qemu[] is supposed to be the conversion table to convert between
4
STORAGE_BUS_TYPE in Windows SDK and GuestDiskBusType in qga.
5
6
But it was incorrectly written that it forces to set a GuestDiskBusType
7
value to STORAGE_BUS_TYPE, which generates an enum conversion warning in clang.
8
9
Suggested-by: Eric Blake <eblake@redhat.com>
10
Signed-off-by: Cao Jiaxi <driver1998@foxmail.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Thomas Huth <thuth@redhat.com>
13
Message-id: 20190503003650.10137-1-driver1998@foxmail.com
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
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>
13
Message-id: 20180313153458.26822-5-peter.maydell@linaro.org
14
---
17
---
15
hw/arm/bcm2836.c | 2 +-
18
qga/commands-win32.c | 2 +-
16
1 file changed, 1 insertion(+), 1 deletion(-)
19
1 file changed, 1 insertion(+), 1 deletion(-)
17
20
18
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
21
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
19
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/bcm2836.c
23
--- a/qga/commands-win32.c
21
+++ b/hw/arm/bcm2836.c
24
+++ b/qga/commands-win32.c
22
@@ -XXX,XX +XXX,XX @@ static void bcm2836_class_init(ObjectClass *oc, void *data)
25
@@ -XXX,XX +XXX,XX @@ void qmp_guest_file_flush(int64_t handle, Error **errp)
23
26
24
static const TypeInfo bcm2836_type_info = {
27
#ifdef CONFIG_QGA_NTDDSCSI
25
.name = TYPE_BCM2836,
28
26
- .parent = TYPE_SYS_BUS_DEVICE,
29
-static STORAGE_BUS_TYPE win2qemu[] = {
27
+ .parent = TYPE_DEVICE,
30
+static GuestDiskBusType win2qemu[] = {
28
.instance_size = sizeof(BCM2836State),
31
[BusTypeUnknown] = GUEST_DISK_BUS_TYPE_UNKNOWN,
29
.instance_init = bcm2836_init,
32
[BusTypeScsi] = GUEST_DISK_BUS_TYPE_SCSI,
30
.class_init = bcm2836_class_init,
33
[BusTypeAtapi] = GUEST_DISK_BUS_TYPE_IDE,
31
--
34
--
32
2.16.2
35
2.20.1
33
36
34
37
diff view generated by jsdifflib
1
From: Wei Huang <wei@redhat.com>
1
From: Cao Jiaxi <driver1998@foxmail.com>
2
2
3
For guest kernel that supports KASLR, the load address can change every
3
Windows ARM64 uses LLP64 model, which breaks current assumptions.
4
time when guest VM runs. To find the physical base address correctly,
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
4
10
Signed-off-by: Wei Huang <wei@redhat.com>
5
Signed-off-by: Cao Jiaxi <driver1998@foxmail.com>
11
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 1520615003-20869-1-git-send-email-wei@redhat.com
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
8
Message-id: 20190503003707.10185-1-driver1998@foxmail.com
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
12
---
15
dump.c | 14 +++++++++++---
13
util/cacheinfo.c | 2 +-
16
1 file changed, 11 insertions(+), 3 deletions(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
17
15
18
diff --git a/dump.c b/dump.c
16
diff --git a/util/cacheinfo.c b/util/cacheinfo.c
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/dump.c
18
--- a/util/cacheinfo.c
21
+++ b/dump.c
19
+++ b/util/cacheinfo.c
22
@@ -XXX,XX +XXX,XX @@ static void vmcoreinfo_update_phys_base(DumpState *s)
20
@@ -XXX,XX +XXX,XX @@ static void sys_cache_info(int *isize, int *dsize)
23
21
static void arch_cache_info(int *isize, int *dsize)
24
lines = g_strsplit((char *)vmci, "\n", -1);
22
{
25
for (i = 0; lines[i]; i++) {
23
if (*isize == 0 || *dsize == 0) {
26
- if (g_str_has_prefix(lines[i], "NUMBER(phys_base)=")) {
24
- unsigned long ctr;
27
- if (qemu_strtou64(lines[i] + 18, NULL, 16,
25
+ uint64_t ctr;
28
+ const char *prefix = NULL;
26
29
+
27
/* The real cache geometry is in CCSIDR_EL1/CLIDR_EL1/CSSELR_EL1,
30
+ if (s->dump_info.d_machine == EM_X86_64) {
28
but (at least under Linux) these are marked protected by the
31
+ prefix = "NUMBER(phys_base)=";
32
+ } else if (s->dump_info.d_machine == EM_AARCH64) {
33
+ prefix = "NUMBER(PHYS_OFFSET)=";
34
+ }
35
+
36
+ if (prefix && g_str_has_prefix(lines[i], prefix)) {
37
+ if (qemu_strtou64(lines[i] + strlen(prefix), NULL, 16,
38
&phys_base) < 0) {
39
- warn_report("Failed to read NUMBER(phys_base)=");
40
+ warn_report("Failed to read %s", prefix);
41
} else {
42
s->dump_info.phys_base = phys_base;
43
}
44
--
29
--
45
2.16.2
30
2.20.1
46
31
47
32
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
From: Cao Jiaxi <driver1998@foxmail.com>
2
2
3
The sabrelite machine model used by qemu-system-arm is based on the
3
I encountered the following compilation error on mingw:
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
4
8
The include/hw/arm/fsm-imx6.h file defines the interrupt vectors for the
5
/mnt/d/qemu/include/qemu/osdep.h:97:9: error: '__USE_MINGW_ANSI_STDIO' macro redefined [-Werror,-Wmacro-redefined]
9
imx.enet device like this:
6
#define __USE_MINGW_ANSI_STDIO 1
7
^
8
/mnt/d/llvm-mingw/aarch64-w64-mingw32/include/_mingw.h:433:9: note: previous definition is here
9
#define __USE_MINGW_ANSI_STDIO 0 /* was not defined so it should be 0 */
10
10
11
#define FSL_IMX6_ENET_MAC_1588_IRQ 118
11
It turns out that __USE_MINGW_ANSI_STDIO must be set before any
12
#define FSL_IMX6_ENET_MAC_IRQ 119
12
system headers are included, not just before stdio.h.
13
13
14
According to https://www.nxp.com/docs/en/reference-manual/IMX6DQRM.pdf,
14
Signed-off-by: Cao Jiaxi <driver1998@foxmail.com>
15
page 225, in Table 3-1. ARM Cortex A9 domain interrupt summary,
15
Reviewed-by: Thomas Huth <thuth@redhat.com>
16
interrupts are as follows.
16
Reviewed-by: Stefan Weil <sw@weilnetz.de>
17
17
Message-id: 20190503003719.10233-1-driver1998@foxmail.com
18
150 ENET MAC 0 IRQ
18
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
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>
42
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
43
---
20
---
44
include/hw/arm/fsl-imx6.h | 4 ++--
21
include/qemu/osdep.h | 10 +++++-----
45
hw/net/imx_fec.c | 28 +++++++++++++++++++++++++++-
22
1 file changed, 5 insertions(+), 5 deletions(-)
46
2 files changed, 29 insertions(+), 3 deletions(-)
47
23
48
diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h
24
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
49
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
50
--- a/include/hw/arm/fsl-imx6.h
26
--- a/include/qemu/osdep.h
51
+++ b/include/hw/arm/fsl-imx6.h
27
+++ b/include/qemu/osdep.h
52
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX6State {
28
@@ -XXX,XX +XXX,XX @@ extern int daemon(int, int);
53
#define FSL_IMX6_HDMI_MASTER_IRQ 115
29
#endif
54
#define FSL_IMX6_HDMI_CEC_IRQ 116
30
#endif
55
#define FSL_IMX6_MLB150_LOW_IRQ 117
31
56
-#define FSL_IMX6_ENET_MAC_1588_IRQ 118
32
+/* enable C99/POSIX format strings (needs mingw32-runtime 3.15 or later) */
57
-#define FSL_IMX6_ENET_MAC_IRQ 119
33
+#ifdef __MINGW32__
58
+#define FSL_IMX6_ENET_MAC_IRQ 118
34
+#define __USE_MINGW_ANSI_STDIO 1
59
+#define FSL_IMX6_ENET_MAC_1588_IRQ 119
35
+#endif
60
#define FSL_IMX6_PCIE1_IRQ 120
36
+
61
#define FSL_IMX6_PCIE2_IRQ 121
37
#include <stdarg.h>
62
#define FSL_IMX6_PCIE3_IRQ 122
38
#include <stddef.h>
63
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
39
#include <stdbool.h>
64
index XXXXXXX..XXXXXXX 100644
40
#include <stdint.h>
65
--- a/hw/net/imx_fec.c
41
#include <sys/types.h>
66
+++ b/hw/net/imx_fec.c
42
#include <stdlib.h>
67
@@ -XXX,XX +XXX,XX @@ static void imx_enet_write_bd(IMXENETBufDesc *bd, dma_addr_t addr)
43
-
68
44
-/* enable C99/POSIX format strings (needs mingw32-runtime 3.15 or later) */
69
static void imx_eth_update(IMXFECState *s)
45
-#ifdef __MINGW32__
70
{
46
-#define __USE_MINGW_ANSI_STDIO 1
71
- if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] & ENET_INT_TS_TIMER) {
47
-#endif
72
+ /*
48
#include <stdio.h>
73
+ * Previous versions of qemu had the ENET_INT_MAC and ENET_INT_TS_TIMER
49
74
+ * interrupts swapped. This worked with older versions of Linux (4.14
50
#include <string.h>
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
+ */
97
+ if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] &
98
+ (ENET_INT_MAC | ENET_INT_TS_TIMER)) {
99
qemu_set_irq(s->irq[1], 1);
100
} else {
101
qemu_set_irq(s->irq[1], 0);
102
--
51
--
103
2.16.2
52
2.20.1
104
53
105
54
diff view generated by jsdifflib
1
The BCM2837 sets the Aff1 field of the MPIDR affinity values for the
1
Rule R_CQRV says that if two pending interrupts have the same
2
CPUs to 0, whereas the BCM2836 uses 0xf. Set this correctly, as it
2
group priority then ties are broken by looking at the subpriority.
3
is required for Linux to boot.
3
We had a comment describing this but had forgotten to actually
4
implement the subpriority comparison. Correct the omission.
5
6
(The further tie break rules of "lowest exception number" and
7
"secure before non-secure" are handled implicitly by the order
8
in which we iterate through the exceptions in the loops.)
4
9
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Message-id: 20190430131439.25251-2-peter.maydell@linaro.org
8
Message-id: 20180313153458.26822-8-peter.maydell@linaro.org
9
---
13
---
10
hw/arm/bcm2836.c | 11 +++++++----
14
hw/intc/armv7m_nvic.c | 9 +++++++--
11
1 file changed, 7 insertions(+), 4 deletions(-)
15
1 file changed, 7 insertions(+), 2 deletions(-)
12
16
13
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
17
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/bcm2836.c
19
--- a/hw/intc/armv7m_nvic.c
16
+++ b/hw/arm/bcm2836.c
20
+++ b/hw/intc/armv7m_nvic.c
17
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static void nvic_recompute_state_secure(NVICState *s)
18
22
int active_prio = NVIC_NOEXC_PRIO;
19
struct BCM283XInfo {
23
int pend_irq = 0;
20
const char *name;
24
bool pending_is_s_banked = false;
21
+ int clusterid;
25
+ int pend_subprio = 0;
22
};
26
23
27
/* R_CQRV: precedence is by:
24
static const BCM283XInfo bcm283x_socs[] = {
28
* - lowest group priority; if both the same then
25
{
29
@@ -XXX,XX +XXX,XX @@ static void nvic_recompute_state_secure(NVICState *s)
26
.name = TYPE_BCM2836,
30
for (i = 1; i < s->num_irq; i++) {
27
+ .clusterid = 0xf,
31
for (bank = M_REG_S; bank >= M_REG_NS; bank--) {
28
},
32
VecInfo *vec;
29
{
33
- int prio;
30
.name = TYPE_BCM2837,
34
+ int prio, subprio;
31
+ .clusterid = 0x0,
35
bool targets_secure;
32
},
36
33
};
37
if (bank == M_REG_S) {
34
38
@@ -XXX,XX +XXX,XX @@ static void nvic_recompute_state_secure(NVICState *s)
35
@@ -XXX,XX +XXX,XX @@ static void bcm2836_init(Object *obj)
39
}
36
static void bcm2836_realize(DeviceState *dev, Error **errp)
40
37
{
41
prio = exc_group_prio(s, vec->prio, targets_secure);
38
BCM283XState *s = BCM283X(dev);
42
- if (vec->enabled && vec->pending && prio < pend_prio) {
39
+ BCM283XClass *bc = BCM283X_GET_CLASS(dev);
43
+ subprio = vec->prio & ~nvic_gprio_mask(s, targets_secure);
40
+ const BCM283XInfo *info = bc->info;
44
+ if (vec->enabled && vec->pending &&
41
Object *obj;
45
+ ((prio < pend_prio) ||
42
Error *err = NULL;
46
+ (prio == pend_prio && prio >= 0 && subprio < pend_subprio))) {
43
int n;
47
pend_prio = prio;
44
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
48
+ pend_subprio = subprio;
45
qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-fiq", 0));
49
pend_irq = i;
46
50
pending_is_s_banked = (bank == M_REG_S);
47
for (n = 0; n < BCM283X_NCPUS; n++) {
51
}
48
- /* Mirror bcm2836, which has clusterid set to 0xf
49
- * TODO: this should be converted to a property of ARM_CPU
50
- */
51
- s->cpus[n].mp_affinity = 0xF00 | n;
52
+ /* TODO: this should be converted to a property of ARM_CPU */
53
+ s->cpus[n].mp_affinity = (info->clusterid << 8) | n;
54
55
/* set periphbase/CBAR value for CPU-local registers */
56
object_property_set_int(OBJECT(&s->cpus[n]),
57
--
52
--
58
2.16.2
53
2.20.1
59
54
60
55
diff view generated by jsdifflib
1
Our BCM2836 type is really a generic one that can be any of
1
The non-secure versions of the BFAR and BFSR registers are
2
the bcm283x family. Rename it accordingly. We change only
2
supposed to be RAZ/WI if AICR.BFHFNMINS == 0; we were
3
the names which are visible via the header file to the
3
incorrectly allowing NS code to access the real values.
4
rest of the QEMU code, leaving private function names
5
in bcm2836.c as they are.
6
7
This is a preliminary to making bcm283x be an abstract
8
parent class to specific types for the bcm2836 and bcm2837.
9
4
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20190430131439.25251-3-peter.maydell@linaro.org
13
Message-id: 20180313153458.26822-6-peter.maydell@linaro.org
14
---
8
---
15
include/hw/arm/bcm2836.h | 12 ++++++------
9
hw/intc/armv7m_nvic.c | 27 ++++++++++++++++++++++++---
16
hw/arm/bcm2836.c | 17 +++++++++--------
10
1 file changed, 24 insertions(+), 3 deletions(-)
17
hw/arm/raspi.c | 16 ++++++++--------
18
3 files changed, 23 insertions(+), 22 deletions(-)
19
11
20
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
12
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
21
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/arm/bcm2836.h
14
--- a/hw/intc/armv7m_nvic.c
23
+++ b/include/hw/arm/bcm2836.h
15
+++ b/hw/intc/armv7m_nvic.c
24
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
25
#include "hw/arm/bcm2835_peripherals.h"
17
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
26
#include "hw/intc/bcm2836_control.h"
18
goto bad_offset;
27
19
}
28
-#define TYPE_BCM2836 "bcm2836"
20
+ if (!attrs.secure &&
29
-#define BCM2836(obj) OBJECT_CHECK(BCM2836State, (obj), TYPE_BCM2836)
21
+ !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
30
+#define TYPE_BCM283X "bcm283x"
22
+ return 0;
31
+#define BCM283X(obj) OBJECT_CHECK(BCM283XState, (obj), TYPE_BCM283X)
23
+ }
32
24
return cpu->env.v7m.bfar;
33
-#define BCM2836_NCPUS 4
25
case 0xd3c: /* Aux Fault Status. */
34
+#define BCM283X_NCPUS 4
26
/* TODO: Implement fault status registers. */
35
27
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
36
-typedef struct BCM2836State {
28
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
37
+typedef struct BCM283XState {
29
goto bad_offset;
38
/*< private >*/
30
}
39
DeviceState parent_obj;
31
+ if (!attrs.secure &&
40
/*< public >*/
32
+ !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
41
@@ -XXX,XX +XXX,XX @@ typedef struct BCM2836State {
33
+ return;
42
char *cpu_type;
34
+ }
43
uint32_t enabled_cpus;
35
cpu->env.v7m.bfar = value;
44
36
return;
45
- ARMCPU cpus[BCM2836_NCPUS];
37
case 0xd3c: /* Aux Fault Status. */
46
+ ARMCPU cpus[BCM283X_NCPUS];
38
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
47
BCM2836ControlState control;
39
val = 0;
48
BCM2835PeripheralState peripherals;
40
break;
49
-} BCM2836State;
41
};
50
+} BCM283XState;
42
- /* The BFSR bits [15:8] are shared between security states
51
43
- * and we store them in the NS copy
52
#endif /* BCM2836_H */
44
+ /*
53
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
45
+ * The BFSR bits [15:8] are shared between security states
54
index XXXXXXX..XXXXXXX 100644
46
+ * and we store them in the NS copy. They are RAZ/WI for
55
--- a/hw/arm/bcm2836.c
47
+ * NS code if AIRCR.BFHFNMINS is 0.
56
+++ b/hw/arm/bcm2836.c
57
@@ -XXX,XX +XXX,XX @@
58
59
static void bcm2836_init(Object *obj)
60
{
61
- BCM2836State *s = BCM2836(obj);
62
+ BCM283XState *s = BCM283X(obj);
63
64
object_initialize(&s->control, sizeof(s->control), TYPE_BCM2836_CONTROL);
65
object_property_add_child(obj, "control", OBJECT(&s->control), NULL);
66
@@ -XXX,XX +XXX,XX @@ static void bcm2836_init(Object *obj)
67
68
static void bcm2836_realize(DeviceState *dev, Error **errp)
69
{
70
- BCM2836State *s = BCM2836(dev);
71
+ BCM283XState *s = BCM283X(dev);
72
Object *obj;
73
Error *err = NULL;
74
int n;
75
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
76
/* common peripherals from bcm2835 */
77
78
obj = OBJECT(dev);
79
- for (n = 0; n < BCM2836_NCPUS; n++) {
80
+ for (n = 0; n < BCM283X_NCPUS; n++) {
81
object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
82
s->cpu_type);
83
object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
84
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
85
sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 1,
86
qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-fiq", 0));
87
88
- for (n = 0; n < BCM2836_NCPUS; n++) {
89
+ for (n = 0; n < BCM283X_NCPUS; n++) {
90
/* Mirror bcm2836, which has clusterid set to 0xf
91
* TODO: this should be converted to a property of ARM_CPU
92
*/
48
*/
93
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
49
val = s->cpu->env.v7m.cfsr[attrs.secure];
94
}
50
- val |= s->cpu->env.v7m.cfsr[M_REG_NS] & R_V7M_CFSR_BFSR_MASK;
95
51
+ if (!attrs.secure &&
96
static Property bcm2836_props[] = {
52
+ !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
97
- DEFINE_PROP_STRING("cpu-type", BCM2836State, cpu_type),
53
+ val &= ~R_V7M_CFSR_BFSR_MASK;
98
- DEFINE_PROP_UINT32("enabled-cpus", BCM2836State, enabled_cpus, BCM2836_NCPUS),
54
+ } else {
99
+ DEFINE_PROP_STRING("cpu-type", BCM283XState, cpu_type),
55
+ val |= s->cpu->env.v7m.cfsr[M_REG_NS] & R_V7M_CFSR_BFSR_MASK;
100
+ DEFINE_PROP_UINT32("enabled-cpus", BCM283XState, enabled_cpus,
56
+ }
101
+ BCM283X_NCPUS),
57
val = extract32(val, (offset - 0xd28) * 8, size * 8);
102
DEFINE_PROP_END_OF_LIST()
58
break;
103
};
59
case 0xfe0 ... 0xfff: /* ID. */
104
60
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
105
@@ -XXX,XX +XXX,XX @@ static void bcm2836_class_init(ObjectClass *oc, void *data)
61
*/
106
}
62
value <<= ((offset - 0xd28) * 8);
107
63
108
static const TypeInfo bcm2836_type_info = {
64
+ if (!attrs.secure &&
109
- .name = TYPE_BCM2836,
65
+ !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
110
+ .name = TYPE_BCM283X,
66
+ /* BFSR bits are RAZ/WI for NS if BFHFNMINS is set */
111
.parent = TYPE_DEVICE,
67
+ value &= ~R_V7M_CFSR_BFSR_MASK;
112
- .instance_size = sizeof(BCM2836State),
68
+ }
113
+ .instance_size = sizeof(BCM283XState),
69
+
114
.instance_init = bcm2836_init,
70
s->cpu->env.v7m.cfsr[attrs.secure] &= ~value;
115
.class_init = bcm2836_class_init,
71
if (attrs.secure) {
116
};
72
/* The BFSR bits [15:8] are shared between security states
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
}
164
DEFINE_MACHINE("raspi3", raspi3_machine_init)
165
--
73
--
166
2.16.2
74
2.20.1
167
75
168
76
diff view generated by jsdifflib
1
If we're directly booting a Linux kernel and the CPU supports both
1
The M-profile architecture specifies that the DebugMonitor exception
2
EL3 and EL2, we start the kernel in EL2, as it expects. We must also
2
should be initially disabled, not enabled. It should be controlled
3
set the SCR_EL3.HCE bit in this situation, so that the HVC
3
by the DEMCR register's MON_EN bit, but we don't implement that
4
instruction is enabled rather than UNDEFing. Otherwise at least some
4
register yet (like most of the debug architecture for M-profile).
5
kernels will panic when trying to initialize KVM in the guest.
5
6
Note that BKPT instructions will still work, because they
7
will be escalated to HardFault.
6
8
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20180313153458.26822-4-peter.maydell@linaro.org
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20190430131439.25251-4-peter.maydell@linaro.org
9
---
12
---
10
hw/arm/boot.c | 5 +++++
13
hw/intc/armv7m_nvic.c | 4 +++-
11
1 file changed, 5 insertions(+)
14
1 file changed, 3 insertions(+), 1 deletion(-)
12
15
13
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
16
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/boot.c
18
--- a/hw/intc/armv7m_nvic.c
16
+++ b/hw/arm/boot.c
19
+++ b/hw/intc/armv7m_nvic.c
17
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
20
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_reset(DeviceState *dev)
18
assert(!info->secure_board_setup);
21
* the System Handler Control register
19
}
22
*/
20
23
s->vectors[ARMV7M_EXCP_SVC].enabled = 1;
21
+ if (arm_feature(env, ARM_FEATURE_EL2)) {
24
- s->vectors[ARMV7M_EXCP_DEBUG].enabled = 1;
22
+ /* If we have EL2 then Linux expects the HVC insn to work */
25
s->vectors[ARMV7M_EXCP_PENDSV].enabled = 1;
23
+ env->cp15.scr_el3 |= SCR_HCE;
26
s->vectors[ARMV7M_EXCP_SYSTICK].enabled = 1;
24
+ }
27
28
+ /* DebugMonitor is enabled via DEMCR.MON_EN */
29
+ s->vectors[ARMV7M_EXCP_DEBUG].enabled = 0;
25
+
30
+
26
/* Set to non-secure if not a secure boot */
31
resetprio = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? -4 : -3;
27
if (!info->secure_boot &&
32
s->vectors[ARMV7M_EXCP_RESET].prio = resetprio;
28
(cs != first_cpu || !info->secure_board_setup)) {
33
s->vectors[ARMV7M_EXCP_NMI].prio = -2;
29
--
34
--
30
2.16.2
35
2.20.1
31
36
32
37
diff view generated by jsdifflib
1
Add some assertions that if we're about to boot an AArch64 kernel,
1
In the M-profile architecture, if the CPU implements the DSP extension
2
the board code has not mistakenly set either secure_boot or
2
then the XPSR has GE bits, in the same way as the A-profile CPSR. When
3
secure_board_setup. It doesn't make sense to set secure_boot,
3
we added DSP extension support we forgot to add support for reading
4
because all AArch64 kernels must be booted in non-secure mode.
4
and writing the GE bits, which are stored in env->GE. We did put in
5
5
the code to add XPSR_GE to the mask of bits to update in the v7m_msr
6
It might in theory make sense to set secure_board_setup, but
6
helper, but forgot it in v7m_mrs. We also must not allow the XPSR we
7
we don't currently support that, because only the AArch32
7
pull off the stack on exception return to set the nonexistent GE bits.
8
bootloader[] code calls this hook; bootloader_aarch64[] does not.
8
Correct these errors:
9
Since we don't have a current need for this functionality, just
9
* read and write env->GE in xpsr_read() and xpsr_write()
10
assert that we don't try to use it. If it's needed we'll add
10
* only set GE bits on exception return if DSP present
11
it later.
11
* read GE bits for MRS if DSP present
12
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20180313153458.26822-3-peter.maydell@linaro.org
15
Message-id: 20190430131439.25251-5-peter.maydell@linaro.org
16
---
16
---
17
hw/arm/boot.c | 7 +++++++
17
target/arm/cpu.h | 4 ++++
18
1 file changed, 7 insertions(+)
18
target/arm/helper.c | 12 ++++++++++--
19
2 files changed, 14 insertions(+), 2 deletions(-)
19
20
20
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/boot.c
23
--- a/target/arm/cpu.h
23
+++ b/hw/arm/boot.c
24
+++ b/target/arm/cpu.h
24
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
25
@@ -XXX,XX +XXX,XX @@ static inline uint32_t xpsr_read(CPUARMState *env)
25
} else {
26
| (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
26
env->pstate = PSTATE_MODE_EL1h;
27
| (env->thumb << 24) | ((env->condexec_bits & 3) << 25)
27
}
28
| ((env->condexec_bits & 0xfc) << 8)
28
+ /* AArch64 kernels never boot in secure mode */
29
+ | (env->GE << 16)
29
+ assert(!info->secure_boot);
30
| env->v7m.exception;
30
+ /* This hook is only supported for AArch32 currently:
31
}
31
+ * bootloader_aarch64[] will not call the hook, and
32
32
+ * the code above has already dropped us into EL2 or EL1.
33
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
33
+ */
34
if (mask & XPSR_Q) {
34
+ assert(!info->secure_board_setup);
35
env->QF = ((val & XPSR_Q) != 0);
35
}
36
}
36
37
+ if (mask & XPSR_GE) {
37
/* Set to non-secure if not a secure boot */
38
+ env->GE = (val & XPSR_GE) >> 16;
39
+ }
40
if (mask & XPSR_T) {
41
env->thumb = ((val & XPSR_T) != 0);
42
}
43
diff --git a/target/arm/helper.c b/target/arm/helper.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/helper.c
46
+++ b/target/arm/helper.c
47
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
48
{
49
CPUARMState *env = &cpu->env;
50
uint32_t excret;
51
- uint32_t xpsr;
52
+ uint32_t xpsr, xpsr_mask;
53
bool ufault = false;
54
bool sfault = false;
55
bool return_to_sp_process;
56
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
57
}
58
*frame_sp_p = frameptr;
59
}
60
+
61
+ xpsr_mask = ~(XPSR_SPREALIGN | XPSR_SFPA);
62
+ if (!arm_feature(env, ARM_FEATURE_THUMB_DSP)) {
63
+ xpsr_mask &= ~XPSR_GE;
64
+ }
65
/* This xpsr_write() will invalidate frame_sp_p as it may switch stack */
66
- xpsr_write(env, xpsr, ~(XPSR_SPREALIGN | XPSR_SFPA));
67
+ xpsr_write(env, xpsr, xpsr_mask);
68
69
if (env->v7m.secure) {
70
bool sfpa = xpsr & XPSR_SFPA;
71
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
72
}
73
if (!(reg & 4)) {
74
mask |= XPSR_NZCV | XPSR_Q; /* APSR */
75
+ if (arm_feature(env, ARM_FEATURE_THUMB_DSP)) {
76
+ mask |= XPSR_GE;
77
+ }
78
}
79
/* EPSR reads as zero */
80
return xpsr_read(env) & mask;
38
--
81
--
39
2.16.2
82
2.20.1
40
83
41
84
diff view generated by jsdifflib
1
For the rpi1 and 2 we want to boot the Linux kernel via some
1
Currently the dc_zva helper function uses a variable length
2
custom setup code that makes sure that the SMC instruction
2
array. In fact we know (as the comment above remarks) that
3
acts as a no-op, because it's used for cache maintenance.
3
the length of this array is bounded because the architecture
4
The rpi3 boots AArch64 kernels, which don't need SMC for
4
limits the block size and QEMU limits the target page size.
5
cache maintenance and always expect to be booted non-secure.
5
Use a fixed array size and assert that we don't run off it.
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>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Message-id: 20180313153458.26822-2-peter.maydell@linaro.org
10
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Message-id: 20190503120448.13385-1-peter.maydell@linaro.org
12
---
12
---
13
hw/arm/raspi.c | 17 +++++++++++++----
13
target/arm/helper.c | 8 ++++++--
14
1 file changed, 13 insertions(+), 4 deletions(-)
14
1 file changed, 6 insertions(+), 2 deletions(-)
15
15
16
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/raspi.c
18
--- a/target/arm/helper.c
19
+++ b/hw/arm/raspi.c
19
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
20
@@ -XXX,XX +XXX,XX @@
21
binfo.board_id = raspi_boardid[version];
21
#include "qemu/osdep.h"
22
binfo.ram_size = ram_size;
22
+#include "qemu/units.h"
23
binfo.nb_cpus = smp_cpus;
23
#include "target/arm/idau.h"
24
- binfo.board_setup_addr = BOARDSETUP_ADDR;
24
#include "trace.h"
25
- binfo.write_board_setup = write_board_setup;
25
#include "cpu.h"
26
- binfo.secure_board_setup = true;
26
@@ -XXX,XX +XXX,XX @@ void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in)
27
- binfo.secure_boot = true;
27
* We know that in fact for any v8 CPU the page size is at least 4K
28
* and the block size must be 2K or less, but TARGET_PAGE_SIZE is only
29
* 1K as an artefact of legacy v5 subpage support being present in the
30
- * same QEMU executable.
31
+ * same QEMU executable. So in practice the hostaddr[] array has
32
+ * two entries, given the current setting of TARGET_PAGE_BITS_MIN.
33
*/
34
int maxidx = DIV_ROUND_UP(blocklen, TARGET_PAGE_SIZE);
35
- void *hostaddr[maxidx];
36
+ void *hostaddr[DIV_ROUND_UP(2 * KiB, 1 << TARGET_PAGE_BITS_MIN)];
37
int try, i;
38
unsigned mmu_idx = cpu_mmu_index(env, false);
39
TCGMemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
40
41
+ assert(maxidx <= ARRAY_SIZE(hostaddr));
28
+
42
+
29
+ if (version <= 2) {
43
for (try = 0; try < 2; try++) {
30
+ /* The rpi1 and 2 require some custom setup code to run in Secure
44
31
+ * mode before booting a kernel (to set up the SMC vectors so
45
for (i = 0; i < maxidx; i++) {
32
+ * that we get a no-op SMC; this is used by Linux to call the
33
+ * firmware for some cache maintenance operations.
34
+ * The rpi3 doesn't need this.
35
+ */
36
+ binfo.board_setup_addr = BOARDSETUP_ADDR;
37
+ binfo.write_board_setup = write_board_setup;
38
+ binfo.secure_board_setup = true;
39
+ binfo.secure_boot = true;
40
+ }
41
42
/* Pi2 and Pi3 requires SMP setup */
43
if (version >= 2) {
44
--
46
--
45
2.16.2
47
2.20.1
46
48
47
49
diff view generated by jsdifflib