1
Arm patch queue -- these are all bug fix patches but we might
1
My OS Lock/DoubleLock patches, plus a small selection of other
2
as well put them in to rc0...
2
bug fixes and minor things.
3
3
4
thanks
4
thanks
5
-- PMM
5
-- PMM
6
6
7
The following changes since commit 2c8cfc0b52b5a4d123c26c0b5fdf941be24805be:
7
The following changes since commit 8e9398e3b1a860b8c29c670c1b6c36afe8d87849:
8
8
9
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2018-03-19 11:44:26 +0000)
9
Merge tag 'pull-ppc-20220706' of https://gitlab.com/danielhb/qemu into staging (2022-07-07 06:21:05 +0530)
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-20220707
14
14
15
for you to fetch changes up to ff72cb6b46b95bb530787add5277c211af3d31c6:
15
for you to fetch changes up to c2360eaa0262a816faf8032b7762d0c73df2cc62:
16
16
17
hw/arm/raspi: Provide spin-loop code for AArch64 CPUs (2018-03-19 18:23:24 +0000)
17
target/arm: Fix qemu-system-arm handling of LPAE block descriptors for highmem (2022-07-07 11:41:04 +0100)
18
18
19
----------------------------------------------------------------
19
----------------------------------------------------------------
20
target-arm queue:
20
target-arm queue:
21
* fsl-imx6: Fix incorrect Ethernet interrupt defines
21
* hw/arm/virt: dt: add rng-seed property
22
* dump: Update correct kdump phys_base field for AArch64
22
* Fix MTE check in sve_ldnfff1_r
23
* char: i.MX: Add support for "TX complete" interrupt
23
* Record tagged bit for user-only in sve_probe_page
24
* bcm2836/raspi: Fix various bugs resulting in panics trying
24
* Correctly implement OS Lock and OS DoubleLock
25
to boot a Debian Linux kernel on raspi3
25
* Implement DBGDEVID, DBGDEVID1, DBGDEVID2 registers
26
* Fix qemu-system-arm handling of LPAE block descriptors for highmem
26
27
27
----------------------------------------------------------------
28
----------------------------------------------------------------
28
Andrey Smirnov (2):
29
Jason A. Donenfeld (1):
29
char: i.MX: Simplify imx_update()
30
hw/arm/virt: dt: add rng-seed property
30
char: i.MX: Add support for "TX complete" interrupt
31
31
32
Guenter Roeck (1):
32
Peter Maydell (6):
33
fsl-imx6: Swap Ethernet interrupt defines
33
target/arm: Fix code style issues in debug helper functions
34
target/arm: Move define_debug_regs() to debug_helper.c
35
target/arm: Suppress debug exceptions when OS Lock set
36
target/arm: Implement AArch32 DBGDEVID, DBGDEVID1, DBGDEVID2
37
target/arm: Correctly implement Feat_DoubleLock
38
target/arm: Fix qemu-system-arm handling of LPAE block descriptors for highmem
34
39
35
Peter Maydell (9):
40
Richard Henderson (2):
36
hw/arm/raspi: Don't do board-setup or secure-boot for raspi3
41
target/arm: Fix MTE check in sve_ldnfff1_r
37
hw/arm/boot: assert that secure_boot and secure_board_setup are false for AArch64
42
target/arm: Record tagged bit for user-only in sve_probe_page
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
43
46
Wei Huang (1):
44
docs/about/deprecated.rst | 8 +
47
dump: Update correct kdump phys_base field for AArch64
45
docs/system/arm/virt.rst | 17 +-
48
46
include/hw/arm/virt.h | 2 +-
49
include/hw/arm/bcm2836.h | 31 +++++++++++++---
47
target/arm/cpregs.h | 3 +
50
include/hw/arm/fsl-imx6.h | 4 +-
48
target/arm/cpu.h | 27 +++
51
include/hw/char/imx_serial.h | 3 ++
49
target/arm/internals.h | 9 +
52
dump.c | 14 +++++--
50
hw/arm/virt.c | 44 ++--
53
hw/arm/bcm2836.c | 87 +++++++++++++++++++++++++++++++-------------
51
target/arm/cpu64.c | 6 +
54
hw/arm/boot.c | 12 ++++++
52
target/arm/cpu_tcg.c | 6 +
55
hw/arm/raspi.c | 77 +++++++++++++++++++++++++++++++--------
53
target/arm/debug_helper.c | 580 ++++++++++++++++++++++++++++++++++++++++++++++
56
hw/char/imx_serial.c | 44 ++++++++++++++++------
54
target/arm/helper.c | 513 +---------------------------------------
57
hw/net/imx_fec.c | 28 +++++++++++++-
55
target/arm/ptw.c | 2 +-
58
9 files changed, 237 insertions(+), 63 deletions(-)
56
target/arm/sve_helper.c | 5 +-
59
57
13 files changed, 684 insertions(+), 538 deletions(-)
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
2
2
3
Code of imx_update() is slightly confusing since the "flags" variable
3
In 60592cfed2 ("hw/arm/virt: dt: add kaslr-seed property"), the
4
doesn't really corespond to anything in real hardware and server as a
4
kaslr-seed property was added, but the equally as important rng-seed
5
kitchensink accumulating events normally reported via USR1 and USR2
5
property was forgotten about, which has identical semantics for a
6
registers.
6
similar purpose. This commit implements it in exactly the same way as
7
kaslr-seed. It then changes the name of the disabling option to reflect
8
that this has more to do with randomness vs determinism, rather than
9
something particular about kaslr.
7
10
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>
11
Cc: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
12
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
29
Message-id: 20180315191141.6789-1-andrew.smirnov@gmail.com
13
[PMM: added deprecated.rst section for the deprecation]
30
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
31
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
---
16
---
33
hw/char/imx_serial.c | 24 ++++++++++++++++--------
17
docs/about/deprecated.rst | 8 +++++++
34
1 file changed, 16 insertions(+), 8 deletions(-)
18
docs/system/arm/virt.rst | 17 +++++++++------
19
include/hw/arm/virt.h | 2 +-
20
hw/arm/virt.c | 44 ++++++++++++++++++++++++---------------
21
4 files changed, 47 insertions(+), 24 deletions(-)
35
22
36
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
23
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
37
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/char/imx_serial.c
25
--- a/docs/about/deprecated.rst
39
+++ b/hw/char/imx_serial.c
26
+++ b/docs/about/deprecated.rst
40
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_serial = {
27
@@ -XXX,XX +XXX,XX @@ Use the more generic event ``DEVICE_UNPLUG_GUEST_ERROR`` instead.
41
28
System emulator machines
42
static void imx_update(IMXSerialState *s)
29
------------------------
30
31
+Arm ``virt`` machine ``dtb-kaslr-seed`` property
32
+''''''''''''''''''''''''''''''''''''''''''''''''
33
+
34
+The ``dtb-kaslr-seed`` property on the ``virt`` board has been
35
+deprecated; use the new name ``dtb-randomness`` instead. The new name
36
+better reflects the way this property affects all random data within
37
+the device tree blob, not just the ``kaslr-seed`` node.
38
+
39
PPC 405 ``taihu`` machine (since 7.0)
40
'''''''''''''''''''''''''''''''''''''
41
42
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
43
index XXXXXXX..XXXXXXX 100644
44
--- a/docs/system/arm/virt.rst
45
+++ b/docs/system/arm/virt.rst
46
@@ -XXX,XX +XXX,XX @@ ras
47
Set ``on``/``off`` to enable/disable reporting host memory errors to a guest
48
using ACPI and guest external abort exceptions. The default is off.
49
50
+dtb-randomness
51
+ Set ``on``/``off`` to pass random seeds via the guest DTB
52
+ rng-seed and kaslr-seed nodes (in both "/chosen" and
53
+ "/secure-chosen") to use for features like the random number
54
+ generator and address space randomisation. The default is
55
+ ``on``. You will want to disable it if your trusted boot chain
56
+ will verify the DTB it is passed, since this option causes the
57
+ DTB to be non-deterministic. It would be the responsibility of
58
+ the firmware to come up with a seed and pass it on if it wants to.
59
+
60
dtb-kaslr-seed
61
- Set ``on``/``off`` to pass a random seed via the guest dtb
62
- kaslr-seed node (in both "/chosen" and /secure-chosen) to use
63
- for features like address space randomisation. The default is
64
- ``on``. You will want to disable it if your trusted boot chain will
65
- verify the DTB it is passed. It would be the responsibility of the
66
- firmware to come up with a seed and pass it on if it wants to.
67
+ A deprecated synonym for dtb-randomness.
68
69
Linux guest kernel configuration
70
""""""""""""""""""""""""""""""""
71
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
72
index XXXXXXX..XXXXXXX 100644
73
--- a/include/hw/arm/virt.h
74
+++ b/include/hw/arm/virt.h
75
@@ -XXX,XX +XXX,XX @@ struct VirtMachineState {
76
bool virt;
77
bool ras;
78
bool mte;
79
- bool dtb_kaslr_seed;
80
+ bool dtb_randomness;
81
OnOffAuto acpi;
82
VirtGICType gic_version;
83
VirtIOMMUType iommu;
84
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/hw/arm/virt.c
87
+++ b/hw/arm/virt.c
88
@@ -XXX,XX +XXX,XX @@ static bool cpu_type_valid(const char *cpu)
89
return false;
90
}
91
92
-static void create_kaslr_seed(MachineState *ms, const char *node)
93
+static void create_randomness(MachineState *ms, const char *node)
43
{
94
{
44
- uint32_t flags;
95
- uint64_t seed;
45
+ uint32_t usr1;
96
+ struct {
46
+ uint32_t usr2;
97
+ uint64_t kaslr;
47
+ uint32_t mask;
98
+ uint8_t rng[32];
48
99
+ } seed;
49
- flags = (s->usr1 & s->ucr1) & (USR1_TRDY|USR1_RRDY);
100
50
- if (s->ucr1 & UCR1_TXMPTYEN) {
101
if (qemu_guest_getrandom(&seed, sizeof(seed), NULL)) {
51
- flags |= (s->uts1 & UTS1_TXEMPTY);
102
return;
52
- } else {
103
}
53
- flags &= ~USR1_TRDY;
104
- qemu_fdt_setprop_u64(ms->fdt, node, "kaslr-seed", seed);
54
- }
105
+ qemu_fdt_setprop_u64(ms->fdt, node, "kaslr-seed", seed.kaslr);
55
+ /*
106
+ qemu_fdt_setprop(ms->fdt, node, "rng-seed", seed.rng, sizeof(seed.rng));
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
}
107
}
71
108
72
static void imx_serial_reset(IMXSerialState *s)
109
static void create_fdt(VirtMachineState *vms)
110
@@ -XXX,XX +XXX,XX @@ static void create_fdt(VirtMachineState *vms)
111
112
/* /chosen must exist for load_dtb to fill in necessary properties later */
113
qemu_fdt_add_subnode(fdt, "/chosen");
114
- if (vms->dtb_kaslr_seed) {
115
- create_kaslr_seed(ms, "/chosen");
116
+ if (vms->dtb_randomness) {
117
+ create_randomness(ms, "/chosen");
118
}
119
120
if (vms->secure) {
121
qemu_fdt_add_subnode(fdt, "/secure-chosen");
122
- if (vms->dtb_kaslr_seed) {
123
- create_kaslr_seed(ms, "/secure-chosen");
124
+ if (vms->dtb_randomness) {
125
+ create_randomness(ms, "/secure-chosen");
126
}
127
}
128
129
@@ -XXX,XX +XXX,XX @@ static void virt_set_its(Object *obj, bool value, Error **errp)
130
vms->its = value;
131
}
132
133
-static bool virt_get_dtb_kaslr_seed(Object *obj, Error **errp)
134
+static bool virt_get_dtb_randomness(Object *obj, Error **errp)
135
{
136
VirtMachineState *vms = VIRT_MACHINE(obj);
137
138
- return vms->dtb_kaslr_seed;
139
+ return vms->dtb_randomness;
140
}
141
142
-static void virt_set_dtb_kaslr_seed(Object *obj, bool value, Error **errp)
143
+static void virt_set_dtb_randomness(Object *obj, bool value, Error **errp)
144
{
145
VirtMachineState *vms = VIRT_MACHINE(obj);
146
147
- vms->dtb_kaslr_seed = value;
148
+ vms->dtb_randomness = value;
149
}
150
151
static char *virt_get_oem_id(Object *obj, Error **errp)
152
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
153
"Set on/off to enable/disable "
154
"ITS instantiation");
155
156
+ object_class_property_add_bool(oc, "dtb-randomness",
157
+ virt_get_dtb_randomness,
158
+ virt_set_dtb_randomness);
159
+ object_class_property_set_description(oc, "dtb-randomness",
160
+ "Set off to disable passing random or "
161
+ "non-deterministic dtb nodes to guest");
162
+
163
object_class_property_add_bool(oc, "dtb-kaslr-seed",
164
- virt_get_dtb_kaslr_seed,
165
- virt_set_dtb_kaslr_seed);
166
+ virt_get_dtb_randomness,
167
+ virt_set_dtb_randomness);
168
object_class_property_set_description(oc, "dtb-kaslr-seed",
169
- "Set off to disable passing of kaslr-seed "
170
- "dtb node to guest");
171
+ "Deprecated synonym of dtb-randomness");
172
173
object_class_property_add_str(oc, "x-oem-id",
174
virt_get_oem_id,
175
@@ -XXX,XX +XXX,XX @@ static void virt_instance_init(Object *obj)
176
/* MTE is disabled by default. */
177
vms->mte = false;
178
179
- /* Supply a kaslr-seed by default */
180
- vms->dtb_kaslr_seed = true;
181
+ /* Supply kaslr-seed and rng-seed by default */
182
+ vms->dtb_randomness = true;
183
184
vms->irqmap = a15irqmap;
185
73
--
186
--
74
2.16.2
187
2.25.1
75
76
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add support for "TX complete"/TXDC interrupt generate by real HW since
3
The comment was correct, but the test was not:
4
it is needed to support guests other than Linux.
4
disable mte if tagged is *not* set.
5
5
6
Based on the patch by Bill Paul as found here:
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
https://bugs.launchpad.net/qemu/+bug/1753314
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>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
9
---
19
include/hw/char/imx_serial.h | 3 +++
10
target/arm/sve_helper.c | 2 +-
20
hw/char/imx_serial.c | 20 +++++++++++++++++---
11
1 file changed, 1 insertion(+), 1 deletion(-)
21
2 files changed, 20 insertions(+), 3 deletions(-)
22
12
23
diff --git a/include/hw/char/imx_serial.h b/include/hw/char/imx_serial.h
13
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
24
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/char/imx_serial.h
15
--- a/target/arm/sve_helper.c
26
+++ b/include/hw/char/imx_serial.h
16
+++ b/target/arm/sve_helper.c
27
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ void sve_ldnfff1_r(CPUARMState *env, void *vg, const target_ulong addr,
28
#define UCR2_RXEN (1<<1) /* Receiver enable */
18
* Disable MTE checking if the Tagged bit is not set. Since TBI must
29
#define UCR2_SRST (1<<0) /* Reset complete */
19
* be set within MTEDESC for MTE, !mtedesc => !mte_active.
30
31
+#define UCR4_TCEN BIT(3) /* TX complete interrupt enable */
32
+
33
#define UTS1_TXEMPTY (1<<6)
34
#define UTS1_RXEMPTY (1<<5)
35
#define UTS1_TXFULL (1<<4)
36
@@ -XXX,XX +XXX,XX @@ typedef struct IMXSerialState {
37
uint32_t ubmr;
38
uint32_t ubrc;
39
uint32_t ucr3;
40
+ uint32_t ucr4;
41
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
*/
20
*/
70
mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
21
- if (arm_tlb_mte_tagged(&info.page[0].attrs)) {
71
+ /*
22
+ if (!arm_tlb_mte_tagged(&info.page[0].attrs)) {
72
+ * TCEN and TXDC are both bit 3
23
mtedesc = 0;
73
+ */
24
}
74
+ mask |= s->ucr4 & UCR4_TCEN;
25
75
+
76
usr2 = s->usr2 & mask;
77
78
qemu_set_irq(s->irq, usr1 || usr2);
79
@@ -XXX,XX +XXX,XX @@ static uint64_t imx_serial_read(void *opaque, hwaddr offset,
80
return s->ucr3;
81
82
case 0x23: /* UCR4 */
83
+ return s->ucr4;
84
+
85
case 0x29: /* BRM Incremental */
86
return 0x0; /* TODO */
87
88
@@ -XXX,XX +XXX,XX @@ static void imx_serial_write(void *opaque, hwaddr offset,
89
* qemu_chr_fe_write and background I/O callbacks */
90
qemu_chr_fe_write_all(&s->chr, &ch, 1);
91
s->usr1 &= ~USR1_TRDY;
92
+ s->usr2 &= ~USR2_TXDC;
93
imx_update(s);
94
s->usr1 |= USR1_TRDY;
95
+ s->usr2 |= USR2_TXDC;
96
imx_update(s);
97
}
98
break;
99
@@ -XXX,XX +XXX,XX @@ static void imx_serial_write(void *opaque, hwaddr offset,
100
s->ucr3 = value & 0xffff;
101
break;
102
103
- case 0x2d: /* UTS1 */
104
case 0x23: /* UCR4 */
105
+ s->ucr4 = value & 0xffff;
106
+ imx_update(s);
107
+ break;
108
+
109
+ case 0x2d: /* UTS1 */
110
qemu_log_mask(LOG_UNIMP, "[%s]%s: Unimplemented reg 0x%"
111
HWADDR_PRIx "\n", TYPE_IMX_SERIAL, __func__, offset);
112
/* TODO */
113
--
26
--
114
2.16.2
27
2.25.1
115
116
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The sabrelite machine model used by qemu-system-arm is based on the
3
Fixes a bug in that we were not honoring MTE from user-only
4
Freescale/NXP i.MX6Q processor. This SoC has an on-board ethernet
4
SVE. Copy the user-only MTE logic from allocation_tag_mem
5
controller which is supported in QEMU using the imx_fec.c module
5
into sve_probe_page.
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
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
imx.enet device like this:
10
11
#define FSL_IMX6_ENET_MAC_1588_IRQ 118
12
#define FSL_IMX6_ENET_MAC_IRQ 119
13
14
According to https://www.nxp.com/docs/en/reference-manual/IMX6DQRM.pdf,
15
page 225, in Table 3-1. ARM Cortex A9 domain interrupt summary,
16
interrupts are as follows.
17
18
150 ENET MAC 0 IRQ
19
151 ENET MAC 0 1588 Timer interrupt
20
21
where
22
23
150 - 32 == 118
24
151 - 32 == 119
25
26
In other words, the vector definitions in the fsl-imx6.h file are reversed.
27
28
Fixing the interrupts alone causes problems with older Linux kernels:
29
The Ethernet interface will fail to probe with Linux v4.9 and earlier.
30
Linux v4.1 and earlier will crash due to a bug in Ethernet driver probe
31
error handling. This is a Linux kernel problem, not a qemu problem:
32
the Linux kernel only worked by accident since it requested both interrupts.
33
34
For backward compatibility, generate the Ethernet interrupt on both interrupt
35
lines. This was shown to work from all Linux kernel releases starting with
36
v3.16.
37
38
Link: https://bugs.launchpad.net/qemu/+bug/1753309
39
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
40
Message-id: 1520723090-22130-1-git-send-email-linux@roeck-us.net
41
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
42
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
43
---
10
---
44
include/hw/arm/fsl-imx6.h | 4 ++--
11
target/arm/sve_helper.c | 3 +++
45
hw/net/imx_fec.c | 28 +++++++++++++++++++++++++++-
12
1 file changed, 3 insertions(+)
46
2 files changed, 29 insertions(+), 3 deletions(-)
47
13
48
diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h
14
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
49
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
50
--- a/include/hw/arm/fsl-imx6.h
16
--- a/target/arm/sve_helper.c
51
+++ b/include/hw/arm/fsl-imx6.h
17
+++ b/target/arm/sve_helper.c
52
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX6State {
18
@@ -XXX,XX +XXX,XX @@ bool sve_probe_page(SVEHostPage *info, bool nofault, CPUARMState *env,
53
#define FSL_IMX6_HDMI_MASTER_IRQ 115
19
54
#define FSL_IMX6_HDMI_CEC_IRQ 116
20
#ifdef CONFIG_USER_ONLY
55
#define FSL_IMX6_MLB150_LOW_IRQ 117
21
memset(&info->attrs, 0, sizeof(info->attrs));
56
-#define FSL_IMX6_ENET_MAC_1588_IRQ 118
22
+ /* Require both MAP_ANON and PROT_MTE -- see allocation_tag_mem. */
57
-#define FSL_IMX6_ENET_MAC_IRQ 119
23
+ arm_tlb_mte_tagged(&info->attrs) =
58
+#define FSL_IMX6_ENET_MAC_IRQ 118
24
+ (flags & PAGE_ANON) && (flags & PAGE_MTE);
59
+#define FSL_IMX6_ENET_MAC_1588_IRQ 119
25
#else
60
#define FSL_IMX6_PCIE1_IRQ 120
26
/*
61
#define FSL_IMX6_PCIE2_IRQ 121
27
* Find the iotlbentry for addr and return the transaction attributes.
62
#define FSL_IMX6_PCIE3_IRQ 122
63
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/net/imx_fec.c
66
+++ b/hw/net/imx_fec.c
67
@@ -XXX,XX +XXX,XX @@ static void imx_enet_write_bd(IMXENETBufDesc *bd, dma_addr_t addr)
68
69
static void imx_eth_update(IMXFECState *s)
70
{
71
- if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] & ENET_INT_TS_TIMER) {
72
+ /*
73
+ * Previous versions of qemu had the ENET_INT_MAC and ENET_INT_TS_TIMER
74
+ * interrupts swapped. This worked with older versions of Linux (4.14
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
--
28
--
103
2.16.2
29
2.25.1
104
105
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
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
1
Now we have separate types for BCM2386 and BCM2387, we might as well
1
Before moving debug system register helper functions to a
2
just hard-code the CPU type they use rather than having it passed
2
different file, fix the code style issues (mostly block
3
through as an object property. This then lets us put the initialization
3
comment syntax) so checkpatch doesn't complain about the
4
of the CPU object in init rather than realize.
4
code-motion patch.
5
6
Note that this change means that it's no longer possible on
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
11
This does require us to only build the bcm2837 object on
12
TARGET_AARCH64 configs, since otherwise it won't instantiate
13
due to the missing cortex-a53 device and "make check" will fail.
14
5
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20220630194116.3438513-2-peter.maydell@linaro.org
18
Message-id: 20180313153458.26822-9-peter.maydell@linaro.org
19
---
9
---
20
hw/arm/bcm2836.c | 24 +++++++++++++++---------
10
target/arm/helper.c | 58 +++++++++++++++++++++++++++++----------------
21
hw/arm/raspi.c | 2 --
11
1 file changed, 38 insertions(+), 20 deletions(-)
22
2 files changed, 15 insertions(+), 11 deletions(-)
23
12
24
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
25
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/bcm2836.c
15
--- a/target/arm/helper.c
27
+++ b/hw/arm/bcm2836.c
16
+++ b/target/arm/helper.c
28
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_mdcr_el2_eff(CPUARMState *env)
29
18
return arm_is_el2_enabled(env) ? env->cp15.mdcr_el2 : 0;
30
struct BCM283XInfo {
19
}
31
const char *name;
20
32
+ const char *cpu_type;
21
-/* Check for traps to "powerdown debug" registers, which are controlled
33
int clusterid;
22
+/*
23
+ * Check for traps to "powerdown debug" registers, which are controlled
24
* by MDCR.TDOSA
25
*/
26
static CPAccessResult access_tdosa(CPUARMState *env, const ARMCPRegInfo *ri,
27
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tdosa(CPUARMState *env, const ARMCPRegInfo *ri,
28
return CP_ACCESS_OK;
29
}
30
31
-/* Check for traps to "debug ROM" registers, which are controlled
32
+/*
33
+ * Check for traps to "debug ROM" registers, which are controlled
34
* by MDCR_EL2.TDRA for EL2 but by the more general MDCR_EL3.TDA for EL3.
35
*/
36
static CPAccessResult access_tdra(CPUARMState *env, const ARMCPRegInfo *ri,
37
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tdra(CPUARMState *env, const ARMCPRegInfo *ri,
38
return CP_ACCESS_OK;
39
}
40
41
-/* Check for traps to general debug registers, which are controlled
42
+/*
43
+ * Check for traps to general debug registers, which are controlled
44
* by MDCR_EL2.TDA for EL2 and MDCR_EL3.TDA for EL3.
45
*/
46
static CPAccessResult access_tda(CPUARMState *env, const ARMCPRegInfo *ri,
47
@@ -XXX,XX +XXX,XX @@ static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri,
48
static void oslar_write(CPUARMState *env, const ARMCPRegInfo *ri,
49
uint64_t value)
50
{
51
- /* Writes to OSLAR_EL1 may update the OS lock status, which can be
52
+ /*
53
+ * Writes to OSLAR_EL1 may update the OS lock status, which can be
54
* read via a bit in OSLSR_EL1.
55
*/
56
int oslock;
57
@@ -XXX,XX +XXX,XX @@ static void oslar_write(CPUARMState *env, const ARMCPRegInfo *ri,
58
}
59
60
static const ARMCPRegInfo debug_cp_reginfo[] = {
61
- /* DBGDRAR, DBGDSAR: always RAZ since we don't implement memory mapped
62
+ /*
63
+ * DBGDRAR, DBGDSAR: always RAZ since we don't implement memory mapped
64
* debug components. The AArch64 version of DBGDRAR is named MDRAR_EL1;
65
* unlike DBGDRAR it is never accessible from EL0.
66
* DBGDSAR is deprecated and must RAZ from v8 anyway, so it has no AArch64
67
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
68
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 4,
69
.access = PL1_RW, .accessfn = access_tdosa,
70
.type = ARM_CP_NOP },
71
- /* Dummy DBGVCR: Linux wants to clear this on startup, but we don't
72
+ /*
73
+ * Dummy DBGVCR: Linux wants to clear this on startup, but we don't
74
* implement vector catch debug events yet.
75
*/
76
{ .name = "DBGVCR",
77
.cp = 14, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
78
.access = PL1_RW, .accessfn = access_tda,
79
.type = ARM_CP_NOP },
80
- /* Dummy DBGVCR32_EL2 (which is only for a 64-bit hypervisor
81
+ /*
82
+ * Dummy DBGVCR32_EL2 (which is only for a 64-bit hypervisor
83
* to save and restore a 32-bit guest's DBGVCR)
84
*/
85
{ .name = "DBGVCR32_EL2", .state = ARM_CP_STATE_AA64,
86
.opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0,
87
.access = PL2_RW, .accessfn = access_tda,
88
.type = ARM_CP_NOP | ARM_CP_EL3_NO_EL2_KEEP },
89
- /* Dummy MDCCINT_EL1, since we don't implement the Debug Communications
90
+ /*
91
+ * Dummy MDCCINT_EL1, since we don't implement the Debug Communications
92
* Channel but Linux may try to access this register. The 32-bit
93
* alias is DBGDCCINT.
94
*/
95
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
96
static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
97
/* 64 bit access versions of the (dummy) debug registers */
98
{ .name = "DBGDRAR", .cp = 14, .crm = 1, .opc1 = 0,
99
- .access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
100
+ .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
101
{ .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0,
102
- .access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
103
+ .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
34
};
104
};
35
105
36
static const BCM283XInfo bcm283x_socs[] = {
106
/*
37
{
107
@@ -XXX,XX +XXX,XX @@ void hw_watchpoint_update(ARMCPU *cpu, int n)
38
.name = TYPE_BCM2836,
108
break;
39
+ .cpu_type = ARM_CPU_TYPE_NAME("cortex-a15"),
109
}
40
.clusterid = 0xf,
110
41
},
111
- /* Attempts to use both MASK and BAS fields simultaneously are
42
+#ifdef TARGET_AARCH64
112
+ /*
43
{
113
+ * Attempts to use both MASK and BAS fields simultaneously are
44
.name = TYPE_BCM2837,
114
* CONSTRAINED UNPREDICTABLE; we opt to ignore BAS in this case,
45
+ .cpu_type = ARM_CPU_TYPE_NAME("cortex-a53"),
115
* thus generating a watchpoint for every byte in the masked region.
46
.clusterid = 0x0,
116
*/
47
},
117
mask = FIELD_EX64(wcr, DBGWCR, MASK);
48
+#endif
118
if (mask == 1 || mask == 2) {
49
};
119
- /* Reserved values of MASK; we must act as if the mask value was
50
120
+ /*
51
static void bcm2836_init(Object *obj)
121
+ * Reserved values of MASK; we must act as if the mask value was
122
* some non-reserved value, or as if the watchpoint were disabled.
123
* We choose the latter.
124
*/
125
@@ -XXX,XX +XXX,XX @@ void hw_watchpoint_update(ARMCPU *cpu, int n)
126
} else if (mask) {
127
/* Watchpoint covers an aligned area up to 2GB in size */
128
len = 1ULL << mask;
129
- /* If masked bits in WVR are not zero it's CONSTRAINED UNPREDICTABLE
130
+ /*
131
+ * If masked bits in WVR are not zero it's CONSTRAINED UNPREDICTABLE
132
* whether the watchpoint fires when the unmasked bits match; we opt
133
* to generate the exceptions.
134
*/
135
@@ -XXX,XX +XXX,XX @@ void hw_watchpoint_update(ARMCPU *cpu, int n)
136
int basstart;
137
138
if (extract64(wvr, 2, 1)) {
139
- /* Deprecated case of an only 4-aligned address. BAS[7:4] are
140
+ /*
141
+ * Deprecated case of an only 4-aligned address. BAS[7:4] are
142
* ignored, and BAS[3:0] define which bytes to watch.
143
*/
144
bas &= 0xf;
145
@@ -XXX,XX +XXX,XX @@ void hw_watchpoint_update(ARMCPU *cpu, int n)
146
return;
147
}
148
149
- /* The BAS bits are supposed to be programmed to indicate a contiguous
150
+ /*
151
+ * The BAS bits are supposed to be programmed to indicate a contiguous
152
* range of bytes. Otherwise it is CONSTRAINED UNPREDICTABLE whether
153
* we fire for each byte in the word/doubleword addressed by the WVR.
154
* We choose to ignore any non-zero bits after the first range of 1s.
155
@@ -XXX,XX +XXX,XX @@ void hw_watchpoint_update_all(ARMCPU *cpu)
156
int i;
157
CPUARMState *env = &cpu->env;
158
159
- /* Completely clear out existing QEMU watchpoints and our array, to
160
+ /*
161
+ * Completely clear out existing QEMU watchpoints and our array, to
162
* avoid possible stale entries following migration load.
163
*/
164
cpu_watchpoint_remove_all(CPU(cpu), BP_CPU);
165
@@ -XXX,XX +XXX,XX @@ void hw_breakpoint_update(ARMCPU *cpu, int n)
166
case 11: /* linked context ID and VMID match (reserved if no EL2) */
167
case 3: /* linked context ID match */
168
default:
169
- /* We must generate no events for Linked context matches (unless
170
+ /*
171
+ * We must generate no events for Linked context matches (unless
172
* they are linked to by some other bp/wp, which is handled in
173
* updates for the linking bp/wp). We choose to also generate no events
174
* for reserved values.
175
@@ -XXX,XX +XXX,XX @@ void hw_breakpoint_update_all(ARMCPU *cpu)
176
int i;
177
CPUARMState *env = &cpu->env;
178
179
- /* Completely clear out existing QEMU breakpoints and our array, to
180
+ /*
181
+ * Completely clear out existing QEMU breakpoints and our array, to
182
* avoid possible stale entries following migration load.
183
*/
184
cpu_breakpoint_remove_all(CPU(cpu), BP_CPU);
185
@@ -XXX,XX +XXX,XX @@ static void dbgbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
186
ARMCPU *cpu = env_archcpu(env);
187
int i = ri->crm;
188
189
- /* BAS[3] is a read-only copy of BAS[2], and BAS[1] a read-only
190
+ /*
191
+ * BAS[3] is a read-only copy of BAS[2], and BAS[1] a read-only
192
* copy of BAS[0].
193
*/
194
value = deposit64(value, 6, 1, extract64(value, 5, 1));
195
@@ -XXX,XX +XXX,XX @@ static void dbgbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
196
197
static void define_debug_regs(ARMCPU *cpu)
52
{
198
{
53
BCM283XState *s = BCM283X(obj);
199
- /* Define v7 and v8 architectural debug registers.
54
+ BCM283XClass *bc = BCM283X_GET_CLASS(obj);
200
+ /*
55
+ const BCM283XInfo *info = bc->info;
201
+ * Define v7 and v8 architectural debug registers.
56
+ int n;
202
* These are just dummy implementations for now.
57
+
203
*/
58
+ for (n = 0; n < BCM283X_NCPUS; n++) {
204
int i;
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
--
205
--
104
2.16.2
206
2.25.1
105
106
diff view generated by jsdifflib
1
The BCM2837 sets the Aff1 field of the MPIDR affinity values for the
1
The target/arm/helper.c file is very long and is a grabbag of all
2
CPUs to 0, whereas the BCM2836 uses 0xf. Set this correctly, as it
2
kinds of functionality. We have already a debug_helper.c which has
3
is required for Linux to boot.
3
code for implementing architectural debug. Move the code which
4
defines the debug-related system registers out to this file also.
5
This affects the define_debug_regs() function and the various
6
functions and arrays which are used only by it.
7
8
The functions raw_write() and arm_mdcr_el2_eff() and
9
define_debug_regs() now need to be global rather than local to
10
helper.c; everything else is pure code movement.
4
11
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20220630194116.3438513-3-peter.maydell@linaro.org
8
Message-id: 20180313153458.26822-8-peter.maydell@linaro.org
9
---
15
---
10
hw/arm/bcm2836.c | 11 +++++++----
16
target/arm/cpregs.h | 3 +
11
1 file changed, 7 insertions(+), 4 deletions(-)
17
target/arm/internals.h | 9 +
18
target/arm/debug_helper.c | 525 +++++++++++++++++++++++++++++++++++++
19
target/arm/helper.c | 531 +-------------------------------------
20
4 files changed, 538 insertions(+), 530 deletions(-)
12
21
13
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
22
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
14
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/bcm2836.c
24
--- a/target/arm/cpregs.h
16
+++ b/hw/arm/bcm2836.c
25
+++ b/target/arm/cpregs.h
26
@@ -XXX,XX +XXX,XX @@ void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
27
/* CPReadFn that can be used for read-as-zero behaviour */
28
uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri);
29
30
+/* CPWriteFn that just writes the value to ri->fieldoffset */
31
+void raw_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value);
32
+
33
/*
34
* CPResetFn that does nothing, for use if no reset is required even
35
* if fieldoffset is non zero.
36
diff --git a/target/arm/internals.h b/target/arm/internals.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/internals.h
39
+++ b/target/arm/internals.h
40
@@ -XXX,XX +XXX,XX @@ int exception_target_el(CPUARMState *env);
41
bool arm_singlestep_active(CPUARMState *env);
42
bool arm_generate_debug_exceptions(CPUARMState *env);
43
44
+/* Add the cpreg definitions for debug related system registers */
45
+void define_debug_regs(ARMCPU *cpu);
46
+
47
+/* Effective value of MDCR_EL2 */
48
+static inline uint64_t arm_mdcr_el2_eff(CPUARMState *env)
49
+{
50
+ return arm_is_el2_enabled(env) ? env->cp15.mdcr_el2 : 0;
51
+}
52
+
53
/* Powers of 2 for sve_vq_map et al. */
54
#define SVE_VQ_POW2_MAP \
55
((1 << (1 - 1)) | (1 << (2 - 1)) | \
56
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/debug_helper.c
59
+++ b/target/arm/debug_helper.c
17
@@ -XXX,XX +XXX,XX @@
60
@@ -XXX,XX +XXX,XX @@
18
61
* SPDX-License-Identifier: GPL-2.0-or-later
19
struct BCM283XInfo {
62
*/
20
const char *name;
63
#include "qemu/osdep.h"
21
+ int clusterid;
64
+#include "qemu/log.h"
65
#include "cpu.h"
66
#include "internals.h"
67
+#include "cpregs.h"
68
#include "exec/exec-all.h"
69
#include "exec/helper-proto.h"
70
71
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_swstep)(CPUARMState *env, uint32_t syndrome)
72
raise_exception_debug(env, EXCP_UDEF, syndrome);
73
}
74
75
+/*
76
+ * Check for traps to "powerdown debug" registers, which are controlled
77
+ * by MDCR.TDOSA
78
+ */
79
+static CPAccessResult access_tdosa(CPUARMState *env, const ARMCPRegInfo *ri,
80
+ bool isread)
81
+{
82
+ int el = arm_current_el(env);
83
+ uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
84
+ bool mdcr_el2_tdosa = (mdcr_el2 & MDCR_TDOSA) || (mdcr_el2 & MDCR_TDE) ||
85
+ (arm_hcr_el2_eff(env) & HCR_TGE);
86
+
87
+ if (el < 2 && mdcr_el2_tdosa) {
88
+ return CP_ACCESS_TRAP_EL2;
89
+ }
90
+ if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDOSA)) {
91
+ return CP_ACCESS_TRAP_EL3;
92
+ }
93
+ return CP_ACCESS_OK;
94
+}
95
+
96
+/*
97
+ * Check for traps to "debug ROM" registers, which are controlled
98
+ * by MDCR_EL2.TDRA for EL2 but by the more general MDCR_EL3.TDA for EL3.
99
+ */
100
+static CPAccessResult access_tdra(CPUARMState *env, const ARMCPRegInfo *ri,
101
+ bool isread)
102
+{
103
+ int el = arm_current_el(env);
104
+ uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
105
+ bool mdcr_el2_tdra = (mdcr_el2 & MDCR_TDRA) || (mdcr_el2 & MDCR_TDE) ||
106
+ (arm_hcr_el2_eff(env) & HCR_TGE);
107
+
108
+ if (el < 2 && mdcr_el2_tdra) {
109
+ return CP_ACCESS_TRAP_EL2;
110
+ }
111
+ if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDA)) {
112
+ return CP_ACCESS_TRAP_EL3;
113
+ }
114
+ return CP_ACCESS_OK;
115
+}
116
+
117
+/*
118
+ * Check for traps to general debug registers, which are controlled
119
+ * by MDCR_EL2.TDA for EL2 and MDCR_EL3.TDA for EL3.
120
+ */
121
+static CPAccessResult access_tda(CPUARMState *env, const ARMCPRegInfo *ri,
122
+ bool isread)
123
+{
124
+ int el = arm_current_el(env);
125
+ uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
126
+ bool mdcr_el2_tda = (mdcr_el2 & MDCR_TDA) || (mdcr_el2 & MDCR_TDE) ||
127
+ (arm_hcr_el2_eff(env) & HCR_TGE);
128
+
129
+ if (el < 2 && mdcr_el2_tda) {
130
+ return CP_ACCESS_TRAP_EL2;
131
+ }
132
+ if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDA)) {
133
+ return CP_ACCESS_TRAP_EL3;
134
+ }
135
+ return CP_ACCESS_OK;
136
+}
137
+
138
+static void oslar_write(CPUARMState *env, const ARMCPRegInfo *ri,
139
+ uint64_t value)
140
+{
141
+ /*
142
+ * Writes to OSLAR_EL1 may update the OS lock status, which can be
143
+ * read via a bit in OSLSR_EL1.
144
+ */
145
+ int oslock;
146
+
147
+ if (ri->state == ARM_CP_STATE_AA32) {
148
+ oslock = (value == 0xC5ACCE55);
149
+ } else {
150
+ oslock = value & 1;
151
+ }
152
+
153
+ env->cp15.oslsr_el1 = deposit32(env->cp15.oslsr_el1, 1, 1, oslock);
154
+}
155
+
156
+static const ARMCPRegInfo debug_cp_reginfo[] = {
157
+ /*
158
+ * DBGDRAR, DBGDSAR: always RAZ since we don't implement memory mapped
159
+ * debug components. The AArch64 version of DBGDRAR is named MDRAR_EL1;
160
+ * unlike DBGDRAR it is never accessible from EL0.
161
+ * DBGDSAR is deprecated and must RAZ from v8 anyway, so it has no AArch64
162
+ * accessor.
163
+ */
164
+ { .name = "DBGDRAR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0,
165
+ .access = PL0_R, .accessfn = access_tdra,
166
+ .type = ARM_CP_CONST, .resetvalue = 0 },
167
+ { .name = "MDRAR_EL1", .state = ARM_CP_STATE_AA64,
168
+ .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0,
169
+ .access = PL1_R, .accessfn = access_tdra,
170
+ .type = ARM_CP_CONST, .resetvalue = 0 },
171
+ { .name = "DBGDSAR", .cp = 14, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
172
+ .access = PL0_R, .accessfn = access_tdra,
173
+ .type = ARM_CP_CONST, .resetvalue = 0 },
174
+ /* Monitor debug system control register; the 32-bit alias is DBGDSCRext. */
175
+ { .name = "MDSCR_EL1", .state = ARM_CP_STATE_BOTH,
176
+ .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
177
+ .access = PL1_RW, .accessfn = access_tda,
178
+ .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1),
179
+ .resetvalue = 0 },
180
+ /*
181
+ * MDCCSR_EL0[30:29] map to EDSCR[30:29]. Simply RAZ as the external
182
+ * Debug Communication Channel is not implemented.
183
+ */
184
+ { .name = "MDCCSR_EL0", .state = ARM_CP_STATE_AA64,
185
+ .opc0 = 2, .opc1 = 3, .crn = 0, .crm = 1, .opc2 = 0,
186
+ .access = PL0_R, .accessfn = access_tda,
187
+ .type = ARM_CP_CONST, .resetvalue = 0 },
188
+ /*
189
+ * DBGDSCRint[15,12,5:2] map to MDSCR_EL1[15,12,5:2]. Map all bits as
190
+ * it is unlikely a guest will care.
191
+ * We don't implement the configurable EL0 access.
192
+ */
193
+ { .name = "DBGDSCRint", .state = ARM_CP_STATE_AA32,
194
+ .cp = 14, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0,
195
+ .type = ARM_CP_ALIAS,
196
+ .access = PL1_R, .accessfn = access_tda,
197
+ .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), },
198
+ { .name = "OSLAR_EL1", .state = ARM_CP_STATE_BOTH,
199
+ .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 4,
200
+ .access = PL1_W, .type = ARM_CP_NO_RAW,
201
+ .accessfn = access_tdosa,
202
+ .writefn = oslar_write },
203
+ { .name = "OSLSR_EL1", .state = ARM_CP_STATE_BOTH,
204
+ .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 4,
205
+ .access = PL1_R, .resetvalue = 10,
206
+ .accessfn = access_tdosa,
207
+ .fieldoffset = offsetof(CPUARMState, cp15.oslsr_el1) },
208
+ /* Dummy OSDLR_EL1: 32-bit Linux will read this */
209
+ { .name = "OSDLR_EL1", .state = ARM_CP_STATE_BOTH,
210
+ .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 4,
211
+ .access = PL1_RW, .accessfn = access_tdosa,
212
+ .type = ARM_CP_NOP },
213
+ /*
214
+ * Dummy DBGVCR: Linux wants to clear this on startup, but we don't
215
+ * implement vector catch debug events yet.
216
+ */
217
+ { .name = "DBGVCR",
218
+ .cp = 14, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
219
+ .access = PL1_RW, .accessfn = access_tda,
220
+ .type = ARM_CP_NOP },
221
+ /*
222
+ * Dummy DBGVCR32_EL2 (which is only for a 64-bit hypervisor
223
+ * to save and restore a 32-bit guest's DBGVCR)
224
+ */
225
+ { .name = "DBGVCR32_EL2", .state = ARM_CP_STATE_AA64,
226
+ .opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0,
227
+ .access = PL2_RW, .accessfn = access_tda,
228
+ .type = ARM_CP_NOP | ARM_CP_EL3_NO_EL2_KEEP },
229
+ /*
230
+ * Dummy MDCCINT_EL1, since we don't implement the Debug Communications
231
+ * Channel but Linux may try to access this register. The 32-bit
232
+ * alias is DBGDCCINT.
233
+ */
234
+ { .name = "MDCCINT_EL1", .state = ARM_CP_STATE_BOTH,
235
+ .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
236
+ .access = PL1_RW, .accessfn = access_tda,
237
+ .type = ARM_CP_NOP },
238
+};
239
+
240
+static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
241
+ /* 64 bit access versions of the (dummy) debug registers */
242
+ { .name = "DBGDRAR", .cp = 14, .crm = 1, .opc1 = 0,
243
+ .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
244
+ { .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0,
245
+ .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
246
+};
247
+
248
+void hw_watchpoint_update(ARMCPU *cpu, int n)
249
+{
250
+ CPUARMState *env = &cpu->env;
251
+ vaddr len = 0;
252
+ vaddr wvr = env->cp15.dbgwvr[n];
253
+ uint64_t wcr = env->cp15.dbgwcr[n];
254
+ int mask;
255
+ int flags = BP_CPU | BP_STOP_BEFORE_ACCESS;
256
+
257
+ if (env->cpu_watchpoint[n]) {
258
+ cpu_watchpoint_remove_by_ref(CPU(cpu), env->cpu_watchpoint[n]);
259
+ env->cpu_watchpoint[n] = NULL;
260
+ }
261
+
262
+ if (!FIELD_EX64(wcr, DBGWCR, E)) {
263
+ /* E bit clear : watchpoint disabled */
264
+ return;
265
+ }
266
+
267
+ switch (FIELD_EX64(wcr, DBGWCR, LSC)) {
268
+ case 0:
269
+ /* LSC 00 is reserved and must behave as if the wp is disabled */
270
+ return;
271
+ case 1:
272
+ flags |= BP_MEM_READ;
273
+ break;
274
+ case 2:
275
+ flags |= BP_MEM_WRITE;
276
+ break;
277
+ case 3:
278
+ flags |= BP_MEM_ACCESS;
279
+ break;
280
+ }
281
+
282
+ /*
283
+ * Attempts to use both MASK and BAS fields simultaneously are
284
+ * CONSTRAINED UNPREDICTABLE; we opt to ignore BAS in this case,
285
+ * thus generating a watchpoint for every byte in the masked region.
286
+ */
287
+ mask = FIELD_EX64(wcr, DBGWCR, MASK);
288
+ if (mask == 1 || mask == 2) {
289
+ /*
290
+ * Reserved values of MASK; we must act as if the mask value was
291
+ * some non-reserved value, or as if the watchpoint were disabled.
292
+ * We choose the latter.
293
+ */
294
+ return;
295
+ } else if (mask) {
296
+ /* Watchpoint covers an aligned area up to 2GB in size */
297
+ len = 1ULL << mask;
298
+ /*
299
+ * If masked bits in WVR are not zero it's CONSTRAINED UNPREDICTABLE
300
+ * whether the watchpoint fires when the unmasked bits match; we opt
301
+ * to generate the exceptions.
302
+ */
303
+ wvr &= ~(len - 1);
304
+ } else {
305
+ /* Watchpoint covers bytes defined by the byte address select bits */
306
+ int bas = FIELD_EX64(wcr, DBGWCR, BAS);
307
+ int basstart;
308
+
309
+ if (extract64(wvr, 2, 1)) {
310
+ /*
311
+ * Deprecated case of an only 4-aligned address. BAS[7:4] are
312
+ * ignored, and BAS[3:0] define which bytes to watch.
313
+ */
314
+ bas &= 0xf;
315
+ }
316
+
317
+ if (bas == 0) {
318
+ /* This must act as if the watchpoint is disabled */
319
+ return;
320
+ }
321
+
322
+ /*
323
+ * The BAS bits are supposed to be programmed to indicate a contiguous
324
+ * range of bytes. Otherwise it is CONSTRAINED UNPREDICTABLE whether
325
+ * we fire for each byte in the word/doubleword addressed by the WVR.
326
+ * We choose to ignore any non-zero bits after the first range of 1s.
327
+ */
328
+ basstart = ctz32(bas);
329
+ len = cto32(bas >> basstart);
330
+ wvr += basstart;
331
+ }
332
+
333
+ cpu_watchpoint_insert(CPU(cpu), wvr, len, flags,
334
+ &env->cpu_watchpoint[n]);
335
+}
336
+
337
+void hw_watchpoint_update_all(ARMCPU *cpu)
338
+{
339
+ int i;
340
+ CPUARMState *env = &cpu->env;
341
+
342
+ /*
343
+ * Completely clear out existing QEMU watchpoints and our array, to
344
+ * avoid possible stale entries following migration load.
345
+ */
346
+ cpu_watchpoint_remove_all(CPU(cpu), BP_CPU);
347
+ memset(env->cpu_watchpoint, 0, sizeof(env->cpu_watchpoint));
348
+
349
+ for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_watchpoint); i++) {
350
+ hw_watchpoint_update(cpu, i);
351
+ }
352
+}
353
+
354
+static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
355
+ uint64_t value)
356
+{
357
+ ARMCPU *cpu = env_archcpu(env);
358
+ int i = ri->crm;
359
+
360
+ /*
361
+ * Bits [1:0] are RES0.
362
+ *
363
+ * It is IMPLEMENTATION DEFINED whether [63:49] ([63:53] with FEAT_LVA)
364
+ * are hardwired to the value of bit [48] ([52] with FEAT_LVA), or if
365
+ * they contain the value written. It is CONSTRAINED UNPREDICTABLE
366
+ * whether the RESS bits are ignored when comparing an address.
367
+ *
368
+ * Therefore we are allowed to compare the entire register, which lets
369
+ * us avoid considering whether or not FEAT_LVA is actually enabled.
370
+ */
371
+ value &= ~3ULL;
372
+
373
+ raw_write(env, ri, value);
374
+ hw_watchpoint_update(cpu, i);
375
+}
376
+
377
+static void dbgwcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
378
+ uint64_t value)
379
+{
380
+ ARMCPU *cpu = env_archcpu(env);
381
+ int i = ri->crm;
382
+
383
+ raw_write(env, ri, value);
384
+ hw_watchpoint_update(cpu, i);
385
+}
386
+
387
+void hw_breakpoint_update(ARMCPU *cpu, int n)
388
+{
389
+ CPUARMState *env = &cpu->env;
390
+ uint64_t bvr = env->cp15.dbgbvr[n];
391
+ uint64_t bcr = env->cp15.dbgbcr[n];
392
+ vaddr addr;
393
+ int bt;
394
+ int flags = BP_CPU;
395
+
396
+ if (env->cpu_breakpoint[n]) {
397
+ cpu_breakpoint_remove_by_ref(CPU(cpu), env->cpu_breakpoint[n]);
398
+ env->cpu_breakpoint[n] = NULL;
399
+ }
400
+
401
+ if (!extract64(bcr, 0, 1)) {
402
+ /* E bit clear : watchpoint disabled */
403
+ return;
404
+ }
405
+
406
+ bt = extract64(bcr, 20, 4);
407
+
408
+ switch (bt) {
409
+ case 4: /* unlinked address mismatch (reserved if AArch64) */
410
+ case 5: /* linked address mismatch (reserved if AArch64) */
411
+ qemu_log_mask(LOG_UNIMP,
412
+ "arm: address mismatch breakpoint types not implemented\n");
413
+ return;
414
+ case 0: /* unlinked address match */
415
+ case 1: /* linked address match */
416
+ {
417
+ /*
418
+ * Bits [1:0] are RES0.
419
+ *
420
+ * It is IMPLEMENTATION DEFINED whether bits [63:49]
421
+ * ([63:53] for FEAT_LVA) are hardwired to a copy of the sign bit
422
+ * of the VA field ([48] or [52] for FEAT_LVA), or whether the
423
+ * value is read as written. It is CONSTRAINED UNPREDICTABLE
424
+ * whether the RESS bits are ignored when comparing an address.
425
+ * Therefore we are allowed to compare the entire register, which
426
+ * lets us avoid considering whether FEAT_LVA is actually enabled.
427
+ *
428
+ * The BAS field is used to allow setting breakpoints on 16-bit
429
+ * wide instructions; it is CONSTRAINED UNPREDICTABLE whether
430
+ * a bp will fire if the addresses covered by the bp and the addresses
431
+ * covered by the insn overlap but the insn doesn't start at the
432
+ * start of the bp address range. We choose to require the insn and
433
+ * the bp to have the same address. The constraints on writing to
434
+ * BAS enforced in dbgbcr_write mean we have only four cases:
435
+ * 0b0000 => no breakpoint
436
+ * 0b0011 => breakpoint on addr
437
+ * 0b1100 => breakpoint on addr + 2
438
+ * 0b1111 => breakpoint on addr
439
+ * See also figure D2-3 in the v8 ARM ARM (DDI0487A.c).
440
+ */
441
+ int bas = extract64(bcr, 5, 4);
442
+ addr = bvr & ~3ULL;
443
+ if (bas == 0) {
444
+ return;
445
+ }
446
+ if (bas == 0xc) {
447
+ addr += 2;
448
+ }
449
+ break;
450
+ }
451
+ case 2: /* unlinked context ID match */
452
+ case 8: /* unlinked VMID match (reserved if no EL2) */
453
+ case 10: /* unlinked context ID and VMID match (reserved if no EL2) */
454
+ qemu_log_mask(LOG_UNIMP,
455
+ "arm: unlinked context breakpoint types not implemented\n");
456
+ return;
457
+ case 9: /* linked VMID match (reserved if no EL2) */
458
+ case 11: /* linked context ID and VMID match (reserved if no EL2) */
459
+ case 3: /* linked context ID match */
460
+ default:
461
+ /*
462
+ * We must generate no events for Linked context matches (unless
463
+ * they are linked to by some other bp/wp, which is handled in
464
+ * updates for the linking bp/wp). We choose to also generate no events
465
+ * for reserved values.
466
+ */
467
+ return;
468
+ }
469
+
470
+ cpu_breakpoint_insert(CPU(cpu), addr, flags, &env->cpu_breakpoint[n]);
471
+}
472
+
473
+void hw_breakpoint_update_all(ARMCPU *cpu)
474
+{
475
+ int i;
476
+ CPUARMState *env = &cpu->env;
477
+
478
+ /*
479
+ * Completely clear out existing QEMU breakpoints and our array, to
480
+ * avoid possible stale entries following migration load.
481
+ */
482
+ cpu_breakpoint_remove_all(CPU(cpu), BP_CPU);
483
+ memset(env->cpu_breakpoint, 0, sizeof(env->cpu_breakpoint));
484
+
485
+ for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_breakpoint); i++) {
486
+ hw_breakpoint_update(cpu, i);
487
+ }
488
+}
489
+
490
+static void dbgbvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
491
+ uint64_t value)
492
+{
493
+ ARMCPU *cpu = env_archcpu(env);
494
+ int i = ri->crm;
495
+
496
+ raw_write(env, ri, value);
497
+ hw_breakpoint_update(cpu, i);
498
+}
499
+
500
+static void dbgbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
501
+ uint64_t value)
502
+{
503
+ ARMCPU *cpu = env_archcpu(env);
504
+ int i = ri->crm;
505
+
506
+ /*
507
+ * BAS[3] is a read-only copy of BAS[2], and BAS[1] a read-only
508
+ * copy of BAS[0].
509
+ */
510
+ value = deposit64(value, 6, 1, extract64(value, 5, 1));
511
+ value = deposit64(value, 8, 1, extract64(value, 7, 1));
512
+
513
+ raw_write(env, ri, value);
514
+ hw_breakpoint_update(cpu, i);
515
+}
516
+
517
+void define_debug_regs(ARMCPU *cpu)
518
+{
519
+ /*
520
+ * Define v7 and v8 architectural debug registers.
521
+ * These are just dummy implementations for now.
522
+ */
523
+ int i;
524
+ int wrps, brps, ctx_cmps;
525
+
526
+ /*
527
+ * The Arm ARM says DBGDIDR is optional and deprecated if EL1 cannot
528
+ * use AArch32. Given that bit 15 is RES1, if the value is 0 then
529
+ * the register must not exist for this cpu.
530
+ */
531
+ if (cpu->isar.dbgdidr != 0) {
532
+ ARMCPRegInfo dbgdidr = {
533
+ .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0,
534
+ .opc1 = 0, .opc2 = 0,
535
+ .access = PL0_R, .accessfn = access_tda,
536
+ .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdidr,
537
+ };
538
+ define_one_arm_cp_reg(cpu, &dbgdidr);
539
+ }
540
+
541
+ brps = arm_num_brps(cpu);
542
+ wrps = arm_num_wrps(cpu);
543
+ ctx_cmps = arm_num_ctx_cmps(cpu);
544
+
545
+ assert(ctx_cmps <= brps);
546
+
547
+ define_arm_cp_regs(cpu, debug_cp_reginfo);
548
+
549
+ if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) {
550
+ define_arm_cp_regs(cpu, debug_lpae_cp_reginfo);
551
+ }
552
+
553
+ for (i = 0; i < brps; i++) {
554
+ char *dbgbvr_el1_name = g_strdup_printf("DBGBVR%d_EL1", i);
555
+ char *dbgbcr_el1_name = g_strdup_printf("DBGBCR%d_EL1", i);
556
+ ARMCPRegInfo dbgregs[] = {
557
+ { .name = dbgbvr_el1_name, .state = ARM_CP_STATE_BOTH,
558
+ .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,
559
+ .access = PL1_RW, .accessfn = access_tda,
560
+ .fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]),
561
+ .writefn = dbgbvr_write, .raw_writefn = raw_write
562
+ },
563
+ { .name = dbgbcr_el1_name, .state = ARM_CP_STATE_BOTH,
564
+ .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5,
565
+ .access = PL1_RW, .accessfn = access_tda,
566
+ .fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]),
567
+ .writefn = dbgbcr_write, .raw_writefn = raw_write
568
+ },
569
+ };
570
+ define_arm_cp_regs(cpu, dbgregs);
571
+ g_free(dbgbvr_el1_name);
572
+ g_free(dbgbcr_el1_name);
573
+ }
574
+
575
+ for (i = 0; i < wrps; i++) {
576
+ char *dbgwvr_el1_name = g_strdup_printf("DBGWVR%d_EL1", i);
577
+ char *dbgwcr_el1_name = g_strdup_printf("DBGWCR%d_EL1", i);
578
+ ARMCPRegInfo dbgregs[] = {
579
+ { .name = dbgwvr_el1_name, .state = ARM_CP_STATE_BOTH,
580
+ .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,
581
+ .access = PL1_RW, .accessfn = access_tda,
582
+ .fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]),
583
+ .writefn = dbgwvr_write, .raw_writefn = raw_write
584
+ },
585
+ { .name = dbgwcr_el1_name, .state = ARM_CP_STATE_BOTH,
586
+ .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7,
587
+ .access = PL1_RW, .accessfn = access_tda,
588
+ .fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]),
589
+ .writefn = dbgwcr_write, .raw_writefn = raw_write
590
+ },
591
+ };
592
+ define_arm_cp_regs(cpu, dbgregs);
593
+ g_free(dbgwvr_el1_name);
594
+ g_free(dbgwcr_el1_name);
595
+ }
596
+}
597
+
598
#if !defined(CONFIG_USER_ONLY)
599
600
vaddr arm_adjust_watchpoint_address(CPUState *cs, vaddr addr, int len)
601
diff --git a/target/arm/helper.c b/target/arm/helper.c
602
index XXXXXXX..XXXXXXX 100644
603
--- a/target/arm/helper.c
604
+++ b/target/arm/helper.c
605
@@ -XXX,XX +XXX,XX @@ static uint64_t raw_read(CPUARMState *env, const ARMCPRegInfo *ri)
606
}
607
}
608
609
-static void raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
610
- uint64_t value)
611
+void raw_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
612
{
613
assert(ri->fieldoffset);
614
if (cpreg_field_is_64bit(ri)) {
615
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_trap_aa32s_el1(CPUARMState *env,
616
return CP_ACCESS_TRAP_UNCATEGORIZED;
617
}
618
619
-static uint64_t arm_mdcr_el2_eff(CPUARMState *env)
620
-{
621
- return arm_is_el2_enabled(env) ? env->cp15.mdcr_el2 : 0;
622
-}
623
-
624
-/*
625
- * Check for traps to "powerdown debug" registers, which are controlled
626
- * by MDCR.TDOSA
627
- */
628
-static CPAccessResult access_tdosa(CPUARMState *env, const ARMCPRegInfo *ri,
629
- bool isread)
630
-{
631
- int el = arm_current_el(env);
632
- uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
633
- bool mdcr_el2_tdosa = (mdcr_el2 & MDCR_TDOSA) || (mdcr_el2 & MDCR_TDE) ||
634
- (arm_hcr_el2_eff(env) & HCR_TGE);
635
-
636
- if (el < 2 && mdcr_el2_tdosa) {
637
- return CP_ACCESS_TRAP_EL2;
638
- }
639
- if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDOSA)) {
640
- return CP_ACCESS_TRAP_EL3;
641
- }
642
- return CP_ACCESS_OK;
643
-}
644
-
645
-/*
646
- * Check for traps to "debug ROM" registers, which are controlled
647
- * by MDCR_EL2.TDRA for EL2 but by the more general MDCR_EL3.TDA for EL3.
648
- */
649
-static CPAccessResult access_tdra(CPUARMState *env, const ARMCPRegInfo *ri,
650
- bool isread)
651
-{
652
- int el = arm_current_el(env);
653
- uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
654
- bool mdcr_el2_tdra = (mdcr_el2 & MDCR_TDRA) || (mdcr_el2 & MDCR_TDE) ||
655
- (arm_hcr_el2_eff(env) & HCR_TGE);
656
-
657
- if (el < 2 && mdcr_el2_tdra) {
658
- return CP_ACCESS_TRAP_EL2;
659
- }
660
- if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDA)) {
661
- return CP_ACCESS_TRAP_EL3;
662
- }
663
- return CP_ACCESS_OK;
664
-}
665
-
666
-/*
667
- * Check for traps to general debug registers, which are controlled
668
- * by MDCR_EL2.TDA for EL2 and MDCR_EL3.TDA for EL3.
669
- */
670
-static CPAccessResult access_tda(CPUARMState *env, const ARMCPRegInfo *ri,
671
- bool isread)
672
-{
673
- int el = arm_current_el(env);
674
- uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
675
- bool mdcr_el2_tda = (mdcr_el2 & MDCR_TDA) || (mdcr_el2 & MDCR_TDE) ||
676
- (arm_hcr_el2_eff(env) & HCR_TGE);
677
-
678
- if (el < 2 && mdcr_el2_tda) {
679
- return CP_ACCESS_TRAP_EL2;
680
- }
681
- if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDA)) {
682
- return CP_ACCESS_TRAP_EL3;
683
- }
684
- return CP_ACCESS_OK;
685
-}
686
-
687
/* Check for traps to performance monitor registers, which are controlled
688
* by MDCR_EL2.TPM for EL2 and MDCR_EL3.TPM for EL3.
689
*/
690
@@ -XXX,XX +XXX,XX @@ static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri,
691
return CP_ACCESS_OK;
692
}
693
694
-static void oslar_write(CPUARMState *env, const ARMCPRegInfo *ri,
695
- uint64_t value)
696
-{
697
- /*
698
- * Writes to OSLAR_EL1 may update the OS lock status, which can be
699
- * read via a bit in OSLSR_EL1.
700
- */
701
- int oslock;
702
-
703
- if (ri->state == ARM_CP_STATE_AA32) {
704
- oslock = (value == 0xC5ACCE55);
705
- } else {
706
- oslock = value & 1;
707
- }
708
-
709
- env->cp15.oslsr_el1 = deposit32(env->cp15.oslsr_el1, 1, 1, oslock);
710
-}
711
-
712
-static const ARMCPRegInfo debug_cp_reginfo[] = {
713
- /*
714
- * DBGDRAR, DBGDSAR: always RAZ since we don't implement memory mapped
715
- * debug components. The AArch64 version of DBGDRAR is named MDRAR_EL1;
716
- * unlike DBGDRAR it is never accessible from EL0.
717
- * DBGDSAR is deprecated and must RAZ from v8 anyway, so it has no AArch64
718
- * accessor.
719
- */
720
- { .name = "DBGDRAR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0,
721
- .access = PL0_R, .accessfn = access_tdra,
722
- .type = ARM_CP_CONST, .resetvalue = 0 },
723
- { .name = "MDRAR_EL1", .state = ARM_CP_STATE_AA64,
724
- .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0,
725
- .access = PL1_R, .accessfn = access_tdra,
726
- .type = ARM_CP_CONST, .resetvalue = 0 },
727
- { .name = "DBGDSAR", .cp = 14, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
728
- .access = PL0_R, .accessfn = access_tdra,
729
- .type = ARM_CP_CONST, .resetvalue = 0 },
730
- /* Monitor debug system control register; the 32-bit alias is DBGDSCRext. */
731
- { .name = "MDSCR_EL1", .state = ARM_CP_STATE_BOTH,
732
- .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
733
- .access = PL1_RW, .accessfn = access_tda,
734
- .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1),
735
- .resetvalue = 0 },
736
- /*
737
- * MDCCSR_EL0[30:29] map to EDSCR[30:29]. Simply RAZ as the external
738
- * Debug Communication Channel is not implemented.
739
- */
740
- { .name = "MDCCSR_EL0", .state = ARM_CP_STATE_AA64,
741
- .opc0 = 2, .opc1 = 3, .crn = 0, .crm = 1, .opc2 = 0,
742
- .access = PL0_R, .accessfn = access_tda,
743
- .type = ARM_CP_CONST, .resetvalue = 0 },
744
- /*
745
- * DBGDSCRint[15,12,5:2] map to MDSCR_EL1[15,12,5:2]. Map all bits as
746
- * it is unlikely a guest will care.
747
- * We don't implement the configurable EL0 access.
748
- */
749
- { .name = "DBGDSCRint", .state = ARM_CP_STATE_AA32,
750
- .cp = 14, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0,
751
- .type = ARM_CP_ALIAS,
752
- .access = PL1_R, .accessfn = access_tda,
753
- .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), },
754
- { .name = "OSLAR_EL1", .state = ARM_CP_STATE_BOTH,
755
- .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 4,
756
- .access = PL1_W, .type = ARM_CP_NO_RAW,
757
- .accessfn = access_tdosa,
758
- .writefn = oslar_write },
759
- { .name = "OSLSR_EL1", .state = ARM_CP_STATE_BOTH,
760
- .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 4,
761
- .access = PL1_R, .resetvalue = 10,
762
- .accessfn = access_tdosa,
763
- .fieldoffset = offsetof(CPUARMState, cp15.oslsr_el1) },
764
- /* Dummy OSDLR_EL1: 32-bit Linux will read this */
765
- { .name = "OSDLR_EL1", .state = ARM_CP_STATE_BOTH,
766
- .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 4,
767
- .access = PL1_RW, .accessfn = access_tdosa,
768
- .type = ARM_CP_NOP },
769
- /*
770
- * Dummy DBGVCR: Linux wants to clear this on startup, but we don't
771
- * implement vector catch debug events yet.
772
- */
773
- { .name = "DBGVCR",
774
- .cp = 14, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
775
- .access = PL1_RW, .accessfn = access_tda,
776
- .type = ARM_CP_NOP },
777
- /*
778
- * Dummy DBGVCR32_EL2 (which is only for a 64-bit hypervisor
779
- * to save and restore a 32-bit guest's DBGVCR)
780
- */
781
- { .name = "DBGVCR32_EL2", .state = ARM_CP_STATE_AA64,
782
- .opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0,
783
- .access = PL2_RW, .accessfn = access_tda,
784
- .type = ARM_CP_NOP | ARM_CP_EL3_NO_EL2_KEEP },
785
- /*
786
- * Dummy MDCCINT_EL1, since we don't implement the Debug Communications
787
- * Channel but Linux may try to access this register. The 32-bit
788
- * alias is DBGDCCINT.
789
- */
790
- { .name = "MDCCINT_EL1", .state = ARM_CP_STATE_BOTH,
791
- .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
792
- .access = PL1_RW, .accessfn = access_tda,
793
- .type = ARM_CP_NOP },
794
-};
795
-
796
-static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
797
- /* 64 bit access versions of the (dummy) debug registers */
798
- { .name = "DBGDRAR", .cp = 14, .crm = 1, .opc1 = 0,
799
- .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
800
- { .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0,
801
- .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
802
-};
803
-
804
/*
805
* Check for traps to RAS registers, which are controlled
806
* by HCR_EL2.TERR and SCR_EL3.TERR.
807
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo sme_reginfo[] = {
22
};
808
};
23
809
#endif /* TARGET_AARCH64 */
24
static const BCM283XInfo bcm283x_socs[] = {
810
25
{
811
-void hw_watchpoint_update(ARMCPU *cpu, int n)
26
.name = TYPE_BCM2836,
812
-{
27
+ .clusterid = 0xf,
813
- CPUARMState *env = &cpu->env;
28
},
814
- vaddr len = 0;
29
{
815
- vaddr wvr = env->cp15.dbgwvr[n];
30
.name = TYPE_BCM2837,
816
- uint64_t wcr = env->cp15.dbgwcr[n];
31
+ .clusterid = 0x0,
817
- int mask;
32
},
818
- int flags = BP_CPU | BP_STOP_BEFORE_ACCESS;
33
};
819
-
34
820
- if (env->cpu_watchpoint[n]) {
35
@@ -XXX,XX +XXX,XX @@ static void bcm2836_init(Object *obj)
821
- cpu_watchpoint_remove_by_ref(CPU(cpu), env->cpu_watchpoint[n]);
36
static void bcm2836_realize(DeviceState *dev, Error **errp)
822
- env->cpu_watchpoint[n] = NULL;
823
- }
824
-
825
- if (!FIELD_EX64(wcr, DBGWCR, E)) {
826
- /* E bit clear : watchpoint disabled */
827
- return;
828
- }
829
-
830
- switch (FIELD_EX64(wcr, DBGWCR, LSC)) {
831
- case 0:
832
- /* LSC 00 is reserved and must behave as if the wp is disabled */
833
- return;
834
- case 1:
835
- flags |= BP_MEM_READ;
836
- break;
837
- case 2:
838
- flags |= BP_MEM_WRITE;
839
- break;
840
- case 3:
841
- flags |= BP_MEM_ACCESS;
842
- break;
843
- }
844
-
845
- /*
846
- * Attempts to use both MASK and BAS fields simultaneously are
847
- * CONSTRAINED UNPREDICTABLE; we opt to ignore BAS in this case,
848
- * thus generating a watchpoint for every byte in the masked region.
849
- */
850
- mask = FIELD_EX64(wcr, DBGWCR, MASK);
851
- if (mask == 1 || mask == 2) {
852
- /*
853
- * Reserved values of MASK; we must act as if the mask value was
854
- * some non-reserved value, or as if the watchpoint were disabled.
855
- * We choose the latter.
856
- */
857
- return;
858
- } else if (mask) {
859
- /* Watchpoint covers an aligned area up to 2GB in size */
860
- len = 1ULL << mask;
861
- /*
862
- * If masked bits in WVR are not zero it's CONSTRAINED UNPREDICTABLE
863
- * whether the watchpoint fires when the unmasked bits match; we opt
864
- * to generate the exceptions.
865
- */
866
- wvr &= ~(len - 1);
867
- } else {
868
- /* Watchpoint covers bytes defined by the byte address select bits */
869
- int bas = FIELD_EX64(wcr, DBGWCR, BAS);
870
- int basstart;
871
-
872
- if (extract64(wvr, 2, 1)) {
873
- /*
874
- * Deprecated case of an only 4-aligned address. BAS[7:4] are
875
- * ignored, and BAS[3:0] define which bytes to watch.
876
- */
877
- bas &= 0xf;
878
- }
879
-
880
- if (bas == 0) {
881
- /* This must act as if the watchpoint is disabled */
882
- return;
883
- }
884
-
885
- /*
886
- * The BAS bits are supposed to be programmed to indicate a contiguous
887
- * range of bytes. Otherwise it is CONSTRAINED UNPREDICTABLE whether
888
- * we fire for each byte in the word/doubleword addressed by the WVR.
889
- * We choose to ignore any non-zero bits after the first range of 1s.
890
- */
891
- basstart = ctz32(bas);
892
- len = cto32(bas >> basstart);
893
- wvr += basstart;
894
- }
895
-
896
- cpu_watchpoint_insert(CPU(cpu), wvr, len, flags,
897
- &env->cpu_watchpoint[n]);
898
-}
899
-
900
-void hw_watchpoint_update_all(ARMCPU *cpu)
901
-{
902
- int i;
903
- CPUARMState *env = &cpu->env;
904
-
905
- /*
906
- * Completely clear out existing QEMU watchpoints and our array, to
907
- * avoid possible stale entries following migration load.
908
- */
909
- cpu_watchpoint_remove_all(CPU(cpu), BP_CPU);
910
- memset(env->cpu_watchpoint, 0, sizeof(env->cpu_watchpoint));
911
-
912
- for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_watchpoint); i++) {
913
- hw_watchpoint_update(cpu, i);
914
- }
915
-}
916
-
917
-static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
918
- uint64_t value)
919
-{
920
- ARMCPU *cpu = env_archcpu(env);
921
- int i = ri->crm;
922
-
923
- /*
924
- * Bits [1:0] are RES0.
925
- *
926
- * It is IMPLEMENTATION DEFINED whether [63:49] ([63:53] with FEAT_LVA)
927
- * are hardwired to the value of bit [48] ([52] with FEAT_LVA), or if
928
- * they contain the value written. It is CONSTRAINED UNPREDICTABLE
929
- * whether the RESS bits are ignored when comparing an address.
930
- *
931
- * Therefore we are allowed to compare the entire register, which lets
932
- * us avoid considering whether or not FEAT_LVA is actually enabled.
933
- */
934
- value &= ~3ULL;
935
-
936
- raw_write(env, ri, value);
937
- hw_watchpoint_update(cpu, i);
938
-}
939
-
940
-static void dbgwcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
941
- uint64_t value)
942
-{
943
- ARMCPU *cpu = env_archcpu(env);
944
- int i = ri->crm;
945
-
946
- raw_write(env, ri, value);
947
- hw_watchpoint_update(cpu, i);
948
-}
949
-
950
-void hw_breakpoint_update(ARMCPU *cpu, int n)
951
-{
952
- CPUARMState *env = &cpu->env;
953
- uint64_t bvr = env->cp15.dbgbvr[n];
954
- uint64_t bcr = env->cp15.dbgbcr[n];
955
- vaddr addr;
956
- int bt;
957
- int flags = BP_CPU;
958
-
959
- if (env->cpu_breakpoint[n]) {
960
- cpu_breakpoint_remove_by_ref(CPU(cpu), env->cpu_breakpoint[n]);
961
- env->cpu_breakpoint[n] = NULL;
962
- }
963
-
964
- if (!extract64(bcr, 0, 1)) {
965
- /* E bit clear : watchpoint disabled */
966
- return;
967
- }
968
-
969
- bt = extract64(bcr, 20, 4);
970
-
971
- switch (bt) {
972
- case 4: /* unlinked address mismatch (reserved if AArch64) */
973
- case 5: /* linked address mismatch (reserved if AArch64) */
974
- qemu_log_mask(LOG_UNIMP,
975
- "arm: address mismatch breakpoint types not implemented\n");
976
- return;
977
- case 0: /* unlinked address match */
978
- case 1: /* linked address match */
979
- {
980
- /*
981
- * Bits [1:0] are RES0.
982
- *
983
- * It is IMPLEMENTATION DEFINED whether bits [63:49]
984
- * ([63:53] for FEAT_LVA) are hardwired to a copy of the sign bit
985
- * of the VA field ([48] or [52] for FEAT_LVA), or whether the
986
- * value is read as written. It is CONSTRAINED UNPREDICTABLE
987
- * whether the RESS bits are ignored when comparing an address.
988
- * Therefore we are allowed to compare the entire register, which
989
- * lets us avoid considering whether FEAT_LVA is actually enabled.
990
- *
991
- * The BAS field is used to allow setting breakpoints on 16-bit
992
- * wide instructions; it is CONSTRAINED UNPREDICTABLE whether
993
- * a bp will fire if the addresses covered by the bp and the addresses
994
- * covered by the insn overlap but the insn doesn't start at the
995
- * start of the bp address range. We choose to require the insn and
996
- * the bp to have the same address. The constraints on writing to
997
- * BAS enforced in dbgbcr_write mean we have only four cases:
998
- * 0b0000 => no breakpoint
999
- * 0b0011 => breakpoint on addr
1000
- * 0b1100 => breakpoint on addr + 2
1001
- * 0b1111 => breakpoint on addr
1002
- * See also figure D2-3 in the v8 ARM ARM (DDI0487A.c).
1003
- */
1004
- int bas = extract64(bcr, 5, 4);
1005
- addr = bvr & ~3ULL;
1006
- if (bas == 0) {
1007
- return;
1008
- }
1009
- if (bas == 0xc) {
1010
- addr += 2;
1011
- }
1012
- break;
1013
- }
1014
- case 2: /* unlinked context ID match */
1015
- case 8: /* unlinked VMID match (reserved if no EL2) */
1016
- case 10: /* unlinked context ID and VMID match (reserved if no EL2) */
1017
- qemu_log_mask(LOG_UNIMP,
1018
- "arm: unlinked context breakpoint types not implemented\n");
1019
- return;
1020
- case 9: /* linked VMID match (reserved if no EL2) */
1021
- case 11: /* linked context ID and VMID match (reserved if no EL2) */
1022
- case 3: /* linked context ID match */
1023
- default:
1024
- /*
1025
- * We must generate no events for Linked context matches (unless
1026
- * they are linked to by some other bp/wp, which is handled in
1027
- * updates for the linking bp/wp). We choose to also generate no events
1028
- * for reserved values.
1029
- */
1030
- return;
1031
- }
1032
-
1033
- cpu_breakpoint_insert(CPU(cpu), addr, flags, &env->cpu_breakpoint[n]);
1034
-}
1035
-
1036
-void hw_breakpoint_update_all(ARMCPU *cpu)
1037
-{
1038
- int i;
1039
- CPUARMState *env = &cpu->env;
1040
-
1041
- /*
1042
- * Completely clear out existing QEMU breakpoints and our array, to
1043
- * avoid possible stale entries following migration load.
1044
- */
1045
- cpu_breakpoint_remove_all(CPU(cpu), BP_CPU);
1046
- memset(env->cpu_breakpoint, 0, sizeof(env->cpu_breakpoint));
1047
-
1048
- for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_breakpoint); i++) {
1049
- hw_breakpoint_update(cpu, i);
1050
- }
1051
-}
1052
-
1053
-static void dbgbvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1054
- uint64_t value)
1055
-{
1056
- ARMCPU *cpu = env_archcpu(env);
1057
- int i = ri->crm;
1058
-
1059
- raw_write(env, ri, value);
1060
- hw_breakpoint_update(cpu, i);
1061
-}
1062
-
1063
-static void dbgbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1064
- uint64_t value)
1065
-{
1066
- ARMCPU *cpu = env_archcpu(env);
1067
- int i = ri->crm;
1068
-
1069
- /*
1070
- * BAS[3] is a read-only copy of BAS[2], and BAS[1] a read-only
1071
- * copy of BAS[0].
1072
- */
1073
- value = deposit64(value, 6, 1, extract64(value, 5, 1));
1074
- value = deposit64(value, 8, 1, extract64(value, 7, 1));
1075
-
1076
- raw_write(env, ri, value);
1077
- hw_breakpoint_update(cpu, i);
1078
-}
1079
-
1080
-static void define_debug_regs(ARMCPU *cpu)
1081
-{
1082
- /*
1083
- * Define v7 and v8 architectural debug registers.
1084
- * These are just dummy implementations for now.
1085
- */
1086
- int i;
1087
- int wrps, brps, ctx_cmps;
1088
-
1089
- /*
1090
- * The Arm ARM says DBGDIDR is optional and deprecated if EL1 cannot
1091
- * use AArch32. Given that bit 15 is RES1, if the value is 0 then
1092
- * the register must not exist for this cpu.
1093
- */
1094
- if (cpu->isar.dbgdidr != 0) {
1095
- ARMCPRegInfo dbgdidr = {
1096
- .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0,
1097
- .opc1 = 0, .opc2 = 0,
1098
- .access = PL0_R, .accessfn = access_tda,
1099
- .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdidr,
1100
- };
1101
- define_one_arm_cp_reg(cpu, &dbgdidr);
1102
- }
1103
-
1104
- brps = arm_num_brps(cpu);
1105
- wrps = arm_num_wrps(cpu);
1106
- ctx_cmps = arm_num_ctx_cmps(cpu);
1107
-
1108
- assert(ctx_cmps <= brps);
1109
-
1110
- define_arm_cp_regs(cpu, debug_cp_reginfo);
1111
-
1112
- if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) {
1113
- define_arm_cp_regs(cpu, debug_lpae_cp_reginfo);
1114
- }
1115
-
1116
- for (i = 0; i < brps; i++) {
1117
- char *dbgbvr_el1_name = g_strdup_printf("DBGBVR%d_EL1", i);
1118
- char *dbgbcr_el1_name = g_strdup_printf("DBGBCR%d_EL1", i);
1119
- ARMCPRegInfo dbgregs[] = {
1120
- { .name = dbgbvr_el1_name, .state = ARM_CP_STATE_BOTH,
1121
- .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,
1122
- .access = PL1_RW, .accessfn = access_tda,
1123
- .fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]),
1124
- .writefn = dbgbvr_write, .raw_writefn = raw_write
1125
- },
1126
- { .name = dbgbcr_el1_name, .state = ARM_CP_STATE_BOTH,
1127
- .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5,
1128
- .access = PL1_RW, .accessfn = access_tda,
1129
- .fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]),
1130
- .writefn = dbgbcr_write, .raw_writefn = raw_write
1131
- },
1132
- };
1133
- define_arm_cp_regs(cpu, dbgregs);
1134
- g_free(dbgbvr_el1_name);
1135
- g_free(dbgbcr_el1_name);
1136
- }
1137
-
1138
- for (i = 0; i < wrps; i++) {
1139
- char *dbgwvr_el1_name = g_strdup_printf("DBGWVR%d_EL1", i);
1140
- char *dbgwcr_el1_name = g_strdup_printf("DBGWCR%d_EL1", i);
1141
- ARMCPRegInfo dbgregs[] = {
1142
- { .name = dbgwvr_el1_name, .state = ARM_CP_STATE_BOTH,
1143
- .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,
1144
- .access = PL1_RW, .accessfn = access_tda,
1145
- .fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]),
1146
- .writefn = dbgwvr_write, .raw_writefn = raw_write
1147
- },
1148
- { .name = dbgwcr_el1_name, .state = ARM_CP_STATE_BOTH,
1149
- .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7,
1150
- .access = PL1_RW, .accessfn = access_tda,
1151
- .fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]),
1152
- .writefn = dbgwcr_write, .raw_writefn = raw_write
1153
- },
1154
- };
1155
- define_arm_cp_regs(cpu, dbgregs);
1156
- g_free(dbgwvr_el1_name);
1157
- g_free(dbgwcr_el1_name);
1158
- }
1159
-}
1160
-
1161
static void define_pmu_regs(ARMCPU *cpu)
37
{
1162
{
38
BCM283XState *s = BCM283X(dev);
1163
/*
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
--
1164
--
58
2.16.2
1165
2.25.1
59
60
diff view generated by jsdifflib
1
The bcm2837 is pretty similar to the bcm2836, but it does have
1
The "OS Lock" in the Arm debug architecture is a way for software
2
some differences. Notably, the MPIDR affinity aff1 values it
2
to suppress debug exceptions while it is trying to power down
3
sets for the CPUs are 0x0, rather than the 0xf that the bcm2836
3
a CPU and save the state of the breakpoint and watchpoint
4
uses, and if this is wrong Linux will not boot.
4
registers. In QEMU we implemented the support for writing
5
the OS Lock bit via OSLAR_EL1 and reading it via OSLSR_EL1,
6
but didn't implement the actual behaviour.
5
7
6
Rather than trying to have one device with properties that
8
The required behaviour with the OS Lock set is:
7
configure it differently for the two cases, create two
9
* debug exceptions (apart from BKPT insns) are suppressed
8
separate QOM devices for the two SoCs. We use the same approach
10
* some MDSCR_EL1 bits allow write access to the corresponding
9
as hw/arm/aspeed_soc.c and share code and have a data table
11
EDSCR external debug status register that they shadow
10
that might differ per-SoC. For the moment the two types don't
12
(we can ignore this because we don't implement external debug)
11
actually have different behaviour.
13
* similarly with the OSECCR_EL1 which shadows the EDECCR
14
(but we don't implement OSECCR_EL1 anyway)
15
16
Implement the missing behaviour of suppressing debug
17
exceptions.
12
18
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20180313153458.26822-7-peter.maydell@linaro.org
21
Message-id: 20220630194116.3438513-4-peter.maydell@linaro.org
16
---
22
---
17
include/hw/arm/bcm2836.h | 19 +++++++++++++++++++
23
target/arm/debug_helper.c | 3 +++
18
hw/arm/bcm2836.c | 37 ++++++++++++++++++++++++++++++++-----
24
1 file changed, 3 insertions(+)
19
hw/arm/raspi.c | 3 ++-
20
3 files changed, 53 insertions(+), 6 deletions(-)
21
25
22
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
26
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
23
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/arm/bcm2836.h
28
--- a/target/arm/debug_helper.c
25
+++ b/include/hw/arm/bcm2836.h
29
+++ b/target/arm/debug_helper.c
26
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@ static bool aa32_generate_debug_exceptions(CPUARMState *env)
27
31
*/
28
#define BCM283X_NCPUS 4
32
bool arm_generate_debug_exceptions(CPUARMState *env)
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
{
33
{
80
BCM283XState *s = BCM283X(obj);
34
+ if (env->cp15.oslsr_el1 & 1) {
81
@@ -XXX,XX +XXX,XX @@ static Property bcm2836_props[] = {
35
+ return false;
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
+ }
36
+ }
123
}
37
if (is_a64(env)) {
124
38
return aa64_generate_debug_exceptions(env);
125
type_init(bcm2836_register_types)
39
} else {
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
140
--
40
--
141
2.16.2
41
2.25.1
142
143
diff view generated by jsdifflib
1
The raspi3 has AArch64 CPUs, which means that our smpboot
1
Starting with v7 of the debug architecture, there are three extra
2
code for keeping the secondary CPUs in a pen needs to have
2
ID registers that add information on top of that provided in
3
a version for A64 as well as A32. Without this, the
3
DBGDIDR. These are DBGDEVID, DBGDEVID1 and DBGDEVID2. In the
4
secondary CPUs go into an infinite loop of taking undefined
4
v7 debug architecture, DBGDEVID is optional, present only of
5
instruction exceptions.
5
DBGDIDR.DEVID_imp is set. In v7.1 all three must be present.
6
7
Implement the missing registers. Note that we only need to set the
8
values in the ARMISARegisters struct for the CPUs Cortex-A7, A15,
9
A53, A57 and A72 (plus the 32-bit 'max' which uses the Cortex-A53
10
values): earlier CPUs didn't implement v7 of the architecture, and
11
our other 64-bit CPUs (Cortex-A76, Neoverse-N1 and A64fx) don't have
12
AArch32 support at EL1.
6
13
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180313153458.26822-10-peter.maydell@linaro.org
16
Message-id: 20220630194116.3438513-5-peter.maydell@linaro.org
10
---
17
---
11
hw/arm/raspi.c | 41 ++++++++++++++++++++++++++++++++++++++++-
18
target/arm/cpu.h | 7 +++++++
12
1 file changed, 40 insertions(+), 1 deletion(-)
19
target/arm/cpu64.c | 6 ++++++
20
target/arm/cpu_tcg.c | 6 ++++++
21
target/arm/debug_helper.c | 36 ++++++++++++++++++++++++++++++++++++
22
4 files changed, 55 insertions(+)
13
23
14
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
24
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/raspi.c
26
--- a/target/arm/cpu.h
17
+++ b/hw/arm/raspi.c
27
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
19
#define BOARDSETUP_ADDR (MVBAR_ADDR + 0x20) /* board setup code */
29
uint32_t mvfr2;
20
#define FIRMWARE_ADDR_2 0x8000 /* Pi 2 loads kernel.img here by default */
30
uint32_t id_dfr0;
21
#define FIRMWARE_ADDR_3 0x80000 /* Pi 3 loads kernel.img here by default */
31
uint32_t dbgdidr;
22
+#define SPINTABLE_ADDR 0xd8 /* Pi 3 bootloader spintable */
32
+ uint32_t dbgdevid;
23
33
+ uint32_t dbgdevid1;
24
/* Table of Linux board IDs for different Pi versions */
34
uint64_t id_aa64isar0;
25
static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44};
35
uint64_t id_aa64isar1;
26
@@ -XXX,XX +XXX,XX @@ static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
36
uint64_t id_aa64pfr0;
27
info->smp_loader_start);
37
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id)
38
return FIELD_EX32(id->id_pfr2, ID_PFR2, SSBS) != 0;
28
}
39
}
29
40
30
+static void write_smpboot64(ARMCPU *cpu, const struct arm_boot_info *info)
41
+static inline bool isar_feature_aa32_debugv7p1(const ARMISARegisters *id)
31
+{
42
+{
32
+ /* Unlike the AArch32 version we don't need to call the board setup hook.
43
+ return FIELD_EX32(id->id_dfr0, ID_DFR0, COPDBG) >= 5;
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
+
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
+}
44
+}
63
+
45
+
64
static void write_board_setup(ARMCPU *cpu, const struct arm_boot_info *info)
46
static inline bool isar_feature_aa32_debugv8p2(const ARMISARegisters *id)
65
{
47
{
66
arm_write_secure_board_setup_dummy_smc(cpu, info, MVBAR_ADDR);
48
return FIELD_EX32(id->id_dfr0, ID_DFR0, COPDBG) >= 8;
67
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
49
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
68
/* Pi2 and Pi3 requires SMP setup */
50
index XXXXXXX..XXXXXXX 100644
69
if (version >= 2) {
51
--- a/target/arm/cpu64.c
70
binfo.smp_loader_start = SMPBOOT_ADDR;
52
+++ b/target/arm/cpu64.c
71
- binfo.write_secondary_boot = write_smpboot;
53
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
72
+ if (version == 2) {
54
cpu->isar.id_aa64isar0 = 0x00011120;
73
+ binfo.write_secondary_boot = write_smpboot;
55
cpu->isar.id_aa64mmfr0 = 0x00001124;
74
+ } else {
56
cpu->isar.dbgdidr = 0x3516d000;
75
+ binfo.write_secondary_boot = write_smpboot64;
57
+ cpu->isar.dbgdevid = 0x01110f13;
76
+ }
58
+ cpu->isar.dbgdevid1 = 0x2;
77
binfo.secondary_cpu_reset_hook = reset_secondary;
59
cpu->isar.reset_pmcr_el0 = 0x41013000;
60
cpu->clidr = 0x0a200023;
61
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
62
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
63
cpu->isar.id_aa64isar0 = 0x00011120;
64
cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
65
cpu->isar.dbgdidr = 0x3516d000;
66
+ cpu->isar.dbgdevid = 0x00110f13;
67
+ cpu->isar.dbgdevid1 = 0x1;
68
cpu->isar.reset_pmcr_el0 = 0x41033000;
69
cpu->clidr = 0x0a200023;
70
cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
71
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
72
cpu->isar.id_aa64isar0 = 0x00011120;
73
cpu->isar.id_aa64mmfr0 = 0x00001124;
74
cpu->isar.dbgdidr = 0x3516d000;
75
+ cpu->isar.dbgdevid = 0x01110f13;
76
+ cpu->isar.dbgdevid1 = 0x2;
77
cpu->isar.reset_pmcr_el0 = 0x41023000;
78
cpu->clidr = 0x0a200023;
79
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
80
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/cpu_tcg.c
83
+++ b/target/arm/cpu_tcg.c
84
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
85
cpu->isar.id_isar3 = 0x11112131;
86
cpu->isar.id_isar4 = 0x10011142;
87
cpu->isar.dbgdidr = 0x3515f005;
88
+ cpu->isar.dbgdevid = 0x01110f13;
89
+ cpu->isar.dbgdevid1 = 0x1;
90
cpu->clidr = 0x0a200023;
91
cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
92
cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
93
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
94
cpu->isar.id_isar3 = 0x11112131;
95
cpu->isar.id_isar4 = 0x10011142;
96
cpu->isar.dbgdidr = 0x3515f021;
97
+ cpu->isar.dbgdevid = 0x01110f13;
98
+ cpu->isar.dbgdevid1 = 0x0;
99
cpu->clidr = 0x0a200023;
100
cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
101
cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
102
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
103
cpu->isar.id_isar5 = 0x00011121;
104
cpu->isar.id_isar6 = 0;
105
cpu->isar.dbgdidr = 0x3516d000;
106
+ cpu->isar.dbgdevid = 0x00110f13;
107
+ cpu->isar.dbgdevid1 = 0x2;
108
cpu->isar.reset_pmcr_el0 = 0x41013000;
109
cpu->clidr = 0x0a200023;
110
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
111
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/target/arm/debug_helper.c
114
+++ b/target/arm/debug_helper.c
115
@@ -XXX,XX +XXX,XX @@ void define_debug_regs(ARMCPU *cpu)
116
define_one_arm_cp_reg(cpu, &dbgdidr);
78
}
117
}
79
118
119
+ /*
120
+ * DBGDEVID is present in the v7 debug architecture if
121
+ * DBGDIDR.DEVID_imp is 1 (bit 15); from v7.1 and on it is
122
+ * mandatory (and bit 15 is RES1). DBGDEVID1 and DBGDEVID2 exist
123
+ * from v7.1 of the debug architecture. Because no fields have yet
124
+ * been defined in DBGDEVID2 (and quite possibly none will ever
125
+ * be) we don't define an ARMISARegisters field for it.
126
+ * These registers exist only if EL1 can use AArch32, but that
127
+ * happens naturally because they are only PL1 accessible anyway.
128
+ */
129
+ if (extract32(cpu->isar.dbgdidr, 15, 1)) {
130
+ ARMCPRegInfo dbgdevid = {
131
+ .name = "DBGDEVID",
132
+ .cp = 14, .opc1 = 0, .crn = 7, .opc2 = 2, .crn = 7,
133
+ .access = PL1_R, .accessfn = access_tda,
134
+ .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdevid,
135
+ };
136
+ define_one_arm_cp_reg(cpu, &dbgdevid);
137
+ }
138
+ if (cpu_isar_feature(aa32_debugv7p1, cpu)) {
139
+ ARMCPRegInfo dbgdevid12[] = {
140
+ {
141
+ .name = "DBGDEVID1",
142
+ .cp = 14, .opc1 = 0, .crn = 7, .opc2 = 1, .crn = 7,
143
+ .access = PL1_R, .accessfn = access_tda,
144
+ .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdevid1,
145
+ }, {
146
+ .name = "DBGDEVID2",
147
+ .cp = 14, .opc1 = 0, .crn = 7, .opc2 = 0, .crn = 7,
148
+ .access = PL1_R, .accessfn = access_tda,
149
+ .type = ARM_CP_CONST, .resetvalue = 0,
150
+ },
151
+ };
152
+ define_arm_cp_regs(cpu, dbgdevid12);
153
+ }
154
+
155
brps = arm_num_brps(cpu);
156
wrps = arm_num_wrps(cpu);
157
ctx_cmps = arm_num_ctx_cmps(cpu);
80
--
158
--
81
2.16.2
159
2.25.1
82
83
diff view generated by jsdifflib
1
Our BCM2836 type is really a generic one that can be any of
1
The architecture defines the OS DoubleLock as a register which
2
the bcm283x family. Rename it accordingly. We change only
2
(similarly to the OS Lock) suppresses debug events for use in CPU
3
the names which are visible via the header file to the
3
powerdown sequences. This functionality is required in Arm v7 and
4
rest of the QEMU code, leaving private function names
4
v8.0; from v8.2 it becomes optional and in v9 it must not be
5
in bcm2836.c as they are.
5
implemented.
6
6
7
This is a preliminary to making bcm283x be an abstract
7
Currently in QEMU we implement the OSDLR_EL1 register as a NOP. This
8
parent class to specific types for the bcm2836 and bcm2837.
8
is wrong both for the "feature implemented" and the "feature not
9
implemented" cases: if the feature is implemented then the DLK bit
10
should read as written and cause suppression of debug exceptions, and
11
if it is not implemented then the bit must be RAZ/WI.
9
12
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
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
---
15
include/hw/arm/bcm2836.h | 12 ++++++------
16
target/arm/cpu.h | 20 ++++++++++++++++++++
16
hw/arm/bcm2836.c | 17 +++++++++--------
17
target/arm/debug_helper.c | 20 ++++++++++++++++++--
17
hw/arm/raspi.c | 16 ++++++++--------
18
2 files changed, 38 insertions(+), 2 deletions(-)
18
3 files changed, 23 insertions(+), 22 deletions(-)
19
19
20
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/arm/bcm2836.h
22
--- a/target/arm/cpu.h
23
+++ b/include/hw/arm/bcm2836.h
23
+++ b/target/arm/cpu.h
24
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
25
#include "hw/arm/bcm2835_peripherals.h"
25
uint64_t dbgwcr[16]; /* watchpoint control registers */
26
#include "hw/intc/bcm2836_control.h"
26
uint64_t mdscr_el1;
27
27
uint64_t oslsr_el1; /* OS Lock Status */
28
-#define TYPE_BCM2836 "bcm2836"
28
+ uint64_t osdlr_el1; /* OS DoubleLock status */
29
-#define BCM2836(obj) OBJECT_CHECK(BCM2836State, (obj), TYPE_BCM2836)
29
uint64_t mdcr_el2;
30
+#define TYPE_BCM283X "bcm283x"
30
uint64_t mdcr_el3;
31
+#define BCM283X(obj) OBJECT_CHECK(BCM283XState, (obj), TYPE_BCM283X)
31
/* Stores the architectural value of the counter *the last time it was
32
32
@@ -XXX,XX +XXX,XX @@ FIELD(DBGDIDR, CTX_CMPS, 20, 4)
33
-#define BCM2836_NCPUS 4
33
FIELD(DBGDIDR, BRPS, 24, 4)
34
+#define BCM283X_NCPUS 4
34
FIELD(DBGDIDR, WRPS, 28, 4)
35
35
36
-typedef struct BCM2836State {
36
+FIELD(DBGDEVID, PCSAMPLE, 0, 4)
37
+typedef struct BCM283XState {
37
+FIELD(DBGDEVID, WPADDRMASK, 4, 4)
38
/*< private >*/
38
+FIELD(DBGDEVID, BPADDRMASK, 8, 4)
39
DeviceState parent_obj;
39
+FIELD(DBGDEVID, VECTORCATCH, 12, 4)
40
/*< public >*/
40
+FIELD(DBGDEVID, VIRTEXTNS, 16, 4)
41
@@ -XXX,XX +XXX,XX @@ typedef struct BCM2836State {
41
+FIELD(DBGDEVID, DOUBLELOCK, 20, 4)
42
char *cpu_type;
42
+FIELD(DBGDEVID, AUXREGS, 24, 4)
43
uint32_t enabled_cpus;
43
+FIELD(DBGDEVID, CIDMASK, 28, 4)
44
44
+
45
- ARMCPU cpus[BCM2836_NCPUS];
45
FIELD(MVFR0, SIMDREG, 0, 4)
46
+ ARMCPU cpus[BCM283X_NCPUS];
46
FIELD(MVFR0, FPSP, 4, 4)
47
BCM2836ControlState control;
47
FIELD(MVFR0, FPDP, 8, 4)
48
BCM2835PeripheralState peripherals;
48
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_debugv8p2(const ARMISARegisters *id)
49
-} BCM2836State;
49
return FIELD_EX32(id->id_dfr0, ID_DFR0, COPDBG) >= 8;
50
+} BCM283XState;
50
}
51
51
52
#endif /* BCM2836_H */
52
+static inline bool isar_feature_aa32_doublelock(const ARMISARegisters *id)
53
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
53
+{
54
+ return FIELD_EX32(id->dbgdevid, DBGDEVID, DOUBLELOCK) > 0;
55
+}
56
+
57
/*
58
* 64-bit feature tests via id registers.
59
*/
60
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_sme_fa64(const ARMISARegisters *id)
61
return FIELD_EX64(id->id_aa64smfr0, ID_AA64SMFR0, FA64);
62
}
63
64
+static inline bool isar_feature_aa64_doublelock(const ARMISARegisters *id)
65
+{
66
+ return FIELD_SEX64(id->id_aa64dfr0, ID_AA64DFR0, DOUBLELOCK) >= 0;
67
+}
68
+
69
/*
70
* Feature tests for "does this exist in either 32-bit or 64-bit?"
71
*/
72
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
54
index XXXXXXX..XXXXXXX 100644
73
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/arm/bcm2836.c
74
--- a/target/arm/debug_helper.c
56
+++ b/hw/arm/bcm2836.c
75
+++ b/target/arm/debug_helper.c
57
@@ -XXX,XX +XXX,XX @@
76
@@ -XXX,XX +XXX,XX @@ static bool aa32_generate_debug_exceptions(CPUARMState *env)
58
77
*/
59
static void bcm2836_init(Object *obj)
78
bool arm_generate_debug_exceptions(CPUARMState *env)
60
{
79
{
61
- BCM2836State *s = BCM2836(obj);
80
- if (env->cp15.oslsr_el1 & 1) {
62
+ BCM283XState *s = BCM283X(obj);
81
+ if ((env->cp15.oslsr_el1 & 1) || (env->cp15.osdlr_el1 & 1)) {
63
82
return false;
64
object_initialize(&s->control, sizeof(s->control), TYPE_BCM2836_CONTROL);
83
}
65
object_property_add_child(obj, "control", OBJECT(&s->control), NULL);
84
if (is_a64(env)) {
66
@@ -XXX,XX +XXX,XX @@ static void bcm2836_init(Object *obj)
85
@@ -XXX,XX +XXX,XX @@ static void oslar_write(CPUARMState *env, const ARMCPRegInfo *ri,
67
86
env->cp15.oslsr_el1 = deposit32(env->cp15.oslsr_el1, 1, 1, oslock);
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
}
87
}
95
88
96
static Property bcm2836_props[] = {
89
+static void osdlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
97
- DEFINE_PROP_STRING("cpu-type", BCM2836State, cpu_type),
90
+ uint64_t value)
98
- DEFINE_PROP_UINT32("enabled-cpus", BCM2836State, enabled_cpus, BCM2836_NCPUS),
91
+{
99
+ DEFINE_PROP_STRING("cpu-type", BCM283XState, cpu_type),
92
+ ARMCPU *cpu = env_archcpu(env);
100
+ DEFINE_PROP_UINT32("enabled-cpus", BCM283XState, enabled_cpus,
93
+ /*
101
+ BCM283X_NCPUS),
94
+ * Only defined bit is bit 0 (DLK); if Feat_DoubleLock is not
102
DEFINE_PROP_END_OF_LIST()
95
+ * implemented this is RAZ/WI.
103
};
96
+ */
104
97
+ if(arm_feature(env, ARM_FEATURE_AARCH64)
105
@@ -XXX,XX +XXX,XX @@ static void bcm2836_class_init(ObjectClass *oc, void *data)
98
+ ? cpu_isar_feature(aa64_doublelock, cpu)
106
}
99
+ : cpu_isar_feature(aa32_doublelock, cpu)) {
107
100
+ env->cp15.osdlr_el1 = value & 1;
108
static const TypeInfo bcm2836_type_info = {
101
+ }
109
- .name = TYPE_BCM2836,
102
+}
110
+ .name = TYPE_BCM283X,
103
+
111
.parent = TYPE_DEVICE,
104
static const ARMCPRegInfo debug_cp_reginfo[] = {
112
- .instance_size = sizeof(BCM2836State),
105
/*
113
+ .instance_size = sizeof(BCM283XState),
106
* DBGDRAR, DBGDSAR: always RAZ since we don't implement memory mapped
114
.instance_init = bcm2836_init,
107
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
115
.class_init = bcm2836_class_init,
108
{ .name = "OSDLR_EL1", .state = ARM_CP_STATE_BOTH,
116
};
109
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 4,
117
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
110
.access = PL1_RW, .accessfn = access_tdosa,
118
index XXXXXXX..XXXXXXX 100644
111
- .type = ARM_CP_NOP },
119
--- a/hw/arm/raspi.c
112
+ .writefn = osdlr_write,
120
+++ b/hw/arm/raspi.c
113
+ .fieldoffset = offsetof(CPUARMState, cp15.osdlr_el1) },
121
@@ -XXX,XX +XXX,XX @@
114
/*
122
static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44};
115
* Dummy DBGVCR: Linux wants to clear this on startup, but we don't
123
116
* implement vector catch debug events yet.
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
--
117
--
166
2.16.2
118
2.25.1
167
168
diff view generated by jsdifflib
1
The TypeInfo and state struct for bcm2386 disagree about what the
1
In commit 39a1fd25287f5d we fixed a bug in the handling of LPAE block
2
parent class is -- the TypeInfo says it's TYPE_SYS_BUS_DEVICE,
2
descriptors where we weren't correctly zeroing out some RES0 bits.
3
but the BCM2386State struct only defines the parent_obj field
3
However this fix has a bug because the calculation of the mask is
4
as DeviceState. This would have caused problems if anything
4
done at the wrong width: in
5
actually tried to treat the object as a TYPE_SYS_BUS_DEVICE.
5
descaddr &= ~(page_size - 1);
6
Fix the TypeInfo to use TYPE_DEVICE as the parent, since we don't
6
page_size is a target_ulong, so in the 'qemu-system-arm' binary it is
7
need any of the additional functionality TYPE_SYS_BUS_DEVICE
7
only 32 bits, and the effect is that we always zero out the top 32
8
provides.
8
bits of the calculated address. Fix the calculation by forcing the
9
mask to be calculated with the same type as descaddr.
9
10
11
This only affects 32-bit CPUs which support LPAE (e.g. cortex-a15)
12
when used on board models which put RAM or devices above the 4GB
13
mark and when the 'qemu-system-arm' executable is being used.
14
It was also masked in 7.0 by the main bug reported in
15
https://gitlab.com/qemu-project/qemu/-/issues/1078 where the
16
virt board incorrectly does not enable 'highmem' for 32-bit CPUs.
17
18
The workaround is to use 'qemu-system-aarch64' with the same
19
command line.
20
21
Reported-by: He Zhe <zhe.he@windriver.com>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
24
Message-id: 20220627134620.3190252-1-peter.maydell@linaro.org
13
Message-id: 20180313153458.26822-5-peter.maydell@linaro.org
25
Fixes: 39a1fd25287f5de ("target/arm: Fix handling of LPAE block descriptors")
26
Cc: qemu-stable@nongnu.org
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
28
---
15
hw/arm/bcm2836.c | 2 +-
29
target/arm/ptw.c | 2 +-
16
1 file changed, 1 insertion(+), 1 deletion(-)
30
1 file changed, 1 insertion(+), 1 deletion(-)
17
31
18
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
32
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
19
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/bcm2836.c
34
--- a/target/arm/ptw.c
21
+++ b/hw/arm/bcm2836.c
35
+++ b/target/arm/ptw.c
22
@@ -XXX,XX +XXX,XX @@ static void bcm2836_class_init(ObjectClass *oc, void *data)
36
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
23
37
* clear the lower bits here before ORing in the low vaddr bits.
24
static const TypeInfo bcm2836_type_info = {
38
*/
25
.name = TYPE_BCM2836,
39
page_size = (1ULL << ((stride * (4 - level)) + 3));
26
- .parent = TYPE_SYS_BUS_DEVICE,
40
- descaddr &= ~(page_size - 1);
27
+ .parent = TYPE_DEVICE,
41
+ descaddr &= ~(hwaddr)(page_size - 1);
28
.instance_size = sizeof(BCM2836State),
42
descaddr |= (address & (page_size - 1));
29
.instance_init = bcm2836_init,
43
/* Extract attributes from the descriptor */
30
.class_init = bcm2836_class_init,
44
attrs = extract64(descriptor, 2, 10)
31
--
45
--
32
2.16.2
46
2.25.1
33
34
diff view generated by jsdifflib