1
Two small bugfixes, plus most of RTH's refactoring of cpregs
1
The following changes since commit b11728dc3ae67ddedf34b7a4f318170e7092803c:
2
handling.
3
2
4
-- PMM
3
Merge tag 'pull-riscv-to-apply-20230224' of github.com:palmer-dabbelt/qemu into staging (2023-02-26 20:14:46 +0000)
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)
9
4
10
are available in the Git repository at:
5
are available in the Git repository at:
11
6
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220505
7
https://git.linaro.org/people/pmaydell/qemu-arm.git pull-target-arm-20230227
13
8
14
for you to fetch changes up to 99a50d1a67c602126fc2b3a4812d3000eba9bf34:
9
for you to fetch changes up to e844f0c5d0bd2c4d8d3c1622eb2a88586c9c4677:
15
10
16
target/arm: read access to performance counters from EL0 (2022-05-05 09:36:22 +0100)
11
hw: Replace qemu_or_irq typedef by OrIRQState (2023-02-27 13:27:05 +0000)
17
12
18
----------------------------------------------------------------
13
----------------------------------------------------------------
19
target-arm queue:
14
target-arm queue:
20
* Enable read access to performance counters from EL0
15
* Various code cleanups
21
* Enable SCTLR_EL1.BT0 for aarch64-linux-user
16
* More refactoring working towards allowing a build
22
* Refactoring of cpreg handling
17
without CONFIG_TCG
23
18
24
----------------------------------------------------------------
19
----------------------------------------------------------------
25
Alex Zuepke (1):
20
Claudio Fontana (2):
26
target/arm: read access to performance counters from EL0
21
target/arm: move helpers to tcg/
22
target/arm: Move psci.c into the tcg directory
27
23
28
Richard Henderson (22):
24
Fabiano Rosas (9):
29
target/arm: Enable SCTLR_EL1.BT0 for aarch64-linux-user
25
target/arm: Wrap breakpoint/watchpoint updates with tcg_enabled
30
target/arm: Split out cpregs.h
26
target/arm: Wrap TCG-only code in debug_helper.c
31
target/arm: Reorg CPAccessResult and access_check_cp_reg
27
target/arm: move translate modules to tcg/
32
target/arm: Replace sentinels with ARRAY_SIZE in cpregs.h
28
target/arm: Wrap arm_rebuild_hflags calls with tcg_enabled
33
target/arm: Make some more cpreg data static const
29
target/arm: Move hflags code into the tcg directory
34
target/arm: Reorg ARMCPRegInfo type field bits
30
target/arm: Move regime_using_lpae_format into internal.h
35
target/arm: Avoid bare abort() or assert(0)
31
target/arm: Don't access TCG code when debugging with KVM
36
target/arm: Change cpreg access permissions to enum
32
cpu-defs.h: Expose CPUTLBEntryFull to non-TCG code
37
target/arm: Name CPState type
33
tests/avocado: add machine:none tag to version.py
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
51
34
52
target/arm/cpregs.h | 453 ++++++++++++++++++++++++++++++++++++++
35
Philippe Mathieu-Daudé (13):
53
target/arm/cpu.h | 393 +++------------------------------
36
hw/gpio/max7310: Simplify max7310_realize()
54
hw/arm/pxa2xx.c | 2 +-
37
hw/char/pl011: Un-inline pl011_create()
55
hw/arm/pxa2xx_pic.c | 2 +-
38
hw/char/pl011: Open-code pl011_luminary_create()
56
hw/intc/arm_gicv3_cpuif.c | 6 +-
39
hw/char/xilinx_uartlite: Expose XILINX_UARTLITE QOM type
57
hw/intc/arm_gicv3_kvm.c | 3 +-
40
hw/char/xilinx_uartlite: Open-code xilinx_uartlite_create()
58
target/arm/cpu.c | 25 +--
41
hw/char/cmsdk-apb-uart: Open-code cmsdk_apb_uart_create()
59
target/arm/cpu64.c | 2 +-
42
hw/timer/cmsdk-apb-timer: Remove unused 'qdev-properties.h' header
60
target/arm/cpu_tcg.c | 5 +-
43
hw/intc/armv7m_nvic: Use QOM cast CPU() macro
61
target/arm/gdbstub.c | 5 +-
44
hw/arm/musicpal: Remove unused dummy MemoryRegion
62
target/arm/helper.c | 358 +++++++++++++-----------------
45
iothread: Remove unused IOThreadClass / IOTHREAD_CLASS
63
target/arm/hvf/hvf.c | 2 +-
46
hw/irq: Declare QOM macros using OBJECT_DECLARE_SIMPLE_TYPE()
64
target/arm/kvm-stub.c | 4 +-
47
hw/or-irq: Declare QOM macros using OBJECT_DECLARE_SIMPLE_TYPE()
65
target/arm/kvm.c | 4 +-
48
hw: Replace qemu_or_irq typedef by OrIRQState
66
target/arm/machine.c | 4 +-
49
67
target/arm/op_helper.c | 57 ++---
50
Thomas Huth (1):
68
target/arm/translate-a64.c | 14 +-
51
include/hw/arm/allwinner-a10.h: Remove superfluous includes from the header
69
target/arm/translate-neon.c | 2 +-
52
70
target/arm/translate.c | 13 +-
53
MAINTAINERS | 1 +
71
tests/tcg/aarch64/bti-3.c | 42 ++++
54
include/exec/cpu-defs.h | 6 +
72
tests/tcg/aarch64/Makefile.target | 6 +-
55
include/hw/arm/allwinner-a10.h | 2 -
73
21 files changed, 738 insertions(+), 664 deletions(-)
56
include/hw/arm/armsse.h | 6 +-
74
create mode 100644 target/arm/cpregs.h
57
include/hw/arm/bcm2835_peripherals.h | 2 +-
75
create mode 100644 tests/tcg/aarch64/bti-3.c
58
include/hw/arm/exynos4210.h | 4 +-
59
include/hw/arm/stm32f205_soc.h | 2 +-
60
include/hw/arm/stm32f405_soc.h | 2 +-
61
include/hw/arm/xlnx-versal.h | 6 +-
62
include/hw/arm/xlnx-zynqmp.h | 2 +-
63
include/hw/char/cmsdk-apb-uart.h | 34 ---
64
include/hw/char/pl011.h | 36 +--
65
include/hw/char/xilinx_uartlite.h | 22 +-
66
include/hw/or-irq.h | 5 +-
67
include/hw/timer/cmsdk-apb-timer.h | 1 -
68
target/arm/internals.h | 23 +-
69
target/arm/{ => tcg}/translate-a64.h | 0
70
target/arm/{ => tcg}/translate.h | 0
71
target/arm/{ => tcg}/vec_internal.h | 0
72
target/arm/{ => tcg}/a32-uncond.decode | 0
73
target/arm/{ => tcg}/a32.decode | 0
74
target/arm/{ => tcg}/m-nocp.decode | 0
75
target/arm/{ => tcg}/mve.decode | 0
76
target/arm/{ => tcg}/neon-dp.decode | 0
77
target/arm/{ => tcg}/neon-ls.decode | 0
78
target/arm/{ => tcg}/neon-shared.decode | 0
79
target/arm/{ => tcg}/sme-fa64.decode | 0
80
target/arm/{ => tcg}/sme.decode | 0
81
target/arm/{ => tcg}/sve.decode | 0
82
target/arm/{ => tcg}/t16.decode | 0
83
target/arm/{ => tcg}/t32.decode | 0
84
target/arm/{ => tcg}/vfp-uncond.decode | 0
85
target/arm/{ => tcg}/vfp.decode | 0
86
hw/arm/allwinner-a10.c | 1 +
87
hw/arm/boot.c | 6 +-
88
hw/arm/exynos4210.c | 4 +-
89
hw/arm/mps2-tz.c | 2 +-
90
hw/arm/mps2.c | 41 ++-
91
hw/arm/musicpal.c | 4 -
92
hw/arm/stellaris.c | 11 +-
93
hw/char/pl011.c | 17 ++
94
hw/char/xilinx_uartlite.c | 4 +-
95
hw/core/irq.c | 9 +-
96
hw/core/or-irq.c | 18 +-
97
hw/gpio/max7310.c | 5 +-
98
hw/intc/armv7m_nvic.c | 26 +-
99
hw/microblaze/petalogix_s3adsp1800_mmu.c | 7 +-
100
hw/pci-host/raven.c | 2 +-
101
iothread.c | 4 -
102
target/arm/arm-powerctl.c | 7 +-
103
target/arm/cpu.c | 9 +-
104
target/arm/debug_helper.c | 490 ++++++++++++++++---------------
105
target/arm/helper.c | 411 +-------------------------
106
target/arm/machine.c | 12 +-
107
target/arm/ptw.c | 4 +
108
target/arm/tcg-stubs.c | 27 ++
109
target/arm/{ => tcg}/crypto_helper.c | 0
110
target/arm/{ => tcg}/helper-a64.c | 0
111
target/arm/tcg/hflags.c | 403 +++++++++++++++++++++++++
112
target/arm/{ => tcg}/iwmmxt_helper.c | 0
113
target/arm/{ => tcg}/m_helper.c | 0
114
target/arm/{ => tcg}/mte_helper.c | 0
115
target/arm/{ => tcg}/mve_helper.c | 0
116
target/arm/{ => tcg}/neon_helper.c | 0
117
target/arm/{ => tcg}/op_helper.c | 0
118
target/arm/{ => tcg}/pauth_helper.c | 0
119
target/arm/{ => tcg}/psci.c | 0
120
target/arm/{ => tcg}/sme_helper.c | 0
121
target/arm/{ => tcg}/sve_helper.c | 0
122
target/arm/{ => tcg}/tlb_helper.c | 18 --
123
target/arm/{ => tcg}/translate-a64.c | 0
124
target/arm/{ => tcg}/translate-m-nocp.c | 0
125
target/arm/{ => tcg}/translate-mve.c | 0
126
target/arm/{ => tcg}/translate-neon.c | 0
127
target/arm/{ => tcg}/translate-sme.c | 0
128
target/arm/{ => tcg}/translate-sve.c | 0
129
target/arm/{ => tcg}/translate-vfp.c | 0
130
target/arm/{ => tcg}/translate.c | 0
131
target/arm/{ => tcg}/vec_helper.c | 0
132
target/arm/meson.build | 46 +--
133
target/arm/tcg/meson.build | 50 ++++
134
tests/avocado/version.py | 1 +
135
82 files changed, 918 insertions(+), 875 deletions(-)
136
rename target/arm/{ => tcg}/translate-a64.h (100%)
137
rename target/arm/{ => tcg}/translate.h (100%)
138
rename target/arm/{ => tcg}/vec_internal.h (100%)
139
rename target/arm/{ => tcg}/a32-uncond.decode (100%)
140
rename target/arm/{ => tcg}/a32.decode (100%)
141
rename target/arm/{ => tcg}/m-nocp.decode (100%)
142
rename target/arm/{ => tcg}/mve.decode (100%)
143
rename target/arm/{ => tcg}/neon-dp.decode (100%)
144
rename target/arm/{ => tcg}/neon-ls.decode (100%)
145
rename target/arm/{ => tcg}/neon-shared.decode (100%)
146
rename target/arm/{ => tcg}/sme-fa64.decode (100%)
147
rename target/arm/{ => tcg}/sme.decode (100%)
148
rename target/arm/{ => tcg}/sve.decode (100%)
149
rename target/arm/{ => tcg}/t16.decode (100%)
150
rename target/arm/{ => tcg}/t32.decode (100%)
151
rename target/arm/{ => tcg}/vfp-uncond.decode (100%)
152
rename target/arm/{ => tcg}/vfp.decode (100%)
153
create mode 100644 target/arm/tcg-stubs.c
154
rename target/arm/{ => tcg}/crypto_helper.c (100%)
155
rename target/arm/{ => tcg}/helper-a64.c (100%)
156
create mode 100644 target/arm/tcg/hflags.c
157
rename target/arm/{ => tcg}/iwmmxt_helper.c (100%)
158
rename target/arm/{ => tcg}/m_helper.c (100%)
159
rename target/arm/{ => tcg}/mte_helper.c (100%)
160
rename target/arm/{ => tcg}/mve_helper.c (100%)
161
rename target/arm/{ => tcg}/neon_helper.c (100%)
162
rename target/arm/{ => tcg}/op_helper.c (100%)
163
rename target/arm/{ => tcg}/pauth_helper.c (100%)
164
rename target/arm/{ => tcg}/psci.c (100%)
165
rename target/arm/{ => tcg}/sme_helper.c (100%)
166
rename target/arm/{ => tcg}/sve_helper.c (100%)
167
rename target/arm/{ => tcg}/tlb_helper.c (94%)
168
rename target/arm/{ => tcg}/translate-a64.c (100%)
169
rename target/arm/{ => tcg}/translate-m-nocp.c (100%)
170
rename target/arm/{ => tcg}/translate-mve.c (100%)
171
rename target/arm/{ => tcg}/translate-neon.c (100%)
172
rename target/arm/{ => tcg}/translate-sme.c (100%)
173
rename target/arm/{ => tcg}/translate-sve.c (100%)
174
rename target/arm/{ => tcg}/translate-vfp.c (100%)
175
rename target/arm/{ => tcg}/translate.c (100%)
176
rename target/arm/{ => tcg}/vec_helper.c (100%)
177
create mode 100644 target/arm/tcg/meson.build
178
diff view generated by jsdifflib
New patch
1
From: Thomas Huth <thuth@redhat.com>
1
2
3
pci_device.h is not needed at all in allwinner-a10.h, and serial.h
4
is only needed by the corresponding .c file.
5
6
Signed-off-by: Thomas Huth <thuth@redhat.com>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20230215152233.210024-1-thuth@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/allwinner-a10.h | 2 --
12
hw/arm/allwinner-a10.c | 1 +
13
2 files changed, 1 insertion(+), 2 deletions(-)
14
15
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/allwinner-a10.h
18
+++ b/include/hw/arm/allwinner-a10.h
19
@@ -XXX,XX +XXX,XX @@
20
#ifndef HW_ARM_ALLWINNER_A10_H
21
#define HW_ARM_ALLWINNER_A10_H
22
23
-#include "hw/char/serial.h"
24
#include "hw/arm/boot.h"
25
-#include "hw/pci/pci_device.h"
26
#include "hw/timer/allwinner-a10-pit.h"
27
#include "hw/intc/allwinner-a10-pic.h"
28
#include "hw/net/allwinner_emac.h"
29
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/allwinner-a10.c
32
+++ b/hw/arm/allwinner-a10.c
33
@@ -XXX,XX +XXX,XX @@
34
#include "qemu/osdep.h"
35
#include "qapi/error.h"
36
#include "qemu/module.h"
37
+#include "hw/char/serial.h"
38
#include "hw/sysbus.h"
39
#include "hw/arm/allwinner-a10.h"
40
#include "hw/misc/unimp.h"
41
--
42
2.34.1
43
44
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Simplify freeing cp_regs hash table entries by using a single
3
This is in preparation for restricting compilation of some parts of
4
allocation for the entire value.
4
debug_helper.c to TCG only.
5
5
6
This fixes a theoretical bug if we were to ever free the entire
6
Signed-off-by: Fabiano Rosas <farosas@suse.de>
7
hash table, because we've been installing string literal constants
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
into the cpreg structure in define_arm_vh_e2h_redirects_aliases.
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.
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
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
9
---
18
target/arm/cpu.c | 16 +---------------
10
target/arm/cpu.c | 6 ++++--
19
target/arm/helper.c | 10 ++++++++--
11
target/arm/debug_helper.c | 16 ++++++++++++----
20
2 files changed, 9 insertions(+), 17 deletions(-)
12
target/arm/machine.c | 7 +++++--
13
3 files changed, 21 insertions(+), 8 deletions(-)
21
14
22
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
15
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
23
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.c
17
--- a/target/arm/cpu.c
25
+++ b/target/arm/cpu.c
18
+++ b/target/arm/cpu.c
26
@@ -XXX,XX +XXX,XX @@ uint64_t arm_cpu_mp_affinity(int idx, uint8_t clustersz)
19
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset_hold(Object *obj)
27
return (Aff1 << ARM_AFF1_SHIFT) | Aff0;
20
}
21
#endif
22
23
- hw_breakpoint_update_all(cpu);
24
- hw_watchpoint_update_all(cpu);
25
+ if (tcg_enabled()) {
26
+ hw_breakpoint_update_all(cpu);
27
+ hw_watchpoint_update_all(cpu);
28
+ }
29
arm_rebuild_hflags(env);
28
}
30
}
29
31
30
-static void cpreg_hashtable_data_destroy(gpointer data)
32
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
31
-{
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
33
index XXXXXXX..XXXXXXX 100644
57
--- a/target/arm/helper.c
34
--- a/target/arm/debug_helper.c
58
+++ b/target/arm/helper.c
35
+++ b/target/arm/debug_helper.c
59
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
36
@@ -XXX,XX +XXX,XX @@ static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
60
* add a single reginfo struct to the hash table.
37
value &= ~3ULL;
61
*/
38
62
uint32_t key;
39
raw_write(env, ri, value);
63
- ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
40
- hw_watchpoint_update(cpu, i);
64
+ ARMCPRegInfo *r2;
41
+ if (tcg_enabled()) {
65
int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
42
+ hw_watchpoint_update(cpu, i);
66
int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
43
+ }
67
+ size_t name_len;
44
}
68
+
45
69
+ /* Combine cpreg and name into one allocation. */
46
static void dbgwcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
70
+ name_len = strlen(name) + 1;
47
@@ -XXX,XX +XXX,XX @@ static void dbgwcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
71
+ r2 = g_malloc(sizeof(*r2) + name_len);
48
int i = ri->crm;
72
+ *r2 = *r;
49
73
+ r2->name = memcpy(r2 + 1, name, name_len);
50
raw_write(env, ri, value);
74
51
- hw_watchpoint_update(cpu, i);
75
- r2->name = g_strdup(name);
52
+ if (tcg_enabled()) {
76
/* Reset the secure state to the specific incoming state. This is
53
+ hw_watchpoint_update(cpu, i);
77
* necessary as the register may have been defined with both states.
54
+ }
78
*/
55
}
56
57
void hw_breakpoint_update(ARMCPU *cpu, int n)
58
@@ -XXX,XX +XXX,XX @@ static void dbgbvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
59
int i = ri->crm;
60
61
raw_write(env, ri, value);
62
- hw_breakpoint_update(cpu, i);
63
+ if (tcg_enabled()) {
64
+ hw_breakpoint_update(cpu, i);
65
+ }
66
}
67
68
static void dbgbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
69
@@ -XXX,XX +XXX,XX @@ static void dbgbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
70
value = deposit64(value, 8, 1, extract64(value, 7, 1));
71
72
raw_write(env, ri, value);
73
- hw_breakpoint_update(cpu, i);
74
+ if (tcg_enabled()) {
75
+ hw_breakpoint_update(cpu, i);
76
+ }
77
}
78
79
void define_debug_regs(ARMCPU *cpu)
80
diff --git a/target/arm/machine.c b/target/arm/machine.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/machine.c
83
+++ b/target/arm/machine.c
84
@@ -XXX,XX +XXX,XX @@
85
#include "cpu.h"
86
#include "qemu/error-report.h"
87
#include "sysemu/kvm.h"
88
+#include "sysemu/tcg.h"
89
#include "kvm_arm.h"
90
#include "internals.h"
91
#include "migration/cpu.h"
92
@@ -XXX,XX +XXX,XX @@ static int cpu_post_load(void *opaque, int version_id)
93
return -1;
94
}
95
96
- hw_breakpoint_update_all(cpu);
97
- hw_watchpoint_update_all(cpu);
98
+ if (tcg_enabled()) {
99
+ hw_breakpoint_update_all(cpu);
100
+ hw_watchpoint_update_all(cpu);
101
+ }
102
103
/*
104
* TCG gen_update_fp_context() relies on the invariant that
79
--
105
--
80
2.25.1
106
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Add the aa64 predicate for detecting RAS support from id registers.
3
The next few patches will move helpers under CONFIG_TCG. We'd prefer
4
We already have the aa32 version from the M-profile work.
4
to keep the debug helpers and debug registers close together, so
5
Add the 'any' predicate for testing both aa64 and aa32.
5
rearrange the file a bit to be able to wrap the helpers with a TCG
6
ifdef.
6
7
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Fabiano Rosas <farosas@suse.de>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220501055028.646596-34-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
---
11
---
12
target/arm/cpu.h | 10 ++++++++++
12
target/arm/debug_helper.c | 476 +++++++++++++++++++-------------------
13
1 file changed, 10 insertions(+)
13
1 file changed, 239 insertions(+), 237 deletions(-)
14
14
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
17
--- a/target/arm/debug_helper.c
18
+++ b/target/arm/cpu.h
18
+++ b/target/arm/debug_helper.c
19
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_aa32_el1(const ARMISARegisters *id)
19
@@ -XXX,XX +XXX,XX @@
20
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, EL1) >= 2;
20
#include "cpregs.h"
21
#include "exec/exec-all.h"
22
#include "exec/helper-proto.h"
23
+#include "sysemu/tcg.h"
24
25
-
26
+#ifdef CONFIG_TCG
27
/* Return the Exception Level targeted by debug exceptions. */
28
static int arm_debug_target_el(CPUARMState *env)
29
{
30
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_swstep)(CPUARMState *env, uint32_t syndrome)
31
raise_exception_debug(env, EXCP_UDEF, syndrome);
21
}
32
}
22
33
23
+static inline bool isar_feature_aa64_ras(const ARMISARegisters *id)
34
+void hw_watchpoint_update(ARMCPU *cpu, int n)
24
+{
35
+{
25
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RAS) != 0;
36
+ CPUARMState *env = &cpu->env;
37
+ vaddr len = 0;
38
+ vaddr wvr = env->cp15.dbgwvr[n];
39
+ uint64_t wcr = env->cp15.dbgwcr[n];
40
+ int mask;
41
+ int flags = BP_CPU | BP_STOP_BEFORE_ACCESS;
42
+
43
+ if (env->cpu_watchpoint[n]) {
44
+ cpu_watchpoint_remove_by_ref(CPU(cpu), env->cpu_watchpoint[n]);
45
+ env->cpu_watchpoint[n] = NULL;
46
+ }
47
+
48
+ if (!FIELD_EX64(wcr, DBGWCR, E)) {
49
+ /* E bit clear : watchpoint disabled */
50
+ return;
51
+ }
52
+
53
+ switch (FIELD_EX64(wcr, DBGWCR, LSC)) {
54
+ case 0:
55
+ /* LSC 00 is reserved and must behave as if the wp is disabled */
56
+ return;
57
+ case 1:
58
+ flags |= BP_MEM_READ;
59
+ break;
60
+ case 2:
61
+ flags |= BP_MEM_WRITE;
62
+ break;
63
+ case 3:
64
+ flags |= BP_MEM_ACCESS;
65
+ break;
66
+ }
67
+
68
+ /*
69
+ * Attempts to use both MASK and BAS fields simultaneously are
70
+ * CONSTRAINED UNPREDICTABLE; we opt to ignore BAS in this case,
71
+ * thus generating a watchpoint for every byte in the masked region.
72
+ */
73
+ mask = FIELD_EX64(wcr, DBGWCR, MASK);
74
+ if (mask == 1 || mask == 2) {
75
+ /*
76
+ * Reserved values of MASK; we must act as if the mask value was
77
+ * some non-reserved value, or as if the watchpoint were disabled.
78
+ * We choose the latter.
79
+ */
80
+ return;
81
+ } else if (mask) {
82
+ /* Watchpoint covers an aligned area up to 2GB in size */
83
+ len = 1ULL << mask;
84
+ /*
85
+ * If masked bits in WVR are not zero it's CONSTRAINED UNPREDICTABLE
86
+ * whether the watchpoint fires when the unmasked bits match; we opt
87
+ * to generate the exceptions.
88
+ */
89
+ wvr &= ~(len - 1);
90
+ } else {
91
+ /* Watchpoint covers bytes defined by the byte address select bits */
92
+ int bas = FIELD_EX64(wcr, DBGWCR, BAS);
93
+ int basstart;
94
+
95
+ if (extract64(wvr, 2, 1)) {
96
+ /*
97
+ * Deprecated case of an only 4-aligned address. BAS[7:4] are
98
+ * ignored, and BAS[3:0] define which bytes to watch.
99
+ */
100
+ bas &= 0xf;
101
+ }
102
+
103
+ if (bas == 0) {
104
+ /* This must act as if the watchpoint is disabled */
105
+ return;
106
+ }
107
+
108
+ /*
109
+ * The BAS bits are supposed to be programmed to indicate a contiguous
110
+ * range of bytes. Otherwise it is CONSTRAINED UNPREDICTABLE whether
111
+ * we fire for each byte in the word/doubleword addressed by the WVR.
112
+ * We choose to ignore any non-zero bits after the first range of 1s.
113
+ */
114
+ basstart = ctz32(bas);
115
+ len = cto32(bas >> basstart);
116
+ wvr += basstart;
117
+ }
118
+
119
+ cpu_watchpoint_insert(CPU(cpu), wvr, len, flags,
120
+ &env->cpu_watchpoint[n]);
26
+}
121
+}
27
+
122
+
28
static inline bool isar_feature_aa64_sve(const ARMISARegisters *id)
123
+void hw_watchpoint_update_all(ARMCPU *cpu)
124
+{
125
+ int i;
126
+ CPUARMState *env = &cpu->env;
127
+
128
+ /*
129
+ * Completely clear out existing QEMU watchpoints and our array, to
130
+ * avoid possible stale entries following migration load.
131
+ */
132
+ cpu_watchpoint_remove_all(CPU(cpu), BP_CPU);
133
+ memset(env->cpu_watchpoint, 0, sizeof(env->cpu_watchpoint));
134
+
135
+ for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_watchpoint); i++) {
136
+ hw_watchpoint_update(cpu, i);
137
+ }
138
+}
139
+
140
+void hw_breakpoint_update(ARMCPU *cpu, int n)
141
+{
142
+ CPUARMState *env = &cpu->env;
143
+ uint64_t bvr = env->cp15.dbgbvr[n];
144
+ uint64_t bcr = env->cp15.dbgbcr[n];
145
+ vaddr addr;
146
+ int bt;
147
+ int flags = BP_CPU;
148
+
149
+ if (env->cpu_breakpoint[n]) {
150
+ cpu_breakpoint_remove_by_ref(CPU(cpu), env->cpu_breakpoint[n]);
151
+ env->cpu_breakpoint[n] = NULL;
152
+ }
153
+
154
+ if (!extract64(bcr, 0, 1)) {
155
+ /* E bit clear : watchpoint disabled */
156
+ return;
157
+ }
158
+
159
+ bt = extract64(bcr, 20, 4);
160
+
161
+ switch (bt) {
162
+ case 4: /* unlinked address mismatch (reserved if AArch64) */
163
+ case 5: /* linked address mismatch (reserved if AArch64) */
164
+ qemu_log_mask(LOG_UNIMP,
165
+ "arm: address mismatch breakpoint types not implemented\n");
166
+ return;
167
+ case 0: /* unlinked address match */
168
+ case 1: /* linked address match */
169
+ {
170
+ /*
171
+ * Bits [1:0] are RES0.
172
+ *
173
+ * It is IMPLEMENTATION DEFINED whether bits [63:49]
174
+ * ([63:53] for FEAT_LVA) are hardwired to a copy of the sign bit
175
+ * of the VA field ([48] or [52] for FEAT_LVA), or whether the
176
+ * value is read as written. It is CONSTRAINED UNPREDICTABLE
177
+ * whether the RESS bits are ignored when comparing an address.
178
+ * Therefore we are allowed to compare the entire register, which
179
+ * lets us avoid considering whether FEAT_LVA is actually enabled.
180
+ *
181
+ * The BAS field is used to allow setting breakpoints on 16-bit
182
+ * wide instructions; it is CONSTRAINED UNPREDICTABLE whether
183
+ * a bp will fire if the addresses covered by the bp and the addresses
184
+ * covered by the insn overlap but the insn doesn't start at the
185
+ * start of the bp address range. We choose to require the insn and
186
+ * the bp to have the same address. The constraints on writing to
187
+ * BAS enforced in dbgbcr_write mean we have only four cases:
188
+ * 0b0000 => no breakpoint
189
+ * 0b0011 => breakpoint on addr
190
+ * 0b1100 => breakpoint on addr + 2
191
+ * 0b1111 => breakpoint on addr
192
+ * See also figure D2-3 in the v8 ARM ARM (DDI0487A.c).
193
+ */
194
+ int bas = extract64(bcr, 5, 4);
195
+ addr = bvr & ~3ULL;
196
+ if (bas == 0) {
197
+ return;
198
+ }
199
+ if (bas == 0xc) {
200
+ addr += 2;
201
+ }
202
+ break;
203
+ }
204
+ case 2: /* unlinked context ID match */
205
+ case 8: /* unlinked VMID match (reserved if no EL2) */
206
+ case 10: /* unlinked context ID and VMID match (reserved if no EL2) */
207
+ qemu_log_mask(LOG_UNIMP,
208
+ "arm: unlinked context breakpoint types not implemented\n");
209
+ return;
210
+ case 9: /* linked VMID match (reserved if no EL2) */
211
+ case 11: /* linked context ID and VMID match (reserved if no EL2) */
212
+ case 3: /* linked context ID match */
213
+ default:
214
+ /*
215
+ * We must generate no events for Linked context matches (unless
216
+ * they are linked to by some other bp/wp, which is handled in
217
+ * updates for the linking bp/wp). We choose to also generate no events
218
+ * for reserved values.
219
+ */
220
+ return;
221
+ }
222
+
223
+ cpu_breakpoint_insert(CPU(cpu), addr, flags, &env->cpu_breakpoint[n]);
224
+}
225
+
226
+void hw_breakpoint_update_all(ARMCPU *cpu)
227
+{
228
+ int i;
229
+ CPUARMState *env = &cpu->env;
230
+
231
+ /*
232
+ * Completely clear out existing QEMU breakpoints and our array, to
233
+ * avoid possible stale entries following migration load.
234
+ */
235
+ cpu_breakpoint_remove_all(CPU(cpu), BP_CPU);
236
+ memset(env->cpu_breakpoint, 0, sizeof(env->cpu_breakpoint));
237
+
238
+ for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_breakpoint); i++) {
239
+ hw_breakpoint_update(cpu, i);
240
+ }
241
+}
242
+
243
+#if !defined(CONFIG_USER_ONLY)
244
+
245
+vaddr arm_adjust_watchpoint_address(CPUState *cs, vaddr addr, int len)
246
+{
247
+ ARMCPU *cpu = ARM_CPU(cs);
248
+ CPUARMState *env = &cpu->env;
249
+
250
+ /*
251
+ * In BE32 system mode, target memory is stored byteswapped (on a
252
+ * little-endian host system), and by the time we reach here (via an
253
+ * opcode helper) the addresses of subword accesses have been adjusted
254
+ * to account for that, which means that watchpoints will not match.
255
+ * Undo the adjustment here.
256
+ */
257
+ if (arm_sctlr_b(env)) {
258
+ if (len == 1) {
259
+ addr ^= 3;
260
+ } else if (len == 2) {
261
+ addr ^= 2;
262
+ }
263
+ }
264
+
265
+ return addr;
266
+}
267
+
268
+#endif /* !CONFIG_USER_ONLY */
269
+#endif /* CONFIG_TCG */
270
+
271
/*
272
* Check for traps to "powerdown debug" registers, which are controlled
273
* by MDCR.TDOSA
274
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
275
.access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
276
};
277
278
-void hw_watchpoint_update(ARMCPU *cpu, int n)
279
-{
280
- CPUARMState *env = &cpu->env;
281
- vaddr len = 0;
282
- vaddr wvr = env->cp15.dbgwvr[n];
283
- uint64_t wcr = env->cp15.dbgwcr[n];
284
- int mask;
285
- int flags = BP_CPU | BP_STOP_BEFORE_ACCESS;
286
-
287
- if (env->cpu_watchpoint[n]) {
288
- cpu_watchpoint_remove_by_ref(CPU(cpu), env->cpu_watchpoint[n]);
289
- env->cpu_watchpoint[n] = NULL;
290
- }
291
-
292
- if (!FIELD_EX64(wcr, DBGWCR, E)) {
293
- /* E bit clear : watchpoint disabled */
294
- return;
295
- }
296
-
297
- switch (FIELD_EX64(wcr, DBGWCR, LSC)) {
298
- case 0:
299
- /* LSC 00 is reserved and must behave as if the wp is disabled */
300
- return;
301
- case 1:
302
- flags |= BP_MEM_READ;
303
- break;
304
- case 2:
305
- flags |= BP_MEM_WRITE;
306
- break;
307
- case 3:
308
- flags |= BP_MEM_ACCESS;
309
- break;
310
- }
311
-
312
- /*
313
- * Attempts to use both MASK and BAS fields simultaneously are
314
- * CONSTRAINED UNPREDICTABLE; we opt to ignore BAS in this case,
315
- * thus generating a watchpoint for every byte in the masked region.
316
- */
317
- mask = FIELD_EX64(wcr, DBGWCR, MASK);
318
- if (mask == 1 || mask == 2) {
319
- /*
320
- * Reserved values of MASK; we must act as if the mask value was
321
- * some non-reserved value, or as if the watchpoint were disabled.
322
- * We choose the latter.
323
- */
324
- return;
325
- } else if (mask) {
326
- /* Watchpoint covers an aligned area up to 2GB in size */
327
- len = 1ULL << mask;
328
- /*
329
- * If masked bits in WVR are not zero it's CONSTRAINED UNPREDICTABLE
330
- * whether the watchpoint fires when the unmasked bits match; we opt
331
- * to generate the exceptions.
332
- */
333
- wvr &= ~(len - 1);
334
- } else {
335
- /* Watchpoint covers bytes defined by the byte address select bits */
336
- int bas = FIELD_EX64(wcr, DBGWCR, BAS);
337
- int basstart;
338
-
339
- if (extract64(wvr, 2, 1)) {
340
- /*
341
- * Deprecated case of an only 4-aligned address. BAS[7:4] are
342
- * ignored, and BAS[3:0] define which bytes to watch.
343
- */
344
- bas &= 0xf;
345
- }
346
-
347
- if (bas == 0) {
348
- /* This must act as if the watchpoint is disabled */
349
- return;
350
- }
351
-
352
- /*
353
- * The BAS bits are supposed to be programmed to indicate a contiguous
354
- * range of bytes. Otherwise it is CONSTRAINED UNPREDICTABLE whether
355
- * we fire for each byte in the word/doubleword addressed by the WVR.
356
- * We choose to ignore any non-zero bits after the first range of 1s.
357
- */
358
- basstart = ctz32(bas);
359
- len = cto32(bas >> basstart);
360
- wvr += basstart;
361
- }
362
-
363
- cpu_watchpoint_insert(CPU(cpu), wvr, len, flags,
364
- &env->cpu_watchpoint[n]);
365
-}
366
-
367
-void hw_watchpoint_update_all(ARMCPU *cpu)
368
-{
369
- int i;
370
- CPUARMState *env = &cpu->env;
371
-
372
- /*
373
- * Completely clear out existing QEMU watchpoints and our array, to
374
- * avoid possible stale entries following migration load.
375
- */
376
- cpu_watchpoint_remove_all(CPU(cpu), BP_CPU);
377
- memset(env->cpu_watchpoint, 0, sizeof(env->cpu_watchpoint));
378
-
379
- for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_watchpoint); i++) {
380
- hw_watchpoint_update(cpu, i);
381
- }
382
-}
383
-
384
static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
385
uint64_t value)
29
{
386
{
30
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0;
387
@@ -XXX,XX +XXX,XX @@ static void dbgwcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
31
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_debugv8p2(const ARMISARegisters *id)
388
}
32
return isar_feature_aa64_debugv8p2(id) || isar_feature_aa32_debugv8p2(id);
33
}
389
}
34
390
35
+static inline bool isar_feature_any_ras(const ARMISARegisters *id)
391
-void hw_breakpoint_update(ARMCPU *cpu, int n)
36
+{
392
-{
37
+ return isar_feature_aa64_ras(id) || isar_feature_aa32_ras(id);
393
- CPUARMState *env = &cpu->env;
38
+}
394
- uint64_t bvr = env->cp15.dbgbvr[n];
39
+
395
- uint64_t bcr = env->cp15.dbgbcr[n];
40
/*
396
- vaddr addr;
41
* Forward to the above feature tests given an ARMCPU pointer.
397
- int bt;
42
*/
398
- int flags = BP_CPU;
399
-
400
- if (env->cpu_breakpoint[n]) {
401
- cpu_breakpoint_remove_by_ref(CPU(cpu), env->cpu_breakpoint[n]);
402
- env->cpu_breakpoint[n] = NULL;
403
- }
404
-
405
- if (!extract64(bcr, 0, 1)) {
406
- /* E bit clear : watchpoint disabled */
407
- return;
408
- }
409
-
410
- bt = extract64(bcr, 20, 4);
411
-
412
- switch (bt) {
413
- case 4: /* unlinked address mismatch (reserved if AArch64) */
414
- case 5: /* linked address mismatch (reserved if AArch64) */
415
- qemu_log_mask(LOG_UNIMP,
416
- "arm: address mismatch breakpoint types not implemented\n");
417
- return;
418
- case 0: /* unlinked address match */
419
- case 1: /* linked address match */
420
- {
421
- /*
422
- * Bits [1:0] are RES0.
423
- *
424
- * It is IMPLEMENTATION DEFINED whether bits [63:49]
425
- * ([63:53] for FEAT_LVA) are hardwired to a copy of the sign bit
426
- * of the VA field ([48] or [52] for FEAT_LVA), or whether the
427
- * value is read as written. It is CONSTRAINED UNPREDICTABLE
428
- * whether the RESS bits are ignored when comparing an address.
429
- * Therefore we are allowed to compare the entire register, which
430
- * lets us avoid considering whether FEAT_LVA is actually enabled.
431
- *
432
- * The BAS field is used to allow setting breakpoints on 16-bit
433
- * wide instructions; it is CONSTRAINED UNPREDICTABLE whether
434
- * a bp will fire if the addresses covered by the bp and the addresses
435
- * covered by the insn overlap but the insn doesn't start at the
436
- * start of the bp address range. We choose to require the insn and
437
- * the bp to have the same address. The constraints on writing to
438
- * BAS enforced in dbgbcr_write mean we have only four cases:
439
- * 0b0000 => no breakpoint
440
- * 0b0011 => breakpoint on addr
441
- * 0b1100 => breakpoint on addr + 2
442
- * 0b1111 => breakpoint on addr
443
- * See also figure D2-3 in the v8 ARM ARM (DDI0487A.c).
444
- */
445
- int bas = extract64(bcr, 5, 4);
446
- addr = bvr & ~3ULL;
447
- if (bas == 0) {
448
- return;
449
- }
450
- if (bas == 0xc) {
451
- addr += 2;
452
- }
453
- break;
454
- }
455
- case 2: /* unlinked context ID match */
456
- case 8: /* unlinked VMID match (reserved if no EL2) */
457
- case 10: /* unlinked context ID and VMID match (reserved if no EL2) */
458
- qemu_log_mask(LOG_UNIMP,
459
- "arm: unlinked context breakpoint types not implemented\n");
460
- return;
461
- case 9: /* linked VMID match (reserved if no EL2) */
462
- case 11: /* linked context ID and VMID match (reserved if no EL2) */
463
- case 3: /* linked context ID match */
464
- default:
465
- /*
466
- * We must generate no events for Linked context matches (unless
467
- * they are linked to by some other bp/wp, which is handled in
468
- * updates for the linking bp/wp). We choose to also generate no events
469
- * for reserved values.
470
- */
471
- return;
472
- }
473
-
474
- cpu_breakpoint_insert(CPU(cpu), addr, flags, &env->cpu_breakpoint[n]);
475
-}
476
-
477
-void hw_breakpoint_update_all(ARMCPU *cpu)
478
-{
479
- int i;
480
- CPUARMState *env = &cpu->env;
481
-
482
- /*
483
- * Completely clear out existing QEMU breakpoints and our array, to
484
- * avoid possible stale entries following migration load.
485
- */
486
- cpu_breakpoint_remove_all(CPU(cpu), BP_CPU);
487
- memset(env->cpu_breakpoint, 0, sizeof(env->cpu_breakpoint));
488
-
489
- for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_breakpoint); i++) {
490
- hw_breakpoint_update(cpu, i);
491
- }
492
-}
493
-
494
static void dbgbvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
495
uint64_t value)
496
{
497
@@ -XXX,XX +XXX,XX @@ void define_debug_regs(ARMCPU *cpu)
498
g_free(dbgwcr_el1_name);
499
}
500
}
501
-
502
-#if !defined(CONFIG_USER_ONLY)
503
-
504
-vaddr arm_adjust_watchpoint_address(CPUState *cs, vaddr addr, int len)
505
-{
506
- ARMCPU *cpu = ARM_CPU(cs);
507
- CPUARMState *env = &cpu->env;
508
-
509
- /*
510
- * In BE32 system mode, target memory is stored byteswapped (on a
511
- * little-endian host system), and by the time we reach here (via an
512
- * opcode helper) the addresses of subword accesses have been adjusted
513
- * to account for that, which means that watchpoints will not match.
514
- * Undo the adjustment here.
515
- */
516
- if (arm_sctlr_b(env)) {
517
- if (len == 1) {
518
- addr ^= 3;
519
- } else if (len == 2) {
520
- addr ^= 2;
521
- }
522
- }
523
-
524
- return addr;
525
-}
526
-
527
-#endif
43
--
528
--
44
2.25.1
529
2.34.1
diff view generated by jsdifflib
New patch
1
1
From: Fabiano Rosas <farosas@suse.de>
2
3
Introduce the target/arm/tcg directory. Its purpose is to hold the TCG
4
code that is selected by CONFIG_TCG.
5
6
Signed-off-by: Claudio Fontana <cfontana@suse.de>
7
Signed-off-by: Fabiano Rosas <farosas@suse.de>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
MAINTAINERS | 1 +
15
target/arm/{ => tcg}/translate-a64.h | 0
16
target/arm/{ => tcg}/translate.h | 0
17
target/arm/{ => tcg}/a32-uncond.decode | 0
18
target/arm/{ => tcg}/a32.decode | 0
19
target/arm/{ => tcg}/m-nocp.decode | 0
20
target/arm/{ => tcg}/mve.decode | 0
21
target/arm/{ => tcg}/neon-dp.decode | 0
22
target/arm/{ => tcg}/neon-ls.decode | 0
23
target/arm/{ => tcg}/neon-shared.decode | 0
24
target/arm/{ => tcg}/sme-fa64.decode | 0
25
target/arm/{ => tcg}/sme.decode | 0
26
target/arm/{ => tcg}/sve.decode | 0
27
target/arm/{ => tcg}/t16.decode | 0
28
target/arm/{ => tcg}/t32.decode | 0
29
target/arm/{ => tcg}/vfp-uncond.decode | 0
30
target/arm/{ => tcg}/vfp.decode | 0
31
target/arm/{ => tcg}/translate-a64.c | 0
32
target/arm/{ => tcg}/translate-m-nocp.c | 0
33
target/arm/{ => tcg}/translate-mve.c | 0
34
target/arm/{ => tcg}/translate-neon.c | 0
35
target/arm/{ => tcg}/translate-sme.c | 0
36
target/arm/{ => tcg}/translate-sve.c | 0
37
target/arm/{ => tcg}/translate-vfp.c | 0
38
target/arm/{ => tcg}/translate.c | 0
39
target/arm/meson.build | 30 +++---------------
40
target/arm/{ => tcg}/meson.build | 41 +------------------------
41
27 files changed, 6 insertions(+), 66 deletions(-)
42
rename target/arm/{ => tcg}/translate-a64.h (100%)
43
rename target/arm/{ => tcg}/translate.h (100%)
44
rename target/arm/{ => tcg}/a32-uncond.decode (100%)
45
rename target/arm/{ => tcg}/a32.decode (100%)
46
rename target/arm/{ => tcg}/m-nocp.decode (100%)
47
rename target/arm/{ => tcg}/mve.decode (100%)
48
rename target/arm/{ => tcg}/neon-dp.decode (100%)
49
rename target/arm/{ => tcg}/neon-ls.decode (100%)
50
rename target/arm/{ => tcg}/neon-shared.decode (100%)
51
rename target/arm/{ => tcg}/sme-fa64.decode (100%)
52
rename target/arm/{ => tcg}/sme.decode (100%)
53
rename target/arm/{ => tcg}/sve.decode (100%)
54
rename target/arm/{ => tcg}/t16.decode (100%)
55
rename target/arm/{ => tcg}/t32.decode (100%)
56
rename target/arm/{ => tcg}/vfp-uncond.decode (100%)
57
rename target/arm/{ => tcg}/vfp.decode (100%)
58
rename target/arm/{ => tcg}/translate-a64.c (100%)
59
rename target/arm/{ => tcg}/translate-m-nocp.c (100%)
60
rename target/arm/{ => tcg}/translate-mve.c (100%)
61
rename target/arm/{ => tcg}/translate-neon.c (100%)
62
rename target/arm/{ => tcg}/translate-sme.c (100%)
63
rename target/arm/{ => tcg}/translate-sve.c (100%)
64
rename target/arm/{ => tcg}/translate-vfp.c (100%)
65
rename target/arm/{ => tcg}/translate.c (100%)
66
copy target/arm/{ => tcg}/meson.build (64%)
67
68
diff --git a/MAINTAINERS b/MAINTAINERS
69
index XXXXXXX..XXXXXXX 100644
70
--- a/MAINTAINERS
71
+++ b/MAINTAINERS
72
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
73
L: qemu-arm@nongnu.org
74
S: Maintained
75
F: target/arm/
76
+F: target/arm/tcg/
77
F: tests/tcg/arm/
78
F: tests/tcg/aarch64/
79
F: tests/qtest/arm-cpu-features.c
80
diff --git a/target/arm/translate-a64.h b/target/arm/tcg/translate-a64.h
81
similarity index 100%
82
rename from target/arm/translate-a64.h
83
rename to target/arm/tcg/translate-a64.h
84
diff --git a/target/arm/translate.h b/target/arm/tcg/translate.h
85
similarity index 100%
86
rename from target/arm/translate.h
87
rename to target/arm/tcg/translate.h
88
diff --git a/target/arm/a32-uncond.decode b/target/arm/tcg/a32-uncond.decode
89
similarity index 100%
90
rename from target/arm/a32-uncond.decode
91
rename to target/arm/tcg/a32-uncond.decode
92
diff --git a/target/arm/a32.decode b/target/arm/tcg/a32.decode
93
similarity index 100%
94
rename from target/arm/a32.decode
95
rename to target/arm/tcg/a32.decode
96
diff --git a/target/arm/m-nocp.decode b/target/arm/tcg/m-nocp.decode
97
similarity index 100%
98
rename from target/arm/m-nocp.decode
99
rename to target/arm/tcg/m-nocp.decode
100
diff --git a/target/arm/mve.decode b/target/arm/tcg/mve.decode
101
similarity index 100%
102
rename from target/arm/mve.decode
103
rename to target/arm/tcg/mve.decode
104
diff --git a/target/arm/neon-dp.decode b/target/arm/tcg/neon-dp.decode
105
similarity index 100%
106
rename from target/arm/neon-dp.decode
107
rename to target/arm/tcg/neon-dp.decode
108
diff --git a/target/arm/neon-ls.decode b/target/arm/tcg/neon-ls.decode
109
similarity index 100%
110
rename from target/arm/neon-ls.decode
111
rename to target/arm/tcg/neon-ls.decode
112
diff --git a/target/arm/neon-shared.decode b/target/arm/tcg/neon-shared.decode
113
similarity index 100%
114
rename from target/arm/neon-shared.decode
115
rename to target/arm/tcg/neon-shared.decode
116
diff --git a/target/arm/sme-fa64.decode b/target/arm/tcg/sme-fa64.decode
117
similarity index 100%
118
rename from target/arm/sme-fa64.decode
119
rename to target/arm/tcg/sme-fa64.decode
120
diff --git a/target/arm/sme.decode b/target/arm/tcg/sme.decode
121
similarity index 100%
122
rename from target/arm/sme.decode
123
rename to target/arm/tcg/sme.decode
124
diff --git a/target/arm/sve.decode b/target/arm/tcg/sve.decode
125
similarity index 100%
126
rename from target/arm/sve.decode
127
rename to target/arm/tcg/sve.decode
128
diff --git a/target/arm/t16.decode b/target/arm/tcg/t16.decode
129
similarity index 100%
130
rename from target/arm/t16.decode
131
rename to target/arm/tcg/t16.decode
132
diff --git a/target/arm/t32.decode b/target/arm/tcg/t32.decode
133
similarity index 100%
134
rename from target/arm/t32.decode
135
rename to target/arm/tcg/t32.decode
136
diff --git a/target/arm/vfp-uncond.decode b/target/arm/tcg/vfp-uncond.decode
137
similarity index 100%
138
rename from target/arm/vfp-uncond.decode
139
rename to target/arm/tcg/vfp-uncond.decode
140
diff --git a/target/arm/vfp.decode b/target/arm/tcg/vfp.decode
141
similarity index 100%
142
rename from target/arm/vfp.decode
143
rename to target/arm/tcg/vfp.decode
144
diff --git a/target/arm/translate-a64.c b/target/arm/tcg/translate-a64.c
145
similarity index 100%
146
rename from target/arm/translate-a64.c
147
rename to target/arm/tcg/translate-a64.c
148
diff --git a/target/arm/translate-m-nocp.c b/target/arm/tcg/translate-m-nocp.c
149
similarity index 100%
150
rename from target/arm/translate-m-nocp.c
151
rename to target/arm/tcg/translate-m-nocp.c
152
diff --git a/target/arm/translate-mve.c b/target/arm/tcg/translate-mve.c
153
similarity index 100%
154
rename from target/arm/translate-mve.c
155
rename to target/arm/tcg/translate-mve.c
156
diff --git a/target/arm/translate-neon.c b/target/arm/tcg/translate-neon.c
157
similarity index 100%
158
rename from target/arm/translate-neon.c
159
rename to target/arm/tcg/translate-neon.c
160
diff --git a/target/arm/translate-sme.c b/target/arm/tcg/translate-sme.c
161
similarity index 100%
162
rename from target/arm/translate-sme.c
163
rename to target/arm/tcg/translate-sme.c
164
diff --git a/target/arm/translate-sve.c b/target/arm/tcg/translate-sve.c
165
similarity index 100%
166
rename from target/arm/translate-sve.c
167
rename to target/arm/tcg/translate-sve.c
168
diff --git a/target/arm/translate-vfp.c b/target/arm/tcg/translate-vfp.c
169
similarity index 100%
170
rename from target/arm/translate-vfp.c
171
rename to target/arm/tcg/translate-vfp.c
172
diff --git a/target/arm/translate.c b/target/arm/tcg/translate.c
173
similarity index 100%
174
rename from target/arm/translate.c
175
rename to target/arm/tcg/translate.c
176
diff --git a/target/arm/meson.build b/target/arm/meson.build
177
index XXXXXXX..XXXXXXX 100644
178
--- a/target/arm/meson.build
179
+++ b/target/arm/meson.build
180
@@ -XXX,XX +XXX,XX @@
181
-gen = [
182
- decodetree.process('sve.decode', extra_args: '--decode=disas_sve'),
183
- decodetree.process('sme.decode', extra_args: '--decode=disas_sme'),
184
- decodetree.process('sme-fa64.decode', extra_args: '--static-decode=disas_sme_fa64'),
185
- decodetree.process('neon-shared.decode', extra_args: '--decode=disas_neon_shared'),
186
- decodetree.process('neon-dp.decode', extra_args: '--decode=disas_neon_dp'),
187
- decodetree.process('neon-ls.decode', extra_args: '--decode=disas_neon_ls'),
188
- decodetree.process('vfp.decode', extra_args: '--decode=disas_vfp'),
189
- decodetree.process('vfp-uncond.decode', extra_args: '--decode=disas_vfp_uncond'),
190
- decodetree.process('m-nocp.decode', extra_args: '--decode=disas_m_nocp'),
191
- decodetree.process('mve.decode', extra_args: '--decode=disas_mve'),
192
- decodetree.process('a32.decode', extra_args: '--static-decode=disas_a32'),
193
- decodetree.process('a32-uncond.decode', extra_args: '--static-decode=disas_a32_uncond'),
194
- decodetree.process('t32.decode', extra_args: '--static-decode=disas_t32'),
195
- decodetree.process('t16.decode', extra_args: ['-w', '16', '--static-decode=disas_t16']),
196
-]
197
-
198
arm_ss = ss.source_set()
199
-arm_ss.add(gen)
200
arm_ss.add(files(
201
'cpu.c',
202
'crypto_helper.c',
203
@@ -XXX,XX +XXX,XX @@ arm_ss.add(files(
204
'neon_helper.c',
205
'op_helper.c',
206
'tlb_helper.c',
207
- 'translate.c',
208
- 'translate-m-nocp.c',
209
- 'translate-mve.c',
210
- 'translate-neon.c',
211
- 'translate-vfp.c',
212
'vec_helper.c',
213
'vfp_helper.c',
214
'cpu_tcg.c',
215
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
216
'pauth_helper.c',
217
'sve_helper.c',
218
'sme_helper.c',
219
- 'translate-a64.c',
220
- 'translate-sve.c',
221
- 'translate-sme.c',
222
))
223
224
arm_softmmu_ss = ss.source_set()
225
@@ -XXX,XX +XXX,XX @@ arm_softmmu_ss.add(files(
226
227
subdir('hvf')
228
229
+if 'CONFIG_TCG' in config_all
230
+ subdir('tcg')
231
+endif
232
+
233
target_arch += {'arm': arm_ss}
234
target_softmmu_arch += {'arm': arm_softmmu_ss}
235
diff --git a/target/arm/meson.build b/target/arm/tcg/meson.build
236
similarity index 64%
237
copy from target/arm/meson.build
238
copy to target/arm/tcg/meson.build
239
index XXXXXXX..XXXXXXX 100644
240
--- a/target/arm/meson.build
241
+++ b/target/arm/tcg/meson.build
242
@@ -XXX,XX +XXX,XX @@ gen = [
243
decodetree.process('t16.decode', extra_args: ['-w', '16', '--static-decode=disas_t16']),
244
]
245
246
-arm_ss = ss.source_set()
247
arm_ss.add(gen)
248
+
249
arm_ss.add(files(
250
- 'cpu.c',
251
- 'crypto_helper.c',
252
- 'debug_helper.c',
253
- 'gdbstub.c',
254
- 'helper.c',
255
- 'iwmmxt_helper.c',
256
- 'm_helper.c',
257
- 'mve_helper.c',
258
- 'neon_helper.c',
259
- 'op_helper.c',
260
- 'tlb_helper.c',
261
'translate.c',
262
'translate-m-nocp.c',
263
'translate-mve.c',
264
'translate-neon.c',
265
'translate-vfp.c',
266
- 'vec_helper.c',
267
- 'vfp_helper.c',
268
- 'cpu_tcg.c',
269
))
270
-arm_ss.add(zlib)
271
-
272
-arm_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c', 'kvm64.c'), if_false: files('kvm-stub.c'))
273
274
arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
275
- 'cpu64.c',
276
- 'gdbstub64.c',
277
- 'helper-a64.c',
278
- 'mte_helper.c',
279
- 'pauth_helper.c',
280
- 'sve_helper.c',
281
- 'sme_helper.c',
282
'translate-a64.c',
283
'translate-sve.c',
284
'translate-sme.c',
285
))
286
-
287
-arm_softmmu_ss = ss.source_set()
288
-arm_softmmu_ss.add(files(
289
- 'arch_dump.c',
290
- 'arm-powerctl.c',
291
- 'machine.c',
292
- 'monitor.c',
293
- 'psci.c',
294
- 'ptw.c',
295
-))
296
-
297
-subdir('hvf')
298
-
299
-target_arch += {'arm': arm_ss}
300
-target_softmmu_arch += {'arm': arm_softmmu_ss}
301
--
302
2.34.1
303
304
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Claudio Fontana <cfontana@suse.de>
2
2
3
This controls whether the PACI{A,B}SP instructions trap with BTYPE=3
3
Signed-off-by: Claudio Fontana <cfontana@suse.de>
4
(indirect branch from register other than x16/x17). The linux kernel
4
Signed-off-by: Fabiano Rosas <farosas@suse.de>
5
sets this in bti_enable().
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/998
7
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20220427042312.294300-1-richard.henderson@linaro.org
11
[PMM: remove stray change to makefile comment]
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
9
---
14
target/arm/cpu.c | 2 ++
10
target/arm/{ => tcg}/vec_internal.h | 0
15
tests/tcg/aarch64/bti-3.c | 42 +++++++++++++++++++++++++++++++
11
target/arm/tcg-stubs.c | 23 +++++++++++++++++++++++
16
tests/tcg/aarch64/Makefile.target | 6 ++---
12
target/arm/{ => tcg}/crypto_helper.c | 0
17
3 files changed, 47 insertions(+), 3 deletions(-)
13
target/arm/{ => tcg}/helper-a64.c | 0
18
create mode 100644 tests/tcg/aarch64/bti-3.c
14
target/arm/{ => tcg}/iwmmxt_helper.c | 0
19
15
target/arm/{ => tcg}/m_helper.c | 0
20
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
target/arm/{ => tcg}/mte_helper.c | 0
21
index XXXXXXX..XXXXXXX 100644
17
target/arm/{ => tcg}/mve_helper.c | 0
22
--- a/target/arm/cpu.c
18
target/arm/{ => tcg}/neon_helper.c | 0
23
+++ b/target/arm/cpu.c
19
target/arm/{ => tcg}/op_helper.c | 0
24
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
20
target/arm/{ => tcg}/pauth_helper.c | 0
25
/* Enable all PAC keys. */
21
target/arm/{ => tcg}/sme_helper.c | 0
26
env->cp15.sctlr_el[1] |= (SCTLR_EnIA | SCTLR_EnIB |
22
target/arm/{ => tcg}/sve_helper.c | 0
27
SCTLR_EnDA | SCTLR_EnDB);
23
target/arm/{ => tcg}/tlb_helper.c | 0
28
+ /* Trap on btype=3 for PACIxSP. */
24
target/arm/{ => tcg}/vec_helper.c | 0
29
+ env->cp15.sctlr_el[1] |= SCTLR_BT0;
25
target/arm/meson.build | 15 ++-------------
30
/* and to the FP/Neon instructions */
26
target/arm/tcg/meson.build | 13 +++++++++++++
31
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3);
27
17 files changed, 38 insertions(+), 13 deletions(-)
32
/* and to the SVE instructions */
28
rename target/arm/{ => tcg}/vec_internal.h (100%)
33
diff --git a/tests/tcg/aarch64/bti-3.c b/tests/tcg/aarch64/bti-3.c
29
create mode 100644 target/arm/tcg-stubs.c
30
rename target/arm/{ => tcg}/crypto_helper.c (100%)
31
rename target/arm/{ => tcg}/helper-a64.c (100%)
32
rename target/arm/{ => tcg}/iwmmxt_helper.c (100%)
33
rename target/arm/{ => tcg}/m_helper.c (100%)
34
rename target/arm/{ => tcg}/mte_helper.c (100%)
35
rename target/arm/{ => tcg}/mve_helper.c (100%)
36
rename target/arm/{ => tcg}/neon_helper.c (100%)
37
rename target/arm/{ => tcg}/op_helper.c (100%)
38
rename target/arm/{ => tcg}/pauth_helper.c (100%)
39
rename target/arm/{ => tcg}/sme_helper.c (100%)
40
rename target/arm/{ => tcg}/sve_helper.c (100%)
41
rename target/arm/{ => tcg}/tlb_helper.c (100%)
42
rename target/arm/{ => tcg}/vec_helper.c (100%)
43
44
diff --git a/target/arm/vec_internal.h b/target/arm/tcg/vec_internal.h
45
similarity index 100%
46
rename from target/arm/vec_internal.h
47
rename to target/arm/tcg/vec_internal.h
48
diff --git a/target/arm/tcg-stubs.c b/target/arm/tcg-stubs.c
34
new file mode 100644
49
new file mode 100644
35
index XXXXXXX..XXXXXXX
50
index XXXXXXX..XXXXXXX
36
--- /dev/null
51
--- /dev/null
37
+++ b/tests/tcg/aarch64/bti-3.c
52
+++ b/target/arm/tcg-stubs.c
38
@@ -XXX,XX +XXX,XX @@
53
@@ -XXX,XX +XXX,XX @@
39
+/*
54
+/*
40
+ * BTI vs PACIASP
55
+ * QEMU ARM stubs for some TCG helper functions
56
+ *
57
+ * Copyright 2021 SUSE LLC
58
+ *
59
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
60
+ * See the COPYING file in the top-level directory.
41
+ */
61
+ */
42
+
62
+
43
+#include "bti-crt.inc.c"
63
+#include "qemu/osdep.h"
64
+#include "cpu.h"
65
+#include "internals.h"
44
+
66
+
45
+static void skip2_sigill(int sig, siginfo_t *info, ucontext_t *uc)
67
+void write_v7m_exception(CPUARMState *env, uint32_t new_exc)
46
+{
68
+{
47
+ uc->uc_mcontext.pc += 8;
69
+ g_assert_not_reached();
48
+ uc->uc_mcontext.pstate = 1;
49
+}
70
+}
50
+
71
+
51
+#define BTYPE_1() \
72
+void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome,
52
+ asm("mov %0,#1; adr x16, 1f; br x16; 1: hint #25; mov %0,#0" \
73
+ uint32_t target_el, uintptr_t ra)
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()
67
+{
74
+{
68
+ int fail = 0;
75
+ g_assert_not_reached();
69
+ int skipped;
70
+
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;
80
+}
76
+}
81
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
77
diff --git a/target/arm/crypto_helper.c b/target/arm/tcg/crypto_helper.c
78
similarity index 100%
79
rename from target/arm/crypto_helper.c
80
rename to target/arm/tcg/crypto_helper.c
81
diff --git a/target/arm/helper-a64.c b/target/arm/tcg/helper-a64.c
82
similarity index 100%
83
rename from target/arm/helper-a64.c
84
rename to target/arm/tcg/helper-a64.c
85
diff --git a/target/arm/iwmmxt_helper.c b/target/arm/tcg/iwmmxt_helper.c
86
similarity index 100%
87
rename from target/arm/iwmmxt_helper.c
88
rename to target/arm/tcg/iwmmxt_helper.c
89
diff --git a/target/arm/m_helper.c b/target/arm/tcg/m_helper.c
90
similarity index 100%
91
rename from target/arm/m_helper.c
92
rename to target/arm/tcg/m_helper.c
93
diff --git a/target/arm/mte_helper.c b/target/arm/tcg/mte_helper.c
94
similarity index 100%
95
rename from target/arm/mte_helper.c
96
rename to target/arm/tcg/mte_helper.c
97
diff --git a/target/arm/mve_helper.c b/target/arm/tcg/mve_helper.c
98
similarity index 100%
99
rename from target/arm/mve_helper.c
100
rename to target/arm/tcg/mve_helper.c
101
diff --git a/target/arm/neon_helper.c b/target/arm/tcg/neon_helper.c
102
similarity index 100%
103
rename from target/arm/neon_helper.c
104
rename to target/arm/tcg/neon_helper.c
105
diff --git a/target/arm/op_helper.c b/target/arm/tcg/op_helper.c
106
similarity index 100%
107
rename from target/arm/op_helper.c
108
rename to target/arm/tcg/op_helper.c
109
diff --git a/target/arm/pauth_helper.c b/target/arm/tcg/pauth_helper.c
110
similarity index 100%
111
rename from target/arm/pauth_helper.c
112
rename to target/arm/tcg/pauth_helper.c
113
diff --git a/target/arm/sme_helper.c b/target/arm/tcg/sme_helper.c
114
similarity index 100%
115
rename from target/arm/sme_helper.c
116
rename to target/arm/tcg/sme_helper.c
117
diff --git a/target/arm/sve_helper.c b/target/arm/tcg/sve_helper.c
118
similarity index 100%
119
rename from target/arm/sve_helper.c
120
rename to target/arm/tcg/sve_helper.c
121
diff --git a/target/arm/tlb_helper.c b/target/arm/tcg/tlb_helper.c
122
similarity index 100%
123
rename from target/arm/tlb_helper.c
124
rename to target/arm/tcg/tlb_helper.c
125
diff --git a/target/arm/vec_helper.c b/target/arm/tcg/vec_helper.c
126
similarity index 100%
127
rename from target/arm/vec_helper.c
128
rename to target/arm/tcg/vec_helper.c
129
diff --git a/target/arm/meson.build b/target/arm/meson.build
82
index XXXXXXX..XXXXXXX 100644
130
index XXXXXXX..XXXXXXX 100644
83
--- a/tests/tcg/aarch64/Makefile.target
131
--- a/target/arm/meson.build
84
+++ b/tests/tcg/aarch64/Makefile.target
132
+++ b/target/arm/meson.build
85
@@ -XXX,XX +XXX,XX @@ endif
133
@@ -XXX,XX +XXX,XX @@
86
# BTI Tests
134
arm_ss = ss.source_set()
87
# bti-1 tests the elf notes, so we require special compiler support.
135
arm_ss.add(files(
88
ifneq ($(CROSS_CC_HAS_ARMV8_BTI),)
136
'cpu.c',
89
-AARCH64_TESTS += bti-1
137
- 'crypto_helper.c',
90
-bti-1: CFLAGS += -mbranch-protection=standard
138
'debug_helper.c',
91
-bti-1: LDFLAGS += -nostdlib
139
'gdbstub.c',
92
+AARCH64_TESTS += bti-1 bti-3
140
'helper.c',
93
+bti-1 bti-3: CFLAGS += -mbranch-protection=standard
141
- 'iwmmxt_helper.c',
94
+bti-1 bti-3: LDFLAGS += -nostdlib
142
- 'm_helper.c',
143
- 'mve_helper.c',
144
- 'neon_helper.c',
145
- 'op_helper.c',
146
- 'tlb_helper.c',
147
- 'vec_helper.c',
148
'vfp_helper.c',
149
'cpu_tcg.c',
150
))
151
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c', 'kvm64.c'), if_false: fil
152
arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
153
'cpu64.c',
154
'gdbstub64.c',
155
- 'helper-a64.c',
156
- 'mte_helper.c',
157
- 'pauth_helper.c',
158
- 'sve_helper.c',
159
- 'sme_helper.c',
160
))
161
162
arm_softmmu_ss = ss.source_set()
163
@@ -XXX,XX +XXX,XX @@ subdir('hvf')
164
165
if 'CONFIG_TCG' in config_all
166
subdir('tcg')
167
+else
168
+ arm_ss.add(files('tcg-stubs.c'))
95
endif
169
endif
96
# bti-2 tests PROT_BTI, so no special compiler support required.
170
97
AARCH64_TESTS += bti-2
171
target_arch += {'arm': arm_ss}
172
diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build
173
index XXXXXXX..XXXXXXX 100644
174
--- a/target/arm/tcg/meson.build
175
+++ b/target/arm/tcg/meson.build
176
@@ -XXX,XX +XXX,XX @@ arm_ss.add(files(
177
'translate-mve.c',
178
'translate-neon.c',
179
'translate-vfp.c',
180
+ 'crypto_helper.c',
181
+ 'iwmmxt_helper.c',
182
+ 'm_helper.c',
183
+ 'mve_helper.c',
184
+ 'neon_helper.c',
185
+ 'op_helper.c',
186
+ 'tlb_helper.c',
187
+ 'vec_helper.c',
188
))
189
190
arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
191
'translate-a64.c',
192
'translate-sve.c',
193
'translate-sme.c',
194
+ 'helper-a64.c',
195
+ 'mte_helper.c',
196
+ 'pauth_helper.c',
197
+ 'sme_helper.c',
198
+ 'sve_helper.c',
199
))
98
--
200
--
99
2.25.1
201
2.34.1
202
203
diff view generated by jsdifflib
1
From: Alex Zuepke <alex.zuepke@tum.de>
1
From: Claudio Fontana <cfontana@suse.de>
2
2
3
The ARMv8 manual defines that PMUSERENR_EL0.ER enables read-access
3
Signed-off-by: Claudio Fontana <cfontana@suse.de>
4
to both PMXEVCNTR_EL0 and PMEVCNTR<n>_EL0 registers, however,
4
Signed-off-by: Fabiano Rosas <farosas@suse.de>
5
we only use it for PMXEVCNTR_EL0. Extend to PMEVCNTR<n>_EL0 as well.
6
7
Signed-off-by: Alex Zuepke <alex.zuepke@tum.de>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220428132717.84190-1-alex.zuepke@tum.de
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
9
---
12
target/arm/helper.c | 4 ++--
10
target/arm/{ => tcg}/psci.c | 0
13
1 file changed, 2 insertions(+), 2 deletions(-)
11
target/arm/meson.build | 1 -
12
target/arm/tcg/meson.build | 4 ++++
13
3 files changed, 4 insertions(+), 1 deletion(-)
14
rename target/arm/{ => tcg}/psci.c (100%)
14
15
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
diff --git a/target/arm/psci.c b/target/arm/tcg/psci.c
17
similarity index 100%
18
rename from target/arm/psci.c
19
rename to target/arm/tcg/psci.c
20
diff --git a/target/arm/meson.build b/target/arm/meson.build
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
22
--- a/target/arm/meson.build
18
+++ b/target/arm/helper.c
23
+++ b/target/arm/meson.build
19
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
24
@@ -XXX,XX +XXX,XX @@ arm_softmmu_ss.add(files(
20
.crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
25
'arm-powerctl.c',
21
.access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
26
'machine.c',
22
.readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
27
'monitor.c',
23
- .accessfn = pmreg_access },
28
- 'psci.c',
24
+ .accessfn = pmreg_access_xevcntr },
29
'ptw.c',
25
{ .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
30
))
26
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 8 | (3 & (i >> 3)),
31
27
- .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
32
diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build
28
+ .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access_xevcntr,
33
index XXXXXXX..XXXXXXX 100644
29
.type = ARM_CP_IO,
34
--- a/target/arm/tcg/meson.build
30
.readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
35
+++ b/target/arm/tcg/meson.build
31
.raw_readfn = pmevcntr_rawread,
36
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
37
'sme_helper.c',
38
'sve_helper.c',
39
))
40
+
41
+arm_softmmu_ss.add(files(
42
+ 'psci.c',
43
+))
32
--
44
--
33
2.25.1
45
2.34.1
46
47
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Instead of defining ARM_CP_FLAG_MASK to remove flags,
3
This is in preparation to moving the hflags code into its own file
4
define ARM_CP_SPECIAL_MASK to isolate special cases.
4
under the tcg/ directory.
5
Sort the specials to the low bits. Use an enum.
5
6
6
Signed-off-by: Fabiano Rosas <farosas@suse.de>
7
Split the large comment block so as to document each
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
value separately.
8
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20220501055028.646596-6-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
10
---
15
target/arm/cpregs.h | 130 +++++++++++++++++++++++--------------
11
hw/arm/boot.c | 6 +++++-
16
target/arm/cpu.c | 4 +-
12
hw/intc/armv7m_nvic.c | 20 +++++++++++++-------
17
target/arm/helper.c | 4 +-
13
target/arm/arm-powerctl.c | 7 +++++--
18
target/arm/translate-a64.c | 6 +-
14
target/arm/cpu.c | 3 ++-
19
target/arm/translate.c | 6 +-
15
target/arm/helper.c | 18 +++++++++++++-----
20
5 files changed, 92 insertions(+), 58 deletions(-)
16
target/arm/machine.c | 5 ++++-
21
17
6 files changed, 42 insertions(+), 17 deletions(-)
22
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
18
23
index XXXXXXX..XXXXXXX 100644
19
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
24
--- a/target/arm/cpregs.h
20
index XXXXXXX..XXXXXXX 100644
25
+++ b/target/arm/cpregs.h
21
--- a/hw/arm/boot.c
22
+++ b/hw/arm/boot.c
26
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@
27
#define TARGET_ARM_CPREGS_H
24
#include "hw/arm/boot.h"
28
25
#include "hw/arm/linux-boot-if.h"
29
/*
26
#include "sysemu/kvm.h"
30
- * ARMCPRegInfo type field bits. If the SPECIAL bit is set this is a
27
+#include "sysemu/tcg.h"
31
- * special-behaviour cp reg and bits [11..8] indicate what behaviour
28
#include "sysemu/sysemu.h"
32
- * it has. Otherwise it is a simple cp reg, where CONST indicates that
29
#include "sysemu/numa.h"
33
- * TCG can assume the value to be constant (ie load at translate time)
30
#include "hw/boards.h"
34
- * and 64BIT indicates a 64 bit wide coprocessor register. SUPPRESS_TB_END
31
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
35
- * indicates that the TB should not be ended after a write to this register
32
info->secondary_cpu_reset_hook(cpu, info);
36
- * (the default is that the TB ends after cp writes). OVERRIDE permits
33
}
37
- * a register definition to override a previous definition for the
34
}
38
- * same (cp, is64, crn, crm, opc1, opc2) tuple: either the new or the
35
- arm_rebuild_hflags(env);
39
- * old must have the OVERRIDE bit set.
36
+
40
- * ALIAS indicates that this register is an alias view of some underlying
37
+ if (tcg_enabled()) {
41
- * state which is also visible via another register, and that the other
38
+ arm_rebuild_hflags(env);
42
- * register is handling migration and reset; registers marked ALIAS will not be
39
+ }
43
- * migrated but may have their state set by syncing of register state from KVM.
40
}
44
- * NO_RAW indicates that this register has no underlying state and does not
41
}
45
- * support raw access for state saving/loading; it will not be used for either
42
46
- * migration or KVM state synchronization. (Typically this is for "registers"
43
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
47
- * which are actually used as instructions for cache maintenance and so on.)
44
index XXXXXXX..XXXXXXX 100644
48
- * IO indicates that this register does I/O and therefore its accesses
45
--- a/hw/intc/armv7m_nvic.c
49
- * need to be marked with gen_io_start() and also end the TB. In particular,
46
+++ b/hw/intc/armv7m_nvic.c
50
- * registers which implement clocks or timers require this.
47
@@ -XXX,XX +XXX,XX @@
51
- * RAISES_EXC is for when the read or write hook might raise an exception;
48
#include "hw/intc/armv7m_nvic.h"
52
- * the generated code will synchronize the CPU state before calling the hook
49
#include "hw/irq.h"
53
- * so that it is safe for the hook to call raise_exception().
50
#include "hw/qdev-properties.h"
54
- * NEWEL is for writes to registers that might change the exception
51
+#include "sysemu/tcg.h"
55
- * level - typically on older ARM chips. For those cases we need to
52
#include "sysemu/runstate.h"
56
- * re-read the new el when recomputing the translation flags.
53
#include "target/arm/cpu.h"
57
+ * ARMCPRegInfo type field bits:
54
#include "exec/exec-all.h"
58
*/
55
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
59
-#define ARM_CP_SPECIAL 0x0001
56
/* This is UNPREDICTABLE; treat as RAZ/WI */
60
-#define ARM_CP_CONST 0x0002
57
61
-#define ARM_CP_64BIT 0x0004
58
exit_ok:
62
-#define ARM_CP_SUPPRESS_TB_END 0x0008
59
- /* Ensure any changes made are reflected in the cached hflags. */
63
-#define ARM_CP_OVERRIDE 0x0010
60
- arm_rebuild_hflags(&s->cpu->env);
64
-#define ARM_CP_ALIAS 0x0020
61
+ if (tcg_enabled()) {
65
-#define ARM_CP_IO 0x0040
62
+ /* Ensure any changes made are reflected in the cached hflags. */
66
-#define ARM_CP_NO_RAW 0x0080
63
+ arm_rebuild_hflags(&s->cpu->env);
67
-#define ARM_CP_NOP (ARM_CP_SPECIAL | 0x0100)
64
+ }
68
-#define ARM_CP_WFI (ARM_CP_SPECIAL | 0x0200)
65
return MEMTX_OK;
69
-#define ARM_CP_NZCV (ARM_CP_SPECIAL | 0x0300)
66
}
70
-#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | 0x0400)
67
71
-#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | 0x0500)
68
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_reset(DeviceState *dev)
72
-#define ARM_CP_DC_GVA (ARM_CP_SPECIAL | 0x0600)
69
}
73
-#define ARM_CP_DC_GZVA (ARM_CP_SPECIAL | 0x0700)
70
}
74
-#define ARM_LAST_SPECIAL ARM_CP_DC_GZVA
71
75
-#define ARM_CP_FPU 0x1000
72
- /*
76
-#define ARM_CP_SVE 0x2000
73
- * We updated state that affects the CPU's MMUidx and thus its hflags;
77
-#define ARM_CP_NO_GDB 0x4000
74
- * and we can't guarantee that we run before the CPU reset function.
78
-#define ARM_CP_RAISES_EXC 0x8000
75
- */
79
-#define ARM_CP_NEWEL 0x10000
76
- arm_rebuild_hflags(&s->cpu->env);
80
-/* Mask of only the flag bits in a type field */
77
+ if (tcg_enabled()) {
81
-#define ARM_CP_FLAG_MASK 0x1f0ff
78
+ /*
82
+enum {
79
+ * We updated state that affects the CPU's MMUidx and thus its
83
+ /*
80
+ * hflags; and we can't guarantee that we run before the CPU
84
+ * Register must be handled specially during translation.
81
+ * reset function.
85
+ * The method is one of the values below:
82
+ */
86
+ */
83
+ arm_rebuild_hflags(&s->cpu->env);
87
+ ARM_CP_SPECIAL_MASK = 0x000f,
84
+ }
88
+ /* Special: no change to PE state: writes ignored, reads ignored. */
85
}
89
+ ARM_CP_NOP = 0x0001,
86
90
+ /* Special: sysreg is WFI, for v5 and v6. */
87
static void nvic_systick_trigger(void *opaque, int n, int level)
91
+ ARM_CP_WFI = 0x0002,
88
diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c
92
+ /* Special: sysreg is NZCV. */
89
index XXXXXXX..XXXXXXX 100644
93
+ ARM_CP_NZCV = 0x0003,
90
--- a/target/arm/arm-powerctl.c
94
+ /* Special: sysreg is CURRENTEL. */
91
+++ b/target/arm/arm-powerctl.c
95
+ ARM_CP_CURRENTEL = 0x0004,
92
@@ -XXX,XX +XXX,XX @@
96
+ /* Special: sysreg is DC ZVA or similar. */
93
#include "arm-powerctl.h"
97
+ ARM_CP_DC_ZVA = 0x0005,
94
#include "qemu/log.h"
98
+ ARM_CP_DC_GVA = 0x0006,
95
#include "qemu/main-loop.h"
99
+ ARM_CP_DC_GZVA = 0x0007,
96
+#include "sysemu/tcg.h"
100
+
97
101
+ /* Flag: reads produce resetvalue; writes ignored. */
98
#ifndef DEBUG_ARM_POWERCTL
102
+ ARM_CP_CONST = 1 << 4,
99
#define DEBUG_ARM_POWERCTL 0
103
+ /* Flag: For ARM_CP_STATE_AA32, sysreg is 64-bit. */
100
@@ -XXX,XX +XXX,XX @@ static void arm_set_cpu_on_async_work(CPUState *target_cpu_state,
104
+ ARM_CP_64BIT = 1 << 5,
101
target_cpu->env.regs[0] = info->context_id;
105
+ /*
102
}
106
+ * Flag: TB should not be ended after a write to this register
103
107
+ * (the default is that the TB ends after cp writes).
104
- /* CP15 update requires rebuilding hflags */
108
+ */
105
- arm_rebuild_hflags(&target_cpu->env);
109
+ ARM_CP_SUPPRESS_TB_END = 1 << 6,
106
+ if (tcg_enabled()) {
110
+ /*
107
+ /* CP15 update requires rebuilding hflags */
111
+ * Flag: Permit a register definition to override a previous definition
108
+ arm_rebuild_hflags(&target_cpu->env);
112
+ * for the same (cp, is64, crn, crm, opc1, opc2) tuple: either the new
109
+ }
113
+ * or the old must have the ARM_CP_OVERRIDE bit set.
110
114
+ */
111
/* Start the new CPU at the requested address */
115
+ ARM_CP_OVERRIDE = 1 << 7,
112
cpu_set_pc(target_cpu_state, info->entry);
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
113
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
165
index XXXXXXX..XXXXXXX 100644
114
index XXXXXXX..XXXXXXX 100644
166
--- a/target/arm/cpu.c
115
--- a/target/arm/cpu.c
167
+++ b/target/arm/cpu.c
116
+++ b/target/arm/cpu.c
168
@@ -XXX,XX +XXX,XX @@ static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
117
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset_hold(Object *obj)
169
ARMCPRegInfo *ri = value;
118
if (tcg_enabled()) {
170
ARMCPU *cpu = opaque;
119
hw_breakpoint_update_all(cpu);
171
120
hw_watchpoint_update_all(cpu);
172
- if (ri->type & (ARM_CP_SPECIAL | ARM_CP_ALIAS)) {
121
+
173
+ if (ri->type & (ARM_CP_SPECIAL_MASK | ARM_CP_ALIAS)) {
122
+ arm_rebuild_hflags(env);
174
return;
123
}
175
}
124
- arm_rebuild_hflags(env);
176
125
}
177
@@ -XXX,XX +XXX,XX @@ static void cp_reg_check_reset(gpointer key, gpointer value, gpointer opaque)
126
178
ARMCPU *cpu = opaque;
127
#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
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
128
diff --git a/target/arm/helper.c b/target/arm/helper.c
187
index XXXXXXX..XXXXXXX 100644
129
index XXXXXXX..XXXXXXX 100644
188
--- a/target/arm/helper.c
130
--- a/target/arm/helper.c
189
+++ b/target/arm/helper.c
131
+++ b/target/arm/helper.c
190
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
132
@@ -XXX,XX +XXX,XX @@ static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
191
* multiple times. Special registers (ie NOP/WFI) are
133
/* This may enable/disable the MMU, so do a TLB flush. */
192
* never migratable and not even raw-accessible.
134
tlb_flush(CPU(cpu));
193
*/
135
194
- if ((r->type & ARM_CP_SPECIAL)) {
136
- if (ri->type & ARM_CP_SUPPRESS_TB_END) {
195
+ if (r->type & ARM_CP_SPECIAL_MASK) {
137
+ if (tcg_enabled() && ri->type & ARM_CP_SUPPRESS_TB_END) {
196
r2->type |= ARM_CP_NO_RAW;
138
/*
197
}
139
* Normally we would always end the TB on an SCTLR write; see the
198
if (((r->crm == CP_ANY) && crm != 0) ||
140
* comment in ARMCPRegInfo sctlr initialization below for why Xscale
199
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
141
@@ -XXX,XX +XXX,XX @@ void aarch64_set_svcr(CPUARMState *env, uint64_t new, uint64_t mask)
200
/* Check that the register definition has enough info to handle
142
memset(env->zarray, 0, sizeof(env->zarray));
201
* reads and writes if they are permitted.
143
}
202
*/
144
203
- if (!(r->type & (ARM_CP_SPECIAL|ARM_CP_CONST))) {
145
- arm_rebuild_hflags(env);
204
+ if (!(r->type & (ARM_CP_SPECIAL_MASK | ARM_CP_CONST))) {
146
+ if (tcg_enabled()) {
205
if (r->access & PL3_R) {
147
+ arm_rebuild_hflags(env);
206
assert((r->fieldoffset ||
148
+ }
207
(r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
149
}
208
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
150
209
index XXXXXXX..XXXXXXX 100644
151
static void svcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
210
--- a/target/arm/translate-a64.c
152
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
211
+++ b/target/arm/translate-a64.c
153
}
212
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
154
mask &= ~CACHED_CPSR_BITS;
213
}
155
env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask);
214
156
- if (rebuild_hflags) {
215
/* Handle special cases first */
157
+ if (tcg_enabled() && rebuild_hflags) {
216
- switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
158
arm_rebuild_hflags(env);
217
+ switch (ri->type & ARM_CP_SPECIAL_MASK) {
159
}
218
+ case 0:
160
}
219
+ break;
161
@@ -XXX,XX +XXX,XX @@ static void take_aarch32_exception(CPUARMState *env, int new_mode,
220
case ARM_CP_NOP:
162
env->regs[14] = env->regs[15] + offset;
221
return;
163
}
222
case ARM_CP_NZCV:
164
env->regs[15] = newpc;
223
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
165
- arm_rebuild_hflags(env);
224
}
166
+
225
return;
167
+ if (tcg_enabled()) {
226
default:
168
+ arm_rebuild_hflags(env);
227
- break;
169
+ }
228
+ g_assert_not_reached();
170
}
229
}
171
230
if ((ri->type & ARM_CP_FPU) && !fp_access_check(s)) {
172
static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
231
return;
173
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
232
diff --git a/target/arm/translate.c b/target/arm/translate.c
174
pstate_write(env, PSTATE_DAIF | new_mode);
233
index XXXXXXX..XXXXXXX 100644
175
env->aarch64 = true;
234
--- a/target/arm/translate.c
176
aarch64_restore_sp(env, new_el);
235
+++ b/target/arm/translate.c
177
- helper_rebuild_hflags_a64(env, new_el);
236
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
178
+
237
}
179
+ if (tcg_enabled()) {
238
180
+ helper_rebuild_hflags_a64(env, new_el);
239
/* Handle special cases first */
181
+ }
240
- switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
182
241
+ switch (ri->type & ARM_CP_SPECIAL_MASK) {
183
env->pc = addr;
242
+ case 0:
184
243
+ break;
185
diff --git a/target/arm/machine.c b/target/arm/machine.c
244
case ARM_CP_NOP:
186
index XXXXXXX..XXXXXXX 100644
245
return;
187
--- a/target/arm/machine.c
246
case ARM_CP_WFI:
188
+++ b/target/arm/machine.c
247
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
189
@@ -XXX,XX +XXX,XX @@ static int cpu_post_load(void *opaque, int version_id)
248
s->base.is_jmp = DISAS_WFI;
190
if (!kvm_enabled()) {
249
return;
191
pmu_op_finish(&cpu->env);
250
default:
192
}
251
- break;
193
- arm_rebuild_hflags(&cpu->env);
252
+ g_assert_not_reached();
194
+
253
}
195
+ if (tcg_enabled()) {
254
196
+ arm_rebuild_hflags(&cpu->env);
255
if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
197
+ }
198
199
return 0;
200
}
256
--
201
--
257
2.25.1
202
2.34.1
203
204
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Remove a possible source of error by removing REGINFO_SENTINEL
3
The hflags are used only for TCG code, so introduce a new file
4
and using ARRAY_SIZE (convinently hidden inside a macro) to
4
hflags.c to keep that code.
5
find the end of the set of regs being registered or modified.
6
5
7
The space saved by not having the extra array element reduces
6
Signed-off-by: Fabiano Rosas <farosas@suse.de>
8
the executable's .data.rel.ro section by about 9k.
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
8
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@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>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
10
---
16
target/arm/cpregs.h | 53 +++++++++---------
11
target/arm/internals.h | 2 +
17
hw/arm/pxa2xx.c | 1 -
12
target/arm/helper.c | 393 +-----------------------------------
18
hw/arm/pxa2xx_pic.c | 1 -
13
target/arm/tcg-stubs.c | 4 +
19
hw/intc/arm_gicv3_cpuif.c | 5 --
14
target/arm/tcg/hflags.c | 403 +++++++++++++++++++++++++++++++++++++
20
hw/intc/arm_gicv3_kvm.c | 1 -
15
target/arm/tcg/meson.build | 1 +
21
target/arm/cpu64.c | 1 -
16
5 files changed, 411 insertions(+), 392 deletions(-)
22
target/arm/cpu_tcg.c | 4 --
17
create mode 100644 target/arm/tcg/hflags.c
23
target/arm/helper.c | 111 ++++++++------------------------------
24
8 files changed, 48 insertions(+), 129 deletions(-)
25
18
26
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
19
diff --git a/target/arm/internals.h b/target/arm/internals.h
27
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/cpregs.h
21
--- a/target/arm/internals.h
29
+++ b/target/arm/cpregs.h
22
+++ b/target/arm/internals.h
30
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
31
#define ARM_CP_NO_GDB 0x4000
24
32
#define ARM_CP_RAISES_EXC 0x8000
25
int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx);
33
#define ARM_CP_NEWEL 0x10000
26
int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx);
34
-/* Used only as a terminator for ARMCPRegInfo lists */
27
+int aa64_va_parameter_tcma(uint64_t tcr, ARMMMUIdx mmu_idx);
35
-#define ARM_CP_SENTINEL 0xfffff
28
36
/* Mask of only the flag bits in a type field */
29
/* Determine if allocation tags are available. */
37
#define ARM_CP_FLAG_MASK 0x1f0ff
30
static inline bool allocation_tag_access_enabled(CPUARMState *env, int el,
38
31
@@ -XXX,XX +XXX,XX @@ static inline bool arm_fgt_active(CPUARMState *env, int el)
39
@@ -XXX,XX +XXX,XX @@ enum {
32
(!arm_feature(env, ARM_FEATURE_EL3) || (env->cp15.scr_el3 & SCR_FGTEN));
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
}
33
}
79
+
34
80
+void define_arm_cp_regs_with_opaque_len(ARMCPU *cpu, const ARMCPRegInfo *regs,
35
+void assert_hflags_rebuild_correctly(CPUARMState *env);
81
+ void *opaque, size_t len);
82
+
83
+#define define_arm_cp_regs_with_opaque(CPU, REGS, OPAQUE) \
84
+ do { \
85
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(REGS) == 0); \
86
+ define_arm_cp_regs_with_opaque_len(CPU, REGS, OPAQUE, \
87
+ ARRAY_SIZE(REGS)); \
88
+ } while (0)
89
+
90
+#define define_arm_cp_regs(CPU, REGS) \
91
+ define_arm_cp_regs_with_opaque(CPU, REGS, NULL)
92
+
93
const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp);
94
95
/*
96
@@ -XXX,XX +XXX,XX @@ typedef struct ARMCPRegUserSpaceInfo {
97
uint64_t fixed_bits;
98
} ARMCPRegUserSpaceInfo;
99
100
-#define REGUSERINFO_SENTINEL { .name = NULL }
101
+void modify_arm_cp_regs_with_len(ARMCPRegInfo *regs, size_t regs_len,
102
+ const ARMCPRegUserSpaceInfo *mods,
103
+ size_t mods_len);
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
117
index XXXXXXX..XXXXXXX 100644
118
--- a/hw/arm/pxa2xx.c
119
+++ b/hw/arm/pxa2xx.c
120
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pxa_cp_reginfo[] = {
121
{ .name = "PWRMODE", .cp = 14, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 0,
122
.access = PL1_RW, .type = ARM_CP_IO,
123
.readfn = arm_cp_read_zero, .writefn = pxa2xx_pwrmode_write },
124
- REGINFO_SENTINEL
125
};
126
127
static void pxa2xx_setup_cp14(PXA2xxState *s)
128
diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c
129
index XXXXXXX..XXXXXXX 100644
130
--- a/hw/arm/pxa2xx_pic.c
131
+++ b/hw/arm/pxa2xx_pic.c
132
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pxa_pic_cp_reginfo[] = {
133
REGINFO_FOR_PIC_CP("ICLR2", 8),
134
REGINFO_FOR_PIC_CP("ICFP2", 9),
135
REGINFO_FOR_PIC_CP("ICPR2", 0xa),
136
- REGINFO_SENTINEL
137
};
138
139
static const MemoryRegionOps pxa2xx_pic_ops = {
140
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
141
index XXXXXXX..XXXXXXX 100644
142
--- a/hw/intc/arm_gicv3_cpuif.c
143
+++ b/hw/intc/arm_gicv3_cpuif.c
144
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
145
.readfn = icc_igrpen1_el3_read,
146
.writefn = icc_igrpen1_el3_write,
147
},
148
- REGINFO_SENTINEL
149
};
150
151
static uint64_t ich_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
152
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_hcr_reginfo[] = {
153
.readfn = ich_vmcr_read,
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
36
#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
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
245
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
246
--- a/target/arm/helper.c
39
--- a/target/arm/helper.c
247
+++ b/target/arm/helper.c
40
+++ b/target/arm/helper.c
248
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cp_reginfo[] = {
41
@@ -XXX,XX +XXX,XX @@ int sme_exception_el(CPUARMState *env, int el)
249
.secure = ARM_CP_SECSTATE_S,
42
return 0;
250
.fieldoffset = offsetof(CPUARMState, cp15.contextidr_s),
43
}
251
.resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
44
252
- REGINFO_SENTINEL
45
-/* This corresponds to the ARM pseudocode function IsFullA64Enabled(). */
253
};
46
-static bool sme_fa64(CPUARMState *env, int el)
254
47
-{
255
static const ARMCPRegInfo not_v8_cp_reginfo[] = {
48
- if (!cpu_isar_feature(aa64_sme_fa64, env_archcpu(env))) {
256
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v8_cp_reginfo[] = {
49
- return false;
257
{ .name = "CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY,
50
- }
258
.opc1 = 0, .opc2 = CP_ANY, .access = PL1_W,
51
-
259
.type = ARM_CP_NOP | ARM_CP_OVERRIDE },
52
- if (el <= 1 && !el_is_in_host(env, el)) {
260
- REGINFO_SENTINEL
53
- if (!FIELD_EX64(env->vfp.smcr_el[1], SMCR, FA64)) {
261
};
54
- return false;
262
55
- }
263
static const ARMCPRegInfo not_v6_cp_reginfo[] = {
56
- }
264
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v6_cp_reginfo[] = {
57
- if (el <= 2 && arm_is_el2_enabled(env)) {
265
*/
58
- if (!FIELD_EX64(env->vfp.smcr_el[2], SMCR, FA64)) {
266
{ .name = "WFI_v5", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = 2,
59
- return false;
267
.access = PL1_W, .type = ARM_CP_WFI },
60
- }
268
- REGINFO_SENTINEL
61
- }
269
};
62
- if (arm_feature(env, ARM_FEATURE_EL3)) {
270
63
- if (!FIELD_EX64(env->vfp.smcr_el[3], SMCR, FA64)) {
271
static const ARMCPRegInfo not_v7_cp_reginfo[] = {
64
- return false;
272
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v7_cp_reginfo[] = {
65
- }
273
.opc1 = 0, .opc2 = 0, .access = PL1_RW, .type = ARM_CP_NOP },
66
- }
274
{ .name = "NMRR", .cp = 15, .crn = 10, .crm = 2,
67
-
275
.opc1 = 0, .opc2 = 1, .access = PL1_RW, .type = ARM_CP_NOP },
68
- return true;
276
- REGINFO_SENTINEL
69
-}
277
};
70
-
278
71
/*
279
static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
72
* Given that SVE is enabled, return the vector length for EL.
280
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
73
*/
281
.crn = 1, .crm = 0, .opc1 = 0, .opc2 = 2, .accessfn = cpacr_access,
74
@@ -XXX,XX +XXX,XX @@ int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx)
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,
839
}
75
}
840
}
76
}
841
77
842
-void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
78
-static int aa64_va_parameter_tcma(uint64_t tcr, ARMMMUIdx mmu_idx)
843
- const ARMCPRegInfo *regs, void *opaque)
79
+int aa64_va_parameter_tcma(uint64_t tcr, ARMMMUIdx mmu_idx)
844
+/* Define a whole list of registers */
845
+void define_arm_cp_regs_with_opaque_len(ARMCPU *cpu, const ARMCPRegInfo *regs,
846
+ void *opaque, size_t len)
847
{
80
{
848
- /* Define a whole list of registers */
81
if (regime_has_2_ranges(mmu_idx)) {
849
- const ARMCPRegInfo *r;
82
return extract64(tcr, 57, 2);
850
- for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
83
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_mmu_idx(CPUARMState *env)
851
- define_one_arm_cp_reg_with_opaque(cpu, r, opaque);
84
return arm_mmu_idx_el(env, arm_current_el(env));
852
+ size_t i;
853
+ for (i = 0; i < len; ++i) {
854
+ define_one_arm_cp_reg_with_opaque(cpu, regs + i, opaque);
855
}
856
}
85
}
857
86
858
@@ -XXX,XX +XXX,XX @@ void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
87
-static inline bool fgt_svc(CPUARMState *env, int el)
859
* user-space cannot alter any values and dynamic values pertaining to
88
-{
860
* execution state are hidden from user space view anyway.
89
- /*
861
*/
90
- * Assuming fine-grained-traps are active, return true if we
862
-void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods)
91
- * should be trapping on SVC instructions. Only AArch64 can
863
+void modify_arm_cp_regs_with_len(ARMCPRegInfo *regs, size_t regs_len,
92
- * trap on an SVC at EL1, but we don't need to special-case this
864
+ const ARMCPRegUserSpaceInfo *mods,
93
- * because if this is AArch32 EL1 then arm_fgt_active() is false.
865
+ size_t mods_len)
94
- * We also know el is 0 or 1.
95
- */
96
- return el == 0 ?
97
- FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, SVC_EL0) :
98
- FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, SVC_EL1);
99
-}
100
-
101
-static CPUARMTBFlags rebuild_hflags_common(CPUARMState *env, int fp_el,
102
- ARMMMUIdx mmu_idx,
103
- CPUARMTBFlags flags)
104
-{
105
- DP_TBFLAG_ANY(flags, FPEXC_EL, fp_el);
106
- DP_TBFLAG_ANY(flags, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
107
-
108
- if (arm_singlestep_active(env)) {
109
- DP_TBFLAG_ANY(flags, SS_ACTIVE, 1);
110
- }
111
-
112
- return flags;
113
-}
114
-
115
-static CPUARMTBFlags rebuild_hflags_common_32(CPUARMState *env, int fp_el,
116
- ARMMMUIdx mmu_idx,
117
- CPUARMTBFlags flags)
118
-{
119
- bool sctlr_b = arm_sctlr_b(env);
120
-
121
- if (sctlr_b) {
122
- DP_TBFLAG_A32(flags, SCTLR__B, 1);
123
- }
124
- if (arm_cpu_data_is_big_endian_a32(env, sctlr_b)) {
125
- DP_TBFLAG_ANY(flags, BE_DATA, 1);
126
- }
127
- DP_TBFLAG_A32(flags, NS, !access_secure_reg(env));
128
-
129
- return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
130
-}
131
-
132
-static CPUARMTBFlags rebuild_hflags_m32(CPUARMState *env, int fp_el,
133
- ARMMMUIdx mmu_idx)
134
-{
135
- CPUARMTBFlags flags = {};
136
- uint32_t ccr = env->v7m.ccr[env->v7m.secure];
137
-
138
- /* Without HaveMainExt, CCR.UNALIGN_TRP is RES1. */
139
- if (ccr & R_V7M_CCR_UNALIGN_TRP_MASK) {
140
- DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
141
- }
142
-
143
- if (arm_v7m_is_handler_mode(env)) {
144
- DP_TBFLAG_M32(flags, HANDLER, 1);
145
- }
146
-
147
- /*
148
- * v8M always applies stack limit checks unless CCR.STKOFHFNMIGN
149
- * is suppressing them because the requested execution priority
150
- * is less than 0.
151
- */
152
- if (arm_feature(env, ARM_FEATURE_V8) &&
153
- !((mmu_idx & ARM_MMU_IDX_M_NEGPRI) &&
154
- (ccr & R_V7M_CCR_STKOFHFNMIGN_MASK))) {
155
- DP_TBFLAG_M32(flags, STACKCHECK, 1);
156
- }
157
-
158
- if (arm_feature(env, ARM_FEATURE_M_SECURITY) && env->v7m.secure) {
159
- DP_TBFLAG_M32(flags, SECURE, 1);
160
- }
161
-
162
- return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
163
-}
164
-
165
-static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el,
166
- ARMMMUIdx mmu_idx)
167
-{
168
- CPUARMTBFlags flags = {};
169
- int el = arm_current_el(env);
170
-
171
- if (arm_sctlr(env, el) & SCTLR_A) {
172
- DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
173
- }
174
-
175
- if (arm_el_is_aa64(env, 1)) {
176
- DP_TBFLAG_A32(flags, VFPEN, 1);
177
- }
178
-
179
- if (el < 2 && env->cp15.hstr_el2 && arm_is_el2_enabled(env) &&
180
- (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
181
- DP_TBFLAG_A32(flags, HSTR_ACTIVE, 1);
182
- }
183
-
184
- if (arm_fgt_active(env, el)) {
185
- DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1);
186
- if (fgt_svc(env, el)) {
187
- DP_TBFLAG_ANY(flags, FGT_SVC, 1);
188
- }
189
- }
190
-
191
- if (env->uncached_cpsr & CPSR_IL) {
192
- DP_TBFLAG_ANY(flags, PSTATE__IL, 1);
193
- }
194
-
195
- /*
196
- * The SME exception we are testing for is raised via
197
- * AArch64.CheckFPAdvSIMDEnabled(), as called from
198
- * AArch32.CheckAdvSIMDOrFPEnabled().
199
- */
200
- if (el == 0
201
- && FIELD_EX64(env->svcr, SVCR, SM)
202
- && (!arm_is_el2_enabled(env)
203
- || (arm_el_is_aa64(env, 2) && !(env->cp15.hcr_el2 & HCR_TGE)))
204
- && arm_el_is_aa64(env, 1)
205
- && !sme_fa64(env, el)) {
206
- DP_TBFLAG_A32(flags, SME_TRAP_NONSTREAMING, 1);
207
- }
208
-
209
- return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
210
-}
211
-
212
-static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
213
- ARMMMUIdx mmu_idx)
214
-{
215
- CPUARMTBFlags flags = {};
216
- ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
217
- uint64_t tcr = regime_tcr(env, mmu_idx);
218
- uint64_t sctlr;
219
- int tbii, tbid;
220
-
221
- DP_TBFLAG_ANY(flags, AARCH64_STATE, 1);
222
-
223
- /* Get control bits for tagged addresses. */
224
- tbid = aa64_va_parameter_tbi(tcr, mmu_idx);
225
- tbii = tbid & ~aa64_va_parameter_tbid(tcr, mmu_idx);
226
-
227
- DP_TBFLAG_A64(flags, TBII, tbii);
228
- DP_TBFLAG_A64(flags, TBID, tbid);
229
-
230
- if (cpu_isar_feature(aa64_sve, env_archcpu(env))) {
231
- int sve_el = sve_exception_el(env, el);
232
-
233
- /*
234
- * If either FP or SVE are disabled, translator does not need len.
235
- * If SVE EL > FP EL, FP exception has precedence, and translator
236
- * does not need SVE EL. Save potential re-translations by forcing
237
- * the unneeded data to zero.
238
- */
239
- if (fp_el != 0) {
240
- if (sve_el > fp_el) {
241
- sve_el = 0;
242
- }
243
- } else if (sve_el == 0) {
244
- DP_TBFLAG_A64(flags, VL, sve_vqm1_for_el(env, el));
245
- }
246
- DP_TBFLAG_A64(flags, SVEEXC_EL, sve_el);
247
- }
248
- if (cpu_isar_feature(aa64_sme, env_archcpu(env))) {
249
- int sme_el = sme_exception_el(env, el);
250
- bool sm = FIELD_EX64(env->svcr, SVCR, SM);
251
-
252
- DP_TBFLAG_A64(flags, SMEEXC_EL, sme_el);
253
- if (sme_el == 0) {
254
- /* Similarly, do not compute SVL if SME is disabled. */
255
- int svl = sve_vqm1_for_el_sm(env, el, true);
256
- DP_TBFLAG_A64(flags, SVL, svl);
257
- if (sm) {
258
- /* If SVE is disabled, we will not have set VL above. */
259
- DP_TBFLAG_A64(flags, VL, svl);
260
- }
261
- }
262
- if (sm) {
263
- DP_TBFLAG_A64(flags, PSTATE_SM, 1);
264
- DP_TBFLAG_A64(flags, SME_TRAP_NONSTREAMING, !sme_fa64(env, el));
265
- }
266
- DP_TBFLAG_A64(flags, PSTATE_ZA, FIELD_EX64(env->svcr, SVCR, ZA));
267
- }
268
-
269
- sctlr = regime_sctlr(env, stage1);
270
-
271
- if (sctlr & SCTLR_A) {
272
- DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
273
- }
274
-
275
- if (arm_cpu_data_is_big_endian_a64(el, sctlr)) {
276
- DP_TBFLAG_ANY(flags, BE_DATA, 1);
277
- }
278
-
279
- if (cpu_isar_feature(aa64_pauth, env_archcpu(env))) {
280
- /*
281
- * In order to save space in flags, we record only whether
282
- * pauth is "inactive", meaning all insns are implemented as
283
- * a nop, or "active" when some action must be performed.
284
- * The decision of which action to take is left to a helper.
285
- */
286
- if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) {
287
- DP_TBFLAG_A64(flags, PAUTH_ACTIVE, 1);
288
- }
289
- }
290
-
291
- if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
292
- /* Note that SCTLR_EL[23].BT == SCTLR_BT1. */
293
- if (sctlr & (el == 0 ? SCTLR_BT0 : SCTLR_BT1)) {
294
- DP_TBFLAG_A64(flags, BT, 1);
295
- }
296
- }
297
-
298
- /* Compute the condition for using AccType_UNPRIV for LDTR et al. */
299
- if (!(env->pstate & PSTATE_UAO)) {
300
- switch (mmu_idx) {
301
- case ARMMMUIdx_E10_1:
302
- case ARMMMUIdx_E10_1_PAN:
303
- /* TODO: ARMv8.3-NV */
304
- DP_TBFLAG_A64(flags, UNPRIV, 1);
305
- break;
306
- case ARMMMUIdx_E20_2:
307
- case ARMMMUIdx_E20_2_PAN:
308
- /*
309
- * Note that EL20_2 is gated by HCR_EL2.E2H == 1, but EL20_0 is
310
- * gated by HCR_EL2.<E2H,TGE> == '11', and so is LDTR.
311
- */
312
- if (env->cp15.hcr_el2 & HCR_TGE) {
313
- DP_TBFLAG_A64(flags, UNPRIV, 1);
314
- }
315
- break;
316
- default:
317
- break;
318
- }
319
- }
320
-
321
- if (env->pstate & PSTATE_IL) {
322
- DP_TBFLAG_ANY(flags, PSTATE__IL, 1);
323
- }
324
-
325
- if (arm_fgt_active(env, el)) {
326
- DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1);
327
- if (FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, ERET)) {
328
- DP_TBFLAG_A64(flags, FGT_ERET, 1);
329
- }
330
- if (fgt_svc(env, el)) {
331
- DP_TBFLAG_ANY(flags, FGT_SVC, 1);
332
- }
333
- }
334
-
335
- if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
336
- /*
337
- * Set MTE_ACTIVE if any access may be Checked, and leave clear
338
- * if all accesses must be Unchecked:
339
- * 1) If no TBI, then there are no tags in the address to check,
340
- * 2) If Tag Check Override, then all accesses are Unchecked,
341
- * 3) If Tag Check Fail == 0, then Checked access have no effect,
342
- * 4) If no Allocation Tag Access, then all accesses are Unchecked.
343
- */
344
- if (allocation_tag_access_enabled(env, el, sctlr)) {
345
- DP_TBFLAG_A64(flags, ATA, 1);
346
- if (tbid
347
- && !(env->pstate & PSTATE_TCO)
348
- && (sctlr & (el == 0 ? SCTLR_TCF0 : SCTLR_TCF))) {
349
- DP_TBFLAG_A64(flags, MTE_ACTIVE, 1);
350
- }
351
- }
352
- /* And again for unprivileged accesses, if required. */
353
- if (EX_TBFLAG_A64(flags, UNPRIV)
354
- && tbid
355
- && !(env->pstate & PSTATE_TCO)
356
- && (sctlr & SCTLR_TCF0)
357
- && allocation_tag_access_enabled(env, 0, sctlr)) {
358
- DP_TBFLAG_A64(flags, MTE0_ACTIVE, 1);
359
- }
360
- /* Cache TCMA as well as TBI. */
361
- DP_TBFLAG_A64(flags, TCMA, aa64_va_parameter_tcma(tcr, mmu_idx));
362
- }
363
-
364
- return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
365
-}
366
-
367
-static CPUARMTBFlags rebuild_hflags_internal(CPUARMState *env)
368
-{
369
- int el = arm_current_el(env);
370
- int fp_el = fp_exception_el(env, el);
371
- ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
372
-
373
- if (is_a64(env)) {
374
- return rebuild_hflags_a64(env, el, fp_el, mmu_idx);
375
- } else if (arm_feature(env, ARM_FEATURE_M)) {
376
- return rebuild_hflags_m32(env, fp_el, mmu_idx);
377
- } else {
378
- return rebuild_hflags_a32(env, fp_el, mmu_idx);
379
- }
380
-}
381
-
382
-void arm_rebuild_hflags(CPUARMState *env)
383
-{
384
- env->hflags = rebuild_hflags_internal(env);
385
-}
386
-
387
-/*
388
- * If we have triggered a EL state change we can't rely on the
389
- * translator having passed it to us, we need to recompute.
390
- */
391
-void HELPER(rebuild_hflags_m32_newel)(CPUARMState *env)
392
-{
393
- int el = arm_current_el(env);
394
- int fp_el = fp_exception_el(env, el);
395
- ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
396
-
397
- env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
398
-}
399
-
400
-void HELPER(rebuild_hflags_m32)(CPUARMState *env, int el)
401
-{
402
- int fp_el = fp_exception_el(env, el);
403
- ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
404
-
405
- env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
406
-}
407
-
408
-/*
409
- * If we have triggered a EL state change we can't rely on the
410
- * translator having passed it to us, we need to recompute.
411
- */
412
-void HELPER(rebuild_hflags_a32_newel)(CPUARMState *env)
413
-{
414
- int el = arm_current_el(env);
415
- int fp_el = fp_exception_el(env, el);
416
- ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
417
- env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
418
-}
419
-
420
-void HELPER(rebuild_hflags_a32)(CPUARMState *env, int el)
421
-{
422
- int fp_el = fp_exception_el(env, el);
423
- ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
424
-
425
- env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
426
-}
427
-
428
-void HELPER(rebuild_hflags_a64)(CPUARMState *env, int el)
429
-{
430
- int fp_el = fp_exception_el(env, el);
431
- ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
432
-
433
- env->hflags = rebuild_hflags_a64(env, el, fp_el, mmu_idx);
434
-}
435
-
436
-static inline void assert_hflags_rebuild_correctly(CPUARMState *env)
437
-{
438
-#ifdef CONFIG_DEBUG_TCG
439
- CPUARMTBFlags c = env->hflags;
440
- CPUARMTBFlags r = rebuild_hflags_internal(env);
441
-
442
- if (unlikely(c.flags != r.flags || c.flags2 != r.flags2)) {
443
- fprintf(stderr, "TCG hflags mismatch "
444
- "(current:(0x%08x,0x" TARGET_FMT_lx ")"
445
- " rebuilt:(0x%08x,0x" TARGET_FMT_lx ")\n",
446
- c.flags, c.flags2, r.flags, r.flags2);
447
- abort();
448
- }
449
-#endif
450
-}
451
-
452
static bool mve_no_pred(CPUARMState *env)
866
{
453
{
867
- const ARMCPRegUserSpaceInfo *m;
454
/*
868
- ARMCPRegInfo *r;
455
diff --git a/target/arm/tcg-stubs.c b/target/arm/tcg-stubs.c
869
-
456
index XXXXXXX..XXXXXXX 100644
870
- for (m = mods; m->name; m++) {
457
--- a/target/arm/tcg-stubs.c
871
+ for (size_t mi = 0; mi < mods_len; ++mi) {
458
+++ b/target/arm/tcg-stubs.c
872
+ const ARMCPRegUserSpaceInfo *m = mods + mi;
459
@@ -XXX,XX +XXX,XX @@ void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome,
873
GPatternSpec *pat = NULL;
460
{
874
+
461
g_assert_not_reached();
875
if (m->is_glob) {
462
}
876
pat = g_pattern_spec_new(m->name);
463
+/* Temporarily while cpu_get_tb_cpu_state() is still in common code */
877
}
464
+void assert_hflags_rebuild_correctly(CPUARMState *env)
878
- for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
465
+{
879
+ for (size_t ri = 0; ri < regs_len; ++ri) {
466
+}
880
+ ARMCPRegInfo *r = regs + ri;
467
diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c
881
+
468
new file mode 100644
882
if (pat && g_pattern_match_string(pat, r->name)) {
469
index XXXXXXX..XXXXXXX
883
r->type = ARM_CP_CONST;
470
--- /dev/null
884
r->access = PL0U_R;
471
+++ b/target/arm/tcg/hflags.c
472
@@ -XXX,XX +XXX,XX @@
473
+/*
474
+ * ARM hflags
475
+ *
476
+ * This code is licensed under the GNU GPL v2 or later.
477
+ *
478
+ * SPDX-License-Identifier: GPL-2.0-or-later
479
+ */
480
+#include "qemu/osdep.h"
481
+#include "cpu.h"
482
+#include "internals.h"
483
+#include "exec/helper-proto.h"
484
+#include "cpregs.h"
485
+
486
+static inline bool fgt_svc(CPUARMState *env, int el)
487
+{
488
+ /*
489
+ * Assuming fine-grained-traps are active, return true if we
490
+ * should be trapping on SVC instructions. Only AArch64 can
491
+ * trap on an SVC at EL1, but we don't need to special-case this
492
+ * because if this is AArch32 EL1 then arm_fgt_active() is false.
493
+ * We also know el is 0 or 1.
494
+ */
495
+ return el == 0 ?
496
+ FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, SVC_EL0) :
497
+ FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, SVC_EL1);
498
+}
499
+
500
+static CPUARMTBFlags rebuild_hflags_common(CPUARMState *env, int fp_el,
501
+ ARMMMUIdx mmu_idx,
502
+ CPUARMTBFlags flags)
503
+{
504
+ DP_TBFLAG_ANY(flags, FPEXC_EL, fp_el);
505
+ DP_TBFLAG_ANY(flags, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
506
+
507
+ if (arm_singlestep_active(env)) {
508
+ DP_TBFLAG_ANY(flags, SS_ACTIVE, 1);
509
+ }
510
+
511
+ return flags;
512
+}
513
+
514
+static CPUARMTBFlags rebuild_hflags_common_32(CPUARMState *env, int fp_el,
515
+ ARMMMUIdx mmu_idx,
516
+ CPUARMTBFlags flags)
517
+{
518
+ bool sctlr_b = arm_sctlr_b(env);
519
+
520
+ if (sctlr_b) {
521
+ DP_TBFLAG_A32(flags, SCTLR__B, 1);
522
+ }
523
+ if (arm_cpu_data_is_big_endian_a32(env, sctlr_b)) {
524
+ DP_TBFLAG_ANY(flags, BE_DATA, 1);
525
+ }
526
+ DP_TBFLAG_A32(flags, NS, !access_secure_reg(env));
527
+
528
+ return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
529
+}
530
+
531
+static CPUARMTBFlags rebuild_hflags_m32(CPUARMState *env, int fp_el,
532
+ ARMMMUIdx mmu_idx)
533
+{
534
+ CPUARMTBFlags flags = {};
535
+ uint32_t ccr = env->v7m.ccr[env->v7m.secure];
536
+
537
+ /* Without HaveMainExt, CCR.UNALIGN_TRP is RES1. */
538
+ if (ccr & R_V7M_CCR_UNALIGN_TRP_MASK) {
539
+ DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
540
+ }
541
+
542
+ if (arm_v7m_is_handler_mode(env)) {
543
+ DP_TBFLAG_M32(flags, HANDLER, 1);
544
+ }
545
+
546
+ /*
547
+ * v8M always applies stack limit checks unless CCR.STKOFHFNMIGN
548
+ * is suppressing them because the requested execution priority
549
+ * is less than 0.
550
+ */
551
+ if (arm_feature(env, ARM_FEATURE_V8) &&
552
+ !((mmu_idx & ARM_MMU_IDX_M_NEGPRI) &&
553
+ (ccr & R_V7M_CCR_STKOFHFNMIGN_MASK))) {
554
+ DP_TBFLAG_M32(flags, STACKCHECK, 1);
555
+ }
556
+
557
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) && env->v7m.secure) {
558
+ DP_TBFLAG_M32(flags, SECURE, 1);
559
+ }
560
+
561
+ return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
562
+}
563
+
564
+/* This corresponds to the ARM pseudocode function IsFullA64Enabled(). */
565
+static bool sme_fa64(CPUARMState *env, int el)
566
+{
567
+ if (!cpu_isar_feature(aa64_sme_fa64, env_archcpu(env))) {
568
+ return false;
569
+ }
570
+
571
+ if (el <= 1 && !el_is_in_host(env, el)) {
572
+ if (!FIELD_EX64(env->vfp.smcr_el[1], SMCR, FA64)) {
573
+ return false;
574
+ }
575
+ }
576
+ if (el <= 2 && arm_is_el2_enabled(env)) {
577
+ if (!FIELD_EX64(env->vfp.smcr_el[2], SMCR, FA64)) {
578
+ return false;
579
+ }
580
+ }
581
+ if (arm_feature(env, ARM_FEATURE_EL3)) {
582
+ if (!FIELD_EX64(env->vfp.smcr_el[3], SMCR, FA64)) {
583
+ return false;
584
+ }
585
+ }
586
+
587
+ return true;
588
+}
589
+
590
+static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el,
591
+ ARMMMUIdx mmu_idx)
592
+{
593
+ CPUARMTBFlags flags = {};
594
+ int el = arm_current_el(env);
595
+
596
+ if (arm_sctlr(env, el) & SCTLR_A) {
597
+ DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
598
+ }
599
+
600
+ if (arm_el_is_aa64(env, 1)) {
601
+ DP_TBFLAG_A32(flags, VFPEN, 1);
602
+ }
603
+
604
+ if (el < 2 && env->cp15.hstr_el2 && arm_is_el2_enabled(env) &&
605
+ (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
606
+ DP_TBFLAG_A32(flags, HSTR_ACTIVE, 1);
607
+ }
608
+
609
+ if (arm_fgt_active(env, el)) {
610
+ DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1);
611
+ if (fgt_svc(env, el)) {
612
+ DP_TBFLAG_ANY(flags, FGT_SVC, 1);
613
+ }
614
+ }
615
+
616
+ if (env->uncached_cpsr & CPSR_IL) {
617
+ DP_TBFLAG_ANY(flags, PSTATE__IL, 1);
618
+ }
619
+
620
+ /*
621
+ * The SME exception we are testing for is raised via
622
+ * AArch64.CheckFPAdvSIMDEnabled(), as called from
623
+ * AArch32.CheckAdvSIMDOrFPEnabled().
624
+ */
625
+ if (el == 0
626
+ && FIELD_EX64(env->svcr, SVCR, SM)
627
+ && (!arm_is_el2_enabled(env)
628
+ || (arm_el_is_aa64(env, 2) && !(env->cp15.hcr_el2 & HCR_TGE)))
629
+ && arm_el_is_aa64(env, 1)
630
+ && !sme_fa64(env, el)) {
631
+ DP_TBFLAG_A32(flags, SME_TRAP_NONSTREAMING, 1);
632
+ }
633
+
634
+ return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
635
+}
636
+
637
+static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
638
+ ARMMMUIdx mmu_idx)
639
+{
640
+ CPUARMTBFlags flags = {};
641
+ ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
642
+ uint64_t tcr = regime_tcr(env, mmu_idx);
643
+ uint64_t sctlr;
644
+ int tbii, tbid;
645
+
646
+ DP_TBFLAG_ANY(flags, AARCH64_STATE, 1);
647
+
648
+ /* Get control bits for tagged addresses. */
649
+ tbid = aa64_va_parameter_tbi(tcr, mmu_idx);
650
+ tbii = tbid & ~aa64_va_parameter_tbid(tcr, mmu_idx);
651
+
652
+ DP_TBFLAG_A64(flags, TBII, tbii);
653
+ DP_TBFLAG_A64(flags, TBID, tbid);
654
+
655
+ if (cpu_isar_feature(aa64_sve, env_archcpu(env))) {
656
+ int sve_el = sve_exception_el(env, el);
657
+
658
+ /*
659
+ * If either FP or SVE are disabled, translator does not need len.
660
+ * If SVE EL > FP EL, FP exception has precedence, and translator
661
+ * does not need SVE EL. Save potential re-translations by forcing
662
+ * the unneeded data to zero.
663
+ */
664
+ if (fp_el != 0) {
665
+ if (sve_el > fp_el) {
666
+ sve_el = 0;
667
+ }
668
+ } else if (sve_el == 0) {
669
+ DP_TBFLAG_A64(flags, VL, sve_vqm1_for_el(env, el));
670
+ }
671
+ DP_TBFLAG_A64(flags, SVEEXC_EL, sve_el);
672
+ }
673
+ if (cpu_isar_feature(aa64_sme, env_archcpu(env))) {
674
+ int sme_el = sme_exception_el(env, el);
675
+ bool sm = FIELD_EX64(env->svcr, SVCR, SM);
676
+
677
+ DP_TBFLAG_A64(flags, SMEEXC_EL, sme_el);
678
+ if (sme_el == 0) {
679
+ /* Similarly, do not compute SVL if SME is disabled. */
680
+ int svl = sve_vqm1_for_el_sm(env, el, true);
681
+ DP_TBFLAG_A64(flags, SVL, svl);
682
+ if (sm) {
683
+ /* If SVE is disabled, we will not have set VL above. */
684
+ DP_TBFLAG_A64(flags, VL, svl);
685
+ }
686
+ }
687
+ if (sm) {
688
+ DP_TBFLAG_A64(flags, PSTATE_SM, 1);
689
+ DP_TBFLAG_A64(flags, SME_TRAP_NONSTREAMING, !sme_fa64(env, el));
690
+ }
691
+ DP_TBFLAG_A64(flags, PSTATE_ZA, FIELD_EX64(env->svcr, SVCR, ZA));
692
+ }
693
+
694
+ sctlr = regime_sctlr(env, stage1);
695
+
696
+ if (sctlr & SCTLR_A) {
697
+ DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
698
+ }
699
+
700
+ if (arm_cpu_data_is_big_endian_a64(el, sctlr)) {
701
+ DP_TBFLAG_ANY(flags, BE_DATA, 1);
702
+ }
703
+
704
+ if (cpu_isar_feature(aa64_pauth, env_archcpu(env))) {
705
+ /*
706
+ * In order to save space in flags, we record only whether
707
+ * pauth is "inactive", meaning all insns are implemented as
708
+ * a nop, or "active" when some action must be performed.
709
+ * The decision of which action to take is left to a helper.
710
+ */
711
+ if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) {
712
+ DP_TBFLAG_A64(flags, PAUTH_ACTIVE, 1);
713
+ }
714
+ }
715
+
716
+ if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
717
+ /* Note that SCTLR_EL[23].BT == SCTLR_BT1. */
718
+ if (sctlr & (el == 0 ? SCTLR_BT0 : SCTLR_BT1)) {
719
+ DP_TBFLAG_A64(flags, BT, 1);
720
+ }
721
+ }
722
+
723
+ /* Compute the condition for using AccType_UNPRIV for LDTR et al. */
724
+ if (!(env->pstate & PSTATE_UAO)) {
725
+ switch (mmu_idx) {
726
+ case ARMMMUIdx_E10_1:
727
+ case ARMMMUIdx_E10_1_PAN:
728
+ /* TODO: ARMv8.3-NV */
729
+ DP_TBFLAG_A64(flags, UNPRIV, 1);
730
+ break;
731
+ case ARMMMUIdx_E20_2:
732
+ case ARMMMUIdx_E20_2_PAN:
733
+ /*
734
+ * Note that EL20_2 is gated by HCR_EL2.E2H == 1, but EL20_0 is
735
+ * gated by HCR_EL2.<E2H,TGE> == '11', and so is LDTR.
736
+ */
737
+ if (env->cp15.hcr_el2 & HCR_TGE) {
738
+ DP_TBFLAG_A64(flags, UNPRIV, 1);
739
+ }
740
+ break;
741
+ default:
742
+ break;
743
+ }
744
+ }
745
+
746
+ if (env->pstate & PSTATE_IL) {
747
+ DP_TBFLAG_ANY(flags, PSTATE__IL, 1);
748
+ }
749
+
750
+ if (arm_fgt_active(env, el)) {
751
+ DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1);
752
+ if (FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, ERET)) {
753
+ DP_TBFLAG_A64(flags, FGT_ERET, 1);
754
+ }
755
+ if (fgt_svc(env, el)) {
756
+ DP_TBFLAG_ANY(flags, FGT_SVC, 1);
757
+ }
758
+ }
759
+
760
+ if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
761
+ /*
762
+ * Set MTE_ACTIVE if any access may be Checked, and leave clear
763
+ * if all accesses must be Unchecked:
764
+ * 1) If no TBI, then there are no tags in the address to check,
765
+ * 2) If Tag Check Override, then all accesses are Unchecked,
766
+ * 3) If Tag Check Fail == 0, then Checked access have no effect,
767
+ * 4) If no Allocation Tag Access, then all accesses are Unchecked.
768
+ */
769
+ if (allocation_tag_access_enabled(env, el, sctlr)) {
770
+ DP_TBFLAG_A64(flags, ATA, 1);
771
+ if (tbid
772
+ && !(env->pstate & PSTATE_TCO)
773
+ && (sctlr & (el == 0 ? SCTLR_TCF0 : SCTLR_TCF))) {
774
+ DP_TBFLAG_A64(flags, MTE_ACTIVE, 1);
775
+ }
776
+ }
777
+ /* And again for unprivileged accesses, if required. */
778
+ if (EX_TBFLAG_A64(flags, UNPRIV)
779
+ && tbid
780
+ && !(env->pstate & PSTATE_TCO)
781
+ && (sctlr & SCTLR_TCF0)
782
+ && allocation_tag_access_enabled(env, 0, sctlr)) {
783
+ DP_TBFLAG_A64(flags, MTE0_ACTIVE, 1);
784
+ }
785
+ /* Cache TCMA as well as TBI. */
786
+ DP_TBFLAG_A64(flags, TCMA, aa64_va_parameter_tcma(tcr, mmu_idx));
787
+ }
788
+
789
+ return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
790
+}
791
+
792
+static CPUARMTBFlags rebuild_hflags_internal(CPUARMState *env)
793
+{
794
+ int el = arm_current_el(env);
795
+ int fp_el = fp_exception_el(env, el);
796
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
797
+
798
+ if (is_a64(env)) {
799
+ return rebuild_hflags_a64(env, el, fp_el, mmu_idx);
800
+ } else if (arm_feature(env, ARM_FEATURE_M)) {
801
+ return rebuild_hflags_m32(env, fp_el, mmu_idx);
802
+ } else {
803
+ return rebuild_hflags_a32(env, fp_el, mmu_idx);
804
+ }
805
+}
806
+
807
+void arm_rebuild_hflags(CPUARMState *env)
808
+{
809
+ env->hflags = rebuild_hflags_internal(env);
810
+}
811
+
812
+/*
813
+ * If we have triggered a EL state change we can't rely on the
814
+ * translator having passed it to us, we need to recompute.
815
+ */
816
+void HELPER(rebuild_hflags_m32_newel)(CPUARMState *env)
817
+{
818
+ int el = arm_current_el(env);
819
+ int fp_el = fp_exception_el(env, el);
820
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
821
+
822
+ env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
823
+}
824
+
825
+void HELPER(rebuild_hflags_m32)(CPUARMState *env, int el)
826
+{
827
+ int fp_el = fp_exception_el(env, el);
828
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
829
+
830
+ env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
831
+}
832
+
833
+/*
834
+ * If we have triggered a EL state change we can't rely on the
835
+ * translator having passed it to us, we need to recompute.
836
+ */
837
+void HELPER(rebuild_hflags_a32_newel)(CPUARMState *env)
838
+{
839
+ int el = arm_current_el(env);
840
+ int fp_el = fp_exception_el(env, el);
841
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
842
+ env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
843
+}
844
+
845
+void HELPER(rebuild_hflags_a32)(CPUARMState *env, int el)
846
+{
847
+ int fp_el = fp_exception_el(env, el);
848
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
849
+
850
+ env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
851
+}
852
+
853
+void HELPER(rebuild_hflags_a64)(CPUARMState *env, int el)
854
+{
855
+ int fp_el = fp_exception_el(env, el);
856
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
857
+
858
+ env->hflags = rebuild_hflags_a64(env, el, fp_el, mmu_idx);
859
+}
860
+
861
+void assert_hflags_rebuild_correctly(CPUARMState *env)
862
+{
863
+#ifdef CONFIG_DEBUG_TCG
864
+ CPUARMTBFlags c = env->hflags;
865
+ CPUARMTBFlags r = rebuild_hflags_internal(env);
866
+
867
+ if (unlikely(c.flags != r.flags || c.flags2 != r.flags2)) {
868
+ fprintf(stderr, "TCG hflags mismatch "
869
+ "(current:(0x%08x,0x" TARGET_FMT_lx ")"
870
+ " rebuilt:(0x%08x,0x" TARGET_FMT_lx ")\n",
871
+ c.flags, c.flags2, r.flags, r.flags2);
872
+ abort();
873
+ }
874
+#endif
875
+}
876
diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build
877
index XXXXXXX..XXXXXXX 100644
878
--- a/target/arm/tcg/meson.build
879
+++ b/target/arm/tcg/meson.build
880
@@ -XXX,XX +XXX,XX @@ arm_ss.add(files(
881
'translate-neon.c',
882
'translate-vfp.c',
883
'crypto_helper.c',
884
+ 'hflags.c',
885
'iwmmxt_helper.c',
886
'm_helper.c',
887
'mve_helper.c',
885
--
888
--
886
2.25.1
889
2.34.1
887
890
888
891
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
This function is needed by common code (ptw.c), so move it along with
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
the other regime_* functions in internal.h. When we enable the build
5
Message-id: 20220501055028.646596-24-richard.henderson@linaro.org
5
without TCG, the tlb_helper.c file will not be present.
6
7
Signed-off-by: Fabiano Rosas <farosas@suse.de>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
target/arm/cpu.h | 15 +++++++++++++++
12
target/arm/internals.h | 21 ++++++++++++++++++---
9
1 file changed, 15 insertions(+)
13
target/arm/tcg/tlb_helper.c | 18 ------------------
14
2 files changed, 18 insertions(+), 21 deletions(-)
10
15
11
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu.h
18
--- a/target/arm/internals.h
14
+++ b/target/arm/cpu.h
19
+++ b/target/arm/internals.h
15
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id)
20
@@ -XXX,XX +XXX,XX @@ int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx);
16
return FIELD_EX32(id->id_pfr2, ID_PFR2, SSBS) != 0;
21
/* Return the MMU index for a v7M CPU in the specified security state */
22
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate);
23
24
-/* Return true if the translation regime is using LPAE format page tables */
25
-bool regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx);
26
-
27
/*
28
* Return true if the stage 1 translation regime is using LPAE
29
* format page tables
30
@@ -XXX,XX +XXX,XX @@ static inline uint64_t regime_tcr(CPUARMState *env, ARMMMUIdx mmu_idx)
31
return env->cp15.tcr_el[regime_el(env, mmu_idx)];
17
}
32
}
18
33
19
+static inline bool isar_feature_aa32_debugv8p2(const ARMISARegisters *id)
34
+/* Return true if the translation regime is using LPAE format page tables */
35
+static inline bool regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx)
20
+{
36
+{
21
+ return FIELD_EX32(id->id_dfr0, ID_DFR0, COPDBG) >= 8;
37
+ int el = regime_el(env, mmu_idx);
38
+ if (el == 2 || arm_el_is_aa64(env, el)) {
39
+ return true;
40
+ }
41
+ if (arm_feature(env, ARM_FEATURE_PMSA) &&
42
+ arm_feature(env, ARM_FEATURE_V8)) {
43
+ return true;
44
+ }
45
+ if (arm_feature(env, ARM_FEATURE_LPAE)
46
+ && (regime_tcr(env, mmu_idx) & TTBCR_EAE)) {
47
+ return true;
48
+ }
49
+ return false;
22
+}
50
+}
23
+
51
+
52
/**
53
* arm_num_brps: Return number of implemented breakpoints.
54
* Note that the ID register BRPS field is "number of bps - 1",
55
diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/arm/tcg/tlb_helper.c
58
+++ b/target/arm/tcg/tlb_helper.c
59
@@ -XXX,XX +XXX,XX @@
60
#include "exec/helper-proto.h"
61
62
63
-/* Return true if the translation regime is using LPAE format page tables */
64
-bool regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx)
65
-{
66
- int el = regime_el(env, mmu_idx);
67
- if (el == 2 || arm_el_is_aa64(env, el)) {
68
- return true;
69
- }
70
- if (arm_feature(env, ARM_FEATURE_PMSA) &&
71
- arm_feature(env, ARM_FEATURE_V8)) {
72
- return true;
73
- }
74
- if (arm_feature(env, ARM_FEATURE_LPAE)
75
- && (regime_tcr(env, mmu_idx) & TTBCR_EAE)) {
76
- return true;
77
- }
78
- return false;
79
-}
80
-
24
/*
81
/*
25
* 64-bit feature tests via id registers.
82
* Returns true if the stage 1 translation regime is using LPAE format page
26
*/
83
* tables. Used when raising alignment exceptions, whose FSR changes depending
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)
32
+{
33
+ return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, DEBUGVER) >= 8;
34
+}
35
+
36
static inline bool isar_feature_aa64_sve2(const ARMISARegisters *id)
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)
44
+{
45
+ return isar_feature_aa64_debugv8p2(id) || isar_feature_aa32_debugv8p2(id);
46
+}
47
+
48
/*
49
* Forward to the above feature tests given an ARMCPU pointer.
50
*/
51
--
84
--
52
2.25.1
85
2.34.1
86
87
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Since e03b56863d2bc, our host endian indicator is unconditionally
3
When TCG is disabled this part of the code should not be reachable, so
4
set, which means that we can use a normal C condition.
4
wrap it with an ifdef for now.
5
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Fabiano Rosas <farosas@suse.de>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220501055028.646596-20-richard.henderson@linaro.org
8
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
[PMM: quote correct git hash in commit message]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
target/arm/helper.c | 9 +++------
11
target/arm/ptw.c | 4 ++++
13
1 file changed, 3 insertions(+), 6 deletions(-)
12
1 file changed, 4 insertions(+)
14
13
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
16
--- a/target/arm/ptw.c
18
+++ b/target/arm/helper.c
17
+++ b/target/arm/ptw.c
19
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
18
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
20
r2->type |= ARM_CP_ALIAS;
19
ptw->out_host = NULL;
21
}
20
ptw->out_rw = false;
22
21
} else {
23
- if (r->state == ARM_CP_STATE_BOTH) {
22
+#ifdef CONFIG_TCG
24
-#if HOST_BIG_ENDIAN
23
CPUTLBEntryFull *full;
25
- if (r2->fieldoffset) {
24
int flags;
26
- r2->fieldoffset += sizeof(uint32_t);
25
27
- }
26
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
28
-#endif
27
ptw->out_rw = full->prot & PAGE_WRITE;
29
+ if (HOST_BIG_ENDIAN &&
28
pte_attrs = full->pte_attrs;
30
+ r->state == ARM_CP_STATE_BOTH && r2->fieldoffset) {
29
pte_secure = full->attrs.secure;
31
+ r2->fieldoffset += sizeof(uint32_t);
30
+#else
32
}
31
+ g_assert_not_reached();
32
+#endif
33
}
33
}
34
34
35
if (regime_is_stage2(s2_mmu_idx)) {
35
--
36
--
36
2.25.1
37
2.34.1
38
39
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Put the block comments into the current coding style.
3
This struct has no dependencies on TCG code and it is being used in
4
target/arm/ptw.c to simplify the passing around of page table walk
5
results. Those routines can be reached by KVM code via the gdbstub
6
breakpoint code, so take the structure out of CONFIG_TCG to make it
7
visible when building with --disable-tcg.
4
8
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Fabiano Rosas <farosas@suse.de>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220501055028.646596-19-richard.henderson@linaro.org
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
14
---
10
target/arm/helper.c | 24 +++++++++++++++---------
15
include/exec/cpu-defs.h | 6 ++++++
11
1 file changed, 15 insertions(+), 9 deletions(-)
16
1 file changed, 6 insertions(+)
12
17
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
14
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
20
--- a/include/exec/cpu-defs.h
16
+++ b/target/arm/helper.c
21
+++ b/include/exec/cpu-defs.h
17
@@ -XXX,XX +XXX,XX @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
22
@@ -XXX,XX +XXX,XX @@ typedef struct CPUTLBEntry {
18
return cpu_list;
23
19
}
24
QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS));
20
25
21
+/*
26
+
22
+ * Private utility function for define_one_arm_cp_reg_with_opaque():
27
+#endif /* !CONFIG_USER_ONLY && CONFIG_TCG */
23
+ * add a single reginfo struct to the hash table.
28
+
24
+ */
29
+#if !defined(CONFIG_USER_ONLY)
25
static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
30
/*
26
void *opaque, CPState state,
31
* The full TLB entry, which is not accessed by generated TCG code,
27
CPSecureState secstate,
32
* so the layout is not as critical as that of CPUTLBEntry. This is
28
int crm, int opc1, int opc2,
33
@@ -XXX,XX +XXX,XX @@ typedef struct CPUTLBEntryFull {
29
const char *name)
34
TARGET_PAGE_ENTRY_EXTRA
30
{
35
#endif
31
- /* Private utility function for define_one_arm_cp_reg_with_opaque():
36
} CPUTLBEntryFull;
32
- * add a single reginfo struct to the hash table.
37
+#endif /* !CONFIG_USER_ONLY */
33
- */
38
34
uint32_t key;
39
+#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG)
35
ARMCPRegInfo *r2;
40
/*
36
bool is64 = r->type & ARM_CP_64BIT;
41
* Data elements that are per MMU mode, minus the bits accessed by
37
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
42
* the TCG fast path.
38
39
isbanked = r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1];
40
if (isbanked) {
41
- /* Register is banked (using both entries in array).
42
+ /*
43
+ * Register is banked (using both entries in array).
44
* Overwriting fieldoffset as the array is only used to define
45
* banked registers but later only fieldoffset is used.
46
*/
47
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
48
49
if (state == ARM_CP_STATE_AA32) {
50
if (isbanked) {
51
- /* If the register is banked then we don't need to migrate or
52
+ /*
53
+ * If the register is banked then we don't need to migrate or
54
* reset the 32-bit instance in certain cases:
55
*
56
* 1) If the register has both 32-bit and 64-bit instances then we
57
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
58
r2->type |= ARM_CP_ALIAS;
59
}
60
} else if ((secstate != r->secure) && !ns) {
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
*/
89
--
43
--
90
2.25.1
44
2.34.1
45
46
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Computing isbanked only once makes the code
3
This test currently fails when run on a host for which the QEMU target
4
a bit easier to read.
4
has no default machine set:
5
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
ERROR| Output: qemu-system-aarch64: No machine specified, and there is
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
no default
8
Message-id: 20220501055028.646596-17-richard.henderson@linaro.org
8
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Signed-off-by: Fabiano Rosas <farosas@suse.de>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
target/arm/helper.c | 6 ++++--
13
tests/avocado/version.py | 1 +
12
1 file changed, 4 insertions(+), 2 deletions(-)
14
1 file changed, 1 insertion(+)
13
15
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
diff --git a/tests/avocado/version.py b/tests/avocado/version.py
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
18
--- a/tests/avocado/version.py
17
+++ b/target/arm/helper.c
19
+++ b/tests/avocado/version.py
18
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
20
@@ -XXX,XX +XXX,XX @@
19
bool is64 = r->type & ARM_CP_64BIT;
21
class Version(QemuSystemTest):
20
bool ns = secstate & ARM_CP_SECSTATE_NS;
22
"""
21
int cp = r->cp;
23
:avocado: tags=quick
22
+ bool isbanked;
24
+ :avocado: tags=machine:none
23
size_t name_len;
25
"""
24
26
def test_qmp_human_info_version(self):
25
switch (state) {
27
self.vm.add_args('-nodefaults')
26
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
27
r2->opaque = opaque;
28
}
29
30
- if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
31
+ isbanked = r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1];
32
+ if (isbanked) {
33
/* Register is banked (using both entries in array).
34
* Overwriting fieldoffset as the array is only used to define
35
* banked registers but later only fieldoffset is used.
36
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
37
}
38
39
if (state == ARM_CP_STATE_AA32) {
40
- if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
41
+ if (isbanked) {
42
/* If the register is banked then we don't need to migrate or
43
* reset the 32-bit instance in certain cases:
44
*
45
--
28
--
46
2.25.1
29
2.34.1
30
31
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Cast the uint32_t key into a gpointer directly, which
3
Since &I2C_SLAVE(dev)->qdev == dev, no need to go back and
4
allows us to avoid allocating storage for each key.
4
forth with QOM type casting. Directly use 'dev'.
5
5
6
Use g_hash_table_lookup when we already have a gpointer
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
(e.g. for callbacks like count_cpreg), or when using
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
get_arm_cp_reginfo would require casting away const.
8
Message-id: 20230220115114.25237-2-philmd@linaro.org
9
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20220501055028.646596-12-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
10
---
15
target/arm/cpu.c | 4 ++--
11
hw/gpio/max7310.c | 5 ++---
16
target/arm/gdbstub.c | 2 +-
12
1 file changed, 2 insertions(+), 3 deletions(-)
17
target/arm/helper.c | 41 ++++++++++++++++++-----------------------
18
3 files changed, 21 insertions(+), 26 deletions(-)
19
13
20
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
14
diff --git a/hw/gpio/max7310.c b/hw/gpio/max7310.c
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.c
16
--- a/hw/gpio/max7310.c
23
+++ b/target/arm/cpu.c
17
+++ b/hw/gpio/max7310.c
24
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_initfn(Object *obj)
18
@@ -XXX,XX +XXX,XX @@ static void max7310_gpio_set(void *opaque, int line, int level)
25
ARMCPU *cpu = ARM_CPU(obj);
19
* but also accepts sequences that are not SMBus so return an I2C device. */
26
20
static void max7310_realize(DeviceState *dev, Error **errp)
27
cpu_set_cpustate_pointers(cpu);
28
- cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
29
- g_free, cpreg_hashtable_data_destroy);
30
+ cpu->cp_regs = g_hash_table_new_full(g_direct_hash, g_direct_equal,
31
+ NULL, cpreg_hashtable_data_destroy);
32
33
QLIST_INIT(&cpu->pre_el_change_hooks);
34
QLIST_INIT(&cpu->el_change_hooks);
35
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/gdbstub.c
38
+++ b/target/arm/gdbstub.c
39
@@ -XXX,XX +XXX,XX @@ static void arm_gen_one_xml_sysreg_tag(GString *s, DynamicGDBXMLInfo *dyn_xml,
40
static void arm_register_sysreg_for_xml(gpointer key, gpointer value,
41
gpointer p)
42
{
21
{
43
- uint32_t ri_key = *(uint32_t *)key;
22
- I2CSlave *i2c = I2C_SLAVE(dev);
44
+ uint32_t ri_key = (uintptr_t)key;
23
MAX7310State *s = MAX7310(dev);
45
ARMCPRegInfo *ri = value;
24
46
RegisterSysregXmlParam *param = (RegisterSysregXmlParam *)p;
25
- qdev_init_gpio_in(&i2c->qdev, max7310_gpio_set, 8);
47
GString *s = param->s;
26
- qdev_init_gpio_out(&i2c->qdev, s->handler, 8);
48
diff --git a/target/arm/helper.c b/target/arm/helper.c
27
+ qdev_init_gpio_in(dev, max7310_gpio_set, ARRAY_SIZE(s->handler));
49
index XXXXXXX..XXXXXXX 100644
28
+ qdev_init_gpio_out(dev, s->handler, ARRAY_SIZE(s->handler));
50
--- a/target/arm/helper.c
51
+++ b/target/arm/helper.c
52
@@ -XXX,XX +XXX,XX @@ bool write_list_to_cpustate(ARMCPU *cpu)
53
static void add_cpreg_to_list(gpointer key, gpointer opaque)
54
{
55
ARMCPU *cpu = opaque;
56
- uint64_t regidx;
57
- const ARMCPRegInfo *ri;
58
-
59
- regidx = *(uint32_t *)key;
60
- ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
61
+ uint32_t regidx = (uintptr_t)key;
62
+ const ARMCPRegInfo *ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
63
64
if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) {
65
cpu->cpreg_indexes[cpu->cpreg_array_len] = cpreg_to_kvm_id(regidx);
66
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_list(gpointer key, gpointer opaque)
67
static void count_cpreg(gpointer key, gpointer opaque)
68
{
69
ARMCPU *cpu = opaque;
70
- uint64_t regidx;
71
const ARMCPRegInfo *ri;
72
73
- regidx = *(uint32_t *)key;
74
- ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
75
+ ri = g_hash_table_lookup(cpu->cp_regs, key);
76
77
if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) {
78
cpu->cpreg_array_len++;
79
@@ -XXX,XX +XXX,XX @@ static void count_cpreg(gpointer key, gpointer opaque)
80
81
static gint cpreg_key_compare(gconstpointer a, gconstpointer b)
82
{
83
- uint64_t aidx = cpreg_to_kvm_id(*(uint32_t *)a);
84
- uint64_t bidx = cpreg_to_kvm_id(*(uint32_t *)b);
85
+ uint64_t aidx = cpreg_to_kvm_id((uintptr_t)a);
86
+ uint64_t bidx = cpreg_to_kvm_id((uintptr_t)b);
87
88
if (aidx > bidx) {
89
return 1;
90
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
91
for (i = 0; i < ARRAY_SIZE(aliases); i++) {
92
const struct E2HAlias *a = &aliases[i];
93
ARMCPRegInfo *src_reg, *dst_reg, *new_reg;
94
- uint32_t *new_key;
95
bool ok;
96
97
if (a->feature && !a->feature(&cpu->isar)) {
98
continue;
99
}
100
101
- src_reg = g_hash_table_lookup(cpu->cp_regs, &a->src_key);
102
- dst_reg = g_hash_table_lookup(cpu->cp_regs, &a->dst_key);
103
+ src_reg = g_hash_table_lookup(cpu->cp_regs,
104
+ (gpointer)(uintptr_t)a->src_key);
105
+ dst_reg = g_hash_table_lookup(cpu->cp_regs,
106
+ (gpointer)(uintptr_t)a->dst_key);
107
g_assert(src_reg != NULL);
108
g_assert(dst_reg != NULL);
109
110
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
111
112
/* Create alias before redirection so we dup the right data. */
113
new_reg = g_memdup(src_reg, sizeof(ARMCPRegInfo));
114
- new_key = g_memdup(&a->new_key, sizeof(uint32_t));
115
116
new_reg->name = a->new_name;
117
new_reg->type |= ARM_CP_ALIAS;
118
/* Remove PL1/PL0 access, leaving PL2/PL3 R/W in place. */
119
new_reg->access &= PL2_RW | PL3_RW;
120
121
- ok = g_hash_table_insert(cpu->cp_regs, new_key, new_reg);
122
+ ok = g_hash_table_insert(cpu->cp_regs,
123
+ (gpointer)(uintptr_t)a->new_key, new_reg);
124
g_assert(ok);
125
126
src_reg->opaque = dst_reg;
127
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
128
/* Private utility function for define_one_arm_cp_reg_with_opaque():
129
* add a single reginfo struct to the hash table.
130
*/
131
- uint32_t *key = g_new(uint32_t, 1);
132
+ uint32_t key;
133
ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
134
int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
135
int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
136
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
137
if (r->cp == 0 || r->state == ARM_CP_STATE_BOTH) {
138
r2->cp = CP_REG_ARM64_SYSREG_CP;
139
}
140
- *key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm,
141
- r2->opc0, opc1, opc2);
142
+ key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm,
143
+ r2->opc0, opc1, opc2);
144
} else {
145
- *key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2);
146
+ key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2);
147
}
148
if (opaque) {
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);
166
}
29
}
167
30
168
31
static void max7310_class_init(ObjectClass *klass, void *data)
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)
172
{
173
- return g_hash_table_lookup(cpregs, &encoded_cp);
174
+ return g_hash_table_lookup(cpregs, (gpointer)(uintptr_t)encoded_cp);
175
}
176
177
void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
178
--
32
--
179
2.25.1
33
2.34.1
34
35
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Perform the override check early, so that it is still done
3
pl011_create() is only used in DeviceRealize handlers,
4
even when we decide to discard an unreachable cpreg.
4
not a hot-path. Inlining is not justified.
5
5
6
Use assert not printf+abort.
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20230220115114.25237-3-philmd@linaro.org
10
Message-id: 20220501055028.646596-18-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
11
---
13
target/arm/helper.c | 22 ++++++++--------------
12
include/hw/char/pl011.h | 19 +------------------
14
1 file changed, 8 insertions(+), 14 deletions(-)
13
hw/char/pl011.c | 17 +++++++++++++++++
14
2 files changed, 18 insertions(+), 18 deletions(-)
15
15
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
diff --git a/include/hw/char/pl011.h b/include/hw/char/pl011.h
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
18
--- a/include/hw/char/pl011.h
19
+++ b/target/arm/helper.c
19
+++ b/include/hw/char/pl011.h
20
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
20
@@ -XXX,XX +XXX,XX @@
21
g_assert_not_reached();
21
#ifndef HW_PL011_H
22
}
22
#define HW_PL011_H
23
23
24
+ /* Overriding of an existing definition must be explicitly requested. */
24
-#include "hw/qdev-properties.h"
25
+ if (!(r->type & ARM_CP_OVERRIDE)) {
25
#include "hw/sysbus.h"
26
+ const ARMCPRegInfo *oldreg = get_arm_cp_reginfo(cpu->cp_regs, key);
26
#include "chardev/char-fe.h"
27
+ if (oldreg) {
27
-#include "qapi/error.h"
28
+ assert(oldreg->type & ARM_CP_OVERRIDE);
28
#include "qom/object.h"
29
+ }
29
30
+ }
30
#define TYPE_PL011 "pl011"
31
@@ -XXX,XX +XXX,XX @@ struct PL011State {
32
const unsigned char *id;
33
};
34
35
-static inline DeviceState *pl011_create(hwaddr addr,
36
- qemu_irq irq,
37
- Chardev *chr)
38
-{
39
- DeviceState *dev;
40
- SysBusDevice *s;
41
-
42
- dev = qdev_new("pl011");
43
- s = SYS_BUS_DEVICE(dev);
44
- qdev_prop_set_chr(dev, "chardev", chr);
45
- sysbus_realize_and_unref(s, &error_fatal);
46
- sysbus_mmio_map(s, 0, addr);
47
- sysbus_connect_irq(s, 0, irq);
48
-
49
- return dev;
50
-}
51
+DeviceState *pl011_create(hwaddr addr, qemu_irq irq, Chardev *chr);
52
53
static inline DeviceState *pl011_luminary_create(hwaddr addr,
54
qemu_irq irq,
55
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/char/pl011.c
58
+++ b/hw/char/pl011.c
59
@@ -XXX,XX +XXX,XX @@
60
*/
61
62
#include "qemu/osdep.h"
63
+#include "qapi/error.h"
64
#include "hw/char/pl011.h"
65
#include "hw/irq.h"
66
#include "hw/sysbus.h"
67
#include "hw/qdev-clock.h"
68
+#include "hw/qdev-properties.h"
69
#include "hw/qdev-properties-system.h"
70
#include "migration/vmstate.h"
71
#include "chardev/char-fe.h"
72
@@ -XXX,XX +XXX,XX @@
73
#include "qemu/module.h"
74
#include "trace.h"
75
76
+DeviceState *pl011_create(hwaddr addr, qemu_irq irq, Chardev *chr)
77
+{
78
+ DeviceState *dev;
79
+ SysBusDevice *s;
31
+
80
+
32
/* Combine cpreg and name into one allocation. */
81
+ dev = qdev_new("pl011");
33
name_len = strlen(name) + 1;
82
+ s = SYS_BUS_DEVICE(dev);
34
r2 = g_malloc(sizeof(*r2) + name_len);
83
+ qdev_prop_set_chr(dev, "chardev", chr);
35
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
84
+ sysbus_realize_and_unref(s, &error_fatal);
36
assert(!raw_accessors_invalid(r2));
85
+ sysbus_mmio_map(s, 0, addr);
37
}
86
+ sysbus_connect_irq(s, 0, irq);
38
87
+
39
- /* Overriding of an existing definition must be explicitly
88
+ return dev;
40
- * requested.
89
+}
41
- */
90
+
42
- if (!(r->type & ARM_CP_OVERRIDE)) {
91
#define PL011_INT_TX 0x20
43
- const ARMCPRegInfo *oldreg = get_arm_cp_reginfo(cpu->cp_regs, key);
92
#define PL011_INT_RX 0x10
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);
54
}
55
93
56
--
94
--
57
2.25.1
95
2.34.1
96
97
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Put most of the value writeback to the same place,
3
pl011_luminary_create() is only used for the Stellaris board,
4
and improve the comment that goes with them.
4
open-code it.
5
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20220501055028.646596-15-richard.henderson@linaro.org
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230220115114.25237-4-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/helper.c | 28 ++++++++++++----------------
12
include/hw/char/pl011.h | 17 -----------------
12
1 file changed, 12 insertions(+), 16 deletions(-)
13
hw/arm/stellaris.c | 11 ++++++++---
14
2 files changed, 8 insertions(+), 20 deletions(-)
13
15
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
diff --git a/include/hw/char/pl011.h b/include/hw/char/pl011.h
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
18
--- a/include/hw/char/pl011.h
17
+++ b/target/arm/helper.c
19
+++ b/include/hw/char/pl011.h
18
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
20
@@ -XXX,XX +XXX,XX @@ struct PL011State {
19
*r2 = *r;
21
20
r2->name = memcpy(r2 + 1, name, name_len);
22
DeviceState *pl011_create(hwaddr addr, qemu_irq irq, Chardev *chr);
21
23
22
- /* Reset the secure state to the specific incoming state. This is
24
-static inline DeviceState *pl011_luminary_create(hwaddr addr,
23
- * necessary as the register may have been defined with both states.
25
- qemu_irq irq,
24
+ /*
26
- Chardev *chr)
25
+ * Update fields to match the instantiation, overwiting wildcards
27
-{
26
+ * such as CP_ANY, ARM_CP_STATE_BOTH, or ARM_CP_SECSTATE_BOTH.
28
- DeviceState *dev;
27
*/
29
- SysBusDevice *s;
28
+ r2->cp = cp;
30
-
29
+ r2->crm = crm;
31
- dev = qdev_new("pl011_luminary");
30
+ r2->opc1 = opc1;
32
- s = SYS_BUS_DEVICE(dev);
31
+ r2->opc2 = opc2;
33
- qdev_prop_set_chr(dev, "chardev", chr);
32
+ r2->state = state;
34
- sysbus_realize_and_unref(s, &error_fatal);
33
r2->secure = secstate;
35
- sysbus_mmio_map(s, 0, addr);
34
+ if (opaque) {
36
- sysbus_connect_irq(s, 0, irq);
35
+ r2->opaque = opaque;
37
-
36
+ }
38
- return dev;
37
39
-}
38
if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
40
-
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
41
#endif
42
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/arm/stellaris.c
45
+++ b/hw/arm/stellaris.c
46
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
47
48
for (i = 0; i < 4; i++) {
49
if (board->dc2 & (1 << i)) {
50
- pl011_luminary_create(0x4000c000 + i * 0x1000,
51
- qdev_get_gpio_in(nvic, uart_irq[i]),
52
- serial_hd(i));
53
+ SysBusDevice *sbd;
54
+
55
+ dev = qdev_new("pl011_luminary");
56
+ sbd = SYS_BUS_DEVICE(dev);
57
+ qdev_prop_set_chr(dev, "chardev", serial_hd(i));
58
+ sysbus_realize_and_unref(sbd, &error_fatal);
59
+ sysbus_mmio_map(sbd, 0, 0x4000c000 + i * 0x1000);
60
+ sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(nvic, uart_irq[i]));
42
}
61
}
43
}
62
}
44
- if (opaque) {
63
if (board->dc2 & (1 << 4)) {
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;
58
+
59
/* By convention, for wildcarded registers only the first
60
* entry is used for migration; the others are marked as
61
* ALIAS so we don't try to transfer the register
62
--
64
--
63
2.25.1
65
2.34.1
66
67
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Bool is a more appropriate type for these variables.
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Message-id: 20230220115114.25237-5-philmd@linaro.org
7
Message-id: 20220501055028.646596-16-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
8
---
10
target/arm/helper.c | 4 ++--
9
include/hw/char/xilinx_uartlite.h | 6 +++++-
11
1 file changed, 2 insertions(+), 2 deletions(-)
10
hw/char/xilinx_uartlite.c | 4 +---
11
2 files changed, 6 insertions(+), 4 deletions(-)
12
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/include/hw/char/xilinx_uartlite.h b/include/hw/char/xilinx_uartlite.h
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
15
--- a/include/hw/char/xilinx_uartlite.h
16
+++ b/target/arm/helper.c
16
+++ b/include/hw/char/xilinx_uartlite.h
17
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
17
@@ -XXX,XX +XXX,XX @@
18
*/
18
#include "hw/qdev-properties.h"
19
uint32_t key;
19
#include "hw/sysbus.h"
20
ARMCPRegInfo *r2;
20
#include "qapi/error.h"
21
- int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
21
+#include "qom/object.h"
22
- int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
22
+
23
+ bool is64 = r->type & ARM_CP_64BIT;
23
+#define TYPE_XILINX_UARTLITE "xlnx.xps-uartlite"
24
+ bool ns = secstate & ARM_CP_SECSTATE_NS;
24
+OBJECT_DECLARE_SIMPLE_TYPE(XilinxUARTLite, XILINX_UARTLITE)
25
int cp = r->cp;
25
26
size_t name_len;
26
static inline DeviceState *xilinx_uartlite_create(hwaddr addr,
27
qemu_irq irq,
28
@@ -XXX,XX +XXX,XX @@ static inline DeviceState *xilinx_uartlite_create(hwaddr addr,
29
DeviceState *dev;
30
SysBusDevice *s;
31
32
- dev = qdev_new("xlnx.xps-uartlite");
33
+ dev = qdev_new(TYPE_XILINX_UARTLITE);
34
s = SYS_BUS_DEVICE(dev);
35
qdev_prop_set_chr(dev, "chardev", chr);
36
sysbus_realize_and_unref(s, &error_fatal);
37
diff --git a/hw/char/xilinx_uartlite.c b/hw/char/xilinx_uartlite.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/char/xilinx_uartlite.c
40
+++ b/hw/char/xilinx_uartlite.c
41
@@ -XXX,XX +XXX,XX @@
42
43
#include "qemu/osdep.h"
44
#include "qemu/log.h"
45
+#include "hw/char/xilinx_uartlite.h"
46
#include "hw/irq.h"
47
#include "hw/qdev-properties.h"
48
#include "hw/qdev-properties-system.h"
49
@@ -XXX,XX +XXX,XX @@
50
#define CONTROL_RST_RX 0x02
51
#define CONTROL_IE 0x10
52
53
-#define TYPE_XILINX_UARTLITE "xlnx.xps-uartlite"
54
-OBJECT_DECLARE_SIMPLE_TYPE(XilinxUARTLite, XILINX_UARTLITE)
55
-
56
struct XilinxUARTLite {
57
SysBusDevice parent_obj;
27
58
28
--
59
--
29
2.25.1
60
2.34.1
61
62
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
These particular data structures are not modified at runtime.
3
Open-code the single use of xilinx_uartlite_create().
4
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230220115114.25237-6-philmd@linaro.org
8
Message-id: 20220501055028.646596-5-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
target/arm/helper.c | 16 ++++++++--------
11
include/hw/char/xilinx_uartlite.h | 20 --------------------
12
1 file changed, 8 insertions(+), 8 deletions(-)
12
hw/microblaze/petalogix_s3adsp1800_mmu.c | 7 +++++--
13
2 files changed, 5 insertions(+), 22 deletions(-)
13
14
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/include/hw/char/xilinx_uartlite.h b/include/hw/char/xilinx_uartlite.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
--- a/include/hw/char/xilinx_uartlite.h
17
+++ b/target/arm/helper.c
18
+++ b/include/hw/char/xilinx_uartlite.h
18
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
19
@@ -XXX,XX +XXX,XX @@
19
.resetvalue = cpu->pmceid1 },
20
#ifndef XILINX_UARTLITE_H
20
};
21
#define XILINX_UARTLITE_H
21
#ifdef CONFIG_USER_ONLY
22
22
- ARMCPRegUserSpaceInfo v8_user_idregs[] = {
23
-#include "hw/qdev-properties.h"
23
+ static const ARMCPRegUserSpaceInfo v8_user_idregs[] = {
24
-#include "hw/sysbus.h"
24
{ .name = "ID_AA64PFR0_EL1",
25
-#include "qapi/error.h"
25
.exported_bits = 0x000f000f00ff0000,
26
#include "qom/object.h"
26
.fixed_bits = 0x0000000000000011 },
27
27
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
28
#define TYPE_XILINX_UARTLITE "xlnx.xps-uartlite"
28
*/
29
OBJECT_DECLARE_SIMPLE_TYPE(XilinxUARTLite, XILINX_UARTLITE)
29
if (arm_feature(env, ARM_FEATURE_EL3)) {
30
30
if (arm_feature(env, ARM_FEATURE_AARCH64)) {
31
-static inline DeviceState *xilinx_uartlite_create(hwaddr addr,
31
- ARMCPRegInfo nsacr = {
32
- qemu_irq irq,
32
+ static const ARMCPRegInfo nsacr = {
33
- Chardev *chr)
33
.name = "NSACR", .type = ARM_CP_CONST,
34
-{
34
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,
35
- DeviceState *dev;
35
.access = PL1_RW, .accessfn = nsacr_access,
36
- SysBusDevice *s;
36
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
37
-
37
};
38
- dev = qdev_new(TYPE_XILINX_UARTLITE);
38
define_one_arm_cp_reg(cpu, &nsacr);
39
- s = SYS_BUS_DEVICE(dev);
39
} else {
40
- qdev_prop_set_chr(dev, "chardev", chr);
40
- ARMCPRegInfo nsacr = {
41
- sysbus_realize_and_unref(s, &error_fatal);
41
+ static const ARMCPRegInfo nsacr = {
42
- sysbus_mmio_map(s, 0, addr);
42
.name = "NSACR",
43
- sysbus_connect_irq(s, 0, irq);
43
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,
44
-
44
.access = PL3_RW | PL1_R,
45
- return dev;
45
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
46
-}
46
}
47
-
47
} else {
48
#endif
48
if (arm_feature(env, ARM_FEATURE_V8)) {
49
diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c
49
- ARMCPRegInfo nsacr = {
50
index XXXXXXX..XXXXXXX 100644
50
+ static const ARMCPRegInfo nsacr = {
51
--- a/hw/microblaze/petalogix_s3adsp1800_mmu.c
51
.name = "NSACR", .type = ARM_CP_CONST,
52
+++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c
52
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,
53
@@ -XXX,XX +XXX,XX @@ petalogix_s3adsp1800_init(MachineState *machine)
53
.access = PL1_R,
54
irq[i] = qdev_get_gpio_in(dev, i);
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)
80
}
55
}
81
56
82
if (arm_feature(env, ARM_FEATURE_VBAR)) {
57
- xilinx_uartlite_create(UARTLITE_BASEADDR, irq[UARTLITE_IRQ],
83
- ARMCPRegInfo vbar_cp_reginfo[] = {
58
- serial_hd(0));
84
+ static const ARMCPRegInfo vbar_cp_reginfo[] = {
59
+ dev = qdev_new(TYPE_XILINX_UARTLITE);
85
{ .name = "VBAR", .state = ARM_CP_STATE_BOTH,
60
+ qdev_prop_set_chr(dev, "chardev", serial_hd(0));
86
.opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
61
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
87
.access = PL1_RW, .writefn = vbar_write,
62
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, UARTLITE_BASEADDR);
63
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[UARTLITE_IRQ]);
64
65
/* 2 timers at irq 2 @ 62 Mhz. */
66
dev = qdev_new("xlnx.xps-timer");
88
--
67
--
89
2.25.1
68
2.34.1
90
69
91
70
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Move ARMCPRegInfo and all related declarations to a new
3
cmsdk_apb_uart_create() is only used twice in the same
4
internal header, out of the public cpu.h.
4
file. Open-code it.
5
5
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230220115114.25237-7-philmd@linaro.org
9
Message-id: 20220501055028.646596-2-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
target/arm/cpregs.h | 413 +++++++++++++++++++++++++++++++++++++
11
include/hw/char/cmsdk-apb-uart.h | 34 --------------------------
13
target/arm/cpu.h | 368 ---------------------------------
12
hw/arm/mps2.c | 41 +++++++++++++++++++++-----------
14
hw/arm/pxa2xx.c | 1 +
13
2 files changed, 27 insertions(+), 48 deletions(-)
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
28
14
29
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
15
diff --git a/include/hw/char/cmsdk-apb-uart.h b/include/hw/char/cmsdk-apb-uart.h
30
new file mode 100644
16
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX
17
--- a/include/hw/char/cmsdk-apb-uart.h
32
--- /dev/null
18
+++ b/include/hw/char/cmsdk-apb-uart.h
33
+++ b/target/arm/cpregs.h
34
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
35
+/*
20
#ifndef CMSDK_APB_UART_H
36
+ * QEMU ARM CP Register access and descriptions
21
#define CMSDK_APB_UART_H
37
+ *
22
38
+ * Copyright (c) 2022 Linaro Ltd
23
-#include "hw/qdev-properties.h"
39
+ *
24
#include "hw/sysbus.h"
40
+ * This program is free software; you can redistribute it and/or
25
#include "chardev/char-fe.h"
41
+ * modify it under the terms of the GNU General Public License
26
-#include "qapi/error.h"
42
+ * as published by the Free Software Foundation; either version 2
27
#include "qom/object.h"
43
+ * of the License, or (at your option) any later version.
28
44
+ *
29
#define TYPE_CMSDK_APB_UART "cmsdk-apb-uart"
45
+ * This program is distributed in the hope that it will be useful,
30
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBUART {
46
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31
uint8_t rxbuf;
47
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32
};
48
+ * GNU General Public License for more details.
33
49
+ *
34
-/**
50
+ * You should have received a copy of the GNU General Public License
35
- * cmsdk_apb_uart_create - convenience function to create TYPE_CMSDK_APB_UART
51
+ * along with this program; if not, see
36
- * @addr: location in system memory to map registers
52
+ * <http://www.gnu.org/licenses/gpl-2.0.html>
37
- * @chr: Chardev backend to connect UART to, or NULL if no backend
53
+ */
38
- * @pclk_frq: frequency in Hz of the PCLK clock (used for calculating baud rate)
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 */
448
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
449
index XXXXXXX..XXXXXXX 100644
450
--- a/target/arm/cpu.h
451
+++ b/target/arm/cpu.h
452
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
453
return kvmid;
454
}
455
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
- */
39
- */
484
-#define ARM_CP_SPECIAL 0x0001
40
-static inline DeviceState *cmsdk_apb_uart_create(hwaddr addr,
485
-#define ARM_CP_CONST 0x0002
41
- qemu_irq txint,
486
-#define ARM_CP_64BIT 0x0004
42
- qemu_irq rxint,
487
-#define ARM_CP_SUPPRESS_TB_END 0x0008
43
- qemu_irq txovrint,
488
-#define ARM_CP_OVERRIDE 0x0010
44
- qemu_irq rxovrint,
489
-#define ARM_CP_ALIAS 0x0020
45
- qemu_irq uartint,
490
-#define ARM_CP_IO 0x0040
46
- Chardev *chr,
491
-#define ARM_CP_NO_RAW 0x0080
47
- uint32_t pclk_frq)
492
-#define ARM_CP_NOP (ARM_CP_SPECIAL | 0x0100)
48
-{
493
-#define ARM_CP_WFI (ARM_CP_SPECIAL | 0x0200)
49
- DeviceState *dev;
494
-#define ARM_CP_NZCV (ARM_CP_SPECIAL | 0x0300)
50
- SysBusDevice *s;
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
-
51
-
510
-/* Valid values for ARMCPRegInfo state field, indicating which of
52
- dev = qdev_new(TYPE_CMSDK_APB_UART);
511
- * the AArch32 and AArch64 execution states this register is visible in.
53
- s = SYS_BUS_DEVICE(dev);
512
- * If the reginfo doesn't explicitly specify then it is AArch32 only.
54
- qdev_prop_set_chr(dev, "chardev", chr);
513
- * If the reginfo is declared to be visible in both states then a second
55
- qdev_prop_set_uint32(dev, "pclk-frq", pclk_frq);
514
- * reginfo is synthesised for the AArch32 view of the AArch64 register,
56
- sysbus_realize_and_unref(s, &error_fatal);
515
- * such that the AArch32 view is the lower 32 bits of the AArch64 one.
57
- sysbus_mmio_map(s, 0, addr);
516
- * Note that we rely on the values of these enums as we iterate through
58
- sysbus_connect_irq(s, 0, txint);
517
- * the various states in some places.
59
- sysbus_connect_irq(s, 1, rxint);
518
- */
60
- sysbus_connect_irq(s, 2, txovrint);
519
-enum {
61
- sysbus_connect_irq(s, 3, rxovrint);
520
- ARM_CP_STATE_AA32 = 0,
62
- sysbus_connect_irq(s, 4, uartint);
521
- ARM_CP_STATE_AA64 = 1,
63
- return dev;
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
-}
64
-}
550
-
65
-
551
-/* Access rights:
66
#endif
552
- * We define bits for Read and Write access for what rev C of the v7-AR ARM ARM
67
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
553
- * defines as PL0 (user), PL1 (fiq/irq/svc/abt/und/sys, ie privileged), and
68
index XXXXXXX..XXXXXXX 100644
554
- * PL2 (hyp). The other level which has Read and Write bits is Secure PL1
69
--- a/hw/arm/mps2.c
555
- * (ie any of the privileged modes in Secure state, or Monitor mode).
70
+++ b/hw/arm/mps2.c
556
- * If a register is accessible in one privilege level it's always accessible
71
@@ -XXX,XX +XXX,XX @@
557
- * in higher privilege levels too. Since "Secure PL1" also follows this rule
72
#include "hw/boards.h"
558
- * (ie anything visible in PL2 is visible in S-PL1, some things are only
73
#include "exec/address-spaces.h"
559
- * visible in S-PL1) but "Secure PL1" is a bit of a mouthful, we bend the
74
#include "sysemu/sysemu.h"
560
- * terminology a little and call this PL3.
75
+#include "hw/qdev-properties.h"
561
- * In AArch64 things are somewhat simpler as the PLx bits line up exactly
76
#include "hw/misc/unimp.h"
562
- * with the ELx exception levels.
77
#include "hw/char/cmsdk-apb-uart.h"
563
- *
78
#include "hw/timer/cmsdk-apb-timer.h"
564
- * If access permissions for a register are more complex than can be
79
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
565
- * described with these bits, then use a laxer set of restrictions, and
80
qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));
566
- * do the more restrictive/complex check inside a helper function.
81
567
- */
82
for (i = 0; i < 5; i++) {
568
-#define PL3_R 0x80
83
+ DeviceState *dev;
569
-#define PL3_W 0x40
84
+ SysBusDevice *s;
570
-#define PL2_R (0x20 | PL3_R)
85
+
571
-#define PL2_W (0x10 | PL3_W)
86
static const hwaddr uartbase[] = {0x40004000, 0x40005000,
572
-#define PL1_R (0x08 | PL2_R)
87
0x40006000, 0x40007000,
573
-#define PL1_W (0x04 | PL2_W)
88
0x40009000};
574
-#define PL0_R (0x02 | PL1_R)
89
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
575
-#define PL0_W (0x01 | PL1_W)
90
rxovrint = qdev_get_gpio_in(orgate_dev, i * 2 + 1);
576
-
91
}
577
-/*
92
578
- * For user-mode some registers are accessible to EL0 via a kernel
93
- cmsdk_apb_uart_create(uartbase[i],
579
- * trap-and-emulate ABI. In this case we define the read permissions
94
- qdev_get_gpio_in(armv7m, uartirq[i] + 1),
580
- * as actually being PL0_R. However some bits of any given register
95
- qdev_get_gpio_in(armv7m, uartirq[i]),
581
- * may still be masked.
96
- txovrint, rxovrint,
582
- */
97
- NULL,
583
-#ifdef CONFIG_USER_ONLY
98
- serial_hd(i), SYSCLK_FRQ);
584
-#define PL0U_R PL0_R
99
+ dev = qdev_new(TYPE_CMSDK_APB_UART);
585
-#else
100
+ s = SYS_BUS_DEVICE(dev);
586
-#define PL0U_R PL1_R
101
+ qdev_prop_set_chr(dev, "chardev", serial_hd(i));
587
-#endif
102
+ qdev_prop_set_uint32(dev, "pclk-frq", SYSCLK_FRQ);
588
-
103
+ sysbus_realize_and_unref(s, &error_fatal);
589
-#define PL3_RW (PL3_R | PL3_W)
104
+ sysbus_mmio_map(s, 0, uartbase[i]);
590
-#define PL2_RW (PL2_R | PL2_W)
105
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(armv7m, uartirq[i] + 1));
591
-#define PL1_RW (PL1_R | PL1_W)
106
+ sysbus_connect_irq(s, 1, qdev_get_gpio_in(armv7m, uartirq[i]));
592
-#define PL0_RW (PL0_R | PL0_W)
107
+ sysbus_connect_irq(s, 2, txovrint);
593
-
108
+ sysbus_connect_irq(s, 3, rxovrint);
594
/* Return the highest implemented Exception Level */
109
}
595
static inline int arm_highest_el(CPUARMState *env)
110
break;
596
{
597
@@ -XXX,XX +XXX,XX @@ static inline int arm_current_el(CPUARMState *env)
598
}
111
}
599
}
112
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
600
113
0x4002c000, 0x4002d000,
601
-typedef struct ARMCPRegInfo ARMCPRegInfo;
114
0x4002e000};
602
-
115
Object *txrx_orgate;
603
-typedef enum CPAccessResult {
116
- DeviceState *txrx_orgate_dev;
604
- /* Access is permitted */
117
+ DeviceState *txrx_orgate_dev, *dev;
605
- CP_ACCESS_OK = 0,
118
+ SysBusDevice *s;
606
- /* Access fails due to a configurable trap or enable which would
119
607
- * result in a categorized exception syndrome giving information about
120
txrx_orgate = object_new(TYPE_OR_IRQ);
608
- * the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6,
121
object_property_set_int(txrx_orgate, "num-lines", 2, &error_fatal);
609
- * 0xc or 0x18). The exception is taken to the usual target EL (EL1 or
122
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
610
- * PL1 if in EL0, otherwise to the current EL).
123
txrx_orgate_dev = DEVICE(txrx_orgate);
611
- */
124
qdev_connect_gpio_out(txrx_orgate_dev, 0,
612
- CP_ACCESS_TRAP = 1,
125
qdev_get_gpio_in(armv7m, uart_txrx_irqno[i]));
613
- /* Access fails and results in an exception syndrome 0x0 ("uncategorized").
126
- cmsdk_apb_uart_create(uartbase[i],
614
- * Note that this is not a catch-all case -- the set of cases which may
127
- qdev_get_gpio_in(txrx_orgate_dev, 0),
615
- * result in this failure is specifically defined by the architecture.
128
- qdev_get_gpio_in(txrx_orgate_dev, 1),
616
- */
129
- qdev_get_gpio_in(orgate_dev, i * 2),
617
- CP_ACCESS_TRAP_UNCATEGORIZED = 2,
130
- qdev_get_gpio_in(orgate_dev, i * 2 + 1),
618
- /* As CP_ACCESS_TRAP, but for traps directly to EL2 or EL3 */
131
- NULL,
619
- CP_ACCESS_TRAP_EL2 = 3,
132
- serial_hd(i), SYSCLK_FRQ);
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"
867
868
/*
869
* Special case return value from hppvi_index(); must be larger than
870
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
871
index XXXXXXX..XXXXXXX 100644
872
--- a/hw/intc/arm_gicv3_kvm.c
873
+++ b/hw/intc/arm_gicv3_kvm.c
874
@@ -XXX,XX +XXX,XX @@
875
#include "vgic_common.h"
876
#include "migration/blocker.h"
877
#include "qom/object.h"
878
+#include "target/arm/cpregs.h"
879
+
133
+
880
134
+ dev = qdev_new(TYPE_CMSDK_APB_UART);
881
#ifdef DEBUG_GICV3_KVM
135
+ s = SYS_BUS_DEVICE(dev);
882
#define DPRINTF(fmt, ...) \
136
+ qdev_prop_set_chr(dev, "chardev", serial_hd(i));
883
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
137
+ qdev_prop_set_uint32(dev, "pclk-frq", SYSCLK_FRQ);
884
index XXXXXXX..XXXXXXX 100644
138
+ sysbus_realize_and_unref(s, &error_fatal);
885
--- a/target/arm/cpu.c
139
+ sysbus_mmio_map(s, 0, uartbase[i]);
886
+++ b/target/arm/cpu.c
140
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(txrx_orgate_dev, 0));
887
@@ -XXX,XX +XXX,XX @@
141
+ sysbus_connect_irq(s, 1, qdev_get_gpio_in(txrx_orgate_dev, 1));
888
#include "kvm_arm.h"
142
+ sysbus_connect_irq(s, 2, qdev_get_gpio_in(orgate_dev, i * 2));
889
#include "disas/capstone.h"
143
+ sysbus_connect_irq(s, 3, qdev_get_gpio_in(orgate_dev, i * 2 + 1));
890
#include "fpu/softfloat.h"
144
}
891
+#include "cpregs.h"
145
break;
892
146
}
893
static void arm_cpu_set_pc(CPUState *cs, vaddr value)
894
{
895
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
896
index XXXXXXX..XXXXXXX 100644
897
--- a/target/arm/cpu64.c
898
+++ b/target/arm/cpu64.c
899
@@ -XXX,XX +XXX,XX @@
900
#include "hvf_arm.h"
901
#include "qapi/visitor.h"
902
#include "hw/qdev-properties.h"
903
+#include "cpregs.h"
904
905
906
#ifndef CONFIG_USER_ONLY
907
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
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;
934
diff --git a/target/arm/helper.c b/target/arm/helper.c
935
index XXXXXXX..XXXXXXX 100644
936
--- a/target/arm/helper.c
937
+++ b/target/arm/helper.c
938
@@ -XXX,XX +XXX,XX @@
939
#include "exec/cpu_ldst.h"
940
#include "semihosting/common-semi.h"
941
#endif
942
+#include "cpregs.h"
943
944
#define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */
945
#define PMCR_NUM_COUNTERS 4 /* QEMU IMPDEF choice */
946
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
947
index XXXXXXX..XXXXXXX 100644
948
--- a/target/arm/op_helper.c
949
+++ b/target/arm/op_helper.c
950
@@ -XXX,XX +XXX,XX @@
951
#include "internals.h"
952
#include "exec/exec-all.h"
953
#include "exec/cpu_ldst.h"
954
+#include "cpregs.h"
955
956
#define SIGNBIT (uint32_t)0x80000000
957
#define SIGNBIT64 ((uint64_t)1 << 63)
958
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
959
index XXXXXXX..XXXXXXX 100644
960
--- a/target/arm/translate-a64.c
961
+++ b/target/arm/translate-a64.c
962
@@ -XXX,XX +XXX,XX @@
963
#include "translate.h"
964
#include "internals.h"
965
#include "qemu/host-utils.h"
966
-
967
#include "semihosting/semihost.h"
968
#include "exec/gen-icount.h"
969
-
970
#include "exec/helper-proto.h"
971
#include "exec/helper-gen.h"
972
#include "exec/log.h"
973
-
974
+#include "cpregs.h"
975
#include "translate-a64.h"
976
#include "qemu/atomic128.h"
977
978
diff --git a/target/arm/translate.c b/target/arm/translate.c
979
index XXXXXXX..XXXXXXX 100644
980
--- a/target/arm/translate.c
981
+++ b/target/arm/translate.c
982
@@ -XXX,XX +XXX,XX @@
983
#include "qemu/bitops.h"
984
#include "arm_ldst.h"
985
#include "semihosting/semihost.h"
986
-
987
#include "exec/helper-proto.h"
988
#include "exec/helper-gen.h"
989
-
990
#include "exec/log.h"
991
+#include "cpregs.h"
992
993
994
#define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
995
--
147
--
996
2.25.1
148
2.34.1
997
149
998
150
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Move the computation of key to the top of the function.
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Hoist the resolution of cp as well, as an input to the
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
computation of key.
5
Message-id: 20230220115114.25237-8-philmd@linaro.org
6
7
This will be required by a subsequent patch.
8
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20220501055028.646596-14-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
7
---
14
target/arm/helper.c | 49 +++++++++++++++++++++++++--------------------
8
include/hw/timer/cmsdk-apb-timer.h | 1 -
15
1 file changed, 27 insertions(+), 22 deletions(-)
9
1 file changed, 1 deletion(-)
16
10
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
11
diff --git a/include/hw/timer/cmsdk-apb-timer.h b/include/hw/timer/cmsdk-apb-timer.h
18
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
13
--- a/include/hw/timer/cmsdk-apb-timer.h
20
+++ b/target/arm/helper.c
14
+++ b/include/hw/timer/cmsdk-apb-timer.h
21
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
15
@@ -XXX,XX +XXX,XX @@
22
ARMCPRegInfo *r2;
16
#ifndef CMSDK_APB_TIMER_H
23
int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
17
#define CMSDK_APB_TIMER_H
24
int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
18
25
+ int cp = r->cp;
19
-#include "hw/qdev-properties.h"
26
size_t name_len;
20
#include "hw/sysbus.h"
27
21
#include "hw/ptimer.h"
28
+ switch (state) {
22
#include "hw/clock.h"
29
+ case ARM_CP_STATE_AA32:
30
+ /* We assume it is a cp15 register if the .cp field is left unset. */
31
+ if (cp == 0 && r->state == ARM_CP_STATE_BOTH) {
32
+ cp = 15;
33
+ }
34
+ key = ENCODE_CP_REG(cp, is64, ns, r->crn, crm, opc1, opc2);
35
+ break;
36
+ case ARM_CP_STATE_AA64:
37
+ /*
38
+ * To allow abbreviation of ARMCPRegInfo definitions, we treat
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();
51
+ }
52
+
53
/* Combine cpreg and name into one allocation. */
54
name_len = strlen(name) + 1;
55
r2 = g_malloc(sizeof(*r2) + name_len);
56
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
57
}
58
59
if (r->state == ARM_CP_STATE_BOTH) {
60
- /* We assume it is a cp15 register if the .cp field is left unset.
61
- */
62
- if (r2->cp == 0) {
63
- r2->cp = 15;
64
- }
65
-
66
#if HOST_BIG_ENDIAN
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;
100
--
23
--
101
2.25.1
24
2.34.1
25
26
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
The new_key field is always non-zero -- drop the if.
3
Avoid accessing 'parent_obj' directly.
4
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20220501055028.646596-11-richard.henderson@linaro.org
7
Message-id: 20230220115114.25237-9-philmd@linaro.org
8
[PMM: reinstated dropped PL3_RW mask]
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
target/arm/helper.c | 23 +++++++++++------------
10
hw/intc/armv7m_nvic.c | 6 +++---
12
1 file changed, 11 insertions(+), 12 deletions(-)
11
1 file changed, 3 insertions(+), 3 deletions(-)
13
12
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
15
--- a/hw/intc/armv7m_nvic.c
17
+++ b/target/arm/helper.c
16
+++ b/hw/intc/armv7m_nvic.c
18
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
17
@@ -XXX,XX +XXX,XX @@ static void do_armv7m_nvic_set_pending(void *opaque, int irq, bool secure,
19
18
* which saves having to have an extra argument is_terminal
20
for (i = 0; i < ARRAY_SIZE(aliases); i++) {
19
* that we'd only use in one place.
21
const struct E2HAlias *a = &aliases[i];
20
*/
22
- ARMCPRegInfo *src_reg, *dst_reg;
21
- cpu_abort(&s->cpu->parent_obj,
23
+ ARMCPRegInfo *src_reg, *dst_reg, *new_reg;
22
+ cpu_abort(CPU(s->cpu),
24
+ uint32_t *new_key;
23
"Lockup: can't take terminal derived exception "
25
+ bool ok;
24
"(original exception priority %d)\n",
26
25
s->vectpending_prio);
27
if (a->feature && !a->feature(&cpu->isar)) {
26
@@ -XXX,XX +XXX,XX @@ static void do_armv7m_nvic_set_pending(void *opaque, int irq, bool secure,
28
continue;
27
* Lockup condition due to a guest bug. We don't model
29
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
28
* Lockup, so report via cpu_abort() instead.
30
g_assert(src_reg->opaque == NULL);
29
*/
31
30
- cpu_abort(&s->cpu->parent_obj,
32
/* Create alias before redirection so we dup the right data. */
31
+ cpu_abort(CPU(s->cpu),
33
- if (a->new_key) {
32
"Lockup: can't escalate %d to HardFault "
34
- ARMCPRegInfo *new_reg = g_memdup(src_reg, sizeof(ARMCPRegInfo));
33
"(current priority %d)\n", irq, running);
35
- uint32_t *new_key = g_memdup(&a->new_key, sizeof(uint32_t));
34
}
36
- bool ok;
35
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_lazyfp(NVICState *s, int irq, bool secure)
37
+ new_reg = g_memdup(src_reg, sizeof(ARMCPRegInfo));
36
* We want to escalate to HardFault but the context the
38
+ new_key = g_memdup(&a->new_key, sizeof(uint32_t));
37
* FP state belongs to prevents the exception pre-empting.
39
38
*/
40
- new_reg->name = a->new_name;
39
- cpu_abort(&s->cpu->parent_obj,
41
- new_reg->type |= ARM_CP_ALIAS;
40
+ cpu_abort(CPU(s->cpu),
42
- /* Remove PL1/PL0 access, leaving PL2/PL3 R/W in place. */
41
"Lockup: can't escalate to HardFault during "
43
- new_reg->access &= PL2_RW | PL3_RW;
42
"lazy FP register stacking\n");
44
+ new_reg->name = a->new_name;
43
}
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;
57
--
44
--
58
2.25.1
45
2.34.1
46
47
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Rearrange the values of the enumerators of CPAccessResult
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
so that we may directly extract the target el. For the two
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
special cases in access_check_cp_reg, use CPAccessResult.
6
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20220501055028.646596-3-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
6
---
13
target/arm/cpregs.h | 26 ++++++++++++--------
7
hw/arm/musicpal.c | 4 ----
14
target/arm/op_helper.c | 56 +++++++++++++++++++++---------------------
8
1 file changed, 4 deletions(-)
15
2 files changed, 44 insertions(+), 38 deletions(-)
16
9
17
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
10
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
18
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpregs.h
12
--- a/hw/arm/musicpal.c
20
+++ b/target/arm/cpregs.h
13
+++ b/hw/arm/musicpal.c
21
@@ -XXX,XX +XXX,XX @@ static inline bool cptype_valid(int cptype)
14
@@ -XXX,XX +XXX,XX @@ struct musicpal_key_state {
22
typedef enum CPAccessResult {
15
SysBusDevice parent_obj;
23
/* Access is permitted */
16
/*< public >*/
24
CP_ACCESS_OK = 0,
17
25
+
18
- MemoryRegion iomem;
26
+ /*
19
uint32_t kbd_extended;
27
+ * Combined with one of the following, the low 2 bits indicate the
20
uint32_t pressed_keys;
28
+ * target exception level. If 0, the exception is taken to the usual
21
qemu_irq out[8];
29
+ * target EL (EL1 or PL1 if in EL0, otherwise to the current EL).
22
@@ -XXX,XX +XXX,XX @@ static void musicpal_key_init(Object *obj)
30
+ */
23
DeviceState *dev = DEVICE(sbd);
31
+ CP_ACCESS_EL_MASK = 3,
24
musicpal_key_state *s = MUSICPAL_KEY(dev);
32
+
25
33
/*
26
- memory_region_init(&s->iomem, obj, "dummy", 0);
34
* Access fails due to a configurable trap or enable which would
27
- sysbus_init_mmio(sbd, &s->iomem);
35
* result in a categorized exception syndrome giving information about
28
-
36
* the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6,
29
s->kbd_extended = 0;
37
- * 0xc or 0x18). The exception is taken to the usual target EL (EL1 or
30
s->pressed_keys = 0;
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;
80
}
81
82
/*
83
@@ -XXX,XX +XXX,XX @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
84
mask &= ~((1 << 4) | (1 << 14));
85
86
if (env->cp15.hstr_el2 & mask) {
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)) {
99
return;
100
}
101
102
- switch (ri->accessfn(env, ri, isread)) {
103
- case CP_ACCESS_OK:
104
- return;
105
+ fail:
106
+ switch (res & ~CP_ACCESS_EL_MASK) {
107
case CP_ACCESS_TRAP:
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();
134
}
135
136
-exept:
137
+ target_el = res & CP_ACCESS_EL_MASK;
138
+ switch (target_el) {
139
+ case 0:
140
+ target_el = exception_target_el(env);
141
+ break;
142
+ case 2:
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
}
156
31
157
--
32
--
158
2.25.1
33
2.34.1
159
34
160
35
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Give this enum a name and use in ARMCPRegInfo,
3
Since commit be8d853766 ("iothread: add I/O thread object") we
4
add_cpreg_to_hashtable and define_one_arm_cp_reg_with_opaque.
4
never used IOThreadClass / IOTHREAD_CLASS() / IOTHREAD_GET_CLASS(),
5
remove these definitions.
5
6
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20220501055028.646596-9-richard.henderson@linaro.org
10
Message-id: 20230113200138.52869-2-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
target/arm/cpregs.h | 6 +++---
13
iothread.c | 4 ----
13
target/arm/helper.c | 6 ++++--
14
1 file changed, 4 deletions(-)
14
2 files changed, 7 insertions(+), 5 deletions(-)
15
15
16
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
16
diff --git a/iothread.c b/iothread.c
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpregs.h
18
--- a/iothread.c
19
+++ b/target/arm/cpregs.h
19
+++ b/iothread.c
20
@@ -XXX,XX +XXX,XX @@ enum {
20
@@ -XXX,XX +XXX,XX @@
21
* Note that we rely on the values of these enums as we iterate through
21
#include "qemu/rcu.h"
22
* the various states in some places.
22
#include "qemu/main-loop.h"
23
*/
23
24
-enum {
24
-typedef ObjectClass IOThreadClass;
25
+typedef enum {
25
-
26
ARM_CP_STATE_AA32 = 0,
26
-DECLARE_CLASS_CHECKERS(IOThreadClass, IOTHREAD,
27
ARM_CP_STATE_AA64 = 1,
27
- TYPE_IOTHREAD)
28
ARM_CP_STATE_BOTH = 2,
28
29
-};
29
#ifdef CONFIG_POSIX
30
+} CPState;
30
/* Benchmark results from 2016 on NVMe SSD drives show max polling times around
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)
48
}
49
50
static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
51
- void *opaque, int state, int secstate,
52
+ void *opaque, CPState state, int secstate,
53
int crm, int opc1, int opc2,
54
const char *name)
55
{
56
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
57
* bits; the ARM_CP_64BIT* flag applies only to the AArch32 view of
58
* the register, if any.
59
*/
60
- int crm, opc1, opc2, state;
61
+ int crm, opc1, opc2;
62
int crmmin = (r->crm == CP_ANY) ? 0 : r->crm;
63
int crmmax = (r->crm == CP_ANY) ? 15 : r->crm;
64
int opc1min = (r->opc1 == CP_ANY) ? 0 : r->opc1;
65
int opc1max = (r->opc1 == CP_ANY) ? 7 : r->opc1;
66
int opc2min = (r->opc2 == CP_ANY) ? 0 : r->opc2;
67
int opc2max = (r->opc2 == CP_ANY) ? 7 : r->opc2;
68
+ CPState state;
69
+
70
/* 64 bit registers have only CRm and Opc1 fields */
71
assert(!((r->type & ARM_CP_64BIT) && (r->opc2 || r->crn)));
72
/* op0 only exists in the AArch64 encodings */
73
--
31
--
74
2.25.1
32
2.34.1
75
33
76
34
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Create a typedef as well, and use it in ARMCPRegInfo.
3
QOM *DECLARE* macros expect a typedef as first argument,
4
This won't be perfect for debugging, but it'll nicely
4
not a structure. Replace 'struct IRQState' by 'IRQState'
5
display the most common cases.
5
to avoid when modifying the macros:
6
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
../hw/core/irq.c:29:1: error: declaration of anonymous struct must be a definition
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
DECLARE_INSTANCE_CHECKER(struct IRQState, IRQ,
9
Message-id: 20220501055028.646596-8-richard.henderson@linaro.org
9
^
10
11
Use OBJECT_DECLARE_SIMPLE_TYPE instead of DECLARE_INSTANCE_CHECKER.
12
13
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-id: 20230113200138.52869-3-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
18
---
12
target/arm/cpregs.h | 44 +++++++++++++++++++++++---------------------
19
hw/core/irq.c | 9 ++++-----
13
target/arm/helper.c | 2 +-
20
1 file changed, 4 insertions(+), 5 deletions(-)
14
2 files changed, 24 insertions(+), 22 deletions(-)
15
21
16
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
22
diff --git a/hw/core/irq.c b/hw/core/irq.c
17
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpregs.h
24
--- a/hw/core/irq.c
19
+++ b/target/arm/cpregs.h
25
+++ b/hw/core/irq.c
20
@@ -XXX,XX +XXX,XX @@ enum {
26
@@ -XXX,XX +XXX,XX @@
21
* described with these bits, then use a laxer set of restrictions, and
27
#include "hw/irq.h"
22
* do the more restrictive/complex check inside a helper function.
28
#include "qom/object.h"
23
*/
29
24
-#define PL3_R 0x80
30
-DECLARE_INSTANCE_CHECKER(struct IRQState, IRQ,
25
-#define PL3_W 0x40
31
- TYPE_IRQ)
26
-#define PL2_R (0x20 | PL3_R)
32
+OBJECT_DECLARE_SIMPLE_TYPE(IRQState, IRQ)
27
-#define PL2_W (0x10 | PL3_W)
33
28
-#define PL1_R (0x08 | PL2_R)
34
struct IRQState {
29
-#define PL1_W (0x04 | PL2_W)
35
Object parent_obj;
30
-#define PL0_R (0x02 | PL1_R)
36
@@ -XXX,XX +XXX,XX @@ qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n)
31
-#define PL0_W (0x01 | PL1_W)
37
32
+typedef enum {
38
qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n)
33
+ PL3_R = 0x80,
39
{
34
+ PL3_W = 0x40,
40
- struct IRQState *irq;
35
+ PL2_R = 0x20 | PL3_R,
41
+ IRQState *irq;
36
+ PL2_W = 0x10 | PL3_W,
42
37
+ PL1_R = 0x08 | PL2_R,
43
irq = IRQ(object_new(TYPE_IRQ));
38
+ PL1_W = 0x04 | PL2_W,
44
irq->handler = handler;
39
+ PL0_R = 0x02 | PL1_R,
45
@@ -XXX,XX +XXX,XX @@ void qemu_free_irq(qemu_irq irq)
40
+ PL0_W = 0x01 | PL1_W,
46
41
47
static void qemu_notirq(void *opaque, int line, int level)
42
-/*
48
{
43
- * For user-mode some registers are accessible to EL0 via a kernel
49
- struct IRQState *irq = opaque;
44
- * trap-and-emulate ABI. In this case we define the read permissions
50
+ IRQState *irq = opaque;
45
- * as actually being PL0_R. However some bits of any given register
51
46
- * may still be masked.
52
irq->handler(irq->opaque, irq->n, !level);
47
- */
53
}
48
+ /*
54
@@ -XXX,XX +XXX,XX @@ void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
49
+ * For user-mode some registers are accessible to EL0 via a kernel
55
static const TypeInfo irq_type_info = {
50
+ * trap-and-emulate ABI. In this case we define the read permissions
56
.name = TYPE_IRQ,
51
+ * as actually being PL0_R. However some bits of any given register
57
.parent = TYPE_OBJECT,
52
+ * may still be masked.
58
- .instance_size = sizeof(struct IRQState),
53
+ */
59
+ .instance_size = sizeof(IRQState),
54
#ifdef CONFIG_USER_ONLY
60
};
55
-#define PL0U_R PL0_R
61
56
+ PL0U_R = PL0_R,
62
static void irq_register_types(void)
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
84
index XXXXXXX..XXXXXXX 100644
85
--- a/target/arm/helper.c
86
+++ b/target/arm/helper.c
87
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
88
* to encompass the generic architectural permission check.
89
*/
90
if (r->state != ARM_CP_STATE_AA32) {
91
- int mask = 0;
92
+ CPAccessRights mask;
93
switch (r->opc1) {
94
case 0:
95
/* min_EL EL1, but some accessible to EL0 via kernel ABI */
96
--
63
--
97
2.25.1
64
2.34.1
65
66
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Standardize on g_assert_not_reached() for "should not happen".
3
Missed during automatic conversion from commit 8063396bf3
4
Retain abort() when preceeded by fprintf or error_report.
4
("Use OBJECT_DECLARE_SIMPLE_TYPE when possible").
5
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Message-id: 20220501055028.646596-7-richard.henderson@linaro.org
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20230113200138.52869-4-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/helper.c | 7 +++----
12
include/hw/or-irq.h | 3 +--
12
target/arm/hvf/hvf.c | 2 +-
13
1 file changed, 1 insertion(+), 2 deletions(-)
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(-)
20
14
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/include/hw/or-irq.h b/include/hw/or-irq.h
22
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/helper.c
17
--- a/include/hw/or-irq.h
24
+++ b/target/arm/helper.c
18
+++ b/include/hw/or-irq.h
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 @@
19
@@ -XXX,XX +XXX,XX @@
71
20
72
bool write_kvmstate_to_list(ARMCPU *cpu)
21
typedef struct OrIRQState qemu_or_irq;
73
{
22
74
- abort();
23
-DECLARE_INSTANCE_CHECKER(qemu_or_irq, OR_IRQ,
75
+ g_assert_not_reached();
24
- TYPE_OR_IRQ)
76
}
25
+OBJECT_DECLARE_SIMPLE_TYPE(OrIRQState, OR_IRQ)
77
26
78
bool write_list_to_kvmstate(ARMCPU *cpu, int level)
27
struct OrIRQState {
79
{
28
DeviceState parent_obj;
80
- abort();
81
+ g_assert_not_reached();
82
}
83
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/target/arm/kvm.c
86
+++ b/target/arm/kvm.c
87
@@ -XXX,XX +XXX,XX @@ bool write_kvmstate_to_list(ARMCPU *cpu)
88
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
89
break;
90
default:
91
- abort();
92
+ g_assert_not_reached();
93
}
94
if (ret) {
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
}
125
}
126
127
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
128
index XXXXXXX..XXXXXXX 100644
129
--- a/target/arm/translate-a64.c
130
+++ b/target/arm/translate-a64.c
131
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn)
132
gen_helper_advsimd_rinth(tcg_res, tcg_op, fpst);
133
break;
134
default:
135
- abort();
136
+ g_assert_not_reached();
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);
184
--
29
--
185
2.25.1
30
2.34.1
31
32
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Give this enum a name and use in ARMCPRegInfo and add_cpreg_to_hashtable.
3
OBJECT_DECLARE_SIMPLE_TYPE() macro provides the OrIRQState
4
Add the enumerator ARM_CP_SECSTATE_BOTH to clarify how 0
4
declaration for free. Besides, the QOM code style is to use
5
is handled in define_one_arm_cp_reg_with_opaque.
5
the structure name as typedef, and QEMU style is to use Camel
6
6
Case, so rename qemu_or_irq as OrIRQState.
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Mechanical change using:
9
Message-id: 20220501055028.646596-10-richard.henderson@linaro.org
9
10
$ sed -i -e 's/qemu_or_irq/OrIRQState/g' $(git grep -l qemu_or_irq)
11
12
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-id: 20230113200138.52869-5-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
17
---
12
target/arm/cpregs.h | 7 ++++---
18
include/hw/arm/armsse.h | 6 +++---
13
target/arm/helper.c | 7 +++++--
19
include/hw/arm/bcm2835_peripherals.h | 2 +-
14
2 files changed, 9 insertions(+), 5 deletions(-)
20
include/hw/arm/exynos4210.h | 4 ++--
15
21
include/hw/arm/stm32f205_soc.h | 2 +-
16
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
22
include/hw/arm/stm32f405_soc.h | 2 +-
17
index XXXXXXX..XXXXXXX 100644
23
include/hw/arm/xlnx-versal.h | 6 +++---
18
--- a/target/arm/cpregs.h
24
include/hw/arm/xlnx-zynqmp.h | 2 +-
19
+++ b/target/arm/cpregs.h
25
include/hw/or-irq.h | 2 --
20
@@ -XXX,XX +XXX,XX @@ typedef enum {
26
hw/arm/exynos4210.c | 4 ++--
21
* registered entry will only have one to identify whether the entry is secure
27
hw/arm/mps2-tz.c | 2 +-
22
* or non-secure.
28
hw/core/or-irq.c | 18 +++++++++---------
29
hw/pci-host/raven.c | 2 +-
30
12 files changed, 25 insertions(+), 27 deletions(-)
31
32
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/include/hw/arm/armsse.h
35
+++ b/include/hw/arm/armsse.h
36
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
37
TZPPC apb_ppc[NUM_INTERNAL_PPCS];
38
TZMPC mpc[IOTS_NUM_MPC];
39
CMSDKAPBTimer timer[3];
40
- qemu_or_irq ppc_irq_orgate;
41
+ OrIRQState ppc_irq_orgate;
42
SplitIRQ sec_resp_splitter;
43
SplitIRQ ppc_irq_splitter[NUM_PPCS];
44
SplitIRQ mpc_irq_splitter[IOTS_NUM_EXP_MPC + IOTS_NUM_MPC];
45
- qemu_or_irq mpc_irq_orgate;
46
- qemu_or_irq nmi_orgate;
47
+ OrIRQState mpc_irq_orgate;
48
+ OrIRQState nmi_orgate;
49
50
SplitIRQ cpu_irq_splitter[NUM_SSE_IRQS];
51
52
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
53
index XXXXXXX..XXXXXXX 100644
54
--- a/include/hw/arm/bcm2835_peripherals.h
55
+++ b/include/hw/arm/bcm2835_peripherals.h
56
@@ -XXX,XX +XXX,XX @@ struct BCM2835PeripheralState {
57
BCM2835AuxState aux;
58
BCM2835FBState fb;
59
BCM2835DMAState dma;
60
- qemu_or_irq orgated_dma_irq;
61
+ OrIRQState orgated_dma_irq;
62
BCM2835ICState ic;
63
BCM2835PropertyState property;
64
BCM2835RngState rng;
65
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
66
index XXXXXXX..XXXXXXX 100644
67
--- a/include/hw/arm/exynos4210.h
68
+++ b/include/hw/arm/exynos4210.h
69
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
70
MemoryRegion boot_secondary;
71
MemoryRegion bootreg_mem;
72
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
73
- qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
74
- qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
75
+ OrIRQState pl330_irq_orgate[EXYNOS4210_NUM_DMA];
76
+ OrIRQState cpu_irq_orgate[EXYNOS4210_NCPUS];
77
A9MPPrivState a9mpcore;
78
Exynos4210GicState ext_gic;
79
Exynos4210CombinerState int_combiner;
80
diff --git a/include/hw/arm/stm32f205_soc.h b/include/hw/arm/stm32f205_soc.h
81
index XXXXXXX..XXXXXXX 100644
82
--- a/include/hw/arm/stm32f205_soc.h
83
+++ b/include/hw/arm/stm32f205_soc.h
84
@@ -XXX,XX +XXX,XX @@ struct STM32F205State {
85
STM32F2XXADCState adc[STM_NUM_ADCS];
86
STM32F2XXSPIState spi[STM_NUM_SPIS];
87
88
- qemu_or_irq *adc_irqs;
89
+ OrIRQState *adc_irqs;
90
91
MemoryRegion sram;
92
MemoryRegion flash;
93
diff --git a/include/hw/arm/stm32f405_soc.h b/include/hw/arm/stm32f405_soc.h
94
index XXXXXXX..XXXXXXX 100644
95
--- a/include/hw/arm/stm32f405_soc.h
96
+++ b/include/hw/arm/stm32f405_soc.h
97
@@ -XXX,XX +XXX,XX @@ struct STM32F405State {
98
STM32F4xxExtiState exti;
99
STM32F2XXUsartState usart[STM_NUM_USARTS];
100
STM32F2XXTimerState timer[STM_NUM_TIMERS];
101
- qemu_or_irq adc_irqs;
102
+ OrIRQState adc_irqs;
103
STM32F2XXADCState adc[STM_NUM_ADCS];
104
STM32F2XXSPIState spi[STM_NUM_SPIS];
105
106
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
107
index XXXXXXX..XXXXXXX 100644
108
--- a/include/hw/arm/xlnx-versal.h
109
+++ b/include/hw/arm/xlnx-versal.h
110
@@ -XXX,XX +XXX,XX @@ struct Versal {
111
} rpu;
112
113
struct {
114
- qemu_or_irq irq_orgate;
115
+ OrIRQState irq_orgate;
116
XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
117
} xram;
118
119
@@ -XXX,XX +XXX,XX @@ struct Versal {
120
XlnxCSUDMA dma_src;
121
XlnxCSUDMA dma_dst;
122
MemoryRegion linear_mr;
123
- qemu_or_irq irq_orgate;
124
+ OrIRQState irq_orgate;
125
} ospi;
126
} iou;
127
128
@@ -XXX,XX +XXX,XX @@ struct Versal {
129
XlnxVersalEFuseCtrl efuse_ctrl;
130
XlnxVersalEFuseCache efuse_cache;
131
132
- qemu_or_irq apb_irq_orgate;
133
+ OrIRQState apb_irq_orgate;
134
} pmc;
135
136
struct {
137
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
138
index XXXXXXX..XXXXXXX 100644
139
--- a/include/hw/arm/xlnx-zynqmp.h
140
+++ b/include/hw/arm/xlnx-zynqmp.h
141
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
142
XlnxZDMA gdma[XLNX_ZYNQMP_NUM_GDMA_CH];
143
XlnxZDMA adma[XLNX_ZYNQMP_NUM_ADMA_CH];
144
XlnxCSUDMA qspi_dma;
145
- qemu_or_irq qspi_irq_orgate;
146
+ OrIRQState qspi_irq_orgate;
147
XlnxZynqMPAPUCtrl apu_ctrl;
148
XlnxZynqMPCRF crf;
149
CadenceTTCState ttc[XLNX_ZYNQMP_NUM_TTC];
150
diff --git a/include/hw/or-irq.h b/include/hw/or-irq.h
151
index XXXXXXX..XXXXXXX 100644
152
--- a/include/hw/or-irq.h
153
+++ b/include/hw/or-irq.h
154
@@ -XXX,XX +XXX,XX @@
23
*/
155
*/
24
-enum {
156
#define MAX_OR_LINES 48
25
+typedef enum {
157
26
+ ARM_CP_SECSTATE_BOTH = 0, /* define one cpreg for each secstate */
158
-typedef struct OrIRQState qemu_or_irq;
27
ARM_CP_SECSTATE_S = (1 << 0), /* bit[0]: Secure state register */
159
-
28
ARM_CP_SECSTATE_NS = (1 << 1), /* bit[1]: Non-secure state register */
160
OBJECT_DECLARE_SIMPLE_TYPE(OrIRQState, OR_IRQ)
29
-};
161
30
+} CPSecureState;
162
struct OrIRQState {
31
163
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
32
/*
164
index XXXXXXX..XXXXXXX 100644
33
* Access rights:
165
--- a/hw/arm/exynos4210.c
34
@@ -XXX,XX +XXX,XX @@ struct ARMCPRegInfo {
166
+++ b/hw/arm/exynos4210.c
35
/* Access rights: PL*_[RW] */
167
@@ -XXX,XX +XXX,XX @@ static uint64_t exynos4210_calc_affinity(int cpu)
36
CPAccessRights access;
168
return (0x9 << ARM_AFF1_SHIFT) | cpu;
37
/* Security state: ARM_CP_SECSTATE_* bits/values */
38
- int secure;
39
+ CPSecureState secure;
40
/*
41
* The opaque pointer passed to define_arm_cp_regs_with_opaque() when
42
* this register was defined: can be used to hand data through to the
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)
48
}
169
}
49
170
50
static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
171
-static DeviceState *pl330_create(uint32_t base, qemu_or_irq *orgate,
51
- void *opaque, CPState state, int secstate,
172
+static DeviceState *pl330_create(uint32_t base, OrIRQState *orgate,
52
+ void *opaque, CPState state,
173
qemu_irq irq, int nreq, int nevents, int width)
53
+ CPSecureState secstate,
174
{
54
int crm, int opc1, int opc2,
175
SysBusDevice *busdev;
55
const char *name)
176
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
56
{
177
57
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
178
for (i = 0; i < ARRAY_SIZE(s->pl330_irq_orgate); i++) {
58
r->secure, crm, opc1, opc2,
179
char *name = g_strdup_printf("pl330-irq-orgate%d", i);
59
r->name);
180
- qemu_or_irq *orgate = &s->pl330_irq_orgate[i];
60
break;
181
+ OrIRQState *orgate = &s->pl330_irq_orgate[i];
61
- default:
182
62
+ case ARM_CP_SECSTATE_BOTH:
183
object_initialize_child(obj, name, orgate, TYPE_OR_IRQ);
63
name = g_strdup_printf("%s_S", r->name);
184
g_free(name);
64
add_cpreg_to_hashtable(cpu, r, opaque, state,
185
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
65
ARM_CP_SECSTATE_S,
186
index XXXXXXX..XXXXXXX 100644
66
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
187
--- a/hw/arm/mps2-tz.c
67
ARM_CP_SECSTATE_NS,
188
+++ b/hw/arm/mps2-tz.c
68
crm, opc1, opc2, r->name);
189
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
69
break;
190
TZMSC msc[4];
70
+ default:
191
CMSDKAPBUART uart[6];
71
+ g_assert_not_reached();
192
SplitIRQ sec_resp_splitter;
72
}
193
- qemu_or_irq uart_irq_orgate;
73
} else {
194
+ OrIRQState uart_irq_orgate;
74
/* AArch64 registers get mapped to non-secure instance
195
DeviceState *lan9118;
196
SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ_MAX];
197
Clock *sysclk;
198
diff --git a/hw/core/or-irq.c b/hw/core/or-irq.c
199
index XXXXXXX..XXXXXXX 100644
200
--- a/hw/core/or-irq.c
201
+++ b/hw/core/or-irq.c
202
@@ -XXX,XX +XXX,XX @@
203
204
static void or_irq_handler(void *opaque, int n, int level)
205
{
206
- qemu_or_irq *s = OR_IRQ(opaque);
207
+ OrIRQState *s = OR_IRQ(opaque);
208
int or_level = 0;
209
int i;
210
211
@@ -XXX,XX +XXX,XX @@ static void or_irq_handler(void *opaque, int n, int level)
212
213
static void or_irq_reset(DeviceState *dev)
214
{
215
- qemu_or_irq *s = OR_IRQ(dev);
216
+ OrIRQState *s = OR_IRQ(dev);
217
int i;
218
219
for (i = 0; i < MAX_OR_LINES; i++) {
220
@@ -XXX,XX +XXX,XX @@ static void or_irq_reset(DeviceState *dev)
221
222
static void or_irq_realize(DeviceState *dev, Error **errp)
223
{
224
- qemu_or_irq *s = OR_IRQ(dev);
225
+ OrIRQState *s = OR_IRQ(dev);
226
227
assert(s->num_lines <= MAX_OR_LINES);
228
229
@@ -XXX,XX +XXX,XX @@ static void or_irq_realize(DeviceState *dev, Error **errp)
230
231
static void or_irq_init(Object *obj)
232
{
233
- qemu_or_irq *s = OR_IRQ(obj);
234
+ OrIRQState *s = OR_IRQ(obj);
235
236
qdev_init_gpio_out(DEVICE(obj), &s->out_irq, 1);
237
}
238
@@ -XXX,XX +XXX,XX @@ static void or_irq_init(Object *obj)
239
240
static bool vmstate_extras_needed(void *opaque)
241
{
242
- qemu_or_irq *s = OR_IRQ(opaque);
243
+ OrIRQState *s = OR_IRQ(opaque);
244
245
return s->num_lines >= OLD_MAX_OR_LINES;
246
}
247
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_or_irq_extras = {
248
.minimum_version_id = 1,
249
.needed = vmstate_extras_needed,
250
.fields = (VMStateField[]) {
251
- VMSTATE_VARRAY_UINT16_UNSAFE(levels, qemu_or_irq, num_lines, 0,
252
+ VMSTATE_VARRAY_UINT16_UNSAFE(levels, OrIRQState, num_lines, 0,
253
vmstate_info_bool, bool),
254
VMSTATE_END_OF_LIST(),
255
},
256
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_or_irq = {
257
.version_id = 1,
258
.minimum_version_id = 1,
259
.fields = (VMStateField[]) {
260
- VMSTATE_BOOL_SUB_ARRAY(levels, qemu_or_irq, 0, OLD_MAX_OR_LINES),
261
+ VMSTATE_BOOL_SUB_ARRAY(levels, OrIRQState, 0, OLD_MAX_OR_LINES),
262
VMSTATE_END_OF_LIST(),
263
},
264
.subsections = (const VMStateDescription*[]) {
265
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_or_irq = {
266
};
267
268
static Property or_irq_properties[] = {
269
- DEFINE_PROP_UINT16("num-lines", qemu_or_irq, num_lines, 1),
270
+ DEFINE_PROP_UINT16("num-lines", OrIRQState, num_lines, 1),
271
DEFINE_PROP_END_OF_LIST(),
272
};
273
274
@@ -XXX,XX +XXX,XX @@ static void or_irq_class_init(ObjectClass *klass, void *data)
275
static const TypeInfo or_irq_type_info = {
276
.name = TYPE_OR_IRQ,
277
.parent = TYPE_DEVICE,
278
- .instance_size = sizeof(qemu_or_irq),
279
+ .instance_size = sizeof(OrIRQState),
280
.instance_init = or_irq_init,
281
.class_init = or_irq_class_init,
282
};
283
diff --git a/hw/pci-host/raven.c b/hw/pci-host/raven.c
284
index XXXXXXX..XXXXXXX 100644
285
--- a/hw/pci-host/raven.c
286
+++ b/hw/pci-host/raven.c
287
@@ -XXX,XX +XXX,XX @@ DECLARE_INSTANCE_CHECKER(PREPPCIState, RAVEN_PCI_HOST_BRIDGE,
288
struct PRePPCIState {
289
PCIHostState parent_obj;
290
291
- qemu_or_irq *or_irq;
292
+ OrIRQState *or_irq;
293
qemu_irq pci_irqs[PCI_NUM_PINS];
294
PCIBus pci_bus;
295
AddressSpace pci_io_as;
75
--
296
--
76
2.25.1
297
2.34.1
298
299
diff view generated by jsdifflib