1
The following changes since commit eae587e8e3694b1aceab23239493fb4c7e1a80f5:
1
Two small bugfixes, plus most of RTH's refactoring of cpregs
2
handling.
2
3
3
Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-09-13' into staging (2021-09-13 11:00:30 +0100)
4
-- PMM
5
6
The following changes since commit 1fba9dc71a170b3a05b9d3272dd8ecfe7f26e215:
7
8
Merge tag 'pull-request-2022-05-04' of https://gitlab.com/thuth/qemu into staging (2022-05-04 08:07:02 -0700)
4
9
5
are available in the Git repository at:
10
are available in the Git repository at:
6
11
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210913
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220505
8
13
9
for you to fetch changes up to 9a2b2ecf4d25a3943918c95d2db4508b304161b5:
14
for you to fetch changes up to 99a50d1a67c602126fc2b3a4812d3000eba9bf34:
10
15
11
hw/arm/mps2.c: Mark internal-only I2C buses as 'full' (2021-09-13 17:09:28 +0100)
16
target/arm: read access to performance counters from EL0 (2022-05-05 09:36:22 +0100)
12
17
13
----------------------------------------------------------------
18
----------------------------------------------------------------
14
target-arm queue:
19
target-arm queue:
15
* mark MPS2/MPS3 board-internal i2c buses as 'full' so that command
20
* Enable read access to performance counters from EL0
16
line user-created devices are not plugged into them
21
* Enable SCTLR_EL1.BT0 for aarch64-linux-user
17
* Take an exception if PSTATE.IL is set
22
* Refactoring of cpreg handling
18
* Support an emulated ITS in the virt board
19
* Add support for kudo-bmc board
20
* Probe for KVM_CAP_ARM_VM_IPA_SIZE when creating scratch VM
21
* cadence_uart: Fix clock handling issues that prevented
22
u-boot from running
23
23
24
----------------------------------------------------------------
24
----------------------------------------------------------------
25
Bin Meng (6):
25
Alex Zuepke (1):
26
hw/misc: zynq_slcr: Correctly compute output clocks in the reset exit phase
26
target/arm: read access to performance counters from EL0
27
hw/char: cadence_uart: Disable transmit when input clock is disabled
28
hw/char: cadence_uart: Move clock/reset check to uart_can_receive()
29
hw/char: cadence_uart: Convert to memop_with_attrs() ops
30
hw/char: cadence_uart: Ignore access when unclocked or in reset for uart_{read, write}()
31
hw/char: cadence_uart: Log a guest error when device is unclocked or in reset
32
27
33
Chris Rauer (1):
28
Richard Henderson (22):
34
hw/arm: Add support for kudo-bmc board.
29
target/arm: Enable SCTLR_EL1.BT0 for aarch64-linux-user
30
target/arm: Split out cpregs.h
31
target/arm: Reorg CPAccessResult and access_check_cp_reg
32
target/arm: Replace sentinels with ARRAY_SIZE in cpregs.h
33
target/arm: Make some more cpreg data static const
34
target/arm: Reorg ARMCPRegInfo type field bits
35
target/arm: Avoid bare abort() or assert(0)
36
target/arm: Change cpreg access permissions to enum
37
target/arm: Name CPState type
38
target/arm: Name CPSecureState type
39
target/arm: Drop always-true test in define_arm_vh_e2h_redirects_aliases
40
target/arm: Store cpregs key in the hash table directly
41
target/arm: Merge allocation of the cpreg and its name
42
target/arm: Hoist computation of key in add_cpreg_to_hashtable
43
target/arm: Consolidate cpreg updates in add_cpreg_to_hashtable
44
target/arm: Use bool for is64 and ns in add_cpreg_to_hashtable
45
target/arm: Hoist isbanked computation in add_cpreg_to_hashtable
46
target/arm: Perform override check early in add_cpreg_to_hashtable
47
target/arm: Reformat comments in add_cpreg_to_hashtable
48
target/arm: Remove HOST_BIG_ENDIAN ifdef in add_cpreg_to_hashtable
49
target/arm: Add isar predicates for FEAT_Debugv8p2
50
target/arm: Add isar_feature_{aa64,any}_ras
35
51
36
Marc Zyngier (1):
52
target/arm/cpregs.h | 453 ++++++++++++++++++++++++++++++++++++++
37
hw/arm/virt: KVM: Probe for KVM_CAP_ARM_VM_IPA_SIZE when creating scratch VM
53
target/arm/cpu.h | 393 +++------------------------------
38
54
hw/arm/pxa2xx.c | 2 +-
39
Peter Maydell (5):
55
hw/arm/pxa2xx_pic.c | 2 +-
40
target/arm: Take an exception if PSTATE.IL is set
56
hw/intc/arm_gicv3_cpuif.c | 6 +-
41
qdev: Support marking individual buses as 'full'
57
hw/intc/arm_gicv3_kvm.c | 3 +-
42
hw/arm/mps2-tz.c: Add extra data parameter to MakeDevFn
58
target/arm/cpu.c | 25 +--
43
hw/arm/mps2-tz.c: Mark internal-only I2C buses as 'full'
59
target/arm/cpu64.c | 2 +-
44
hw/arm/mps2.c: Mark internal-only I2C buses as 'full'
60
target/arm/cpu_tcg.c | 5 +-
45
61
target/arm/gdbstub.c | 5 +-
46
Richard Henderson (1):
62
target/arm/helper.c | 358 +++++++++++++-----------------
47
target/arm: Merge disas_a64_insn into aarch64_tr_translate_insn
63
target/arm/hvf/hvf.c | 2 +-
48
64
target/arm/kvm-stub.c | 4 +-
49
Shashi Mallela (9):
65
target/arm/kvm.c | 4 +-
50
hw/intc: GICv3 ITS initial framework
66
target/arm/machine.c | 4 +-
51
hw/intc: GICv3 ITS register definitions added
67
target/arm/op_helper.c | 57 ++---
52
hw/intc: GICv3 ITS command queue framework
68
target/arm/translate-a64.c | 14 +-
53
hw/intc: GICv3 ITS Command processing
69
target/arm/translate-neon.c | 2 +-
54
hw/intc: GICv3 ITS Feature enablement
70
target/arm/translate.c | 13 +-
55
hw/intc: GICv3 redistributor ITS processing
71
tests/tcg/aarch64/bti-3.c | 42 ++++
56
tests/data/acpi/virt: Add IORT files for ITS
72
tests/tcg/aarch64/Makefile.target | 6 +-
57
hw/arm/virt: add ITS support in virt GIC
73
21 files changed, 738 insertions(+), 664 deletions(-)
58
tests/data/acpi/virt: Update IORT files for ITS
74
create mode 100644 target/arm/cpregs.h
59
75
create mode 100644 tests/tcg/aarch64/bti-3.c
60
docs/system/arm/nuvoton.rst | 1 +
61
hw/intc/gicv3_internal.h | 188 ++++-
62
include/hw/arm/virt.h | 2 +
63
include/hw/intc/arm_gicv3_common.h | 13 +
64
include/hw/intc/arm_gicv3_its_common.h | 32 +-
65
include/hw/qdev-core.h | 24 +
66
target/arm/cpu.h | 1 +
67
target/arm/kvm_arm.h | 4 +-
68
target/arm/syndrome.h | 5 +
69
target/arm/translate.h | 2 +
70
hw/arm/mps2-tz.c | 92 ++-
71
hw/arm/mps2.c | 12 +-
72
hw/arm/npcm7xx_boards.c | 34 +
73
hw/arm/virt.c | 29 +-
74
hw/char/cadence_uart.c | 61 +-
75
hw/intc/arm_gicv3.c | 14 +
76
hw/intc/arm_gicv3_common.c | 13 +
77
hw/intc/arm_gicv3_cpuif.c | 7 +-
78
hw/intc/arm_gicv3_dist.c | 5 +-
79
hw/intc/arm_gicv3_its.c | 1322 ++++++++++++++++++++++++++++++++
80
hw/intc/arm_gicv3_its_common.c | 7 +-
81
hw/intc/arm_gicv3_its_kvm.c | 2 +-
82
hw/intc/arm_gicv3_redist.c | 153 +++-
83
hw/misc/zynq_slcr.c | 31 +-
84
softmmu/qdev-monitor.c | 7 +-
85
target/arm/helper-a64.c | 1 +
86
target/arm/helper.c | 8 +
87
target/arm/kvm.c | 7 +-
88
target/arm/translate-a64.c | 255 +++---
89
target/arm/translate.c | 21 +
90
hw/intc/meson.build | 1 +
91
tests/data/acpi/virt/IORT | Bin 0 -> 124 bytes
92
tests/data/acpi/virt/IORT.memhp | Bin 0 -> 124 bytes
93
tests/data/acpi/virt/IORT.numamem | Bin 0 -> 124 bytes
94
tests/data/acpi/virt/IORT.pxb | Bin 0 -> 124 bytes
95
35 files changed, 2144 insertions(+), 210 deletions(-)
96
create mode 100644 hw/intc/arm_gicv3_its.c
97
create mode 100644 tests/data/acpi/virt/IORT
98
create mode 100644 tests/data/acpi/virt/IORT.memhp
99
create mode 100644 tests/data/acpi/virt/IORT.numamem
100
create mode 100644 tests/data/acpi/virt/IORT.pxb
101
diff view generated by jsdifflib
1
From: Shashi Mallela <shashi.mallela@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Added register definitions relevant to ITS,implemented overall
3
This controls whether the PACI{A,B}SP instructions trap with BTYPE=3
4
ITS device framework with stubs for ITS control and translater
4
(indirect branch from register other than x16/x17). The linux kernel
5
regions read/write,extended ITS common to handle mmio init between
5
sets this in bti_enable().
6
existing kvm device and newer qemu device.
7
6
8
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
7
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/998
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
10
Message-id: 20220427042312.294300-1-richard.henderson@linaro.org
11
Tested-by: Neil Armstrong <narmstrong@baylibre.com>
11
[PMM: remove stray change to makefile comment]
12
Message-id: 20210910143951.92242-2-shashi.mallela@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
13
---
15
hw/intc/gicv3_internal.h | 96 +++++++++-
14
target/arm/cpu.c | 2 ++
16
include/hw/intc/arm_gicv3_its_common.h | 9 +-
15
tests/tcg/aarch64/bti-3.c | 42 +++++++++++++++++++++++++++++++
17
hw/intc/arm_gicv3_its.c | 241 +++++++++++++++++++++++++
16
tests/tcg/aarch64/Makefile.target | 6 ++---
18
hw/intc/arm_gicv3_its_common.c | 7 +-
17
3 files changed, 47 insertions(+), 3 deletions(-)
19
hw/intc/arm_gicv3_its_kvm.c | 2 +-
18
create mode 100644 tests/tcg/aarch64/bti-3.c
20
hw/intc/meson.build | 1 +
21
6 files changed, 342 insertions(+), 14 deletions(-)
22
create mode 100644 hw/intc/arm_gicv3_its.c
23
19
24
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
20
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
25
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/intc/gicv3_internal.h
22
--- a/target/arm/cpu.c
27
+++ b/hw/intc/gicv3_internal.h
23
+++ b/target/arm/cpu.c
28
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
29
#ifndef QEMU_ARM_GICV3_INTERNAL_H
25
/* Enable all PAC keys. */
30
#define QEMU_ARM_GICV3_INTERNAL_H
26
env->cp15.sctlr_el[1] |= (SCTLR_EnIA | SCTLR_EnIB |
31
27
SCTLR_EnDA | SCTLR_EnDB);
32
+#include "hw/registerfields.h"
28
+ /* Trap on btype=3 for PACIxSP. */
33
#include "hw/intc/arm_gicv3_common.h"
29
+ env->cp15.sctlr_el[1] |= SCTLR_BT0;
34
30
/* and to the FP/Neon instructions */
35
/* Distributor registers, as offsets from the distributor base address */
31
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3);
36
@@ -XXX,XX +XXX,XX @@
32
/* and to the SVE instructions */
37
#define GICD_CTLR_E1NWF (1U << 7)
33
diff --git a/tests/tcg/aarch64/bti-3.c b/tests/tcg/aarch64/bti-3.c
38
#define GICD_CTLR_RWP (1U << 31)
39
40
+/* 16 bits EventId */
41
+#define GICD_TYPER_IDBITS 0xf
42
+
43
/*
44
* Redistributor frame offsets from RD_base
45
*/
46
@@ -XXX,XX +XXX,XX @@
47
#define GICR_WAKER_ProcessorSleep (1U << 1)
48
#define GICR_WAKER_ChildrenAsleep (1U << 2)
49
50
-#define GICR_PROPBASER_OUTER_CACHEABILITY_MASK (7ULL << 56)
51
-#define GICR_PROPBASER_ADDR_MASK (0xfffffffffULL << 12)
52
-#define GICR_PROPBASER_SHAREABILITY_MASK (3U << 10)
53
-#define GICR_PROPBASER_CACHEABILITY_MASK (7U << 7)
54
-#define GICR_PROPBASER_IDBITS_MASK (0x1f)
55
+FIELD(GICR_PROPBASER, IDBITS, 0, 5)
56
+FIELD(GICR_PROPBASER, INNERCACHE, 7, 3)
57
+FIELD(GICR_PROPBASER, SHAREABILITY, 10, 2)
58
+FIELD(GICR_PROPBASER, PHYADDR, 12, 40)
59
+FIELD(GICR_PROPBASER, OUTERCACHE, 56, 3)
60
61
-#define GICR_PENDBASER_PTZ (1ULL << 62)
62
-#define GICR_PENDBASER_OUTER_CACHEABILITY_MASK (7ULL << 56)
63
-#define GICR_PENDBASER_ADDR_MASK (0xffffffffULL << 16)
64
-#define GICR_PENDBASER_SHAREABILITY_MASK (3U << 10)
65
-#define GICR_PENDBASER_CACHEABILITY_MASK (7U << 7)
66
+FIELD(GICR_PENDBASER, INNERCACHE, 7, 3)
67
+FIELD(GICR_PENDBASER, SHAREABILITY, 10, 2)
68
+FIELD(GICR_PENDBASER, PHYADDR, 16, 36)
69
+FIELD(GICR_PENDBASER, OUTERCACHE, 56, 3)
70
+FIELD(GICR_PENDBASER, PTZ, 62, 1)
71
72
#define ICC_CTLR_EL1_CBPR (1U << 0)
73
#define ICC_CTLR_EL1_EOIMODE (1U << 1)
74
@@ -XXX,XX +XXX,XX @@
75
#define ICH_VTR_EL2_PREBITS_SHIFT 26
76
#define ICH_VTR_EL2_PRIBITS_SHIFT 29
77
78
+/* ITS Registers */
79
+
80
+FIELD(GITS_BASER, SIZE, 0, 8)
81
+FIELD(GITS_BASER, PAGESIZE, 8, 2)
82
+FIELD(GITS_BASER, SHAREABILITY, 10, 2)
83
+FIELD(GITS_BASER, PHYADDR, 12, 36)
84
+FIELD(GITS_BASER, PHYADDRL_64K, 16, 32)
85
+FIELD(GITS_BASER, PHYADDRH_64K, 12, 4)
86
+FIELD(GITS_BASER, ENTRYSIZE, 48, 5)
87
+FIELD(GITS_BASER, OUTERCACHE, 53, 3)
88
+FIELD(GITS_BASER, TYPE, 56, 3)
89
+FIELD(GITS_BASER, INNERCACHE, 59, 3)
90
+FIELD(GITS_BASER, INDIRECT, 62, 1)
91
+FIELD(GITS_BASER, VALID, 63, 1)
92
+
93
+FIELD(GITS_CTLR, QUIESCENT, 31, 1)
94
+
95
+FIELD(GITS_TYPER, PHYSICAL, 0, 1)
96
+FIELD(GITS_TYPER, ITT_ENTRY_SIZE, 4, 4)
97
+FIELD(GITS_TYPER, IDBITS, 8, 5)
98
+FIELD(GITS_TYPER, DEVBITS, 13, 5)
99
+FIELD(GITS_TYPER, SEIS, 18, 1)
100
+FIELD(GITS_TYPER, PTA, 19, 1)
101
+FIELD(GITS_TYPER, CIDBITS, 32, 4)
102
+FIELD(GITS_TYPER, CIL, 36, 1)
103
+
104
+#define GITS_BASER_PAGESIZE_4K 0
105
+#define GITS_BASER_PAGESIZE_16K 1
106
+#define GITS_BASER_PAGESIZE_64K 2
107
+
108
+#define GITS_BASER_TYPE_DEVICE 1ULL
109
+#define GITS_BASER_TYPE_COLLECTION 4ULL
110
+
111
+/**
112
+ * Default features advertised by this version of ITS
113
+ */
114
+/* Physical LPIs supported */
115
+#define GITS_TYPE_PHYSICAL (1U << 0)
116
+
117
+/*
118
+ * 12 bytes Interrupt translation Table Entry size
119
+ * as per Table 5.3 in GICv3 spec
120
+ * ITE Lower 8 Bytes
121
+ * Bits: | 49 ... 26 | 25 ... 2 | 1 | 0 |
122
+ * Values: | 1023 | IntNum | IntType | Valid |
123
+ * ITE Higher 4 Bytes
124
+ * Bits: | 31 ... 16 | 15 ...0 |
125
+ * Values: | vPEID | ICID |
126
+ */
127
+#define ITS_ITT_ENTRY_SIZE 0xC
128
+
129
+/* 16 bits EventId */
130
+#define ITS_IDBITS GICD_TYPER_IDBITS
131
+
132
+/* 16 bits DeviceId */
133
+#define ITS_DEVBITS 0xF
134
+
135
+/* 16 bits CollectionId */
136
+#define ITS_CIDBITS 0xF
137
+
138
+/*
139
+ * 8 bytes Device Table Entry size
140
+ * Valid = 1 bit,ITTAddr = 44 bits,Size = 5 bits
141
+ */
142
+#define GITS_DTE_SIZE (0x8ULL)
143
+
144
+/*
145
+ * 8 bytes Collection Table Entry size
146
+ * Valid = 1 bit,RDBase = 36 bits(considering max RDBASE)
147
+ */
148
+#define GITS_CTE_SIZE (0x8ULL)
149
+
150
/* Special interrupt IDs */
151
#define INTID_SECURE 1020
152
#define INTID_NONSECURE 1021
153
diff --git a/include/hw/intc/arm_gicv3_its_common.h b/include/hw/intc/arm_gicv3_its_common.h
154
index XXXXXXX..XXXXXXX 100644
155
--- a/include/hw/intc/arm_gicv3_its_common.h
156
+++ b/include/hw/intc/arm_gicv3_its_common.h
157
@@ -XXX,XX +XXX,XX @@
158
#include "hw/intc/arm_gicv3_common.h"
159
#include "qom/object.h"
160
161
+#define TYPE_ARM_GICV3_ITS "arm-gicv3-its"
162
+
163
#define ITS_CONTROL_SIZE 0x10000
164
#define ITS_TRANS_SIZE 0x10000
165
#define ITS_SIZE (ITS_CONTROL_SIZE + ITS_TRANS_SIZE)
166
167
#define GITS_CTLR 0x0
168
#define GITS_IIDR 0x4
169
+#define GITS_TYPER 0x8
170
#define GITS_CBASER 0x80
171
#define GITS_CWRITER 0x88
172
#define GITS_CREADR 0x90
173
#define GITS_BASER 0x100
174
175
+#define GITS_TRANSLATER 0x0040
176
+
177
struct GICv3ITSState {
178
SysBusDevice parent_obj;
179
180
@@ -XXX,XX +XXX,XX @@ struct GICv3ITSState {
181
/* Registers */
182
uint32_t ctlr;
183
uint32_t iidr;
184
+ uint64_t typer;
185
uint64_t cbaser;
186
uint64_t cwriter;
187
uint64_t creadr;
188
@@ -XXX,XX +XXX,XX @@ struct GICv3ITSState {
189
190
typedef struct GICv3ITSState GICv3ITSState;
191
192
-void gicv3_its_init_mmio(GICv3ITSState *s, const MemoryRegionOps *ops);
193
+void gicv3_its_init_mmio(GICv3ITSState *s, const MemoryRegionOps *ops,
194
+ const MemoryRegionOps *tops);
195
196
#define TYPE_ARM_GICV3_ITS_COMMON "arm-gicv3-its-common"
197
typedef struct GICv3ITSCommonClass GICv3ITSCommonClass;
198
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
199
new file mode 100644
34
new file mode 100644
200
index XXXXXXX..XXXXXXX
35
index XXXXXXX..XXXXXXX
201
--- /dev/null
36
--- /dev/null
202
+++ b/hw/intc/arm_gicv3_its.c
37
+++ b/tests/tcg/aarch64/bti-3.c
203
@@ -XXX,XX +XXX,XX @@
38
@@ -XXX,XX +XXX,XX @@
204
+/*
39
+/*
205
+ * ITS emulation for a GICv3-based system
40
+ * BTI vs PACIASP
206
+ *
207
+ * Copyright Linaro.org 2021
208
+ *
209
+ * Authors:
210
+ * Shashi Mallela <shashi.mallela@linaro.org>
211
+ *
212
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at your
213
+ * option) any later version. See the COPYING file in the top-level directory.
214
+ *
215
+ */
41
+ */
216
+
42
+
217
+#include "qemu/osdep.h"
43
+#include "bti-crt.inc.c"
218
+#include "qemu/log.h"
219
+#include "hw/qdev-properties.h"
220
+#include "hw/intc/arm_gicv3_its_common.h"
221
+#include "gicv3_internal.h"
222
+#include "qom/object.h"
223
+#include "qapi/error.h"
224
+
44
+
225
+typedef struct GICv3ITSClass GICv3ITSClass;
45
+static void skip2_sigill(int sig, siginfo_t *info, ucontext_t *uc)
226
+/* This is reusing the GICv3ITSState typedef from ARM_GICV3_ITS_COMMON */
227
+DECLARE_OBJ_CHECKERS(GICv3ITSState, GICv3ITSClass,
228
+ ARM_GICV3_ITS, TYPE_ARM_GICV3_ITS)
229
+
230
+struct GICv3ITSClass {
231
+ GICv3ITSCommonClass parent_class;
232
+ void (*parent_reset)(DeviceState *dev);
233
+};
234
+
235
+static MemTxResult gicv3_its_translation_write(void *opaque, hwaddr offset,
236
+ uint64_t data, unsigned size,
237
+ MemTxAttrs attrs)
238
+{
46
+{
239
+ return MEMTX_OK;
47
+ uc->uc_mcontext.pc += 8;
48
+ uc->uc_mcontext.pstate = 1;
240
+}
49
+}
241
+
50
+
242
+static bool its_writel(GICv3ITSState *s, hwaddr offset,
51
+#define BTYPE_1() \
243
+ uint64_t value, MemTxAttrs attrs)
52
+ asm("mov %0,#1; adr x16, 1f; br x16; 1: hint #25; mov %0,#0" \
53
+ : "=r"(skipped) : : "x16", "x30")
54
+
55
+#define BTYPE_2() \
56
+ asm("mov %0,#1; adr x16, 1f; blr x16; 1: hint #25; mov %0,#0" \
57
+ : "=r"(skipped) : : "x16", "x30")
58
+
59
+#define BTYPE_3() \
60
+ asm("mov %0,#1; adr x15, 1f; br x15; 1: hint #25; mov %0,#0" \
61
+ : "=r"(skipped) : : "x15", "x30")
62
+
63
+#define TEST(WHICH, EXPECT) \
64
+ do { WHICH(); fail += skipped ^ EXPECT; } while (0)
65
+
66
+int main()
244
+{
67
+{
245
+ bool result = true;
68
+ int fail = 0;
69
+ int skipped;
246
+
70
+
247
+ return result;
71
+ /* Signal-like with SA_SIGINFO. */
72
+ signal_info(SIGILL, skip2_sigill);
73
+
74
+ /* With SCTLR_EL1.BT0 set, PACIASP is not compatible with type=3. */
75
+ TEST(BTYPE_1, 0);
76
+ TEST(BTYPE_2, 0);
77
+ TEST(BTYPE_3, 1);
78
+
79
+ return fail;
248
+}
80
+}
249
+
81
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
250
+static bool its_readl(GICv3ITSState *s, hwaddr offset,
251
+ uint64_t *data, MemTxAttrs attrs)
252
+{
253
+ bool result = true;
254
+
255
+ return result;
256
+}
257
+
258
+static bool its_writell(GICv3ITSState *s, hwaddr offset,
259
+ uint64_t value, MemTxAttrs attrs)
260
+{
261
+ bool result = true;
262
+
263
+ return result;
264
+}
265
+
266
+static bool its_readll(GICv3ITSState *s, hwaddr offset,
267
+ uint64_t *data, MemTxAttrs attrs)
268
+{
269
+ bool result = true;
270
+
271
+ return result;
272
+}
273
+
274
+static MemTxResult gicv3_its_read(void *opaque, hwaddr offset, uint64_t *data,
275
+ unsigned size, MemTxAttrs attrs)
276
+{
277
+ GICv3ITSState *s = (GICv3ITSState *)opaque;
278
+ bool result;
279
+
280
+ switch (size) {
281
+ case 4:
282
+ result = its_readl(s, offset, data, attrs);
283
+ break;
284
+ case 8:
285
+ result = its_readll(s, offset, data, attrs);
286
+ break;
287
+ default:
288
+ result = false;
289
+ break;
290
+ }
291
+
292
+ if (!result) {
293
+ qemu_log_mask(LOG_GUEST_ERROR,
294
+ "%s: invalid guest read at offset " TARGET_FMT_plx
295
+ "size %u\n", __func__, offset, size);
296
+ /*
297
+ * The spec requires that reserved registers are RAZ/WI;
298
+ * so use false returns from leaf functions as a way to
299
+ * trigger the guest-error logging but don't return it to
300
+ * the caller, or we'll cause a spurious guest data abort.
301
+ */
302
+ *data = 0;
303
+ }
304
+ return MEMTX_OK;
305
+}
306
+
307
+static MemTxResult gicv3_its_write(void *opaque, hwaddr offset, uint64_t data,
308
+ unsigned size, MemTxAttrs attrs)
309
+{
310
+ GICv3ITSState *s = (GICv3ITSState *)opaque;
311
+ bool result;
312
+
313
+ switch (size) {
314
+ case 4:
315
+ result = its_writel(s, offset, data, attrs);
316
+ break;
317
+ case 8:
318
+ result = its_writell(s, offset, data, attrs);
319
+ break;
320
+ default:
321
+ result = false;
322
+ break;
323
+ }
324
+
325
+ if (!result) {
326
+ qemu_log_mask(LOG_GUEST_ERROR,
327
+ "%s: invalid guest write at offset " TARGET_FMT_plx
328
+ "size %u\n", __func__, offset, size);
329
+ /*
330
+ * The spec requires that reserved registers are RAZ/WI;
331
+ * so use false returns from leaf functions as a way to
332
+ * trigger the guest-error logging but don't return it to
333
+ * the caller, or we'll cause a spurious guest data abort.
334
+ */
335
+ }
336
+ return MEMTX_OK;
337
+}
338
+
339
+static const MemoryRegionOps gicv3_its_control_ops = {
340
+ .read_with_attrs = gicv3_its_read,
341
+ .write_with_attrs = gicv3_its_write,
342
+ .valid.min_access_size = 4,
343
+ .valid.max_access_size = 8,
344
+ .impl.min_access_size = 4,
345
+ .impl.max_access_size = 8,
346
+ .endianness = DEVICE_NATIVE_ENDIAN,
347
+};
348
+
349
+static const MemoryRegionOps gicv3_its_translation_ops = {
350
+ .write_with_attrs = gicv3_its_translation_write,
351
+ .valid.min_access_size = 2,
352
+ .valid.max_access_size = 4,
353
+ .impl.min_access_size = 2,
354
+ .impl.max_access_size = 4,
355
+ .endianness = DEVICE_NATIVE_ENDIAN,
356
+};
357
+
358
+static void gicv3_arm_its_realize(DeviceState *dev, Error **errp)
359
+{
360
+ GICv3ITSState *s = ARM_GICV3_ITS_COMMON(dev);
361
+ int i;
362
+
363
+ for (i = 0; i < s->gicv3->num_cpu; i++) {
364
+ if (!(s->gicv3->cpu[i].gicr_typer & GICR_TYPER_PLPIS)) {
365
+ error_setg(errp, "Physical LPI not supported by CPU %d", i);
366
+ return;
367
+ }
368
+ }
369
+
370
+ gicv3_its_init_mmio(s, &gicv3_its_control_ops, &gicv3_its_translation_ops);
371
+
372
+ /* set the ITS default features supported */
373
+ s->typer = FIELD_DP64(s->typer, GITS_TYPER, PHYSICAL,
374
+ GITS_TYPE_PHYSICAL);
375
+ s->typer = FIELD_DP64(s->typer, GITS_TYPER, ITT_ENTRY_SIZE,
376
+ ITS_ITT_ENTRY_SIZE - 1);
377
+ s->typer = FIELD_DP64(s->typer, GITS_TYPER, IDBITS, ITS_IDBITS);
378
+ s->typer = FIELD_DP64(s->typer, GITS_TYPER, DEVBITS, ITS_DEVBITS);
379
+ s->typer = FIELD_DP64(s->typer, GITS_TYPER, CIL, 1);
380
+ s->typer = FIELD_DP64(s->typer, GITS_TYPER, CIDBITS, ITS_CIDBITS);
381
+}
382
+
383
+static void gicv3_its_reset(DeviceState *dev)
384
+{
385
+ GICv3ITSState *s = ARM_GICV3_ITS_COMMON(dev);
386
+ GICv3ITSClass *c = ARM_GICV3_ITS_GET_CLASS(s);
387
+
388
+ c->parent_reset(dev);
389
+
390
+ /* Quiescent bit reset to 1 */
391
+ s->ctlr = FIELD_DP32(s->ctlr, GITS_CTLR, QUIESCENT, 1);
392
+
393
+ /*
394
+ * setting GITS_BASER0.Type = 0b001 (Device)
395
+ * GITS_BASER1.Type = 0b100 (Collection Table)
396
+ * GITS_BASER<n>.Type,where n = 3 to 7 are 0b00 (Unimplemented)
397
+ * GITS_BASER<0,1>.Page_Size = 64KB
398
+ * and default translation table entry size to 16 bytes
399
+ */
400
+ s->baser[0] = FIELD_DP64(s->baser[0], GITS_BASER, TYPE,
401
+ GITS_BASER_TYPE_DEVICE);
402
+ s->baser[0] = FIELD_DP64(s->baser[0], GITS_BASER, PAGESIZE,
403
+ GITS_BASER_PAGESIZE_64K);
404
+ s->baser[0] = FIELD_DP64(s->baser[0], GITS_BASER, ENTRYSIZE,
405
+ GITS_DTE_SIZE - 1);
406
+
407
+ s->baser[1] = FIELD_DP64(s->baser[1], GITS_BASER, TYPE,
408
+ GITS_BASER_TYPE_COLLECTION);
409
+ s->baser[1] = FIELD_DP64(s->baser[1], GITS_BASER, PAGESIZE,
410
+ GITS_BASER_PAGESIZE_64K);
411
+ s->baser[1] = FIELD_DP64(s->baser[1], GITS_BASER, ENTRYSIZE,
412
+ GITS_CTE_SIZE - 1);
413
+}
414
+
415
+static Property gicv3_its_props[] = {
416
+ DEFINE_PROP_LINK("parent-gicv3", GICv3ITSState, gicv3, "arm-gicv3",
417
+ GICv3State *),
418
+ DEFINE_PROP_END_OF_LIST(),
419
+};
420
+
421
+static void gicv3_its_class_init(ObjectClass *klass, void *data)
422
+{
423
+ DeviceClass *dc = DEVICE_CLASS(klass);
424
+ GICv3ITSClass *ic = ARM_GICV3_ITS_CLASS(klass);
425
+
426
+ dc->realize = gicv3_arm_its_realize;
427
+ device_class_set_props(dc, gicv3_its_props);
428
+ device_class_set_parent_reset(dc, gicv3_its_reset, &ic->parent_reset);
429
+}
430
+
431
+static const TypeInfo gicv3_its_info = {
432
+ .name = TYPE_ARM_GICV3_ITS,
433
+ .parent = TYPE_ARM_GICV3_ITS_COMMON,
434
+ .instance_size = sizeof(GICv3ITSState),
435
+ .class_init = gicv3_its_class_init,
436
+ .class_size = sizeof(GICv3ITSClass),
437
+};
438
+
439
+static void gicv3_its_register_types(void)
440
+{
441
+ type_register_static(&gicv3_its_info);
442
+}
443
+
444
+type_init(gicv3_its_register_types)
445
diff --git a/hw/intc/arm_gicv3_its_common.c b/hw/intc/arm_gicv3_its_common.c
446
index XXXXXXX..XXXXXXX 100644
82
index XXXXXXX..XXXXXXX 100644
447
--- a/hw/intc/arm_gicv3_its_common.c
83
--- a/tests/tcg/aarch64/Makefile.target
448
+++ b/hw/intc/arm_gicv3_its_common.c
84
+++ b/tests/tcg/aarch64/Makefile.target
449
@@ -XXX,XX +XXX,XX @@ static int gicv3_its_post_load(void *opaque, int version_id)
85
@@ -XXX,XX +XXX,XX @@ endif
450
86
# BTI Tests
451
static const VMStateDescription vmstate_its = {
87
# bti-1 tests the elf notes, so we require special compiler support.
452
.name = "arm_gicv3_its",
88
ifneq ($(CROSS_CC_HAS_ARMV8_BTI),)
453
+ .version_id = 1,
89
-AARCH64_TESTS += bti-1
454
+ .minimum_version_id = 1,
90
-bti-1: CFLAGS += -mbranch-protection=standard
455
.pre_save = gicv3_its_pre_save,
91
-bti-1: LDFLAGS += -nostdlib
456
.post_load = gicv3_its_post_load,
92
+AARCH64_TESTS += bti-1 bti-3
457
.priority = MIG_PRI_GICV3_ITS,
93
+bti-1 bti-3: CFLAGS += -mbranch-protection=standard
458
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps gicv3_its_trans_ops = {
94
+bti-1 bti-3: LDFLAGS += -nostdlib
459
.endianness = DEVICE_NATIVE_ENDIAN,
95
endif
460
};
96
# bti-2 tests PROT_BTI, so no special compiler support required.
461
97
AARCH64_TESTS += bti-2
462
-void gicv3_its_init_mmio(GICv3ITSState *s, const MemoryRegionOps *ops)
463
+void gicv3_its_init_mmio(GICv3ITSState *s, const MemoryRegionOps *ops,
464
+ const MemoryRegionOps *tops)
465
{
466
SysBusDevice *sbd = SYS_BUS_DEVICE(s);
467
468
memory_region_init_io(&s->iomem_its_cntrl, OBJECT(s), ops, s,
469
"control", ITS_CONTROL_SIZE);
470
memory_region_init_io(&s->iomem_its_translation, OBJECT(s),
471
- &gicv3_its_trans_ops, s,
472
+ tops ? tops : &gicv3_its_trans_ops, s,
473
"translation", ITS_TRANS_SIZE);
474
475
/* Our two regions are always adjacent, therefore we now combine them
476
diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
477
index XXXXXXX..XXXXXXX 100644
478
--- a/hw/intc/arm_gicv3_its_kvm.c
479
+++ b/hw/intc/arm_gicv3_its_kvm.c
480
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_realize(DeviceState *dev, Error **errp)
481
kvm_arm_register_device(&s->iomem_its_cntrl, -1, KVM_DEV_ARM_VGIC_GRP_ADDR,
482
KVM_VGIC_ITS_ADDR_TYPE, s->dev_fd, 0);
483
484
- gicv3_its_init_mmio(s, NULL);
485
+ gicv3_its_init_mmio(s, NULL, NULL);
486
487
if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
488
GITS_CTLR)) {
489
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
490
index XXXXXXX..XXXXXXX 100644
491
--- a/hw/intc/meson.build
492
+++ b/hw/intc/meson.build
493
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_ARM_GIC', if_true: files(
494
'arm_gicv3_dist.c',
495
'arm_gicv3_its_common.c',
496
'arm_gicv3_redist.c',
497
+ 'arm_gicv3_its.c',
498
))
499
softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_pic.c'))
500
softmmu_ss.add(when: 'CONFIG_HEATHROW_PIC', if_true: files('heathrow_pic.c'))
501
--
98
--
502
2.20.1
99
2.25.1
503
504
diff view generated by jsdifflib
1
In v8A, the PSTATE.IL bit is set for various kinds of illegal
1
From: Richard Henderson <richard.henderson@linaro.org>
2
exception return or mode-change attempts. We already set PSTATE.IL
3
(or its AArch32 equivalent CPSR.IL) in all those cases, but we
4
weren't implementing the part of the behaviour where attempting to
5
execute an instruction with PSTATE.IL takes an immediate exception
6
with an appropriate syndrome value.
7
2
8
Add a new TB flags bit tracking PSTATE.IL/CPSR.IL, and generate code
3
Move ARMCPRegInfo and all related declarations to a new
9
to take an exception instead of whatever the instruction would have
4
internal header, out of the public cpu.h.
10
been.
11
5
12
PSTATE.IL and CPSR.IL change only on exception entry, attempted
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
exception exit, and various AArch32 mode changes via cpsr_write().
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
These places generally already rebuild the hflags, so the only place
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
we need an extra rebuild_hflags call is in the illegal-return
9
Message-id: 20220501055028.646596-2-richard.henderson@linaro.org
16
codepath of the AArch64 exception_return helper.
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpregs.h | 413 +++++++++++++++++++++++++++++++++++++
13
target/arm/cpu.h | 368 ---------------------------------
14
hw/arm/pxa2xx.c | 1 +
15
hw/arm/pxa2xx_pic.c | 1 +
16
hw/intc/arm_gicv3_cpuif.c | 1 +
17
hw/intc/arm_gicv3_kvm.c | 2 +
18
target/arm/cpu.c | 1 +
19
target/arm/cpu64.c | 1 +
20
target/arm/cpu_tcg.c | 1 +
21
target/arm/gdbstub.c | 3 +-
22
target/arm/helper.c | 1 +
23
target/arm/op_helper.c | 1 +
24
target/arm/translate-a64.c | 4 +-
25
target/arm/translate.c | 3 +-
26
14 files changed, 427 insertions(+), 374 deletions(-)
27
create mode 100644 target/arm/cpregs.h
17
28
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
19
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
30
new file mode 100644
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
31
index XXXXXXX..XXXXXXX
21
Message-id: 20210821195958.41312-2-richard.henderson@linaro.org
32
--- /dev/null
22
Message-Id: <20210817162118.24319-1-peter.maydell@linaro.org>
33
+++ b/target/arm/cpregs.h
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
34
@@ -XXX,XX +XXX,XX @@
24
[rth: Added missing returns; set IL bit in syndrome]
35
+/*
25
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
36
+ * QEMU ARM CP Register access and descriptions
26
---
37
+ *
27
target/arm/cpu.h | 1 +
38
+ * Copyright (c) 2022 Linaro Ltd
28
target/arm/syndrome.h | 5 +++++
39
+ *
29
target/arm/translate.h | 2 ++
40
+ * This program is free software; you can redistribute it and/or
30
target/arm/helper-a64.c | 1 +
41
+ * modify it under the terms of the GNU General Public License
31
target/arm/helper.c | 8 ++++++++
42
+ * as published by the Free Software Foundation; either version 2
32
target/arm/translate-a64.c | 11 +++++++++++
43
+ * of the License, or (at your option) any later version.
33
target/arm/translate.c | 21 +++++++++++++++++++++
44
+ *
34
7 files changed, 49 insertions(+)
45
+ * This program is distributed in the hope that it will be useful,
35
46
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
47
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
48
+ * GNU General Public License for more details.
49
+ *
50
+ * You should have received a copy of the GNU General Public License
51
+ * along with this program; if not, see
52
+ * <http://www.gnu.org/licenses/gpl-2.0.html>
53
+ */
54
+
55
+#ifndef TARGET_ARM_CPREGS_H
56
+#define TARGET_ARM_CPREGS_H
57
+
58
+/*
59
+ * ARMCPRegInfo type field bits. If the SPECIAL bit is set this is a
60
+ * special-behaviour cp reg and bits [11..8] indicate what behaviour
61
+ * it has. Otherwise it is a simple cp reg, where CONST indicates that
62
+ * TCG can assume the value to be constant (ie load at translate time)
63
+ * and 64BIT indicates a 64 bit wide coprocessor register. SUPPRESS_TB_END
64
+ * indicates that the TB should not be ended after a write to this register
65
+ * (the default is that the TB ends after cp writes). OVERRIDE permits
66
+ * a register definition to override a previous definition for the
67
+ * same (cp, is64, crn, crm, opc1, opc2) tuple: either the new or the
68
+ * old must have the OVERRIDE bit set.
69
+ * ALIAS indicates that this register is an alias view of some underlying
70
+ * state which is also visible via another register, and that the other
71
+ * register is handling migration and reset; registers marked ALIAS will not be
72
+ * migrated but may have their state set by syncing of register state from KVM.
73
+ * NO_RAW indicates that this register has no underlying state and does not
74
+ * support raw access for state saving/loading; it will not be used for either
75
+ * migration or KVM state synchronization. (Typically this is for "registers"
76
+ * which are actually used as instructions for cache maintenance and so on.)
77
+ * IO indicates that this register does I/O and therefore its accesses
78
+ * need to be marked with gen_io_start() and also end the TB. In particular,
79
+ * registers which implement clocks or timers require this.
80
+ * RAISES_EXC is for when the read or write hook might raise an exception;
81
+ * the generated code will synchronize the CPU state before calling the hook
82
+ * so that it is safe for the hook to call raise_exception().
83
+ * NEWEL is for writes to registers that might change the exception
84
+ * level - typically on older ARM chips. For those cases we need to
85
+ * re-read the new el when recomputing the translation flags.
86
+ */
87
+#define ARM_CP_SPECIAL 0x0001
88
+#define ARM_CP_CONST 0x0002
89
+#define ARM_CP_64BIT 0x0004
90
+#define ARM_CP_SUPPRESS_TB_END 0x0008
91
+#define ARM_CP_OVERRIDE 0x0010
92
+#define ARM_CP_ALIAS 0x0020
93
+#define ARM_CP_IO 0x0040
94
+#define ARM_CP_NO_RAW 0x0080
95
+#define ARM_CP_NOP (ARM_CP_SPECIAL | 0x0100)
96
+#define ARM_CP_WFI (ARM_CP_SPECIAL | 0x0200)
97
+#define ARM_CP_NZCV (ARM_CP_SPECIAL | 0x0300)
98
+#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | 0x0400)
99
+#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | 0x0500)
100
+#define ARM_CP_DC_GVA (ARM_CP_SPECIAL | 0x0600)
101
+#define ARM_CP_DC_GZVA (ARM_CP_SPECIAL | 0x0700)
102
+#define ARM_LAST_SPECIAL ARM_CP_DC_GZVA
103
+#define ARM_CP_FPU 0x1000
104
+#define ARM_CP_SVE 0x2000
105
+#define ARM_CP_NO_GDB 0x4000
106
+#define ARM_CP_RAISES_EXC 0x8000
107
+#define ARM_CP_NEWEL 0x10000
108
+/* Used only as a terminator for ARMCPRegInfo lists */
109
+#define ARM_CP_SENTINEL 0xfffff
110
+/* Mask of only the flag bits in a type field */
111
+#define ARM_CP_FLAG_MASK 0x1f0ff
112
+
113
+/*
114
+ * Valid values for ARMCPRegInfo state field, indicating which of
115
+ * the AArch32 and AArch64 execution states this register is visible in.
116
+ * If the reginfo doesn't explicitly specify then it is AArch32 only.
117
+ * If the reginfo is declared to be visible in both states then a second
118
+ * reginfo is synthesised for the AArch32 view of the AArch64 register,
119
+ * such that the AArch32 view is the lower 32 bits of the AArch64 one.
120
+ * Note that we rely on the values of these enums as we iterate through
121
+ * the various states in some places.
122
+ */
123
+enum {
124
+ ARM_CP_STATE_AA32 = 0,
125
+ ARM_CP_STATE_AA64 = 1,
126
+ ARM_CP_STATE_BOTH = 2,
127
+};
128
+
129
+/*
130
+ * ARM CP register secure state flags. These flags identify security state
131
+ * attributes for a given CP register entry.
132
+ * The existence of both or neither secure and non-secure flags indicates that
133
+ * the register has both a secure and non-secure hash entry. A single one of
134
+ * these flags causes the register to only be hashed for the specified
135
+ * security state.
136
+ * Although definitions may have any combination of the S/NS bits, each
137
+ * registered entry will only have one to identify whether the entry is secure
138
+ * or non-secure.
139
+ */
140
+enum {
141
+ ARM_CP_SECSTATE_S = (1 << 0), /* bit[0]: Secure state register */
142
+ ARM_CP_SECSTATE_NS = (1 << 1), /* bit[1]: Non-secure state register */
143
+};
144
+
145
+/*
146
+ * Return true if cptype is a valid type field. This is used to try to
147
+ * catch errors where the sentinel has been accidentally left off the end
148
+ * of a list of registers.
149
+ */
150
+static inline bool cptype_valid(int cptype)
151
+{
152
+ return ((cptype & ~ARM_CP_FLAG_MASK) == 0)
153
+ || ((cptype & ARM_CP_SPECIAL) &&
154
+ ((cptype & ~ARM_CP_FLAG_MASK) <= ARM_LAST_SPECIAL));
155
+}
156
+
157
+/*
158
+ * Access rights:
159
+ * We define bits for Read and Write access for what rev C of the v7-AR ARM ARM
160
+ * defines as PL0 (user), PL1 (fiq/irq/svc/abt/und/sys, ie privileged), and
161
+ * PL2 (hyp). The other level which has Read and Write bits is Secure PL1
162
+ * (ie any of the privileged modes in Secure state, or Monitor mode).
163
+ * If a register is accessible in one privilege level it's always accessible
164
+ * in higher privilege levels too. Since "Secure PL1" also follows this rule
165
+ * (ie anything visible in PL2 is visible in S-PL1, some things are only
166
+ * visible in S-PL1) but "Secure PL1" is a bit of a mouthful, we bend the
167
+ * terminology a little and call this PL3.
168
+ * In AArch64 things are somewhat simpler as the PLx bits line up exactly
169
+ * with the ELx exception levels.
170
+ *
171
+ * If access permissions for a register are more complex than can be
172
+ * described with these bits, then use a laxer set of restrictions, and
173
+ * do the more restrictive/complex check inside a helper function.
174
+ */
175
+#define PL3_R 0x80
176
+#define PL3_W 0x40
177
+#define PL2_R (0x20 | PL3_R)
178
+#define PL2_W (0x10 | PL3_W)
179
+#define PL1_R (0x08 | PL2_R)
180
+#define PL1_W (0x04 | PL2_W)
181
+#define PL0_R (0x02 | PL1_R)
182
+#define PL0_W (0x01 | PL1_W)
183
+
184
+/*
185
+ * For user-mode some registers are accessible to EL0 via a kernel
186
+ * trap-and-emulate ABI. In this case we define the read permissions
187
+ * as actually being PL0_R. However some bits of any given register
188
+ * may still be masked.
189
+ */
190
+#ifdef CONFIG_USER_ONLY
191
+#define PL0U_R PL0_R
192
+#else
193
+#define PL0U_R PL1_R
194
+#endif
195
+
196
+#define PL3_RW (PL3_R | PL3_W)
197
+#define PL2_RW (PL2_R | PL2_W)
198
+#define PL1_RW (PL1_R | PL1_W)
199
+#define PL0_RW (PL0_R | PL0_W)
200
+
201
+typedef enum CPAccessResult {
202
+ /* Access is permitted */
203
+ CP_ACCESS_OK = 0,
204
+ /*
205
+ * Access fails due to a configurable trap or enable which would
206
+ * result in a categorized exception syndrome giving information about
207
+ * the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6,
208
+ * 0xc or 0x18). The exception is taken to the usual target EL (EL1 or
209
+ * PL1 if in EL0, otherwise to the current EL).
210
+ */
211
+ CP_ACCESS_TRAP = 1,
212
+ /*
213
+ * Access fails and results in an exception syndrome 0x0 ("uncategorized").
214
+ * Note that this is not a catch-all case -- the set of cases which may
215
+ * result in this failure is specifically defined by the architecture.
216
+ */
217
+ CP_ACCESS_TRAP_UNCATEGORIZED = 2,
218
+ /* As CP_ACCESS_TRAP, but for traps directly to EL2 or EL3 */
219
+ CP_ACCESS_TRAP_EL2 = 3,
220
+ CP_ACCESS_TRAP_EL3 = 4,
221
+ /* As CP_ACCESS_UNCATEGORIZED, but for traps directly to EL2 or EL3 */
222
+ CP_ACCESS_TRAP_UNCATEGORIZED_EL2 = 5,
223
+ CP_ACCESS_TRAP_UNCATEGORIZED_EL3 = 6,
224
+} CPAccessResult;
225
+
226
+typedef struct ARMCPRegInfo ARMCPRegInfo;
227
+
228
+/*
229
+ * Access functions for coprocessor registers. These cannot fail and
230
+ * may not raise exceptions.
231
+ */
232
+typedef uint64_t CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque);
233
+typedef void CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
234
+ uint64_t value);
235
+/* Access permission check functions for coprocessor registers. */
236
+typedef CPAccessResult CPAccessFn(CPUARMState *env,
237
+ const ARMCPRegInfo *opaque,
238
+ bool isread);
239
+/* Hook function for register reset */
240
+typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque);
241
+
242
+#define CP_ANY 0xff
243
+
244
+/* Definition of an ARM coprocessor register */
245
+struct ARMCPRegInfo {
246
+ /* Name of register (useful mainly for debugging, need not be unique) */
247
+ const char *name;
248
+ /*
249
+ * Location of register: coprocessor number and (crn,crm,opc1,opc2)
250
+ * tuple. Any of crm, opc1 and opc2 may be CP_ANY to indicate a
251
+ * 'wildcard' field -- any value of that field in the MRC/MCR insn
252
+ * will be decoded to this register. The register read and write
253
+ * callbacks will be passed an ARMCPRegInfo with the crn/crm/opc1/opc2
254
+ * used by the program, so it is possible to register a wildcard and
255
+ * then behave differently on read/write if necessary.
256
+ * For 64 bit registers, only crm and opc1 are relevant; crn and opc2
257
+ * must both be zero.
258
+ * For AArch64-visible registers, opc0 is also used.
259
+ * Since there are no "coprocessors" in AArch64, cp is purely used as a
260
+ * way to distinguish (for KVM's benefit) guest-visible system registers
261
+ * from demuxed ones provided to preserve the "no side effects on
262
+ * KVM register read/write from QEMU" semantics. cp==0x13 is guest
263
+ * visible (to match KVM's encoding); cp==0 will be converted to
264
+ * cp==0x13 when the ARMCPRegInfo is registered, for convenience.
265
+ */
266
+ uint8_t cp;
267
+ uint8_t crn;
268
+ uint8_t crm;
269
+ uint8_t opc0;
270
+ uint8_t opc1;
271
+ uint8_t opc2;
272
+ /* Execution state in which this register is visible: ARM_CP_STATE_* */
273
+ int state;
274
+ /* Register type: ARM_CP_* bits/values */
275
+ int type;
276
+ /* Access rights: PL*_[RW] */
277
+ int access;
278
+ /* Security state: ARM_CP_SECSTATE_* bits/values */
279
+ int secure;
280
+ /*
281
+ * The opaque pointer passed to define_arm_cp_regs_with_opaque() when
282
+ * this register was defined: can be used to hand data through to the
283
+ * register read/write functions, since they are passed the ARMCPRegInfo*.
284
+ */
285
+ void *opaque;
286
+ /*
287
+ * Value of this register, if it is ARM_CP_CONST. Otherwise, if
288
+ * fieldoffset is non-zero, the reset value of the register.
289
+ */
290
+ uint64_t resetvalue;
291
+ /*
292
+ * Offset of the field in CPUARMState for this register.
293
+ * This is not needed if either:
294
+ * 1. type is ARM_CP_CONST or one of the ARM_CP_SPECIALs
295
+ * 2. both readfn and writefn are specified
296
+ */
297
+ ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
298
+
299
+ /*
300
+ * Offsets of the secure and non-secure fields in CPUARMState for the
301
+ * register if it is banked. These fields are only used during the static
302
+ * registration of a register. During hashing the bank associated
303
+ * with a given security state is copied to fieldoffset which is used from
304
+ * there on out.
305
+ *
306
+ * It is expected that register definitions use either fieldoffset or
307
+ * bank_fieldoffsets in the definition but not both. It is also expected
308
+ * that both bank offsets are set when defining a banked register. This
309
+ * use indicates that a register is banked.
310
+ */
311
+ ptrdiff_t bank_fieldoffsets[2];
312
+
313
+ /*
314
+ * Function for making any access checks for this register in addition to
315
+ * those specified by the 'access' permissions bits. If NULL, no extra
316
+ * checks required. The access check is performed at runtime, not at
317
+ * translate time.
318
+ */
319
+ CPAccessFn *accessfn;
320
+ /*
321
+ * Function for handling reads of this register. If NULL, then reads
322
+ * will be done by loading from the offset into CPUARMState specified
323
+ * by fieldoffset.
324
+ */
325
+ CPReadFn *readfn;
326
+ /*
327
+ * Function for handling writes of this register. If NULL, then writes
328
+ * will be done by writing to the offset into CPUARMState specified
329
+ * by fieldoffset.
330
+ */
331
+ CPWriteFn *writefn;
332
+ /*
333
+ * Function for doing a "raw" read; used when we need to copy
334
+ * coprocessor state to the kernel for KVM or out for
335
+ * migration. This only needs to be provided if there is also a
336
+ * readfn and it has side effects (for instance clear-on-read bits).
337
+ */
338
+ CPReadFn *raw_readfn;
339
+ /*
340
+ * Function for doing a "raw" write; used when we need to copy KVM
341
+ * kernel coprocessor state into userspace, or for inbound
342
+ * migration. This only needs to be provided if there is also a
343
+ * writefn and it masks out "unwritable" bits or has write-one-to-clear
344
+ * or similar behaviour.
345
+ */
346
+ CPWriteFn *raw_writefn;
347
+ /*
348
+ * Function for resetting the register. If NULL, then reset will be done
349
+ * by writing resetvalue to the field specified in fieldoffset. If
350
+ * fieldoffset is 0 then no reset will be done.
351
+ */
352
+ CPResetFn *resetfn;
353
+
354
+ /*
355
+ * "Original" writefn and readfn.
356
+ * For ARMv8.1-VHE register aliases, we overwrite the read/write
357
+ * accessor functions of various EL1/EL0 to perform the runtime
358
+ * check for which sysreg should actually be modified, and then
359
+ * forwards the operation. Before overwriting the accessors,
360
+ * the original function is copied here, so that accesses that
361
+ * really do go to the EL1/EL0 version proceed normally.
362
+ * (The corresponding EL2 register is linked via opaque.)
363
+ */
364
+ CPReadFn *orig_readfn;
365
+ CPWriteFn *orig_writefn;
366
+};
367
+
368
+/*
369
+ * Macros which are lvalues for the field in CPUARMState for the
370
+ * ARMCPRegInfo *ri.
371
+ */
372
+#define CPREG_FIELD32(env, ri) \
373
+ (*(uint32_t *)((char *)(env) + (ri)->fieldoffset))
374
+#define CPREG_FIELD64(env, ri) \
375
+ (*(uint64_t *)((char *)(env) + (ri)->fieldoffset))
376
+
377
+#define REGINFO_SENTINEL { .type = ARM_CP_SENTINEL }
378
+
379
+void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
380
+ const ARMCPRegInfo *regs, void *opaque);
381
+void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
382
+ const ARMCPRegInfo *regs, void *opaque);
383
+static inline void define_arm_cp_regs(ARMCPU *cpu, const ARMCPRegInfo *regs)
384
+{
385
+ define_arm_cp_regs_with_opaque(cpu, regs, 0);
386
+}
387
+static inline void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs)
388
+{
389
+ define_one_arm_cp_reg_with_opaque(cpu, regs, 0);
390
+}
391
+const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp);
392
+
393
+/*
394
+ * Definition of an ARM co-processor register as viewed from
395
+ * userspace. This is used for presenting sanitised versions of
396
+ * registers to userspace when emulating the Linux AArch64 CPU
397
+ * ID/feature ABI (advertised as HWCAP_CPUID).
398
+ */
399
+typedef struct ARMCPRegUserSpaceInfo {
400
+ /* Name of register */
401
+ const char *name;
402
+
403
+ /* Is the name actually a glob pattern */
404
+ bool is_glob;
405
+
406
+ /* Only some bits are exported to user space */
407
+ uint64_t exported_bits;
408
+
409
+ /* Fixed bits are applied after the mask */
410
+ uint64_t fixed_bits;
411
+} ARMCPRegUserSpaceInfo;
412
+
413
+#define REGUSERINFO_SENTINEL { .name = NULL }
414
+
415
+void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods);
416
+
417
+/* CPWriteFn that can be used to implement writes-ignored behaviour */
418
+void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
419
+ uint64_t value);
420
+/* CPReadFn that can be used for read-as-zero behaviour */
421
+uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri);
422
+
423
+/*
424
+ * CPResetFn that does nothing, for use if no reset is required even
425
+ * if fieldoffset is non zero.
426
+ */
427
+void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque);
428
+
429
+/*
430
+ * Return true if this reginfo struct's field in the cpu state struct
431
+ * is 64 bits wide.
432
+ */
433
+static inline bool cpreg_field_is_64bit(const ARMCPRegInfo *ri)
434
+{
435
+ return (ri->state == ARM_CP_STATE_AA64) || (ri->type & ARM_CP_64BIT);
436
+}
437
+
438
+static inline bool cp_access_ok(int current_el,
439
+ const ARMCPRegInfo *ri, int isread)
440
+{
441
+ return (ri->access >> ((current_el * 2) + isread)) & 1;
442
+}
443
+
444
+/* Raw read of a coprocessor register (as needed for migration, etc) */
445
+uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri);
446
+
447
+#endif /* TARGET_ARM_CPREGS_H */
36
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
448
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
37
index XXXXXXX..XXXXXXX 100644
449
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/cpu.h
450
--- a/target/arm/cpu.h
39
+++ b/target/arm/cpu.h
451
+++ b/target/arm/cpu.h
40
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, FPEXC_EL, 8, 2)
452
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
41
FIELD(TBFLAG_ANY, DEBUG_TARGET_EL, 10, 2)
453
return kvmid;
42
/* Memory operations require alignment: SCTLR_ELx.A or CCR.UNALIGN_TRP */
454
}
43
FIELD(TBFLAG_ANY, ALIGN_MEM, 12, 1)
455
44
+FIELD(TBFLAG_ANY, PSTATE__IL, 13, 1)
456
-/* ARMCPRegInfo type field bits. If the SPECIAL bit is set this is a
457
- * special-behaviour cp reg and bits [11..8] indicate what behaviour
458
- * it has. Otherwise it is a simple cp reg, where CONST indicates that
459
- * TCG can assume the value to be constant (ie load at translate time)
460
- * and 64BIT indicates a 64 bit wide coprocessor register. SUPPRESS_TB_END
461
- * indicates that the TB should not be ended after a write to this register
462
- * (the default is that the TB ends after cp writes). OVERRIDE permits
463
- * a register definition to override a previous definition for the
464
- * same (cp, is64, crn, crm, opc1, opc2) tuple: either the new or the
465
- * old must have the OVERRIDE bit set.
466
- * ALIAS indicates that this register is an alias view of some underlying
467
- * state which is also visible via another register, and that the other
468
- * register is handling migration and reset; registers marked ALIAS will not be
469
- * migrated but may have their state set by syncing of register state from KVM.
470
- * NO_RAW indicates that this register has no underlying state and does not
471
- * support raw access for state saving/loading; it will not be used for either
472
- * migration or KVM state synchronization. (Typically this is for "registers"
473
- * which are actually used as instructions for cache maintenance and so on.)
474
- * IO indicates that this register does I/O and therefore its accesses
475
- * need to be marked with gen_io_start() and also end the TB. In particular,
476
- * registers which implement clocks or timers require this.
477
- * RAISES_EXC is for when the read or write hook might raise an exception;
478
- * the generated code will synchronize the CPU state before calling the hook
479
- * so that it is safe for the hook to call raise_exception().
480
- * NEWEL is for writes to registers that might change the exception
481
- * level - typically on older ARM chips. For those cases we need to
482
- * re-read the new el when recomputing the translation flags.
483
- */
484
-#define ARM_CP_SPECIAL 0x0001
485
-#define ARM_CP_CONST 0x0002
486
-#define ARM_CP_64BIT 0x0004
487
-#define ARM_CP_SUPPRESS_TB_END 0x0008
488
-#define ARM_CP_OVERRIDE 0x0010
489
-#define ARM_CP_ALIAS 0x0020
490
-#define ARM_CP_IO 0x0040
491
-#define ARM_CP_NO_RAW 0x0080
492
-#define ARM_CP_NOP (ARM_CP_SPECIAL | 0x0100)
493
-#define ARM_CP_WFI (ARM_CP_SPECIAL | 0x0200)
494
-#define ARM_CP_NZCV (ARM_CP_SPECIAL | 0x0300)
495
-#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | 0x0400)
496
-#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | 0x0500)
497
-#define ARM_CP_DC_GVA (ARM_CP_SPECIAL | 0x0600)
498
-#define ARM_CP_DC_GZVA (ARM_CP_SPECIAL | 0x0700)
499
-#define ARM_LAST_SPECIAL ARM_CP_DC_GZVA
500
-#define ARM_CP_FPU 0x1000
501
-#define ARM_CP_SVE 0x2000
502
-#define ARM_CP_NO_GDB 0x4000
503
-#define ARM_CP_RAISES_EXC 0x8000
504
-#define ARM_CP_NEWEL 0x10000
505
-/* Used only as a terminator for ARMCPRegInfo lists */
506
-#define ARM_CP_SENTINEL 0xfffff
507
-/* Mask of only the flag bits in a type field */
508
-#define ARM_CP_FLAG_MASK 0x1f0ff
509
-
510
-/* Valid values for ARMCPRegInfo state field, indicating which of
511
- * the AArch32 and AArch64 execution states this register is visible in.
512
- * If the reginfo doesn't explicitly specify then it is AArch32 only.
513
- * If the reginfo is declared to be visible in both states then a second
514
- * reginfo is synthesised for the AArch32 view of the AArch64 register,
515
- * such that the AArch32 view is the lower 32 bits of the AArch64 one.
516
- * Note that we rely on the values of these enums as we iterate through
517
- * the various states in some places.
518
- */
519
-enum {
520
- ARM_CP_STATE_AA32 = 0,
521
- ARM_CP_STATE_AA64 = 1,
522
- ARM_CP_STATE_BOTH = 2,
523
-};
524
-
525
-/* ARM CP register secure state flags. These flags identify security state
526
- * attributes for a given CP register entry.
527
- * The existence of both or neither secure and non-secure flags indicates that
528
- * the register has both a secure and non-secure hash entry. A single one of
529
- * these flags causes the register to only be hashed for the specified
530
- * security state.
531
- * Although definitions may have any combination of the S/NS bits, each
532
- * registered entry will only have one to identify whether the entry is secure
533
- * or non-secure.
534
- */
535
-enum {
536
- ARM_CP_SECSTATE_S = (1 << 0), /* bit[0]: Secure state register */
537
- ARM_CP_SECSTATE_NS = (1 << 1), /* bit[1]: Non-secure state register */
538
-};
539
-
540
-/* Return true if cptype is a valid type field. This is used to try to
541
- * catch errors where the sentinel has been accidentally left off the end
542
- * of a list of registers.
543
- */
544
-static inline bool cptype_valid(int cptype)
545
-{
546
- return ((cptype & ~ARM_CP_FLAG_MASK) == 0)
547
- || ((cptype & ARM_CP_SPECIAL) &&
548
- ((cptype & ~ARM_CP_FLAG_MASK) <= ARM_LAST_SPECIAL));
549
-}
550
-
551
-/* Access rights:
552
- * We define bits for Read and Write access for what rev C of the v7-AR ARM ARM
553
- * defines as PL0 (user), PL1 (fiq/irq/svc/abt/und/sys, ie privileged), and
554
- * PL2 (hyp). The other level which has Read and Write bits is Secure PL1
555
- * (ie any of the privileged modes in Secure state, or Monitor mode).
556
- * If a register is accessible in one privilege level it's always accessible
557
- * in higher privilege levels too. Since "Secure PL1" also follows this rule
558
- * (ie anything visible in PL2 is visible in S-PL1, some things are only
559
- * visible in S-PL1) but "Secure PL1" is a bit of a mouthful, we bend the
560
- * terminology a little and call this PL3.
561
- * In AArch64 things are somewhat simpler as the PLx bits line up exactly
562
- * with the ELx exception levels.
563
- *
564
- * If access permissions for a register are more complex than can be
565
- * described with these bits, then use a laxer set of restrictions, and
566
- * do the more restrictive/complex check inside a helper function.
567
- */
568
-#define PL3_R 0x80
569
-#define PL3_W 0x40
570
-#define PL2_R (0x20 | PL3_R)
571
-#define PL2_W (0x10 | PL3_W)
572
-#define PL1_R (0x08 | PL2_R)
573
-#define PL1_W (0x04 | PL2_W)
574
-#define PL0_R (0x02 | PL1_R)
575
-#define PL0_W (0x01 | PL1_W)
576
-
577
-/*
578
- * For user-mode some registers are accessible to EL0 via a kernel
579
- * trap-and-emulate ABI. In this case we define the read permissions
580
- * as actually being PL0_R. However some bits of any given register
581
- * may still be masked.
582
- */
583
-#ifdef CONFIG_USER_ONLY
584
-#define PL0U_R PL0_R
585
-#else
586
-#define PL0U_R PL1_R
587
-#endif
588
-
589
-#define PL3_RW (PL3_R | PL3_W)
590
-#define PL2_RW (PL2_R | PL2_W)
591
-#define PL1_RW (PL1_R | PL1_W)
592
-#define PL0_RW (PL0_R | PL0_W)
593
-
594
/* Return the highest implemented Exception Level */
595
static inline int arm_highest_el(CPUARMState *env)
596
{
597
@@ -XXX,XX +XXX,XX @@ static inline int arm_current_el(CPUARMState *env)
598
}
599
}
600
601
-typedef struct ARMCPRegInfo ARMCPRegInfo;
602
-
603
-typedef enum CPAccessResult {
604
- /* Access is permitted */
605
- CP_ACCESS_OK = 0,
606
- /* Access fails due to a configurable trap or enable which would
607
- * result in a categorized exception syndrome giving information about
608
- * the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6,
609
- * 0xc or 0x18). The exception is taken to the usual target EL (EL1 or
610
- * PL1 if in EL0, otherwise to the current EL).
611
- */
612
- CP_ACCESS_TRAP = 1,
613
- /* Access fails and results in an exception syndrome 0x0 ("uncategorized").
614
- * Note that this is not a catch-all case -- the set of cases which may
615
- * result in this failure is specifically defined by the architecture.
616
- */
617
- CP_ACCESS_TRAP_UNCATEGORIZED = 2,
618
- /* As CP_ACCESS_TRAP, but for traps directly to EL2 or EL3 */
619
- CP_ACCESS_TRAP_EL2 = 3,
620
- CP_ACCESS_TRAP_EL3 = 4,
621
- /* As CP_ACCESS_UNCATEGORIZED, but for traps directly to EL2 or EL3 */
622
- CP_ACCESS_TRAP_UNCATEGORIZED_EL2 = 5,
623
- CP_ACCESS_TRAP_UNCATEGORIZED_EL3 = 6,
624
-} CPAccessResult;
625
-
626
-/* Access functions for coprocessor registers. These cannot fail and
627
- * may not raise exceptions.
628
- */
629
-typedef uint64_t CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque);
630
-typedef void CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
631
- uint64_t value);
632
-/* Access permission check functions for coprocessor registers. */
633
-typedef CPAccessResult CPAccessFn(CPUARMState *env,
634
- const ARMCPRegInfo *opaque,
635
- bool isread);
636
-/* Hook function for register reset */
637
-typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque);
638
-
639
-#define CP_ANY 0xff
640
-
641
-/* Definition of an ARM coprocessor register */
642
-struct ARMCPRegInfo {
643
- /* Name of register (useful mainly for debugging, need not be unique) */
644
- const char *name;
645
- /* Location of register: coprocessor number and (crn,crm,opc1,opc2)
646
- * tuple. Any of crm, opc1 and opc2 may be CP_ANY to indicate a
647
- * 'wildcard' field -- any value of that field in the MRC/MCR insn
648
- * will be decoded to this register. The register read and write
649
- * callbacks will be passed an ARMCPRegInfo with the crn/crm/opc1/opc2
650
- * used by the program, so it is possible to register a wildcard and
651
- * then behave differently on read/write if necessary.
652
- * For 64 bit registers, only crm and opc1 are relevant; crn and opc2
653
- * must both be zero.
654
- * For AArch64-visible registers, opc0 is also used.
655
- * Since there are no "coprocessors" in AArch64, cp is purely used as a
656
- * way to distinguish (for KVM's benefit) guest-visible system registers
657
- * from demuxed ones provided to preserve the "no side effects on
658
- * KVM register read/write from QEMU" semantics. cp==0x13 is guest
659
- * visible (to match KVM's encoding); cp==0 will be converted to
660
- * cp==0x13 when the ARMCPRegInfo is registered, for convenience.
661
- */
662
- uint8_t cp;
663
- uint8_t crn;
664
- uint8_t crm;
665
- uint8_t opc0;
666
- uint8_t opc1;
667
- uint8_t opc2;
668
- /* Execution state in which this register is visible: ARM_CP_STATE_* */
669
- int state;
670
- /* Register type: ARM_CP_* bits/values */
671
- int type;
672
- /* Access rights: PL*_[RW] */
673
- int access;
674
- /* Security state: ARM_CP_SECSTATE_* bits/values */
675
- int secure;
676
- /* The opaque pointer passed to define_arm_cp_regs_with_opaque() when
677
- * this register was defined: can be used to hand data through to the
678
- * register read/write functions, since they are passed the ARMCPRegInfo*.
679
- */
680
- void *opaque;
681
- /* Value of this register, if it is ARM_CP_CONST. Otherwise, if
682
- * fieldoffset is non-zero, the reset value of the register.
683
- */
684
- uint64_t resetvalue;
685
- /* Offset of the field in CPUARMState for this register.
686
- *
687
- * This is not needed if either:
688
- * 1. type is ARM_CP_CONST or one of the ARM_CP_SPECIALs
689
- * 2. both readfn and writefn are specified
690
- */
691
- ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
692
-
693
- /* Offsets of the secure and non-secure fields in CPUARMState for the
694
- * register if it is banked. These fields are only used during the static
695
- * registration of a register. During hashing the bank associated
696
- * with a given security state is copied to fieldoffset which is used from
697
- * there on out.
698
- *
699
- * It is expected that register definitions use either fieldoffset or
700
- * bank_fieldoffsets in the definition but not both. It is also expected
701
- * that both bank offsets are set when defining a banked register. This
702
- * use indicates that a register is banked.
703
- */
704
- ptrdiff_t bank_fieldoffsets[2];
705
-
706
- /* Function for making any access checks for this register in addition to
707
- * those specified by the 'access' permissions bits. If NULL, no extra
708
- * checks required. The access check is performed at runtime, not at
709
- * translate time.
710
- */
711
- CPAccessFn *accessfn;
712
- /* Function for handling reads of this register. If NULL, then reads
713
- * will be done by loading from the offset into CPUARMState specified
714
- * by fieldoffset.
715
- */
716
- CPReadFn *readfn;
717
- /* Function for handling writes of this register. If NULL, then writes
718
- * will be done by writing to the offset into CPUARMState specified
719
- * by fieldoffset.
720
- */
721
- CPWriteFn *writefn;
722
- /* Function for doing a "raw" read; used when we need to copy
723
- * coprocessor state to the kernel for KVM or out for
724
- * migration. This only needs to be provided if there is also a
725
- * readfn and it has side effects (for instance clear-on-read bits).
726
- */
727
- CPReadFn *raw_readfn;
728
- /* Function for doing a "raw" write; used when we need to copy KVM
729
- * kernel coprocessor state into userspace, or for inbound
730
- * migration. This only needs to be provided if there is also a
731
- * writefn and it masks out "unwritable" bits or has write-one-to-clear
732
- * or similar behaviour.
733
- */
734
- CPWriteFn *raw_writefn;
735
- /* Function for resetting the register. If NULL, then reset will be done
736
- * by writing resetvalue to the field specified in fieldoffset. If
737
- * fieldoffset is 0 then no reset will be done.
738
- */
739
- CPResetFn *resetfn;
740
-
741
- /*
742
- * "Original" writefn and readfn.
743
- * For ARMv8.1-VHE register aliases, we overwrite the read/write
744
- * accessor functions of various EL1/EL0 to perform the runtime
745
- * check for which sysreg should actually be modified, and then
746
- * forwards the operation. Before overwriting the accessors,
747
- * the original function is copied here, so that accesses that
748
- * really do go to the EL1/EL0 version proceed normally.
749
- * (The corresponding EL2 register is linked via opaque.)
750
- */
751
- CPReadFn *orig_readfn;
752
- CPWriteFn *orig_writefn;
753
-};
754
-
755
-/* Macros which are lvalues for the field in CPUARMState for the
756
- * ARMCPRegInfo *ri.
757
- */
758
-#define CPREG_FIELD32(env, ri) \
759
- (*(uint32_t *)((char *)(env) + (ri)->fieldoffset))
760
-#define CPREG_FIELD64(env, ri) \
761
- (*(uint64_t *)((char *)(env) + (ri)->fieldoffset))
762
-
763
-#define REGINFO_SENTINEL { .type = ARM_CP_SENTINEL }
764
-
765
-void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
766
- const ARMCPRegInfo *regs, void *opaque);
767
-void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
768
- const ARMCPRegInfo *regs, void *opaque);
769
-static inline void define_arm_cp_regs(ARMCPU *cpu, const ARMCPRegInfo *regs)
770
-{
771
- define_arm_cp_regs_with_opaque(cpu, regs, 0);
772
-}
773
-static inline void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs)
774
-{
775
- define_one_arm_cp_reg_with_opaque(cpu, regs, 0);
776
-}
777
-const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp);
778
-
779
-/*
780
- * Definition of an ARM co-processor register as viewed from
781
- * userspace. This is used for presenting sanitised versions of
782
- * registers to userspace when emulating the Linux AArch64 CPU
783
- * ID/feature ABI (advertised as HWCAP_CPUID).
784
- */
785
-typedef struct ARMCPRegUserSpaceInfo {
786
- /* Name of register */
787
- const char *name;
788
-
789
- /* Is the name actually a glob pattern */
790
- bool is_glob;
791
-
792
- /* Only some bits are exported to user space */
793
- uint64_t exported_bits;
794
-
795
- /* Fixed bits are applied after the mask */
796
- uint64_t fixed_bits;
797
-} ARMCPRegUserSpaceInfo;
798
-
799
-#define REGUSERINFO_SENTINEL { .name = NULL }
800
-
801
-void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods);
802
-
803
-/* CPWriteFn that can be used to implement writes-ignored behaviour */
804
-void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
805
- uint64_t value);
806
-/* CPReadFn that can be used for read-as-zero behaviour */
807
-uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri);
808
-
809
-/* CPResetFn that does nothing, for use if no reset is required even
810
- * if fieldoffset is non zero.
811
- */
812
-void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque);
813
-
814
-/* Return true if this reginfo struct's field in the cpu state struct
815
- * is 64 bits wide.
816
- */
817
-static inline bool cpreg_field_is_64bit(const ARMCPRegInfo *ri)
818
-{
819
- return (ri->state == ARM_CP_STATE_AA64) || (ri->type & ARM_CP_64BIT);
820
-}
821
-
822
-static inline bool cp_access_ok(int current_el,
823
- const ARMCPRegInfo *ri, int isread)
824
-{
825
- return (ri->access >> ((current_el * 2) + isread)) & 1;
826
-}
827
-
828
-/* Raw read of a coprocessor register (as needed for migration, etc) */
829
-uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri);
830
-
831
/**
832
* write_list_to_cpustate
833
* @cpu: ARMCPU
834
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
835
index XXXXXXX..XXXXXXX 100644
836
--- a/hw/arm/pxa2xx.c
837
+++ b/hw/arm/pxa2xx.c
838
@@ -XXX,XX +XXX,XX @@
839
#include "qemu/cutils.h"
840
#include "qemu/log.h"
841
#include "qom/object.h"
842
+#include "target/arm/cpregs.h"
843
844
static struct {
845
hwaddr io_base;
846
diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c
847
index XXXXXXX..XXXXXXX 100644
848
--- a/hw/arm/pxa2xx_pic.c
849
+++ b/hw/arm/pxa2xx_pic.c
850
@@ -XXX,XX +XXX,XX @@
851
#include "hw/sysbus.h"
852
#include "migration/vmstate.h"
853
#include "qom/object.h"
854
+#include "target/arm/cpregs.h"
855
856
#define ICIP    0x00    /* Interrupt Controller IRQ Pending register */
857
#define ICMR    0x04    /* Interrupt Controller Mask register */
858
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
859
index XXXXXXX..XXXXXXX 100644
860
--- a/hw/intc/arm_gicv3_cpuif.c
861
+++ b/hw/intc/arm_gicv3_cpuif.c
862
@@ -XXX,XX +XXX,XX @@
863
#include "gicv3_internal.h"
864
#include "hw/irq.h"
865
#include "cpu.h"
866
+#include "target/arm/cpregs.h"
45
867
46
/*
868
/*
47
* Bit usage when in AArch32 state, both A- and M-profile.
869
* Special case return value from hppvi_index(); must be larger than
48
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
870
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
49
index XXXXXXX..XXXXXXX 100644
871
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/syndrome.h
872
--- a/hw/intc/arm_gicv3_kvm.c
51
+++ b/target/arm/syndrome.h
873
+++ b/hw/intc/arm_gicv3_kvm.c
52
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_wfx(int cv, int cond, int ti, bool is_16bit)
874
@@ -XXX,XX +XXX,XX @@
53
(cv << 24) | (cond << 20) | ti;
875
#include "vgic_common.h"
54
}
876
#include "migration/blocker.h"
55
877
#include "qom/object.h"
56
+static inline uint32_t syn_illegalstate(void)
878
+#include "target/arm/cpregs.h"
57
+{
879
+
58
+ return (EC_ILLEGALSTATE << ARM_EL_EC_SHIFT) | ARM_EL_IL;
880
59
+}
881
#ifdef DEBUG_GICV3_KVM
60
+
882
#define DPRINTF(fmt, ...) \
61
#endif /* TARGET_ARM_SYNDROME_H */
883
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
62
diff --git a/target/arm/translate.h b/target/arm/translate.h
884
index XXXXXXX..XXXXXXX 100644
63
index XXXXXXX..XXXXXXX 100644
885
--- a/target/arm/cpu.c
64
--- a/target/arm/translate.h
886
+++ b/target/arm/cpu.c
65
+++ b/target/arm/translate.h
887
@@ -XXX,XX +XXX,XX @@
66
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
888
#include "kvm_arm.h"
67
bool hstr_active;
889
#include "disas/capstone.h"
68
/* True if memory operations require alignment */
890
#include "fpu/softfloat.h"
69
bool align_mem;
891
+#include "cpregs.h"
70
+ /* True if PSTATE.IL is set */
892
71
+ bool pstate_il;
893
static void arm_cpu_set_pc(CPUState *cs, vaddr value)
72
/*
894
{
73
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
895
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
74
* < 0, set by the current instruction.
896
index XXXXXXX..XXXXXXX 100644
75
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
897
--- a/target/arm/cpu64.c
76
index XXXXXXX..XXXXXXX 100644
898
+++ b/target/arm/cpu64.c
77
--- a/target/arm/helper-a64.c
899
@@ -XXX,XX +XXX,XX @@
78
+++ b/target/arm/helper-a64.c
900
#include "hvf_arm.h"
79
@@ -XXX,XX +XXX,XX @@ illegal_return:
901
#include "qapi/visitor.h"
80
if (!arm_singlestep_active(env)) {
902
#include "hw/qdev-properties.h"
81
env->pstate &= ~PSTATE_SS;
903
+#include "cpregs.h"
82
}
904
83
+ helper_rebuild_hflags_a64(env, cur_el);
905
84
qemu_log_mask(LOG_GUEST_ERROR, "Illegal exception return at EL%d: "
906
#ifndef CONFIG_USER_ONLY
85
"resuming execution at 0x%" PRIx64 "\n", cur_el, env->pc);
907
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
86
}
908
index XXXXXXX..XXXXXXX 100644
909
--- a/target/arm/cpu_tcg.c
910
+++ b/target/arm/cpu_tcg.c
911
@@ -XXX,XX +XXX,XX @@
912
#if !defined(CONFIG_USER_ONLY)
913
#include "hw/boards.h"
914
#endif
915
+#include "cpregs.h"
916
917
/* CPU models. These are not needed for the AArch64 linux-user build. */
918
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
919
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
920
index XXXXXXX..XXXXXXX 100644
921
--- a/target/arm/gdbstub.c
922
+++ b/target/arm/gdbstub.c
923
@@ -XXX,XX +XXX,XX @@
924
*/
925
#include "qemu/osdep.h"
926
#include "cpu.h"
927
-#include "internals.h"
928
#include "exec/gdbstub.h"
929
+#include "internals.h"
930
+#include "cpregs.h"
931
932
typedef struct RegisterSysregXmlParam {
933
CPUState *cs;
87
diff --git a/target/arm/helper.c b/target/arm/helper.c
934
diff --git a/target/arm/helper.c b/target/arm/helper.c
88
index XXXXXXX..XXXXXXX 100644
935
index XXXXXXX..XXXXXXX 100644
89
--- a/target/arm/helper.c
936
--- a/target/arm/helper.c
90
+++ b/target/arm/helper.c
937
+++ b/target/arm/helper.c
91
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el,
938
@@ -XXX,XX +XXX,XX @@
92
DP_TBFLAG_A32(flags, HSTR_ACTIVE, 1);
939
#include "exec/cpu_ldst.h"
93
}
940
#include "semihosting/common-semi.h"
94
941
#endif
95
+ if (env->uncached_cpsr & CPSR_IL) {
942
+#include "cpregs.h"
96
+ DP_TBFLAG_ANY(flags, PSTATE__IL, 1);
943
97
+ }
944
#define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */
98
+
945
#define PMCR_NUM_COUNTERS 4 /* QEMU IMPDEF choice */
99
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
946
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
100
}
947
index XXXXXXX..XXXXXXX 100644
101
948
--- a/target/arm/op_helper.c
102
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
949
+++ b/target/arm/op_helper.c
103
}
950
@@ -XXX,XX +XXX,XX @@
104
}
951
#include "internals.h"
105
952
#include "exec/exec-all.h"
106
+ if (env->pstate & PSTATE_IL) {
953
#include "exec/cpu_ldst.h"
107
+ DP_TBFLAG_ANY(flags, PSTATE__IL, 1);
954
+#include "cpregs.h"
108
+ }
955
109
+
956
#define SIGNBIT (uint32_t)0x80000000
110
if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
957
#define SIGNBIT64 ((uint64_t)1 << 63)
111
/*
112
* Set MTE_ACTIVE if any access may be Checked, and leave clear
113
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
958
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
114
index XXXXXXX..XXXXXXX 100644
959
index XXXXXXX..XXXXXXX 100644
115
--- a/target/arm/translate-a64.c
960
--- a/target/arm/translate-a64.c
116
+++ b/target/arm/translate-a64.c
961
+++ b/target/arm/translate-a64.c
117
@@ -XXX,XX +XXX,XX @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
962
@@ -XXX,XX +XXX,XX @@
118
s->fp_access_checked = false;
963
#include "translate.h"
119
s->sve_access_checked = false;
964
#include "internals.h"
120
965
#include "qemu/host-utils.h"
121
+ if (s->pstate_il) {
966
-
122
+ /*
967
#include "semihosting/semihost.h"
123
+ * Illegal execution state. This has priority over BTI
968
#include "exec/gen-icount.h"
124
+ * exceptions, but comes after instruction abort exceptions.
969
-
125
+ */
970
#include "exec/helper-proto.h"
126
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
971
#include "exec/helper-gen.h"
127
+ syn_illegalstate(), default_exception_el(s));
972
#include "exec/log.h"
128
+ return;
973
-
129
+ }
974
+#include "cpregs.h"
130
+
975
#include "translate-a64.h"
131
if (dc_isar_feature(aa64_bti, s)) {
976
#include "qemu/atomic128.h"
132
if (s->base.num_insns == 1) {
977
133
/*
134
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
135
#endif
136
dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
137
dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
138
+ dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
139
dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
140
dc->sve_len = (EX_TBFLAG_A64(tb_flags, ZCR_LEN) + 1) * 16;
141
dc->pauth_active = EX_TBFLAG_A64(tb_flags, PAUTH_ACTIVE);
142
diff --git a/target/arm/translate.c b/target/arm/translate.c
978
diff --git a/target/arm/translate.c b/target/arm/translate.c
143
index XXXXXXX..XXXXXXX 100644
979
index XXXXXXX..XXXXXXX 100644
144
--- a/target/arm/translate.c
980
--- a/target/arm/translate.c
145
+++ b/target/arm/translate.c
981
+++ b/target/arm/translate.c
146
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
982
@@ -XXX,XX +XXX,XX @@
147
return;
983
#include "qemu/bitops.h"
148
}
984
#include "arm_ldst.h"
149
985
#include "semihosting/semihost.h"
150
+ if (s->pstate_il) {
986
-
151
+ /*
987
#include "exec/helper-proto.h"
152
+ * Illegal execution state. This has priority over BTI
988
#include "exec/helper-gen.h"
153
+ * exceptions, but comes after instruction abort exceptions.
989
-
154
+ */
990
#include "exec/log.h"
155
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
991
+#include "cpregs.h"
156
+ syn_illegalstate(), default_exception_el(s));
992
157
+ return;
993
158
+ }
994
#define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
159
+
160
if (cond == 0xf) {
161
/* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
162
* choose to UNDEF. In ARMv5 and above the space is used
163
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
164
#endif
165
dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
166
dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
167
+ dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
168
169
if (arm_feature(env, ARM_FEATURE_M)) {
170
dc->vfp_enabled = 1;
171
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
172
}
173
dc->insn = insn;
174
175
+ if (dc->pstate_il) {
176
+ /*
177
+ * Illegal execution state. This has priority over BTI
178
+ * exceptions, but comes after instruction abort exceptions.
179
+ */
180
+ gen_exception_insn(dc, dc->pc_curr, EXCP_UDEF,
181
+ syn_illegalstate(), default_exception_el(dc));
182
+ return;
183
+ }
184
+
185
if (dc->eci) {
186
/*
187
* For M-profile continuable instructions, ECI/ICI handling
188
--
995
--
189
2.20.1
996
2.25.1
190
997
191
998
diff view generated by jsdifflib
1
From: Bin Meng <bmeng.cn@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
We've got SW that expects FSBL (Bootlooader) to setup clocks and
3
Rearrange the values of the enumerators of CPAccessResult
4
resets. It's quite common that users run that SW on QEMU without
4
so that we may directly extract the target el. For the two
5
FSBL (FSBL typically requires the Xilinx tools installed). That's
5
special cases in access_check_cp_reg, use CPAccessResult.
6
fine, since users can stil use -device loader to enable clocks etc.
7
6
8
To help folks understand what's going, a log (guest-error) message
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
would be helpful here. In particular with the serial port since
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
things will go very quiet if they get things wrong.
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
10
Message-id: 20220501055028.646596-3-richard.henderson@linaro.org
12
Suggested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
13
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
14
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-id: 20210901124521.30599-7-bmeng.cn@gmail.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
12
---
19
hw/char/cadence_uart.c | 8 ++++++++
13
target/arm/cpregs.h | 26 ++++++++++++--------
20
1 file changed, 8 insertions(+)
14
target/arm/op_helper.c | 56 +++++++++++++++++++++---------------------
15
2 files changed, 44 insertions(+), 38 deletions(-)
21
16
22
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
17
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
23
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/char/cadence_uart.c
19
--- a/target/arm/cpregs.h
25
+++ b/hw/char/cadence_uart.c
20
+++ b/target/arm/cpregs.h
26
@@ -XXX,XX +XXX,XX @@ static int uart_can_receive(void *opaque)
21
@@ -XXX,XX +XXX,XX @@ static inline bool cptype_valid(int cptype)
27
22
typedef enum CPAccessResult {
28
/* ignore characters when unclocked or in reset */
23
/* Access is permitted */
29
if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
24
CP_ACCESS_OK = 0,
30
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: uart is unclocked or in reset\n",
25
+
31
+ __func__);
26
+ /*
32
return 0;
27
+ * Combined with one of the following, the low 2 bits indicate the
28
+ * target exception level. If 0, the exception is taken to the usual
29
+ * target EL (EL1 or PL1 if in EL0, otherwise to the current EL).
30
+ */
31
+ CP_ACCESS_EL_MASK = 3,
32
+
33
/*
34
* Access fails due to a configurable trap or enable which would
35
* result in a categorized exception syndrome giving information about
36
* the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6,
37
- * 0xc or 0x18). The exception is taken to the usual target EL (EL1 or
38
- * PL1 if in EL0, otherwise to the current EL).
39
+ * 0xc or 0x18).
40
*/
41
- CP_ACCESS_TRAP = 1,
42
+ CP_ACCESS_TRAP = (1 << 2),
43
+ CP_ACCESS_TRAP_EL2 = CP_ACCESS_TRAP | 2,
44
+ CP_ACCESS_TRAP_EL3 = CP_ACCESS_TRAP | 3,
45
+
46
/*
47
* Access fails and results in an exception syndrome 0x0 ("uncategorized").
48
* Note that this is not a catch-all case -- the set of cases which may
49
* result in this failure is specifically defined by the architecture.
50
*/
51
- CP_ACCESS_TRAP_UNCATEGORIZED = 2,
52
- /* As CP_ACCESS_TRAP, but for traps directly to EL2 or EL3 */
53
- CP_ACCESS_TRAP_EL2 = 3,
54
- CP_ACCESS_TRAP_EL3 = 4,
55
- /* As CP_ACCESS_UNCATEGORIZED, but for traps directly to EL2 or EL3 */
56
- CP_ACCESS_TRAP_UNCATEGORIZED_EL2 = 5,
57
- CP_ACCESS_TRAP_UNCATEGORIZED_EL3 = 6,
58
+ CP_ACCESS_TRAP_UNCATEGORIZED = (2 << 2),
59
+ CP_ACCESS_TRAP_UNCATEGORIZED_EL2 = CP_ACCESS_TRAP_UNCATEGORIZED | 2,
60
+ CP_ACCESS_TRAP_UNCATEGORIZED_EL3 = CP_ACCESS_TRAP_UNCATEGORIZED | 3,
61
} CPAccessResult;
62
63
typedef struct ARMCPRegInfo ARMCPRegInfo;
64
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/op_helper.c
67
+++ b/target/arm/op_helper.c
68
@@ -XXX,XX +XXX,XX @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
69
uint32_t isread)
70
{
71
const ARMCPRegInfo *ri = rip;
72
+ CPAccessResult res = CP_ACCESS_OK;
73
int target_el;
74
75
if (arm_feature(env, ARM_FEATURE_XSCALE) && ri->cp < 14
76
&& extract32(env->cp15.c15_cpar, ri->cp, 1) == 0) {
77
- raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env));
78
+ res = CP_ACCESS_TRAP;
79
+ goto fail;
33
}
80
}
34
81
35
@@ -XXX,XX +XXX,XX @@ static void uart_event(void *opaque, QEMUChrEvent event)
82
/*
36
83
@@ -XXX,XX +XXX,XX @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
37
/* ignore characters when unclocked or in reset */
84
mask &= ~((1 << 4) | (1 << 14));
38
if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
85
39
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: uart is unclocked or in reset\n",
86
if (env->cp15.hstr_el2 & mask) {
40
+ __func__);
87
- target_el = 2;
88
- goto exept;
89
+ res = CP_ACCESS_TRAP_EL2;
90
+ goto fail;
91
}
92
}
93
94
- if (!ri->accessfn) {
95
+ if (ri->accessfn) {
96
+ res = ri->accessfn(env, ri, isread);
97
+ }
98
+ if (likely(res == CP_ACCESS_OK)) {
41
return;
99
return;
42
}
100
}
43
101
44
@@ -XXX,XX +XXX,XX @@ static MemTxResult uart_write(void *opaque, hwaddr offset,
102
- switch (ri->accessfn(env, ri, isread)) {
45
103
- case CP_ACCESS_OK:
46
/* ignore access when unclocked or in reset */
104
- return;
47
if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
105
+ fail:
48
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: uart is unclocked or in reset\n",
106
+ switch (res & ~CP_ACCESS_EL_MASK) {
49
+ __func__);
107
case CP_ACCESS_TRAP:
50
return MEMTX_ERROR;
108
- target_el = exception_target_el(env);
109
- break;
110
- case CP_ACCESS_TRAP_EL2:
111
- /* Requesting a trap to EL2 when we're in EL3 is
112
- * a bug in the access function.
113
- */
114
- assert(arm_current_el(env) != 3);
115
- target_el = 2;
116
- break;
117
- case CP_ACCESS_TRAP_EL3:
118
- target_el = 3;
119
break;
120
case CP_ACCESS_TRAP_UNCATEGORIZED:
121
- target_el = exception_target_el(env);
122
- syndrome = syn_uncategorized();
123
- break;
124
- case CP_ACCESS_TRAP_UNCATEGORIZED_EL2:
125
- target_el = 2;
126
- syndrome = syn_uncategorized();
127
- break;
128
- case CP_ACCESS_TRAP_UNCATEGORIZED_EL3:
129
- target_el = 3;
130
syndrome = syn_uncategorized();
131
break;
132
default:
133
g_assert_not_reached();
51
}
134
}
52
135
53
@@ -XXX,XX +XXX,XX @@ static MemTxResult uart_read(void *opaque, hwaddr offset,
136
-exept:
54
137
+ target_el = res & CP_ACCESS_EL_MASK;
55
/* ignore access when unclocked or in reset */
138
+ switch (target_el) {
56
if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
139
+ case 0:
57
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: uart is unclocked or in reset\n",
140
+ target_el = exception_target_el(env);
58
+ __func__);
141
+ break;
59
return MEMTX_ERROR;
142
+ case 2:
60
}
143
+ assert(arm_current_el(env) != 3);
144
+ assert(arm_is_el2_enabled(env));
145
+ break;
146
+ case 3:
147
+ assert(arm_feature(env, ARM_FEATURE_EL3));
148
+ break;
149
+ default:
150
+ /* No "direct" traps to EL1 */
151
+ g_assert_not_reached();
152
+ }
153
+
154
raise_exception(env, EXCP_UDEF, syndrome, target_el);
155
}
61
156
62
--
157
--
63
2.20.1
158
2.25.1
64
159
65
160
diff view generated by jsdifflib
1
From: Shashi Mallela <shashi.mallela@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Implemented lpi processing at redistributor to get lpi config info
3
Remove a possible source of error by removing REGINFO_SENTINEL
4
from lpi configuration table,determine priority,set pending state in
4
and using ARRAY_SIZE (convinently hidden inside a macro) to
5
lpi pending table and forward the lpi to cpuif.Added logic to invoke
5
find the end of the set of regs being registered or modified.
6
redistributor lpi processing with translated LPI which set/clear LPI
7
from ITS device as part of ITS INT,CLEAR,DISCARD command and
8
GITS_TRANSLATER processing.
9
6
10
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
7
The space saved by not having the extra array element reduces
11
Tested-by: Neil Armstrong <narmstrong@baylibre.com>
8
the executable's .data.rel.ro section by about 9k.
9
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20210910143951.92242-7-shashi.mallela@linaro.org
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20220501055028.646596-4-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
15
---
16
hw/intc/gicv3_internal.h | 9 ++
16
target/arm/cpregs.h | 53 +++++++++---------
17
include/hw/intc/arm_gicv3_common.h | 7 ++
17
hw/arm/pxa2xx.c | 1 -
18
hw/intc/arm_gicv3.c | 14 +++
18
hw/arm/pxa2xx_pic.c | 1 -
19
hw/intc/arm_gicv3_common.c | 1 +
19
hw/intc/arm_gicv3_cpuif.c | 5 --
20
hw/intc/arm_gicv3_cpuif.c | 7 +-
20
hw/intc/arm_gicv3_kvm.c | 1 -
21
hw/intc/arm_gicv3_its.c | 23 +++++
21
target/arm/cpu64.c | 1 -
22
hw/intc/arm_gicv3_redist.c | 141 +++++++++++++++++++++++++++++
22
target/arm/cpu_tcg.c | 4 --
23
7 files changed, 200 insertions(+), 2 deletions(-)
23
target/arm/helper.c | 111 ++++++++------------------------------
24
8 files changed, 48 insertions(+), 129 deletions(-)
24
25
25
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
26
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
26
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/intc/gicv3_internal.h
28
--- a/target/arm/cpregs.h
28
+++ b/hw/intc/gicv3_internal.h
29
+++ b/target/arm/cpregs.h
29
@@ -XXX,XX +XXX,XX @@ FIELD(GICR_PENDBASER, PHYADDR, 16, 36)
30
@@ -XXX,XX +XXX,XX @@
30
FIELD(GICR_PENDBASER, OUTERCACHE, 56, 3)
31
#define ARM_CP_NO_GDB 0x4000
31
FIELD(GICR_PENDBASER, PTZ, 62, 1)
32
#define ARM_CP_RAISES_EXC 0x8000
32
33
#define ARM_CP_NEWEL 0x10000
33
+#define GICR_PROPBASER_IDBITS_THRESHOLD 0xd
34
-/* Used only as a terminator for ARMCPRegInfo lists */
35
-#define ARM_CP_SENTINEL 0xfffff
36
/* Mask of only the flag bits in a type field */
37
#define ARM_CP_FLAG_MASK 0x1f0ff
38
39
@@ -XXX,XX +XXX,XX @@ enum {
40
ARM_CP_SECSTATE_NS = (1 << 1), /* bit[1]: Non-secure state register */
41
};
42
43
-/*
44
- * Return true if cptype is a valid type field. This is used to try to
45
- * catch errors where the sentinel has been accidentally left off the end
46
- * of a list of registers.
47
- */
48
-static inline bool cptype_valid(int cptype)
49
-{
50
- return ((cptype & ~ARM_CP_FLAG_MASK) == 0)
51
- || ((cptype & ARM_CP_SPECIAL) &&
52
- ((cptype & ~ARM_CP_FLAG_MASK) <= ARM_LAST_SPECIAL));
53
-}
54
-
55
/*
56
* Access rights:
57
* We define bits for Read and Write access for what rev C of the v7-AR ARM ARM
58
@@ -XXX,XX +XXX,XX @@ struct ARMCPRegInfo {
59
#define CPREG_FIELD64(env, ri) \
60
(*(uint64_t *)((char *)(env) + (ri)->fieldoffset))
61
62
-#define REGINFO_SENTINEL { .type = ARM_CP_SENTINEL }
63
+void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu, const ARMCPRegInfo *reg,
64
+ void *opaque);
65
66
-void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
67
- const ARMCPRegInfo *regs, void *opaque);
68
-void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
69
- const ARMCPRegInfo *regs, void *opaque);
70
-static inline void define_arm_cp_regs(ARMCPU *cpu, const ARMCPRegInfo *regs)
71
-{
72
- define_arm_cp_regs_with_opaque(cpu, regs, 0);
73
-}
74
static inline void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs)
75
{
76
- define_one_arm_cp_reg_with_opaque(cpu, regs, 0);
77
+ define_one_arm_cp_reg_with_opaque(cpu, regs, NULL);
78
}
34
+
79
+
35
#define ICC_CTLR_EL1_CBPR (1U << 0)
80
+void define_arm_cp_regs_with_opaque_len(ARMCPU *cpu, const ARMCPRegInfo *regs,
36
#define ICC_CTLR_EL1_EOIMODE (1U << 1)
81
+ void *opaque, size_t len);
37
#define ICC_CTLR_EL1_PMHE (1U << 6)
38
@@ -XXX,XX +XXX,XX @@ FIELD(GITS_TYPER, CIL, 36, 1)
39
40
#define L1TABLE_ENTRY_SIZE 8
41
42
+#define LPI_CTE_ENABLED TABLE_ENTRY_VALID_MASK
43
+#define LPI_PRIORITY_MASK 0xfc
44
+
82
+
45
#define GITS_CMDQ_ENTRY_SIZE 32
83
+#define define_arm_cp_regs_with_opaque(CPU, REGS, OPAQUE) \
46
#define NUM_BYTES_IN_DW 8
84
+ do { \
47
85
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(REGS) == 0); \
48
@@ -XXX,XX +XXX,XX @@ FIELD(MAPC, RDBASE, 16, 32)
86
+ define_arm_cp_regs_with_opaque_len(CPU, REGS, OPAQUE, \
49
* Valid = 1 bit,RDBase = 36 bits(considering max RDBASE)
87
+ ARRAY_SIZE(REGS)); \
50
*/
88
+ } while (0)
51
#define GITS_CTE_SIZE (0x8ULL)
89
+
52
+#define GITS_CTE_RDBASE_PROCNUM_MASK MAKE_64BIT_MASK(1, RDBASE_PROCNUM_LENGTH)
90
+#define define_arm_cp_regs(CPU, REGS) \
53
91
+ define_arm_cp_regs_with_opaque(CPU, REGS, NULL)
54
/* Special interrupt IDs */
92
+
55
#define INTID_SECURE 1020
93
const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp);
56
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
94
57
unsigned size, MemTxAttrs attrs);
95
/*
58
void gicv3_dist_set_irq(GICv3State *s, int irq, int level);
96
@@ -XXX,XX +XXX,XX @@ typedef struct ARMCPRegUserSpaceInfo {
59
void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level);
97
uint64_t fixed_bits;
60
+void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level);
98
} ARMCPRegUserSpaceInfo;
61
+void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level);
99
62
+void gicv3_redist_update_lpi(GICv3CPUState *cs);
100
-#define REGUSERINFO_SENTINEL { .name = NULL }
63
void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns);
101
+void modify_arm_cp_regs_with_len(ARMCPRegInfo *regs, size_t regs_len,
64
void gicv3_init_cpuif(GICv3State *s);
102
+ const ARMCPRegUserSpaceInfo *mods,
65
103
+ size_t mods_len);
66
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
104
105
-void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods);
106
+#define modify_arm_cp_regs(REGS, MODS) \
107
+ do { \
108
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(REGS) == 0); \
109
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(MODS) == 0); \
110
+ modify_arm_cp_regs_with_len(REGS, ARRAY_SIZE(REGS), \
111
+ MODS, ARRAY_SIZE(MODS)); \
112
+ } while (0)
113
114
/* CPWriteFn that can be used to implement writes-ignored behaviour */
115
void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
116
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
67
index XXXXXXX..XXXXXXX 100644
117
index XXXXXXX..XXXXXXX 100644
68
--- a/include/hw/intc/arm_gicv3_common.h
118
--- a/hw/arm/pxa2xx.c
69
+++ b/include/hw/intc/arm_gicv3_common.h
119
+++ b/hw/arm/pxa2xx.c
70
@@ -XXX,XX +XXX,XX @@ struct GICv3CPUState {
120
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pxa_cp_reginfo[] = {
71
* real state above; it doesn't need to be migrated.
121
{ .name = "PWRMODE", .cp = 14, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 0,
72
*/
122
.access = PL1_RW, .type = ARM_CP_IO,
73
PendingIrq hppi;
123
.readfn = arm_cp_read_zero, .writefn = pxa2xx_pwrmode_write },
74
+
124
- REGINFO_SENTINEL
75
+ /*
125
};
76
+ * Cached information recalculated from LPI tables
126
77
+ * in guest memory
127
static void pxa2xx_setup_cp14(PXA2xxState *s)
78
+ */
128
diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c
79
+ PendingIrq hpplpi;
80
+
81
/* This is temporary working state, to avoid a malloc in gicv3_update() */
82
bool seenbetter;
83
};
84
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
85
index XXXXXXX..XXXXXXX 100644
129
index XXXXXXX..XXXXXXX 100644
86
--- a/hw/intc/arm_gicv3.c
130
--- a/hw/arm/pxa2xx_pic.c
87
+++ b/hw/intc/arm_gicv3.c
131
+++ b/hw/arm/pxa2xx_pic.c
88
@@ -XXX,XX +XXX,XX @@ static void gicv3_redist_update_noirqset(GICv3CPUState *cs)
132
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pxa_pic_cp_reginfo[] = {
89
cs->hppi.grp = gicv3_irq_group(cs->gic, cs, cs->hppi.irq);
133
REGINFO_FOR_PIC_CP("ICLR2", 8),
90
}
134
REGINFO_FOR_PIC_CP("ICFP2", 9),
91
135
REGINFO_FOR_PIC_CP("ICPR2", 0xa),
92
+ if ((cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) && cs->gic->lpi_enable &&
136
- REGINFO_SENTINEL
93
+ (cs->hpplpi.prio != 0xff)) {
137
};
94
+ if (irqbetter(cs, cs->hpplpi.irq, cs->hpplpi.prio)) {
138
95
+ cs->hppi.irq = cs->hpplpi.irq;
139
static const MemoryRegionOps pxa2xx_pic_ops = {
96
+ cs->hppi.prio = cs->hpplpi.prio;
97
+ cs->hppi.grp = cs->hpplpi.grp;
98
+ seenbetter = true;
99
+ }
100
+ }
101
+
102
/* If the best interrupt we just found would preempt whatever
103
* was the previous best interrupt before this update, then
104
* we know it's definitely the best one now.
105
@@ -XXX,XX +XXX,XX @@ static void gicv3_set_irq(void *opaque, int irq, int level)
106
107
static void arm_gicv3_post_load(GICv3State *s)
108
{
109
+ int i;
110
/* Recalculate our cached idea of the current highest priority
111
* pending interrupt, but don't set IRQ or FIQ lines.
112
*/
113
+ for (i = 0; i < s->num_cpu; i++) {
114
+ gicv3_redist_update_lpi(&s->cpu[i]);
115
+ }
116
gicv3_full_update_noirqset(s);
117
/* Repopulate the cache of GICv3CPUState pointers for target CPUs */
118
gicv3_cache_all_target_cpustates(s);
119
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
120
index XXXXXXX..XXXXXXX 100644
121
--- a/hw/intc/arm_gicv3_common.c
122
+++ b/hw/intc/arm_gicv3_common.c
123
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_common_reset(DeviceState *dev)
124
memset(cs->gicr_ipriorityr, 0, sizeof(cs->gicr_ipriorityr));
125
126
cs->hppi.prio = 0xff;
127
+ cs->hpplpi.prio = 0xff;
128
129
/* State in the CPU interface must *not* be reset here, because it
130
* is part of the CPU's reset domain, not the GIC device's.
131
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
140
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
132
index XXXXXXX..XXXXXXX 100644
141
index XXXXXXX..XXXXXXX 100644
133
--- a/hw/intc/arm_gicv3_cpuif.c
142
--- a/hw/intc/arm_gicv3_cpuif.c
134
+++ b/hw/intc/arm_gicv3_cpuif.c
143
+++ b/hw/intc/arm_gicv3_cpuif.c
135
@@ -XXX,XX +XXX,XX @@ static void icc_activate_irq(GICv3CPUState *cs, int irq)
144
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
136
cs->gicr_iactiver0 = deposit32(cs->gicr_iactiver0, irq, 1, 1);
145
.readfn = icc_igrpen1_el3_read,
137
cs->gicr_ipendr0 = deposit32(cs->gicr_ipendr0, irq, 1, 0);
146
.writefn = icc_igrpen1_el3_write,
138
gicv3_redist_update(cs);
147
},
139
- } else {
148
- REGINFO_SENTINEL
140
+ } else if (irq < GICV3_LPI_INTID_START) {
149
};
141
gicv3_gicd_active_set(cs->gic, irq);
150
142
gicv3_gicd_pending_clear(cs->gic, irq);
151
static uint64_t ich_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
143
gicv3_update(cs->gic, irq, 1);
152
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_hcr_reginfo[] = {
144
+ } else {
153
.readfn = ich_vmcr_read,
145
+ gicv3_redist_lpi_pending(cs, irq, 0);
154
.writefn = ich_vmcr_write,
155
},
156
- REGINFO_SENTINEL
157
};
158
159
static const ARMCPRegInfo gicv3_cpuif_ich_apxr1_reginfo[] = {
160
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_ich_apxr1_reginfo[] = {
161
.readfn = ich_ap_read,
162
.writefn = ich_ap_write,
163
},
164
- REGINFO_SENTINEL
165
};
166
167
static const ARMCPRegInfo gicv3_cpuif_ich_apxr23_reginfo[] = {
168
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_ich_apxr23_reginfo[] = {
169
.readfn = ich_ap_read,
170
.writefn = ich_ap_write,
171
},
172
- REGINFO_SENTINEL
173
};
174
175
static void gicv3_cpuif_el_change_hook(ARMCPU *cpu, void *opaque)
176
@@ -XXX,XX +XXX,XX @@ void gicv3_init_cpuif(GICv3State *s)
177
.readfn = ich_lr_read,
178
.writefn = ich_lr_write,
179
},
180
- REGINFO_SENTINEL
181
};
182
define_arm_cp_regs(cpu, lr_regset);
183
}
184
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
185
index XXXXXXX..XXXXXXX 100644
186
--- a/hw/intc/arm_gicv3_kvm.c
187
+++ b/hw/intc/arm_gicv3_kvm.c
188
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
189
*/
190
.resetfn = arm_gicv3_icc_reset,
191
},
192
- REGINFO_SENTINEL
193
};
194
195
/**
196
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
197
index XXXXXXX..XXXXXXX 100644
198
--- a/target/arm/cpu64.c
199
+++ b/target/arm/cpu64.c
200
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = {
201
{ .name = "L2MERRSR",
202
.cp = 15, .opc1 = 3, .crm = 15,
203
.access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
204
- REGINFO_SENTINEL
205
};
206
207
static void aarch64_a57_initfn(Object *obj)
208
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
209
index XXXXXXX..XXXXXXX 100644
210
--- a/target/arm/cpu_tcg.c
211
+++ b/target/arm/cpu_tcg.c
212
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cortexa8_cp_reginfo[] = {
213
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
214
{ .name = "L2AUXCR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2,
215
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
216
- REGINFO_SENTINEL
217
};
218
219
static void cortex_a8_initfn(Object *obj)
220
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cortexa9_cp_reginfo[] = {
221
.access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
222
{ .name = "TLB_ATTR", .cp = 15, .crn = 15, .crm = 7, .opc1 = 5, .opc2 = 2,
223
.access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
224
- REGINFO_SENTINEL
225
};
226
227
static void cortex_a9_initfn(Object *obj)
228
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cortexa15_cp_reginfo[] = {
229
#endif
230
{ .name = "L2ECTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 3,
231
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
232
- REGINFO_SENTINEL
233
};
234
235
static void cortex_a7_initfn(Object *obj)
236
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cortexr5_cp_reginfo[] = {
237
.access = PL1_RW, .type = ARM_CP_CONST },
238
{ .name = "DCACHE_INVAL", .cp = 15, .opc1 = 0, .crn = 15, .crm = 5,
239
.opc2 = 0, .access = PL1_W, .type = ARM_CP_NOP },
240
- REGINFO_SENTINEL
241
};
242
243
static void cortex_r5_initfn(Object *obj)
244
diff --git a/target/arm/helper.c b/target/arm/helper.c
245
index XXXXXXX..XXXXXXX 100644
246
--- a/target/arm/helper.c
247
+++ b/target/arm/helper.c
248
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cp_reginfo[] = {
249
.secure = ARM_CP_SECSTATE_S,
250
.fieldoffset = offsetof(CPUARMState, cp15.contextidr_s),
251
.resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
252
- REGINFO_SENTINEL
253
};
254
255
static const ARMCPRegInfo not_v8_cp_reginfo[] = {
256
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v8_cp_reginfo[] = {
257
{ .name = "CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY,
258
.opc1 = 0, .opc2 = CP_ANY, .access = PL1_W,
259
.type = ARM_CP_NOP | ARM_CP_OVERRIDE },
260
- REGINFO_SENTINEL
261
};
262
263
static const ARMCPRegInfo not_v6_cp_reginfo[] = {
264
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v6_cp_reginfo[] = {
265
*/
266
{ .name = "WFI_v5", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = 2,
267
.access = PL1_W, .type = ARM_CP_WFI },
268
- REGINFO_SENTINEL
269
};
270
271
static const ARMCPRegInfo not_v7_cp_reginfo[] = {
272
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v7_cp_reginfo[] = {
273
.opc1 = 0, .opc2 = 0, .access = PL1_RW, .type = ARM_CP_NOP },
274
{ .name = "NMRR", .cp = 15, .crn = 10, .crm = 2,
275
.opc1 = 0, .opc2 = 1, .access = PL1_RW, .type = ARM_CP_NOP },
276
- REGINFO_SENTINEL
277
};
278
279
static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
280
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
281
.crn = 1, .crm = 0, .opc1 = 0, .opc2 = 2, .accessfn = cpacr_access,
282
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.cpacr_el1),
283
.resetfn = cpacr_reset, .writefn = cpacr_write, .readfn = cpacr_read },
284
- REGINFO_SENTINEL
285
};
286
287
typedef struct pm_event {
288
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
289
{ .name = "TLBIMVAA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3,
290
.type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
291
.writefn = tlbimvaa_write },
292
- REGINFO_SENTINEL
293
};
294
295
static const ARMCPRegInfo v7mp_cp_reginfo[] = {
296
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7mp_cp_reginfo[] = {
297
{ .name = "TLBIMVAAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3,
298
.type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
299
.writefn = tlbimvaa_is_write },
300
- REGINFO_SENTINEL
301
};
302
303
static const ARMCPRegInfo pmovsset_cp_reginfo[] = {
304
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmovsset_cp_reginfo[] = {
305
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
306
.writefn = pmovsset_write,
307
.raw_writefn = raw_write },
308
- REGINFO_SENTINEL
309
};
310
311
static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri,
312
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo t2ee_cp_reginfo[] = {
313
{ .name = "TEEHBR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 6, .opc2 = 0,
314
.access = PL0_RW, .fieldoffset = offsetof(CPUARMState, teehbr),
315
.accessfn = teehbr_access, .resetvalue = 0 },
316
- REGINFO_SENTINEL
317
};
318
319
static const ARMCPRegInfo v6k_cp_reginfo[] = {
320
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
321
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrprw_s),
322
offsetoflow32(CPUARMState, cp15.tpidrprw_ns) },
323
.resetvalue = 0 },
324
- REGINFO_SENTINEL
325
};
326
327
#ifndef CONFIG_USER_ONLY
328
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
329
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_SEC].cval),
330
.writefn = gt_sec_cval_write, .raw_writefn = raw_write,
331
},
332
- REGINFO_SENTINEL
333
};
334
335
static CPAccessResult e2h_access(CPUARMState *env, const ARMCPRegInfo *ri,
336
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
337
.access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO,
338
.readfn = gt_virt_cnt_read,
339
},
340
- REGINFO_SENTINEL
341
};
342
343
#endif
344
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vapa_cp_reginfo[] = {
345
.access = PL1_W, .accessfn = ats_access,
346
.writefn = ats_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC },
347
#endif
348
- REGINFO_SENTINEL
349
};
350
351
/* Return basic MPU access permission bits. */
352
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmsav7_cp_reginfo[] = {
353
.fieldoffset = offsetof(CPUARMState, pmsav7.rnr[M_REG_NS]),
354
.writefn = pmsav7_rgnr_write,
355
.resetfn = arm_cp_reset_ignore },
356
- REGINFO_SENTINEL
357
};
358
359
static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
360
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
361
{ .name = "946_PRBS7", .cp = 15, .crn = 6, .crm = 7, .opc1 = 0,
362
.opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
363
.fieldoffset = offsetof(CPUARMState, cp15.c6_region[7]) },
364
- REGINFO_SENTINEL
365
};
366
367
static void vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
368
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_pmsa_cp_reginfo[] = {
369
.access = PL1_RW, .accessfn = access_tvm_trvm,
370
.fieldoffset = offsetof(CPUARMState, cp15.far_el[1]),
371
.resetvalue = 0, },
372
- REGINFO_SENTINEL
373
};
374
375
static const ARMCPRegInfo vmsa_cp_reginfo[] = {
376
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
377
/* No offsetoflow32 -- pass the entire TCR to writefn/raw_writefn. */
378
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.tcr_el[3]),
379
offsetof(CPUARMState, cp15.tcr_el[1])} },
380
- REGINFO_SENTINEL
381
};
382
383
/* Note that unlike TTBCR, writing to TTBCR2 does not require flushing
384
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo omap_cp_reginfo[] = {
385
{ .name = "C9", .cp = 15, .crn = 9,
386
.crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW,
387
.type = ARM_CP_CONST | ARM_CP_OVERRIDE, .resetvalue = 0 },
388
- REGINFO_SENTINEL
389
};
390
391
static void xscale_cpar_write(CPUARMState *env, const ARMCPRegInfo *ri,
392
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo xscale_cp_reginfo[] = {
393
{ .name = "XSCALE_UNLOCK_DCACHE",
394
.cp = 15, .opc1 = 0, .crn = 9, .crm = 2, .opc2 = 1,
395
.access = PL1_W, .type = ARM_CP_NOP },
396
- REGINFO_SENTINEL
397
};
398
399
static const ARMCPRegInfo dummy_c15_cp_reginfo[] = {
400
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo dummy_c15_cp_reginfo[] = {
401
.access = PL1_RW,
402
.type = ARM_CP_CONST | ARM_CP_NO_RAW | ARM_CP_OVERRIDE,
403
.resetvalue = 0 },
404
- REGINFO_SENTINEL
405
};
406
407
static const ARMCPRegInfo cache_dirty_status_cp_reginfo[] = {
408
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cache_dirty_status_cp_reginfo[] = {
409
{ .name = "CDSR", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 6,
410
.access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
411
.resetvalue = 0 },
412
- REGINFO_SENTINEL
413
};
414
415
static const ARMCPRegInfo cache_block_ops_cp_reginfo[] = {
416
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cache_block_ops_cp_reginfo[] = {
417
.access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
418
{ .name = "CIDCR", .cp = 15, .crm = 14, .opc1 = 0,
419
.access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
420
- REGINFO_SENTINEL
421
};
422
423
static const ARMCPRegInfo cache_test_clean_cp_reginfo[] = {
424
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cache_test_clean_cp_reginfo[] = {
425
{ .name = "TCI_DCACHE", .cp = 15, .crn = 7, .crm = 14, .opc1 = 0, .opc2 = 3,
426
.access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
427
.resetvalue = (1 << 30) },
428
- REGINFO_SENTINEL
429
};
430
431
static const ARMCPRegInfo strongarm_cp_reginfo[] = {
432
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo strongarm_cp_reginfo[] = {
433
.crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY,
434
.access = PL1_RW, .resetvalue = 0,
435
.type = ARM_CP_CONST | ARM_CP_OVERRIDE | ARM_CP_NO_RAW },
436
- REGINFO_SENTINEL
437
};
438
439
static uint64_t midr_read(CPUARMState *env, const ARMCPRegInfo *ri)
440
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
441
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
442
offsetof(CPUARMState, cp15.ttbr1_ns) },
443
.writefn = vmsa_ttbr_write, },
444
- REGINFO_SENTINEL
445
};
446
447
static uint64_t aa64_fpcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
448
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
449
.access = PL1_RW, .accessfn = access_trap_aa32s_el1,
450
.writefn = sdcr_write,
451
.fieldoffset = offsetoflow32(CPUARMState, cp15.mdcr_el3) },
452
- REGINFO_SENTINEL
453
};
454
455
/* Used to describe the behaviour of EL2 regs when EL2 does not exist. */
456
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
457
.type = ARM_CP_CONST,
458
.cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 2,
459
.access = PL2_RW, .resetvalue = 0 },
460
- REGINFO_SENTINEL
461
};
462
463
/* Ditto, but for registers which exist in ARMv8 but not v7 */
464
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_no_el2_v8_cp_reginfo[] = {
465
.cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4,
466
.access = PL2_RW,
467
.type = ARM_CP_CONST, .resetvalue = 0 },
468
- REGINFO_SENTINEL
469
};
470
471
static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
472
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
473
.cp = 15, .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 3,
474
.access = PL2_RW,
475
.fieldoffset = offsetof(CPUARMState, cp15.hstr_el2) },
476
- REGINFO_SENTINEL
477
};
478
479
static const ARMCPRegInfo el2_v8_cp_reginfo[] = {
480
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_v8_cp_reginfo[] = {
481
.access = PL2_RW,
482
.fieldoffset = offsetofhigh32(CPUARMState, cp15.hcr_el2),
483
.writefn = hcr_writehigh },
484
- REGINFO_SENTINEL
485
};
486
487
static CPAccessResult sel2_access(CPUARMState *env, const ARMCPRegInfo *ri,
488
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_sec_cp_reginfo[] = {
489
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 6, .opc2 = 2,
490
.access = PL2_RW, .accessfn = sel2_access,
491
.fieldoffset = offsetof(CPUARMState, cp15.vstcr_el2) },
492
- REGINFO_SENTINEL
493
};
494
495
static CPAccessResult nsacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
496
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
497
.opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 5,
498
.access = PL3_W, .type = ARM_CP_NO_RAW,
499
.writefn = tlbi_aa64_vae3_write },
500
- REGINFO_SENTINEL
501
};
502
503
#ifndef CONFIG_USER_ONLY
504
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
505
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
506
.access = PL1_RW, .accessfn = access_tda,
507
.type = ARM_CP_NOP },
508
- REGINFO_SENTINEL
509
};
510
511
static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
512
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
513
.access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
514
{ .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0,
515
.access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
516
- REGINFO_SENTINEL
517
};
518
519
/* Return the exception level to which exceptions should be taken
520
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
521
.fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]),
522
.writefn = dbgbcr_write, .raw_writefn = raw_write
523
},
524
- REGINFO_SENTINEL
525
};
526
define_arm_cp_regs(cpu, dbgregs);
527
}
528
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
529
.fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]),
530
.writefn = dbgwcr_write, .raw_writefn = raw_write
531
},
532
- REGINFO_SENTINEL
533
};
534
define_arm_cp_regs(cpu, dbgregs);
535
}
536
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
537
.type = ARM_CP_IO,
538
.readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
539
.raw_writefn = pmevtyper_rawwrite },
540
- REGINFO_SENTINEL
541
};
542
define_arm_cp_regs(cpu, pmev_regs);
543
g_free(pmevcntr_name);
544
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
545
.cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5,
546
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
547
.resetvalue = extract64(cpu->pmceid1, 32, 32) },
548
- REGINFO_SENTINEL
549
};
550
define_arm_cp_regs(cpu, v81_pmu_regs);
551
}
552
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lor_reginfo[] = {
553
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7,
554
.access = PL1_R, .accessfn = access_lor_ns,
555
.type = ARM_CP_CONST, .resetvalue = 0 },
556
- REGINFO_SENTINEL
557
};
558
559
#ifdef TARGET_AARCH64
560
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pauth_reginfo[] = {
561
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 3,
562
.access = PL1_RW, .accessfn = access_pauth,
563
.fieldoffset = offsetof(CPUARMState, keys.apib.hi) },
564
- REGINFO_SENTINEL
565
};
566
567
static const ARMCPRegInfo tlbirange_reginfo[] = {
568
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbirange_reginfo[] = {
569
.opc0 = 1, .opc1 = 6, .crn = 8, .crm = 6, .opc2 = 5,
570
.access = PL3_W, .type = ARM_CP_NO_RAW,
571
.writefn = tlbi_aa64_rvae3_write },
572
- REGINFO_SENTINEL
573
};
574
575
static const ARMCPRegInfo tlbios_reginfo[] = {
576
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbios_reginfo[] = {
577
.opc0 = 1, .opc1 = 6, .crn = 8, .crm = 1, .opc2 = 5,
578
.access = PL3_W, .type = ARM_CP_NO_RAW,
579
.writefn = tlbi_aa64_vae3is_write },
580
- REGINFO_SENTINEL
581
};
582
583
static uint64_t rndr_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
584
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo rndr_reginfo[] = {
585
.type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END | ARM_CP_IO,
586
.opc0 = 3, .opc1 = 3, .crn = 2, .crm = 4, .opc2 = 1,
587
.access = PL0_R, .readfn = rndr_readfn },
588
- REGINFO_SENTINEL
589
};
590
591
#ifndef CONFIG_USER_ONLY
592
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo dcpop_reg[] = {
593
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 1,
594
.access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
595
.accessfn = aa64_cacheop_poc_access, .writefn = dccvap_writefn },
596
- REGINFO_SENTINEL
597
};
598
599
static const ARMCPRegInfo dcpodp_reg[] = {
600
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo dcpodp_reg[] = {
601
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 1,
602
.access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
603
.accessfn = aa64_cacheop_poc_access, .writefn = dccvap_writefn },
604
- REGINFO_SENTINEL
605
};
606
#endif /*CONFIG_USER_ONLY*/
607
608
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_reginfo[] = {
609
{ .name = "DC_CIGDSW", .state = ARM_CP_STATE_AA64,
610
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 6,
611
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
612
- REGINFO_SENTINEL
613
};
614
615
static const ARMCPRegInfo mte_tco_ro_reginfo[] = {
616
{ .name = "TCO", .state = ARM_CP_STATE_AA64,
617
.opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 7,
618
.type = ARM_CP_CONST, .access = PL0_RW, },
619
- REGINFO_SENTINEL
620
};
621
622
static const ARMCPRegInfo mte_el0_cacheop_reginfo[] = {
623
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_el0_cacheop_reginfo[] = {
624
.accessfn = aa64_zva_access,
625
#endif
626
},
627
- REGINFO_SENTINEL
628
};
629
630
#endif
631
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo predinv_reginfo[] = {
632
{ .name = "CPPRCTX", .state = ARM_CP_STATE_AA32,
633
.cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 7,
634
.type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
635
- REGINFO_SENTINEL
636
};
637
638
static uint64_t ccsidr2_read(CPUARMState *env, const ARMCPRegInfo *ri)
639
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo ccsidr2_reginfo[] = {
640
.access = PL1_R,
641
.accessfn = access_aa64_tid2,
642
.readfn = ccsidr2_read, .type = ARM_CP_NO_RAW },
643
- REGINFO_SENTINEL
644
};
645
646
static CPAccessResult access_aa64_tid3(CPUARMState *env, const ARMCPRegInfo *ri,
647
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo jazelle_regs[] = {
648
.cp = 14, .crn = 2, .crm = 0, .opc1 = 7, .opc2 = 0,
649
.accessfn = access_joscr_jmcr,
650
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
651
- REGINFO_SENTINEL
652
};
653
654
static const ARMCPRegInfo vhe_reginfo[] = {
655
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vhe_reginfo[] = {
656
.access = PL2_RW, .accessfn = e2h_access,
657
.writefn = gt_virt_cval_write, .raw_writefn = raw_write },
658
#endif
659
- REGINFO_SENTINEL
660
};
661
662
#ifndef CONFIG_USER_ONLY
663
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo ats1e1_reginfo[] = {
664
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1,
665
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
666
.writefn = ats_write64 },
667
- REGINFO_SENTINEL
668
};
669
670
static const ARMCPRegInfo ats1cp_reginfo[] = {
671
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo ats1cp_reginfo[] = {
672
.cp = 15, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1,
673
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
674
.writefn = ats_write },
675
- REGINFO_SENTINEL
676
};
677
#endif
678
679
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo actlr2_hactlr2_reginfo[] = {
680
.cp = 15, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 3,
681
.access = PL2_RW, .type = ARM_CP_CONST,
682
.resetvalue = 0 },
683
- REGINFO_SENTINEL
684
};
685
686
void register_cp_regs_for_features(ARMCPU *cpu)
687
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
688
.access = PL1_R, .type = ARM_CP_CONST,
689
.accessfn = access_aa32_tid3,
690
.resetvalue = cpu->isar.id_isar6 },
691
- REGINFO_SENTINEL
692
};
693
define_arm_cp_regs(cpu, v6_idregs);
694
define_arm_cp_regs(cpu, v6_cp_reginfo);
695
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
696
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 7,
697
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
698
.resetvalue = cpu->pmceid1 },
699
- REGINFO_SENTINEL
700
};
701
#ifdef CONFIG_USER_ONLY
702
ARMCPRegUserSpaceInfo v8_user_idregs[] = {
703
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
704
.exported_bits = 0x000000f0ffffffff },
705
{ .name = "ID_AA64ISAR*_EL1_RESERVED",
706
.is_glob = true },
707
- REGUSERINFO_SENTINEL
708
};
709
modify_arm_cp_regs(v8_idregs, v8_user_idregs);
710
#endif
711
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
712
.access = PL2_RW,
713
.resetvalue = vmpidr_def,
714
.fieldoffset = offsetof(CPUARMState, cp15.vmpidr_el2) },
715
- REGINFO_SENTINEL
716
};
717
define_arm_cp_regs(cpu, vpidr_regs);
718
define_arm_cp_regs(cpu, el2_cp_reginfo);
719
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
720
.access = PL2_RW, .accessfn = access_el3_aa32ns,
721
.type = ARM_CP_NO_RAW,
722
.writefn = arm_cp_write_ignore, .readfn = mpidr_read },
723
- REGINFO_SENTINEL
724
};
725
define_arm_cp_regs(cpu, vpidr_regs);
726
define_arm_cp_regs(cpu, el3_no_el2_cp_reginfo);
727
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
728
.raw_writefn = raw_write, .writefn = sctlr_write,
729
.fieldoffset = offsetof(CPUARMState, cp15.sctlr_el[3]),
730
.resetvalue = cpu->reset_sctlr },
731
- REGINFO_SENTINEL
732
};
733
734
define_arm_cp_regs(cpu, el3_regs);
735
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
736
{ .name = "DUMMY",
737
.cp = 15, .crn = 0, .crm = 7, .opc1 = 0, .opc2 = CP_ANY,
738
.access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
739
- REGINFO_SENTINEL
740
};
741
ARMCPRegInfo id_v8_midr_cp_reginfo[] = {
742
{ .name = "MIDR_EL1", .state = ARM_CP_STATE_BOTH,
743
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
744
.access = PL1_R,
745
.accessfn = access_aa64_tid1,
746
.type = ARM_CP_CONST, .resetvalue = cpu->revidr },
747
- REGINFO_SENTINEL
748
};
749
ARMCPRegInfo id_cp_reginfo[] = {
750
/* These are common to v8 and pre-v8 */
751
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
752
.access = PL1_R,
753
.accessfn = access_aa32_tid1,
754
.type = ARM_CP_CONST, .resetvalue = 0 },
755
- REGINFO_SENTINEL
756
};
757
/* TLBTR is specific to VMSA */
758
ARMCPRegInfo id_tlbtr_reginfo = {
759
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
760
{ .name = "MIDR_EL1",
761
.exported_bits = 0x00000000ffffffff },
762
{ .name = "REVIDR_EL1" },
763
- REGUSERINFO_SENTINEL
764
};
765
modify_arm_cp_regs(id_v8_midr_cp_reginfo, id_v8_user_midr_cp_reginfo);
766
#endif
767
if (arm_feature(env, ARM_FEATURE_OMAPCP) ||
768
arm_feature(env, ARM_FEATURE_STRONGARM)) {
769
- ARMCPRegInfo *r;
770
+ size_t i;
771
/* Register the blanket "writes ignored" value first to cover the
772
* whole space. Then update the specific ID registers to allow write
773
* access, so that they ignore writes rather than causing them to
774
* UNDEF.
775
*/
776
define_one_arm_cp_reg(cpu, &crn0_wi_reginfo);
777
- for (r = id_pre_v8_midr_cp_reginfo;
778
- r->type != ARM_CP_SENTINEL; r++) {
779
- r->access = PL1_RW;
780
+ for (i = 0; i < ARRAY_SIZE(id_pre_v8_midr_cp_reginfo); ++i) {
781
+ id_pre_v8_midr_cp_reginfo[i].access = PL1_RW;
782
}
783
- for (r = id_cp_reginfo; r->type != ARM_CP_SENTINEL; r++) {
784
- r->access = PL1_RW;
785
+ for (i = 0; i < ARRAY_SIZE(id_cp_reginfo); ++i) {
786
+ id_cp_reginfo[i].access = PL1_RW;
787
}
788
id_mpuir_reginfo.access = PL1_RW;
789
id_tlbtr_reginfo.access = PL1_RW;
790
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
791
{ .name = "MPIDR_EL1", .state = ARM_CP_STATE_BOTH,
792
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 5,
793
.access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_RAW },
794
- REGINFO_SENTINEL
795
};
796
#ifdef CONFIG_USER_ONLY
797
ARMCPRegUserSpaceInfo mpidr_user_cp_reginfo[] = {
798
{ .name = "MPIDR_EL1",
799
.fixed_bits = 0x0000000080000000 },
800
- REGUSERINFO_SENTINEL
801
};
802
modify_arm_cp_regs(mpidr_cp_reginfo, mpidr_user_cp_reginfo);
803
#endif
804
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
805
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 0, .opc2 = 1,
806
.access = PL3_RW, .type = ARM_CP_CONST,
807
.resetvalue = 0 },
808
- REGINFO_SENTINEL
809
};
810
define_arm_cp_regs(cpu, auxcr_reginfo);
811
if (cpu_isar_feature(aa32_ac2, cpu)) {
812
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
813
.type = ARM_CP_CONST,
814
.opc0 = 3, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 0,
815
.access = PL1_R, .resetvalue = cpu->reset_cbar },
816
- REGINFO_SENTINEL
817
};
818
/* We don't implement a r/w 64 bit CBAR currently */
819
assert(arm_feature(env, ARM_FEATURE_CBAR_RO));
820
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
821
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s),
822
offsetof(CPUARMState, cp15.vbar_ns) },
823
.resetvalue = 0 },
824
- REGINFO_SENTINEL
825
};
826
define_arm_cp_regs(cpu, vbar_cp_reginfo);
827
}
828
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
829
r->writefn);
830
}
831
}
832
- /* Bad type field probably means missing sentinel at end of reg list */
833
- assert(cptype_valid(r->type));
834
+
835
for (crm = crmmin; crm <= crmmax; crm++) {
836
for (opc1 = opc1min; opc1 <= opc1max; opc1++) {
837
for (opc2 = opc2min; opc2 <= opc2max; opc2++) {
838
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
146
}
839
}
147
}
840
}
148
841
149
@@ -XXX,XX +XXX,XX @@ static void icc_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri,
842
-void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
150
trace_gicv3_icc_eoir_write(is_eoir0 ? 0 : 1,
843
- const ARMCPRegInfo *regs, void *opaque)
151
gicv3_redist_affid(cs), value);
844
+/* Define a whole list of registers */
152
845
+void define_arm_cp_regs_with_opaque_len(ARMCPU *cpu, const ARMCPRegInfo *regs,
153
- if (irq >= cs->gic->num_irq) {
846
+ void *opaque, size_t len)
154
+ if ((irq >= cs->gic->num_irq) &&
847
{
155
+ !(cs->gic->lpi_enable && (irq >= GICV3_LPI_INTID_START))) {
848
- /* Define a whole list of registers */
156
/* This handles two cases:
849
- const ARMCPRegInfo *r;
157
* 1. If software writes the ID of a spurious interrupt [ie 1020-1023]
850
- for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
158
* to the GICC_EOIR, the GIC ignores that write.
851
- define_one_arm_cp_reg_with_opaque(cpu, r, opaque);
159
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
852
+ size_t i;
160
index XXXXXXX..XXXXXXX 100644
853
+ for (i = 0; i < len; ++i) {
161
--- a/hw/intc/arm_gicv3_its.c
854
+ define_one_arm_cp_reg_with_opaque(cpu, regs + i, opaque);
162
+++ b/hw/intc/arm_gicv3_its.c
855
}
163
@@ -XXX,XX +XXX,XX @@ static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset,
856
}
164
uint64_t cte = 0;
857
165
bool cte_valid = false;
858
@@ -XXX,XX +XXX,XX @@ void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
166
bool result = false;
859
* user-space cannot alter any values and dynamic values pertaining to
167
+ uint64_t rdbase;
860
* execution state are hidden from user space view anyway.
168
861
*/
169
if (cmd == NONE) {
862
-void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods)
170
devid = offset;
863
+void modify_arm_cp_regs_with_len(ARMCPRegInfo *regs, size_t regs_len,
171
@@ -XXX,XX +XXX,XX @@ static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset,
864
+ const ARMCPRegUserSpaceInfo *mods,
172
* Current implementation only supports rdbase == procnum
865
+ size_t mods_len)
173
* Hence rdbase physical address is ignored
866
{
174
*/
867
- const ARMCPRegUserSpaceInfo *m;
175
+ rdbase = (cte & GITS_CTE_RDBASE_PROCNUM_MASK) >> 1U;
868
- ARMCPRegInfo *r;
869
-
870
- for (m = mods; m->name; m++) {
871
+ for (size_t mi = 0; mi < mods_len; ++mi) {
872
+ const ARMCPRegUserSpaceInfo *m = mods + mi;
873
GPatternSpec *pat = NULL;
176
+
874
+
177
+ if (rdbase > s->gicv3->num_cpu) {
875
if (m->is_glob) {
178
+ return result;
876
pat = g_pattern_spec_new(m->name);
179
+ }
877
}
878
- for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
879
+ for (size_t ri = 0; ri < regs_len; ++ri) {
880
+ ARMCPRegInfo *r = regs + ri;
180
+
881
+
181
+ if ((cmd == CLEAR) || (cmd == DISCARD)) {
882
if (pat && g_pattern_match_string(pat, r->name)) {
182
+ gicv3_redist_process_lpi(&s->gicv3->cpu[rdbase], pIntid, 0);
883
r->type = ARM_CP_CONST;
183
+ } else {
884
r->access = PL0U_R;
184
+ gicv3_redist_process_lpi(&s->gicv3->cpu[rdbase], pIntid, 1);
185
+ }
186
+
187
if (cmd == DISCARD) {
188
IteEntry ite = {};
189
/* remove mapping from interrupt translation table */
190
@@ -XXX,XX +XXX,XX @@ static void process_cmdq(GICv3ITSState *s)
191
MemTxResult res = MEMTX_OK;
192
bool result = true;
193
uint8_t cmd;
194
+ int i;
195
196
if (!(s->ctlr & ITS_CTLR_ENABLED)) {
197
return;
198
@@ -XXX,XX +XXX,XX @@ static void process_cmdq(GICv3ITSState *s)
199
break;
200
case GITS_CMD_INV:
201
case GITS_CMD_INVALL:
202
+ /*
203
+ * Current implementation doesn't cache any ITS tables,
204
+ * but the calculated lpi priority information. We only
205
+ * need to trigger lpi priority re-calculation to be in
206
+ * sync with LPI config table or pending table changes.
207
+ */
208
+ for (i = 0; i < s->gicv3->num_cpu; i++) {
209
+ gicv3_redist_update_lpi(&s->gicv3->cpu[i]);
210
+ }
211
break;
212
default:
213
break;
214
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
215
index XXXXXXX..XXXXXXX 100644
216
--- a/hw/intc/arm_gicv3_redist.c
217
+++ b/hw/intc/arm_gicv3_redist.c
218
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicr_writel(GICv3CPUState *cs, hwaddr offset,
219
if (cs->gicr_typer & GICR_TYPER_PLPIS) {
220
if (value & GICR_CTLR_ENABLE_LPIS) {
221
cs->gicr_ctlr |= GICR_CTLR_ENABLE_LPIS;
222
+ /* Check for any pending interr in pending table */
223
+ gicv3_redist_update_lpi(cs);
224
+ gicv3_redist_update(cs);
225
} else {
226
cs->gicr_ctlr &= ~GICR_CTLR_ENABLE_LPIS;
227
}
228
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
229
return r;
230
}
231
232
+static void gicv3_redist_check_lpi_priority(GICv3CPUState *cs, int irq)
233
+{
234
+ AddressSpace *as = &cs->gic->dma_as;
235
+ uint64_t lpict_baddr;
236
+ uint8_t lpite;
237
+ uint8_t prio;
238
+
239
+ lpict_baddr = cs->gicr_propbaser & R_GICR_PROPBASER_PHYADDR_MASK;
240
+
241
+ address_space_read(as, lpict_baddr + ((irq - GICV3_LPI_INTID_START) *
242
+ sizeof(lpite)), MEMTXATTRS_UNSPECIFIED, &lpite,
243
+ sizeof(lpite));
244
+
245
+ if (!(lpite & LPI_CTE_ENABLED)) {
246
+ return;
247
+ }
248
+
249
+ if (cs->gic->gicd_ctlr & GICD_CTLR_DS) {
250
+ prio = lpite & LPI_PRIORITY_MASK;
251
+ } else {
252
+ prio = ((lpite & LPI_PRIORITY_MASK) >> 1) | 0x80;
253
+ }
254
+
255
+ if ((prio < cs->hpplpi.prio) ||
256
+ ((prio == cs->hpplpi.prio) && (irq <= cs->hpplpi.irq))) {
257
+ cs->hpplpi.irq = irq;
258
+ cs->hpplpi.prio = prio;
259
+ /* LPIs are always non-secure Grp1 interrupts */
260
+ cs->hpplpi.grp = GICV3_G1NS;
261
+ }
262
+}
263
+
264
+void gicv3_redist_update_lpi(GICv3CPUState *cs)
265
+{
266
+ /*
267
+ * This function scans the LPI pending table and for each pending
268
+ * LPI, reads the corresponding entry from LPI configuration table
269
+ * to extract the priority info and determine if the current LPI
270
+ * priority is lower than the last computed high priority lpi interrupt.
271
+ * If yes, replace current LPI as the new high priority lpi interrupt.
272
+ */
273
+ AddressSpace *as = &cs->gic->dma_as;
274
+ uint64_t lpipt_baddr;
275
+ uint32_t pendt_size = 0;
276
+ uint8_t pend;
277
+ int i, bit;
278
+ uint64_t idbits;
279
+
280
+ idbits = MIN(FIELD_EX64(cs->gicr_propbaser, GICR_PROPBASER, IDBITS),
281
+ GICD_TYPER_IDBITS);
282
+
283
+ if (!(cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) || !cs->gicr_propbaser ||
284
+ !cs->gicr_pendbaser) {
285
+ return;
286
+ }
287
+
288
+ cs->hpplpi.prio = 0xff;
289
+
290
+ lpipt_baddr = cs->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;
291
+
292
+ /* Determine the highest priority pending interrupt among LPIs */
293
+ pendt_size = (1ULL << (idbits + 1));
294
+
295
+ for (i = GICV3_LPI_INTID_START / 8; i < pendt_size / 8; i++) {
296
+ address_space_read(as, lpipt_baddr + i, MEMTXATTRS_UNSPECIFIED, &pend,
297
+ sizeof(pend));
298
+
299
+ while (pend) {
300
+ bit = ctz32(pend);
301
+ gicv3_redist_check_lpi_priority(cs, i * 8 + bit);
302
+ pend &= ~(1 << bit);
303
+ }
304
+ }
305
+}
306
+
307
+void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level)
308
+{
309
+ /*
310
+ * This function updates the pending bit in lpi pending table for
311
+ * the irq being activated or deactivated.
312
+ */
313
+ AddressSpace *as = &cs->gic->dma_as;
314
+ uint64_t lpipt_baddr;
315
+ bool ispend = false;
316
+ uint8_t pend;
317
+
318
+ /*
319
+ * get the bit value corresponding to this irq in the
320
+ * lpi pending table
321
+ */
322
+ lpipt_baddr = cs->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;
323
+
324
+ address_space_read(as, lpipt_baddr + ((irq / 8) * sizeof(pend)),
325
+ MEMTXATTRS_UNSPECIFIED, &pend, sizeof(pend));
326
+
327
+ ispend = extract32(pend, irq % 8, 1);
328
+
329
+ /* no change in the value of pending bit, return */
330
+ if (ispend == level) {
331
+ return;
332
+ }
333
+ pend = deposit32(pend, irq % 8, 1, level ? 1 : 0);
334
+
335
+ address_space_write(as, lpipt_baddr + ((irq / 8) * sizeof(pend)),
336
+ MEMTXATTRS_UNSPECIFIED, &pend, sizeof(pend));
337
+
338
+ /*
339
+ * check if this LPI is better than the current hpplpi, if yes
340
+ * just set hpplpi.prio and .irq without doing a full rescan
341
+ */
342
+ if (level) {
343
+ gicv3_redist_check_lpi_priority(cs, irq);
344
+ } else {
345
+ if (irq == cs->hpplpi.irq) {
346
+ gicv3_redist_update_lpi(cs);
347
+ }
348
+ }
349
+}
350
+
351
+void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level)
352
+{
353
+ uint64_t idbits;
354
+
355
+ idbits = MIN(FIELD_EX64(cs->gicr_propbaser, GICR_PROPBASER, IDBITS),
356
+ GICD_TYPER_IDBITS);
357
+
358
+ if (!(cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) || !cs->gicr_propbaser ||
359
+ !cs->gicr_pendbaser || (irq > (1ULL << (idbits + 1)) - 1) ||
360
+ irq < GICV3_LPI_INTID_START) {
361
+ return;
362
+ }
363
+
364
+ /* set/clear the pending bit for this irq */
365
+ gicv3_redist_lpi_pending(cs, irq, level);
366
+
367
+ gicv3_redist_update(cs);
368
+}
369
+
370
void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level)
371
{
372
/* Update redistributor state for a change in an external PPI input line */
373
--
885
--
374
2.20.1
886
2.25.1
375
887
376
888
diff view generated by jsdifflib
1
From: Bin Meng <bmeng.cn@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
As of today, when booting upstream U-Boot for Xilinx Zynq, the UART
3
These particular data structures are not modified at runtime.
4
does not receive anything. Debugging shows that the UART input clock
5
frequency is zero which prevents the UART from receiving anything as
6
per the logic in uart_receive().
7
4
8
From zynq_slcr_reset_exit() comment, it intends to compute output
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
clocks according to ps_clk and registers. zynq_slcr_compute_clocks()
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
is called to accomplish the task, inside which device_is_in_reset()
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
is called to actually make the attempt in vain.
8
Message-id: 20220501055028.646596-5-richard.henderson@linaro.org
12
13
Rework reset_hold() and reset_exit() so that in the reset exit phase,
14
the logic can really compute output clocks in reset_exit().
15
16
With this change, upstream U-Boot boots properly again with:
17
18
$ qemu-system-arm -M xilinx-zynq-a9 -m 1G -display none -serial null -serial stdio \
19
-device loader,file=u-boot-dtb.bin,addr=0x4000000,cpu-num=0
20
21
Fixes: 38867cb7ec90 ("hw/misc/zynq_slcr: add clock generation for uarts")
22
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
23
Acked-by: Alistair Francis <alistair.francis@wdc.com>
24
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
25
Message-id: 20210901124521.30599-2-bmeng.cn@gmail.com
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
---
10
---
28
hw/misc/zynq_slcr.c | 31 ++++++++++++++++++-------------
11
target/arm/helper.c | 16 ++++++++--------
29
1 file changed, 18 insertions(+), 13 deletions(-)
12
1 file changed, 8 insertions(+), 8 deletions(-)
30
13
31
diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/misc/zynq_slcr.c
16
--- a/target/arm/helper.c
34
+++ b/hw/misc/zynq_slcr.c
17
+++ b/target/arm/helper.c
35
@@ -XXX,XX +XXX,XX @@ static uint64_t zynq_slcr_compute_clock(const uint64_t periods[],
18
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
36
zynq_slcr_compute_clock((plls), (state)->regs[reg], \
19
.resetvalue = cpu->pmceid1 },
37
reg ## _ ## enable_field ## _SHIFT)
20
};
38
21
#ifdef CONFIG_USER_ONLY
39
+static void zynq_slcr_compute_clocks_internal(ZynqSLCRState *s, uint64_t ps_clk)
22
- ARMCPRegUserSpaceInfo v8_user_idregs[] = {
40
+{
23
+ static const ARMCPRegUserSpaceInfo v8_user_idregs[] = {
41
+ uint64_t io_pll = zynq_slcr_compute_pll(ps_clk, s->regs[R_IO_PLL_CTRL]);
24
{ .name = "ID_AA64PFR0_EL1",
42
+ uint64_t arm_pll = zynq_slcr_compute_pll(ps_clk, s->regs[R_ARM_PLL_CTRL]);
25
.exported_bits = 0x000f000f00ff0000,
43
+ uint64_t ddr_pll = zynq_slcr_compute_pll(ps_clk, s->regs[R_DDR_PLL_CTRL]);
26
.fixed_bits = 0x0000000000000011 },
44
+
27
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
45
+ uint64_t uart_mux[4] = {io_pll, io_pll, arm_pll, ddr_pll};
28
*/
46
+
29
if (arm_feature(env, ARM_FEATURE_EL3)) {
47
+ /* compute uartX reference clocks */
30
if (arm_feature(env, ARM_FEATURE_AARCH64)) {
48
+ clock_set(s->uart0_ref_clk,
31
- ARMCPRegInfo nsacr = {
49
+ ZYNQ_COMPUTE_CLK(s, uart_mux, R_UART_CLK_CTRL, CLKACT0));
32
+ static const ARMCPRegInfo nsacr = {
50
+ clock_set(s->uart1_ref_clk,
33
.name = "NSACR", .type = ARM_CP_CONST,
51
+ ZYNQ_COMPUTE_CLK(s, uart_mux, R_UART_CLK_CTRL, CLKACT1));
34
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,
52
+}
35
.access = PL1_RW, .accessfn = nsacr_access,
53
+
36
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
54
/**
37
};
55
* Compute and set the ouputs clocks periods.
38
define_one_arm_cp_reg(cpu, &nsacr);
56
* But do not propagate them further. Connected clocks
39
} else {
57
@@ -XXX,XX +XXX,XX @@ static void zynq_slcr_compute_clocks(ZynqSLCRState *s)
40
- ARMCPRegInfo nsacr = {
58
ps_clk = 0;
41
+ static const ARMCPRegInfo nsacr = {
42
.name = "NSACR",
43
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,
44
.access = PL3_RW | PL1_R,
45
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
46
}
47
} else {
48
if (arm_feature(env, ARM_FEATURE_V8)) {
49
- ARMCPRegInfo nsacr = {
50
+ static const ARMCPRegInfo nsacr = {
51
.name = "NSACR", .type = ARM_CP_CONST,
52
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,
53
.access = PL1_R,
54
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
55
.access = PL1_R, .type = ARM_CP_CONST,
56
.resetvalue = cpu->pmsav7_dregion << 8
57
};
58
- ARMCPRegInfo crn0_wi_reginfo = {
59
+ static const ARMCPRegInfo crn0_wi_reginfo = {
60
.name = "CRN0_WI", .cp = 15, .crn = 0, .crm = CP_ANY,
61
.opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W,
62
.type = ARM_CP_NOP | ARM_CP_OVERRIDE
63
};
64
#ifdef CONFIG_USER_ONLY
65
- ARMCPRegUserSpaceInfo id_v8_user_midr_cp_reginfo[] = {
66
+ static const ARMCPRegUserSpaceInfo id_v8_user_midr_cp_reginfo[] = {
67
{ .name = "MIDR_EL1",
68
.exported_bits = 0x00000000ffffffff },
69
{ .name = "REVIDR_EL1" },
70
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
71
.access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_RAW },
72
};
73
#ifdef CONFIG_USER_ONLY
74
- ARMCPRegUserSpaceInfo mpidr_user_cp_reginfo[] = {
75
+ static const ARMCPRegUserSpaceInfo mpidr_user_cp_reginfo[] = {
76
{ .name = "MPIDR_EL1",
77
.fixed_bits = 0x0000000080000000 },
78
};
79
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
59
}
80
}
60
81
61
- uint64_t io_pll = zynq_slcr_compute_pll(ps_clk, s->regs[R_IO_PLL_CTRL]);
82
if (arm_feature(env, ARM_FEATURE_VBAR)) {
62
- uint64_t arm_pll = zynq_slcr_compute_pll(ps_clk, s->regs[R_ARM_PLL_CTRL]);
83
- ARMCPRegInfo vbar_cp_reginfo[] = {
63
- uint64_t ddr_pll = zynq_slcr_compute_pll(ps_clk, s->regs[R_DDR_PLL_CTRL]);
84
+ static const ARMCPRegInfo vbar_cp_reginfo[] = {
64
-
85
{ .name = "VBAR", .state = ARM_CP_STATE_BOTH,
65
- uint64_t uart_mux[4] = {io_pll, io_pll, arm_pll, ddr_pll};
86
.opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
66
-
87
.access = PL1_RW, .writefn = vbar_write,
67
- /* compute uartX reference clocks */
68
- clock_set(s->uart0_ref_clk,
69
- ZYNQ_COMPUTE_CLK(s, uart_mux, R_UART_CLK_CTRL, CLKACT0));
70
- clock_set(s->uart1_ref_clk,
71
- ZYNQ_COMPUTE_CLK(s, uart_mux, R_UART_CLK_CTRL, CLKACT1));
72
+ zynq_slcr_compute_clocks_internal(s, ps_clk);
73
}
74
75
/**
76
@@ -XXX,XX +XXX,XX @@ static void zynq_slcr_reset_hold(Object *obj)
77
ZynqSLCRState *s = ZYNQ_SLCR(obj);
78
79
/* will disable all output clocks */
80
- zynq_slcr_compute_clocks(s);
81
+ zynq_slcr_compute_clocks_internal(s, 0);
82
zynq_slcr_propagate_clocks(s);
83
}
84
85
@@ -XXX,XX +XXX,XX @@ static void zynq_slcr_reset_exit(Object *obj)
86
ZynqSLCRState *s = ZYNQ_SLCR(obj);
87
88
/* will compute output clocks according to ps_clk and registers */
89
- zynq_slcr_compute_clocks(s);
90
+ zynq_slcr_compute_clocks_internal(s, clock_get(s->ps_clk));
91
zynq_slcr_propagate_clocks(s);
92
}
93
94
--
88
--
95
2.20.1
89
2.25.1
96
90
97
91
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
It is confusing to have different exits from translation
3
Instead of defining ARM_CP_FLAG_MASK to remove flags,
4
for various conditions in separate functions.
4
define ARM_CP_SPECIAL_MASK to isolate special cases.
5
5
Sort the specials to the low bits. Use an enum.
6
Merge disas_a64_insn into its only caller. Standardize
6
7
on the "s" name for the DisasContext, as the code from
7
Split the large comment block so as to document each
8
disas_a64_insn had more instances.
8
value separately.
9
9
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20220501055028.646596-6-richard.henderson@linaro.org
12
Message-id: 20210821195958.41312-3-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
14
---
15
target/arm/translate-a64.c | 224 ++++++++++++++++++-------------------
15
target/arm/cpregs.h | 130 +++++++++++++++++++++++--------------
16
1 file changed, 109 insertions(+), 115 deletions(-)
16
target/arm/cpu.c | 4 +-
17
17
target/arm/helper.c | 4 +-
18
target/arm/translate-a64.c | 6 +-
19
target/arm/translate.c | 6 +-
20
5 files changed, 92 insertions(+), 58 deletions(-)
21
22
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpregs.h
25
+++ b/target/arm/cpregs.h
26
@@ -XXX,XX +XXX,XX @@
27
#define TARGET_ARM_CPREGS_H
28
29
/*
30
- * ARMCPRegInfo type field bits. If the SPECIAL bit is set this is a
31
- * special-behaviour cp reg and bits [11..8] indicate what behaviour
32
- * it has. Otherwise it is a simple cp reg, where CONST indicates that
33
- * TCG can assume the value to be constant (ie load at translate time)
34
- * and 64BIT indicates a 64 bit wide coprocessor register. SUPPRESS_TB_END
35
- * indicates that the TB should not be ended after a write to this register
36
- * (the default is that the TB ends after cp writes). OVERRIDE permits
37
- * a register definition to override a previous definition for the
38
- * same (cp, is64, crn, crm, opc1, opc2) tuple: either the new or the
39
- * old must have the OVERRIDE bit set.
40
- * ALIAS indicates that this register is an alias view of some underlying
41
- * state which is also visible via another register, and that the other
42
- * register is handling migration and reset; registers marked ALIAS will not be
43
- * migrated but may have their state set by syncing of register state from KVM.
44
- * NO_RAW indicates that this register has no underlying state and does not
45
- * support raw access for state saving/loading; it will not be used for either
46
- * migration or KVM state synchronization. (Typically this is for "registers"
47
- * which are actually used as instructions for cache maintenance and so on.)
48
- * IO indicates that this register does I/O and therefore its accesses
49
- * need to be marked with gen_io_start() and also end the TB. In particular,
50
- * registers which implement clocks or timers require this.
51
- * RAISES_EXC is for when the read or write hook might raise an exception;
52
- * the generated code will synchronize the CPU state before calling the hook
53
- * so that it is safe for the hook to call raise_exception().
54
- * NEWEL is for writes to registers that might change the exception
55
- * level - typically on older ARM chips. For those cases we need to
56
- * re-read the new el when recomputing the translation flags.
57
+ * ARMCPRegInfo type field bits:
58
*/
59
-#define ARM_CP_SPECIAL 0x0001
60
-#define ARM_CP_CONST 0x0002
61
-#define ARM_CP_64BIT 0x0004
62
-#define ARM_CP_SUPPRESS_TB_END 0x0008
63
-#define ARM_CP_OVERRIDE 0x0010
64
-#define ARM_CP_ALIAS 0x0020
65
-#define ARM_CP_IO 0x0040
66
-#define ARM_CP_NO_RAW 0x0080
67
-#define ARM_CP_NOP (ARM_CP_SPECIAL | 0x0100)
68
-#define ARM_CP_WFI (ARM_CP_SPECIAL | 0x0200)
69
-#define ARM_CP_NZCV (ARM_CP_SPECIAL | 0x0300)
70
-#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | 0x0400)
71
-#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | 0x0500)
72
-#define ARM_CP_DC_GVA (ARM_CP_SPECIAL | 0x0600)
73
-#define ARM_CP_DC_GZVA (ARM_CP_SPECIAL | 0x0700)
74
-#define ARM_LAST_SPECIAL ARM_CP_DC_GZVA
75
-#define ARM_CP_FPU 0x1000
76
-#define ARM_CP_SVE 0x2000
77
-#define ARM_CP_NO_GDB 0x4000
78
-#define ARM_CP_RAISES_EXC 0x8000
79
-#define ARM_CP_NEWEL 0x10000
80
-/* Mask of only the flag bits in a type field */
81
-#define ARM_CP_FLAG_MASK 0x1f0ff
82
+enum {
83
+ /*
84
+ * Register must be handled specially during translation.
85
+ * The method is one of the values below:
86
+ */
87
+ ARM_CP_SPECIAL_MASK = 0x000f,
88
+ /* Special: no change to PE state: writes ignored, reads ignored. */
89
+ ARM_CP_NOP = 0x0001,
90
+ /* Special: sysreg is WFI, for v5 and v6. */
91
+ ARM_CP_WFI = 0x0002,
92
+ /* Special: sysreg is NZCV. */
93
+ ARM_CP_NZCV = 0x0003,
94
+ /* Special: sysreg is CURRENTEL. */
95
+ ARM_CP_CURRENTEL = 0x0004,
96
+ /* Special: sysreg is DC ZVA or similar. */
97
+ ARM_CP_DC_ZVA = 0x0005,
98
+ ARM_CP_DC_GVA = 0x0006,
99
+ ARM_CP_DC_GZVA = 0x0007,
100
+
101
+ /* Flag: reads produce resetvalue; writes ignored. */
102
+ ARM_CP_CONST = 1 << 4,
103
+ /* Flag: For ARM_CP_STATE_AA32, sysreg is 64-bit. */
104
+ ARM_CP_64BIT = 1 << 5,
105
+ /*
106
+ * Flag: TB should not be ended after a write to this register
107
+ * (the default is that the TB ends after cp writes).
108
+ */
109
+ ARM_CP_SUPPRESS_TB_END = 1 << 6,
110
+ /*
111
+ * Flag: Permit a register definition to override a previous definition
112
+ * for the same (cp, is64, crn, crm, opc1, opc2) tuple: either the new
113
+ * or the old must have the ARM_CP_OVERRIDE bit set.
114
+ */
115
+ ARM_CP_OVERRIDE = 1 << 7,
116
+ /*
117
+ * Flag: Register is an alias view of some underlying state which is also
118
+ * visible via another register, and that the other register is handling
119
+ * migration and reset; registers marked ARM_CP_ALIAS will not be migrated
120
+ * but may have their state set by syncing of register state from KVM.
121
+ */
122
+ ARM_CP_ALIAS = 1 << 8,
123
+ /*
124
+ * Flag: Register does I/O and therefore its accesses need to be marked
125
+ * with gen_io_start() and also end the TB. In particular, registers which
126
+ * implement clocks or timers require this.
127
+ */
128
+ ARM_CP_IO = 1 << 9,
129
+ /*
130
+ * Flag: Register has no underlying state and does not support raw access
131
+ * for state saving/loading; it will not be used for either migration or
132
+ * KVM state synchronization. Typically this is for "registers" which are
133
+ * actually used as instructions for cache maintenance and so on.
134
+ */
135
+ ARM_CP_NO_RAW = 1 << 10,
136
+ /*
137
+ * Flag: The read or write hook might raise an exception; the generated
138
+ * code will synchronize the CPU state before calling the hook so that it
139
+ * is safe for the hook to call raise_exception().
140
+ */
141
+ ARM_CP_RAISES_EXC = 1 << 11,
142
+ /*
143
+ * Flag: Writes to the sysreg might change the exception level - typically
144
+ * on older ARM chips. For those cases we need to re-read the new el when
145
+ * recomputing the translation flags.
146
+ */
147
+ ARM_CP_NEWEL = 1 << 12,
148
+ /*
149
+ * Flag: Access check for this sysreg is identical to accessing FPU state
150
+ * from an instruction: use translation fp_access_check().
151
+ */
152
+ ARM_CP_FPU = 1 << 13,
153
+ /*
154
+ * Flag: Access check for this sysreg is identical to accessing SVE state
155
+ * from an instruction: use translation sve_access_check().
156
+ */
157
+ ARM_CP_SVE = 1 << 14,
158
+ /* Flag: Do not expose in gdb sysreg xml. */
159
+ ARM_CP_NO_GDB = 1 << 15,
160
+};
161
162
/*
163
* Valid values for ARMCPRegInfo state field, indicating which of
164
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
165
index XXXXXXX..XXXXXXX 100644
166
--- a/target/arm/cpu.c
167
+++ b/target/arm/cpu.c
168
@@ -XXX,XX +XXX,XX @@ static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
169
ARMCPRegInfo *ri = value;
170
ARMCPU *cpu = opaque;
171
172
- if (ri->type & (ARM_CP_SPECIAL | ARM_CP_ALIAS)) {
173
+ if (ri->type & (ARM_CP_SPECIAL_MASK | ARM_CP_ALIAS)) {
174
return;
175
}
176
177
@@ -XXX,XX +XXX,XX @@ static void cp_reg_check_reset(gpointer key, gpointer value, gpointer opaque)
178
ARMCPU *cpu = opaque;
179
uint64_t oldvalue, newvalue;
180
181
- if (ri->type & (ARM_CP_SPECIAL | ARM_CP_ALIAS | ARM_CP_NO_RAW)) {
182
+ if (ri->type & (ARM_CP_SPECIAL_MASK | ARM_CP_ALIAS | ARM_CP_NO_RAW)) {
183
return;
184
}
185
186
diff --git a/target/arm/helper.c b/target/arm/helper.c
187
index XXXXXXX..XXXXXXX 100644
188
--- a/target/arm/helper.c
189
+++ b/target/arm/helper.c
190
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
191
* multiple times. Special registers (ie NOP/WFI) are
192
* never migratable and not even raw-accessible.
193
*/
194
- if ((r->type & ARM_CP_SPECIAL)) {
195
+ if (r->type & ARM_CP_SPECIAL_MASK) {
196
r2->type |= ARM_CP_NO_RAW;
197
}
198
if (((r->crm == CP_ANY) && crm != 0) ||
199
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
200
/* Check that the register definition has enough info to handle
201
* reads and writes if they are permitted.
202
*/
203
- if (!(r->type & (ARM_CP_SPECIAL|ARM_CP_CONST))) {
204
+ if (!(r->type & (ARM_CP_SPECIAL_MASK | ARM_CP_CONST))) {
205
if (r->access & PL3_R) {
206
assert((r->fieldoffset ||
207
(r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
18
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
208
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
19
index XXXXXXX..XXXXXXX 100644
209
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate-a64.c
210
--- a/target/arm/translate-a64.c
21
+++ b/target/arm/translate-a64.c
211
+++ b/target/arm/translate-a64.c
22
@@ -XXX,XX +XXX,XX @@ static bool btype_destination_ok(uint32_t insn, bool bt, int btype)
212
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
23
return false;
213
}
24
}
214
25
215
/* Handle special cases first */
26
-/* C3.1 A64 instruction index by encoding */
216
- switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
27
-static void disas_a64_insn(CPUARMState *env, DisasContext *s)
217
+ switch (ri->type & ARM_CP_SPECIAL_MASK) {
28
-{
218
+ case 0:
29
- uint32_t insn;
219
+ break;
30
-
220
case ARM_CP_NOP:
31
- s->pc_curr = s->base.pc_next;
221
return;
32
- insn = arm_ldl_code(env, s->base.pc_next, s->sctlr_b);
222
case ARM_CP_NZCV:
33
- s->insn = insn;
223
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
34
- s->base.pc_next += 4;
224
}
35
-
225
return;
36
- s->fp_access_checked = false;
226
default:
37
- s->sve_access_checked = false;
38
-
39
- if (s->pstate_il) {
40
- /*
41
- * Illegal execution state. This has priority over BTI
42
- * exceptions, but comes after instruction abort exceptions.
43
- */
44
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
45
- syn_illegalstate(), default_exception_el(s));
46
- return;
47
- }
48
-
49
- if (dc_isar_feature(aa64_bti, s)) {
50
- if (s->base.num_insns == 1) {
51
- /*
52
- * At the first insn of the TB, compute s->guarded_page.
53
- * We delayed computing this until successfully reading
54
- * the first insn of the TB, above. This (mostly) ensures
55
- * that the softmmu tlb entry has been populated, and the
56
- * page table GP bit is available.
57
- *
58
- * Note that we need to compute this even if btype == 0,
59
- * because this value is used for BR instructions later
60
- * where ENV is not available.
61
- */
62
- s->guarded_page = is_guarded_page(env, s);
63
-
64
- /* First insn can have btype set to non-zero. */
65
- tcg_debug_assert(s->btype >= 0);
66
-
67
- /*
68
- * Note that the Branch Target Exception has fairly high
69
- * priority -- below debugging exceptions but above most
70
- * everything else. This allows us to handle this now
71
- * instead of waiting until the insn is otherwise decoded.
72
- */
73
- if (s->btype != 0
74
- && s->guarded_page
75
- && !btype_destination_ok(insn, s->bt, s->btype)) {
76
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
77
- syn_btitrap(s->btype),
78
- default_exception_el(s));
79
- return;
80
- }
81
- } else {
82
- /* Not the first insn: btype must be 0. */
83
- tcg_debug_assert(s->btype == 0);
84
- }
85
- }
86
-
87
- switch (extract32(insn, 25, 4)) {
88
- case 0x0: case 0x1: case 0x3: /* UNALLOCATED */
89
- unallocated_encoding(s);
90
- break;
227
- break;
91
- case 0x2:
228
+ g_assert_not_reached();
92
- if (!dc_isar_feature(aa64_sve, s) || !disas_sve(s, insn)) {
229
}
93
- unallocated_encoding(s);
230
if ((ri->type & ARM_CP_FPU) && !fp_access_check(s)) {
94
- }
231
return;
95
- break;
232
diff --git a/target/arm/translate.c b/target/arm/translate.c
96
- case 0x8: case 0x9: /* Data processing - immediate */
233
index XXXXXXX..XXXXXXX 100644
97
- disas_data_proc_imm(s, insn);
234
--- a/target/arm/translate.c
98
- break;
235
+++ b/target/arm/translate.c
99
- case 0xa: case 0xb: /* Branch, exception generation and system insns */
236
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
100
- disas_b_exc_sys(s, insn);
237
}
101
- break;
238
102
- case 0x4:
239
/* Handle special cases first */
103
- case 0x6:
240
- switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
104
- case 0xc:
241
+ switch (ri->type & ARM_CP_SPECIAL_MASK) {
105
- case 0xe: /* Loads and stores */
242
+ case 0:
106
- disas_ldst(s, insn);
243
+ break;
107
- break;
244
case ARM_CP_NOP:
108
- case 0x5:
245
return;
109
- case 0xd: /* Data processing - register */
246
case ARM_CP_WFI:
110
- disas_data_proc_reg(s, insn);
247
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
111
- break;
248
s->base.is_jmp = DISAS_WFI;
112
- case 0x7:
249
return;
113
- case 0xf: /* Data processing - SIMD and floating point */
250
default:
114
- disas_data_proc_simd_fp(s, insn);
251
- break;
115
- break;
252
+ g_assert_not_reached();
116
- default:
253
}
117
- assert(FALSE); /* all 15 cases should be handled above */
254
118
- break;
255
if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
119
- }
120
-
121
- /* if we allocated any temporaries, free them here */
122
- free_tmp_a64(s);
123
-
124
- /*
125
- * After execution of most insns, btype is reset to 0.
126
- * Note that we set btype == -1 when the insn sets btype.
127
- */
128
- if (s->btype > 0 && s->base.is_jmp != DISAS_NORETURN) {
129
- reset_btype(s);
130
- }
131
-}
132
-
133
static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
134
CPUState *cpu)
135
{
136
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
137
138
static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
139
{
140
- DisasContext *dc = container_of(dcbase, DisasContext, base);
141
+ DisasContext *s = container_of(dcbase, DisasContext, base);
142
CPUARMState *env = cpu->env_ptr;
143
+ uint32_t insn;
144
145
- if (dc->ss_active && !dc->pstate_ss) {
146
+ if (s->ss_active && !s->pstate_ss) {
147
/* Singlestep state is Active-pending.
148
* If we're in this state at the start of a TB then either
149
* a) we just took an exception to an EL which is being debugged
150
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
151
* "did not step an insn" case, and so the syndrome ISV and EX
152
* bits should be zero.
153
*/
154
- assert(dc->base.num_insns == 1);
155
- gen_swstep_exception(dc, 0, 0);
156
- dc->base.is_jmp = DISAS_NORETURN;
157
- } else {
158
- disas_a64_insn(env, dc);
159
+ assert(s->base.num_insns == 1);
160
+ gen_swstep_exception(s, 0, 0);
161
+ s->base.is_jmp = DISAS_NORETURN;
162
+ return;
163
}
164
165
- translator_loop_temp_check(&dc->base);
166
+ s->pc_curr = s->base.pc_next;
167
+ insn = arm_ldl_code(env, s->base.pc_next, s->sctlr_b);
168
+ s->insn = insn;
169
+ s->base.pc_next += 4;
170
+
171
+ s->fp_access_checked = false;
172
+ s->sve_access_checked = false;
173
+
174
+ if (s->pstate_il) {
175
+ /*
176
+ * Illegal execution state. This has priority over BTI
177
+ * exceptions, but comes after instruction abort exceptions.
178
+ */
179
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
180
+ syn_illegalstate(), default_exception_el(s));
181
+ return;
182
+ }
183
+
184
+ if (dc_isar_feature(aa64_bti, s)) {
185
+ if (s->base.num_insns == 1) {
186
+ /*
187
+ * At the first insn of the TB, compute s->guarded_page.
188
+ * We delayed computing this until successfully reading
189
+ * the first insn of the TB, above. This (mostly) ensures
190
+ * that the softmmu tlb entry has been populated, and the
191
+ * page table GP bit is available.
192
+ *
193
+ * Note that we need to compute this even if btype == 0,
194
+ * because this value is used for BR instructions later
195
+ * where ENV is not available.
196
+ */
197
+ s->guarded_page = is_guarded_page(env, s);
198
+
199
+ /* First insn can have btype set to non-zero. */
200
+ tcg_debug_assert(s->btype >= 0);
201
+
202
+ /*
203
+ * Note that the Branch Target Exception has fairly high
204
+ * priority -- below debugging exceptions but above most
205
+ * everything else. This allows us to handle this now
206
+ * instead of waiting until the insn is otherwise decoded.
207
+ */
208
+ if (s->btype != 0
209
+ && s->guarded_page
210
+ && !btype_destination_ok(insn, s->bt, s->btype)) {
211
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
212
+ syn_btitrap(s->btype),
213
+ default_exception_el(s));
214
+ return;
215
+ }
216
+ } else {
217
+ /* Not the first insn: btype must be 0. */
218
+ tcg_debug_assert(s->btype == 0);
219
+ }
220
+ }
221
+
222
+ switch (extract32(insn, 25, 4)) {
223
+ case 0x0: case 0x1: case 0x3: /* UNALLOCATED */
224
+ unallocated_encoding(s);
225
+ break;
226
+ case 0x2:
227
+ if (!dc_isar_feature(aa64_sve, s) || !disas_sve(s, insn)) {
228
+ unallocated_encoding(s);
229
+ }
230
+ break;
231
+ case 0x8: case 0x9: /* Data processing - immediate */
232
+ disas_data_proc_imm(s, insn);
233
+ break;
234
+ case 0xa: case 0xb: /* Branch, exception generation and system insns */
235
+ disas_b_exc_sys(s, insn);
236
+ break;
237
+ case 0x4:
238
+ case 0x6:
239
+ case 0xc:
240
+ case 0xe: /* Loads and stores */
241
+ disas_ldst(s, insn);
242
+ break;
243
+ case 0x5:
244
+ case 0xd: /* Data processing - register */
245
+ disas_data_proc_reg(s, insn);
246
+ break;
247
+ case 0x7:
248
+ case 0xf: /* Data processing - SIMD and floating point */
249
+ disas_data_proc_simd_fp(s, insn);
250
+ break;
251
+ default:
252
+ assert(FALSE); /* all 15 cases should be handled above */
253
+ break;
254
+ }
255
+
256
+ /* if we allocated any temporaries, free them here */
257
+ free_tmp_a64(s);
258
+
259
+ /*
260
+ * After execution of most insns, btype is reset to 0.
261
+ * Note that we set btype == -1 when the insn sets btype.
262
+ */
263
+ if (s->btype > 0 && s->base.is_jmp != DISAS_NORETURN) {
264
+ reset_btype(s);
265
+ }
266
+
267
+ translator_loop_temp_check(&s->base);
268
}
269
270
static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
271
--
256
--
272
2.20.1
257
2.25.1
273
274
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Although we probe for the IPA limits imposed by KVM (and the hardware)
3
Standardize on g_assert_not_reached() for "should not happen".
4
when computing the memory map, we still use the old style '0' when
4
Retain abort() when preceeded by fprintf or error_report.
5
creating a scratch VM in kvm_arm_create_scratch_host_vcpu().
6
5
7
On systems that are severely IPA challenged (such as the Apple M1),
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
this results in a failure as KVM cannot use the default 40bit that
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
'0' represents.
8
Message-id: 20220501055028.646596-7-richard.henderson@linaro.org
10
11
Instead, probe for the extension and use the reported IPA limit
12
if available.
13
14
Cc: Andrew Jones <drjones@redhat.com>
15
Cc: Eric Auger <eric.auger@redhat.com>
16
Cc: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Marc Zyngier <maz@kernel.org>
18
Reviewed-by: Andrew Jones <drjones@redhat.com>
19
Message-id: 20210822144441.1290891-2-maz@kernel.org
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
10
---
22
target/arm/kvm.c | 7 ++++++-
11
target/arm/helper.c | 7 +++----
23
1 file changed, 6 insertions(+), 1 deletion(-)
12
target/arm/hvf/hvf.c | 2 +-
13
target/arm/kvm-stub.c | 4 ++--
14
target/arm/kvm.c | 4 ++--
15
target/arm/machine.c | 4 ++--
16
target/arm/translate-a64.c | 4 ++--
17
target/arm/translate-neon.c | 2 +-
18
target/arm/translate.c | 4 ++--
19
8 files changed, 15 insertions(+), 16 deletions(-)
24
20
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/helper.c
24
+++ b/target/arm/helper.c
25
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
26
break;
27
default:
28
/* broken reginfo with out-of-range opc1 */
29
- assert(false);
30
- break;
31
+ g_assert_not_reached();
32
}
33
/* assert our permissions are not too lax (stricter is fine) */
34
assert((r->access & ~mask) == 0);
35
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
36
break;
37
default:
38
/* Never happens, but compiler isn't smart enough to tell. */
39
- abort();
40
+ g_assert_not_reached();
41
}
42
}
43
*prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
44
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
45
break;
46
default:
47
/* Never happens, but compiler isn't smart enough to tell. */
48
- abort();
49
+ g_assert_not_reached();
50
}
51
}
52
if (domain_prot == 3) {
53
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/hvf/hvf.c
56
+++ b/target/arm/hvf/hvf.c
57
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
58
/* we got kicked, no exit to process */
59
return 0;
60
default:
61
- assert(0);
62
+ g_assert_not_reached();
63
}
64
65
hvf_sync_vtimer(cpu);
66
diff --git a/target/arm/kvm-stub.c b/target/arm/kvm-stub.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/kvm-stub.c
69
+++ b/target/arm/kvm-stub.c
70
@@ -XXX,XX +XXX,XX @@
71
72
bool write_kvmstate_to_list(ARMCPU *cpu)
73
{
74
- abort();
75
+ g_assert_not_reached();
76
}
77
78
bool write_list_to_kvmstate(ARMCPU *cpu, int level)
79
{
80
- abort();
81
+ g_assert_not_reached();
82
}
25
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
83
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
26
index XXXXXXX..XXXXXXX 100644
84
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/kvm.c
85
--- a/target/arm/kvm.c
28
+++ b/target/arm/kvm.c
86
+++ b/target/arm/kvm.c
29
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
87
@@ -XXX,XX +XXX,XX @@ bool write_kvmstate_to_list(ARMCPU *cpu)
30
struct kvm_vcpu_init *init)
88
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
31
{
89
break;
32
int ret = 0, kvmfd = -1, vmfd = -1, cpufd = -1;
90
default:
33
+ int max_vm_pa_size;
91
- abort();
34
92
+ g_assert_not_reached();
35
kvmfd = qemu_open_old("/dev/kvm", O_RDWR);
93
}
36
if (kvmfd < 0) {
94
if (ret) {
37
goto err;
95
ok = false;
96
@@ -XXX,XX +XXX,XX @@ bool write_list_to_kvmstate(ARMCPU *cpu, int level)
97
r.addr = (uintptr_t)(cpu->cpreg_values + i);
98
break;
99
default:
100
- abort();
101
+ g_assert_not_reached();
102
}
103
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
104
if (ret) {
105
diff --git a/target/arm/machine.c b/target/arm/machine.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/arm/machine.c
108
+++ b/target/arm/machine.c
109
@@ -XXX,XX +XXX,XX @@ static int cpu_pre_save(void *opaque)
110
if (kvm_enabled()) {
111
if (!write_kvmstate_to_list(cpu)) {
112
/* This should never fail */
113
- abort();
114
+ g_assert_not_reached();
115
}
116
117
/*
118
@@ -XXX,XX +XXX,XX @@ static int cpu_pre_save(void *opaque)
119
} else {
120
if (!write_cpustate_to_list(cpu, false)) {
121
/* This should never fail. */
122
- abort();
123
+ g_assert_not_reached();
124
}
38
}
125
}
39
- vmfd = ioctl(kvmfd, KVM_CREATE_VM, 0);
126
40
+ max_vm_pa_size = ioctl(kvmfd, KVM_CHECK_EXTENSION, KVM_CAP_ARM_VM_IPA_SIZE);
127
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
41
+ if (max_vm_pa_size < 0) {
128
index XXXXXXX..XXXXXXX 100644
42
+ max_vm_pa_size = 0;
129
--- a/target/arm/translate-a64.c
43
+ }
130
+++ b/target/arm/translate-a64.c
44
+ vmfd = ioctl(kvmfd, KVM_CREATE_VM, max_vm_pa_size);
131
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn)
45
if (vmfd < 0) {
132
gen_helper_advsimd_rinth(tcg_res, tcg_op, fpst);
46
goto err;
133
break;
134
default:
135
- abort();
136
+ g_assert_not_reached();
47
}
137
}
138
139
write_fp_sreg(s, rd, tcg_res);
140
@@ -XXX,XX +XXX,XX @@ static void handle_fp_fcvt(DisasContext *s, int opcode,
141
break;
142
}
143
default:
144
- abort();
145
+ g_assert_not_reached();
146
}
147
}
148
149
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
150
index XXXXXXX..XXXXXXX 100644
151
--- a/target/arm/translate-neon.c
152
+++ b/target/arm/translate-neon.c
153
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
154
}
155
break;
156
default:
157
- abort();
158
+ g_assert_not_reached();
159
}
160
if ((vd + a->stride * (nregs - 1)) > 31) {
161
/*
162
diff --git a/target/arm/translate.c b/target/arm/translate.c
163
index XXXXXXX..XXXXXXX 100644
164
--- a/target/arm/translate.c
165
+++ b/target/arm/translate.c
166
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
167
offset = 4;
168
break;
169
default:
170
- abort();
171
+ g_assert_not_reached();
172
}
173
tcg_gen_addi_i32(addr, addr, offset);
174
tmp = load_reg(s, 14);
175
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
176
offset = 0;
177
break;
178
default:
179
- abort();
180
+ g_assert_not_reached();
181
}
182
tcg_gen_addi_i32(addr, addr, offset);
183
gen_helper_set_r13_banked(cpu_env, tcg_constant_i32(mode), addr);
48
--
184
--
49
2.20.1
185
2.25.1
50
51
diff view generated by jsdifflib
1
From: Shashi Mallela <shashi.mallela@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Updated expected IORT files applicable with latest GICv3
3
Create a typedef as well, and use it in ARMCPRegInfo.
4
ITS changes.
4
This won't be perfect for debugging, but it'll nicely
5
display the most common cases.
5
6
6
Full diff of new file disassembly:
7
8
/*
9
* Intel ACPI Component Architecture
10
* AML/ASL+ Disassembler version 20180629 (64-bit version)
11
* Copyright (c) 2000 - 2018 Intel Corporation
12
*
13
* Disassembly of tests/data/acpi/virt/IORT.pxb, Tue Jun 29 17:35:38 2021
14
*
15
* ACPI Data Table [IORT]
16
*
17
* Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue
18
*/
19
20
[000h 0000 4] Signature : "IORT" [IO Remapping Table]
21
[004h 0004 4] Table Length : 0000007C
22
[008h 0008 1] Revision : 00
23
[009h 0009 1] Checksum : 07
24
[00Ah 0010 6] Oem ID : "BOCHS "
25
[010h 0016 8] Oem Table ID : "BXPC "
26
[018h 0024 4] Oem Revision : 00000001
27
[01Ch 0028 4] Asl Compiler ID : "BXPC"
28
[020h 0032 4] Asl Compiler Revision : 00000001
29
30
[024h 0036 4] Node Count : 00000002
31
[028h 0040 4] Node Offset : 00000030
32
[02Ch 0044 4] Reserved : 00000000
33
34
[030h 0048 1] Type : 00
35
[031h 0049 2] Length : 0018
36
[033h 0051 1] Revision : 00
37
[034h 0052 4] Reserved : 00000000
38
[038h 0056 4] Mapping Count : 00000000
39
[03Ch 0060 4] Mapping Offset : 00000000
40
41
[040h 0064 4] ItsCount : 00000001
42
[044h 0068 4] Identifiers : 00000000
43
44
[048h 0072 1] Type : 02
45
[049h 0073 2] Length : 0034
46
[04Bh 0075 1] Revision : 00
47
[04Ch 0076 4] Reserved : 00000000
48
[050h 0080 4] Mapping Count : 00000001
49
[054h 0084 4] Mapping Offset : 00000020
50
51
[058h 0088 8] Memory Properties : [IORT Memory Access Properties]
52
[058h 0088 4] Cache Coherency : 00000001
53
[05Ch 0092 1] Hints (decoded below) : 00
54
Transient : 0
55
Write Allocate : 0
56
Read Allocate : 0
57
Override : 0
58
[05Dh 0093 2] Reserved : 0000
59
[05Fh 0095 1] Memory Flags (decoded below) : 03
60
Coherency : 1
61
Device Attribute : 1
62
[060h 0096 4] ATS Attribute : 00000000
63
[064h 0100 4] PCI Segment Number : 00000000
64
[068h 0104 1] Memory Size Limit : 00
65
[069h 0105 3] Reserved : 000000
66
67
[068h 0104 4] Input base : 00000000
68
[06Ch 0108 4] ID Count : 0000FFFF
69
[070h 0112 4] Output Base : 00000000
70
[074h 0116 4] Output Reference : 00000030
71
[078h 0120 4] Flags (decoded below) : 00000000
72
Single Mapping : 0
73
74
Raw Table Data: Length 124 (0x7C)
75
76
0000: 49 4F 52 54 7C 00 00 00 00 07 42 4F 43 48 53 20 // IORT|.....BOCHS
77
0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC
78
0020: 01 00 00 00 02 00 00 00 30 00 00 00 00 00 00 00 // ........0.......
79
0030: 00 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
80
0040: 01 00 00 00 00 00 00 00 02 34 00 00 00 00 00 00 // .........4......
81
0050: 01 00 00 00 20 00 00 00 01 00 00 00 00 00 00 03 // .... ...........
82
0060: 00 00 00 00 00 00 00 00 00 00 00 00 FF FF 00 00 // ................
83
0070: 00 00 00 00 30 00 00 00 00 00 00 00 // ....0.......
84
85
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
86
Acked-by: Igor Mammedov <imammedo@redhat.com>
87
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
88
Message-id: 20210910143951.92242-10-shashi.mallela@linaro.org
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220501055028.646596-8-richard.henderson@linaro.org
89
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
90
---
11
---
91
tests/qtest/bios-tables-test-allowed-diff.h | 4 ----
12
target/arm/cpregs.h | 44 +++++++++++++++++++++++---------------------
92
tests/data/acpi/virt/IORT | Bin 0 -> 124 bytes
13
target/arm/helper.c | 2 +-
93
tests/data/acpi/virt/IORT.memhp | Bin 0 -> 124 bytes
14
2 files changed, 24 insertions(+), 22 deletions(-)
94
tests/data/acpi/virt/IORT.numamem | Bin 0 -> 124 bytes
95
tests/data/acpi/virt/IORT.pxb | Bin 0 -> 124 bytes
96
5 files changed, 4 deletions(-)
97
15
98
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
16
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
99
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
100
--- a/tests/qtest/bios-tables-test-allowed-diff.h
18
--- a/target/arm/cpregs.h
101
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
19
+++ b/target/arm/cpregs.h
102
@@ -1,5 +1 @@
20
@@ -XXX,XX +XXX,XX @@ enum {
103
/* List of comma-separated changed AML files to ignore */
21
* described with these bits, then use a laxer set of restrictions, and
104
-"tests/data/acpi/virt/IORT",
22
* do the more restrictive/complex check inside a helper function.
105
-"tests/data/acpi/virt/IORT.memhp",
23
*/
106
-"tests/data/acpi/virt/IORT.numamem",
24
-#define PL3_R 0x80
107
-"tests/data/acpi/virt/IORT.pxb",
25
-#define PL3_W 0x40
108
diff --git a/tests/data/acpi/virt/IORT b/tests/data/acpi/virt/IORT
26
-#define PL2_R (0x20 | PL3_R)
27
-#define PL2_W (0x10 | PL3_W)
28
-#define PL1_R (0x08 | PL2_R)
29
-#define PL1_W (0x04 | PL2_W)
30
-#define PL0_R (0x02 | PL1_R)
31
-#define PL0_W (0x01 | PL1_W)
32
+typedef enum {
33
+ PL3_R = 0x80,
34
+ PL3_W = 0x40,
35
+ PL2_R = 0x20 | PL3_R,
36
+ PL2_W = 0x10 | PL3_W,
37
+ PL1_R = 0x08 | PL2_R,
38
+ PL1_W = 0x04 | PL2_W,
39
+ PL0_R = 0x02 | PL1_R,
40
+ PL0_W = 0x01 | PL1_W,
41
42
-/*
43
- * For user-mode some registers are accessible to EL0 via a kernel
44
- * trap-and-emulate ABI. In this case we define the read permissions
45
- * as actually being PL0_R. However some bits of any given register
46
- * may still be masked.
47
- */
48
+ /*
49
+ * For user-mode some registers are accessible to EL0 via a kernel
50
+ * trap-and-emulate ABI. In this case we define the read permissions
51
+ * as actually being PL0_R. However some bits of any given register
52
+ * may still be masked.
53
+ */
54
#ifdef CONFIG_USER_ONLY
55
-#define PL0U_R PL0_R
56
+ PL0U_R = PL0_R,
57
#else
58
-#define PL0U_R PL1_R
59
+ PL0U_R = PL1_R,
60
#endif
61
62
-#define PL3_RW (PL3_R | PL3_W)
63
-#define PL2_RW (PL2_R | PL2_W)
64
-#define PL1_RW (PL1_R | PL1_W)
65
-#define PL0_RW (PL0_R | PL0_W)
66
+ PL3_RW = PL3_R | PL3_W,
67
+ PL2_RW = PL2_R | PL2_W,
68
+ PL1_RW = PL1_R | PL1_W,
69
+ PL0_RW = PL0_R | PL0_W,
70
+} CPAccessRights;
71
72
typedef enum CPAccessResult {
73
/* Access is permitted */
74
@@ -XXX,XX +XXX,XX @@ struct ARMCPRegInfo {
75
/* Register type: ARM_CP_* bits/values */
76
int type;
77
/* Access rights: PL*_[RW] */
78
- int access;
79
+ CPAccessRights access;
80
/* Security state: ARM_CP_SECSTATE_* bits/values */
81
int secure;
82
/*
83
diff --git a/target/arm/helper.c b/target/arm/helper.c
109
index XXXXXXX..XXXXXXX 100644
84
index XXXXXXX..XXXXXXX 100644
110
GIT binary patch
85
--- a/target/arm/helper.c
111
literal 124
86
+++ b/target/arm/helper.c
112
zcmebD4+^Pa00MR=e`k+i1*eDrX9XZ&1PX!JAesq?4S*O7Bw!2(4Uz`|CKCt^;wu0#
87
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
113
QRGb+i3L*dhhtM#y0PN=p0RR91
88
* to encompass the generic architectural permission check.
114
89
*/
115
literal 0
90
if (r->state != ARM_CP_STATE_AA32) {
116
HcmV?d00001
91
- int mask = 0;
117
92
+ CPAccessRights mask;
118
diff --git a/tests/data/acpi/virt/IORT.memhp b/tests/data/acpi/virt/IORT.memhp
93
switch (r->opc1) {
119
index XXXXXXX..XXXXXXX 100644
94
case 0:
120
GIT binary patch
95
/* min_EL EL1, but some accessible to EL0 via kernel ABI */
121
literal 124
122
zcmebD4+^Pa00MR=e`k+i1*eDrX9XZ&1PX!JAesq?4S*O7Bw!2(4Uz`|CKCt^;wu0#
123
QRGb+i3L*dhhtM#y0PN=p0RR91
124
125
literal 0
126
HcmV?d00001
127
128
diff --git a/tests/data/acpi/virt/IORT.numamem b/tests/data/acpi/virt/IORT.numamem
129
index XXXXXXX..XXXXXXX 100644
130
GIT binary patch
131
literal 124
132
zcmebD4+^Pa00MR=e`k+i1*eDrX9XZ&1PX!JAesq?4S*O7Bw!2(4Uz`|CKCt^;wu0#
133
QRGb+i3L*dhhtM#y0PN=p0RR91
134
135
literal 0
136
HcmV?d00001
137
138
diff --git a/tests/data/acpi/virt/IORT.pxb b/tests/data/acpi/virt/IORT.pxb
139
index XXXXXXX..XXXXXXX 100644
140
GIT binary patch
141
literal 124
142
zcmebD4+^Pa00MR=e`k+i1*eDrX9XZ&1PX!JAesq?4S*O7Bw!2(4Uz`|CKCt^;wu0#
143
QRGb+i3L*dhhtM#y0PN=p0RR91
144
145
literal 0
146
HcmV?d00001
147
148
--
96
--
149
2.20.1
97
2.25.1
150
151
diff view generated by jsdifflib
1
By default, QEMU will allow devices to be plugged into a bus up to
1
From: Richard Henderson <richard.henderson@linaro.org>
2
the bus class's device count limit. If the user creates a device on
3
the command line or via the monitor and doesn't explicitly specify
4
the bus to plug it in, QEMU will plug it into the first non-full bus
5
that it finds.
6
2
7
This is fine in most cases, but some machines have multiple buses of
3
Give this enum a name and use in ARMCPRegInfo,
8
a given type, some of which are dedicated to on-board devices and
4
add_cpreg_to_hashtable and define_one_arm_cp_reg_with_opaque.
9
some of which have an externally exposed connector for user-pluggable
10
devices. One example is I2C buses.
11
5
12
Provide a new function qbus_mark_full() so that a machine model can
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
mark this kind of "internal only" bus as 'full' after it has created
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
all the devices that should be plugged into that bus. The "find a
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
non-full bus" algorithm will then skip the internal-only bus when
9
Message-id: 20220501055028.646596-9-richard.henderson@linaro.org
16
looking for a place to plug in user-created devices.
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpregs.h | 6 +++---
13
target/arm/helper.c | 6 ++++--
14
2 files changed, 7 insertions(+), 5 deletions(-)
17
15
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-id: 20210903151435.22379-2-peter.maydell@linaro.org
21
---
22
include/hw/qdev-core.h | 24 ++++++++++++++++++++++++
23
softmmu/qdev-monitor.c | 7 ++++++-
24
2 files changed, 30 insertions(+), 1 deletion(-)
25
26
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
27
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/qdev-core.h
18
--- a/target/arm/cpregs.h
29
+++ b/include/hw/qdev-core.h
19
+++ b/target/arm/cpregs.h
30
@@ -XXX,XX +XXX,XX @@ struct BusState {
20
@@ -XXX,XX +XXX,XX @@ enum {
31
HotplugHandler *hotplug_handler;
21
* Note that we rely on the values of these enums as we iterate through
32
int max_index;
22
* the various states in some places.
33
bool realized;
23
*/
34
+ bool full;
24
-enum {
35
int num_children;
25
+typedef enum {
36
26
ARM_CP_STATE_AA32 = 0,
37
/*
27
ARM_CP_STATE_AA64 = 1,
38
@@ -XXX,XX +XXX,XX @@ static inline bool qbus_is_hotpluggable(BusState *bus)
28
ARM_CP_STATE_BOTH = 2,
39
return bus->hotplug_handler;
29
-};
30
+} CPState;
31
32
/*
33
* ARM CP register secure state flags. These flags identify security state
34
@@ -XXX,XX +XXX,XX @@ struct ARMCPRegInfo {
35
uint8_t opc1;
36
uint8_t opc2;
37
/* Execution state in which this register is visible: ARM_CP_STATE_* */
38
- int state;
39
+ CPState state;
40
/* Register type: ARM_CP_* bits/values */
41
int type;
42
/* Access rights: PL*_[RW] */
43
diff --git a/target/arm/helper.c b/target/arm/helper.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/helper.c
46
+++ b/target/arm/helper.c
47
@@ -XXX,XX +XXX,XX @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
40
}
48
}
41
49
42
+/**
50
static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
43
+ * qbus_mark_full: Mark this bus as full, so no more devices can be attached
51
- void *opaque, int state, int secstate,
44
+ * @bus: Bus to mark as full
52
+ void *opaque, CPState state, int secstate,
45
+ *
53
int crm, int opc1, int opc2,
46
+ * By default, QEMU will allow devices to be plugged into a bus up
54
const char *name)
47
+ * to the bus class's device count limit. Calling this function
55
{
48
+ * marks a particular bus as full, so that no more devices can be
56
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
49
+ * plugged into it. In particular this means that the bus will not
57
* bits; the ARM_CP_64BIT* flag applies only to the AArch32 view of
50
+ * be considered as a candidate for plugging in devices created by
58
* the register, if any.
51
+ * the user on the commandline or via the monitor.
59
*/
52
+ * If a machine has multiple buses of a given type, such as I2C,
60
- int crm, opc1, opc2, state;
53
+ * where some of those buses in the real hardware are used only for
61
+ int crm, opc1, opc2;
54
+ * internal devices and some are exposed via expansion ports, you
62
int crmmin = (r->crm == CP_ANY) ? 0 : r->crm;
55
+ * can use this function to mark the internal-only buses as full
63
int crmmax = (r->crm == CP_ANY) ? 15 : r->crm;
56
+ * after you have created all their internal devices. Then user
64
int opc1min = (r->opc1 == CP_ANY) ? 0 : r->opc1;
57
+ * created devices will appear on the expansion-port bus where
65
int opc1max = (r->opc1 == CP_ANY) ? 7 : r->opc1;
58
+ * guest software expects them.
66
int opc2min = (r->opc2 == CP_ANY) ? 0 : r->opc2;
59
+ */
67
int opc2max = (r->opc2 == CP_ANY) ? 7 : r->opc2;
60
+static inline void qbus_mark_full(BusState *bus)
68
+ CPState state;
61
+{
62
+ bus->full = true;
63
+}
64
+
69
+
65
void device_listener_register(DeviceListener *listener);
70
/* 64 bit registers have only CRm and Opc1 fields */
66
void device_listener_unregister(DeviceListener *listener);
71
assert(!((r->type & ARM_CP_64BIT) && (r->opc2 || r->crn)));
67
72
/* op0 only exists in the AArch64 encodings */
68
diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/softmmu/qdev-monitor.c
71
+++ b/softmmu/qdev-monitor.c
72
@@ -XXX,XX +XXX,XX @@ static DeviceState *qbus_find_dev(BusState *bus, char *elem)
73
74
static inline bool qbus_is_full(BusState *bus)
75
{
76
- BusClass *bus_class = BUS_GET_CLASS(bus);
77
+ BusClass *bus_class;
78
+
79
+ if (bus->full) {
80
+ return true;
81
+ }
82
+ bus_class = BUS_GET_CLASS(bus);
83
return bus_class->max_dev && bus->num_children >= bus_class->max_dev;
84
}
85
86
--
73
--
87
2.20.1
74
2.25.1
88
75
89
76
diff view generated by jsdifflib
1
The various MPS2 boards have multiple I2C buses: typically a bus
1
From: Richard Henderson <richard.henderson@linaro.org>
2
dedicated to the audio configuration, one for the LCD touchscreen
3
controller, one for a DDR4 EEPROM, and two which are connected to the
4
external Shield expansion connector. Mark the buses which are used
5
only for board-internal devices as 'full' so that if the user creates
6
i2c devices on the commandline without specifying a bus name then
7
they will be connected to the I2C controller used for the Shield
8
connector, where guest software will expect them.
9
2
3
Give this enum a name and use in ARMCPRegInfo and add_cpreg_to_hashtable.
4
Add the enumerator ARM_CP_SECSTATE_BOTH to clarify how 0
5
is handled in define_one_arm_cp_reg_with_opaque.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220501055028.646596-10-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210903151435.22379-4-peter.maydell@linaro.org
13
---
11
---
14
hw/arm/mps2-tz.c | 57 ++++++++++++++++++++++++++++++++++++------------
12
target/arm/cpregs.h | 7 ++++---
15
1 file changed, 43 insertions(+), 14 deletions(-)
13
target/arm/helper.c | 7 +++++--
14
2 files changed, 9 insertions(+), 5 deletions(-)
16
15
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/mps2-tz.c
18
--- a/target/arm/cpregs.h
20
+++ b/hw/arm/mps2-tz.c
19
+++ b/target/arm/cpregs.h
21
@@ -XXX,XX +XXX,XX @@ static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
20
@@ -XXX,XX +XXX,XX @@ typedef enum {
22
21
* registered entry will only have one to identify whether the entry is secure
23
/* Union describing the device-specific extra data we pass to the devfn. */
22
* or non-secure.
24
typedef union PPCExtraData {
23
*/
25
+ bool i2c_internal;
24
-enum {
26
} PPCExtraData;
25
+typedef enum {
27
26
+ ARM_CP_SECSTATE_BOTH = 0, /* define one cpreg for each secstate */
28
/* Most of the devices in the AN505 FPGA image sit behind
27
ARM_CP_SECSTATE_S = (1 << 0), /* bit[0]: Secure state register */
29
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
28
ARM_CP_SECSTATE_NS = (1 << 1), /* bit[1]: Non-secure state register */
30
object_initialize_child(OBJECT(mms), name, i2c, TYPE_ARM_SBCON_I2C);
29
-};
31
s = SYS_BUS_DEVICE(i2c);
30
+} CPSecureState;
32
sysbus_realize(s, &error_fatal);
31
33
+
32
/*
34
+ /*
33
* Access rights:
35
+ * If this is an internal-use-only i2c bus, mark it full
34
@@ -XXX,XX +XXX,XX @@ struct ARMCPRegInfo {
36
+ * so that user-created i2c devices are not plugged into it.
35
/* Access rights: PL*_[RW] */
37
+ * If we implement models of any on-board i2c devices that
36
CPAccessRights access;
38
+ * plug in to one of the internal-use-only buses, then we will
37
/* Security state: ARM_CP_SECSTATE_* bits/values */
39
+ * need to create and plugging those in here before we mark the
38
- int secure;
40
+ * bus as full.
39
+ CPSecureState secure;
41
+ */
40
/*
42
+ if (extradata->i2c_internal) {
41
* The opaque pointer passed to define_arm_cp_regs_with_opaque() when
43
+ BusState *qbus = qdev_get_child_bus(DEVICE(i2c), "i2c");
42
* this register was defined: can be used to hand data through to the
44
+ qbus_mark_full(qbus);
43
diff --git a/target/arm/helper.c b/target/arm/helper.c
45
+ }
44
index XXXXXXX..XXXXXXX 100644
46
+
45
--- a/target/arm/helper.c
47
return sysbus_mmio_get_region(s, 0);
46
+++ b/target/arm/helper.c
47
@@ -XXX,XX +XXX,XX @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
48
}
48
}
49
49
50
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
50
static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
51
{ "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000, { 36, 37, 44 } },
51
- void *opaque, CPState state, int secstate,
52
{ "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000, { 38, 39, 45 } },
52
+ void *opaque, CPState state,
53
{ "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000, { 40, 41, 46 } },
53
+ CPSecureState secstate,
54
- { "i2c0", make_i2c, &mms->i2c[0], 0x40207000, 0x1000 },
54
int crm, int opc1, int opc2,
55
- { "i2c1", make_i2c, &mms->i2c[1], 0x40208000, 0x1000 },
55
const char *name)
56
- { "i2c2", make_i2c, &mms->i2c[2], 0x4020c000, 0x1000 },
56
{
57
- { "i2c3", make_i2c, &mms->i2c[3], 0x4020d000, 0x1000 },
57
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
58
+ { "i2c0", make_i2c, &mms->i2c[0], 0x40207000, 0x1000, {},
58
r->secure, crm, opc1, opc2,
59
+ { .i2c_internal = true /* touchscreen */ } },
59
r->name);
60
+ { "i2c1", make_i2c, &mms->i2c[1], 0x40208000, 0x1000, {},
60
break;
61
+ { .i2c_internal = true /* audio conf */ } },
61
- default:
62
+ { "i2c2", make_i2c, &mms->i2c[2], 0x4020c000, 0x1000, {},
62
+ case ARM_CP_SECSTATE_BOTH:
63
+ { .i2c_internal = false /* shield 0 */ } },
63
name = g_strdup_printf("%s_S", r->name);
64
+ { "i2c3", make_i2c, &mms->i2c[3], 0x4020d000, 0x1000, {},
64
add_cpreg_to_hashtable(cpu, r, opaque, state,
65
+ { .i2c_internal = false /* shield 1 */ } },
65
ARM_CP_SECSTATE_S,
66
},
66
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
67
}, {
67
ARM_CP_SECSTATE_NS,
68
.name = "apb_ppcexp2",
68
crm, opc1, opc2, r->name);
69
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
69
break;
70
}, {
70
+ default:
71
.name = "apb_ppcexp1",
71
+ g_assert_not_reached();
72
.ports = {
72
}
73
- { "i2c0", make_i2c, &mms->i2c[0], 0x41200000, 0x1000 },
73
} else {
74
- { "i2c1", make_i2c, &mms->i2c[1], 0x41201000, 0x1000 },
74
/* AArch64 registers get mapped to non-secure instance
75
+ { "i2c0", make_i2c, &mms->i2c[0], 0x41200000, 0x1000, {},
76
+ { .i2c_internal = true /* touchscreen */ } },
77
+ { "i2c1", make_i2c, &mms->i2c[1], 0x41201000, 0x1000, {},
78
+ { .i2c_internal = true /* audio conf */ } },
79
{ "spi0", make_spi, &mms->spi[0], 0x41202000, 0x1000, { 52 } },
80
{ "spi1", make_spi, &mms->spi[1], 0x41203000, 0x1000, { 53 } },
81
{ "spi2", make_spi, &mms->spi[2], 0x41204000, 0x1000, { 54 } },
82
- { "i2c2", make_i2c, &mms->i2c[2], 0x41205000, 0x1000 },
83
- { "i2c3", make_i2c, &mms->i2c[3], 0x41206000, 0x1000 },
84
+ { "i2c2", make_i2c, &mms->i2c[2], 0x41205000, 0x1000, {},
85
+ { .i2c_internal = false /* shield 0 */ } },
86
+ { "i2c3", make_i2c, &mms->i2c[3], 0x41206000, 0x1000, {},
87
+ { .i2c_internal = false /* shield 1 */ } },
88
{ /* port 7 reserved */ },
89
- { "i2c4", make_i2c, &mms->i2c[4], 0x41208000, 0x1000 },
90
+ { "i2c4", make_i2c, &mms->i2c[4], 0x41208000, 0x1000, {},
91
+ { .i2c_internal = true /* DDR4 EEPROM */ } },
92
},
93
}, {
94
.name = "apb_ppcexp2",
95
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
96
}, {
97
.name = "apb_ppcexp1",
98
.ports = {
99
- { "i2c0", make_i2c, &mms->i2c[0], 0x49200000, 0x1000 },
100
- { "i2c1", make_i2c, &mms->i2c[1], 0x49201000, 0x1000 },
101
+ { "i2c0", make_i2c, &mms->i2c[0], 0x49200000, 0x1000, {},
102
+ { .i2c_internal = true /* touchscreen */ } },
103
+ { "i2c1", make_i2c, &mms->i2c[1], 0x49201000, 0x1000, {},
104
+ { .i2c_internal = true /* audio conf */ } },
105
{ "spi0", make_spi, &mms->spi[0], 0x49202000, 0x1000, { 53 } },
106
{ "spi1", make_spi, &mms->spi[1], 0x49203000, 0x1000, { 54 } },
107
{ "spi2", make_spi, &mms->spi[2], 0x49204000, 0x1000, { 55 } },
108
- { "i2c2", make_i2c, &mms->i2c[2], 0x49205000, 0x1000 },
109
- { "i2c3", make_i2c, &mms->i2c[3], 0x49206000, 0x1000 },
110
+ { "i2c2", make_i2c, &mms->i2c[2], 0x49205000, 0x1000, {},
111
+ { .i2c_internal = false /* shield 0 */ } },
112
+ { "i2c3", make_i2c, &mms->i2c[3], 0x49206000, 0x1000, {},
113
+ { .i2c_internal = false /* shield 1 */ } },
114
{ /* port 7 reserved */ },
115
- { "i2c4", make_i2c, &mms->i2c[4], 0x49208000, 0x1000 },
116
+ { "i2c4", make_i2c, &mms->i2c[4], 0x49208000, 0x1000, {},
117
+ { .i2c_internal = true /* DDR4 EEPROM */ } },
118
},
119
}, {
120
.name = "apb_ppcexp2",
121
--
75
--
122
2.20.1
76
2.25.1
123
124
diff view generated by jsdifflib
1
From: Shashi Mallela <shashi.mallela@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Added expected IORT files applicable with latest GICv3
3
The new_key field is always non-zero -- drop the if.
4
ITS changes.Temporarily differences in these files are
5
okay.
6
4
7
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Acked-by: Igor Mammedov <imammedo@redhat.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20210910143951.92242-8-shashi.mallela@linaro.org
7
Message-id: 20220501055028.646596-11-richard.henderson@linaro.org
8
[PMM: reinstated dropped PL3_RW mask]
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
tests/qtest/bios-tables-test-allowed-diff.h | 4 ++++
11
target/arm/helper.c | 23 +++++++++++------------
14
tests/data/acpi/virt/IORT | 0
12
1 file changed, 11 insertions(+), 12 deletions(-)
15
tests/data/acpi/virt/IORT.memhp | 0
16
tests/data/acpi/virt/IORT.numamem | 0
17
tests/data/acpi/virt/IORT.pxb | 0
18
5 files changed, 4 insertions(+)
19
create mode 100644 tests/data/acpi/virt/IORT
20
create mode 100644 tests/data/acpi/virt/IORT.memhp
21
create mode 100644 tests/data/acpi/virt/IORT.numamem
22
create mode 100644 tests/data/acpi/virt/IORT.pxb
23
13
24
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/tests/qtest/bios-tables-test-allowed-diff.h
16
--- a/target/arm/helper.c
27
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
17
+++ b/target/arm/helper.c
28
@@ -1 +1,5 @@
18
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
29
/* List of comma-separated changed AML files to ignore */
19
30
+"tests/data/acpi/virt/IORT",
20
for (i = 0; i < ARRAY_SIZE(aliases); i++) {
31
+"tests/data/acpi/virt/IORT.memhp",
21
const struct E2HAlias *a = &aliases[i];
32
+"tests/data/acpi/virt/IORT.numamem",
22
- ARMCPRegInfo *src_reg, *dst_reg;
33
+"tests/data/acpi/virt/IORT.pxb",
23
+ ARMCPRegInfo *src_reg, *dst_reg, *new_reg;
34
diff --git a/tests/data/acpi/virt/IORT b/tests/data/acpi/virt/IORT
24
+ uint32_t *new_key;
35
new file mode 100644
25
+ bool ok;
36
index XXXXXXX..XXXXXXX
26
37
diff --git a/tests/data/acpi/virt/IORT.memhp b/tests/data/acpi/virt/IORT.memhp
27
if (a->feature && !a->feature(&cpu->isar)) {
38
new file mode 100644
28
continue;
39
index XXXXXXX..XXXXXXX
29
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
40
diff --git a/tests/data/acpi/virt/IORT.numamem b/tests/data/acpi/virt/IORT.numamem
30
g_assert(src_reg->opaque == NULL);
41
new file mode 100644
31
42
index XXXXXXX..XXXXXXX
32
/* Create alias before redirection so we dup the right data. */
43
diff --git a/tests/data/acpi/virt/IORT.pxb b/tests/data/acpi/virt/IORT.pxb
33
- if (a->new_key) {
44
new file mode 100644
34
- ARMCPRegInfo *new_reg = g_memdup(src_reg, sizeof(ARMCPRegInfo));
45
index XXXXXXX..XXXXXXX
35
- uint32_t *new_key = g_memdup(&a->new_key, sizeof(uint32_t));
36
- bool ok;
37
+ new_reg = g_memdup(src_reg, sizeof(ARMCPRegInfo));
38
+ new_key = g_memdup(&a->new_key, sizeof(uint32_t));
39
40
- new_reg->name = a->new_name;
41
- new_reg->type |= ARM_CP_ALIAS;
42
- /* Remove PL1/PL0 access, leaving PL2/PL3 R/W in place. */
43
- new_reg->access &= PL2_RW | PL3_RW;
44
+ new_reg->name = a->new_name;
45
+ new_reg->type |= ARM_CP_ALIAS;
46
+ /* Remove PL1/PL0 access, leaving PL2/PL3 R/W in place. */
47
+ new_reg->access &= PL2_RW | PL3_RW;
48
49
- ok = g_hash_table_insert(cpu->cp_regs, new_key, new_reg);
50
- g_assert(ok);
51
- }
52
+ ok = g_hash_table_insert(cpu->cp_regs, new_key, new_reg);
53
+ g_assert(ok);
54
55
src_reg->opaque = dst_reg;
56
src_reg->orig_readfn = src_reg->readfn ?: raw_read;
46
--
57
--
47
2.20.1
58
2.25.1
48
49
diff view generated by jsdifflib
1
From: Shashi Mallela <shashi.mallela@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Defined descriptors for ITS device table,collection table and ITS
3
Cast the uint32_t key into a gpointer directly, which
4
command queue entities.Implemented register read/write functions,
4
allows us to avoid allocating storage for each key.
5
extract ITS table parameters and command queue parameters,extended
6
gicv3 common to capture qemu address space(which host the ITS table
7
platform memories required for subsequent ITS processing) and
8
initialize the same in ITS device.
9
5
10
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
6
Use g_hash_table_lookup when we already have a gpointer
7
(e.g. for callbacks like count_cpreg), or when using
8
get_arm_cp_reginfo would require casting away const.
9
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Eric Auger <eric.auger@redhat.com>
12
Message-id: 20220501055028.646596-12-richard.henderson@linaro.org
13
Tested-by: Neil Armstrong <narmstrong@baylibre.com>
14
Message-id: 20210910143951.92242-3-shashi.mallela@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
14
---
17
hw/intc/gicv3_internal.h | 29 ++
15
target/arm/cpu.c | 4 ++--
18
include/hw/intc/arm_gicv3_common.h | 3 +
16
target/arm/gdbstub.c | 2 +-
19
include/hw/intc/arm_gicv3_its_common.h | 23 ++
17
target/arm/helper.c | 41 ++++++++++++++++++-----------------------
20
hw/intc/arm_gicv3_its.c | 376 +++++++++++++++++++++++++
18
3 files changed, 21 insertions(+), 26 deletions(-)
21
4 files changed, 431 insertions(+)
22
19
23
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
20
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
24
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/intc/gicv3_internal.h
22
--- a/target/arm/cpu.c
26
+++ b/hw/intc/gicv3_internal.h
23
+++ b/target/arm/cpu.c
27
@@ -XXX,XX +XXX,XX @@ FIELD(GITS_BASER, INNERCACHE, 59, 3)
24
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_initfn(Object *obj)
28
FIELD(GITS_BASER, INDIRECT, 62, 1)
25
ARMCPU *cpu = ARM_CPU(obj);
29
FIELD(GITS_BASER, VALID, 63, 1)
26
30
27
cpu_set_cpustate_pointers(cpu);
31
+FIELD(GITS_CBASER, SIZE, 0, 8)
28
- cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
32
+FIELD(GITS_CBASER, SHAREABILITY, 10, 2)
29
- g_free, cpreg_hashtable_data_destroy);
33
+FIELD(GITS_CBASER, PHYADDR, 12, 40)
30
+ cpu->cp_regs = g_hash_table_new_full(g_direct_hash, g_direct_equal,
34
+FIELD(GITS_CBASER, OUTERCACHE, 53, 3)
31
+ NULL, cpreg_hashtable_data_destroy);
35
+FIELD(GITS_CBASER, INNERCACHE, 59, 3)
32
36
+FIELD(GITS_CBASER, VALID, 63, 1)
33
QLIST_INIT(&cpu->pre_el_change_hooks);
37
+
34
QLIST_INIT(&cpu->el_change_hooks);
38
+FIELD(GITS_CREADR, STALLED, 0, 1)
35
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
39
+FIELD(GITS_CREADR, OFFSET, 5, 15)
40
+
41
+FIELD(GITS_CWRITER, RETRY, 0, 1)
42
+FIELD(GITS_CWRITER, OFFSET, 5, 15)
43
+
44
+FIELD(GITS_CTLR, ENABLED, 0, 1)
45
FIELD(GITS_CTLR, QUIESCENT, 31, 1)
46
47
FIELD(GITS_TYPER, PHYSICAL, 0, 1)
48
@@ -XXX,XX +XXX,XX @@ FIELD(GITS_TYPER, PTA, 19, 1)
49
FIELD(GITS_TYPER, CIDBITS, 32, 4)
50
FIELD(GITS_TYPER, CIL, 36, 1)
51
52
+#define GITS_IDREGS 0xFFD0
53
+
54
+#define ITS_CTLR_ENABLED (1U) /* ITS Enabled */
55
+
56
+#define GITS_BASER_RO_MASK (R_GITS_BASER_ENTRYSIZE_MASK | \
57
+ R_GITS_BASER_TYPE_MASK)
58
+
59
#define GITS_BASER_PAGESIZE_4K 0
60
#define GITS_BASER_PAGESIZE_16K 1
61
#define GITS_BASER_PAGESIZE_64K 2
62
@@ -XXX,XX +XXX,XX @@ FIELD(GITS_TYPER, CIL, 36, 1)
63
#define GITS_BASER_TYPE_DEVICE 1ULL
64
#define GITS_BASER_TYPE_COLLECTION 4ULL
65
66
+#define GITS_PAGE_SIZE_4K 0x1000
67
+#define GITS_PAGE_SIZE_16K 0x4000
68
+#define GITS_PAGE_SIZE_64K 0x10000
69
+
70
+#define L1TABLE_ENTRY_SIZE 8
71
+
72
+#define GITS_CMDQ_ENTRY_SIZE 32
73
+
74
/**
75
* Default features advertised by this version of ITS
76
*/
77
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
78
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
79
--- a/include/hw/intc/arm_gicv3_common.h
37
--- a/target/arm/gdbstub.c
80
+++ b/include/hw/intc/arm_gicv3_common.h
38
+++ b/target/arm/gdbstub.c
81
@@ -XXX,XX +XXX,XX @@ struct GICv3State {
39
@@ -XXX,XX +XXX,XX @@ static void arm_gen_one_xml_sysreg_tag(GString *s, DynamicGDBXMLInfo *dyn_xml,
82
int dev_fd; /* kvm device fd if backed by kvm vgic support */
40
static void arm_register_sysreg_for_xml(gpointer key, gpointer value,
83
Error *migration_blocker;
41
gpointer p)
84
42
{
85
+ MemoryRegion *dma;
43
- uint32_t ri_key = *(uint32_t *)key;
86
+ AddressSpace dma_as;
44
+ uint32_t ri_key = (uintptr_t)key;
87
+
45
ARMCPRegInfo *ri = value;
88
/* Distributor */
46
RegisterSysregXmlParam *param = (RegisterSysregXmlParam *)p;
89
47
GString *s = param->s;
90
/* for a GIC with the security extensions the NS banked version of this
48
diff --git a/target/arm/helper.c b/target/arm/helper.c
91
diff --git a/include/hw/intc/arm_gicv3_its_common.h b/include/hw/intc/arm_gicv3_its_common.h
92
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
93
--- a/include/hw/intc/arm_gicv3_its_common.h
50
--- a/target/arm/helper.c
94
+++ b/include/hw/intc/arm_gicv3_its_common.h
51
+++ b/target/arm/helper.c
95
@@ -XXX,XX +XXX,XX @@
52
@@ -XXX,XX +XXX,XX @@ bool write_list_to_cpustate(ARMCPU *cpu)
96
53
static void add_cpreg_to_list(gpointer key, gpointer opaque)
97
#define GITS_TRANSLATER 0x0040
98
99
+typedef struct {
100
+ bool valid;
101
+ bool indirect;
102
+ uint16_t entry_sz;
103
+ uint32_t page_sz;
104
+ uint32_t max_entries;
105
+ union {
106
+ uint32_t max_devids;
107
+ uint32_t max_collids;
108
+ } maxids;
109
+ uint64_t base_addr;
110
+} TableDesc;
111
+
112
+typedef struct {
113
+ bool valid;
114
+ uint32_t max_entries;
115
+ uint64_t base_addr;
116
+} CmdQDesc;
117
+
118
struct GICv3ITSState {
119
SysBusDevice parent_obj;
120
121
@@ -XXX,XX +XXX,XX @@ struct GICv3ITSState {
122
uint64_t creadr;
123
uint64_t baser[8];
124
125
+ TableDesc dt;
126
+ TableDesc ct;
127
+ CmdQDesc cq;
128
+
129
Error *migration_blocker;
130
};
131
132
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/hw/intc/arm_gicv3_its.c
135
+++ b/hw/intc/arm_gicv3_its.c
136
@@ -XXX,XX +XXX,XX @@ struct GICv3ITSClass {
137
void (*parent_reset)(DeviceState *dev);
138
};
139
140
+static uint64_t baser_base_addr(uint64_t value, uint32_t page_sz)
141
+{
142
+ uint64_t result = 0;
143
+
144
+ switch (page_sz) {
145
+ case GITS_PAGE_SIZE_4K:
146
+ case GITS_PAGE_SIZE_16K:
147
+ result = FIELD_EX64(value, GITS_BASER, PHYADDR) << 12;
148
+ break;
149
+
150
+ case GITS_PAGE_SIZE_64K:
151
+ result = FIELD_EX64(value, GITS_BASER, PHYADDRL_64K) << 16;
152
+ result |= FIELD_EX64(value, GITS_BASER, PHYADDRH_64K) << 48;
153
+ break;
154
+
155
+ default:
156
+ break;
157
+ }
158
+ return result;
159
+}
160
+
161
+/*
162
+ * This function extracts the ITS Device and Collection table specific
163
+ * parameters (like base_addr, size etc) from GITS_BASER register.
164
+ * It is called during ITS enable and also during post_load migration
165
+ */
166
+static void extract_table_params(GICv3ITSState *s)
167
+{
168
+ uint16_t num_pages = 0;
169
+ uint8_t page_sz_type;
170
+ uint8_t type;
171
+ uint32_t page_sz = 0;
172
+ uint64_t value;
173
+
174
+ for (int i = 0; i < 8; i++) {
175
+ value = s->baser[i];
176
+
177
+ if (!value) {
178
+ continue;
179
+ }
180
+
181
+ page_sz_type = FIELD_EX64(value, GITS_BASER, PAGESIZE);
182
+
183
+ switch (page_sz_type) {
184
+ case 0:
185
+ page_sz = GITS_PAGE_SIZE_4K;
186
+ break;
187
+
188
+ case 1:
189
+ page_sz = GITS_PAGE_SIZE_16K;
190
+ break;
191
+
192
+ case 2:
193
+ case 3:
194
+ page_sz = GITS_PAGE_SIZE_64K;
195
+ break;
196
+
197
+ default:
198
+ g_assert_not_reached();
199
+ }
200
+
201
+ num_pages = FIELD_EX64(value, GITS_BASER, SIZE) + 1;
202
+
203
+ type = FIELD_EX64(value, GITS_BASER, TYPE);
204
+
205
+ switch (type) {
206
+
207
+ case GITS_BASER_TYPE_DEVICE:
208
+ memset(&s->dt, 0 , sizeof(s->dt));
209
+ s->dt.valid = FIELD_EX64(value, GITS_BASER, VALID);
210
+
211
+ if (!s->dt.valid) {
212
+ return;
213
+ }
214
+
215
+ s->dt.page_sz = page_sz;
216
+ s->dt.indirect = FIELD_EX64(value, GITS_BASER, INDIRECT);
217
+ s->dt.entry_sz = FIELD_EX64(value, GITS_BASER, ENTRYSIZE);
218
+
219
+ if (!s->dt.indirect) {
220
+ s->dt.max_entries = (num_pages * page_sz) / s->dt.entry_sz;
221
+ } else {
222
+ s->dt.max_entries = (((num_pages * page_sz) /
223
+ L1TABLE_ENTRY_SIZE) *
224
+ (page_sz / s->dt.entry_sz));
225
+ }
226
+
227
+ s->dt.maxids.max_devids = (1UL << (FIELD_EX64(s->typer, GITS_TYPER,
228
+ DEVBITS) + 1));
229
+
230
+ s->dt.base_addr = baser_base_addr(value, page_sz);
231
+
232
+ break;
233
+
234
+ case GITS_BASER_TYPE_COLLECTION:
235
+ memset(&s->ct, 0 , sizeof(s->ct));
236
+ s->ct.valid = FIELD_EX64(value, GITS_BASER, VALID);
237
+
238
+ /*
239
+ * GITS_TYPER.HCC is 0 for this implementation
240
+ * hence writes are discarded if ct.valid is 0
241
+ */
242
+ if (!s->ct.valid) {
243
+ return;
244
+ }
245
+
246
+ s->ct.page_sz = page_sz;
247
+ s->ct.indirect = FIELD_EX64(value, GITS_BASER, INDIRECT);
248
+ s->ct.entry_sz = FIELD_EX64(value, GITS_BASER, ENTRYSIZE);
249
+
250
+ if (!s->ct.indirect) {
251
+ s->ct.max_entries = (num_pages * page_sz) / s->ct.entry_sz;
252
+ } else {
253
+ s->ct.max_entries = (((num_pages * page_sz) /
254
+ L1TABLE_ENTRY_SIZE) *
255
+ (page_sz / s->ct.entry_sz));
256
+ }
257
+
258
+ if (FIELD_EX64(s->typer, GITS_TYPER, CIL)) {
259
+ s->ct.maxids.max_collids = (1UL << (FIELD_EX64(s->typer,
260
+ GITS_TYPER, CIDBITS) + 1));
261
+ } else {
262
+ /* 16-bit CollectionId supported when CIL == 0 */
263
+ s->ct.maxids.max_collids = (1UL << 16);
264
+ }
265
+
266
+ s->ct.base_addr = baser_base_addr(value, page_sz);
267
+
268
+ break;
269
+
270
+ default:
271
+ break;
272
+ }
273
+ }
274
+}
275
+
276
+static void extract_cmdq_params(GICv3ITSState *s)
277
+{
278
+ uint16_t num_pages = 0;
279
+ uint64_t value = s->cbaser;
280
+
281
+ num_pages = FIELD_EX64(value, GITS_CBASER, SIZE) + 1;
282
+
283
+ memset(&s->cq, 0 , sizeof(s->cq));
284
+ s->cq.valid = FIELD_EX64(value, GITS_CBASER, VALID);
285
+
286
+ if (s->cq.valid) {
287
+ s->cq.max_entries = (num_pages * GITS_PAGE_SIZE_4K) /
288
+ GITS_CMDQ_ENTRY_SIZE;
289
+ s->cq.base_addr = FIELD_EX64(value, GITS_CBASER, PHYADDR);
290
+ s->cq.base_addr <<= R_GITS_CBASER_PHYADDR_SHIFT;
291
+ }
292
+}
293
+
294
static MemTxResult gicv3_its_translation_write(void *opaque, hwaddr offset,
295
uint64_t data, unsigned size,
296
MemTxAttrs attrs)
297
@@ -XXX,XX +XXX,XX @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
298
uint64_t value, MemTxAttrs attrs)
299
{
54
{
300
bool result = true;
55
ARMCPU *cpu = opaque;
301
+ int index;
56
- uint64_t regidx;
302
57
- const ARMCPRegInfo *ri;
303
+ switch (offset) {
58
-
304
+ case GITS_CTLR:
59
- regidx = *(uint32_t *)key;
305
+ s->ctlr |= (value & ~(s->ctlr));
60
- ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
306
+
61
+ uint32_t regidx = (uintptr_t)key;
307
+ if (s->ctlr & ITS_CTLR_ENABLED) {
62
+ const ARMCPRegInfo *ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
308
+ extract_table_params(s);
63
309
+ extract_cmdq_params(s);
64
if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) {
310
+ s->creadr = 0;
65
cpu->cpreg_indexes[cpu->cpreg_array_len] = cpreg_to_kvm_id(regidx);
311
+ }
66
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_list(gpointer key, gpointer opaque)
312
+ break;
67
static void count_cpreg(gpointer key, gpointer opaque)
313
+ case GITS_CBASER:
68
{
314
+ /*
69
ARMCPU *cpu = opaque;
315
+ * IMPDEF choice:- GITS_CBASER register becomes RO if ITS is
70
- uint64_t regidx;
316
+ * already enabled
71
const ARMCPRegInfo *ri;
317
+ */
72
318
+ if (!(s->ctlr & ITS_CTLR_ENABLED)) {
73
- regidx = *(uint32_t *)key;
319
+ s->cbaser = deposit64(s->cbaser, 0, 32, value);
74
- ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
320
+ s->creadr = 0;
75
+ ri = g_hash_table_lookup(cpu->cp_regs, key);
321
+ s->cwriter = s->creadr;
76
322
+ }
77
if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) {
323
+ break;
78
cpu->cpreg_array_len++;
324
+ case GITS_CBASER + 4:
79
@@ -XXX,XX +XXX,XX @@ static void count_cpreg(gpointer key, gpointer opaque)
325
+ /*
80
326
+ * IMPDEF choice:- GITS_CBASER register becomes RO if ITS is
81
static gint cpreg_key_compare(gconstpointer a, gconstpointer b)
327
+ * already enabled
82
{
328
+ */
83
- uint64_t aidx = cpreg_to_kvm_id(*(uint32_t *)a);
329
+ if (!(s->ctlr & ITS_CTLR_ENABLED)) {
84
- uint64_t bidx = cpreg_to_kvm_id(*(uint32_t *)b);
330
+ s->cbaser = deposit64(s->cbaser, 32, 32, value);
85
+ uint64_t aidx = cpreg_to_kvm_id((uintptr_t)a);
331
+ s->creadr = 0;
86
+ uint64_t bidx = cpreg_to_kvm_id((uintptr_t)b);
332
+ s->cwriter = s->creadr;
87
333
+ }
88
if (aidx > bidx) {
334
+ break;
89
return 1;
335
+ case GITS_CWRITER:
90
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
336
+ s->cwriter = deposit64(s->cwriter, 0, 32,
91
for (i = 0; i < ARRAY_SIZE(aliases); i++) {
337
+ (value & ~R_GITS_CWRITER_RETRY_MASK));
92
const struct E2HAlias *a = &aliases[i];
338
+ break;
93
ARMCPRegInfo *src_reg, *dst_reg, *new_reg;
339
+ case GITS_CWRITER + 4:
94
- uint32_t *new_key;
340
+ s->cwriter = deposit64(s->cwriter, 32, 32, value);
95
bool ok;
341
+ break;
96
342
+ case GITS_CREADR:
97
if (a->feature && !a->feature(&cpu->isar)) {
343
+ if (s->gicv3->gicd_ctlr & GICD_CTLR_DS) {
98
continue;
344
+ s->creadr = deposit64(s->creadr, 0, 32,
99
}
345
+ (value & ~R_GITS_CREADR_STALLED_MASK));
100
346
+ } else {
101
- src_reg = g_hash_table_lookup(cpu->cp_regs, &a->src_key);
347
+ /* RO register, ignore the write */
102
- dst_reg = g_hash_table_lookup(cpu->cp_regs, &a->dst_key);
348
+ qemu_log_mask(LOG_GUEST_ERROR,
103
+ src_reg = g_hash_table_lookup(cpu->cp_regs,
349
+ "%s: invalid guest write to RO register at offset "
104
+ (gpointer)(uintptr_t)a->src_key);
350
+ TARGET_FMT_plx "\n", __func__, offset);
105
+ dst_reg = g_hash_table_lookup(cpu->cp_regs,
351
+ }
106
+ (gpointer)(uintptr_t)a->dst_key);
352
+ break;
107
g_assert(src_reg != NULL);
353
+ case GITS_CREADR + 4:
108
g_assert(dst_reg != NULL);
354
+ if (s->gicv3->gicd_ctlr & GICD_CTLR_DS) {
109
355
+ s->creadr = deposit64(s->creadr, 32, 32, value);
110
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
356
+ } else {
111
357
+ /* RO register, ignore the write */
112
/* Create alias before redirection so we dup the right data. */
358
+ qemu_log_mask(LOG_GUEST_ERROR,
113
new_reg = g_memdup(src_reg, sizeof(ARMCPRegInfo));
359
+ "%s: invalid guest write to RO register at offset "
114
- new_key = g_memdup(&a->new_key, sizeof(uint32_t));
360
+ TARGET_FMT_plx "\n", __func__, offset);
115
361
+ }
116
new_reg->name = a->new_name;
362
+ break;
117
new_reg->type |= ARM_CP_ALIAS;
363
+ case GITS_BASER ... GITS_BASER + 0x3f:
118
/* Remove PL1/PL0 access, leaving PL2/PL3 R/W in place. */
364
+ /*
119
new_reg->access &= PL2_RW | PL3_RW;
365
+ * IMPDEF choice:- GITS_BASERn register becomes RO if ITS is
120
366
+ * already enabled
121
- ok = g_hash_table_insert(cpu->cp_regs, new_key, new_reg);
367
+ */
122
+ ok = g_hash_table_insert(cpu->cp_regs,
368
+ if (!(s->ctlr & ITS_CTLR_ENABLED)) {
123
+ (gpointer)(uintptr_t)a->new_key, new_reg);
369
+ index = (offset - GITS_BASER) / 8;
124
g_assert(ok);
370
+
125
371
+ if (offset & 7) {
126
src_reg->opaque = dst_reg;
372
+ value <<= 32;
127
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
373
+ value &= ~GITS_BASER_RO_MASK;
128
/* Private utility function for define_one_arm_cp_reg_with_opaque():
374
+ s->baser[index] &= GITS_BASER_RO_MASK | MAKE_64BIT_MASK(0, 32);
129
* add a single reginfo struct to the hash table.
375
+ s->baser[index] |= value;
130
*/
376
+ } else {
131
- uint32_t *key = g_new(uint32_t, 1);
377
+ value &= ~GITS_BASER_RO_MASK;
132
+ uint32_t key;
378
+ s->baser[index] &= GITS_BASER_RO_MASK | MAKE_64BIT_MASK(32, 32);
133
ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
379
+ s->baser[index] |= value;
134
int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
380
+ }
135
int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
381
+ }
136
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
382
+ break;
137
if (r->cp == 0 || r->state == ARM_CP_STATE_BOTH) {
383
+ case GITS_IIDR:
138
r2->cp = CP_REG_ARM64_SYSREG_CP;
384
+ case GITS_IDREGS ... GITS_IDREGS + 0x2f:
139
}
385
+ /* RO registers, ignore the write */
140
- *key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm,
386
+ qemu_log_mask(LOG_GUEST_ERROR,
141
- r2->opc0, opc1, opc2);
387
+ "%s: invalid guest write to RO register at offset "
142
+ key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm,
388
+ TARGET_FMT_plx "\n", __func__, offset);
143
+ r2->opc0, opc1, opc2);
389
+ break;
144
} else {
390
+ default:
145
- *key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2);
391
+ result = false;
146
+ key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2);
392
+ break;
147
}
393
+ }
148
if (opaque) {
394
return result;
149
r2->opaque = opaque;
150
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
151
* requested.
152
*/
153
if (!(r->type & ARM_CP_OVERRIDE)) {
154
- ARMCPRegInfo *oldreg;
155
- oldreg = g_hash_table_lookup(cpu->cp_regs, key);
156
+ const ARMCPRegInfo *oldreg = get_arm_cp_reginfo(cpu->cp_regs, key);
157
if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) {
158
fprintf(stderr, "Register redefined: cp=%d %d bit "
159
"crn=%d crm=%d opc1=%d opc2=%d, "
160
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
161
g_assert_not_reached();
162
}
163
}
164
- g_hash_table_insert(cpu->cp_regs, key, r2);
165
+ g_hash_table_insert(cpu->cp_regs, (gpointer)(uintptr_t)key, r2);
395
}
166
}
396
167
397
@@ -XXX,XX +XXX,XX @@ static bool its_readl(GICv3ITSState *s, hwaddr offset,
168
398
uint64_t *data, MemTxAttrs attrs)
169
@@ -XXX,XX +XXX,XX @@ void modify_arm_cp_regs_with_len(ARMCPRegInfo *regs, size_t regs_len,
170
171
const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp)
399
{
172
{
400
bool result = true;
173
- return g_hash_table_lookup(cpregs, &encoded_cp);
401
+ int index;
174
+ return g_hash_table_lookup(cpregs, (gpointer)(uintptr_t)encoded_cp);
402
403
+ switch (offset) {
404
+ case GITS_CTLR:
405
+ *data = s->ctlr;
406
+ break;
407
+ case GITS_IIDR:
408
+ *data = gicv3_iidr();
409
+ break;
410
+ case GITS_IDREGS ... GITS_IDREGS + 0x2f:
411
+ /* ID registers */
412
+ *data = gicv3_idreg(offset - GITS_IDREGS);
413
+ break;
414
+ case GITS_TYPER:
415
+ *data = extract64(s->typer, 0, 32);
416
+ break;
417
+ case GITS_TYPER + 4:
418
+ *data = extract64(s->typer, 32, 32);
419
+ break;
420
+ case GITS_CBASER:
421
+ *data = extract64(s->cbaser, 0, 32);
422
+ break;
423
+ case GITS_CBASER + 4:
424
+ *data = extract64(s->cbaser, 32, 32);
425
+ break;
426
+ case GITS_CREADR:
427
+ *data = extract64(s->creadr, 0, 32);
428
+ break;
429
+ case GITS_CREADR + 4:
430
+ *data = extract64(s->creadr, 32, 32);
431
+ break;
432
+ case GITS_CWRITER:
433
+ *data = extract64(s->cwriter, 0, 32);
434
+ break;
435
+ case GITS_CWRITER + 4:
436
+ *data = extract64(s->cwriter, 32, 32);
437
+ break;
438
+ case GITS_BASER ... GITS_BASER + 0x3f:
439
+ index = (offset - GITS_BASER) / 8;
440
+ if (offset & 7) {
441
+ *data = extract64(s->baser[index], 32, 32);
442
+ } else {
443
+ *data = extract64(s->baser[index], 0, 32);
444
+ }
445
+ break;
446
+ default:
447
+ result = false;
448
+ break;
449
+ }
450
return result;
451
}
175
}
452
176
453
@@ -XXX,XX +XXX,XX @@ static bool its_writell(GICv3ITSState *s, hwaddr offset,
177
void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
454
uint64_t value, MemTxAttrs attrs)
455
{
456
bool result = true;
457
+ int index;
458
459
+ switch (offset) {
460
+ case GITS_BASER ... GITS_BASER + 0x3f:
461
+ /*
462
+ * IMPDEF choice:- GITS_BASERn register becomes RO if ITS is
463
+ * already enabled
464
+ */
465
+ if (!(s->ctlr & ITS_CTLR_ENABLED)) {
466
+ index = (offset - GITS_BASER) / 8;
467
+ s->baser[index] &= GITS_BASER_RO_MASK;
468
+ s->baser[index] |= (value & ~GITS_BASER_RO_MASK);
469
+ }
470
+ break;
471
+ case GITS_CBASER:
472
+ /*
473
+ * IMPDEF choice:- GITS_CBASER register becomes RO if ITS is
474
+ * already enabled
475
+ */
476
+ if (!(s->ctlr & ITS_CTLR_ENABLED)) {
477
+ s->cbaser = value;
478
+ s->creadr = 0;
479
+ s->cwriter = s->creadr;
480
+ }
481
+ break;
482
+ case GITS_CWRITER:
483
+ s->cwriter = value & ~R_GITS_CWRITER_RETRY_MASK;
484
+ break;
485
+ case GITS_CREADR:
486
+ if (s->gicv3->gicd_ctlr & GICD_CTLR_DS) {
487
+ s->creadr = value & ~R_GITS_CREADR_STALLED_MASK;
488
+ } else {
489
+ /* RO register, ignore the write */
490
+ qemu_log_mask(LOG_GUEST_ERROR,
491
+ "%s: invalid guest write to RO register at offset "
492
+ TARGET_FMT_plx "\n", __func__, offset);
493
+ }
494
+ break;
495
+ case GITS_TYPER:
496
+ /* RO registers, ignore the write */
497
+ qemu_log_mask(LOG_GUEST_ERROR,
498
+ "%s: invalid guest write to RO register at offset "
499
+ TARGET_FMT_plx "\n", __func__, offset);
500
+ break;
501
+ default:
502
+ result = false;
503
+ break;
504
+ }
505
return result;
506
}
507
508
@@ -XXX,XX +XXX,XX @@ static bool its_readll(GICv3ITSState *s, hwaddr offset,
509
uint64_t *data, MemTxAttrs attrs)
510
{
511
bool result = true;
512
+ int index;
513
514
+ switch (offset) {
515
+ case GITS_TYPER:
516
+ *data = s->typer;
517
+ break;
518
+ case GITS_BASER ... GITS_BASER + 0x3f:
519
+ index = (offset - GITS_BASER) / 8;
520
+ *data = s->baser[index];
521
+ break;
522
+ case GITS_CBASER:
523
+ *data = s->cbaser;
524
+ break;
525
+ case GITS_CREADR:
526
+ *data = s->creadr;
527
+ break;
528
+ case GITS_CWRITER:
529
+ *data = s->cwriter;
530
+ break;
531
+ default:
532
+ result = false;
533
+ break;
534
+ }
535
return result;
536
}
537
538
@@ -XXX,XX +XXX,XX @@ static void gicv3_arm_its_realize(DeviceState *dev, Error **errp)
539
540
gicv3_its_init_mmio(s, &gicv3_its_control_ops, &gicv3_its_translation_ops);
541
542
+ address_space_init(&s->gicv3->dma_as, s->gicv3->dma,
543
+ "gicv3-its-sysmem");
544
+
545
/* set the ITS default features supported */
546
s->typer = FIELD_DP64(s->typer, GITS_TYPER, PHYSICAL,
547
GITS_TYPE_PHYSICAL);
548
@@ -XXX,XX +XXX,XX @@ static void gicv3_its_reset(DeviceState *dev)
549
GITS_CTE_SIZE - 1);
550
}
551
552
+static void gicv3_its_post_load(GICv3ITSState *s)
553
+{
554
+ if (s->ctlr & ITS_CTLR_ENABLED) {
555
+ extract_table_params(s);
556
+ extract_cmdq_params(s);
557
+ }
558
+}
559
+
560
static Property gicv3_its_props[] = {
561
DEFINE_PROP_LINK("parent-gicv3", GICv3ITSState, gicv3, "arm-gicv3",
562
GICv3State *),
563
@@ -XXX,XX +XXX,XX @@ static void gicv3_its_class_init(ObjectClass *klass, void *data)
564
{
565
DeviceClass *dc = DEVICE_CLASS(klass);
566
GICv3ITSClass *ic = ARM_GICV3_ITS_CLASS(klass);
567
+ GICv3ITSCommonClass *icc = ARM_GICV3_ITS_COMMON_CLASS(klass);
568
569
dc->realize = gicv3_arm_its_realize;
570
device_class_set_props(dc, gicv3_its_props);
571
device_class_set_parent_reset(dc, gicv3_its_reset, &ic->parent_reset);
572
+ icc->post_load = gicv3_its_post_load;
573
}
574
575
static const TypeInfo gicv3_its_info = {
576
--
178
--
577
2.20.1
179
2.25.1
578
579
diff view generated by jsdifflib
1
The mps2-tz boards use a data-driven structure to create the devices
1
From: Richard Henderson <richard.henderson@linaro.org>
2
that sit behind peripheral protection controllers. Currently the
3
functions which create these devices are passed an 'opaque' pointer
4
which is always the address within the machine struct of the device
5
to create, and some "all devices need this" information like irqs and
6
addresses.
7
2
8
If a specific device needs more information than this, it is
3
Simplify freeing cp_regs hash table entries by using a single
9
currently not possible to pass that through from the PPCInfo
4
allocation for the entire value.
10
data structure. Add support for passing an extra data parameter,
11
so that we can more flexibly handle the needs of specific
12
device types. To provide some type-safety we make this extra
13
parameter a pointer to a union (which initially has no members).
14
5
15
In particular, we would like to be able to indicate which of the
6
This fixes a theoretical bug if we were to ever free the entire
16
i2c controllers are for on-board devices only and which are
7
hash table, because we've been installing string literal constants
17
connected to the external 'shield' expansion port; a subsequent
8
into the cpreg structure in define_arm_vh_e2h_redirects_aliases.
18
patch will use this mechanism for that purpose.
9
However, at present we only free entries created for AArch32
10
wildcard cpregs which get overwritten by more specific cpregs,
11
so this bug is never exposed.
19
12
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Message-id: 20220501055028.646596-13-richard.henderson@linaro.org
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Message-id: 20210903151435.22379-3-peter.maydell@linaro.org
23
---
17
---
24
hw/arm/mps2-tz.c | 35 ++++++++++++++++++++++-------------
18
target/arm/cpu.c | 16 +---------------
25
1 file changed, 22 insertions(+), 13 deletions(-)
19
target/arm/helper.c | 10 ++++++++--
20
2 files changed, 9 insertions(+), 17 deletions(-)
26
21
27
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
22
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
28
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/mps2-tz.c
24
--- a/target/arm/cpu.c
30
+++ b/hw/arm/mps2-tz.c
25
+++ b/target/arm/cpu.c
31
@@ -XXX,XX +XXX,XX @@ static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
26
@@ -XXX,XX +XXX,XX @@ uint64_t arm_cpu_mp_affinity(int idx, uint8_t clustersz)
32
}
27
return (Aff1 << ARM_AFF1_SHIFT) | Aff0;
33
}
28
}
34
29
35
+/* Union describing the device-specific extra data we pass to the devfn. */
30
-static void cpreg_hashtable_data_destroy(gpointer data)
36
+typedef union PPCExtraData {
31
-{
37
+} PPCExtraData;
32
- /*
33
- * Destroy function for cpu->cp_regs hashtable data entries.
34
- * We must free the name string because it was g_strdup()ed in
35
- * add_cpreg_to_hashtable(). It's OK to cast away the 'const'
36
- * from r->name because we know we definitely allocated it.
37
- */
38
- ARMCPRegInfo *r = data;
39
-
40
- g_free((void *)r->name);
41
- g_free(r);
42
-}
43
-
44
static void arm_cpu_initfn(Object *obj)
45
{
46
ARMCPU *cpu = ARM_CPU(obj);
47
48
cpu_set_cpustate_pointers(cpu);
49
cpu->cp_regs = g_hash_table_new_full(g_direct_hash, g_direct_equal,
50
- NULL, cpreg_hashtable_data_destroy);
51
+ NULL, g_free);
52
53
QLIST_INIT(&cpu->pre_el_change_hooks);
54
QLIST_INIT(&cpu->el_change_hooks);
55
diff --git a/target/arm/helper.c b/target/arm/helper.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/arm/helper.c
58
+++ b/target/arm/helper.c
59
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
60
* add a single reginfo struct to the hash table.
61
*/
62
uint32_t key;
63
- ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
64
+ ARMCPRegInfo *r2;
65
int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
66
int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
67
+ size_t name_len;
38
+
68
+
39
/* Most of the devices in the AN505 FPGA image sit behind
69
+ /* Combine cpreg and name into one allocation. */
40
* Peripheral Protection Controllers. These data structures
70
+ name_len = strlen(name) + 1;
41
* define the layout of which devices sit behind which PPCs.
71
+ r2 = g_malloc(sizeof(*r2) + name_len);
42
@@ -XXX,XX +XXX,XX @@ static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
72
+ *r2 = *r;
43
*/
73
+ r2->name = memcpy(r2 + 1, name, name_len);
44
typedef MemoryRegion *MakeDevFn(MPS2TZMachineState *mms, void *opaque,
74
45
const char *name, hwaddr size,
75
- r2->name = g_strdup(name);
46
- const int *irqs);
76
/* Reset the secure state to the specific incoming state. This is
47
+ const int *irqs,
77
* necessary as the register may have been defined with both states.
48
+ const PPCExtraData *extradata);
78
*/
49
50
typedef struct PPCPortInfo {
51
const char *name;
52
@@ -XXX,XX +XXX,XX @@ typedef struct PPCPortInfo {
53
hwaddr addr;
54
hwaddr size;
55
int irqs[3]; /* currently no device needs more IRQ lines than this */
56
+ PPCExtraData extradata; /* to pass device-specific info to the devfn */
57
} PPCPortInfo;
58
59
typedef struct PPCInfo {
60
@@ -XXX,XX +XXX,XX @@ typedef struct PPCInfo {
61
static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
62
void *opaque,
63
const char *name, hwaddr size,
64
- const int *irqs)
65
+ const int *irqs,
66
+ const PPCExtraData *extradata)
67
{
68
/* Initialize, configure and realize a TYPE_UNIMPLEMENTED_DEVICE,
69
* and return a pointer to its MemoryRegion.
70
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
71
72
static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
73
const char *name, hwaddr size,
74
- const int *irqs)
75
+ const int *irqs, const PPCExtraData *extradata)
76
{
77
/* The irq[] array is tx, rx, combined, in that order */
78
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
79
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
80
81
static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
82
const char *name, hwaddr size,
83
- const int *irqs)
84
+ const int *irqs, const PPCExtraData *extradata)
85
{
86
MPS2SCC *scc = opaque;
87
DeviceState *sccdev;
88
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
89
90
static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
91
const char *name, hwaddr size,
92
- const int *irqs)
93
+ const int *irqs, const PPCExtraData *extradata)
94
{
95
MPS2FPGAIO *fpgaio = opaque;
96
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
97
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
98
99
static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
100
const char *name, hwaddr size,
101
- const int *irqs)
102
+ const int *irqs,
103
+ const PPCExtraData *extradata)
104
{
105
SysBusDevice *s;
106
NICInfo *nd = &nd_table[0];
107
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
108
109
static MemoryRegion *make_eth_usb(MPS2TZMachineState *mms, void *opaque,
110
const char *name, hwaddr size,
111
- const int *irqs)
112
+ const int *irqs,
113
+ const PPCExtraData *extradata)
114
{
115
/*
116
* The AN524 makes the ethernet and USB share a PPC port.
117
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_usb(MPS2TZMachineState *mms, void *opaque,
118
119
static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
120
const char *name, hwaddr size,
121
- const int *irqs)
122
+ const int *irqs, const PPCExtraData *extradata)
123
{
124
TZMPC *mpc = opaque;
125
int i = mpc - &mms->mpc[0];
126
@@ -XXX,XX +XXX,XX @@ static void remap_irq_fn(void *opaque, int n, int level)
127
128
static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
129
const char *name, hwaddr size,
130
- const int *irqs)
131
+ const int *irqs, const PPCExtraData *extradata)
132
{
133
/* The irq[] array is DMACINTR, DMACINTERR, DMACINTTC, in that order */
134
PL080State *dma = opaque;
135
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
136
137
static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
138
const char *name, hwaddr size,
139
- const int *irqs)
140
+ const int *irqs, const PPCExtraData *extradata)
141
{
142
/*
143
* The AN505 has five PL022 SPI controllers.
144
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
145
146
static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
147
const char *name, hwaddr size,
148
- const int *irqs)
149
+ const int *irqs, const PPCExtraData *extradata)
150
{
151
ArmSbconI2CState *i2c = opaque;
152
SysBusDevice *s;
153
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
154
155
static MemoryRegion *make_rtc(MPS2TZMachineState *mms, void *opaque,
156
const char *name, hwaddr size,
157
- const int *irqs)
158
+ const int *irqs, const PPCExtraData *extradata)
159
{
160
PL031State *pl031 = opaque;
161
SysBusDevice *s;
162
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
163
}
164
165
mr = pinfo->devfn(mms, pinfo->opaque, pinfo->name, pinfo->size,
166
- pinfo->irqs);
167
+ pinfo->irqs, &pinfo->extradata);
168
portname = g_strdup_printf("port[%d]", port);
169
object_property_set_link(OBJECT(ppc), portname, OBJECT(mr),
170
&error_fatal);
171
--
79
--
172
2.20.1
80
2.25.1
173
174
diff view generated by jsdifflib
1
From: Bin Meng <bmeng.cn@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Read or write to uart registers when unclocked or in reset should be
3
Move the computation of key to the top of the function.
4
ignored. Add the check there, and as a result of this, the check in
4
Hoist the resolution of cp as well, as an input to the
5
uart_write_tx_fifo() is now unnecessary.
5
computation of key.
6
6
7
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
7
This will be required by a subsequent patch.
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210901124521.30599-6-bmeng.cn@gmail.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20220501055028.646596-14-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
---
13
hw/char/cadence_uart.c | 15 ++++++++++-----
14
target/arm/helper.c | 49 +++++++++++++++++++++++++--------------------
14
1 file changed, 10 insertions(+), 5 deletions(-)
15
1 file changed, 27 insertions(+), 22 deletions(-)
15
16
16
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/char/cadence_uart.c
19
--- a/target/arm/helper.c
19
+++ b/hw/char/cadence_uart.c
20
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ static gboolean cadence_uart_xmit(void *do_not_use, GIOCondition cond,
21
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
21
static void uart_write_tx_fifo(CadenceUARTState *s, const uint8_t *buf,
22
ARMCPRegInfo *r2;
22
int size)
23
int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
23
{
24
int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
24
- /* ignore characters when unclocked or in reset */
25
+ int cp = r->cp;
25
- if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
26
size_t name_len;
26
- return;
27
27
- }
28
+ switch (state) {
28
-
29
+ case ARM_CP_STATE_AA32:
29
if ((s->r[R_CR] & UART_CR_TX_DIS) || !(s->r[R_CR] & UART_CR_TX_EN)) {
30
+ /* We assume it is a cp15 register if the .cp field is left unset. */
30
return;
31
+ if (cp == 0 && r->state == ARM_CP_STATE_BOTH) {
31
}
32
+ cp = 15;
32
@@ -XXX,XX +XXX,XX @@ static MemTxResult uart_write(void *opaque, hwaddr offset,
33
+ }
33
{
34
+ key = ENCODE_CP_REG(cp, is64, ns, r->crn, crm, opc1, opc2);
34
CadenceUARTState *s = opaque;
35
+ break;
35
36
+ case ARM_CP_STATE_AA64:
36
+ /* ignore access when unclocked or in reset */
37
+ /*
37
+ if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
38
+ * To allow abbreviation of ARMCPRegInfo definitions, we treat
38
+ return MEMTX_ERROR;
39
+ * cp == 0 as equivalent to the value for "standard guest-visible
40
+ * sysreg". STATE_BOTH definitions are also always "standard sysreg"
41
+ * in their AArch64 view (the .cp value may be non-zero for the
42
+ * benefit of the AArch32 view).
43
+ */
44
+ if (cp == 0 || r->state == ARM_CP_STATE_BOTH) {
45
+ cp = CP_REG_ARM64_SYSREG_CP;
46
+ }
47
+ key = ENCODE_AA64_CP_REG(cp, r->crn, crm, r->opc0, opc1, opc2);
48
+ break;
49
+ default:
50
+ g_assert_not_reached();
39
+ }
51
+ }
40
+
52
+
41
DB_PRINT(" offset:%x data:%08x\n", (unsigned)offset, (unsigned)value);
53
/* Combine cpreg and name into one allocation. */
42
offset >>= 2;
54
name_len = strlen(name) + 1;
43
if (offset >= CADENCE_UART_R_MAX) {
55
r2 = g_malloc(sizeof(*r2) + name_len);
44
@@ -XXX,XX +XXX,XX @@ static MemTxResult uart_read(void *opaque, hwaddr offset,
56
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
45
CadenceUARTState *s = opaque;
57
}
46
uint32_t c = 0;
58
47
59
if (r->state == ARM_CP_STATE_BOTH) {
48
+ /* ignore access when unclocked or in reset */
60
- /* We assume it is a cp15 register if the .cp field is left unset.
49
+ if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
61
- */
50
+ return MEMTX_ERROR;
62
- if (r2->cp == 0) {
51
+ }
63
- r2->cp = 15;
52
+
64
- }
53
offset >>= 2;
65
-
54
if (offset >= CADENCE_UART_R_MAX) {
66
#if HOST_BIG_ENDIAN
55
return MEMTX_DECODE_ERROR;
67
if (r2->fieldoffset) {
68
r2->fieldoffset += sizeof(uint32_t);
69
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
70
#endif
71
}
72
}
73
- if (state == ARM_CP_STATE_AA64) {
74
- /* To allow abbreviation of ARMCPRegInfo
75
- * definitions, we treat cp == 0 as equivalent to
76
- * the value for "standard guest-visible sysreg".
77
- * STATE_BOTH definitions are also always "standard
78
- * sysreg" in their AArch64 view (the .cp value may
79
- * be non-zero for the benefit of the AArch32 view).
80
- */
81
- if (r->cp == 0 || r->state == ARM_CP_STATE_BOTH) {
82
- r2->cp = CP_REG_ARM64_SYSREG_CP;
83
- }
84
- key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm,
85
- r2->opc0, opc1, opc2);
86
- } else {
87
- key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2);
88
- }
89
if (opaque) {
90
r2->opaque = opaque;
91
}
92
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
93
/* Make sure reginfo passed to helpers for wildcarded regs
94
* has the correct crm/opc1/opc2 for this reg, not CP_ANY:
95
*/
96
+ r2->cp = cp;
97
r2->crm = crm;
98
r2->opc1 = opc1;
99
r2->opc2 = opc2;
56
--
100
--
57
2.20.1
101
2.25.1
58
59
diff view generated by jsdifflib
1
From: Bin Meng <bmeng.cn@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Currently the clock/reset check is done in uart_receive(), but we
3
Put most of the value writeback to the same place,
4
can move the check to uart_can_receive() which is earlier.
4
and improve the comment that goes with them.
5
5
6
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20220501055028.646596-15-richard.henderson@linaro.org
9
Message-id: 20210901124521.30599-4-bmeng.cn@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
hw/char/cadence_uart.c | 17 ++++++++++-------
11
target/arm/helper.c | 28 ++++++++++++----------------
13
1 file changed, 10 insertions(+), 7 deletions(-)
12
1 file changed, 12 insertions(+), 16 deletions(-)
14
13
15
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/char/cadence_uart.c
16
--- a/target/arm/helper.c
18
+++ b/hw/char/cadence_uart.c
17
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ static void uart_parameters_setup(CadenceUARTState *s)
18
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
20
static int uart_can_receive(void *opaque)
19
*r2 = *r;
21
{
20
r2->name = memcpy(r2 + 1, name, name_len);
22
CadenceUARTState *s = opaque;
21
23
- int ret = MAX(CADENCE_UART_RX_FIFO_SIZE, CADENCE_UART_TX_FIFO_SIZE);
22
- /* Reset the secure state to the specific incoming state. This is
24
- uint32_t ch_mode = s->r[R_MR] & UART_MR_CHMODE;
23
- * necessary as the register may have been defined with both states.
25
+ int ret;
24
+ /*
26
+ uint32_t ch_mode;
25
+ * Update fields to match the instantiation, overwiting wildcards
26
+ * such as CP_ANY, ARM_CP_STATE_BOTH, or ARM_CP_SECSTATE_BOTH.
27
*/
28
+ r2->cp = cp;
29
+ r2->crm = crm;
30
+ r2->opc1 = opc1;
31
+ r2->opc2 = opc2;
32
+ r2->state = state;
33
r2->secure = secstate;
34
+ if (opaque) {
35
+ r2->opaque = opaque;
36
+ }
37
38
if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
39
/* Register is banked (using both entries in array).
40
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
41
#endif
42
}
43
}
44
- if (opaque) {
45
- r2->opaque = opaque;
46
- }
47
- /* reginfo passed to helpers is correct for the actual access,
48
- * and is never ARM_CP_STATE_BOTH:
49
- */
50
- r2->state = state;
51
- /* Make sure reginfo passed to helpers for wildcarded regs
52
- * has the correct crm/opc1/opc2 for this reg, not CP_ANY:
53
- */
54
- r2->cp = cp;
55
- r2->crm = crm;
56
- r2->opc1 = opc1;
57
- r2->opc2 = opc2;
27
+
58
+
28
+ /* ignore characters when unclocked or in reset */
59
/* By convention, for wildcarded registers only the first
29
+ if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
60
* entry is used for migration; the others are marked as
30
+ return 0;
61
* ALIAS so we don't try to transfer the register
31
+ }
32
+
33
+ ret = MAX(CADENCE_UART_RX_FIFO_SIZE, CADENCE_UART_TX_FIFO_SIZE);
34
+ ch_mode = s->r[R_MR] & UART_MR_CHMODE;
35
36
if (ch_mode == NORMAL_MODE || ch_mode == ECHO_MODE) {
37
ret = MIN(ret, CADENCE_UART_RX_FIFO_SIZE - s->rx_count);
38
@@ -XXX,XX +XXX,XX @@ static void uart_receive(void *opaque, const uint8_t *buf, int size)
39
CadenceUARTState *s = opaque;
40
uint32_t ch_mode = s->r[R_MR] & UART_MR_CHMODE;
41
42
- /* ignore characters when unclocked or in reset */
43
- if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
44
- return;
45
- }
46
-
47
if (ch_mode == NORMAL_MODE || ch_mode == ECHO_MODE) {
48
uart_write_rx_fifo(opaque, buf, size);
49
}
50
--
62
--
51
2.20.1
63
2.25.1
52
53
diff view generated by jsdifflib
1
The various MPS2 boards implemented in mps2.c have multiple I2C
1
From: Richard Henderson <richard.henderson@linaro.org>
2
buses: a bus dedicated to the audio configuration, one for the LCD
3
touchscreen controller, and two which are connected to the external
4
Shield expansion connector. Mark the buses which are used only for
5
board-internal devices as 'full' so that if the user creates i2c
6
devices on the commandline without specifying a bus name then they
7
will be connected to the I2C controller used for the Shield
8
connector, where guest software will expect them.
9
2
3
Bool is a more appropriate type for these variables.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20220501055028.646596-16-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210903151435.22379-5-peter.maydell@linaro.org
13
---
9
---
14
hw/arm/mps2.c | 12 +++++++++++-
10
target/arm/helper.c | 4 ++--
15
1 file changed, 11 insertions(+), 1 deletion(-)
11
1 file changed, 2 insertions(+), 2 deletions(-)
16
12
17
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/mps2.c
15
--- a/target/arm/helper.c
20
+++ b/hw/arm/mps2.c
16
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
17
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
22
0x40023000, /* Audio */
18
*/
23
0x40029000, /* Shield0 */
19
uint32_t key;
24
0x4002a000}; /* Shield1 */
20
ARMCPRegInfo *r2;
25
- sysbus_create_simple(TYPE_ARM_SBCON_I2C, i2cbase[i], NULL);
21
- int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
26
+ DeviceState *dev;
22
- int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
27
+
23
+ bool is64 = r->type & ARM_CP_64BIT;
28
+ dev = sysbus_create_simple(TYPE_ARM_SBCON_I2C, i2cbase[i], NULL);
24
+ bool ns = secstate & ARM_CP_SECSTATE_NS;
29
+ if (i < 2) {
25
int cp = r->cp;
30
+ /*
26
size_t name_len;
31
+ * internal-only bus: mark it full to avoid user-created
32
+ * i2c devices being plugged into it.
33
+ */
34
+ BusState *qbus = qdev_get_child_bus(dev, "i2c");
35
+ qbus_mark_full(qbus);
36
+ }
37
}
38
create_unimplemented_device("i2s", 0x40024000, 0x400);
39
27
40
--
28
--
41
2.20.1
29
2.25.1
42
43
diff view generated by jsdifflib
1
From: Shashi Mallela <shashi.mallela@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Included creation of ITS as part of virt platform GIC
3
Computing isbanked only once makes the code
4
initialization. This Emulated ITS model now co-exists with kvm
4
a bit easier to read.
5
ITS and is enabled in absence of kvm irq kernel support in a
6
platform.
7
5
8
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20210910143951.92242-9-shashi.mallela@linaro.org
8
Message-id: 20220501055028.646596-17-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
include/hw/arm/virt.h | 2 ++
11
target/arm/helper.c | 6 ++++--
14
target/arm/kvm_arm.h | 4 ++--
12
1 file changed, 4 insertions(+), 2 deletions(-)
15
hw/arm/virt.c | 29 +++++++++++++++++++++++++++--
16
3 files changed, 31 insertions(+), 4 deletions(-)
17
13
18
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/virt.h
16
--- a/target/arm/helper.c
21
+++ b/include/hw/arm/virt.h
17
+++ b/target/arm/helper.c
22
@@ -XXX,XX +XXX,XX @@ struct VirtMachineClass {
18
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
23
MachineClass parent;
19
bool is64 = r->type & ARM_CP_64BIT;
24
bool disallow_affinity_adjustment;
20
bool ns = secstate & ARM_CP_SECSTATE_NS;
25
bool no_its;
21
int cp = r->cp;
26
+ bool no_tcg_its;
22
+ bool isbanked;
27
bool no_pmu;
23
size_t name_len;
28
bool claim_edge_triggered_timers;
24
29
bool smbios_old_sys_ver;
25
switch (state) {
30
@@ -XXX,XX +XXX,XX @@ struct VirtMachineState {
26
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
31
bool highmem;
27
r2->opaque = opaque;
32
bool highmem_ecam;
33
bool its;
34
+ bool tcg_its;
35
bool virt;
36
bool ras;
37
bool mte;
38
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/kvm_arm.h
41
+++ b/target/arm/kvm_arm.h
42
@@ -XXX,XX +XXX,XX @@ static inline const char *its_class_name(void)
43
/* KVM implementation requires this capability */
44
return kvm_direct_msi_enabled() ? "arm-its-kvm" : NULL;
45
} else {
46
- /* Software emulation is not implemented yet */
47
- return NULL;
48
+ /* Software emulation based model */
49
+ return "arm-gicv3-its";
50
}
28
}
51
}
29
52
30
- if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
53
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
31
+ isbanked = r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1];
54
index XXXXXXX..XXXXXXX 100644
32
+ if (isbanked) {
55
--- a/hw/arm/virt.c
33
/* Register is banked (using both entries in array).
56
+++ b/hw/arm/virt.c
34
* Overwriting fieldoffset as the array is only used to define
57
@@ -XXX,XX +XXX,XX @@ static void create_its(VirtMachineState *vms)
35
* banked registers but later only fieldoffset is used.
58
const char *itsclass = its_class_name();
36
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
59
DeviceState *dev;
60
61
+ if (!strcmp(itsclass, "arm-gicv3-its")) {
62
+ if (!vms->tcg_its) {
63
+ itsclass = NULL;
64
+ }
65
+ }
66
+
67
if (!itsclass) {
68
/* Do nothing if not supported */
69
return;
70
@@ -XXX,XX +XXX,XX @@ static void create_v2m(VirtMachineState *vms)
71
vms->msi_controller = VIRT_MSI_CTRL_GICV2M;
72
}
73
74
-static void create_gic(VirtMachineState *vms)
75
+static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
76
{
77
MachineState *ms = MACHINE(vms);
78
/* We create a standalone GIC */
79
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms)
80
nb_redist_regions);
81
qdev_prop_set_uint32(vms->gic, "redist-region-count[0]", redist0_count);
82
83
+ if (!kvm_irqchip_in_kernel()) {
84
+ if (vms->tcg_its) {
85
+ object_property_set_link(OBJECT(vms->gic), "sysmem",
86
+ OBJECT(mem), &error_fatal);
87
+ qdev_prop_set_bit(vms->gic, "has-lpi", true);
88
+ }
89
+ }
90
+
91
if (nb_redist_regions == 2) {
92
uint32_t redist1_capacity =
93
vms->memmap[VIRT_HIGH_GIC_REDIST2].size / GICV3_REDIST_SIZE;
94
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
95
96
virt_flash_fdt(vms, sysmem, secure_sysmem ?: sysmem);
97
98
- create_gic(vms);
99
+ create_gic(vms, sysmem);
100
101
virt_cpu_post_init(vms, sysmem);
102
103
@@ -XXX,XX +XXX,XX @@ static void virt_instance_init(Object *obj)
104
} else {
105
/* Default allows ITS instantiation */
106
vms->its = true;
107
+
108
+ if (vmc->no_tcg_its) {
109
+ vms->tcg_its = false;
110
+ } else {
111
+ vms->tcg_its = true;
112
+ }
113
}
37
}
114
38
115
/* Default disallows iommu instantiation */
39
if (state == ARM_CP_STATE_AA32) {
116
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(6, 2)
40
- if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
117
41
+ if (isbanked) {
118
static void virt_machine_6_1_options(MachineClass *mc)
42
/* If the register is banked then we don't need to migrate or
119
{
43
* reset the 32-bit instance in certain cases:
120
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
44
*
121
+
122
virt_machine_6_2_options(mc);
123
compat_props_add(mc->compat_props, hw_compat_6_1, hw_compat_6_1_len);
124
+
125
+ /* qemu ITS was introduced with 6.2 */
126
+ vmc->no_tcg_its = true;
127
}
128
DEFINE_VIRT_MACHINE(6, 1)
129
130
--
45
--
131
2.20.1
46
2.25.1
132
133
diff view generated by jsdifflib
1
From: Shashi Mallela <shashi.mallela@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Added properties to enable ITS feature and define qemu system
3
Perform the override check early, so that it is still done
4
address space memory in gicv3 common,setup distributor and
4
even when we decide to discard an unreachable cpreg.
5
redistributor registers to indicate LPI support.
6
5
7
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
6
Use assert not printf+abort.
7
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Tested-by: Neil Armstrong <narmstrong@baylibre.com>
10
Message-id: 20220501055028.646596-18-richard.henderson@linaro.org
10
Message-id: 20210910143951.92242-6-shashi.mallela@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
12
---
13
hw/intc/gicv3_internal.h | 2 ++
13
target/arm/helper.c | 22 ++++++++--------------
14
include/hw/intc/arm_gicv3_common.h | 1 +
14
1 file changed, 8 insertions(+), 14 deletions(-)
15
hw/intc/arm_gicv3_common.c | 12 ++++++++++++
16
hw/intc/arm_gicv3_dist.c | 5 ++++-
17
hw/intc/arm_gicv3_redist.c | 12 +++++++++---
18
5 files changed, 28 insertions(+), 4 deletions(-)
19
15
20
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/intc/gicv3_internal.h
18
--- a/target/arm/helper.c
23
+++ b/hw/intc/gicv3_internal.h
19
+++ b/target/arm/helper.c
24
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
25
#define GICD_CTLR_E1NWF (1U << 7)
21
g_assert_not_reached();
26
#define GICD_CTLR_RWP (1U << 31)
27
28
+#define GICD_TYPER_LPIS_SHIFT 17
29
+
30
/* 16 bits EventId */
31
#define GICD_TYPER_IDBITS 0xf
32
33
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
34
index XXXXXXX..XXXXXXX 100644
35
--- a/include/hw/intc/arm_gicv3_common.h
36
+++ b/include/hw/intc/arm_gicv3_common.h
37
@@ -XXX,XX +XXX,XX @@ struct GICv3State {
38
uint32_t num_cpu;
39
uint32_t num_irq;
40
uint32_t revision;
41
+ bool lpi_enable;
42
bool security_extn;
43
bool irq_reset_nonsecure;
44
bool gicd_no_migration_shift_bug;
45
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/intc/arm_gicv3_common.c
48
+++ b/hw/intc/arm_gicv3_common.c
49
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
50
return;
51
}
22
}
52
23
53
+ if (s->lpi_enable && !s->dma) {
24
+ /* Overriding of an existing definition must be explicitly requested. */
54
+ error_setg(errp, "Redist-ITS: Guest 'sysmem' reference link not set");
25
+ if (!(r->type & ARM_CP_OVERRIDE)) {
55
+ return;
26
+ const ARMCPRegInfo *oldreg = get_arm_cp_reginfo(cpu->cp_regs, key);
27
+ if (oldreg) {
28
+ assert(oldreg->type & ARM_CP_OVERRIDE);
29
+ }
56
+ }
30
+ }
57
+
31
+
58
s->cpu = g_new0(GICv3CPUState, s->num_cpu);
32
/* Combine cpreg and name into one allocation. */
59
33
name_len = strlen(name) + 1;
60
for (i = 0; i < s->num_cpu; i++) {
34
r2 = g_malloc(sizeof(*r2) + name_len);
61
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
35
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
62
(1 << 24) |
36
assert(!raw_accessors_invalid(r2));
63
(i << 8) |
64
(last << 4);
65
+
66
+ if (s->lpi_enable) {
67
+ s->cpu[i].gicr_typer |= GICR_TYPER_PLPIS;
68
+ }
69
}
37
}
38
39
- /* Overriding of an existing definition must be explicitly
40
- * requested.
41
- */
42
- if (!(r->type & ARM_CP_OVERRIDE)) {
43
- const ARMCPRegInfo *oldreg = get_arm_cp_reginfo(cpu->cp_regs, key);
44
- if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) {
45
- fprintf(stderr, "Register redefined: cp=%d %d bit "
46
- "crn=%d crm=%d opc1=%d opc2=%d, "
47
- "was %s, now %s\n", r2->cp, 32 + 32 * is64,
48
- r2->crn, r2->crm, r2->opc1, r2->opc2,
49
- oldreg->name, r2->name);
50
- g_assert_not_reached();
51
- }
52
- }
53
g_hash_table_insert(cpu->cp_regs, (gpointer)(uintptr_t)key, r2);
70
}
54
}
71
55
72
@@ -XXX,XX +XXX,XX @@ static Property arm_gicv3_common_properties[] = {
73
DEFINE_PROP_UINT32("num-cpu", GICv3State, num_cpu, 1),
74
DEFINE_PROP_UINT32("num-irq", GICv3State, num_irq, 32),
75
DEFINE_PROP_UINT32("revision", GICv3State, revision, 3),
76
+ DEFINE_PROP_BOOL("has-lpi", GICv3State, lpi_enable, 0),
77
DEFINE_PROP_BOOL("has-security-extensions", GICv3State, security_extn, 0),
78
DEFINE_PROP_ARRAY("redist-region-count", GICv3State, nb_redist_regions,
79
redist_region_count, qdev_prop_uint32, uint32_t),
80
+ DEFINE_PROP_LINK("sysmem", GICv3State, dma, TYPE_MEMORY_REGION,
81
+ MemoryRegion *),
82
DEFINE_PROP_END_OF_LIST(),
83
};
84
85
diff --git a/hw/intc/arm_gicv3_dist.c b/hw/intc/arm_gicv3_dist.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/hw/intc/arm_gicv3_dist.c
88
+++ b/hw/intc/arm_gicv3_dist.c
89
@@ -XXX,XX +XXX,XX @@ static bool gicd_readl(GICv3State *s, hwaddr offset,
90
* A3V == 1 (non-zero values of Affinity level 3 supported)
91
* IDbits == 0xf (we support 16-bit interrupt identifiers)
92
* DVIS == 0 (Direct virtual LPI injection not supported)
93
- * LPIS == 0 (LPIs not supported)
94
+ * LPIS == 1 (LPIs are supported if affinity routing is enabled)
95
+ * num_LPIs == 0b00000 (bits [15:11],Number of LPIs as indicated
96
+ * by GICD_TYPER.IDbits)
97
* MBIS == 0 (message-based SPIs not supported)
98
* SecurityExtn == 1 if security extns supported
99
* CPUNumber == 0 since for us ARE is always 1
100
@@ -XXX,XX +XXX,XX @@ static bool gicd_readl(GICv3State *s, hwaddr offset,
101
bool sec_extn = !(s->gicd_ctlr & GICD_CTLR_DS);
102
103
*data = (1 << 25) | (1 << 24) | (sec_extn << 10) |
104
+ (s->lpi_enable << GICD_TYPER_LPIS_SHIFT) |
105
(0xf << 19) | itlinesnumber;
106
return true;
107
}
108
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/hw/intc/arm_gicv3_redist.c
111
+++ b/hw/intc/arm_gicv3_redist.c
112
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicr_writel(GICv3CPUState *cs, hwaddr offset,
113
case GICR_CTLR:
114
/* For our implementation, GICR_TYPER.DPGS is 0 and so all
115
* the DPG bits are RAZ/WI. We don't do anything asynchronously,
116
- * so UWP and RWP are RAZ/WI. And GICR_TYPER.LPIS is 0 (we don't
117
- * implement LPIs) so Enable_LPIs is RES0. So there are no writable
118
- * bits for us.
119
+ * so UWP and RWP are RAZ/WI. GICR_TYPER.LPIS is 1 (we
120
+ * implement LPIs) so Enable_LPIs is programmable.
121
*/
122
+ if (cs->gicr_typer & GICR_TYPER_PLPIS) {
123
+ if (value & GICR_CTLR_ENABLE_LPIS) {
124
+ cs->gicr_ctlr |= GICR_CTLR_ENABLE_LPIS;
125
+ } else {
126
+ cs->gicr_ctlr &= ~GICR_CTLR_ENABLE_LPIS;
127
+ }
128
+ }
129
return MEMTX_OK;
130
case GICR_STATUSR:
131
/* RAZ/WI for our implementation */
132
--
56
--
133
2.20.1
57
2.25.1
134
135
diff view generated by jsdifflib
1
From: Chris Rauer <crauer@google.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
kudo-bmc is a board supported by OpenBMC.
3
Put the block comments into the current coding style.
4
https://github.com/openbmc/openbmc/tree/master/meta-fii/meta-kudo
5
4
6
Since v1:
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
- hyphenated Cortex-A9
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
7
Message-id: 20220501055028.646596-19-richard.henderson@linaro.org
9
Tested: Booted kudo firmware.
10
Signed-off-by: Chris Rauer <crauer@google.com>
11
Reviewed-by: Patrick Venture <venture@google.com>
12
Message-id: 20210907223234.1165705-1-crauer@google.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
9
---
15
docs/system/arm/nuvoton.rst | 1 +
10
target/arm/helper.c | 24 +++++++++++++++---------
16
hw/arm/npcm7xx_boards.c | 34 ++++++++++++++++++++++++++++++++++
11
1 file changed, 15 insertions(+), 9 deletions(-)
17
2 files changed, 35 insertions(+)
18
12
19
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
21
--- a/docs/system/arm/nuvoton.rst
15
--- a/target/arm/helper.c
22
+++ b/docs/system/arm/nuvoton.rst
16
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@ Hyperscale applications. The following machines are based on this chip :
17
@@ -XXX,XX +XXX,XX @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
24
18
return cpu_list;
25
- ``quanta-gbs-bmc`` Quanta GBS server BMC
26
- ``quanta-gsj`` Quanta GSJ server BMC
27
+- ``kudo-bmc`` Fii USA Kudo server BMC
28
29
There are also two more SoCs, NPCM710 and NPCM705, which are single-core
30
variants of NPCM750 and NPCM730, respectively. These are currently not
31
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/arm/npcm7xx_boards.c
34
+++ b/hw/arm/npcm7xx_boards.c
35
@@ -XXX,XX +XXX,XX @@
36
#define NPCM750_EVB_POWER_ON_STRAPS 0x00001ff7
37
#define QUANTA_GSJ_POWER_ON_STRAPS 0x00001fff
38
#define QUANTA_GBS_POWER_ON_STRAPS 0x000017ff
39
+#define KUDO_BMC_POWER_ON_STRAPS 0x00001fff
40
41
static const char npcm7xx_default_bootrom[] = "npcm7xx_bootrom.bin";
42
43
@@ -XXX,XX +XXX,XX @@ static void quanta_gbs_init(MachineState *machine)
44
npcm7xx_load_kernel(machine, soc);
45
}
19
}
46
20
47
+static void kudo_bmc_init(MachineState *machine)
21
+/*
48
+{
22
+ * Private utility function for define_one_arm_cp_reg_with_opaque():
49
+ NPCM7xxState *soc;
23
+ * add a single reginfo struct to the hash table.
50
+
24
+ */
51
+ soc = npcm7xx_create_soc(machine, KUDO_BMC_POWER_ON_STRAPS);
25
static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
52
+ npcm7xx_connect_dram(soc, machine->ram);
26
void *opaque, CPState state,
53
+ qdev_realize(DEVICE(soc), NULL, &error_fatal);
27
CPSecureState secstate,
54
+
28
int crm, int opc1, int opc2,
55
+ npcm7xx_load_bootrom(machine, soc);
29
const char *name)
56
+ npcm7xx_connect_flash(&soc->fiu[0], 0, "mx66u51235f",
57
+ drive_get(IF_MTD, 0, 0));
58
+ npcm7xx_connect_flash(&soc->fiu[1], 0, "mx66u51235f",
59
+ drive_get(IF_MTD, 3, 0));
60
+
61
+ npcm7xx_load_kernel(machine, soc);
62
+}
63
+
64
static void npcm7xx_set_soc_type(NPCM7xxMachineClass *nmc, const char *type)
65
{
30
{
66
NPCM7xxClass *sc = NPCM7XX_CLASS(object_class_by_name(type));
31
- /* Private utility function for define_one_arm_cp_reg_with_opaque():
67
@@ -XXX,XX +XXX,XX @@ static void gbs_bmc_machine_class_init(ObjectClass *oc, void *data)
32
- * add a single reginfo struct to the hash table.
68
mc->default_ram_size = 1 * GiB;
33
- */
69
}
34
uint32_t key;
70
35
ARMCPRegInfo *r2;
71
+static void kudo_bmc_machine_class_init(ObjectClass *oc, void *data)
36
bool is64 = r->type & ARM_CP_64BIT;
72
+{
37
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
73
+ NPCM7xxMachineClass *nmc = NPCM7XX_MACHINE_CLASS(oc);
38
74
+ MachineClass *mc = MACHINE_CLASS(oc);
39
isbanked = r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1];
75
+
40
if (isbanked) {
76
+ npcm7xx_set_soc_type(nmc, TYPE_NPCM730);
41
- /* Register is banked (using both entries in array).
77
+
42
+ /*
78
+ mc->desc = "Kudo BMC (Cortex-A9)";
43
+ * Register is banked (using both entries in array).
79
+ mc->init = kudo_bmc_init;
44
* Overwriting fieldoffset as the array is only used to define
80
+ mc->default_ram_size = 1 * GiB;
45
* banked registers but later only fieldoffset is used.
81
+};
46
*/
82
+
47
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
83
static const TypeInfo npcm7xx_machine_types[] = {
48
84
{
49
if (state == ARM_CP_STATE_AA32) {
85
.name = TYPE_NPCM7XX_MACHINE,
50
if (isbanked) {
86
@@ -XXX,XX +XXX,XX @@ static const TypeInfo npcm7xx_machine_types[] = {
51
- /* If the register is banked then we don't need to migrate or
87
.name = MACHINE_TYPE_NAME("quanta-gbs-bmc"),
52
+ /*
88
.parent = TYPE_NPCM7XX_MACHINE,
53
+ * If the register is banked then we don't need to migrate or
89
.class_init = gbs_bmc_machine_class_init,
54
* reset the 32-bit instance in certain cases:
90
+ }, {
55
*
91
+ .name = MACHINE_TYPE_NAME("kudo-bmc"),
56
* 1) If the register has both 32-bit and 64-bit instances then we
92
+ .parent = TYPE_NPCM7XX_MACHINE,
57
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
93
+ .class_init = kudo_bmc_machine_class_init,
58
r2->type |= ARM_CP_ALIAS;
94
},
59
}
95
};
60
} else if ((secstate != r->secure) && !ns) {
96
61
- /* The register is not banked so we only want to allow migration of
62
- * the non-secure instance.
63
+ /*
64
+ * The register is not banked so we only want to allow migration
65
+ * of the non-secure instance.
66
*/
67
r2->type |= ARM_CP_ALIAS;
68
}
69
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
70
}
71
}
72
73
- /* By convention, for wildcarded registers only the first
74
+ /*
75
+ * By convention, for wildcarded registers only the first
76
* entry is used for migration; the others are marked as
77
* ALIAS so we don't try to transfer the register
78
* multiple times. Special registers (ie NOP/WFI) are
79
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
80
r2->type |= ARM_CP_ALIAS | ARM_CP_NO_GDB;
81
}
82
83
- /* Check that raw accesses are either forbidden or handled. Note that
84
+ /*
85
+ * Check that raw accesses are either forbidden or handled. Note that
86
* we can't assert this earlier because the setup of fieldoffset for
87
* banked registers has to be done first.
88
*/
97
--
89
--
98
2.20.1
90
2.25.1
99
100
diff view generated by jsdifflib
1
From: Bin Meng <bmeng.cn@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This converts uart_read() and uart_write() to memop_with_attrs() ops.
3
Since e03b56863d2bc, our host endian indicator is unconditionally
4
set, which means that we can use a normal C condition.
4
5
5
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20220501055028.646596-20-richard.henderson@linaro.org
8
Message-id: 20210901124521.30599-5-bmeng.cn@gmail.com
9
[PMM: quote correct git hash in commit message]
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
hw/char/cadence_uart.c | 26 +++++++++++++++-----------
12
target/arm/helper.c | 9 +++------
12
1 file changed, 15 insertions(+), 11 deletions(-)
13
1 file changed, 3 insertions(+), 6 deletions(-)
13
14
14
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/char/cadence_uart.c
17
--- a/target/arm/helper.c
17
+++ b/hw/char/cadence_uart.c
18
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static void uart_read_rx_fifo(CadenceUARTState *s, uint32_t *c)
19
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
19
uart_update_status(s);
20
r2->type |= ARM_CP_ALIAS;
20
}
21
}
21
22
22
-static void uart_write(void *opaque, hwaddr offset,
23
- if (r->state == ARM_CP_STATE_BOTH) {
23
- uint64_t value, unsigned size)
24
-#if HOST_BIG_ENDIAN
24
+static MemTxResult uart_write(void *opaque, hwaddr offset,
25
- if (r2->fieldoffset) {
25
+ uint64_t value, unsigned size, MemTxAttrs attrs)
26
- r2->fieldoffset += sizeof(uint32_t);
26
{
27
- }
27
CadenceUARTState *s = opaque;
28
-#endif
28
29
+ if (HOST_BIG_ENDIAN &&
29
DB_PRINT(" offset:%x data:%08x\n", (unsigned)offset, (unsigned)value);
30
+ r->state == ARM_CP_STATE_BOTH && r2->fieldoffset) {
30
offset >>= 2;
31
+ r2->fieldoffset += sizeof(uint32_t);
31
if (offset >= CADENCE_UART_R_MAX) {
32
}
32
- return;
33
+ return MEMTX_DECODE_ERROR;
34
}
33
}
35
switch (offset) {
36
case R_IER: /* ier (wts imr) */
37
@@ -XXX,XX +XXX,XX @@ static void uart_write(void *opaque, hwaddr offset,
38
break;
39
}
40
uart_update_status(s);
41
+
42
+ return MEMTX_OK;
43
}
44
45
-static uint64_t uart_read(void *opaque, hwaddr offset,
46
- unsigned size)
47
+static MemTxResult uart_read(void *opaque, hwaddr offset,
48
+ uint64_t *value, unsigned size, MemTxAttrs attrs)
49
{
50
CadenceUARTState *s = opaque;
51
uint32_t c = 0;
52
53
offset >>= 2;
54
if (offset >= CADENCE_UART_R_MAX) {
55
- c = 0;
56
- } else if (offset == R_TX_RX) {
57
+ return MEMTX_DECODE_ERROR;
58
+ }
59
+ if (offset == R_TX_RX) {
60
uart_read_rx_fifo(s, &c);
61
} else {
62
- c = s->r[offset];
63
+ c = s->r[offset];
64
}
65
66
DB_PRINT(" offset:%x data:%08x\n", (unsigned)(offset << 2), (unsigned)c);
67
- return c;
68
+ *value = c;
69
+ return MEMTX_OK;
70
}
71
72
static const MemoryRegionOps uart_ops = {
73
- .read = uart_read,
74
- .write = uart_write,
75
+ .read_with_attrs = uart_read,
76
+ .write_with_attrs = uart_write,
77
.endianness = DEVICE_NATIVE_ENDIAN,
78
};
79
34
80
--
35
--
81
2.20.1
36
2.25.1
82
83
diff view generated by jsdifflib
1
From: Shashi Mallela <shashi.mallela@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Added ITS command queue handling for MAPTI,MAPI commands,handled ITS
4
translation which triggers an LPI via INT command as well as write
5
to GITS_TRANSLATER register,defined enum to differentiate between ITS
6
command interrupt trigger and GITS_TRANSLATER based interrupt trigger.
7
Each of these commands make use of other functionalities implemented to
8
get device table entry,collection table entry or interrupt translation
9
table entry required for their processing.
10
11
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20210910143951.92242-5-shashi.mallela@linaro.org
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20220501055028.646596-24-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
7
---
16
hw/intc/gicv3_internal.h | 12 +
8
target/arm/cpu.h | 15 +++++++++++++++
17
include/hw/intc/arm_gicv3_common.h | 2 +
9
1 file changed, 15 insertions(+)
18
hw/intc/arm_gicv3_its.c | 365 ++++++++++++++++++++++++++++-
19
3 files changed, 378 insertions(+), 1 deletion(-)
20
10
21
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
11
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/intc/gicv3_internal.h
13
--- a/target/arm/cpu.h
24
+++ b/hw/intc/gicv3_internal.h
14
+++ b/target/arm/cpu.h
25
@@ -XXX,XX +XXX,XX @@ FIELD(MAPC, RDBASE, 16, 32)
15
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id)
26
#define ITTADDR_MASK MAKE_64BIT_MASK(ITTADDR_SHIFT, ITTADDR_LENGTH)
16
return FIELD_EX32(id->id_pfr2, ID_PFR2, SSBS) != 0;
27
#define SIZE_MASK 0x1f
28
29
+/* MAPI command fields */
30
+#define EVENTID_MASK ((1ULL << 32) - 1)
31
+
32
+/* MAPTI command fields */
33
+#define pINTID_SHIFT 32
34
+#define pINTID_MASK MAKE_64BIT_MASK(32, 32)
35
+
36
#define DEVID_SHIFT 32
37
#define DEVID_MASK MAKE_64BIT_MASK(32, 32)
38
39
@@ -XXX,XX +XXX,XX @@ FIELD(MAPC, RDBASE, 16, 32)
40
* Values: | vPEID | ICID |
41
*/
42
#define ITS_ITT_ENTRY_SIZE 0xC
43
+#define ITE_ENTRY_INTTYPE_SHIFT 1
44
+#define ITE_ENTRY_INTID_SHIFT 2
45
+#define ITE_ENTRY_INTID_MASK MAKE_64BIT_MASK(2, 24)
46
+#define ITE_ENTRY_INTSP_SHIFT 26
47
+#define ITE_ENTRY_ICID_MASK MAKE_64BIT_MASK(0, 16)
48
49
/* 16 bits EventId */
50
#define ITS_IDBITS GICD_TYPER_IDBITS
51
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
52
index XXXXXXX..XXXXXXX 100644
53
--- a/include/hw/intc/arm_gicv3_common.h
54
+++ b/include/hw/intc/arm_gicv3_common.h
55
@@ -XXX,XX +XXX,XX @@
56
#define GICV3_MAXIRQ 1020
57
#define GICV3_MAXSPI (GICV3_MAXIRQ - GIC_INTERNAL)
58
59
+#define GICV3_LPI_INTID_START 8192
60
+
61
#define GICV3_REDIST_SIZE 0x20000
62
63
/* Number of SGI target-list bits */
64
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/hw/intc/arm_gicv3_its.c
67
+++ b/hw/intc/arm_gicv3_its.c
68
@@ -XXX,XX +XXX,XX @@ struct GICv3ITSClass {
69
void (*parent_reset)(DeviceState *dev);
70
};
71
72
+/*
73
+ * This is an internal enum used to distinguish between LPI triggered
74
+ * via command queue and LPI triggered via gits_translater write.
75
+ */
76
+typedef enum ItsCmdType {
77
+ NONE = 0, /* internal indication for GITS_TRANSLATER write */
78
+ CLEAR = 1,
79
+ DISCARD = 2,
80
+ INT = 3,
81
+} ItsCmdType;
82
+
83
+typedef struct {
84
+ uint32_t iteh;
85
+ uint64_t itel;
86
+} IteEntry;
87
+
88
static uint64_t baser_base_addr(uint64_t value, uint32_t page_sz)
89
{
90
uint64_t result = 0;
91
@@ -XXX,XX +XXX,XX @@ static uint64_t baser_base_addr(uint64_t value, uint32_t page_sz)
92
return result;
93
}
17
}
94
18
95
+static bool get_cte(GICv3ITSState *s, uint16_t icid, uint64_t *cte,
19
+static inline bool isar_feature_aa32_debugv8p2(const ARMISARegisters *id)
96
+ MemTxResult *res)
97
+{
20
+{
98
+ AddressSpace *as = &s->gicv3->dma_as;
21
+ return FIELD_EX32(id->id_dfr0, ID_DFR0, COPDBG) >= 8;
99
+ uint64_t l2t_addr;
100
+ uint64_t value;
101
+ bool valid_l2t;
102
+ uint32_t l2t_id;
103
+ uint32_t max_l2_entries;
104
+
105
+ if (s->ct.indirect) {
106
+ l2t_id = icid / (s->ct.page_sz / L1TABLE_ENTRY_SIZE);
107
+
108
+ value = address_space_ldq_le(as,
109
+ s->ct.base_addr +
110
+ (l2t_id * L1TABLE_ENTRY_SIZE),
111
+ MEMTXATTRS_UNSPECIFIED, res);
112
+
113
+ if (*res == MEMTX_OK) {
114
+ valid_l2t = (value & L2_TABLE_VALID_MASK) != 0;
115
+
116
+ if (valid_l2t) {
117
+ max_l2_entries = s->ct.page_sz / s->ct.entry_sz;
118
+
119
+ l2t_addr = value & ((1ULL << 51) - 1);
120
+
121
+ *cte = address_space_ldq_le(as, l2t_addr +
122
+ ((icid % max_l2_entries) * GITS_CTE_SIZE),
123
+ MEMTXATTRS_UNSPECIFIED, res);
124
+ }
125
+ }
126
+ } else {
127
+ /* Flat level table */
128
+ *cte = address_space_ldq_le(as, s->ct.base_addr +
129
+ (icid * GITS_CTE_SIZE),
130
+ MEMTXATTRS_UNSPECIFIED, res);
131
+ }
132
+
133
+ return (*cte & TABLE_ENTRY_VALID_MASK) != 0;
134
+}
22
+}
135
+
23
+
136
+static bool update_ite(GICv3ITSState *s, uint32_t eventid, uint64_t dte,
24
/*
137
+ IteEntry ite)
25
* 64-bit feature tests via id registers.
26
*/
27
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id)
28
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SSBS) != 0;
29
}
30
31
+static inline bool isar_feature_aa64_debugv8p2(const ARMISARegisters *id)
138
+{
32
+{
139
+ AddressSpace *as = &s->gicv3->dma_as;
33
+ return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, DEBUGVER) >= 8;
140
+ uint64_t itt_addr;
141
+ MemTxResult res = MEMTX_OK;
142
+
143
+ itt_addr = (dte & GITS_DTE_ITTADDR_MASK) >> GITS_DTE_ITTADDR_SHIFT;
144
+ itt_addr <<= ITTADDR_SHIFT; /* 256 byte aligned */
145
+
146
+ address_space_stq_le(as, itt_addr + (eventid * (sizeof(uint64_t) +
147
+ sizeof(uint32_t))), ite.itel, MEMTXATTRS_UNSPECIFIED,
148
+ &res);
149
+
150
+ if (res == MEMTX_OK) {
151
+ address_space_stl_le(as, itt_addr + (eventid * (sizeof(uint64_t) +
152
+ sizeof(uint32_t))) + sizeof(uint32_t), ite.iteh,
153
+ MEMTXATTRS_UNSPECIFIED, &res);
154
+ }
155
+ if (res != MEMTX_OK) {
156
+ return false;
157
+ } else {
158
+ return true;
159
+ }
160
+}
34
+}
161
+
35
+
162
+static bool get_ite(GICv3ITSState *s, uint32_t eventid, uint64_t dte,
36
static inline bool isar_feature_aa64_sve2(const ARMISARegisters *id)
163
+ uint16_t *icid, uint32_t *pIntid, MemTxResult *res)
37
{
38
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SVEVER) != 0;
39
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_tts2uxn(const ARMISARegisters *id)
40
return isar_feature_aa64_tts2uxn(id) || isar_feature_aa32_tts2uxn(id);
41
}
42
43
+static inline bool isar_feature_any_debugv8p2(const ARMISARegisters *id)
164
+{
44
+{
165
+ AddressSpace *as = &s->gicv3->dma_as;
45
+ return isar_feature_aa64_debugv8p2(id) || isar_feature_aa32_debugv8p2(id);
166
+ uint64_t itt_addr;
167
+ bool status = false;
168
+ IteEntry ite = {};
169
+
170
+ itt_addr = (dte & GITS_DTE_ITTADDR_MASK) >> GITS_DTE_ITTADDR_SHIFT;
171
+ itt_addr <<= ITTADDR_SHIFT; /* 256 byte aligned */
172
+
173
+ ite.itel = address_space_ldq_le(as, itt_addr +
174
+ (eventid * (sizeof(uint64_t) +
175
+ sizeof(uint32_t))), MEMTXATTRS_UNSPECIFIED,
176
+ res);
177
+
178
+ if (*res == MEMTX_OK) {
179
+ ite.iteh = address_space_ldl_le(as, itt_addr +
180
+ (eventid * (sizeof(uint64_t) +
181
+ sizeof(uint32_t))) + sizeof(uint32_t),
182
+ MEMTXATTRS_UNSPECIFIED, res);
183
+
184
+ if (*res == MEMTX_OK) {
185
+ if (ite.itel & TABLE_ENTRY_VALID_MASK) {
186
+ if ((ite.itel >> ITE_ENTRY_INTTYPE_SHIFT) &
187
+ GITS_TYPE_PHYSICAL) {
188
+ *pIntid = (ite.itel & ITE_ENTRY_INTID_MASK) >>
189
+ ITE_ENTRY_INTID_SHIFT;
190
+ *icid = ite.iteh & ITE_ENTRY_ICID_MASK;
191
+ status = true;
192
+ }
193
+ }
194
+ }
195
+ }
196
+ return status;
197
+}
46
+}
198
+
47
+
199
+static uint64_t get_dte(GICv3ITSState *s, uint32_t devid, MemTxResult *res)
48
/*
200
+{
49
* Forward to the above feature tests given an ARMCPU pointer.
201
+ AddressSpace *as = &s->gicv3->dma_as;
50
*/
202
+ uint64_t l2t_addr;
203
+ uint64_t value;
204
+ bool valid_l2t;
205
+ uint32_t l2t_id;
206
+ uint32_t max_l2_entries;
207
+
208
+ if (s->dt.indirect) {
209
+ l2t_id = devid / (s->dt.page_sz / L1TABLE_ENTRY_SIZE);
210
+
211
+ value = address_space_ldq_le(as,
212
+ s->dt.base_addr +
213
+ (l2t_id * L1TABLE_ENTRY_SIZE),
214
+ MEMTXATTRS_UNSPECIFIED, res);
215
+
216
+ if (*res == MEMTX_OK) {
217
+ valid_l2t = (value & L2_TABLE_VALID_MASK) != 0;
218
+
219
+ if (valid_l2t) {
220
+ max_l2_entries = s->dt.page_sz / s->dt.entry_sz;
221
+
222
+ l2t_addr = value & ((1ULL << 51) - 1);
223
+
224
+ value = address_space_ldq_le(as, l2t_addr +
225
+ ((devid % max_l2_entries) * GITS_DTE_SIZE),
226
+ MEMTXATTRS_UNSPECIFIED, res);
227
+ }
228
+ }
229
+ } else {
230
+ /* Flat level table */
231
+ value = address_space_ldq_le(as, s->dt.base_addr +
232
+ (devid * GITS_DTE_SIZE),
233
+ MEMTXATTRS_UNSPECIFIED, res);
234
+ }
235
+
236
+ return value;
237
+}
238
+
239
+/*
240
+ * This function handles the processing of following commands based on
241
+ * the ItsCmdType parameter passed:-
242
+ * 1. triggering of lpi interrupt translation via ITS INT command
243
+ * 2. triggering of lpi interrupt translation via gits_translater register
244
+ * 3. handling of ITS CLEAR command
245
+ * 4. handling of ITS DISCARD command
246
+ */
247
+static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset,
248
+ ItsCmdType cmd)
249
+{
250
+ AddressSpace *as = &s->gicv3->dma_as;
251
+ uint32_t devid, eventid;
252
+ MemTxResult res = MEMTX_OK;
253
+ bool dte_valid;
254
+ uint64_t dte = 0;
255
+ uint32_t max_eventid;
256
+ uint16_t icid = 0;
257
+ uint32_t pIntid = 0;
258
+ bool ite_valid = false;
259
+ uint64_t cte = 0;
260
+ bool cte_valid = false;
261
+ bool result = false;
262
+
263
+ if (cmd == NONE) {
264
+ devid = offset;
265
+ } else {
266
+ devid = ((value & DEVID_MASK) >> DEVID_SHIFT);
267
+
268
+ offset += NUM_BYTES_IN_DW;
269
+ value = address_space_ldq_le(as, s->cq.base_addr + offset,
270
+ MEMTXATTRS_UNSPECIFIED, &res);
271
+ }
272
+
273
+ if (res != MEMTX_OK) {
274
+ return result;
275
+ }
276
+
277
+ eventid = (value & EVENTID_MASK);
278
+
279
+ dte = get_dte(s, devid, &res);
280
+
281
+ if (res != MEMTX_OK) {
282
+ return result;
283
+ }
284
+ dte_valid = dte & TABLE_ENTRY_VALID_MASK;
285
+
286
+ if (dte_valid) {
287
+ max_eventid = (1UL << (((dte >> 1U) & SIZE_MASK) + 1));
288
+
289
+ ite_valid = get_ite(s, eventid, dte, &icid, &pIntid, &res);
290
+
291
+ if (res != MEMTX_OK) {
292
+ return result;
293
+ }
294
+
295
+ if (ite_valid) {
296
+ cte_valid = get_cte(s, icid, &cte, &res);
297
+ }
298
+
299
+ if (res != MEMTX_OK) {
300
+ return result;
301
+ }
302
+ }
303
+
304
+ if ((devid > s->dt.maxids.max_devids) || !dte_valid || !ite_valid ||
305
+ !cte_valid || (eventid > max_eventid)) {
306
+ qemu_log_mask(LOG_GUEST_ERROR,
307
+ "%s: invalid command attributes "
308
+ "devid %d or eventid %d or invalid dte %d or"
309
+ "invalid cte %d or invalid ite %d\n",
310
+ __func__, devid, eventid, dte_valid, cte_valid,
311
+ ite_valid);
312
+ /*
313
+ * in this implementation, in case of error
314
+ * we ignore this command and move onto the next
315
+ * command in the queue
316
+ */
317
+ } else {
318
+ /*
319
+ * Current implementation only supports rdbase == procnum
320
+ * Hence rdbase physical address is ignored
321
+ */
322
+ if (cmd == DISCARD) {
323
+ IteEntry ite = {};
324
+ /* remove mapping from interrupt translation table */
325
+ result = update_ite(s, eventid, dte, ite);
326
+ }
327
+ }
328
+
329
+ return result;
330
+}
331
+
332
+static bool process_mapti(GICv3ITSState *s, uint64_t value, uint32_t offset,
333
+ bool ignore_pInt)
334
+{
335
+ AddressSpace *as = &s->gicv3->dma_as;
336
+ uint32_t devid, eventid;
337
+ uint32_t pIntid = 0;
338
+ uint32_t max_eventid, max_Intid;
339
+ bool dte_valid;
340
+ MemTxResult res = MEMTX_OK;
341
+ uint16_t icid = 0;
342
+ uint64_t dte = 0;
343
+ IteEntry ite;
344
+ uint32_t int_spurious = INTID_SPURIOUS;
345
+ bool result = false;
346
+
347
+ devid = ((value & DEVID_MASK) >> DEVID_SHIFT);
348
+ offset += NUM_BYTES_IN_DW;
349
+ value = address_space_ldq_le(as, s->cq.base_addr + offset,
350
+ MEMTXATTRS_UNSPECIFIED, &res);
351
+
352
+ if (res != MEMTX_OK) {
353
+ return result;
354
+ }
355
+
356
+ eventid = (value & EVENTID_MASK);
357
+
358
+ if (!ignore_pInt) {
359
+ pIntid = ((value & pINTID_MASK) >> pINTID_SHIFT);
360
+ }
361
+
362
+ offset += NUM_BYTES_IN_DW;
363
+ value = address_space_ldq_le(as, s->cq.base_addr + offset,
364
+ MEMTXATTRS_UNSPECIFIED, &res);
365
+
366
+ if (res != MEMTX_OK) {
367
+ return result;
368
+ }
369
+
370
+ icid = value & ICID_MASK;
371
+
372
+ dte = get_dte(s, devid, &res);
373
+
374
+ if (res != MEMTX_OK) {
375
+ return result;
376
+ }
377
+ dte_valid = dte & TABLE_ENTRY_VALID_MASK;
378
+
379
+ max_eventid = (1UL << (((dte >> 1U) & SIZE_MASK) + 1));
380
+
381
+ if (!ignore_pInt) {
382
+ max_Intid = (1ULL << (GICD_TYPER_IDBITS + 1)) - 1;
383
+ }
384
+
385
+ if ((devid > s->dt.maxids.max_devids) || (icid > s->ct.maxids.max_collids)
386
+ || !dte_valid || (eventid > max_eventid) ||
387
+ (!ignore_pInt && (((pIntid < GICV3_LPI_INTID_START) ||
388
+ (pIntid > max_Intid)) && (pIntid != INTID_SPURIOUS)))) {
389
+ qemu_log_mask(LOG_GUEST_ERROR,
390
+ "%s: invalid command attributes "
391
+ "devid %d or icid %d or eventid %d or pIntid %d or"
392
+ "unmapped dte %d\n", __func__, devid, icid, eventid,
393
+ pIntid, dte_valid);
394
+ /*
395
+ * in this implementation, in case of error
396
+ * we ignore this command and move onto the next
397
+ * command in the queue
398
+ */
399
+ } else {
400
+ /* add ite entry to interrupt translation table */
401
+ ite.itel = (dte_valid & TABLE_ENTRY_VALID_MASK) |
402
+ (GITS_TYPE_PHYSICAL << ITE_ENTRY_INTTYPE_SHIFT);
403
+
404
+ if (ignore_pInt) {
405
+ ite.itel |= (eventid << ITE_ENTRY_INTID_SHIFT);
406
+ } else {
407
+ ite.itel |= (pIntid << ITE_ENTRY_INTID_SHIFT);
408
+ }
409
+ ite.itel |= (int_spurious << ITE_ENTRY_INTSP_SHIFT);
410
+ ite.iteh = icid;
411
+
412
+ result = update_ite(s, eventid, dte, ite);
413
+ }
414
+
415
+ return result;
416
+}
417
+
418
static bool update_cte(GICv3ITSState *s, uint16_t icid, bool valid,
419
uint64_t rdbase)
420
{
421
@@ -XXX,XX +XXX,XX @@ static void process_cmdq(GICv3ITSState *s)
422
423
switch (cmd) {
424
case GITS_CMD_INT:
425
+ res = process_its_cmd(s, data, cq_offset, INT);
426
break;
427
case GITS_CMD_CLEAR:
428
+ res = process_its_cmd(s, data, cq_offset, CLEAR);
429
break;
430
case GITS_CMD_SYNC:
431
/*
432
@@ -XXX,XX +XXX,XX @@ static void process_cmdq(GICv3ITSState *s)
433
result = process_mapc(s, cq_offset);
434
break;
435
case GITS_CMD_MAPTI:
436
+ result = process_mapti(s, data, cq_offset, false);
437
break;
438
case GITS_CMD_MAPI:
439
+ result = process_mapti(s, data, cq_offset, true);
440
break;
441
case GITS_CMD_DISCARD:
442
+ result = process_its_cmd(s, data, cq_offset, DISCARD);
443
break;
444
case GITS_CMD_INV:
445
case GITS_CMD_INVALL:
446
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_translation_write(void *opaque, hwaddr offset,
447
uint64_t data, unsigned size,
448
MemTxAttrs attrs)
449
{
450
- return MEMTX_OK;
451
+ GICv3ITSState *s = (GICv3ITSState *)opaque;
452
+ bool result = true;
453
+ uint32_t devid = 0;
454
+
455
+ switch (offset) {
456
+ case GITS_TRANSLATER:
457
+ if (s->ctlr & ITS_CTLR_ENABLED) {
458
+ devid = attrs.requester_id;
459
+ result = process_its_cmd(s, data, devid, NONE);
460
+ }
461
+ break;
462
+ default:
463
+ break;
464
+ }
465
+
466
+ if (result) {
467
+ return MEMTX_OK;
468
+ } else {
469
+ return MEMTX_ERROR;
470
+ }
471
}
472
473
static bool its_writel(GICv3ITSState *s, hwaddr offset,
474
--
51
--
475
2.20.1
52
2.25.1
476
477
diff view generated by jsdifflib
1
From: Shashi Mallela <shashi.mallela@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Added functionality to trigger ITS command queue processing on
3
Add the aa64 predicate for detecting RAS support from id registers.
4
write to CWRITE register and process each command queue entry to
4
We already have the aa32 version from the M-profile work.
5
identify the command type and handle commands like MAPD,MAPC,SYNC.
5
Add the 'any' predicate for testing both aa64 and aa32.
6
6
7
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Tested-by: Neil Armstrong <narmstrong@baylibre.com>
9
Message-id: 20220501055028.646596-34-richard.henderson@linaro.org
11
Message-id: 20210910143951.92242-4-shashi.mallela@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
11
---
14
hw/intc/gicv3_internal.h | 40 +++++
12
target/arm/cpu.h | 10 ++++++++++
15
hw/intc/arm_gicv3_its.c | 319 +++++++++++++++++++++++++++++++++++++++
13
1 file changed, 10 insertions(+)
16
2 files changed, 359 insertions(+)
17
14
18
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/intc/gicv3_internal.h
17
--- a/target/arm/cpu.h
21
+++ b/hw/intc/gicv3_internal.h
18
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ FIELD(GITS_TYPER, CIL, 36, 1)
19
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_aa32_el1(const ARMISARegisters *id)
23
#define L1TABLE_ENTRY_SIZE 8
20
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, EL1) >= 2;
24
25
#define GITS_CMDQ_ENTRY_SIZE 32
26
+#define NUM_BYTES_IN_DW 8
27
+
28
+#define CMD_MASK 0xff
29
+
30
+/* ITS Commands */
31
+#define GITS_CMD_CLEAR 0x04
32
+#define GITS_CMD_DISCARD 0x0F
33
+#define GITS_CMD_INT 0x03
34
+#define GITS_CMD_MAPC 0x09
35
+#define GITS_CMD_MAPD 0x08
36
+#define GITS_CMD_MAPI 0x0B
37
+#define GITS_CMD_MAPTI 0x0A
38
+#define GITS_CMD_INV 0x0C
39
+#define GITS_CMD_INVALL 0x0D
40
+#define GITS_CMD_SYNC 0x05
41
+
42
+/* MAPC command fields */
43
+#define ICID_LENGTH 16
44
+#define ICID_MASK ((1U << ICID_LENGTH) - 1)
45
+FIELD(MAPC, RDBASE, 16, 32)
46
+
47
+#define RDBASE_PROCNUM_LENGTH 16
48
+#define RDBASE_PROCNUM_MASK ((1ULL << RDBASE_PROCNUM_LENGTH) - 1)
49
+
50
+/* MAPD command fields */
51
+#define ITTADDR_LENGTH 44
52
+#define ITTADDR_SHIFT 8
53
+#define ITTADDR_MASK MAKE_64BIT_MASK(ITTADDR_SHIFT, ITTADDR_LENGTH)
54
+#define SIZE_MASK 0x1f
55
+
56
+#define DEVID_SHIFT 32
57
+#define DEVID_MASK MAKE_64BIT_MASK(32, 32)
58
+
59
+#define VALID_SHIFT 63
60
+#define CMD_FIELD_VALID_MASK (1ULL << VALID_SHIFT)
61
+#define L2_TABLE_VALID_MASK CMD_FIELD_VALID_MASK
62
+#define TABLE_ENTRY_VALID_MASK (1ULL << 0)
63
64
/**
65
* Default features advertised by this version of ITS
66
@@ -XXX,XX +XXX,XX @@ FIELD(GITS_TYPER, CIL, 36, 1)
67
* Valid = 1 bit,ITTAddr = 44 bits,Size = 5 bits
68
*/
69
#define GITS_DTE_SIZE (0x8ULL)
70
+#define GITS_DTE_ITTADDR_SHIFT 6
71
+#define GITS_DTE_ITTADDR_MASK MAKE_64BIT_MASK(GITS_DTE_ITTADDR_SHIFT, \
72
+ ITTADDR_LENGTH)
73
74
/*
75
* 8 bytes Collection Table Entry size
76
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/hw/intc/arm_gicv3_its.c
79
+++ b/hw/intc/arm_gicv3_its.c
80
@@ -XXX,XX +XXX,XX @@ static uint64_t baser_base_addr(uint64_t value, uint32_t page_sz)
81
return result;
82
}
21
}
83
22
84
+static bool update_cte(GICv3ITSState *s, uint16_t icid, bool valid,
23
+static inline bool isar_feature_aa64_ras(const ARMISARegisters *id)
85
+ uint64_t rdbase)
86
+{
24
+{
87
+ AddressSpace *as = &s->gicv3->dma_as;
25
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RAS) != 0;
88
+ uint64_t value;
89
+ uint64_t l2t_addr;
90
+ bool valid_l2t;
91
+ uint32_t l2t_id;
92
+ uint32_t max_l2_entries;
93
+ uint64_t cte = 0;
94
+ MemTxResult res = MEMTX_OK;
95
+
96
+ if (!s->ct.valid) {
97
+ return true;
98
+ }
99
+
100
+ if (valid) {
101
+ /* add mapping entry to collection table */
102
+ cte = (valid & TABLE_ENTRY_VALID_MASK) | (rdbase << 1ULL);
103
+ }
104
+
105
+ /*
106
+ * The specification defines the format of level 1 entries of a
107
+ * 2-level table, but the format of level 2 entries and the format
108
+ * of flat-mapped tables is IMPDEF.
109
+ */
110
+ if (s->ct.indirect) {
111
+ l2t_id = icid / (s->ct.page_sz / L1TABLE_ENTRY_SIZE);
112
+
113
+ value = address_space_ldq_le(as,
114
+ s->ct.base_addr +
115
+ (l2t_id * L1TABLE_ENTRY_SIZE),
116
+ MEMTXATTRS_UNSPECIFIED, &res);
117
+
118
+ if (res != MEMTX_OK) {
119
+ return false;
120
+ }
121
+
122
+ valid_l2t = (value & L2_TABLE_VALID_MASK) != 0;
123
+
124
+ if (valid_l2t) {
125
+ max_l2_entries = s->ct.page_sz / s->ct.entry_sz;
126
+
127
+ l2t_addr = value & ((1ULL << 51) - 1);
128
+
129
+ address_space_stq_le(as, l2t_addr +
130
+ ((icid % max_l2_entries) * GITS_CTE_SIZE),
131
+ cte, MEMTXATTRS_UNSPECIFIED, &res);
132
+ }
133
+ } else {
134
+ /* Flat level table */
135
+ address_space_stq_le(as, s->ct.base_addr + (icid * GITS_CTE_SIZE),
136
+ cte, MEMTXATTRS_UNSPECIFIED, &res);
137
+ }
138
+ if (res != MEMTX_OK) {
139
+ return false;
140
+ } else {
141
+ return true;
142
+ }
143
+}
26
+}
144
+
27
+
145
+static bool process_mapc(GICv3ITSState *s, uint32_t offset)
28
static inline bool isar_feature_aa64_sve(const ARMISARegisters *id)
29
{
30
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0;
31
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_debugv8p2(const ARMISARegisters *id)
32
return isar_feature_aa64_debugv8p2(id) || isar_feature_aa32_debugv8p2(id);
33
}
34
35
+static inline bool isar_feature_any_ras(const ARMISARegisters *id)
146
+{
36
+{
147
+ AddressSpace *as = &s->gicv3->dma_as;
37
+ return isar_feature_aa64_ras(id) || isar_feature_aa32_ras(id);
148
+ uint16_t icid;
149
+ uint64_t rdbase;
150
+ bool valid;
151
+ MemTxResult res = MEMTX_OK;
152
+ bool result = false;
153
+ uint64_t value;
154
+
155
+ offset += NUM_BYTES_IN_DW;
156
+ offset += NUM_BYTES_IN_DW;
157
+
158
+ value = address_space_ldq_le(as, s->cq.base_addr + offset,
159
+ MEMTXATTRS_UNSPECIFIED, &res);
160
+
161
+ if (res != MEMTX_OK) {
162
+ return result;
163
+ }
164
+
165
+ icid = value & ICID_MASK;
166
+
167
+ rdbase = (value & R_MAPC_RDBASE_MASK) >> R_MAPC_RDBASE_SHIFT;
168
+ rdbase &= RDBASE_PROCNUM_MASK;
169
+
170
+ valid = (value & CMD_FIELD_VALID_MASK);
171
+
172
+ if ((icid > s->ct.maxids.max_collids) || (rdbase > s->gicv3->num_cpu)) {
173
+ qemu_log_mask(LOG_GUEST_ERROR,
174
+ "ITS MAPC: invalid collection table attributes "
175
+ "icid %d rdbase %lu\n", icid, rdbase);
176
+ /*
177
+ * in this implementation, in case of error
178
+ * we ignore this command and move onto the next
179
+ * command in the queue
180
+ */
181
+ } else {
182
+ result = update_cte(s, icid, valid, rdbase);
183
+ }
184
+
185
+ return result;
186
+}
187
+
188
+static bool update_dte(GICv3ITSState *s, uint32_t devid, bool valid,
189
+ uint8_t size, uint64_t itt_addr)
190
+{
191
+ AddressSpace *as = &s->gicv3->dma_as;
192
+ uint64_t value;
193
+ uint64_t l2t_addr;
194
+ bool valid_l2t;
195
+ uint32_t l2t_id;
196
+ uint32_t max_l2_entries;
197
+ uint64_t dte = 0;
198
+ MemTxResult res = MEMTX_OK;
199
+
200
+ if (s->dt.valid) {
201
+ if (valid) {
202
+ /* add mapping entry to device table */
203
+ dte = (valid & TABLE_ENTRY_VALID_MASK) |
204
+ ((size & SIZE_MASK) << 1U) |
205
+ (itt_addr << GITS_DTE_ITTADDR_SHIFT);
206
+ }
207
+ } else {
208
+ return true;
209
+ }
210
+
211
+ /*
212
+ * The specification defines the format of level 1 entries of a
213
+ * 2-level table, but the format of level 2 entries and the format
214
+ * of flat-mapped tables is IMPDEF.
215
+ */
216
+ if (s->dt.indirect) {
217
+ l2t_id = devid / (s->dt.page_sz / L1TABLE_ENTRY_SIZE);
218
+
219
+ value = address_space_ldq_le(as,
220
+ s->dt.base_addr +
221
+ (l2t_id * L1TABLE_ENTRY_SIZE),
222
+ MEMTXATTRS_UNSPECIFIED, &res);
223
+
224
+ if (res != MEMTX_OK) {
225
+ return false;
226
+ }
227
+
228
+ valid_l2t = (value & L2_TABLE_VALID_MASK) != 0;
229
+
230
+ if (valid_l2t) {
231
+ max_l2_entries = s->dt.page_sz / s->dt.entry_sz;
232
+
233
+ l2t_addr = value & ((1ULL << 51) - 1);
234
+
235
+ address_space_stq_le(as, l2t_addr +
236
+ ((devid % max_l2_entries) * GITS_DTE_SIZE),
237
+ dte, MEMTXATTRS_UNSPECIFIED, &res);
238
+ }
239
+ } else {
240
+ /* Flat level table */
241
+ address_space_stq_le(as, s->dt.base_addr + (devid * GITS_DTE_SIZE),
242
+ dte, MEMTXATTRS_UNSPECIFIED, &res);
243
+ }
244
+ if (res != MEMTX_OK) {
245
+ return false;
246
+ } else {
247
+ return true;
248
+ }
249
+}
250
+
251
+static bool process_mapd(GICv3ITSState *s, uint64_t value, uint32_t offset)
252
+{
253
+ AddressSpace *as = &s->gicv3->dma_as;
254
+ uint32_t devid;
255
+ uint8_t size;
256
+ uint64_t itt_addr;
257
+ bool valid;
258
+ MemTxResult res = MEMTX_OK;
259
+ bool result = false;
260
+
261
+ devid = ((value & DEVID_MASK) >> DEVID_SHIFT);
262
+
263
+ offset += NUM_BYTES_IN_DW;
264
+ value = address_space_ldq_le(as, s->cq.base_addr + offset,
265
+ MEMTXATTRS_UNSPECIFIED, &res);
266
+
267
+ if (res != MEMTX_OK) {
268
+ return result;
269
+ }
270
+
271
+ size = (value & SIZE_MASK);
272
+
273
+ offset += NUM_BYTES_IN_DW;
274
+ value = address_space_ldq_le(as, s->cq.base_addr + offset,
275
+ MEMTXATTRS_UNSPECIFIED, &res);
276
+
277
+ if (res != MEMTX_OK) {
278
+ return result;
279
+ }
280
+
281
+ itt_addr = (value & ITTADDR_MASK) >> ITTADDR_SHIFT;
282
+
283
+ valid = (value & CMD_FIELD_VALID_MASK);
284
+
285
+ if ((devid > s->dt.maxids.max_devids) ||
286
+ (size > FIELD_EX64(s->typer, GITS_TYPER, IDBITS))) {
287
+ qemu_log_mask(LOG_GUEST_ERROR,
288
+ "ITS MAPD: invalid device table attributes "
289
+ "devid %d or size %d\n", devid, size);
290
+ /*
291
+ * in this implementation, in case of error
292
+ * we ignore this command and move onto the next
293
+ * command in the queue
294
+ */
295
+ } else {
296
+ result = update_dte(s, devid, valid, size, itt_addr);
297
+ }
298
+
299
+ return result;
300
+}
301
+
302
+/*
303
+ * Current implementation blocks until all
304
+ * commands are processed
305
+ */
306
+static void process_cmdq(GICv3ITSState *s)
307
+{
308
+ uint32_t wr_offset = 0;
309
+ uint32_t rd_offset = 0;
310
+ uint32_t cq_offset = 0;
311
+ uint64_t data;
312
+ AddressSpace *as = &s->gicv3->dma_as;
313
+ MemTxResult res = MEMTX_OK;
314
+ bool result = true;
315
+ uint8_t cmd;
316
+
317
+ if (!(s->ctlr & ITS_CTLR_ENABLED)) {
318
+ return;
319
+ }
320
+
321
+ wr_offset = FIELD_EX64(s->cwriter, GITS_CWRITER, OFFSET);
322
+
323
+ if (wr_offset > s->cq.max_entries) {
324
+ qemu_log_mask(LOG_GUEST_ERROR,
325
+ "%s: invalid write offset "
326
+ "%d\n", __func__, wr_offset);
327
+ return;
328
+ }
329
+
330
+ rd_offset = FIELD_EX64(s->creadr, GITS_CREADR, OFFSET);
331
+
332
+ if (rd_offset > s->cq.max_entries) {
333
+ qemu_log_mask(LOG_GUEST_ERROR,
334
+ "%s: invalid read offset "
335
+ "%d\n", __func__, rd_offset);
336
+ return;
337
+ }
338
+
339
+ while (wr_offset != rd_offset) {
340
+ cq_offset = (rd_offset * GITS_CMDQ_ENTRY_SIZE);
341
+ data = address_space_ldq_le(as, s->cq.base_addr + cq_offset,
342
+ MEMTXATTRS_UNSPECIFIED, &res);
343
+ if (res != MEMTX_OK) {
344
+ result = false;
345
+ }
346
+ cmd = (data & CMD_MASK);
347
+
348
+ switch (cmd) {
349
+ case GITS_CMD_INT:
350
+ break;
351
+ case GITS_CMD_CLEAR:
352
+ break;
353
+ case GITS_CMD_SYNC:
354
+ /*
355
+ * Current implementation makes a blocking synchronous call
356
+ * for every command issued earlier, hence the internal state
357
+ * is already consistent by the time SYNC command is executed.
358
+ * Hence no further processing is required for SYNC command.
359
+ */
360
+ break;
361
+ case GITS_CMD_MAPD:
362
+ result = process_mapd(s, data, cq_offset);
363
+ break;
364
+ case GITS_CMD_MAPC:
365
+ result = process_mapc(s, cq_offset);
366
+ break;
367
+ case GITS_CMD_MAPTI:
368
+ break;
369
+ case GITS_CMD_MAPI:
370
+ break;
371
+ case GITS_CMD_DISCARD:
372
+ break;
373
+ case GITS_CMD_INV:
374
+ case GITS_CMD_INVALL:
375
+ break;
376
+ default:
377
+ break;
378
+ }
379
+ if (result) {
380
+ rd_offset++;
381
+ rd_offset %= s->cq.max_entries;
382
+ s->creadr = FIELD_DP64(s->creadr, GITS_CREADR, OFFSET, rd_offset);
383
+ } else {
384
+ /*
385
+ * in this implementation, in case of dma read/write error
386
+ * we stall the command processing
387
+ */
388
+ s->creadr = FIELD_DP64(s->creadr, GITS_CREADR, STALLED, 1);
389
+ qemu_log_mask(LOG_GUEST_ERROR,
390
+ "%s: %x cmd processing failed\n", __func__, cmd);
391
+ break;
392
+ }
393
+ }
394
+}
38
+}
395
+
39
+
396
/*
40
/*
397
* This function extracts the ITS Device and Collection table specific
41
* Forward to the above feature tests given an ARMCPU pointer.
398
* parameters (like base_addr, size etc) from GITS_BASER register.
42
*/
399
@@ -XXX,XX +XXX,XX @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
400
extract_table_params(s);
401
extract_cmdq_params(s);
402
s->creadr = 0;
403
+ process_cmdq(s);
404
}
405
break;
406
case GITS_CBASER:
407
@@ -XXX,XX +XXX,XX @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
408
case GITS_CWRITER:
409
s->cwriter = deposit64(s->cwriter, 0, 32,
410
(value & ~R_GITS_CWRITER_RETRY_MASK));
411
+ if (s->cwriter != s->creadr) {
412
+ process_cmdq(s);
413
+ }
414
break;
415
case GITS_CWRITER + 4:
416
s->cwriter = deposit64(s->cwriter, 32, 32, value);
417
@@ -XXX,XX +XXX,XX @@ static bool its_writell(GICv3ITSState *s, hwaddr offset,
418
break;
419
case GITS_CWRITER:
420
s->cwriter = value & ~R_GITS_CWRITER_RETRY_MASK;
421
+ if (s->cwriter != s->creadr) {
422
+ process_cmdq(s);
423
+ }
424
break;
425
case GITS_CREADR:
426
if (s->gicv3->gicd_ctlr & GICD_CTLR_DS) {
427
--
43
--
428
2.20.1
44
2.25.1
429
430
diff view generated by jsdifflib
1
From: Bin Meng <bmeng.cn@gmail.com>
1
From: Alex Zuepke <alex.zuepke@tum.de>
2
2
3
At present when input clock is disabled, any character transmitted
3
The ARMv8 manual defines that PMUSERENR_EL0.ER enables read-access
4
to tx fifo can still show on the serial line, which is wrong.
4
to both PMXEVCNTR_EL0 and PMEVCNTR<n>_EL0 registers, however,
5
we only use it for PMXEVCNTR_EL0. Extend to PMEVCNTR<n>_EL0 as well.
5
6
6
Fixes: b636db306e06 ("hw/char/cadence_uart: add clock support")
7
Signed-off-by: Alex Zuepke <alex.zuepke@tum.de>
7
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20220428132717.84190-1-alex.zuepke@tum.de
9
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Message-id: 20210901124521.30599-3-bmeng.cn@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
11
---
13
hw/char/cadence_uart.c | 5 +++++
12
target/arm/helper.c | 4 ++--
14
1 file changed, 5 insertions(+)
13
1 file changed, 2 insertions(+), 2 deletions(-)
15
14
16
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/char/cadence_uart.c
17
--- a/target/arm/helper.c
19
+++ b/hw/char/cadence_uart.c
18
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ static gboolean cadence_uart_xmit(void *do_not_use, GIOCondition cond,
19
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
21
static void uart_write_tx_fifo(CadenceUARTState *s, const uint8_t *buf,
20
.crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
22
int size)
21
.access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
23
{
22
.readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
24
+ /* ignore characters when unclocked or in reset */
23
- .accessfn = pmreg_access },
25
+ if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
24
+ .accessfn = pmreg_access_xevcntr },
26
+ return;
25
{ .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
27
+ }
26
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 8 | (3 & (i >> 3)),
28
+
27
- .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
29
if ((s->r[R_CR] & UART_CR_TX_DIS) || !(s->r[R_CR] & UART_CR_TX_EN)) {
28
+ .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access_xevcntr,
30
return;
29
.type = ARM_CP_IO,
31
}
30
.readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
31
.raw_readfn = pmevcntr_rawread,
32
--
32
--
33
2.20.1
33
2.25.1
34
35
diff view generated by jsdifflib