1
Arm patch queue -- these are all bug fix patches but we might
1
Hi; this is a collection of mostly GIC related patches for rc3.
2
as well put them in to rc0...
2
The "Update cached state after LPI state changes" fix is important
3
and fixes what would otherwise be a regression since we enable the
4
ITS by default in the virt board now. The others are not regressions
5
but I think are OK for rc3 as they're fairly self contained (and two
6
of them are fixes to new-in-6.2 functionality).
3
7
4
thanks
8
thanks
5
-- PMM
9
-- PMM
6
10
7
The following changes since commit 2c8cfc0b52b5a4d123c26c0b5fdf941be24805be:
11
The following changes since commit dd4b0de45965538f19bb40c7ddaaba384a8c613a:
8
12
9
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2018-03-19 11:44:26 +0000)
13
Fix version for v6.2.0-rc2 release (2021-11-26 11:58:54 +0100)
10
14
11
are available in the Git repository at:
15
are available in the Git repository at:
12
16
13
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180319
17
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20211129
14
18
15
for you to fetch changes up to ff72cb6b46b95bb530787add5277c211af3d31c6:
19
for you to fetch changes up to 90feffad2aafe856ed2af75313b2c1669ba671e9:
16
20
17
hw/arm/raspi: Provide spin-loop code for AArch64 CPUs (2018-03-19 18:23:24 +0000)
21
hw/intc/arm_gicv3: fix handling of LPIs in list registers (2021-11-29 10:10:21 +0000)
18
22
19
----------------------------------------------------------------
23
----------------------------------------------------------------
20
target-arm queue:
24
target-arm queue:
21
* fsl-imx6: Fix incorrect Ethernet interrupt defines
25
* virt: Diagnose attempts to enable MTE or virt when using HVF accelerator
22
* dump: Update correct kdump phys_base field for AArch64
26
* GICv3 ITS: Allow clearing of ITS CTLR Enabled bit
23
* char: i.MX: Add support for "TX complete" interrupt
27
* GICv3: Update cached state after LPI state changes
24
* bcm2836/raspi: Fix various bugs resulting in panics trying
28
* GICv3: Fix handling of LPIs in list registers
25
to boot a Debian Linux kernel on raspi3
26
29
27
----------------------------------------------------------------
30
----------------------------------------------------------------
28
Andrey Smirnov (2):
31
Alexander Graf (1):
29
char: i.MX: Simplify imx_update()
32
hw/arm/virt: Extend nested and mte checks to hvf
30
char: i.MX: Add support for "TX complete" interrupt
31
33
32
Guenter Roeck (1):
34
Peter Maydell (3):
33
fsl-imx6: Swap Ethernet interrupt defines
35
hw/intc/arm_gicv3: Update cached state after LPI state changes
36
hw/intc/arm_gicv3: Add new gicv3_intid_is_special() function
37
hw/intc/arm_gicv3: fix handling of LPIs in list registers
34
38
35
Peter Maydell (9):
39
Shashi Mallela (1):
36
hw/arm/raspi: Don't do board-setup or secure-boot for raspi3
40
hw/intc: cannot clear GICv3 ITS CTLR[Enabled] bit
37
hw/arm/boot: assert that secure_boot and secure_board_setup are false for AArch64
38
hw/arm/boot: If booting a kernel in EL2, set SCR_EL3.HCE
39
hw/arm/bcm2386: Fix parent type of bcm2386
40
hw/arm/bcm2836: Rename bcm2836 type/struct to bcm283x
41
hw/arm/bcm2836: Create proper bcm2837 device
42
hw/arm/bcm2836: Use correct affinity values for BCM2837
43
hw/arm/bcm2836: Hardcode correct CPU type
44
hw/arm/raspi: Provide spin-loop code for AArch64 CPUs
45
41
46
Wei Huang (1):
42
hw/intc/gicv3_internal.h | 30 ++++++++++++++++++++++++++++++
47
dump: Update correct kdump phys_base field for AArch64
43
hw/arm/virt.c | 15 +++++++++------
44
hw/intc/arm_gicv3.c | 6 ++++--
45
hw/intc/arm_gicv3_cpuif.c | 9 ++++-----
46
hw/intc/arm_gicv3_its.c | 7 ++++---
47
hw/intc/arm_gicv3_redist.c | 14 ++++++++++----
48
6 files changed, 61 insertions(+), 20 deletions(-)
48
49
49
include/hw/arm/bcm2836.h | 31 +++++++++++++---
50
include/hw/arm/fsl-imx6.h | 4 +-
51
include/hw/char/imx_serial.h | 3 ++
52
dump.c | 14 +++++--
53
hw/arm/bcm2836.c | 87 +++++++++++++++++++++++++++++++-------------
54
hw/arm/boot.c | 12 ++++++
55
hw/arm/raspi.c | 77 +++++++++++++++++++++++++++++++--------
56
hw/char/imx_serial.c | 44 ++++++++++++++++------
57
hw/net/imx_fec.c | 28 +++++++++++++-
58
9 files changed, 237 insertions(+), 63 deletions(-)
59
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
The sabrelite machine model used by qemu-system-arm is based on the
3
The virt machine has properties to enable MTE and Nested Virtualization
4
Freescale/NXP i.MX6Q processor. This SoC has an on-board ethernet
4
support. However, its check to ensure the backing accel implementation
5
controller which is supported in QEMU using the imx_fec.c module
5
supports it today only looks for KVM and bails out if it finds it.
6
(actually called imx.enet for this model.)
7
6
8
The include/hw/arm/fsm-imx6.h file defines the interrupt vectors for the
7
Extend the checks to HVF as well as it does not support either today.
9
imx.enet device like this:
8
This will cause QEMU to print a useful error message rather than
9
silently ignoring the attempt by the user to enable either MTE or
10
the Virtualization extensions.
10
11
11
#define FSL_IMX6_ENET_MAC_1588_IRQ 118
12
Reported-by: saar amar <saaramar5@gmail.com>
12
#define FSL_IMX6_ENET_MAC_IRQ 119
13
Signed-off-by: Alexander Graf <agraf@csgraf.de>
13
14
Message-id: 20211123122859.22452-1-agraf@csgraf.de
14
According to https://www.nxp.com/docs/en/reference-manual/IMX6DQRM.pdf,
15
page 225, in Table 3-1. ARM Cortex A9 domain interrupt summary,
16
interrupts are as follows.
17
18
150 ENET MAC 0 IRQ
19
151 ENET MAC 0 1588 Timer interrupt
20
21
where
22
23
150 - 32 == 118
24
151 - 32 == 119
25
26
In other words, the vector definitions in the fsl-imx6.h file are reversed.
27
28
Fixing the interrupts alone causes problems with older Linux kernels:
29
The Ethernet interface will fail to probe with Linux v4.9 and earlier.
30
Linux v4.1 and earlier will crash due to a bug in Ethernet driver probe
31
error handling. This is a Linux kernel problem, not a qemu problem:
32
the Linux kernel only worked by accident since it requested both interrupts.
33
34
For backward compatibility, generate the Ethernet interrupt on both interrupt
35
lines. This was shown to work from all Linux kernel releases starting with
36
v3.16.
37
38
Link: https://bugs.launchpad.net/qemu/+bug/1753309
39
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
40
Message-id: 1520723090-22130-1-git-send-email-linux@roeck-us.net
41
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
42
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
43
---
17
---
44
include/hw/arm/fsl-imx6.h | 4 ++--
18
hw/arm/virt.c | 15 +++++++++------
45
hw/net/imx_fec.c | 28 +++++++++++++++++++++++++++-
19
1 file changed, 9 insertions(+), 6 deletions(-)
46
2 files changed, 29 insertions(+), 3 deletions(-)
47
20
48
diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h
21
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
49
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
50
--- a/include/hw/arm/fsl-imx6.h
23
--- a/hw/arm/virt.c
51
+++ b/include/hw/arm/fsl-imx6.h
24
+++ b/hw/arm/virt.c
52
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX6State {
25
@@ -XXX,XX +XXX,XX @@
53
#define FSL_IMX6_HDMI_MASTER_IRQ 115
26
#include "sysemu/runstate.h"
54
#define FSL_IMX6_HDMI_CEC_IRQ 116
27
#include "sysemu/tpm.h"
55
#define FSL_IMX6_MLB150_LOW_IRQ 117
28
#include "sysemu/kvm.h"
56
-#define FSL_IMX6_ENET_MAC_1588_IRQ 118
29
+#include "sysemu/hvf.h"
57
-#define FSL_IMX6_ENET_MAC_IRQ 119
30
#include "hw/loader.h"
58
+#define FSL_IMX6_ENET_MAC_IRQ 118
31
#include "qapi/error.h"
59
+#define FSL_IMX6_ENET_MAC_1588_IRQ 119
32
#include "qemu/bitops.h"
60
#define FSL_IMX6_PCIE1_IRQ 120
33
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
61
#define FSL_IMX6_PCIE2_IRQ 121
34
exit(1);
62
#define FSL_IMX6_PCIE3_IRQ 122
35
}
63
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
36
64
index XXXXXXX..XXXXXXX 100644
37
- if (vms->virt && kvm_enabled()) {
65
--- a/hw/net/imx_fec.c
38
- error_report("mach-virt: KVM does not support providing "
66
+++ b/hw/net/imx_fec.c
39
- "Virtualization extensions to the guest CPU");
67
@@ -XXX,XX +XXX,XX @@ static void imx_enet_write_bd(IMXENETBufDesc *bd, dma_addr_t addr)
40
+ if (vms->virt && (kvm_enabled() || hvf_enabled())) {
68
41
+ error_report("mach-virt: %s does not support providing "
69
static void imx_eth_update(IMXFECState *s)
42
+ "Virtualization extensions to the guest CPU",
70
{
43
+ kvm_enabled() ? "KVM" : "HVF");
71
- if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] & ENET_INT_TS_TIMER) {
44
exit(1);
72
+ /*
45
}
73
+ * Previous versions of qemu had the ENET_INT_MAC and ENET_INT_TS_TIMER
46
74
+ * interrupts swapped. This worked with older versions of Linux (4.14
47
- if (vms->mte && kvm_enabled()) {
75
+ * and older) since Linux associated both interrupt lines with Ethernet
48
- error_report("mach-virt: KVM does not support providing "
76
+ * MAC interrupts. Specifically,
49
- "MTE to the guest CPU");
77
+ * - Linux 4.15 and later have separate interrupt handlers for the MAC and
50
+ if (vms->mte && (kvm_enabled() || hvf_enabled())) {
78
+ * timer interrupts. Those versions of Linux fail with versions of QEMU
51
+ error_report("mach-virt: %s does not support providing "
79
+ * with swapped interrupt assignments.
52
+ "MTE to the guest CPU",
80
+ * - In linux 4.14, both interrupt lines were registered with the Ethernet
53
+ kvm_enabled() ? "KVM" : "HVF");
81
+ * MAC interrupt handler. As a result, all versions of qemu happen to
54
exit(1);
82
+ * work, though that is accidental.
55
}
83
+ * - In Linux 4.9 and older, the timer interrupt was registered directly
56
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
--
57
--
103
2.16.2
58
2.25.1
104
59
105
60
diff view generated by jsdifflib
Deleted patch
1
From: Wei Huang <wei@redhat.com>
2
1
3
For guest kernel that supports KASLR, the load address can change every
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
10
Signed-off-by: Wei Huang <wei@redhat.com>
11
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
12
Message-id: 1520615003-20869-1-git-send-email-wei@redhat.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
dump.c | 14 +++++++++++---
16
1 file changed, 11 insertions(+), 3 deletions(-)
17
18
diff --git a/dump.c b/dump.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/dump.c
21
+++ b/dump.c
22
@@ -XXX,XX +XXX,XX @@ static void vmcoreinfo_update_phys_base(DumpState *s)
23
24
lines = g_strsplit((char *)vmci, "\n", -1);
25
for (i = 0; lines[i]; i++) {
26
- if (g_str_has_prefix(lines[i], "NUMBER(phys_base)=")) {
27
- if (qemu_strtou64(lines[i] + 18, NULL, 16,
28
+ const char *prefix = NULL;
29
+
30
+ if (s->dump_info.d_machine == EM_X86_64) {
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
--
45
2.16.2
46
47
diff view generated by jsdifflib
Deleted patch
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
2
1
3
Code of imx_update() is slightly confusing since the "flags" variable
4
doesn't really corespond to anything in real hardware and server as a
5
kitchensink accumulating events normally reported via USR1 and USR2
6
registers.
7
8
Change the code to explicitly evaluate state of interrupts reported
9
via USR1 and USR2 against corresponding masking bits and use the to
10
detemine if IRQ line should be asserted or not.
11
12
NOTE: Check for UTS1_TXEMPTY being set has been dropped for two
13
reasons:
14
15
1. Emulation code implements a single character FIFO, so this flag
16
will always be set since characters are trasmitted as a part of
17
the code emulating "push" into the FIFO
18
19
2. imx_update() is really just a function doing ORing and maksing
20
of reported events, so checking for UTS1_TXEMPTY should happen,
21
if it's ever really needed should probably happen outside of
22
it.
23
24
Cc: qemu-devel@nongnu.org
25
Cc: qemu-arm@nongnu.org
26
Cc: Bill Paul <wpaul@windriver.com>
27
Cc: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
29
Message-id: 20180315191141.6789-1-andrew.smirnov@gmail.com
30
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
31
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
---
33
hw/char/imx_serial.c | 24 ++++++++++++++++--------
34
1 file changed, 16 insertions(+), 8 deletions(-)
35
36
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/char/imx_serial.c
39
+++ b/hw/char/imx_serial.c
40
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_serial = {
41
42
static void imx_update(IMXSerialState *s)
43
{
44
- uint32_t flags;
45
+ uint32_t usr1;
46
+ uint32_t usr2;
47
+ uint32_t mask;
48
49
- flags = (s->usr1 & s->ucr1) & (USR1_TRDY|USR1_RRDY);
50
- if (s->ucr1 & UCR1_TXMPTYEN) {
51
- flags |= (s->uts1 & UTS1_TXEMPTY);
52
- } else {
53
- flags &= ~USR1_TRDY;
54
- }
55
+ /*
56
+ * Lucky for us TRDY and RRDY has the same offset in both USR1 and
57
+ * UCR1, so we can get away with something as simple as the
58
+ * following:
59
+ */
60
+ usr1 = s->usr1 & s->ucr1 & (USR1_TRDY | USR1_RRDY);
61
+ /*
62
+ * Bits that we want in USR2 are not as conveniently laid out,
63
+ * unfortunately.
64
+ */
65
+ mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
66
+ usr2 = s->usr2 & mask;
67
68
- qemu_set_irq(s->irq, !!flags);
69
+ qemu_set_irq(s->irq, usr1 || usr2);
70
}
71
72
static void imx_serial_reset(IMXSerialState *s)
73
--
74
2.16.2
75
76
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Shashi Mallela <shashi.mallela@linaro.org>
2
2
3
Add support for "TX complete"/TXDC interrupt generate by real HW since
3
When Enabled bit is cleared in GITS_CTLR,ITS feature continues
4
it is needed to support guests other than Linux.
4
to be enabled.This patch fixes the issue.
5
5
6
Based on the patch by Bill Paul as found here:
6
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
7
https://bugs.launchpad.net/qemu/+bug/1753314
7
Tested-by: Alex Bennée <alex.bennee@linaro.org>
8
9
Cc: qemu-devel@nongnu.org
10
Cc: qemu-arm@nongnu.org
11
Cc: Bill Paul <wpaul@windriver.com>
12
Cc: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Bill Paul <wpaul@windriver.com>
14
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
15
Message-id: 20180315191141.6789-2-andrew.smirnov@gmail.com
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20211124182246.67691-1-shashi.mallela@linaro.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
11
---
19
include/hw/char/imx_serial.h | 3 +++
12
hw/intc/arm_gicv3_its.c | 7 ++++---
20
hw/char/imx_serial.c | 20 +++++++++++++++++---
13
1 file changed, 4 insertions(+), 3 deletions(-)
21
2 files changed, 20 insertions(+), 3 deletions(-)
22
14
23
diff --git a/include/hw/char/imx_serial.h b/include/hw/char/imx_serial.h
15
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
24
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/char/imx_serial.h
17
--- a/hw/intc/arm_gicv3_its.c
26
+++ b/include/hw/char/imx_serial.h
18
+++ b/hw/intc/arm_gicv3_its.c
27
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
28
#define UCR2_RXEN (1<<1) /* Receiver enable */
20
29
#define UCR2_SRST (1<<0) /* Reset complete */
21
switch (offset) {
30
22
case GITS_CTLR:
31
+#define UCR4_TCEN BIT(3) /* TX complete interrupt enable */
23
- s->ctlr |= (value & ~(s->ctlr));
32
+
24
-
33
#define UTS1_TXEMPTY (1<<6)
25
- if (s->ctlr & ITS_CTLR_ENABLED) {
34
#define UTS1_RXEMPTY (1<<5)
26
+ if (value & R_GITS_CTLR_ENABLED_MASK) {
35
#define UTS1_TXFULL (1<<4)
27
+ s->ctlr |= ITS_CTLR_ENABLED;
36
@@ -XXX,XX +XXX,XX @@ typedef struct IMXSerialState {
28
extract_table_params(s);
37
uint32_t ubmr;
29
extract_cmdq_params(s);
38
uint32_t ubrc;
30
s->creadr = 0;
39
uint32_t ucr3;
31
process_cmdq(s);
40
+ uint32_t ucr4;
32
+ } else {
41
33
+ s->ctlr &= ~ITS_CTLR_ENABLED;
42
qemu_irq irq;
43
CharBackend chr;
44
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/char/imx_serial.c
47
+++ b/hw/char/imx_serial.c
48
@@ -XXX,XX +XXX,XX @@
49
50
static const VMStateDescription vmstate_imx_serial = {
51
.name = TYPE_IMX_SERIAL,
52
- .version_id = 1,
53
- .minimum_version_id = 1,
54
+ .version_id = 2,
55
+ .minimum_version_id = 2,
56
.fields = (VMStateField[]) {
57
VMSTATE_INT32(readbuff, IMXSerialState),
58
VMSTATE_UINT32(usr1, IMXSerialState),
59
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_serial = {
60
VMSTATE_UINT32(ubmr, IMXSerialState),
61
VMSTATE_UINT32(ubrc, IMXSerialState),
62
VMSTATE_UINT32(ucr3, IMXSerialState),
63
+ VMSTATE_UINT32(ucr4, IMXSerialState),
64
VMSTATE_END_OF_LIST()
65
},
66
};
67
@@ -XXX,XX +XXX,XX @@ static void imx_update(IMXSerialState *s)
68
* unfortunately.
69
*/
70
mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
71
+ /*
72
+ * TCEN and TXDC are both bit 3
73
+ */
74
+ mask |= s->ucr4 & UCR4_TCEN;
75
+
76
usr2 = s->usr2 & mask;
77
78
qemu_set_irq(s->irq, usr1 || usr2);
79
@@ -XXX,XX +XXX,XX @@ static uint64_t imx_serial_read(void *opaque, hwaddr offset,
80
return s->ucr3;
81
82
case 0x23: /* UCR4 */
83
+ return s->ucr4;
84
+
85
case 0x29: /* BRM Incremental */
86
return 0x0; /* TODO */
87
88
@@ -XXX,XX +XXX,XX @@ static void imx_serial_write(void *opaque, hwaddr offset,
89
* qemu_chr_fe_write and background I/O callbacks */
90
qemu_chr_fe_write_all(&s->chr, &ch, 1);
91
s->usr1 &= ~USR1_TRDY;
92
+ s->usr2 &= ~USR2_TXDC;
93
imx_update(s);
94
s->usr1 |= USR1_TRDY;
95
+ s->usr2 |= USR2_TXDC;
96
imx_update(s);
97
}
34
}
98
break;
35
break;
99
@@ -XXX,XX +XXX,XX @@ static void imx_serial_write(void *opaque, hwaddr offset,
36
case GITS_CBASER:
100
s->ucr3 = value & 0xffff;
101
break;
102
103
- case 0x2d: /* UTS1 */
104
case 0x23: /* UCR4 */
105
+ s->ucr4 = value & 0xffff;
106
+ imx_update(s);
107
+ break;
108
+
109
+ case 0x2d: /* UTS1 */
110
qemu_log_mask(LOG_UNIMP, "[%s]%s: Unimplemented reg 0x%"
111
HWADDR_PRIx "\n", TYPE_IMX_SERIAL, __func__, offset);
112
/* TODO */
113
--
37
--
114
2.16.2
38
2.25.1
115
39
116
40
diff view generated by jsdifflib
Deleted patch
1
For the rpi1 and 2 we want to boot the Linux kernel via some
2
custom setup code that makes sure that the SMC instruction
3
acts as a no-op, because it's used for cache maintenance.
4
The rpi3 boots AArch64 kernels, which don't need SMC for
5
cache maintenance and always expect to be booted non-secure.
6
Don't fill in the aarch32-specific parts of the binfo struct.
7
1
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20180313153458.26822-2-peter.maydell@linaro.org
12
---
13
hw/arm/raspi.c | 17 +++++++++++++----
14
1 file changed, 13 insertions(+), 4 deletions(-)
15
16
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/raspi.c
19
+++ b/hw/arm/raspi.c
20
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
21
binfo.board_id = raspi_boardid[version];
22
binfo.ram_size = ram_size;
23
binfo.nb_cpus = smp_cpus;
24
- binfo.board_setup_addr = BOARDSETUP_ADDR;
25
- binfo.write_board_setup = write_board_setup;
26
- binfo.secure_board_setup = true;
27
- binfo.secure_boot = true;
28
+
29
+ if (version <= 2) {
30
+ /* The rpi1 and 2 require some custom setup code to run in Secure
31
+ * mode before booting a kernel (to set up the SMC vectors so
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
--
45
2.16.2
46
47
diff view generated by jsdifflib
Deleted patch
1
Add some assertions that if we're about to boot an AArch64 kernel,
2
the board code has not mistakenly set either secure_boot or
3
secure_board_setup. It doesn't make sense to set secure_boot,
4
because all AArch64 kernels must be booted in non-secure mode.
5
1
6
It might in theory make sense to set secure_board_setup, but
7
we don't currently support that, because only the AArch32
8
bootloader[] code calls this hook; bootloader_aarch64[] does not.
9
Since we don't have a current need for this functionality, just
10
assert that we don't try to use it. If it's needed we'll add
11
it later.
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Message-id: 20180313153458.26822-3-peter.maydell@linaro.org
16
---
17
hw/arm/boot.c | 7 +++++++
18
1 file changed, 7 insertions(+)
19
20
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/boot.c
23
+++ b/hw/arm/boot.c
24
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
25
} else {
26
env->pstate = PSTATE_MODE_EL1h;
27
}
28
+ /* AArch64 kernels never boot in secure mode */
29
+ assert(!info->secure_boot);
30
+ /* This hook is only supported for AArch32 currently:
31
+ * bootloader_aarch64[] will not call the hook, and
32
+ * the code above has already dropped us into EL2 or EL1.
33
+ */
34
+ assert(!info->secure_board_setup);
35
}
36
37
/* Set to non-secure if not a secure boot */
38
--
39
2.16.2
40
41
diff view generated by jsdifflib
Deleted patch
1
If we're directly booting a Linux kernel and the CPU supports both
2
EL3 and EL2, we start the kernel in EL2, as it expects. We must also
3
set the SCR_EL3.HCE bit in this situation, so that the HVC
4
instruction is enabled rather than UNDEFing. Otherwise at least some
5
kernels will panic when trying to initialize KVM in the guest.
6
1
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20180313153458.26822-4-peter.maydell@linaro.org
9
---
10
hw/arm/boot.c | 5 +++++
11
1 file changed, 5 insertions(+)
12
13
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/boot.c
16
+++ b/hw/arm/boot.c
17
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
18
assert(!info->secure_board_setup);
19
}
20
21
+ if (arm_feature(env, ARM_FEATURE_EL2)) {
22
+ /* If we have EL2 then Linux expects the HVC insn to work */
23
+ env->cp15.scr_el3 |= SCR_HCE;
24
+ }
25
+
26
/* Set to non-secure if not a secure boot */
27
if (!info->secure_boot &&
28
(cs != first_cpu || !info->secure_board_setup)) {
29
--
30
2.16.2
31
32
diff view generated by jsdifflib
Deleted patch
1
The TypeInfo and state struct for bcm2386 disagree about what the
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
1
10
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
---
15
hw/arm/bcm2836.c | 2 +-
16
1 file changed, 1 insertion(+), 1 deletion(-)
17
18
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/bcm2836.c
21
+++ b/hw/arm/bcm2836.c
22
@@ -XXX,XX +XXX,XX @@ static void bcm2836_class_init(ObjectClass *oc, void *data)
23
24
static const TypeInfo bcm2836_type_info = {
25
.name = TYPE_BCM2836,
26
- .parent = TYPE_SYS_BUS_DEVICE,
27
+ .parent = TYPE_DEVICE,
28
.instance_size = sizeof(BCM2836State),
29
.instance_init = bcm2836_init,
30
.class_init = bcm2836_class_init,
31
--
32
2.16.2
33
34
diff view generated by jsdifflib
Deleted patch
1
Our BCM2836 type is really a generic one that can be any of
2
the bcm283x family. Rename it accordingly. We change only
3
the names which are visible via the header file to the
4
rest of the QEMU code, leaving private function names
5
in bcm2836.c as they are.
6
1
7
This is a preliminary to making bcm283x be an abstract
8
parent class to specific types for the bcm2836 and bcm2837.
9
10
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-6-peter.maydell@linaro.org
14
---
15
include/hw/arm/bcm2836.h | 12 ++++++------
16
hw/arm/bcm2836.c | 17 +++++++++--------
17
hw/arm/raspi.c | 16 ++++++++--------
18
3 files changed, 23 insertions(+), 22 deletions(-)
19
20
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/arm/bcm2836.h
23
+++ b/include/hw/arm/bcm2836.h
24
@@ -XXX,XX +XXX,XX @@
25
#include "hw/arm/bcm2835_peripherals.h"
26
#include "hw/intc/bcm2836_control.h"
27
28
-#define TYPE_BCM2836 "bcm2836"
29
-#define BCM2836(obj) OBJECT_CHECK(BCM2836State, (obj), TYPE_BCM2836)
30
+#define TYPE_BCM283X "bcm283x"
31
+#define BCM283X(obj) OBJECT_CHECK(BCM283XState, (obj), TYPE_BCM283X)
32
33
-#define BCM2836_NCPUS 4
34
+#define BCM283X_NCPUS 4
35
36
-typedef struct BCM2836State {
37
+typedef struct BCM283XState {
38
/*< private >*/
39
DeviceState parent_obj;
40
/*< public >*/
41
@@ -XXX,XX +XXX,XX @@ typedef struct BCM2836State {
42
char *cpu_type;
43
uint32_t enabled_cpus;
44
45
- ARMCPU cpus[BCM2836_NCPUS];
46
+ ARMCPU cpus[BCM283X_NCPUS];
47
BCM2836ControlState control;
48
BCM2835PeripheralState peripherals;
49
-} BCM2836State;
50
+} BCM283XState;
51
52
#endif /* BCM2836_H */
53
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/arm/bcm2836.c
56
+++ b/hw/arm/bcm2836.c
57
@@ -XXX,XX +XXX,XX @@
58
59
static void bcm2836_init(Object *obj)
60
{
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
*/
93
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
94
}
95
96
static Property bcm2836_props[] = {
97
- DEFINE_PROP_STRING("cpu-type", BCM2836State, cpu_type),
98
- DEFINE_PROP_UINT32("enabled-cpus", BCM2836State, enabled_cpus, BCM2836_NCPUS),
99
+ DEFINE_PROP_STRING("cpu-type", BCM283XState, cpu_type),
100
+ DEFINE_PROP_UINT32("enabled-cpus", BCM283XState, enabled_cpus,
101
+ BCM283X_NCPUS),
102
DEFINE_PROP_END_OF_LIST()
103
};
104
105
@@ -XXX,XX +XXX,XX @@ static void bcm2836_class_init(ObjectClass *oc, void *data)
106
}
107
108
static const TypeInfo bcm2836_type_info = {
109
- .name = TYPE_BCM2836,
110
+ .name = TYPE_BCM283X,
111
.parent = TYPE_DEVICE,
112
- .instance_size = sizeof(BCM2836State),
113
+ .instance_size = sizeof(BCM283XState),
114
.instance_init = bcm2836_init,
115
.class_init = bcm2836_class_init,
116
};
117
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/hw/arm/raspi.c
120
+++ b/hw/arm/raspi.c
121
@@ -XXX,XX +XXX,XX @@
122
static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44};
123
124
typedef struct RasPiState {
125
- BCM2836State soc;
126
+ BCM283XState soc;
127
MemoryRegion ram;
128
} RasPiState;
129
130
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
131
BusState *bus;
132
DeviceState *carddev;
133
134
- object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM2836);
135
+ object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM283X);
136
object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
137
&error_abort);
138
139
@@ -XXX,XX +XXX,XX @@ static void raspi2_machine_init(MachineClass *mc)
140
mc->no_floppy = 1;
141
mc->no_cdrom = 1;
142
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
143
- mc->max_cpus = BCM2836_NCPUS;
144
- mc->min_cpus = BCM2836_NCPUS;
145
- mc->default_cpus = BCM2836_NCPUS;
146
+ mc->max_cpus = BCM283X_NCPUS;
147
+ mc->min_cpus = BCM283X_NCPUS;
148
+ mc->default_cpus = BCM283X_NCPUS;
149
mc->default_ram_size = 1024 * 1024 * 1024;
150
mc->ignore_memory_transaction_failures = true;
151
};
152
@@ -XXX,XX +XXX,XX @@ static void raspi3_machine_init(MachineClass *mc)
153
mc->no_floppy = 1;
154
mc->no_cdrom = 1;
155
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a53");
156
- mc->max_cpus = BCM2836_NCPUS;
157
- mc->min_cpus = BCM2836_NCPUS;
158
- mc->default_cpus = BCM2836_NCPUS;
159
+ mc->max_cpus = BCM283X_NCPUS;
160
+ mc->min_cpus = BCM283X_NCPUS;
161
+ mc->default_cpus = BCM283X_NCPUS;
162
mc->default_ram_size = 1024 * 1024 * 1024;
163
}
164
DEFINE_MACHINE("raspi3", raspi3_machine_init)
165
--
166
2.16.2
167
168
diff view generated by jsdifflib
1
Now we have separate types for BCM2386 and BCM2387, we might as well
1
The logic of gicv3_redist_update() is as follows:
2
just hard-code the CPU type they use rather than having it passed
2
* it must be called in any code path that changes the state of
3
through as an object property. This then lets us put the initialization
3
(only) redistributor interrupts
4
of the CPU object in init rather than realize.
4
* if it finds a redistributor interrupt that is (now) higher
5
priority than the previous highest-priority pending interrupt,
6
then this must be the new highest-priority pending interrupt
7
* if it does *not* find a better redistributor interrupt, then:
8
- if the previous state was "no interrupts pending" then
9
the new state is still "no interrupts pending"
10
- if the previous best interrupt was not a redistributor
11
interrupt then that remains the best interrupt
12
- if the previous best interrupt *was* a redistributor interrupt,
13
then the new best interrupt must be some non-redistributor
14
interrupt, but we don't know which so must do a full scan
5
15
6
Note that this change means that it's no longer possible on
16
In commit 17fb5e36aabd4b2c125 we effectively added the LPI interrupts
7
the command line to use -cpu to ask for a different kind of
17
as a kind of "redistributor interrupt" for this purpose, by adding
8
CPU than the SoC supports. This was never a supported thing to
18
cs->hpplpi to the set of things that gicv3_redist_update() considers
9
do anyway; we were just not sanity-checking the command line.
19
before it gives up and decides to do a full scan of distributor
20
interrupts. However we didn't quite get this right:
21
* the condition check for "was the previous best interrupt a
22
redistributor interrupt" must be updated to include LPIs
23
in what it considers to be redistributor interrupts
24
* every code path which updates the LPI state which
25
gicv3_redist_update() checks must also call gicv3_redist_update():
26
this is cs->hpplpi and the GICR_CTLR ENABLE_LPIS bit
10
27
11
This does require us to only build the bcm2837 object on
28
This commit fixes this by:
12
TARGET_AARCH64 configs, since otherwise it won't instantiate
29
* correcting the test on cs->hppi.irq in gicv3_redist_update()
13
due to the missing cortex-a53 device and "make check" will fail.
30
* making gicv3_redist_update_lpi() always call gicv3_redist_update()
31
* introducing a new gicv3_redist_update_lpi_only() for the one
32
callsite (the post-load hook) which must not call
33
gicv3_redist_update()
34
* making gicv3_redist_lpi_pending() always call gicv3_redist_update(),
35
either directly or via gicv3_redist_update_lpi()
36
* removing a couple of now-unnecessary calls to gicv3_redist_update()
37
from some callers of those two functions
38
* calling gicv3_redist_update() when the GICR_CTLR ENABLE_LPIS
39
bit is cleared
40
41
(This means that the not-file-local gicv3_redist_* LPI related
42
functions now all take care of the updates of internally cached
43
GICv3 information, in the same way the older functions
44
gicv3_redist_set_irq() and gicv3_redist_send_sgi() do.)
45
46
The visible effect of this bug was that when the guest acknowledged
47
an LPI by reading ICC_IAR1_EL1, we marked it as not pending in the
48
LPI data structure but still left it in cs->hppi so we would offer it
49
to the guest again. In particular for setups using an emulated GICv3
50
and ITS and using devices which use LPIs (ie PCI devices) a Linux
51
guest would complain "irq 54: nobody cared" and then hang. (The hang
52
was intermittent, presumably depending on the timing between
53
different interrupts arriving and being completed.)
14
54
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
55
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
56
Tested-by: Alex Bennée <alex.bennee@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
57
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
18
Message-id: 20180313153458.26822-9-peter.maydell@linaro.org
58
Message-id: 20211124202005.989935-1-peter.maydell@linaro.org
19
---
59
---
20
hw/arm/bcm2836.c | 24 +++++++++++++++---------
60
hw/intc/gicv3_internal.h | 17 +++++++++++++++++
21
hw/arm/raspi.c | 2 --
61
hw/intc/arm_gicv3.c | 6 ++++--
22
2 files changed, 15 insertions(+), 11 deletions(-)
62
hw/intc/arm_gicv3_redist.c | 14 ++++++++++----
63
3 files changed, 31 insertions(+), 6 deletions(-)
23
64
24
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
65
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
25
index XXXXXXX..XXXXXXX 100644
66
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/bcm2836.c
67
--- a/hw/intc/gicv3_internal.h
27
+++ b/hw/arm/bcm2836.c
68
+++ b/hw/intc/gicv3_internal.h
28
@@ -XXX,XX +XXX,XX @@
69
@@ -XXX,XX +XXX,XX @@ void gicv3_dist_set_irq(GICv3State *s, int irq, int level);
29
70
void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level);
30
struct BCM283XInfo {
71
void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level);
31
const char *name;
72
void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level);
32
+ const char *cpu_type;
73
+/**
33
int clusterid;
74
+ * gicv3_redist_update_lpi:
34
};
75
+ * @cs: GICv3CPUState
35
76
+ *
36
static const BCM283XInfo bcm283x_socs[] = {
77
+ * Scan the LPI pending table and recalculate the highest priority
37
{
78
+ * pending LPI and also the overall highest priority pending interrupt.
38
.name = TYPE_BCM2836,
79
+ */
39
+ .cpu_type = ARM_CPU_TYPE_NAME("cortex-a15"),
80
void gicv3_redist_update_lpi(GICv3CPUState *cs);
40
.clusterid = 0xf,
81
+/**
41
},
82
+ * gicv3_redist_update_lpi_only:
42
+#ifdef TARGET_AARCH64
83
+ * @cs: GICv3CPUState
43
{
84
+ *
44
.name = TYPE_BCM2837,
85
+ * Scan the LPI pending table and recalculate cs->hpplpi only,
45
+ .cpu_type = ARM_CPU_TYPE_NAME("cortex-a53"),
86
+ * without calling gicv3_redist_update() to recalculate the overall
46
.clusterid = 0x0,
87
+ * highest priority pending interrupt. This should be called after
47
},
88
+ * an incoming migration has loaded new state.
48
+#endif
89
+ */
49
};
90
+void gicv3_redist_update_lpi_only(GICv3CPUState *cs);
50
91
void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns);
51
static void bcm2836_init(Object *obj)
92
void gicv3_init_cpuif(GICv3State *s);
93
94
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
95
index XXXXXXX..XXXXXXX 100644
96
--- a/hw/intc/arm_gicv3.c
97
+++ b/hw/intc/arm_gicv3.c
98
@@ -XXX,XX +XXX,XX @@ static void gicv3_redist_update_noirqset(GICv3CPUState *cs)
99
* interrupt has reduced in priority and any other interrupt could
100
* now be the new best one).
101
*/
102
- if (!seenbetter && cs->hppi.prio != 0xff && cs->hppi.irq < GIC_INTERNAL) {
103
+ if (!seenbetter && cs->hppi.prio != 0xff &&
104
+ (cs->hppi.irq < GIC_INTERNAL ||
105
+ cs->hppi.irq >= GICV3_LPI_INTID_START)) {
106
gicv3_full_update_noirqset(cs->gic);
107
}
108
}
109
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_post_load(GICv3State *s)
110
* pending interrupt, but don't set IRQ or FIQ lines.
111
*/
112
for (i = 0; i < s->num_cpu; i++) {
113
- gicv3_redist_update_lpi(&s->cpu[i]);
114
+ gicv3_redist_update_lpi_only(&s->cpu[i]);
115
}
116
gicv3_full_update_noirqset(s);
117
/* Repopulate the cache of GICv3CPUState pointers for target CPUs */
118
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
119
index XXXXXXX..XXXXXXX 100644
120
--- a/hw/intc/arm_gicv3_redist.c
121
+++ b/hw/intc/arm_gicv3_redist.c
122
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicr_writel(GICv3CPUState *cs, hwaddr offset,
123
cs->gicr_ctlr |= GICR_CTLR_ENABLE_LPIS;
124
/* Check for any pending interr in pending table */
125
gicv3_redist_update_lpi(cs);
126
- gicv3_redist_update(cs);
127
} else {
128
cs->gicr_ctlr &= ~GICR_CTLR_ENABLE_LPIS;
129
+ /* cs->hppi might have been an LPI; recalculate */
130
+ gicv3_redist_update(cs);
131
}
132
}
133
return MEMTX_OK;
134
@@ -XXX,XX +XXX,XX @@ static void gicv3_redist_check_lpi_priority(GICv3CPUState *cs, int irq)
135
}
136
}
137
138
-void gicv3_redist_update_lpi(GICv3CPUState *cs)
139
+void gicv3_redist_update_lpi_only(GICv3CPUState *cs)
52
{
140
{
53
BCM283XState *s = BCM283X(obj);
141
/*
54
+ BCM283XClass *bc = BCM283X_GET_CLASS(obj);
142
* This function scans the LPI pending table and for each pending
55
+ const BCM283XInfo *info = bc->info;
143
@@ -XXX,XX +XXX,XX @@ void gicv3_redist_update_lpi(GICv3CPUState *cs)
56
+ int n;
144
}
145
}
146
147
+void gicv3_redist_update_lpi(GICv3CPUState *cs)
148
+{
149
+ gicv3_redist_update_lpi_only(cs);
150
+ gicv3_redist_update(cs);
151
+}
57
+
152
+
58
+ for (n = 0; n < BCM283X_NCPUS; n++) {
153
void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level)
59
+ object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
154
{
60
+ info->cpu_type);
155
/*
61
+ object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
156
@@ -XXX,XX +XXX,XX @@ void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level)
62
+ &error_abort);
157
*/
63
+ }
158
if (level) {
64
159
gicv3_redist_check_lpi_priority(cs, irq);
65
object_initialize(&s->control, sizeof(s->control), TYPE_BCM2836_CONTROL);
160
+ gicv3_redist_update(cs);
66
object_property_add_child(obj, "control", OBJECT(&s->control), NULL);
161
} else {
67
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
162
if (irq == cs->hpplpi.irq) {
68
163
gicv3_redist_update_lpi(cs);
69
/* common peripherals from bcm2835 */
164
@@ -XXX,XX +XXX,XX @@ void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level)
70
165
71
- obj = OBJECT(dev);
166
/* set/clear the pending bit for this irq */
72
- for (n = 0; n < BCM283X_NCPUS; n++) {
167
gicv3_redist_lpi_pending(cs, irq, level);
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
-
168
-
79
obj = object_property_get_link(OBJECT(dev), "ram", &err);
169
- gicv3_redist_update(cs);
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
}
170
}
84
171
85
static Property bcm2836_props[] = {
172
void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level)
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
--
173
--
104
2.16.2
174
2.25.1
105
175
106
176
diff view generated by jsdifflib
1
The bcm2837 is pretty similar to the bcm2836, but it does have
1
The GICv3/v4 pseudocode has a function IsSpecial() which returns true
2
some differences. Notably, the MPIDR affinity aff1 values it
2
if passed a "special" interrupt ID number (anything between 1020 and
3
sets for the CPUs are 0x0, rather than the 0xf that the bcm2836
3
1023 inclusive). We open-code this condition in a couple of places,
4
uses, and if this is wrong Linux will not boot.
4
so abstract it out into a new function gicv3_intid_is_special().
5
6
Rather than trying to have one device with properties that
7
configure it differently for the two cases, create two
8
separate QOM devices for the two SoCs. We use the same approach
9
as hw/arm/aspeed_soc.c and share code and have a data table
10
that might differ per-SoC. For the moment the two types don't
11
actually have different behaviour.
12
5
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Marc Zyngier <maz@kernel.org>
15
Message-id: 20180313153458.26822-7-peter.maydell@linaro.org
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
16
---
9
---
17
include/hw/arm/bcm2836.h | 19 +++++++++++++++++++
10
hw/intc/gicv3_internal.h | 13 +++++++++++++
18
hw/arm/bcm2836.c | 37 ++++++++++++++++++++++++++++++++-----
11
hw/intc/arm_gicv3_cpuif.c | 4 ++--
19
hw/arm/raspi.c | 3 ++-
12
2 files changed, 15 insertions(+), 2 deletions(-)
20
3 files changed, 53 insertions(+), 6 deletions(-)
21
13
22
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
14
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
23
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/arm/bcm2836.h
16
--- a/hw/intc/gicv3_internal.h
25
+++ b/include/hw/arm/bcm2836.h
17
+++ b/hw/intc/gicv3_internal.h
26
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ FIELD(MAPC, RDBASE, 16, 32)
27
19
28
#define BCM283X_NCPUS 4
20
/* Functions internal to the emulated GICv3 */
29
21
30
+/* These type names are for specific SoCs; other than instantiating
22
+/**
31
+ * them, code using these devices should always handle them via the
23
+ * gicv3_intid_is_special:
32
+ * BCM283x base class, so they have no BCM2836(obj) etc macros.
24
+ * @intid: interrupt ID
25
+ *
26
+ * Return true if @intid is a special interrupt ID (1020 to
27
+ * 1023 inclusive). This corresponds to the GIC spec pseudocode
28
+ * IsSpecial() function.
33
+ */
29
+ */
34
+#define TYPE_BCM2836 "bcm2836"
30
+static inline bool gicv3_intid_is_special(int intid)
35
+#define TYPE_BCM2837 "bcm2837"
31
+{
32
+ return intid >= INTID_SECURE && intid <= INTID_SPURIOUS;
33
+}
36
+
34
+
37
typedef struct BCM283XState {
35
/**
38
/*< private >*/
36
* gicv3_redist_update:
39
DeviceState parent_obj;
37
* @cs: GICv3CPUState for this redistributor
40
@@ -XXX,XX +XXX,XX @@ typedef struct BCM283XState {
38
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
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
39
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/arm/bcm2836.c
40
--- a/hw/intc/arm_gicv3_cpuif.c
60
+++ b/hw/arm/bcm2836.c
41
+++ b/hw/intc/arm_gicv3_cpuif.c
61
@@ -XXX,XX +XXX,XX @@
42
@@ -XXX,XX +XXX,XX @@ static uint64_t icc_iar0_read(CPUARMState *env, const ARMCPRegInfo *ri)
62
/* "QA7" (Pi2) interrupt controller and mailboxes etc. */
43
intid = icc_hppir0_value(cs, env);
63
#define BCM2836_CONTROL_BASE 0x40000000
44
}
64
45
65
+struct BCM283XInfo {
46
- if (!(intid >= INTID_SECURE && intid <= INTID_SPURIOUS)) {
66
+ const char *name;
47
+ if (!gicv3_intid_is_special(intid)) {
67
+};
48
icc_activate_irq(cs, intid);
68
+
49
}
69
+static const BCM283XInfo bcm283x_socs[] = {
50
70
+ {
51
@@ -XXX,XX +XXX,XX @@ static uint64_t icc_iar1_read(CPUARMState *env, const ARMCPRegInfo *ri)
71
+ .name = TYPE_BCM2836,
52
intid = icc_hppir1_value(cs, env);
72
+ },
53
}
73
+ {
54
74
+ .name = TYPE_BCM2837,
55
- if (!(intid >= INTID_SECURE && intid <= INTID_SPURIOUS)) {
75
+ },
56
+ if (!gicv3_intid_is_special(intid)) {
76
+};
57
icc_activate_irq(cs, intid);
77
+
58
}
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
127
index XXXXXXX..XXXXXXX 100644
128
--- a/hw/arm/raspi.c
129
+++ b/hw/arm/raspi.c
130
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
131
BusState *bus;
132
DeviceState *carddev;
133
134
- object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM283X);
135
+ object_initialize(&s->soc, sizeof(s->soc),
136
+ version == 3 ? TYPE_BCM2837 : TYPE_BCM2836);
137
object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
138
&error_abort);
139
59
140
--
60
--
141
2.16.2
61
2.25.1
142
62
143
63
diff view generated by jsdifflib
Deleted patch
1
The BCM2837 sets the Aff1 field of the MPIDR affinity values for the
2
CPUs to 0, whereas the BCM2836 uses 0xf. Set this correctly, as it
3
is required for Linux to boot.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20180313153458.26822-8-peter.maydell@linaro.org
9
---
10
hw/arm/bcm2836.c | 11 +++++++----
11
1 file changed, 7 insertions(+), 4 deletions(-)
12
13
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/bcm2836.c
16
+++ b/hw/arm/bcm2836.c
17
@@ -XXX,XX +XXX,XX @@
18
19
struct BCM283XInfo {
20
const char *name;
21
+ int clusterid;
22
};
23
24
static const BCM283XInfo bcm283x_socs[] = {
25
{
26
.name = TYPE_BCM2836,
27
+ .clusterid = 0xf,
28
},
29
{
30
.name = TYPE_BCM2837,
31
+ .clusterid = 0x0,
32
},
33
};
34
35
@@ -XXX,XX +XXX,XX @@ static void bcm2836_init(Object *obj)
36
static void bcm2836_realize(DeviceState *dev, Error **errp)
37
{
38
BCM283XState *s = BCM283X(dev);
39
+ BCM283XClass *bc = BCM283X_GET_CLASS(dev);
40
+ const BCM283XInfo *info = bc->info;
41
Object *obj;
42
Error *err = NULL;
43
int n;
44
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
45
qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-fiq", 0));
46
47
for (n = 0; n < BCM283X_NCPUS; n++) {
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
--
58
2.16.2
59
60
diff view generated by jsdifflib
1
The raspi3 has AArch64 CPUs, which means that our smpboot
1
It is valid for an OS to put virtual interrupt ID values into the
2
code for keeping the secondary CPUs in a pen needs to have
2
list registers ICH_LR<n> which are greater than 1023. This
3
a version for A64 as well as A32. Without this, the
3
corresponds to (for example) KVM using the in-kernel emulated ITS to
4
secondary CPUs go into an infinite loop of taking undefined
4
give a (nested) guest an ITS. LPIs are delivered by the L1 kernel to
5
instruction exceptions.
5
the L2 guest via the list registers in the same way as non-LPI
6
interrupts.
7
8
QEMU's code for handling writes to ICV_IARn (which happen when the L2
9
guest acknowledges an interrupt) and to ICV_EOIRn (which happen at
10
the end of the interrupt) did not consider LPIs, so it would
11
incorrectly treat interrupt IDs above 1023 as invalid. Fix this by
12
using the correct condition, which is gicv3_intid_is_special().
13
14
Note that the condition in icv_dir_write() is correct -- LPIs
15
are not valid there and so we want to ignore both "special" ID
16
values and LPIs.
17
18
(In the pseudocode this logic is in:
19
- VirtualReadIAR0(), VirtualReadIAR1(), which call IsSpecial()
20
- VirtualWriteEOIR0(), VirtualWriteEOIR1(), which call
21
VirtualIdentifierValid(data, TRUE) meaning "LPIs OK"
22
- VirtualWriteDIR(), which calls VirtualIdentifierValid(data, FALSE)
23
meaning "LPIs not OK")
24
25
This bug doesn't seem to have any visible effect on Linux L2 guests
26
most of the time, because the two bugs cancel each other out: we
27
neither mark the interrupt active nor deactivate it. However it does
28
mean that the L2 vCPU priority while the LPI handler is running will
29
not be correct, so the interrupt handler could be unexpectedly
30
interrupted by a different interrupt.
31
32
(NB: this has nothing to do with using QEMU's emulated ITS.)
6
33
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
35
Reviewed-by: Marc Zyngier <maz@kernel.org>
9
Message-id: 20180313153458.26822-10-peter.maydell@linaro.org
10
---
36
---
11
hw/arm/raspi.c | 41 ++++++++++++++++++++++++++++++++++++++++-
37
hw/intc/arm_gicv3_cpuif.c | 5 ++---
12
1 file changed, 40 insertions(+), 1 deletion(-)
38
1 file changed, 2 insertions(+), 3 deletions(-)
13
39
14
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
40
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
15
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/raspi.c
42
--- a/hw/intc/arm_gicv3_cpuif.c
17
+++ b/hw/arm/raspi.c
43
+++ b/hw/intc/arm_gicv3_cpuif.c
18
@@ -XXX,XX +XXX,XX @@
44
@@ -XXX,XX +XXX,XX @@ static uint64_t icv_iar_read(CPUARMState *env, const ARMCPRegInfo *ri)
19
#define BOARDSETUP_ADDR (MVBAR_ADDR + 0x20) /* board setup code */
45
20
#define FIRMWARE_ADDR_2 0x8000 /* Pi 2 loads kernel.img here by default */
46
if (thisgrp == grp && icv_hppi_can_preempt(cs, lr)) {
21
#define FIRMWARE_ADDR_3 0x80000 /* Pi 3 loads kernel.img here by default */
47
intid = ich_lr_vintid(lr);
22
+#define SPINTABLE_ADDR 0xd8 /* Pi 3 bootloader spintable */
48
- if (intid < INTID_SECURE) {
23
49
+ if (!gicv3_intid_is_special(intid)) {
24
/* Table of Linux board IDs for different Pi versions */
50
icv_activate_irq(cs, idx, grp);
25
static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44};
51
} else {
26
@@ -XXX,XX +XXX,XX @@ static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
52
/* Interrupt goes from Pending to Invalid */
27
info->smp_loader_start);
53
@@ -XXX,XX +XXX,XX @@ static void icv_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri,
28
}
54
trace_gicv3_icv_eoir_write(ri->crm == 8 ? 0 : 1,
29
55
gicv3_redist_affid(cs), value);
30
+static void write_smpboot64(ARMCPU *cpu, const struct arm_boot_info *info)
56
31
+{
57
- if (irq >= GICV3_MAXIRQ) {
32
+ /* Unlike the AArch32 version we don't need to call the board setup hook.
58
- /* Also catches special interrupt numbers and LPIs */
33
+ * The mechanism for doing the spin-table is also entirely different.
59
+ if (gicv3_intid_is_special(irq)) {
34
+ * We must have four 64-bit fields at absolute addresses
60
return;
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
+
54
+ static const uint64_t spintables[] = {
55
+ 0, 0, 0, 0
56
+ };
57
+
58
+ rom_add_blob_fixed("raspi_smpboot", smpboot, sizeof(smpboot),
59
+ info->smp_loader_start);
60
+ rom_add_blob_fixed("raspi_spintables", spintables, sizeof(spintables),
61
+ SPINTABLE_ADDR);
62
+}
63
+
64
static void write_board_setup(ARMCPU *cpu, const struct arm_boot_info *info)
65
{
66
arm_write_secure_board_setup_dummy_smc(cpu, info, MVBAR_ADDR);
67
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
68
/* Pi2 and Pi3 requires SMP setup */
69
if (version >= 2) {
70
binfo.smp_loader_start = SMPBOOT_ADDR;
71
- binfo.write_secondary_boot = write_smpboot;
72
+ if (version == 2) {
73
+ binfo.write_secondary_boot = write_smpboot;
74
+ } else {
75
+ binfo.write_secondary_boot = write_smpboot64;
76
+ }
77
binfo.secondary_cpu_reset_hook = reset_secondary;
78
}
61
}
79
62
80
--
63
--
81
2.16.2
64
2.25.1
82
65
83
66
diff view generated by jsdifflib