1
Two small bugfixes, plus most of RTH's refactoring of cpregs
1
Here's another arm pullreq; nothing too exciting in here I think.
2
handling.
3
2
3
thanks
4
-- PMM
4
-- PMM
5
5
6
The following changes since commit 1fba9dc71a170b3a05b9d3272dd8ecfe7f26e215:
6
The following changes since commit 5fee33d97a7f2e95716417bd164f2f5264acd976:
7
7
8
Merge tag 'pull-request-2022-05-04' of https://gitlab.com/thuth/qemu into staging (2022-05-04 08:07:02 -0700)
8
Merge tag 'samuel-thibault' of https://people.debian.org/~sthibault/qemu into staging (2024-04-29 14:34:25 -0700)
9
9
10
are available in the Git repository at:
10
are available in the Git repository at:
11
11
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220505
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240430
13
13
14
for you to fetch changes up to 99a50d1a67c602126fc2b3a4812d3000eba9bf34:
14
for you to fetch changes up to a0c325c4b05cf7815739d6a84e567b95c8c5be7e:
15
15
16
target/arm: read access to performance counters from EL0 (2022-05-05 09:36:22 +0100)
16
tests/qtest : Add testcase for DM163 (2024-04-30 16:05:08 +0100)
17
17
18
----------------------------------------------------------------
18
----------------------------------------------------------------
19
target-arm queue:
19
target-arm queue:
20
* Enable read access to performance counters from EL0
20
* hw/core/clock: allow clock_propagate on child clocks
21
* Enable SCTLR_EL1.BT0 for aarch64-linux-user
21
* hvf: arm: Remove unused PL1_WRITE_MASK define
22
* Refactoring of cpreg handling
22
* target/arm: Restrict translation disabled alignment check to VMSA
23
* docs/system/arm/emulation.rst: Add missing implemented features
24
* target/arm: Enable FEAT_CSV2_3, FEAT_ETS2, FEAT_Spec_FPACC for 'max'
25
* tests/avocado: update sunxi kernel from armbian to 6.6.16
26
* target/arm: Make new CPUs default to 1GHz generic timer
27
* hw/dmax/xlnx_dpdma: fix handling of address_extension descriptor fields
28
* hw/char/stm32l4x5_usart: Fix memory corruption by adding correct class_size
29
* hw/arm/npcm7xx: Store derivative OTP fuse key in little endian
30
* hw/arm: Add DM163 display to B-L475E-IOT01A board
23
31
24
----------------------------------------------------------------
32
----------------------------------------------------------------
25
Alex Zuepke (1):
33
Alexandra Diupina (1):
26
target/arm: read access to performance counters from EL0
34
hw/dmax/xlnx_dpdma: fix handling of address_extension descriptor fields
27
35
28
Richard Henderson (22):
36
Inès Varhol (5):
29
target/arm: Enable SCTLR_EL1.BT0 for aarch64-linux-user
37
hw/display : Add device DM163
30
target/arm: Split out cpregs.h
38
hw/arm : Pass STM32L4x5 SYSCFG gpios to STM32L4x5 SoC
31
target/arm: Reorg CPAccessResult and access_check_cp_reg
39
hw/arm : Create Bl475eMachineState
32
target/arm: Replace sentinels with ARRAY_SIZE in cpregs.h
40
hw/arm : Connect DM163 to B-L475E-IOT01A
33
target/arm: Make some more cpreg data static const
41
tests/qtest : Add testcase for DM163
34
target/arm: Reorg ARMCPRegInfo type field bits
35
target/arm: Avoid bare abort() or assert(0)
36
target/arm: Change cpreg access permissions to enum
37
target/arm: Name CPState type
38
target/arm: Name CPSecureState type
39
target/arm: Drop always-true test in define_arm_vh_e2h_redirects_aliases
40
target/arm: Store cpregs key in the hash table directly
41
target/arm: Merge allocation of the cpreg and its name
42
target/arm: Hoist computation of key in add_cpreg_to_hashtable
43
target/arm: Consolidate cpreg updates in add_cpreg_to_hashtable
44
target/arm: Use bool for is64 and ns in add_cpreg_to_hashtable
45
target/arm: Hoist isbanked computation in add_cpreg_to_hashtable
46
target/arm: Perform override check early in add_cpreg_to_hashtable
47
target/arm: Reformat comments in add_cpreg_to_hashtable
48
target/arm: Remove HOST_BIG_ENDIAN ifdef in add_cpreg_to_hashtable
49
target/arm: Add isar predicates for FEAT_Debugv8p2
50
target/arm: Add isar_feature_{aa64,any}_ras
51
42
52
target/arm/cpregs.h | 453 ++++++++++++++++++++++++++++++++++++++
43
Peter Maydell (10):
53
target/arm/cpu.h | 393 +++------------------------------
44
docs/system/arm/emulation.rst: Add missing implemented features
54
hw/arm/pxa2xx.c | 2 +-
45
target/arm: Enable FEAT_CSV2_3 for -cpu max
55
hw/arm/pxa2xx_pic.c | 2 +-
46
target/arm: Enable FEAT_ETS2 for -cpu max
56
hw/intc/arm_gicv3_cpuif.c | 6 +-
47
target/arm: Implement ID_AA64MMFR3_EL1
57
hw/intc/arm_gicv3_kvm.c | 3 +-
48
target/arm: Enable FEAT_Spec_FPACC for -cpu max
58
target/arm/cpu.c | 25 +--
49
tests/avocado: update sunxi kernel from armbian to 6.6.16
59
target/arm/cpu64.c | 2 +-
50
target/arm: Refactor default generic timer frequency handling
60
target/arm/cpu_tcg.c | 5 +-
51
hw/arm/sbsa-ref: Force CPU generic timer to 62.5MHz
61
target/arm/gdbstub.c | 5 +-
52
hw/watchdog/sbsa_gwdt: Make watchdog timer frequency a QOM property
62
target/arm/helper.c | 358 +++++++++++++-----------------
53
target/arm: Default to 1GHz cntfrq for 'max' and new CPUs
63
target/arm/hvf/hvf.c | 2 +-
54
64
target/arm/kvm-stub.c | 4 +-
55
Philippe Mathieu-Daudé (1):
65
target/arm/kvm.c | 4 +-
56
hw/arm/npcm7xx: Store derivative OTP fuse key in little endian
66
target/arm/machine.c | 4 +-
57
67
target/arm/op_helper.c | 57 ++---
58
Raphael Poggi (1):
68
target/arm/translate-a64.c | 14 +-
59
hw/core/clock: allow clock_propagate on child clocks
69
target/arm/translate-neon.c | 2 +-
60
70
target/arm/translate.c | 13 +-
61
Richard Henderson (1):
71
tests/tcg/aarch64/bti-3.c | 42 ++++
62
target/arm: Restrict translation disabled alignment check to VMSA
72
tests/tcg/aarch64/Makefile.target | 6 +-
63
73
21 files changed, 738 insertions(+), 664 deletions(-)
64
Thomas Huth (1):
74
create mode 100644 target/arm/cpregs.h
65
hw/char/stm32l4x5_usart: Fix memory corruption by adding correct class_size
75
create mode 100644 tests/tcg/aarch64/bti-3.c
66
67
Zenghui Yu (1):
68
hvf: arm: Remove PL1_WRITE_MASK
69
70
docs/system/arm/b-l475e-iot01a.rst | 3 +-
71
docs/system/arm/emulation.rst | 42 ++++-
72
include/hw/display/dm163.h | 59 ++++++
73
include/hw/watchdog/sbsa_gwdt.h | 3 +-
74
target/arm/cpu.h | 28 +++
75
target/arm/internals.h | 15 +-
76
hw/arm/b-l475e-iot01a.c | 105 +++++++++--
77
hw/arm/npcm7xx.c | 3 +-
78
hw/arm/sbsa-ref.c | 16 ++
79
hw/arm/stm32l4x5_soc.c | 6 +-
80
hw/char/stm32l4x5_usart.c | 1 +
81
hw/core/clock.c | 1 -
82
hw/core/machine.c | 4 +-
83
hw/display/dm163.c | 349 ++++++++++++++++++++++++++++++++++++
84
hw/dma/xlnx_dpdma.c | 20 +--
85
hw/watchdog/sbsa_gwdt.c | 15 +-
86
target/arm/cpu.c | 42 +++--
87
target/arm/cpu64.c | 2 +
88
target/arm/helper.c | 22 +--
89
target/arm/hvf/hvf.c | 3 +-
90
target/arm/kvm.c | 2 +
91
target/arm/tcg/cpu32.c | 6 +-
92
target/arm/tcg/cpu64.c | 28 ++-
93
target/arm/tcg/hflags.c | 12 +-
94
tests/qtest/dm163-test.c | 194 ++++++++++++++++++++
95
tests/qtest/stm32l4x5_gpio-test.c | 13 +-
96
tests/qtest/stm32l4x5_syscfg-test.c | 17 +-
97
hw/arm/Kconfig | 1 +
98
hw/display/Kconfig | 3 +
99
hw/display/meson.build | 1 +
100
hw/display/trace-events | 14 ++
101
tests/avocado/boot_linux_console.py | 70 ++++----
102
tests/avocado/replay_kernel.py | 8 +-
103
tests/qtest/meson.build | 2 +
104
34 files changed, 987 insertions(+), 123 deletions(-)
105
create mode 100644 include/hw/display/dm163.h
106
create mode 100644 hw/display/dm163.c
107
create mode 100644 tests/qtest/dm163-test.c
108
diff view generated by jsdifflib
1
From: Alex Zuepke <alex.zuepke@tum.de>
1
From: Raphael Poggi <raphael.poggi@lynxleap.co.uk>
2
2
3
The ARMv8 manual defines that PMUSERENR_EL0.ER enables read-access
3
clock_propagate() has an assert that clk->source is NULL, i.e. that
4
to both PMXEVCNTR_EL0 and PMEVCNTR<n>_EL0 registers, however,
4
you are calling it on a clock which has no source clock. This made
5
we only use it for PMXEVCNTR_EL0. Extend to PMEVCNTR<n>_EL0 as well.
5
sense in the original design where the only way for a clock's
6
frequency to change if it had a source clock was when that source
7
clock changed. However, we subsequently added multiplier/divider
8
support, but didn't look at what that meant for propagation.
6
9
7
Signed-off-by: Alex Zuepke <alex.zuepke@tum.de>
10
If a clock-management device changes the multiplier or divider value
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
on a clock, it needs to propagate that change down to child clocks,
9
Message-id: 20220428132717.84190-1-alex.zuepke@tum.de
12
even if the clock has a source clock set. So the assertion is now
13
incorrect.
14
15
Remove the assertion.
16
17
Signed-off-by: Raphael Poggi <raphael.poggi@lynxleap.co.uk>
18
Message-id: 20240419162951.23558-1-raphael.poggi@lynxleap.co.uk
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
[PMM: Rewrote the commit message]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
22
---
12
target/arm/helper.c | 4 ++--
23
hw/core/clock.c | 1 -
13
1 file changed, 2 insertions(+), 2 deletions(-)
24
1 file changed, 1 deletion(-)
14
25
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
26
diff --git a/hw/core/clock.c b/hw/core/clock.c
16
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
28
--- a/hw/core/clock.c
18
+++ b/target/arm/helper.c
29
+++ b/hw/core/clock.c
19
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
30
@@ -XXX,XX +XXX,XX @@ static void clock_propagate_period(Clock *clk, bool call_callbacks)
20
.crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
31
21
.access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
32
void clock_propagate(Clock *clk)
22
.readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
33
{
23
- .accessfn = pmreg_access },
34
- assert(clk->source == NULL);
24
+ .accessfn = pmreg_access_xevcntr },
35
trace_clock_propagate(CLOCK_PATH(clk));
25
{ .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
36
clock_propagate_period(clk, true);
26
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 8 | (3 & (i >> 3)),
37
}
27
- .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
28
+ .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access_xevcntr,
29
.type = ARM_CP_IO,
30
.readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
31
.raw_readfn = pmevcntr_rawread,
32
--
38
--
33
2.25.1
39
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Zenghui Yu <zenghui.yu@linux.dev>
2
2
3
Computing isbanked only once makes the code
3
As it had never been used since the first commit a1477da3ddeb ("hvf: Add
4
a bit easier to read.
4
Apple Silicon support").
5
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Zenghui Yu <zenghui.yu@linux.dev>
7
Message-id: 20240422092715.71973-1-zenghui.yu@linux.dev
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20220501055028.646596-17-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 | 6 ++++--
11
target/arm/hvf/hvf.c | 1 -
12
1 file changed, 4 insertions(+), 2 deletions(-)
12
1 file changed, 1 deletion(-)
13
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
16
--- a/target/arm/hvf/hvf.c
17
+++ b/target/arm/helper.c
17
+++ b/target/arm/hvf/hvf.c
18
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
18
@@ -XXX,XX +XXX,XX @@ void hvf_arm_init_debug(void)
19
bool is64 = r->type & ARM_CP_64BIT;
19
20
bool ns = secstate & ARM_CP_SECSTATE_NS;
20
#define HVF_SYSREG(crn, crm, op0, op1, op2) \
21
int cp = r->cp;
21
ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP, crn, crm, op0, op1, op2)
22
+ bool isbanked;
22
-#define PL1_WRITE_MASK 0x4
23
size_t name_len;
23
24
24
#define SYSREG_OP0_SHIFT 20
25
switch (state) {
25
#define SYSREG_OP0_MASK 0x3
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
--
26
--
46
2.25.1
27
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Put the block comments into the current coding style.
3
For cpus using PMSA, when the MPU is disabled, the default memory
4
type is Normal, Non-cachable. This means that it should not
5
have alignment restrictions enforced.
4
6
7
Cc: qemu-stable@nongnu.org
8
Fixes: 59754f85ed3 ("target/arm: Do memory type alignment check when translation disabled")
9
Reported-by: Clément Chigot <chigot@adacore.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20220501055028.646596-19-richard.henderson@linaro.org
12
Tested-by: Clément Chigot <chigot@adacore.com>
13
Message-id: 20240422170722.117409-1-richard.henderson@linaro.org
14
[PMM: trivial comment, commit message tweaks]
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
16
---
10
target/arm/helper.c | 24 +++++++++++++++---------
17
target/arm/tcg/hflags.c | 12 ++++++++++--
11
1 file changed, 15 insertions(+), 9 deletions(-)
18
1 file changed, 10 insertions(+), 2 deletions(-)
12
19
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c
14
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
22
--- a/target/arm/tcg/hflags.c
16
+++ b/target/arm/helper.c
23
+++ b/target/arm/tcg/hflags.c
17
@@ -XXX,XX +XXX,XX @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
24
@@ -XXX,XX +XXX,XX @@ static bool aprofile_require_alignment(CPUARMState *env, int el, uint64_t sctlr)
18
return cpu_list;
19
}
20
21
+/*
22
+ * Private utility function for define_one_arm_cp_reg_with_opaque():
23
+ * add a single reginfo struct to the hash table.
24
+ */
25
static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
26
void *opaque, CPState state,
27
CPSecureState secstate,
28
int crm, int opc1, int opc2,
29
const char *name)
30
{
31
- /* Private utility function for define_one_arm_cp_reg_with_opaque():
32
- * add a single reginfo struct to the hash table.
33
- */
34
uint32_t key;
35
ARMCPRegInfo *r2;
36
bool is64 = r->type & ARM_CP_64BIT;
37
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
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
}
25
}
72
26
73
- /* By convention, for wildcarded registers only the first
27
/*
28
- * If translation is disabled, then the default memory type is
29
- * Device(-nGnRnE) instead of Normal, which requires that alignment
30
+ * With PMSA, when the MPU is disabled, all memory types in the
31
+ * default map are Normal, so don't need aligment enforcing.
32
+ */
33
+ if (arm_feature(env, ARM_FEATURE_PMSA)) {
34
+ return false;
35
+ }
36
+
74
+ /*
37
+ /*
75
+ * By convention, for wildcarded registers only the first
38
+ * With VMSA, if translation is disabled, then the default memory type
76
* entry is used for migration; the others are marked as
39
+ * is Device(-nGnRnE) instead of Normal, which requires that alignment
77
* ALIAS so we don't try to transfer the register
40
* be enforced. Since this affects all ram, it is most efficient
78
* multiple times. Special registers (ie NOP/WFI) are
41
* to handle this during translation.
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
*/
42
*/
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
As of version DDI0487K.a of the Arm ARM, some architectural features
2
which previously didn't have official names have been named. Add
3
these to the list of features which QEMU's TCG emulation supports.
4
Mostly these are features which we thought of as part of baseline 8.0
5
support. For SVE and SVE2, the names have been brought into line
6
with the FEAT_* naming convention of other extensions, and some
7
sub-components split into separate FEAT_ items. In a few cases (eg
8
FEAT_CCIDX, FEAT_DPB2) the omission from our list was just an oversight.
2
9
3
Put most of the value writeback to the same place,
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
and improve the comment that goes with them.
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20240418152004.2106516-2-peter.maydell@linaro.org
13
---
14
docs/system/arm/emulation.rst | 38 +++++++++++++++++++++++++++++++++--
15
1 file changed, 36 insertions(+), 2 deletions(-)
5
16
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20220501055028.646596-15-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/helper.c | 28 ++++++++++++----------------
12
1 file changed, 12 insertions(+), 16 deletions(-)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
19
--- a/docs/system/arm/emulation.rst
17
+++ b/target/arm/helper.c
20
+++ b/docs/system/arm/emulation.rst
18
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
21
@@ -XXX,XX +XXX,XX @@ Armv8 versions of the A-profile architecture. It also has support for
19
*r2 = *r;
22
the following architecture extensions:
20
r2->name = memcpy(r2 + 1, name, name_len);
23
21
24
- FEAT_AA32BF16 (AArch32 BFloat16 instructions)
22
- /* Reset the secure state to the specific incoming state. This is
25
+- FEAT_AA32EL0 (Support for AArch32 at EL0)
23
- * necessary as the register may have been defined with both states.
26
+- FEAT_AA32EL1 (Support for AArch32 at EL1)
24
+ /*
27
+- FEAT_AA32EL2 (Support for AArch32 at EL2)
25
+ * Update fields to match the instantiation, overwiting wildcards
28
+- FEAT_AA32EL3 (Support for AArch32 at EL3)
26
+ * such as CP_ANY, ARM_CP_STATE_BOTH, or ARM_CP_SECSTATE_BOTH.
29
- FEAT_AA32HPD (AArch32 hierarchical permission disables)
27
*/
30
- FEAT_AA32I8MM (AArch32 Int8 matrix multiplication instructions)
28
+ r2->cp = cp;
31
+- FEAT_AA64EL0 (Support for AArch64 at EL0)
29
+ r2->crm = crm;
32
+- FEAT_AA64EL1 (Support for AArch64 at EL1)
30
+ r2->opc1 = opc1;
33
+- FEAT_AA64EL2 (Support for AArch64 at EL2)
31
+ r2->opc2 = opc2;
34
+- FEAT_AA64EL3 (Support for AArch64 at EL3)
32
+ r2->state = state;
35
+- FEAT_AdvSIMD (Advanced SIMD Extension)
33
r2->secure = secstate;
36
- FEAT_AES (AESD and AESE instructions)
34
+ if (opaque) {
37
+- FEAT_Armv9_Crypto (Armv9 Cryptographic Extension)
35
+ r2->opaque = opaque;
38
+- FEAT_ASID16 (16 bit ASID)
36
+ }
39
- FEAT_BBM at level 2 (Translation table break-before-make levels)
37
40
- FEAT_BF16 (AArch64 BFloat16 instructions)
38
if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
41
- FEAT_BTI (Branch Target Identification)
39
/* Register is banked (using both entries in array).
42
+- FEAT_CCIDX (Extended cache index)
40
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
43
- FEAT_CRC32 (CRC32 instructions)
41
#endif
44
+- FEAT_Crypto (Cryptographic Extension)
42
}
45
- FEAT_CSV2 (Cache speculation variant 2)
43
}
46
- FEAT_CSV2_1p1 (Cache speculation variant 2, version 1.1)
44
- if (opaque) {
47
- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
45
- r2->opaque = opaque;
48
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
46
- }
49
- FEAT_DGH (Data gathering hint)
47
- /* reginfo passed to helpers is correct for the actual access,
50
- FEAT_DIT (Data Independent Timing instructions)
48
- * and is never ARM_CP_STATE_BOTH:
51
- FEAT_DPB (DC CVAP instruction)
49
- */
52
+- FEAT_DPB2 (DC CVADP instruction)
50
- r2->state = state;
53
+- FEAT_Debugv8p1 (Debug with VHE)
51
- /* Make sure reginfo passed to helpers for wildcarded regs
54
- FEAT_Debugv8p2 (Debug changes for v8.2)
52
- * has the correct crm/opc1/opc2 for this reg, not CP_ANY:
55
- FEAT_Debugv8p4 (Debug changes for v8.4)
53
- */
56
- FEAT_DotProd (Advanced SIMD dot product instructions)
54
- r2->cp = cp;
57
- FEAT_DoubleFault (Double Fault Extension)
55
- r2->crm = crm;
58
- FEAT_E0PD (Preventing EL0 access to halves of address maps)
56
- r2->opc1 = opc1;
59
- FEAT_ECV (Enhanced Counter Virtualization)
57
- r2->opc2 = opc2;
60
+- FEAT_EL0 (Support for execution at EL0)
58
+
61
+- FEAT_EL1 (Support for execution at EL1)
59
/* By convention, for wildcarded registers only the first
62
+- FEAT_EL2 (Support for execution at EL2)
60
* entry is used for migration; the others are marked as
63
+- FEAT_EL3 (Support for execution at EL3)
61
* ALIAS so we don't try to transfer the register
64
- FEAT_EPAC (Enhanced pointer authentication)
65
- FEAT_ETS (Enhanced Translation Synchronization)
66
- FEAT_EVT (Enhanced Virtualization Traps)
67
+- FEAT_F32MM (Single-precision Matrix Multiplication)
68
+- FEAT_F64MM (Double-precision Matrix Multiplication)
69
- FEAT_FCMA (Floating-point complex number instructions)
70
- FEAT_FGT (Fine-Grained Traps)
71
- FEAT_FHM (Floating-point half-precision multiplication instructions)
72
+- FEAT_FP (Floating Point extensions)
73
- FEAT_FP16 (Half-precision floating-point data processing)
74
- FEAT_FPAC (Faulting on AUT* instructions)
75
- FEAT_FPACCOMBINE (Faulting on combined pointer authentication instructions)
76
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
77
- FEAT_LSE (Large System Extensions)
78
- FEAT_LSE2 (Large System Extensions v2)
79
- FEAT_LVA (Large Virtual Address space)
80
+- FEAT_MixedEnd (Mixed-endian support)
81
+- FEAT_MixdEndEL0 (Mixed-endian support at EL0)
82
- FEAT_MOPS (Standardization of memory operations)
83
- FEAT_MTE (Memory Tagging Extension)
84
- FEAT_MTE2 (Memory Tagging Extension)
85
- FEAT_MTE3 (MTE Asymmetric Fault Handling)
86
+- FEAT_MTE_ASYM_FAULT (Memory tagging asymmetric faults)
87
- FEAT_NMI (Non-maskable Interrupt)
88
- FEAT_NV (Nested Virtualization)
89
- FEAT_NV2 (Enhanced nested virtualization support)
90
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
91
- FEAT_PAuth (Pointer authentication)
92
- FEAT_PAuth2 (Enhancements to pointer authentication)
93
- FEAT_PMULL (PMULL, PMULL2 instructions)
94
+- FEAT_PMUv3 (PMU extension version 3)
95
- FEAT_PMUv3p1 (PMU Extensions v3.1)
96
- FEAT_PMUv3p4 (PMU Extensions v3.4)
97
- FEAT_PMUv3p5 (PMU Extensions v3.5)
98
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
99
- FEAT_SME_FA64 (Full A64 instruction set in Streaming SVE mode)
100
- FEAT_SME_F64F64 (Double-precision floating-point outer product instructions)
101
- FEAT_SME_I16I64 (16-bit to 64-bit integer widening outer product instructions)
102
+- FEAT_SVE (Scalable Vector Extension)
103
+- FEAT_SVE_AES (Scalable Vector AES instructions)
104
+- FEAT_SVE_BitPerm (Scalable Vector Bit Permutes instructions)
105
+- FEAT_SVE_PMULL128 (Scalable Vector PMULL instructions)
106
+- FEAT_SVE_SHA3 (Scalable Vector SHA3 instructions)
107
+- FEAT_SVE_SM4 (Scalable Vector SM4 instructions)
108
+- FEAT_SVE2 (Scalable Vector Extension version 2)
109
- FEAT_SPECRES (Speculation restriction instructions)
110
- FEAT_SSBS (Speculative Store Bypass Safe)
111
+- FEAT_TGran16K (Support for 16KB memory translation granule size at stage 1)
112
+- FEAT_TGran4K (Support for 4KB memory translation granule size at stage 1)
113
+- FEAT_TGran64K (Support for 64KB memory translation granule size at stage 1)
114
- FEAT_TIDCP1 (EL0 use of IMPLEMENTATION DEFINED functionality)
115
- FEAT_TLBIOS (TLB invalidate instructions in Outer Shareable domain)
116
- FEAT_TLBIRANGE (TLB invalidate range instructions)
117
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
118
- FEAT_VHE (Virtualization Host Extensions)
119
- FEAT_VMID16 (16-bit VMID)
120
- FEAT_XNX (Translation table stage 2 Unprivileged Execute-never)
121
-- SVE (The Scalable Vector Extension)
122
-- SVE2 (The Scalable Vector Extension v2)
123
124
For information on the specifics of these extensions, please refer
125
to the `Armv8-A Arm Architecture Reference Manual
62
--
126
--
63
2.25.1
127
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
FEAT_CSV2_3 adds a mechanism to identify if hardware cannot disclose
2
information about whether branch targets and branch history trained
3
in one hardware described context can control speculative execution
4
in a different hardware context.
2
5
3
Bool is a more appropriate type for these variables.
6
There is no branch prediction in TCG, so we don't need to do anything
7
to be compliant with this. Upadte the '-cpu max' ID registers to
8
advertise the feature.
4
9
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20220501055028.646596-16-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Message-id: 20240418152004.2106516-3-peter.maydell@linaro.org
9
---
14
---
10
target/arm/helper.c | 4 ++--
15
docs/system/arm/emulation.rst | 1 +
11
1 file changed, 2 insertions(+), 2 deletions(-)
16
target/arm/tcg/cpu64.c | 4 ++--
17
2 files changed, 3 insertions(+), 2 deletions(-)
12
18
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
21
--- a/docs/system/arm/emulation.rst
16
+++ b/target/arm/helper.c
22
+++ b/docs/system/arm/emulation.rst
17
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
23
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
18
*/
24
- FEAT_CSV2_1p1 (Cache speculation variant 2, version 1.1)
19
uint32_t key;
25
- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
20
ARMCPRegInfo *r2;
26
- FEAT_CSV2_2 (Cache speculation variant 2, version 2)
21
- int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
27
+- FEAT_CSV2_3 (Cache speculation variant 2, version 3)
22
- int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
28
- FEAT_CSV3 (Cache speculation variant 3)
23
+ bool is64 = r->type & ARM_CP_64BIT;
29
- FEAT_DGH (Data gathering hint)
24
+ bool ns = secstate & ARM_CP_SECSTATE_NS;
30
- FEAT_DIT (Data Independent Timing instructions)
25
int cp = r->cp;
31
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
26
size_t name_len;
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/tcg/cpu64.c
34
+++ b/target/arm/tcg/cpu64.c
35
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
36
t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
37
t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); /* FEAT_SEL2 */
38
t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
39
- t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 2); /* FEAT_CSV2_2 */
40
+ t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 3); /* FEAT_CSV2_3 */
41
t = FIELD_DP64(t, ID_AA64PFR0, CSV3, 1); /* FEAT_CSV3 */
42
cpu->isar.id_aa64pfr0 = t;
43
44
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
45
t = FIELD_DP64(t, ID_AA64PFR1, MTE, 3); /* FEAT_MTE3 */
46
t = FIELD_DP64(t, ID_AA64PFR1, RAS_FRAC, 0); /* FEAT_RASv1p1 + FEAT_DoubleFault */
47
t = FIELD_DP64(t, ID_AA64PFR1, SME, 1); /* FEAT_SME */
48
- t = FIELD_DP64(t, ID_AA64PFR1, CSV2_FRAC, 0); /* FEAT_CSV2_2 */
49
+ t = FIELD_DP64(t, ID_AA64PFR1, CSV2_FRAC, 0); /* FEAT_CSV2_3 */
50
t = FIELD_DP64(t, ID_AA64PFR1, NMI, 1); /* FEAT_NMI */
51
cpu->isar.id_aa64pfr1 = t;
27
52
28
--
53
--
29
2.25.1
54
2.34.1
55
56
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
FEAT_ETS2 is a tighter set of guarantees about memory ordering
2
involving translation table walks than the old FEAT_ETS; FEAT_ETS has
3
been retired from the Arm ARM and the old ID_AA64MMFR1.ETS == 1
4
now gives no greater guarantees than ETS == 0.
2
5
3
Move the computation of key to the top of the function.
6
FEAT_ETS2 requires:
4
Hoist the resolution of cp as well, as an input to the
7
* the virtual address of a load or store that appears in program
5
computation of key.
8
order after a DSB cannot be translated until after the DSB
9
completes (section B2.10.9)
10
* TLB maintenance operations that only affect translations without
11
execute permission are guaranteed complete after a DSB
12
(R_BLDZX)
13
* if a memory access RW2 is ordered-before memory access RW2,
14
then RW1 is also ordered-before any translation table walk
15
generated by RW2 that generates a Translation, Address size
16
or Access flag fault (R_NNFPF, I_CLGHP)
6
17
7
This will be required by a subsequent patch.
18
As with FEAT_ETS, QEMU is already compliant, because we do not
19
reorder translation table walk memory accesses relative to other
20
memory accesses, and we always guarantee to have finished TLB
21
maintenance as soon as the TLB op is done.
8
22
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
23
Update the documentation to list FEAT_ETS2 instead of the
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
24
no-longer-existent FEAT_ETS, and update the 'max' CPU ID registers.
11
Message-id: 20220501055028.646596-14-richard.henderson@linaro.org
25
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
28
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
29
Message-id: 20240418152004.2106516-4-peter.maydell@linaro.org
13
---
30
---
14
target/arm/helper.c | 49 +++++++++++++++++++++++++--------------------
31
docs/system/arm/emulation.rst | 2 +-
15
1 file changed, 27 insertions(+), 22 deletions(-)
32
target/arm/tcg/cpu32.c | 2 +-
33
target/arm/tcg/cpu64.c | 2 +-
34
3 files changed, 3 insertions(+), 3 deletions(-)
16
35
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
36
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
18
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
38
--- a/docs/system/arm/emulation.rst
20
+++ b/target/arm/helper.c
39
+++ b/docs/system/arm/emulation.rst
21
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
40
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
22
ARMCPRegInfo *r2;
41
- FEAT_EL2 (Support for execution at EL2)
23
int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
42
- FEAT_EL3 (Support for execution at EL3)
24
int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
43
- FEAT_EPAC (Enhanced pointer authentication)
25
+ int cp = r->cp;
44
-- FEAT_ETS (Enhanced Translation Synchronization)
26
size_t name_len;
45
+- FEAT_ETS2 (Enhanced Translation Synchronization)
27
46
- FEAT_EVT (Enhanced Virtualization Traps)
28
+ switch (state) {
47
- FEAT_F32MM (Single-precision Matrix Multiplication)
29
+ case ARM_CP_STATE_AA32:
48
- FEAT_F64MM (Double-precision Matrix Multiplication)
30
+ /* We assume it is a cp15 register if the .cp field is left unset. */
49
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
31
+ if (cp == 0 && r->state == ARM_CP_STATE_BOTH) {
50
index XXXXXXX..XXXXXXX 100644
32
+ cp = 15;
51
--- a/target/arm/tcg/cpu32.c
33
+ }
52
+++ b/target/arm/tcg/cpu32.c
34
+ key = ENCODE_CP_REG(cp, is64, ns, r->crn, crm, opc1, opc2);
53
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
35
+ break;
54
cpu->isar.id_mmfr4 = t;
36
+ case ARM_CP_STATE_AA64:
55
37
+ /*
56
t = cpu->isar.id_mmfr5;
38
+ * To allow abbreviation of ARMCPRegInfo definitions, we treat
57
- t = FIELD_DP32(t, ID_MMFR5, ETS, 1); /* FEAT_ETS */
39
+ * cp == 0 as equivalent to the value for "standard guest-visible
58
+ t = FIELD_DP32(t, ID_MMFR5, ETS, 2); /* FEAT_ETS2 */
40
+ * sysreg". STATE_BOTH definitions are also always "standard sysreg"
59
cpu->isar.id_mmfr5 = t;
41
+ * in their AArch64 view (the .cp value may be non-zero for the
60
42
+ * benefit of the AArch32 view).
61
t = cpu->isar.id_pfr0;
43
+ */
62
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
44
+ if (cp == 0 || r->state == ARM_CP_STATE_BOTH) {
63
index XXXXXXX..XXXXXXX 100644
45
+ cp = CP_REG_ARM64_SYSREG_CP;
64
--- a/target/arm/tcg/cpu64.c
46
+ }
65
+++ b/target/arm/tcg/cpu64.c
47
+ key = ENCODE_AA64_CP_REG(cp, r->crn, crm, r->opc0, opc1, opc2);
66
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
48
+ break;
67
t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1); /* FEAT_LOR */
49
+ default:
68
t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 3); /* FEAT_PAN3 */
50
+ g_assert_not_reached();
69
t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* FEAT_XNX */
51
+ }
70
- t = FIELD_DP64(t, ID_AA64MMFR1, ETS, 1); /* FEAT_ETS */
52
+
71
+ t = FIELD_DP64(t, ID_AA64MMFR1, ETS, 2); /* FEAT_ETS2 */
53
/* Combine cpreg and name into one allocation. */
72
t = FIELD_DP64(t, ID_AA64MMFR1, HCX, 1); /* FEAT_HCX */
54
name_len = strlen(name) + 1;
73
t = FIELD_DP64(t, ID_AA64MMFR1, TIDCP1, 1); /* FEAT_TIDCP1 */
55
r2 = g_malloc(sizeof(*r2) + name_len);
74
cpu->isar.id_aa64mmfr1 = t;
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
--
75
--
101
2.25.1
76
2.34.1
77
78
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Newer versions of the Arm ARM (e.g. rev K.a) now define fields for
2
ID_AA64MMFR3_EL1. Implement this register, so that we can set the
3
fields if we need to. There's no behaviour change here since we
4
don't currently set the register value to non-zero.
2
5
3
Standardize on g_assert_not_reached() for "should not happen".
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Retain abort() when preceeded by fprintf or error_report.
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 20240418152004.2106516-5-peter.maydell@linaro.org
10
---
11
target/arm/cpu.h | 17 +++++++++++++++++
12
target/arm/helper.c | 6 ++++--
13
target/arm/hvf/hvf.c | 2 ++
14
target/arm/kvm.c | 2 ++
15
4 files changed, 25 insertions(+), 2 deletions(-)
5
16
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
index XXXXXXX..XXXXXXX 100644
8
Message-id: 20220501055028.646596-7-richard.henderson@linaro.org
19
--- a/target/arm/cpu.h
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
+++ b/target/arm/cpu.h
10
---
21
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
11
target/arm/helper.c | 7 +++----
22
uint64_t id_aa64mmfr0;
12
target/arm/hvf/hvf.c | 2 +-
23
uint64_t id_aa64mmfr1;
13
target/arm/kvm-stub.c | 4 ++--
24
uint64_t id_aa64mmfr2;
14
target/arm/kvm.c | 4 ++--
25
+ uint64_t id_aa64mmfr3;
15
target/arm/machine.c | 4 ++--
26
uint64_t id_aa64dfr0;
16
target/arm/translate-a64.c | 4 ++--
27
uint64_t id_aa64dfr1;
17
target/arm/translate-neon.c | 2 +-
28
uint64_t id_aa64zfr0;
18
target/arm/translate.c | 4 ++--
29
@@ -XXX,XX +XXX,XX @@ FIELD(ID_AA64MMFR2, BBM, 52, 4)
19
8 files changed, 15 insertions(+), 16 deletions(-)
30
FIELD(ID_AA64MMFR2, EVT, 56, 4)
20
31
FIELD(ID_AA64MMFR2, E0PD, 60, 4)
32
33
+FIELD(ID_AA64MMFR3, TCRX, 0, 4)
34
+FIELD(ID_AA64MMFR3, SCTLRX, 4, 4)
35
+FIELD(ID_AA64MMFR3, S1PIE, 8, 4)
36
+FIELD(ID_AA64MMFR3, S2PIE, 12, 4)
37
+FIELD(ID_AA64MMFR3, S1POE, 16, 4)
38
+FIELD(ID_AA64MMFR3, S2POE, 20, 4)
39
+FIELD(ID_AA64MMFR3, AIE, 24, 4)
40
+FIELD(ID_AA64MMFR3, MEC, 28, 4)
41
+FIELD(ID_AA64MMFR3, D128, 32, 4)
42
+FIELD(ID_AA64MMFR3, D128_2, 36, 4)
43
+FIELD(ID_AA64MMFR3, SNERR, 40, 4)
44
+FIELD(ID_AA64MMFR3, ANERR, 44, 4)
45
+FIELD(ID_AA64MMFR3, SDERR, 52, 4)
46
+FIELD(ID_AA64MMFR3, ADERR, 56, 4)
47
+FIELD(ID_AA64MMFR3, SPEC_FPACC, 60, 4)
48
+
49
FIELD(ID_AA64DFR0, DEBUGVER, 0, 4)
50
FIELD(ID_AA64DFR0, TRACEVER, 4, 4)
51
FIELD(ID_AA64DFR0, PMUVER, 8, 4)
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
52
diff --git a/target/arm/helper.c b/target/arm/helper.c
22
index XXXXXXX..XXXXXXX 100644
53
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/helper.c
54
--- a/target/arm/helper.c
24
+++ b/target/arm/helper.c
55
+++ b/target/arm/helper.c
25
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
56
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
26
break;
57
.access = PL1_R, .type = ARM_CP_CONST,
27
default:
58
.accessfn = access_aa64_tid3,
28
/* broken reginfo with out-of-range opc1 */
59
.resetvalue = cpu->isar.id_aa64mmfr2 },
29
- assert(false);
60
- { .name = "ID_AA64MMFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
30
- break;
61
+ { .name = "ID_AA64MMFR3_EL1", .state = ARM_CP_STATE_AA64,
31
+ g_assert_not_reached();
62
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3,
32
}
63
.access = PL1_R, .type = ARM_CP_CONST,
33
/* assert our permissions are not too lax (stricter is fine) */
64
.accessfn = access_aa64_tid3,
34
assert((r->access & ~mask) == 0);
65
- .resetvalue = 0 },
35
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
66
+ .resetvalue = cpu->isar.id_aa64mmfr3 },
36
break;
67
{ .name = "ID_AA64MMFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
37
default:
68
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 4,
38
/* Never happens, but compiler isn't smart enough to tell. */
69
.access = PL1_R, .type = ARM_CP_CONST,
39
- abort();
70
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
40
+ g_assert_not_reached();
71
.exported_bits = R_ID_AA64MMFR1_AFP_MASK },
41
}
72
{ .name = "ID_AA64MMFR2_EL1",
42
}
73
.exported_bits = R_ID_AA64MMFR2_AT_MASK },
43
*prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
74
+ { .name = "ID_AA64MMFR3_EL1",
44
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
75
+ .exported_bits = 0 },
45
break;
76
{ .name = "ID_AA64MMFR*_EL1_RESERVED",
46
default:
77
.is_glob = true },
47
/* Never happens, but compiler isn't smart enough to tell. */
78
{ .name = "ID_AA64DFR0_EL1",
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
79
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
54
index XXXXXXX..XXXXXXX 100644
80
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/hvf/hvf.c
81
--- a/target/arm/hvf/hvf.c
56
+++ b/target/arm/hvf/hvf.c
82
+++ b/target/arm/hvf/hvf.c
57
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
83
@@ -XXX,XX +XXX,XX @@ static struct hvf_sreg_match hvf_sreg_match[] = {
58
/* we got kicked, no exit to process */
84
#endif
59
return 0;
85
{ HV_SYS_REG_ID_AA64MMFR1_EL1, HVF_SYSREG(0, 7, 3, 0, 1) },
60
default:
86
{ HV_SYS_REG_ID_AA64MMFR2_EL1, HVF_SYSREG(0, 7, 3, 0, 2) },
61
- assert(0);
87
+ /* Add ID_AA64MMFR3_EL1 here when HVF supports it */
62
+ g_assert_not_reached();
88
63
}
89
{ HV_SYS_REG_MDSCR_EL1, HVF_SYSREG(0, 2, 2, 0, 2) },
64
90
{ HV_SYS_REG_SCTLR_EL1, HVF_SYSREG(1, 0, 3, 0, 0) },
65
hvf_sync_vtimer(cpu);
91
@@ -XXX,XX +XXX,XX @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
66
diff --git a/target/arm/kvm-stub.c b/target/arm/kvm-stub.c
92
{ HV_SYS_REG_ID_AA64MMFR0_EL1, &host_isar.id_aa64mmfr0 },
67
index XXXXXXX..XXXXXXX 100644
93
{ HV_SYS_REG_ID_AA64MMFR1_EL1, &host_isar.id_aa64mmfr1 },
68
--- a/target/arm/kvm-stub.c
94
{ HV_SYS_REG_ID_AA64MMFR2_EL1, &host_isar.id_aa64mmfr2 },
69
+++ b/target/arm/kvm-stub.c
95
+ /* Add ID_AA64MMFR3_EL1 here when HVF supports it */
70
@@ -XXX,XX +XXX,XX @@
96
};
71
97
hv_vcpu_t fd;
72
bool write_kvmstate_to_list(ARMCPU *cpu)
98
hv_return_t r = HV_SUCCESS;
73
{
74
- abort();
75
+ g_assert_not_reached();
76
}
77
78
bool write_list_to_kvmstate(ARMCPU *cpu, int level)
79
{
80
- abort();
81
+ g_assert_not_reached();
82
}
83
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
99
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
84
index XXXXXXX..XXXXXXX 100644
100
index XXXXXXX..XXXXXXX 100644
85
--- a/target/arm/kvm.c
101
--- a/target/arm/kvm.c
86
+++ b/target/arm/kvm.c
102
+++ b/target/arm/kvm.c
87
@@ -XXX,XX +XXX,XX @@ bool write_kvmstate_to_list(ARMCPU *cpu)
103
@@ -XXX,XX +XXX,XX @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
88
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
104
ARM64_SYS_REG(3, 0, 0, 7, 1));
89
break;
105
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr2,
90
default:
106
ARM64_SYS_REG(3, 0, 0, 7, 2));
91
- abort();
107
+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr3,
92
+ g_assert_not_reached();
108
+ ARM64_SYS_REG(3, 0, 0, 7, 3));
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
109
117
/*
110
/*
118
@@ -XXX,XX +XXX,XX @@ static int cpu_pre_save(void *opaque)
111
* Note that if AArch32 support is not present in the host,
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
--
112
--
185
2.25.1
113
2.34.1
114
115
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
FEAT_Spec_FPACC is a feature describing speculative behaviour in the
2
event of a PAC authontication failure when FEAT_FPACCOMBINE is
3
implemented. FEAT_Spec_FPACC means that the speculative use of
4
pointers processed by a PAC Authentication is not materially
5
different in terms of the impact on cached microarchitectural state
6
(caches, TLBs, etc) between passing and failing of the PAC
7
Authentication.
2
8
3
Simplify freeing cp_regs hash table entries by using a single
9
QEMU doesn't do speculative execution, so we can advertise
4
allocation for the entire value.
10
this feature.
5
11
6
This fixes a theoretical bug if we were to ever free the entire
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
hash table, because we've been installing string literal constants
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
into the cpreg structure in define_arm_vh_e2h_redirects_aliases.
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
However, at present we only free entries created for AArch32
15
Message-id: 20240418152004.2106516-6-peter.maydell@linaro.org
10
wildcard cpregs which get overwritten by more specific cpregs,
16
---
11
so this bug is never exposed.
17
docs/system/arm/emulation.rst | 1 +
18
target/arm/tcg/cpu64.c | 4 ++++
19
2 files changed, 5 insertions(+)
12
20
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
21
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
22
index XXXXXXX..XXXXXXX 100644
15
Message-id: 20220501055028.646596-13-richard.henderson@linaro.org
23
--- a/docs/system/arm/emulation.rst
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
+++ b/docs/system/arm/emulation.rst
17
---
25
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
18
target/arm/cpu.c | 16 +---------------
26
- FEAT_FP16 (Half-precision floating-point data processing)
19
target/arm/helper.c | 10 ++++++++--
27
- FEAT_FPAC (Faulting on AUT* instructions)
20
2 files changed, 9 insertions(+), 17 deletions(-)
28
- FEAT_FPACCOMBINE (Faulting on combined pointer authentication instructions)
29
+- FEAT_FPACC_SPEC (Speculative behavior of combined pointer authentication instructions)
30
- FEAT_FRINTTS (Floating-point to integer instructions)
31
- FEAT_FlagM (Flag manipulation instructions v2)
32
- FEAT_FlagM2 (Enhancements to flag manipulation instructions)
33
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/tcg/cpu64.c
36
+++ b/target/arm/tcg/cpu64.c
37
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
38
t = FIELD_DP64(t, ID_AA64MMFR2, E0PD, 1); /* FEAT_E0PD */
39
cpu->isar.id_aa64mmfr2 = t;
40
41
+ t = cpu->isar.id_aa64mmfr3;
42
+ t = FIELD_DP64(t, ID_AA64MMFR3, SPEC_FPACC, 1); /* FEAT_FPACC_SPEC */
43
+ cpu->isar.id_aa64mmfr3 = t;
44
+
45
t = cpu->isar.id_aa64zfr0;
46
t = FIELD_DP64(t, ID_AA64ZFR0, SVEVER, 1);
47
t = FIELD_DP64(t, ID_AA64ZFR0, AES, 2); /* FEAT_SVE_PMULL128 */
48
--
49
2.34.1
21
50
22
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
51
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.c
25
+++ b/target/arm/cpu.c
26
@@ -XXX,XX +XXX,XX @@ uint64_t arm_cpu_mp_affinity(int idx, uint8_t clustersz)
27
return (Aff1 << ARM_AFF1_SHIFT) | Aff0;
28
}
29
30
-static void cpreg_hashtable_data_destroy(gpointer data)
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
57
--- a/target/arm/helper.c
58
+++ b/target/arm/helper.c
59
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
60
* add a single reginfo struct to the hash table.
61
*/
62
uint32_t key;
63
- ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
64
+ ARMCPRegInfo *r2;
65
int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
66
int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
67
+ size_t name_len;
68
+
69
+ /* Combine cpreg and name into one allocation. */
70
+ name_len = strlen(name) + 1;
71
+ r2 = g_malloc(sizeof(*r2) + name_len);
72
+ *r2 = *r;
73
+ r2->name = memcpy(r2 + 1, name, name_len);
74
75
- r2->name = g_strdup(name);
76
/* Reset the secure state to the specific incoming state. This is
77
* necessary as the register may have been defined with both states.
78
*/
79
--
80
2.25.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The Linux kernel 5.10.16 binary for sunxi has been removed from
2
apt.armbian.com. This means that the avocado tests for these machines
3
will be skipped (status CANCEL) if the old binary isn't present in
4
the avocado cache.
2
5
3
Cast the uint32_t key into a gpointer directly, which
6
Update to 6.6.16, in the same way we did in commit e384db41d8661
4
allows us to avoid allocating storage for each key.
7
when we moved to 5.10.16 in 2021.
5
8
6
Use g_hash_table_lookup when we already have a gpointer
9
Cc: qemu-stable@nongnu.org
7
(e.g. for callbacks like count_cpreg), or when using
10
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2284
8
get_arm_cp_reginfo would require casting away const.
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
13
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
14
Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com>
15
Message-id: 20240415151845.1564201-1-peter.maydell@linaro.org
16
---
17
tests/avocado/boot_linux_console.py | 70 ++++++++++++++---------------
18
tests/avocado/replay_kernel.py | 8 ++--
19
2 files changed, 39 insertions(+), 39 deletions(-)
9
20
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
21
diff --git a/tests/avocado/boot_linux_console.py b/tests/avocado/boot_linux_console.py
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>
14
---
15
target/arm/cpu.c | 4 ++--
16
target/arm/gdbstub.c | 2 +-
17
target/arm/helper.c | 41 ++++++++++++++++++-----------------------
18
3 files changed, 21 insertions(+), 26 deletions(-)
19
20
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
21
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.c
23
--- a/tests/avocado/boot_linux_console.py
23
+++ b/target/arm/cpu.c
24
+++ b/tests/avocado/boot_linux_console.py
24
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_initfn(Object *obj)
25
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_initrd(self):
25
ARMCPU *cpu = ARM_CPU(obj);
26
:avocado: tags=accel:tcg
26
27
"""
27
cpu_set_cpustate_pointers(cpu);
28
deb_url = ('https://apt.armbian.com/pool/main/l/'
28
- cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
29
- 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
29
- g_free, cpreg_hashtable_data_destroy);
30
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
30
+ cpu->cp_regs = g_hash_table_new_full(g_direct_hash, g_direct_equal,
31
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
31
+ NULL, cpreg_hashtable_data_destroy);
32
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
32
33
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
33
QLIST_INIT(&cpu->pre_el_change_hooks);
34
kernel_path = self.extract_from_deb(deb_path,
34
QLIST_INIT(&cpu->el_change_hooks);
35
- '/boot/vmlinuz-5.10.16-sunxi')
35
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
36
- dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
37
+ '/boot/vmlinuz-6.6.16-current-sunxi')
38
+ dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun4i-a10-cubieboard.dtb'
39
dtb_path = self.extract_from_deb(deb_path, dtb_path)
40
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
41
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
42
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_sata(self):
43
:avocado: tags=accel:tcg
44
"""
45
deb_url = ('https://apt.armbian.com/pool/main/l/'
46
- 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
47
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
48
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
49
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
50
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
51
kernel_path = self.extract_from_deb(deb_path,
52
- '/boot/vmlinuz-5.10.16-sunxi')
53
- dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
54
+ '/boot/vmlinuz-6.6.16-current-sunxi')
55
+ dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun4i-a10-cubieboard.dtb'
56
dtb_path = self.extract_from_deb(deb_path, dtb_path)
57
rootfs_url = ('https://github.com/groeck/linux-build-test/raw/'
58
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
59
@@ -XXX,XX +XXX,XX @@ def test_arm_bpim2u(self):
60
:avocado: tags=machine:bpim2u
61
:avocado: tags=accel:tcg
62
"""
63
- deb_url = ('https://apt.armbian.com/pool/main/l/linux-5.10.16-sunxi/'
64
- 'linux-image-current-sunxi_21.02.2_armhf.deb')
65
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
66
+ deb_url = ('https://apt.armbian.com/pool/main/l/'
67
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
68
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
69
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
70
kernel_path = self.extract_from_deb(deb_path,
71
- '/boot/vmlinuz-5.10.16-sunxi')
72
- dtb_path = ('/usr/lib/linux-image-current-sunxi/'
73
+ '/boot/vmlinuz-6.6.16-current-sunxi')
74
+ dtb_path = ('/usr/lib/linux-image-6.6.16-current-sunxi/'
75
'sun8i-r40-bananapi-m2-ultra.dtb')
76
dtb_path = self.extract_from_deb(deb_path, dtb_path)
77
78
@@ -XXX,XX +XXX,XX @@ def test_arm_bpim2u_initrd(self):
79
:avocado: tags=accel:tcg
80
:avocado: tags=machine:bpim2u
81
"""
82
- deb_url = ('https://apt.armbian.com/pool/main/l/linux-5.10.16-sunxi/'
83
- 'linux-image-current-sunxi_21.02.2_armhf.deb')
84
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
85
+ deb_url = ('https://apt.armbian.com/pool/main/l/'
86
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
87
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
88
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
89
kernel_path = self.extract_from_deb(deb_path,
90
- '/boot/vmlinuz-5.10.16-sunxi')
91
- dtb_path = ('/usr/lib/linux-image-current-sunxi/'
92
+ '/boot/vmlinuz-6.6.16-current-sunxi')
93
+ dtb_path = ('/usr/lib/linux-image-6.6.16-current-sunxi/'
94
'sun8i-r40-bananapi-m2-ultra.dtb')
95
dtb_path = self.extract_from_deb(deb_path, dtb_path)
96
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
97
@@ -XXX,XX +XXX,XX @@ def test_arm_bpim2u_gmac(self):
98
"""
99
self.require_netdev('user')
100
101
- deb_url = ('https://apt.armbian.com/pool/main/l/linux-5.10.16-sunxi/'
102
- 'linux-image-current-sunxi_21.02.2_armhf.deb')
103
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
104
+ deb_url = ('https://apt.armbian.com/pool/main/l/'
105
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
106
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
107
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
108
kernel_path = self.extract_from_deb(deb_path,
109
- '/boot/vmlinuz-5.10.16-sunxi')
110
- dtb_path = ('/usr/lib/linux-image-current-sunxi/'
111
+ '/boot/vmlinuz-6.6.16-current-sunxi')
112
+ dtb_path = ('/usr/lib/linux-image-6.6.16-current-sunxi/'
113
'sun8i-r40-bananapi-m2-ultra.dtb')
114
dtb_path = self.extract_from_deb(deb_path, dtb_path)
115
rootfs_url = ('http://storage.kernelci.org/images/rootfs/buildroot/'
116
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi(self):
117
:avocado: tags=accel:tcg
118
"""
119
deb_url = ('https://apt.armbian.com/pool/main/l/'
120
- 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
121
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
122
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
123
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
124
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
125
kernel_path = self.extract_from_deb(deb_path,
126
- '/boot/vmlinuz-5.10.16-sunxi')
127
- dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb'
128
+ '/boot/vmlinuz-6.6.16-current-sunxi')
129
+ dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun8i-h3-orangepi-pc.dtb'
130
dtb_path = self.extract_from_deb(deb_path, dtb_path)
131
132
self.vm.set_console()
133
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_initrd(self):
134
:avocado: tags=machine:orangepi-pc
135
"""
136
deb_url = ('https://apt.armbian.com/pool/main/l/'
137
- 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
138
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
139
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
140
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
141
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
142
kernel_path = self.extract_from_deb(deb_path,
143
- '/boot/vmlinuz-5.10.16-sunxi')
144
- dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb'
145
+ '/boot/vmlinuz-6.6.16-current-sunxi')
146
+ dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun8i-h3-orangepi-pc.dtb'
147
dtb_path = self.extract_from_deb(deb_path, dtb_path)
148
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
149
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
150
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_sd(self):
151
self.require_netdev('user')
152
153
deb_url = ('https://apt.armbian.com/pool/main/l/'
154
- 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
155
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
156
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
157
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
158
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
159
kernel_path = self.extract_from_deb(deb_path,
160
- '/boot/vmlinuz-5.10.16-sunxi')
161
- dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb'
162
+ '/boot/vmlinuz-6.6.16-current-sunxi')
163
+ dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun8i-h3-orangepi-pc.dtb'
164
dtb_path = self.extract_from_deb(deb_path, dtb_path)
165
rootfs_url = ('http://storage.kernelci.org/images/rootfs/buildroot/'
166
'buildroot-baseline/20221116.0/armel/rootfs.ext2.xz')
167
diff --git a/tests/avocado/replay_kernel.py b/tests/avocado/replay_kernel.py
36
index XXXXXXX..XXXXXXX 100644
168
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/gdbstub.c
169
--- a/tests/avocado/replay_kernel.py
38
+++ b/target/arm/gdbstub.c
170
+++ b/tests/avocado/replay_kernel.py
39
@@ -XXX,XX +XXX,XX @@ static void arm_gen_one_xml_sysreg_tag(GString *s, DynamicGDBXMLInfo *dyn_xml,
171
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_initrd(self):
40
static void arm_register_sysreg_for_xml(gpointer key, gpointer value,
172
:avocado: tags=machine:cubieboard
41
gpointer p)
173
"""
42
{
174
deb_url = ('https://apt.armbian.com/pool/main/l/'
43
- uint32_t ri_key = *(uint32_t *)key;
175
- 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
44
+ uint32_t ri_key = (uintptr_t)key;
176
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
45
ARMCPRegInfo *ri = value;
177
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
46
RegisterSysregXmlParam *param = (RegisterSysregXmlParam *)p;
178
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
47
GString *s = param->s;
179
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
48
diff --git a/target/arm/helper.c b/target/arm/helper.c
180
kernel_path = self.extract_from_deb(deb_path,
49
index XXXXXXX..XXXXXXX 100644
181
- '/boot/vmlinuz-5.10.16-sunxi')
50
--- a/target/arm/helper.c
182
- dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
51
+++ b/target/arm/helper.c
183
+ '/boot/vmlinuz-6.6.16-current-sunxi')
52
@@ -XXX,XX +XXX,XX @@ bool write_list_to_cpustate(ARMCPU *cpu)
184
+ dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun4i-a10-cubieboard.dtb'
53
static void add_cpreg_to_list(gpointer key, gpointer opaque)
185
dtb_path = self.extract_from_deb(deb_path, dtb_path)
54
{
186
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
55
ARMCPU *cpu = opaque;
187
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
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
}
167
168
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
--
188
--
179
2.25.1
189
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The generic timer frequency is settable by board code via a QOM
2
property "cntfrq", but otherwise defaults to 62.5MHz. The way this
3
is done includes some complication resulting from how this was
4
originally a fixed value with no QOM property. Clean it up:
2
5
3
Instead of defining ARM_CP_FLAG_MASK to remove flags,
6
* always set cpu->gt_cntfrq_hz to some sensible value, whether
4
define ARM_CP_SPECIAL_MASK to isolate special cases.
7
the CPU has the generic timer or not, and whether it's system
5
Sort the specials to the low bits. Use an enum.
8
or user-only emulation
9
* this means we can always use gt_cntfrq_hz, and never need
10
the old GTIMER_SCALE define
11
* set the default value in exactly one place, in the realize fn
6
12
7
Split the large comment block so as to document each
13
The aim here is to pave the way for handling the ARMv8.6 requirement
8
value separately.
14
that the generic timer frequency is always 1GHz. We're going to do
15
that by having old CPU types keep their legacy-in-QEMU behaviour and
16
having the default for any new CPU types be a 1GHz rather han 62.5MHz
17
cntfrq, so we want the point where the default is decided to be in
18
one place, and in code, not in a DEFINE_PROP_UINT64() initializer.
9
19
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
20
This commit should have no behavioural changes.
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
21
12
Message-id: 20220501055028.646596-6-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Message-id: 20240426122913.3427983-2-peter.maydell@linaro.org
14
---
26
---
15
target/arm/cpregs.h | 130 +++++++++++++++++++++++--------------
27
target/arm/internals.h | 7 ++++---
16
target/arm/cpu.c | 4 +-
28
target/arm/cpu.c | 31 +++++++++++++++++--------------
17
target/arm/helper.c | 4 +-
29
target/arm/helper.c | 16 ++++++++--------
18
target/arm/translate-a64.c | 6 +-
30
3 files changed, 29 insertions(+), 25 deletions(-)
19
target/arm/translate.c | 6 +-
20
5 files changed, 92 insertions(+), 58 deletions(-)
21
31
22
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
32
diff --git a/target/arm/internals.h b/target/arm/internals.h
23
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpregs.h
34
--- a/target/arm/internals.h
25
+++ b/target/arm/cpregs.h
35
+++ b/target/arm/internals.h
26
@@ -XXX,XX +XXX,XX @@
36
@@ -XXX,XX +XXX,XX @@ static inline bool excp_is_internal(int excp)
27
#define TARGET_ARM_CPREGS_H
37
|| excp == EXCP_SEMIHOST;
28
38
}
29
/*
39
30
- * ARMCPRegInfo type field bits. If the SPECIAL bit is set this is a
40
-/* Scale factor for generic timers, ie number of ns per tick.
31
- * special-behaviour cp reg and bits [11..8] indicate what behaviour
41
- * This gives a 62.5MHz timer.
32
- * it has. Otherwise it is a simple cp reg, where CONST indicates that
42
+/*
33
- * TCG can assume the value to be constant (ie load at translate time)
43
+ * Default frequency for the generic timer, in Hz.
34
- * and 64BIT indicates a 64 bit wide coprocessor register. SUPPRESS_TB_END
44
+ * This is 62.5MHz, which gives a 16 ns tick period.
35
- * indicates that the TB should not be ended after a write to this register
36
- * (the default is that the TB ends after cp writes). OVERRIDE permits
37
- * a register definition to override a previous definition for the
38
- * same (cp, is64, crn, crm, opc1, opc2) tuple: either the new or the
39
- * old must have the OVERRIDE bit set.
40
- * ALIAS indicates that this register is an alias view of some underlying
41
- * state which is also visible via another register, and that the other
42
- * register is handling migration and reset; registers marked ALIAS will not be
43
- * migrated but may have their state set by syncing of register state from KVM.
44
- * NO_RAW indicates that this register has no underlying state and does not
45
- * support raw access for state saving/loading; it will not be used for either
46
- * migration or KVM state synchronization. (Typically this is for "registers"
47
- * which are actually used as instructions for cache maintenance and so on.)
48
- * IO indicates that this register does I/O and therefore its accesses
49
- * need to be marked with gen_io_start() and also end the TB. In particular,
50
- * registers which implement clocks or timers require this.
51
- * RAISES_EXC is for when the read or write hook might raise an exception;
52
- * the generated code will synchronize the CPU state before calling the hook
53
- * so that it is safe for the hook to call raise_exception().
54
- * NEWEL is for writes to registers that might change the exception
55
- * level - typically on older ARM chips. For those cases we need to
56
- * re-read the new el when recomputing the translation flags.
57
+ * ARMCPRegInfo type field bits:
58
*/
45
*/
59
-#define ARM_CP_SPECIAL 0x0001
46
-#define GTIMER_SCALE 16
60
-#define ARM_CP_CONST 0x0002
47
+#define GTIMER_DEFAULT_HZ 62500000
61
-#define ARM_CP_64BIT 0x0004
48
62
-#define ARM_CP_SUPPRESS_TB_END 0x0008
49
/* Bit definitions for the v7M CONTROL register */
63
-#define ARM_CP_OVERRIDE 0x0010
50
FIELD(V7M_CONTROL, NPRIV, 0, 1)
64
-#define ARM_CP_ALIAS 0x0020
65
-#define ARM_CP_IO 0x0040
66
-#define ARM_CP_NO_RAW 0x0080
67
-#define ARM_CP_NOP (ARM_CP_SPECIAL | 0x0100)
68
-#define ARM_CP_WFI (ARM_CP_SPECIAL | 0x0200)
69
-#define ARM_CP_NZCV (ARM_CP_SPECIAL | 0x0300)
70
-#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | 0x0400)
71
-#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | 0x0500)
72
-#define ARM_CP_DC_GVA (ARM_CP_SPECIAL | 0x0600)
73
-#define ARM_CP_DC_GZVA (ARM_CP_SPECIAL | 0x0700)
74
-#define ARM_LAST_SPECIAL ARM_CP_DC_GZVA
75
-#define ARM_CP_FPU 0x1000
76
-#define ARM_CP_SVE 0x2000
77
-#define ARM_CP_NO_GDB 0x4000
78
-#define ARM_CP_RAISES_EXC 0x8000
79
-#define ARM_CP_NEWEL 0x10000
80
-/* Mask of only the flag bits in a type field */
81
-#define ARM_CP_FLAG_MASK 0x1f0ff
82
+enum {
83
+ /*
84
+ * Register must be handled specially during translation.
85
+ * The method is one of the values below:
86
+ */
87
+ ARM_CP_SPECIAL_MASK = 0x000f,
88
+ /* Special: no change to PE state: writes ignored, reads ignored. */
89
+ ARM_CP_NOP = 0x0001,
90
+ /* Special: sysreg is WFI, for v5 and v6. */
91
+ ARM_CP_WFI = 0x0002,
92
+ /* Special: sysreg is NZCV. */
93
+ ARM_CP_NZCV = 0x0003,
94
+ /* Special: sysreg is CURRENTEL. */
95
+ ARM_CP_CURRENTEL = 0x0004,
96
+ /* Special: sysreg is DC ZVA or similar. */
97
+ ARM_CP_DC_ZVA = 0x0005,
98
+ ARM_CP_DC_GVA = 0x0006,
99
+ ARM_CP_DC_GZVA = 0x0007,
100
+
101
+ /* Flag: reads produce resetvalue; writes ignored. */
102
+ ARM_CP_CONST = 1 << 4,
103
+ /* Flag: For ARM_CP_STATE_AA32, sysreg is 64-bit. */
104
+ ARM_CP_64BIT = 1 << 5,
105
+ /*
106
+ * Flag: TB should not be ended after a write to this register
107
+ * (the default is that the TB ends after cp writes).
108
+ */
109
+ ARM_CP_SUPPRESS_TB_END = 1 << 6,
110
+ /*
111
+ * Flag: Permit a register definition to override a previous definition
112
+ * for the same (cp, is64, crn, crm, opc1, opc2) tuple: either the new
113
+ * or the old must have the ARM_CP_OVERRIDE bit set.
114
+ */
115
+ ARM_CP_OVERRIDE = 1 << 7,
116
+ /*
117
+ * Flag: Register is an alias view of some underlying state which is also
118
+ * visible via another register, and that the other register is handling
119
+ * migration and reset; registers marked ARM_CP_ALIAS will not be migrated
120
+ * but may have their state set by syncing of register state from KVM.
121
+ */
122
+ ARM_CP_ALIAS = 1 << 8,
123
+ /*
124
+ * Flag: Register does I/O and therefore its accesses need to be marked
125
+ * with gen_io_start() and also end the TB. In particular, registers which
126
+ * implement clocks or timers require this.
127
+ */
128
+ ARM_CP_IO = 1 << 9,
129
+ /*
130
+ * Flag: Register has no underlying state and does not support raw access
131
+ * for state saving/loading; it will not be used for either migration or
132
+ * KVM state synchronization. Typically this is for "registers" which are
133
+ * actually used as instructions for cache maintenance and so on.
134
+ */
135
+ ARM_CP_NO_RAW = 1 << 10,
136
+ /*
137
+ * Flag: The read or write hook might raise an exception; the generated
138
+ * code will synchronize the CPU state before calling the hook so that it
139
+ * is safe for the hook to call raise_exception().
140
+ */
141
+ ARM_CP_RAISES_EXC = 1 << 11,
142
+ /*
143
+ * Flag: Writes to the sysreg might change the exception level - typically
144
+ * on older ARM chips. For those cases we need to re-read the new el when
145
+ * recomputing the translation flags.
146
+ */
147
+ ARM_CP_NEWEL = 1 << 12,
148
+ /*
149
+ * Flag: Access check for this sysreg is identical to accessing FPU state
150
+ * from an instruction: use translation fp_access_check().
151
+ */
152
+ ARM_CP_FPU = 1 << 13,
153
+ /*
154
+ * Flag: Access check for this sysreg is identical to accessing SVE state
155
+ * from an instruction: use translation sve_access_check().
156
+ */
157
+ ARM_CP_SVE = 1 << 14,
158
+ /* Flag: Do not expose in gdb sysreg xml. */
159
+ ARM_CP_NO_GDB = 1 << 15,
160
+};
161
162
/*
163
* Valid values for ARMCPRegInfo state field, indicating which of
164
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
51
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
165
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
166
--- a/target/arm/cpu.c
53
--- a/target/arm/cpu.c
167
+++ b/target/arm/cpu.c
54
+++ b/target/arm/cpu.c
168
@@ -XXX,XX +XXX,XX @@ static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
55
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_initfn(Object *obj)
169
ARMCPRegInfo *ri = value;
56
}
170
ARMCPU *cpu = opaque;
57
}
171
58
172
- if (ri->type & (ARM_CP_SPECIAL | ARM_CP_ALIAS)) {
59
+/*
173
+ if (ri->type & (ARM_CP_SPECIAL_MASK | ARM_CP_ALIAS)) {
60
+ * 0 means "unset, use the default value". That default might vary depending
61
+ * on the CPU type, and is set in the realize fn.
62
+ */
63
static Property arm_cpu_gt_cntfrq_property =
64
- DEFINE_PROP_UINT64("cntfrq", ARMCPU, gt_cntfrq_hz,
65
- NANOSECONDS_PER_SECOND / GTIMER_SCALE);
66
+ DEFINE_PROP_UINT64("cntfrq", ARMCPU, gt_cntfrq_hz, 0);
67
68
static Property arm_cpu_reset_cbar_property =
69
DEFINE_PROP_UINT64("reset-cbar", ARMCPU, reset_cbar, 0);
70
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
174
return;
71
return;
175
}
72
}
176
73
177
@@ -XXX,XX +XXX,XX @@ static void cp_reg_check_reset(gpointer key, gpointer value, gpointer opaque)
74
+ if (!cpu->gt_cntfrq_hz) {
178
ARMCPU *cpu = opaque;
75
+ /*
179
uint64_t oldvalue, newvalue;
76
+ * 0 means "the board didn't set a value, use the default".
180
77
+ * The default value of the generic timer frequency (as seen in
181
- if (ri->type & (ARM_CP_SPECIAL | ARM_CP_ALIAS | ARM_CP_NO_RAW)) {
78
+ * CNTFRQ_EL0) is 62.5MHz, which corresponds to a period of 16ns.
182
+ if (ri->type & (ARM_CP_SPECIAL_MASK | ARM_CP_ALIAS | ARM_CP_NO_RAW)) {
79
+ * This is what you get (a) for a CONFIG_USER_ONLY CPU (b) if the
183
return;
80
+ * board doesn't set it.
81
+ */
82
+ cpu->gt_cntfrq_hz = GTIMER_DEFAULT_HZ;
83
+ }
84
+
85
#ifndef CONFIG_USER_ONLY
86
/* The NVIC and M-profile CPU are two halves of a single piece of
87
* hardware; trying to use one without the other is a command line
88
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
184
}
89
}
185
90
91
{
92
- uint64_t scale;
93
-
94
- if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) {
95
- if (!cpu->gt_cntfrq_hz) {
96
- error_setg(errp, "Invalid CNTFRQ: %"PRId64"Hz",
97
- cpu->gt_cntfrq_hz);
98
- return;
99
- }
100
- scale = gt_cntfrq_period_ns(cpu);
101
- } else {
102
- scale = GTIMER_SCALE;
103
- }
104
+ uint64_t scale = gt_cntfrq_period_ns(cpu);
105
106
cpu->gt_timer[GTIMER_PHYS] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
107
arm_gt_ptimer_cb, cpu);
186
diff --git a/target/arm/helper.c b/target/arm/helper.c
108
diff --git a/target/arm/helper.c b/target/arm/helper.c
187
index XXXXXXX..XXXXXXX 100644
109
index XXXXXXX..XXXXXXX 100644
188
--- a/target/arm/helper.c
110
--- a/target/arm/helper.c
189
+++ b/target/arm/helper.c
111
+++ b/target/arm/helper.c
190
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
112
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
191
* multiple times. Special registers (ie NOP/WFI) are
113
.resetvalue = 0 },
192
* never migratable and not even raw-accessible.
114
};
193
*/
115
194
- if ((r->type & ARM_CP_SPECIAL)) {
116
+static void arm_gt_cntfrq_reset(CPUARMState *env, const ARMCPRegInfo *opaque)
195
+ if (r->type & ARM_CP_SPECIAL_MASK) {
117
+{
196
r2->type |= ARM_CP_NO_RAW;
118
+ ARMCPU *cpu = env_archcpu(env);
197
}
119
+
198
if (((r->crm == CP_ANY) && crm != 0) ||
120
+ cpu->env.cp15.c14_cntfrq = cpu->gt_cntfrq_hz;
199
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
121
+}
200
/* Check that the register definition has enough info to handle
122
+
201
* reads and writes if they are permitted.
123
#ifndef CONFIG_USER_ONLY
202
*/
124
203
- if (!(r->type & (ARM_CP_SPECIAL|ARM_CP_CONST))) {
125
static CPAccessResult gt_cntfrq_access(CPUARMState *env, const ARMCPRegInfo *ri,
204
+ if (!(r->type & (ARM_CP_SPECIAL_MASK | ARM_CP_CONST))) {
126
@@ -XXX,XX +XXX,XX @@ void arm_gt_hvtimer_cb(void *opaque)
205
if (r->access & PL3_R) {
127
gt_recalc_timer(cpu, GTIMER_HYPVIRT);
206
assert((r->fieldoffset ||
128
}
207
(r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
129
208
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
130
-static void arm_gt_cntfrq_reset(CPUARMState *env, const ARMCPRegInfo *opaque)
209
index XXXXXXX..XXXXXXX 100644
131
-{
210
--- a/target/arm/translate-a64.c
132
- ARMCPU *cpu = env_archcpu(env);
211
+++ b/target/arm/translate-a64.c
133
-
212
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
134
- cpu->env.cp15.c14_cntfrq = cpu->gt_cntfrq_hz;
213
}
135
-}
214
136
-
215
/* Handle special cases first */
137
static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
216
- switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
138
/*
217
+ switch (ri->type & ARM_CP_SPECIAL_MASK) {
139
* Note that CNTFRQ is purely reads-as-written for the benefit
218
+ case 0:
140
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
219
+ break;
141
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 0,
220
case ARM_CP_NOP:
142
.type = ARM_CP_CONST, .access = PL0_R /* no PL1_RW in linux-user */,
221
return;
143
.fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq),
222
case ARM_CP_NZCV:
144
- .resetvalue = NANOSECONDS_PER_SECOND / GTIMER_SCALE,
223
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
145
+ .resetfn = arm_gt_cntfrq_reset,
224
}
146
},
225
return;
147
{ .name = "CNTVCT_EL0", .state = ARM_CP_STATE_AA64,
226
default:
148
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 2,
227
- break;
228
+ g_assert_not_reached();
229
}
230
if ((ri->type & ARM_CP_FPU) && !fp_access_check(s)) {
231
return;
232
diff --git a/target/arm/translate.c b/target/arm/translate.c
233
index XXXXXXX..XXXXXXX 100644
234
--- a/target/arm/translate.c
235
+++ b/target/arm/translate.c
236
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
237
}
238
239
/* Handle special cases first */
240
- switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
241
+ switch (ri->type & ARM_CP_SPECIAL_MASK) {
242
+ case 0:
243
+ break;
244
case ARM_CP_NOP:
245
return;
246
case ARM_CP_WFI:
247
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
248
s->base.is_jmp = DISAS_WFI;
249
return;
250
default:
251
- break;
252
+ g_assert_not_reached();
253
}
254
255
if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
256
--
149
--
257
2.25.1
150
2.34.1
151
152
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Currently QEMU CPUs always run with a generic timer counter frequency
2
of 62.5MHz, but ARMv8.6 CPUs will run at 1GHz. For older versions of
3
the TF-A firmware that sbsa-ref runs, the frequency of the generic
4
timer is hardcoded into the firmware, and so if the CPU actually has
5
a different frequency then timers in the guest will be set
6
incorrectly.
2
7
3
Since e03b56863d2bc, our host endian indicator is unconditionally
8
The default frequency used by the 'max' CPU is about to change, so
4
set, which means that we can use a normal C condition.
9
make the sbsa-ref board force the CPU frequency to the value which
10
the firmware expects.
5
11
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Newer versions of TF-A will read the frequency from the CPU's
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
CNTFRQ_EL0 register:
8
Message-id: 20220501055028.646596-20-richard.henderson@linaro.org
14
https://github.com/ARM-software/arm-trusted-firmware/commit/4c77fac98dac0bebc63798aae9101ac865b87148
9
[PMM: quote correct git hash in commit message]
15
so in the longer term we could make this board use the 1GHz
16
frequency. We will need to make sure we update the binaries used
17
by our avocado test
18
Aarch64SbsarefMachine.test_sbsaref_alpine_linux_max_pauth_impdef
19
before we can do that.
20
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
23
Reviewed-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
24
Message-id: 20240426122913.3427983-3-peter.maydell@linaro.org
11
---
25
---
12
target/arm/helper.c | 9 +++------
26
hw/arm/sbsa-ref.c | 15 +++++++++++++++
13
1 file changed, 3 insertions(+), 6 deletions(-)
27
1 file changed, 15 insertions(+)
14
28
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
29
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
16
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
31
--- a/hw/arm/sbsa-ref.c
18
+++ b/target/arm/helper.c
32
+++ b/hw/arm/sbsa-ref.c
19
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
33
@@ -XXX,XX +XXX,XX @@
20
r2->type |= ARM_CP_ALIAS;
34
#define NUM_SMMU_IRQS 4
35
#define NUM_SATA_PORTS 6
36
37
+/*
38
+ * Generic timer frequency in Hz (which drives both the CPU generic timers
39
+ * and the SBSA watchdog-timer). Older versions of the TF-A firmware
40
+ * typically used with sbsa-ref (including the binaries in our Avocado test
41
+ * Aarch64SbsarefMachine.test_sbsaref_alpine_linux_max_pauth_impdef
42
+ * assume it is this value.
43
+ *
44
+ * TODO: this value is not architecturally correct for an Armv8.6 or
45
+ * better CPU, so we should move to 1GHz once the TF-A fix above has
46
+ * made it into a release and into our Avocado test.
47
+ */
48
+#define SBSA_GTIMER_HZ 62500000
49
+
50
enum {
51
SBSA_FLASH,
52
SBSA_MEM,
53
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
54
&error_abort);
21
}
55
}
22
56
23
- if (r->state == ARM_CP_STATE_BOTH) {
57
+ object_property_set_int(cpuobj, "cntfrq", SBSA_GTIMER_HZ, &error_abort);
24
-#if HOST_BIG_ENDIAN
58
+
25
- if (r2->fieldoffset) {
59
object_property_set_link(cpuobj, "memory", OBJECT(sysmem),
26
- r2->fieldoffset += sizeof(uint32_t);
60
&error_abort);
27
- }
28
-#endif
29
+ if (HOST_BIG_ENDIAN &&
30
+ r->state == ARM_CP_STATE_BOTH && r2->fieldoffset) {
31
+ r2->fieldoffset += sizeof(uint32_t);
32
}
33
}
34
61
35
--
62
--
36
2.25.1
63
2.34.1
64
65
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Currently the sbsa_gdwt watchdog device hardcodes its frequency at
2
62.5MHz. In real hardware, this watchdog is supposed to be driven
3
from the system counter, which also drives the CPU generic timers.
4
Newer CPU types (in particular from Armv8.6) should have a CPU
5
generic timer frequency of 1GHz, so we can't leave the watchdog
6
on the old QEMU default of 62.5GHz.
2
7
3
Add the aa64 predicate for detecting RAS support from id registers.
8
Make the frequency a QOM property so it can be set by the board,
4
We already have the aa32 version from the M-profile work.
9
and have our only board that uses this device set that frequency
5
Add the 'any' predicate for testing both aa64 and aa32.
10
to the same value it sets the CPU frequency.
6
11
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-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>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Message-id: 20240426122913.3427983-4-peter.maydell@linaro.org
11
---
15
---
12
target/arm/cpu.h | 10 ++++++++++
16
include/hw/watchdog/sbsa_gwdt.h | 3 +--
13
1 file changed, 10 insertions(+)
17
hw/arm/sbsa-ref.c | 1 +
18
hw/watchdog/sbsa_gwdt.c | 15 ++++++++++++++-
19
3 files changed, 16 insertions(+), 3 deletions(-)
14
20
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
diff --git a/include/hw/watchdog/sbsa_gwdt.h b/include/hw/watchdog/sbsa_gwdt.h
16
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
23
--- a/include/hw/watchdog/sbsa_gwdt.h
18
+++ b/target/arm/cpu.h
24
+++ b/include/hw/watchdog/sbsa_gwdt.h
19
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_aa32_el1(const ARMISARegisters *id)
25
@@ -XXX,XX +XXX,XX @@
20
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, EL1) >= 2;
26
#define SBSA_GWDT_RMMIO_SIZE 0x1000
27
#define SBSA_GWDT_CMMIO_SIZE 0x1000
28
29
-#define SBSA_TIMER_FREQ 62500000 /* Hz */
30
-
31
typedef struct SBSA_GWDTState {
32
/* <private> */
33
SysBusDevice parent_obj;
34
@@ -XXX,XX +XXX,XX @@ typedef struct SBSA_GWDTState {
35
qemu_irq irq;
36
37
QEMUTimer *timer;
38
+ uint64_t freq;
39
40
uint32_t id;
41
uint32_t wcs;
42
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/arm/sbsa-ref.c
45
+++ b/hw/arm/sbsa-ref.c
46
@@ -XXX,XX +XXX,XX @@ static void create_wdt(const SBSAMachineState *sms)
47
SysBusDevice *s = SYS_BUS_DEVICE(dev);
48
int irq = sbsa_ref_irqmap[SBSA_GWDT_WS0];
49
50
+ qdev_prop_set_uint64(dev, "clock-frequency", SBSA_GTIMER_HZ);
51
sysbus_realize_and_unref(s, &error_fatal);
52
sysbus_mmio_map(s, 0, rbase);
53
sysbus_mmio_map(s, 1, cbase);
54
diff --git a/hw/watchdog/sbsa_gwdt.c b/hw/watchdog/sbsa_gwdt.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/watchdog/sbsa_gwdt.c
57
+++ b/hw/watchdog/sbsa_gwdt.c
58
@@ -XXX,XX +XXX,XX @@
59
#include "qemu/osdep.h"
60
#include "sysemu/reset.h"
61
#include "sysemu/watchdog.h"
62
+#include "hw/qdev-properties.h"
63
#include "hw/watchdog/sbsa_gwdt.h"
64
#include "qemu/timer.h"
65
#include "migration/vmstate.h"
66
@@ -XXX,XX +XXX,XX @@ static void sbsa_gwdt_update_timer(SBSA_GWDTState *s, WdtRefreshType rtype)
67
timeout = s->woru;
68
timeout <<= 32;
69
timeout |= s->worl;
70
- timeout = muldiv64(timeout, NANOSECONDS_PER_SECOND, SBSA_TIMER_FREQ);
71
+ timeout = muldiv64(timeout, NANOSECONDS_PER_SECOND, s->freq);
72
timeout += qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
73
74
if ((rtype == EXPLICIT_REFRESH) || ((rtype == TIMEOUT_REFRESH) &&
75
@@ -XXX,XX +XXX,XX @@ static void wdt_sbsa_gwdt_realize(DeviceState *dev, Error **errp)
76
dev);
21
}
77
}
22
78
23
+static inline bool isar_feature_aa64_ras(const ARMISARegisters *id)
79
+static Property wdt_sbsa_gwdt_props[] = {
24
+{
80
+ /*
25
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RAS) != 0;
81
+ * Timer frequency in Hz. This must match the frequency used by
26
+}
82
+ * the CPU's generic timer. Default 62.5Hz matches QEMU's legacy
83
+ * CPU timer frequency default.
84
+ */
85
+ DEFINE_PROP_UINT64("clock-frequency", struct SBSA_GWDTState, freq,
86
+ 62500000),
87
+ DEFINE_PROP_END_OF_LIST(),
88
+};
27
+
89
+
28
static inline bool isar_feature_aa64_sve(const ARMISARegisters *id)
90
static void wdt_sbsa_gwdt_class_init(ObjectClass *klass, void *data)
29
{
91
{
30
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0;
92
DeviceClass *dc = DEVICE_CLASS(klass);
31
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_debugv8p2(const ARMISARegisters *id)
93
@@ -XXX,XX +XXX,XX @@ static void wdt_sbsa_gwdt_class_init(ObjectClass *klass, void *data)
32
return isar_feature_aa64_debugv8p2(id) || isar_feature_aa32_debugv8p2(id);
94
set_bit(DEVICE_CATEGORY_WATCHDOG, dc->categories);
95
dc->vmsd = &vmstate_sbsa_gwdt;
96
dc->desc = "SBSA-compliant generic watchdog device";
97
+ device_class_set_props(dc, wdt_sbsa_gwdt_props);
33
}
98
}
34
99
35
+static inline bool isar_feature_any_ras(const ARMISARegisters *id)
100
static const TypeInfo wdt_sbsa_gwdt_info = {
36
+{
37
+ return isar_feature_aa64_ras(id) || isar_feature_aa32_ras(id);
38
+}
39
+
40
/*
41
* Forward to the above feature tests given an ARMCPU pointer.
42
*/
43
--
101
--
44
2.25.1
102
2.34.1
103
104
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
In previous versions of the Arm architecture, the frequency of the
2
2
generic timers as reported in CNTFRQ_EL0 could be any IMPDEF value,
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
and for QEMU we picked 62.5MHz, giving a timer tick period of 16ns.
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
In Armv8.6, the architecture standardized this frequency to 1GHz.
5
Message-id: 20220501055028.646596-24-richard.henderson@linaro.org
5
6
Because there is no ID register feature field that indicates whether
7
a CPU is v8.6 or that it ought to have this counter frequency, we
8
implement this by changing our default CNTFRQ value for all CPUs,
9
with exceptions for backwards compatibility:
10
11
* CPU types which we already implement will retain the old
12
default value. None of these are v8.6 CPUs, so this is
13
architecturally OK.
14
* CPUs used in versioned machine types with a version of 9.0
15
or earlier will retain the old default value.
16
17
The upshot is that the only CPU type that changes is 'max'; but any
18
new type we add in future (whether v8.6 or not) will also get the new
19
1GHz default.
20
21
It remains the case that the machine model can override the default
22
value via the 'cntfrq' QOM property (regardless of the CPU type).
23
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
27
Message-id: 20240426122913.3427983-5-peter.maydell@linaro.org
7
---
28
---
8
target/arm/cpu.h | 15 +++++++++++++++
29
target/arm/cpu.h | 11 +++++++++++
9
1 file changed, 15 insertions(+)
30
target/arm/internals.h | 12 ++++++++++--
31
hw/core/machine.c | 4 +++-
32
target/arm/cpu.c | 23 +++++++++++++++++------
33
target/arm/cpu64.c | 2 ++
34
target/arm/tcg/cpu32.c | 4 ++++
35
target/arm/tcg/cpu64.c | 18 ++++++++++++++++++
36
7 files changed, 65 insertions(+), 9 deletions(-)
10
37
11
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
38
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
12
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu.h
40
--- a/target/arm/cpu.h
14
+++ b/target/arm/cpu.h
41
+++ b/target/arm/cpu.h
15
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id)
42
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
16
return FIELD_EX32(id->id_pfr2, ID_PFR2, SSBS) != 0;
43
*/
17
}
44
bool host_cpu_probe_failed;
18
45
19
+static inline bool isar_feature_aa32_debugv8p2(const ARMISARegisters *id)
46
+ /* QOM property to indicate we should use the back-compat CNTFRQ default */
20
+{
47
+ bool backcompat_cntfrq;
21
+ return FIELD_EX32(id->id_dfr0, ID_DFR0, COPDBG) >= 8;
22
+}
23
+
48
+
49
/* Specify the number of cores in this CPU cluster. Used for the L2CTLR
50
* register.
51
*/
52
@@ -XXX,XX +XXX,XX @@ enum arm_features {
53
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
54
ARM_FEATURE_M_MAIN, /* M profile Main Extension */
55
ARM_FEATURE_V8_1M, /* M profile extras only in v8.1M and later */
56
+ /*
57
+ * ARM_FEATURE_BACKCOMPAT_CNTFRQ makes the CPU default cntfrq be 62.5MHz
58
+ * if the board doesn't set a value, instead of 1GHz. It is for backwards
59
+ * compatibility and used only with CPU definitions that were already
60
+ * in QEMU before we changed the default. It should not be set on any
61
+ * CPU types added in future.
62
+ */
63
+ ARM_FEATURE_BACKCOMPAT_CNTFRQ, /* 62.5MHz timer default */
64
};
65
66
static inline int arm_feature(CPUARMState *env, int feature)
67
diff --git a/target/arm/internals.h b/target/arm/internals.h
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/arm/internals.h
70
+++ b/target/arm/internals.h
71
@@ -XXX,XX +XXX,XX @@ static inline bool excp_is_internal(int excp)
72
24
/*
73
/*
25
* 64-bit feature tests via id registers.
74
* Default frequency for the generic timer, in Hz.
75
- * This is 62.5MHz, which gives a 16 ns tick period.
76
+ * ARMv8.6 and later CPUs architecturally must use a 1GHz timer; before
77
+ * that it was an IMPDEF choice, and QEMU initially picked 62.5MHz,
78
+ * which gives a 16ns tick period.
79
+ *
80
+ * We will use the back-compat value:
81
+ * - for QEMU CPU types added before we standardized on 1GHz
82
+ * - for versioned machine types with a version of 9.0 or earlier
83
+ * In any case, the machine model may override via the cntfrq property.
26
*/
84
*/
27
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id)
85
-#define GTIMER_DEFAULT_HZ 62500000
28
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SSBS) != 0;
86
+#define GTIMER_DEFAULT_HZ 1000000000
29
}
87
+#define GTIMER_BACKCOMPAT_HZ 62500000
30
88
31
+static inline bool isar_feature_aa64_debugv8p2(const ARMISARegisters *id)
89
/* Bit definitions for the v7M CONTROL register */
32
+{
90
FIELD(V7M_CONTROL, NPRIV, 0, 1)
33
+ return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, DEBUGVER) >= 8;
91
diff --git a/hw/core/machine.c b/hw/core/machine.c
34
+}
92
index XXXXXXX..XXXXXXX 100644
93
--- a/hw/core/machine.c
94
+++ b/hw/core/machine.c
95
@@ -XXX,XX +XXX,XX @@
96
#include "hw/virtio/virtio-iommu.h"
97
#include "audio/audio.h"
98
99
-GlobalProperty hw_compat_9_0[] = {};
100
+GlobalProperty hw_compat_9_0[] = {
101
+ {"arm-cpu", "backcompat-cntfrq", "true" },
102
+};
103
const size_t hw_compat_9_0_len = G_N_ELEMENTS(hw_compat_9_0);
104
105
GlobalProperty hw_compat_8_2[] = {
106
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/cpu.c
109
+++ b/target/arm/cpu.c
110
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
111
112
if (!cpu->gt_cntfrq_hz) {
113
/*
114
- * 0 means "the board didn't set a value, use the default".
115
- * The default value of the generic timer frequency (as seen in
116
- * CNTFRQ_EL0) is 62.5MHz, which corresponds to a period of 16ns.
117
- * This is what you get (a) for a CONFIG_USER_ONLY CPU (b) if the
118
- * board doesn't set it.
119
+ * 0 means "the board didn't set a value, use the default". (We also
120
+ * get here for the CONFIG_USER_ONLY case.)
121
+ * ARMv8.6 and later CPUs architecturally must use a 1GHz timer; before
122
+ * that it was an IMPDEF choice, and QEMU initially picked 62.5MHz,
123
+ * which gives a 16ns tick period.
124
+ *
125
+ * We will use the back-compat value:
126
+ * - for QEMU CPU types added before we standardized on 1GHz
127
+ * - for versioned machine types with a version of 9.0 or earlier
128
*/
129
- cpu->gt_cntfrq_hz = GTIMER_DEFAULT_HZ;
130
+ if (arm_feature(env, ARM_FEATURE_BACKCOMPAT_CNTFRQ) ||
131
+ cpu->backcompat_cntfrq) {
132
+ cpu->gt_cntfrq_hz = GTIMER_BACKCOMPAT_HZ;
133
+ } else {
134
+ cpu->gt_cntfrq_hz = GTIMER_DEFAULT_HZ;
135
+ }
136
}
137
138
#ifndef CONFIG_USER_ONLY
139
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_properties[] = {
140
mp_affinity, ARM64_AFFINITY_INVALID),
141
DEFINE_PROP_INT32("node-id", ARMCPU, node_id, CPU_UNSET_NUMA_NODE_ID),
142
DEFINE_PROP_INT32("core-count", ARMCPU, core_count, -1),
143
+ /* True to default to the backward-compat old CNTFRQ rather than 1Ghz */
144
+ DEFINE_PROP_BOOL("backcompat-cntfrq", ARMCPU, backcompat_cntfrq, false),
145
DEFINE_PROP_END_OF_LIST()
146
};
147
148
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
149
index XXXXXXX..XXXXXXX 100644
150
--- a/target/arm/cpu64.c
151
+++ b/target/arm/cpu64.c
152
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
153
set_feature(&cpu->env, ARM_FEATURE_V8);
154
set_feature(&cpu->env, ARM_FEATURE_NEON);
155
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
156
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
157
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
158
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
159
set_feature(&cpu->env, ARM_FEATURE_EL2);
160
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
161
set_feature(&cpu->env, ARM_FEATURE_V8);
162
set_feature(&cpu->env, ARM_FEATURE_NEON);
163
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
164
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
165
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
166
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
167
set_feature(&cpu->env, ARM_FEATURE_EL2);
168
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
169
index XXXXXXX..XXXXXXX 100644
170
--- a/target/arm/tcg/cpu32.c
171
+++ b/target/arm/tcg/cpu32.c
172
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
173
set_feature(&cpu->env, ARM_FEATURE_NEON);
174
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
175
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
176
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
177
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
178
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
179
set_feature(&cpu->env, ARM_FEATURE_EL2);
180
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
181
set_feature(&cpu->env, ARM_FEATURE_NEON);
182
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
183
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
184
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
185
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
186
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
187
set_feature(&cpu->env, ARM_FEATURE_EL2);
188
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
189
set_feature(&cpu->env, ARM_FEATURE_PMSA);
190
set_feature(&cpu->env, ARM_FEATURE_NEON);
191
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
192
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
193
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
194
set_feature(&cpu->env, ARM_FEATURE_AUXCR);
195
cpu->midr = 0x411fd133; /* r1p3 */
196
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
197
set_feature(&cpu->env, ARM_FEATURE_V8);
198
set_feature(&cpu->env, ARM_FEATURE_NEON);
199
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
200
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
201
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
202
set_feature(&cpu->env, ARM_FEATURE_EL2);
203
set_feature(&cpu->env, ARM_FEATURE_EL3);
204
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
205
index XXXXXXX..XXXXXXX 100644
206
--- a/target/arm/tcg/cpu64.c
207
+++ b/target/arm/tcg/cpu64.c
208
@@ -XXX,XX +XXX,XX @@ static void aarch64_a35_initfn(Object *obj)
209
set_feature(&cpu->env, ARM_FEATURE_V8);
210
set_feature(&cpu->env, ARM_FEATURE_NEON);
211
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
212
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
213
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
214
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
215
set_feature(&cpu->env, ARM_FEATURE_EL2);
216
@@ -XXX,XX +XXX,XX @@ static void aarch64_a55_initfn(Object *obj)
217
set_feature(&cpu->env, ARM_FEATURE_V8);
218
set_feature(&cpu->env, ARM_FEATURE_NEON);
219
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
220
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
221
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
222
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
223
set_feature(&cpu->env, ARM_FEATURE_EL2);
224
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
225
set_feature(&cpu->env, ARM_FEATURE_V8);
226
set_feature(&cpu->env, ARM_FEATURE_NEON);
227
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
228
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
229
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
230
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
231
set_feature(&cpu->env, ARM_FEATURE_EL2);
232
@@ -XXX,XX +XXX,XX @@ static void aarch64_a76_initfn(Object *obj)
233
set_feature(&cpu->env, ARM_FEATURE_V8);
234
set_feature(&cpu->env, ARM_FEATURE_NEON);
235
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
236
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
237
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
238
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
239
set_feature(&cpu->env, ARM_FEATURE_EL2);
240
@@ -XXX,XX +XXX,XX @@ static void aarch64_a64fx_initfn(Object *obj)
241
set_feature(&cpu->env, ARM_FEATURE_V8);
242
set_feature(&cpu->env, ARM_FEATURE_NEON);
243
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
244
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
245
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
246
set_feature(&cpu->env, ARM_FEATURE_EL2);
247
set_feature(&cpu->env, ARM_FEATURE_EL3);
248
@@ -XXX,XX +XXX,XX @@ static void aarch64_neoverse_n1_initfn(Object *obj)
249
set_feature(&cpu->env, ARM_FEATURE_V8);
250
set_feature(&cpu->env, ARM_FEATURE_NEON);
251
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
252
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
253
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
254
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
255
set_feature(&cpu->env, ARM_FEATURE_EL2);
256
@@ -XXX,XX +XXX,XX @@ static void aarch64_neoverse_v1_initfn(Object *obj)
257
set_feature(&cpu->env, ARM_FEATURE_V8);
258
set_feature(&cpu->env, ARM_FEATURE_NEON);
259
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
260
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
261
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
262
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
263
set_feature(&cpu->env, ARM_FEATURE_EL2);
264
@@ -XXX,XX +XXX,XX @@ static void aarch64_a710_initfn(Object *obj)
265
set_feature(&cpu->env, ARM_FEATURE_V8);
266
set_feature(&cpu->env, ARM_FEATURE_NEON);
267
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
268
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
269
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
270
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
271
set_feature(&cpu->env, ARM_FEATURE_EL2);
272
@@ -XXX,XX +XXX,XX @@ static void aarch64_neoverse_n2_initfn(Object *obj)
273
set_feature(&cpu->env, ARM_FEATURE_V8);
274
set_feature(&cpu->env, ARM_FEATURE_NEON);
275
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
276
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
277
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
278
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
279
set_feature(&cpu->env, ARM_FEATURE_EL2);
280
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
281
uint64_t t;
282
uint32_t u;
283
284
+ /*
285
+ * Unset ARM_FEATURE_BACKCOMPAT_CNTFRQ, which we would otherwise default
286
+ * to because we started with aarch64_a57_initfn(). A 'max' CPU might
287
+ * be a v8.6-or-later one, in which case the cntfrq must be 1GHz; and
288
+ * because it is our "may change" CPU type we are OK with it not being
289
+ * backwards-compatible with how it worked in old QEMU.
290
+ */
291
+ unset_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
35
+
292
+
36
static inline bool isar_feature_aa64_sve2(const ARMISARegisters *id)
293
/*
37
{
294
* Reset MIDR so the guest doesn't mistake our 'max' CPU type for a real
38
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SVEVER) != 0;
295
* one and try to apply errata workarounds or use impdef features we
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
--
296
--
52
2.25.1
297
2.34.1
298
299
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Alexandra Diupina <adiupina@astralinux.ru>
2
2
3
The new_key field is always non-zero -- drop the if.
3
The DMA descriptor structures for this device have
4
a set of "address extension" fields which extend the 32
5
bit source addresses with an extra 16 bits to give a
6
48 bit address:
7
https://docs.amd.com/r/en-US/ug1085-zynq-ultrascale-trm/ADDR_EXT-Field
4
8
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
However, we misimplemented this address extension in several ways:
10
* we only extracted 12 bits of the extension fields, not 16
11
* we didn't shift the extension field up far enough
12
* we accidentally did the shift as 32-bit arithmetic, which
13
meant that we would have an overflow instead of setting
14
bits [47:32] of the resulting 64-bit address
15
16
Add a type cast and use extract64() instead of extract32()
17
to avoid integer overflow on addition. Fix bit fields
18
extraction according to documentation.
19
20
Found by Linux Verification Center (linuxtesting.org) with SVACE.
21
22
Cc: qemu-stable@nongnu.org
23
Fixes: d3c6369a96 ("introduce xlnx-dpdma")
24
Signed-off-by: Alexandra Diupina <adiupina@astralinux.ru>
25
Message-id: 20240428181131.23801-1-adiupina@astralinux.ru
26
[PMM: adjusted commit message]
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
27
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20220501055028.646596-11-richard.henderson@linaro.org
8
[PMM: reinstated dropped PL3_RW mask]
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
29
---
11
target/arm/helper.c | 23 +++++++++++------------
30
hw/dma/xlnx_dpdma.c | 20 ++++++++++----------
12
1 file changed, 11 insertions(+), 12 deletions(-)
31
1 file changed, 10 insertions(+), 10 deletions(-)
13
32
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
33
diff --git a/hw/dma/xlnx_dpdma.c b/hw/dma/xlnx_dpdma.c
15
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
35
--- a/hw/dma/xlnx_dpdma.c
17
+++ b/target/arm/helper.c
36
+++ b/hw/dma/xlnx_dpdma.c
18
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
37
@@ -XXX,XX +XXX,XX @@ static uint64_t xlnx_dpdma_desc_get_source_address(DPDMADescriptor *desc,
19
38
20
for (i = 0; i < ARRAY_SIZE(aliases); i++) {
39
switch (frag) {
21
const struct E2HAlias *a = &aliases[i];
40
case 0:
22
- ARMCPRegInfo *src_reg, *dst_reg;
41
- addr = desc->source_address
23
+ ARMCPRegInfo *src_reg, *dst_reg, *new_reg;
42
- + (extract32(desc->address_extension, 16, 12) << 20);
24
+ uint32_t *new_key;
43
+ addr = (uint64_t)desc->source_address
25
+ bool ok;
44
+ + (extract64(desc->address_extension, 16, 16) << 32);
26
45
break;
27
if (a->feature && !a->feature(&cpu->isar)) {
46
case 1:
28
continue;
47
- addr = desc->source_address2
29
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
48
- + (extract32(desc->address_extension_23, 0, 12) << 8);
30
g_assert(src_reg->opaque == NULL);
49
+ addr = (uint64_t)desc->source_address2
31
50
+ + (extract64(desc->address_extension_23, 0, 16) << 32);
32
/* Create alias before redirection so we dup the right data. */
51
break;
33
- if (a->new_key) {
52
case 2:
34
- ARMCPRegInfo *new_reg = g_memdup(src_reg, sizeof(ARMCPRegInfo));
53
- addr = desc->source_address3
35
- uint32_t *new_key = g_memdup(&a->new_key, sizeof(uint32_t));
54
- + (extract32(desc->address_extension_23, 16, 12) << 20);
36
- bool ok;
55
+ addr = (uint64_t)desc->source_address3
37
+ new_reg = g_memdup(src_reg, sizeof(ARMCPRegInfo));
56
+ + (extract64(desc->address_extension_23, 16, 16) << 32);
38
+ new_key = g_memdup(&a->new_key, sizeof(uint32_t));
57
break;
39
58
case 3:
40
- new_reg->name = a->new_name;
59
- addr = desc->source_address4
41
- new_reg->type |= ARM_CP_ALIAS;
60
- + (extract32(desc->address_extension_45, 0, 12) << 8);
42
- /* Remove PL1/PL0 access, leaving PL2/PL3 R/W in place. */
61
+ addr = (uint64_t)desc->source_address4
43
- new_reg->access &= PL2_RW | PL3_RW;
62
+ + (extract64(desc->address_extension_45, 0, 16) << 32);
44
+ new_reg->name = a->new_name;
63
break;
45
+ new_reg->type |= ARM_CP_ALIAS;
64
case 4:
46
+ /* Remove PL1/PL0 access, leaving PL2/PL3 R/W in place. */
65
- addr = desc->source_address5
47
+ new_reg->access &= PL2_RW | PL3_RW;
66
- + (extract32(desc->address_extension_45, 16, 12) << 20);
48
67
+ addr = (uint64_t)desc->source_address5
49
- ok = g_hash_table_insert(cpu->cp_regs, new_key, new_reg);
68
+ + (extract64(desc->address_extension_45, 16, 16) << 32);
50
- g_assert(ok);
69
break;
51
- }
70
default:
52
+ ok = g_hash_table_insert(cpu->cp_regs, new_key, new_reg);
71
addr = 0;
53
+ g_assert(ok);
54
55
src_reg->opaque = dst_reg;
56
src_reg->orig_readfn = src_reg->readfn ?: raw_read;
57
--
72
--
58
2.25.1
73
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
These particular data structures are not modified at runtime.
3
"make check-qtest-aarch64" recently started failing on FreeBSD builds,
4
and valgrind on Linux also detected that there is something fishy with
5
the new stm32l4x5-usart: The code forgot to set the correct class_size
6
here, so the various class_init functions in this file wrote beyond
7
the allocated buffer when setting the subc->type field.
4
8
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Fixes: 4fb37aea7e ("hw/char: Implement STM32L4x5 USART skeleton")
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Thomas Huth <thuth@redhat.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20220501055028.646596-5-richard.henderson@linaro.org
12
Message-id: 20240429075908.36302-1-thuth@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
14
---
11
target/arm/helper.c | 16 ++++++++--------
15
hw/char/stm32l4x5_usart.c | 1 +
12
1 file changed, 8 insertions(+), 8 deletions(-)
16
1 file changed, 1 insertion(+)
13
17
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
diff --git a/hw/char/stm32l4x5_usart.c b/hw/char/stm32l4x5_usart.c
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
20
--- a/hw/char/stm32l4x5_usart.c
17
+++ b/target/arm/helper.c
21
+++ b/hw/char/stm32l4x5_usart.c
18
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
22
@@ -XXX,XX +XXX,XX @@ static const TypeInfo stm32l4x5_usart_types[] = {
19
.resetvalue = cpu->pmceid1 },
23
.parent = TYPE_SYS_BUS_DEVICE,
20
};
24
.instance_size = sizeof(Stm32l4x5UsartBaseState),
21
#ifdef CONFIG_USER_ONLY
25
.instance_init = stm32l4x5_usart_base_init,
22
- ARMCPRegUserSpaceInfo v8_user_idregs[] = {
26
+ .class_size = sizeof(Stm32l4x5UsartBaseClass),
23
+ static const ARMCPRegUserSpaceInfo v8_user_idregs[] = {
27
.class_init = stm32l4x5_usart_base_class_init,
24
{ .name = "ID_AA64PFR0_EL1",
28
.abstract = true,
25
.exported_bits = 0x000f000f00ff0000,
29
}, {
26
.fixed_bits = 0x0000000000000011 },
27
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
28
*/
29
if (arm_feature(env, ARM_FEATURE_EL3)) {
30
if (arm_feature(env, ARM_FEATURE_AARCH64)) {
31
- ARMCPRegInfo nsacr = {
32
+ static const ARMCPRegInfo nsacr = {
33
.name = "NSACR", .type = ARM_CP_CONST,
34
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,
35
.access = PL1_RW, .accessfn = nsacr_access,
36
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
37
};
38
define_one_arm_cp_reg(cpu, &nsacr);
39
} else {
40
- ARMCPRegInfo nsacr = {
41
+ static const ARMCPRegInfo nsacr = {
42
.name = "NSACR",
43
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,
44
.access = PL3_RW | PL1_R,
45
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
46
}
47
} else {
48
if (arm_feature(env, ARM_FEATURE_V8)) {
49
- ARMCPRegInfo nsacr = {
50
+ static const ARMCPRegInfo nsacr = {
51
.name = "NSACR", .type = ARM_CP_CONST,
52
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,
53
.access = PL1_R,
54
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
55
.access = PL1_R, .type = ARM_CP_CONST,
56
.resetvalue = cpu->pmsav7_dregion << 8
57
};
58
- ARMCPRegInfo crn0_wi_reginfo = {
59
+ static const ARMCPRegInfo crn0_wi_reginfo = {
60
.name = "CRN0_WI", .cp = 15, .crn = 0, .crm = CP_ANY,
61
.opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W,
62
.type = ARM_CP_NOP | ARM_CP_OVERRIDE
63
};
64
#ifdef CONFIG_USER_ONLY
65
- ARMCPRegUserSpaceInfo id_v8_user_midr_cp_reginfo[] = {
66
+ static const ARMCPRegUserSpaceInfo id_v8_user_midr_cp_reginfo[] = {
67
{ .name = "MIDR_EL1",
68
.exported_bits = 0x00000000ffffffff },
69
{ .name = "REVIDR_EL1" },
70
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
71
.access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_RAW },
72
};
73
#ifdef CONFIG_USER_ONLY
74
- ARMCPRegUserSpaceInfo mpidr_user_cp_reginfo[] = {
75
+ static const ARMCPRegUserSpaceInfo mpidr_user_cp_reginfo[] = {
76
{ .name = "MPIDR_EL1",
77
.fixed_bits = 0x0000000080000000 },
78
};
79
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
80
}
81
82
if (arm_feature(env, ARM_FEATURE_VBAR)) {
83
- ARMCPRegInfo vbar_cp_reginfo[] = {
84
+ static const ARMCPRegInfo vbar_cp_reginfo[] = {
85
{ .name = "VBAR", .state = ARM_CP_STATE_BOTH,
86
.opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
87
.access = PL1_RW, .writefn = vbar_write,
88
--
30
--
89
2.25.1
31
2.34.1
90
32
91
33
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Remove a possible source of error by removing REGINFO_SENTINEL
3
Use little endian for derivative OTP fuse key.
4
and using ARRAY_SIZE (convinently hidden inside a macro) to
5
find the end of the set of regs being registered or modified.
6
4
7
The space saved by not having the extra array element reduces
5
Cc: qemu-stable@nongnu.org
8
the executable's .data.rel.ro section by about 9k.
6
Fixes: c752bb079b ("hw/nvram: NPCM7xx OTP device model")
9
7
Suggested-by: Avi Fishman <Avi.Fishman@nuvoton.com>
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 20240422125813.1403-1-philmd@linaro.org
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
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>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
12
---
16
target/arm/cpregs.h | 53 +++++++++---------
13
hw/arm/npcm7xx.c | 3 ++-
17
hw/arm/pxa2xx.c | 1 -
14
1 file changed, 2 insertions(+), 1 deletion(-)
18
hw/arm/pxa2xx_pic.c | 1 -
19
hw/intc/arm_gicv3_cpuif.c | 5 --
20
hw/intc/arm_gicv3_kvm.c | 1 -
21
target/arm/cpu64.c | 1 -
22
target/arm/cpu_tcg.c | 4 --
23
target/arm/helper.c | 111 ++++++++------------------------------
24
8 files changed, 48 insertions(+), 129 deletions(-)
25
15
26
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
16
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
27
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/cpregs.h
18
--- a/hw/arm/npcm7xx.c
29
+++ b/target/arm/cpregs.h
19
+++ b/hw/arm/npcm7xx.c
30
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
31
#define ARM_CP_NO_GDB 0x4000
21
#include "hw/qdev-clock.h"
32
#define ARM_CP_RAISES_EXC 0x8000
22
#include "hw/qdev-properties.h"
33
#define ARM_CP_NEWEL 0x10000
23
#include "qapi/error.h"
34
-/* Used only as a terminator for ARMCPRegInfo lists */
24
+#include "qemu/bswap.h"
35
-#define ARM_CP_SENTINEL 0xfffff
25
#include "qemu/units.h"
36
/* Mask of only the flag bits in a type field */
26
#include "sysemu/sysemu.h"
37
#define ARM_CP_FLAG_MASK 0x1f0ff
27
#include "target/arm/cpu-qom.h"
38
28
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_init_fuses(NPCM7xxState *s)
39
@@ -XXX,XX +XXX,XX @@ enum {
29
* The initial mask of disabled modules indicates the chip derivative (e.g.
40
ARM_CP_SECSTATE_NS = (1 << 1), /* bit[1]: Non-secure state register */
30
* NPCM750 or NPCM730).
41
};
31
*/
42
32
- value = tswap32(nc->disabled_modules);
43
-/*
33
+ value = cpu_to_le32(nc->disabled_modules);
44
- * Return true if cptype is a valid type field. This is used to try to
34
npcm7xx_otp_array_write(&s->fuse_array, &value, NPCM7XX_FUSE_DERIVATIVE,
45
- * catch errors where the sentinel has been accidentally left off the end
35
sizeof(value));
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
}
36
}
79
+
80
+void define_arm_cp_regs_with_opaque_len(ARMCPU *cpu, const ARMCPRegInfo *regs,
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
230
{ .name = "L2ECTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 3,
231
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
232
- REGINFO_SENTINEL
233
};
234
235
static void cortex_a7_initfn(Object *obj)
236
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cortexr5_cp_reginfo[] = {
237
.access = PL1_RW, .type = ARM_CP_CONST },
238
{ .name = "DCACHE_INVAL", .cp = 15, .opc1 = 0, .crn = 15, .crm = 5,
239
.opc2 = 0, .access = PL1_W, .type = ARM_CP_NOP },
240
- REGINFO_SENTINEL
241
};
242
243
static void cortex_r5_initfn(Object *obj)
244
diff --git a/target/arm/helper.c b/target/arm/helper.c
245
index XXXXXXX..XXXXXXX 100644
246
--- a/target/arm/helper.c
247
+++ b/target/arm/helper.c
248
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cp_reginfo[] = {
249
.secure = ARM_CP_SECSTATE_S,
250
.fieldoffset = offsetof(CPUARMState, cp15.contextidr_s),
251
.resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
252
- REGINFO_SENTINEL
253
};
254
255
static const ARMCPRegInfo not_v8_cp_reginfo[] = {
256
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v8_cp_reginfo[] = {
257
{ .name = "CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY,
258
.opc1 = 0, .opc2 = CP_ANY, .access = PL1_W,
259
.type = ARM_CP_NOP | ARM_CP_OVERRIDE },
260
- REGINFO_SENTINEL
261
};
262
263
static const ARMCPRegInfo not_v6_cp_reginfo[] = {
264
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v6_cp_reginfo[] = {
265
*/
266
{ .name = "WFI_v5", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = 2,
267
.access = PL1_W, .type = ARM_CP_WFI },
268
- REGINFO_SENTINEL
269
};
270
271
static const ARMCPRegInfo not_v7_cp_reginfo[] = {
272
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v7_cp_reginfo[] = {
273
.opc1 = 0, .opc2 = 0, .access = PL1_RW, .type = ARM_CP_NOP },
274
{ .name = "NMRR", .cp = 15, .crn = 10, .crm = 2,
275
.opc1 = 0, .opc2 = 1, .access = PL1_RW, .type = ARM_CP_NOP },
276
- REGINFO_SENTINEL
277
};
278
279
static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
280
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
281
.crn = 1, .crm = 0, .opc1 = 0, .opc2 = 2, .accessfn = cpacr_access,
282
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.cpacr_el1),
283
.resetfn = cpacr_reset, .writefn = cpacr_write, .readfn = cpacr_read },
284
- REGINFO_SENTINEL
285
};
286
287
typedef struct pm_event {
288
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
289
{ .name = "TLBIMVAA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3,
290
.type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
291
.writefn = tlbimvaa_write },
292
- REGINFO_SENTINEL
293
};
294
295
static const ARMCPRegInfo v7mp_cp_reginfo[] = {
296
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7mp_cp_reginfo[] = {
297
{ .name = "TLBIMVAAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3,
298
.type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
299
.writefn = tlbimvaa_is_write },
300
- REGINFO_SENTINEL
301
};
302
303
static const ARMCPRegInfo pmovsset_cp_reginfo[] = {
304
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmovsset_cp_reginfo[] = {
305
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
306
.writefn = pmovsset_write,
307
.raw_writefn = raw_write },
308
- REGINFO_SENTINEL
309
};
310
311
static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri,
312
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo t2ee_cp_reginfo[] = {
313
{ .name = "TEEHBR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 6, .opc2 = 0,
314
.access = PL0_RW, .fieldoffset = offsetof(CPUARMState, teehbr),
315
.accessfn = teehbr_access, .resetvalue = 0 },
316
- REGINFO_SENTINEL
317
};
318
319
static const ARMCPRegInfo v6k_cp_reginfo[] = {
320
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
321
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrprw_s),
322
offsetoflow32(CPUARMState, cp15.tpidrprw_ns) },
323
.resetvalue = 0 },
324
- REGINFO_SENTINEL
325
};
326
327
#ifndef CONFIG_USER_ONLY
328
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
329
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_SEC].cval),
330
.writefn = gt_sec_cval_write, .raw_writefn = raw_write,
331
},
332
- REGINFO_SENTINEL
333
};
334
335
static CPAccessResult e2h_access(CPUARMState *env, const ARMCPRegInfo *ri,
336
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
337
.access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO,
338
.readfn = gt_virt_cnt_read,
339
},
340
- REGINFO_SENTINEL
341
};
342
343
#endif
344
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vapa_cp_reginfo[] = {
345
.access = PL1_W, .accessfn = ats_access,
346
.writefn = ats_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC },
347
#endif
348
- REGINFO_SENTINEL
349
};
350
351
/* Return basic MPU access permission bits. */
352
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmsav7_cp_reginfo[] = {
353
.fieldoffset = offsetof(CPUARMState, pmsav7.rnr[M_REG_NS]),
354
.writefn = pmsav7_rgnr_write,
355
.resetfn = arm_cp_reset_ignore },
356
- REGINFO_SENTINEL
357
};
358
359
static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
360
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
361
{ .name = "946_PRBS7", .cp = 15, .crn = 6, .crm = 7, .opc1 = 0,
362
.opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
363
.fieldoffset = offsetof(CPUARMState, cp15.c6_region[7]) },
364
- REGINFO_SENTINEL
365
};
366
367
static void vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
368
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_pmsa_cp_reginfo[] = {
369
.access = PL1_RW, .accessfn = access_tvm_trvm,
370
.fieldoffset = offsetof(CPUARMState, cp15.far_el[1]),
371
.resetvalue = 0, },
372
- REGINFO_SENTINEL
373
};
374
375
static const ARMCPRegInfo vmsa_cp_reginfo[] = {
376
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
377
/* No offsetoflow32 -- pass the entire TCR to writefn/raw_writefn. */
378
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.tcr_el[3]),
379
offsetof(CPUARMState, cp15.tcr_el[1])} },
380
- REGINFO_SENTINEL
381
};
382
383
/* Note that unlike TTBCR, writing to TTBCR2 does not require flushing
384
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo omap_cp_reginfo[] = {
385
{ .name = "C9", .cp = 15, .crn = 9,
386
.crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW,
387
.type = ARM_CP_CONST | ARM_CP_OVERRIDE, .resetvalue = 0 },
388
- REGINFO_SENTINEL
389
};
390
391
static void xscale_cpar_write(CPUARMState *env, const ARMCPRegInfo *ri,
392
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo xscale_cp_reginfo[] = {
393
{ .name = "XSCALE_UNLOCK_DCACHE",
394
.cp = 15, .opc1 = 0, .crn = 9, .crm = 2, .opc2 = 1,
395
.access = PL1_W, .type = ARM_CP_NOP },
396
- REGINFO_SENTINEL
397
};
398
399
static const ARMCPRegInfo dummy_c15_cp_reginfo[] = {
400
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo dummy_c15_cp_reginfo[] = {
401
.access = PL1_RW,
402
.type = ARM_CP_CONST | ARM_CP_NO_RAW | ARM_CP_OVERRIDE,
403
.resetvalue = 0 },
404
- REGINFO_SENTINEL
405
};
406
407
static const ARMCPRegInfo cache_dirty_status_cp_reginfo[] = {
408
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cache_dirty_status_cp_reginfo[] = {
409
{ .name = "CDSR", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 6,
410
.access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
411
.resetvalue = 0 },
412
- REGINFO_SENTINEL
413
};
414
415
static const ARMCPRegInfo cache_block_ops_cp_reginfo[] = {
416
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cache_block_ops_cp_reginfo[] = {
417
.access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
418
{ .name = "CIDCR", .cp = 15, .crm = 14, .opc1 = 0,
419
.access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
420
- REGINFO_SENTINEL
421
};
422
423
static const ARMCPRegInfo cache_test_clean_cp_reginfo[] = {
424
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cache_test_clean_cp_reginfo[] = {
425
{ .name = "TCI_DCACHE", .cp = 15, .crn = 7, .crm = 14, .opc1 = 0, .opc2 = 3,
426
.access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
427
.resetvalue = (1 << 30) },
428
- REGINFO_SENTINEL
429
};
430
431
static const ARMCPRegInfo strongarm_cp_reginfo[] = {
432
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo strongarm_cp_reginfo[] = {
433
.crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY,
434
.access = PL1_RW, .resetvalue = 0,
435
.type = ARM_CP_CONST | ARM_CP_OVERRIDE | ARM_CP_NO_RAW },
436
- REGINFO_SENTINEL
437
};
438
439
static uint64_t midr_read(CPUARMState *env, const ARMCPRegInfo *ri)
440
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
441
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
442
offsetof(CPUARMState, cp15.ttbr1_ns) },
443
.writefn = vmsa_ttbr_write, },
444
- REGINFO_SENTINEL
445
};
446
447
static uint64_t aa64_fpcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
448
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
449
.access = PL1_RW, .accessfn = access_trap_aa32s_el1,
450
.writefn = sdcr_write,
451
.fieldoffset = offsetoflow32(CPUARMState, cp15.mdcr_el3) },
452
- REGINFO_SENTINEL
453
};
454
455
/* Used to describe the behaviour of EL2 regs when EL2 does not exist. */
456
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
457
.type = ARM_CP_CONST,
458
.cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 2,
459
.access = PL2_RW, .resetvalue = 0 },
460
- REGINFO_SENTINEL
461
};
462
463
/* Ditto, but for registers which exist in ARMv8 but not v7 */
464
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_no_el2_v8_cp_reginfo[] = {
465
.cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4,
466
.access = PL2_RW,
467
.type = ARM_CP_CONST, .resetvalue = 0 },
468
- REGINFO_SENTINEL
469
};
470
471
static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
472
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
473
.cp = 15, .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 3,
474
.access = PL2_RW,
475
.fieldoffset = offsetof(CPUARMState, cp15.hstr_el2) },
476
- REGINFO_SENTINEL
477
};
478
479
static const ARMCPRegInfo el2_v8_cp_reginfo[] = {
480
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_v8_cp_reginfo[] = {
481
.access = PL2_RW,
482
.fieldoffset = offsetofhigh32(CPUARMState, cp15.hcr_el2),
483
.writefn = hcr_writehigh },
484
- REGINFO_SENTINEL
485
};
486
487
static CPAccessResult sel2_access(CPUARMState *env, const ARMCPRegInfo *ri,
488
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_sec_cp_reginfo[] = {
489
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 6, .opc2 = 2,
490
.access = PL2_RW, .accessfn = sel2_access,
491
.fieldoffset = offsetof(CPUARMState, cp15.vstcr_el2) },
492
- REGINFO_SENTINEL
493
};
494
495
static CPAccessResult nsacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
496
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
497
.opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 5,
498
.access = PL3_W, .type = ARM_CP_NO_RAW,
499
.writefn = tlbi_aa64_vae3_write },
500
- REGINFO_SENTINEL
501
};
502
503
#ifndef CONFIG_USER_ONLY
504
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
505
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
506
.access = PL1_RW, .accessfn = access_tda,
507
.type = ARM_CP_NOP },
508
- REGINFO_SENTINEL
509
};
510
511
static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
512
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
513
.access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
514
{ .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0,
515
.access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
516
- REGINFO_SENTINEL
517
};
518
519
/* Return the exception level to which exceptions should be taken
520
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
521
.fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]),
522
.writefn = dbgbcr_write, .raw_writefn = raw_write
523
},
524
- REGINFO_SENTINEL
525
};
526
define_arm_cp_regs(cpu, dbgregs);
527
}
528
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
529
.fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]),
530
.writefn = dbgwcr_write, .raw_writefn = raw_write
531
},
532
- REGINFO_SENTINEL
533
};
534
define_arm_cp_regs(cpu, dbgregs);
535
}
536
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
537
.type = ARM_CP_IO,
538
.readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
539
.raw_writefn = pmevtyper_rawwrite },
540
- REGINFO_SENTINEL
541
};
542
define_arm_cp_regs(cpu, pmev_regs);
543
g_free(pmevcntr_name);
544
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
545
.cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5,
546
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
547
.resetvalue = extract64(cpu->pmceid1, 32, 32) },
548
- REGINFO_SENTINEL
549
};
550
define_arm_cp_regs(cpu, v81_pmu_regs);
551
}
552
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lor_reginfo[] = {
553
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7,
554
.access = PL1_R, .accessfn = access_lor_ns,
555
.type = ARM_CP_CONST, .resetvalue = 0 },
556
- REGINFO_SENTINEL
557
};
558
559
#ifdef TARGET_AARCH64
560
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pauth_reginfo[] = {
561
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 3,
562
.access = PL1_RW, .accessfn = access_pauth,
563
.fieldoffset = offsetof(CPUARMState, keys.apib.hi) },
564
- REGINFO_SENTINEL
565
};
566
567
static const ARMCPRegInfo tlbirange_reginfo[] = {
568
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbirange_reginfo[] = {
569
.opc0 = 1, .opc1 = 6, .crn = 8, .crm = 6, .opc2 = 5,
570
.access = PL3_W, .type = ARM_CP_NO_RAW,
571
.writefn = tlbi_aa64_rvae3_write },
572
- REGINFO_SENTINEL
573
};
574
575
static const ARMCPRegInfo tlbios_reginfo[] = {
576
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbios_reginfo[] = {
577
.opc0 = 1, .opc1 = 6, .crn = 8, .crm = 1, .opc2 = 5,
578
.access = PL3_W, .type = ARM_CP_NO_RAW,
579
.writefn = tlbi_aa64_vae3is_write },
580
- REGINFO_SENTINEL
581
};
582
583
static uint64_t rndr_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
584
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo rndr_reginfo[] = {
585
.type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END | ARM_CP_IO,
586
.opc0 = 3, .opc1 = 3, .crn = 2, .crm = 4, .opc2 = 1,
587
.access = PL0_R, .readfn = rndr_readfn },
588
- REGINFO_SENTINEL
589
};
590
591
#ifndef CONFIG_USER_ONLY
592
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo dcpop_reg[] = {
593
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 1,
594
.access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
595
.accessfn = aa64_cacheop_poc_access, .writefn = dccvap_writefn },
596
- REGINFO_SENTINEL
597
};
598
599
static const ARMCPRegInfo dcpodp_reg[] = {
600
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo dcpodp_reg[] = {
601
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 1,
602
.access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
603
.accessfn = aa64_cacheop_poc_access, .writefn = dccvap_writefn },
604
- REGINFO_SENTINEL
605
};
606
#endif /*CONFIG_USER_ONLY*/
607
608
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_reginfo[] = {
609
{ .name = "DC_CIGDSW", .state = ARM_CP_STATE_AA64,
610
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 6,
611
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
612
- REGINFO_SENTINEL
613
};
614
615
static const ARMCPRegInfo mte_tco_ro_reginfo[] = {
616
{ .name = "TCO", .state = ARM_CP_STATE_AA64,
617
.opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 7,
618
.type = ARM_CP_CONST, .access = PL0_RW, },
619
- REGINFO_SENTINEL
620
};
621
622
static const ARMCPRegInfo mte_el0_cacheop_reginfo[] = {
623
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_el0_cacheop_reginfo[] = {
624
.accessfn = aa64_zva_access,
625
#endif
626
},
627
- REGINFO_SENTINEL
628
};
629
630
#endif
631
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo predinv_reginfo[] = {
632
{ .name = "CPPRCTX", .state = ARM_CP_STATE_AA32,
633
.cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 7,
634
.type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
635
- REGINFO_SENTINEL
636
};
637
638
static uint64_t ccsidr2_read(CPUARMState *env, const ARMCPRegInfo *ri)
639
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo ccsidr2_reginfo[] = {
640
.access = PL1_R,
641
.accessfn = access_aa64_tid2,
642
.readfn = ccsidr2_read, .type = ARM_CP_NO_RAW },
643
- REGINFO_SENTINEL
644
};
645
646
static CPAccessResult access_aa64_tid3(CPUARMState *env, const ARMCPRegInfo *ri,
647
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo jazelle_regs[] = {
648
.cp = 14, .crn = 2, .crm = 0, .opc1 = 7, .opc2 = 0,
649
.accessfn = access_joscr_jmcr,
650
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
651
- REGINFO_SENTINEL
652
};
653
654
static const ARMCPRegInfo vhe_reginfo[] = {
655
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vhe_reginfo[] = {
656
.access = PL2_RW, .accessfn = e2h_access,
657
.writefn = gt_virt_cval_write, .raw_writefn = raw_write },
658
#endif
659
- REGINFO_SENTINEL
660
};
661
662
#ifndef CONFIG_USER_ONLY
663
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo ats1e1_reginfo[] = {
664
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1,
665
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
666
.writefn = ats_write64 },
667
- REGINFO_SENTINEL
668
};
669
670
static const ARMCPRegInfo ats1cp_reginfo[] = {
671
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo ats1cp_reginfo[] = {
672
.cp = 15, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1,
673
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
674
.writefn = ats_write },
675
- REGINFO_SENTINEL
676
};
677
#endif
678
679
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo actlr2_hactlr2_reginfo[] = {
680
.cp = 15, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 3,
681
.access = PL2_RW, .type = ARM_CP_CONST,
682
.resetvalue = 0 },
683
- REGINFO_SENTINEL
684
};
685
686
void register_cp_regs_for_features(ARMCPU *cpu)
687
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
688
.access = PL1_R, .type = ARM_CP_CONST,
689
.accessfn = access_aa32_tid3,
690
.resetvalue = cpu->isar.id_isar6 },
691
- REGINFO_SENTINEL
692
};
693
define_arm_cp_regs(cpu, v6_idregs);
694
define_arm_cp_regs(cpu, v6_cp_reginfo);
695
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
696
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 7,
697
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
698
.resetvalue = cpu->pmceid1 },
699
- REGINFO_SENTINEL
700
};
701
#ifdef CONFIG_USER_ONLY
702
ARMCPRegUserSpaceInfo v8_user_idregs[] = {
703
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
704
.exported_bits = 0x000000f0ffffffff },
705
{ .name = "ID_AA64ISAR*_EL1_RESERVED",
706
.is_glob = true },
707
- REGUSERINFO_SENTINEL
708
};
709
modify_arm_cp_regs(v8_idregs, v8_user_idregs);
710
#endif
711
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
712
.access = PL2_RW,
713
.resetvalue = vmpidr_def,
714
.fieldoffset = offsetof(CPUARMState, cp15.vmpidr_el2) },
715
- REGINFO_SENTINEL
716
};
717
define_arm_cp_regs(cpu, vpidr_regs);
718
define_arm_cp_regs(cpu, el2_cp_reginfo);
719
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
720
.access = PL2_RW, .accessfn = access_el3_aa32ns,
721
.type = ARM_CP_NO_RAW,
722
.writefn = arm_cp_write_ignore, .readfn = mpidr_read },
723
- REGINFO_SENTINEL
724
};
725
define_arm_cp_regs(cpu, vpidr_regs);
726
define_arm_cp_regs(cpu, el3_no_el2_cp_reginfo);
727
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
728
.raw_writefn = raw_write, .writefn = sctlr_write,
729
.fieldoffset = offsetof(CPUARMState, cp15.sctlr_el[3]),
730
.resetvalue = cpu->reset_sctlr },
731
- REGINFO_SENTINEL
732
};
733
734
define_arm_cp_regs(cpu, el3_regs);
735
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
736
{ .name = "DUMMY",
737
.cp = 15, .crn = 0, .crm = 7, .opc1 = 0, .opc2 = CP_ANY,
738
.access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
739
- REGINFO_SENTINEL
740
};
741
ARMCPRegInfo id_v8_midr_cp_reginfo[] = {
742
{ .name = "MIDR_EL1", .state = ARM_CP_STATE_BOTH,
743
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
744
.access = PL1_R,
745
.accessfn = access_aa64_tid1,
746
.type = ARM_CP_CONST, .resetvalue = cpu->revidr },
747
- REGINFO_SENTINEL
748
};
749
ARMCPRegInfo id_cp_reginfo[] = {
750
/* These are common to v8 and pre-v8 */
751
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
752
.access = PL1_R,
753
.accessfn = access_aa32_tid1,
754
.type = ARM_CP_CONST, .resetvalue = 0 },
755
- REGINFO_SENTINEL
756
};
757
/* TLBTR is specific to VMSA */
758
ARMCPRegInfo id_tlbtr_reginfo = {
759
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
760
{ .name = "MIDR_EL1",
761
.exported_bits = 0x00000000ffffffff },
762
{ .name = "REVIDR_EL1" },
763
- REGUSERINFO_SENTINEL
764
};
765
modify_arm_cp_regs(id_v8_midr_cp_reginfo, id_v8_user_midr_cp_reginfo);
766
#endif
767
if (arm_feature(env, ARM_FEATURE_OMAPCP) ||
768
arm_feature(env, ARM_FEATURE_STRONGARM)) {
769
- ARMCPRegInfo *r;
770
+ size_t i;
771
/* Register the blanket "writes ignored" value first to cover the
772
* whole space. Then update the specific ID registers to allow write
773
* access, so that they ignore writes rather than causing them to
774
* UNDEF.
775
*/
776
define_one_arm_cp_reg(cpu, &crn0_wi_reginfo);
777
- for (r = id_pre_v8_midr_cp_reginfo;
778
- r->type != ARM_CP_SENTINEL; r++) {
779
- r->access = PL1_RW;
780
+ for (i = 0; i < ARRAY_SIZE(id_pre_v8_midr_cp_reginfo); ++i) {
781
+ id_pre_v8_midr_cp_reginfo[i].access = PL1_RW;
782
}
783
- for (r = id_cp_reginfo; r->type != ARM_CP_SENTINEL; r++) {
784
- r->access = PL1_RW;
785
+ for (i = 0; i < ARRAY_SIZE(id_cp_reginfo); ++i) {
786
+ id_cp_reginfo[i].access = PL1_RW;
787
}
788
id_mpuir_reginfo.access = PL1_RW;
789
id_tlbtr_reginfo.access = PL1_RW;
790
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
791
{ .name = "MPIDR_EL1", .state = ARM_CP_STATE_BOTH,
792
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 5,
793
.access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_RAW },
794
- REGINFO_SENTINEL
795
};
796
#ifdef CONFIG_USER_ONLY
797
ARMCPRegUserSpaceInfo mpidr_user_cp_reginfo[] = {
798
{ .name = "MPIDR_EL1",
799
.fixed_bits = 0x0000000080000000 },
800
- REGUSERINFO_SENTINEL
801
};
802
modify_arm_cp_regs(mpidr_cp_reginfo, mpidr_user_cp_reginfo);
803
#endif
804
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
805
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 0, .opc2 = 1,
806
.access = PL3_RW, .type = ARM_CP_CONST,
807
.resetvalue = 0 },
808
- REGINFO_SENTINEL
809
};
810
define_arm_cp_regs(cpu, auxcr_reginfo);
811
if (cpu_isar_feature(aa32_ac2, cpu)) {
812
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
813
.type = ARM_CP_CONST,
814
.opc0 = 3, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 0,
815
.access = PL1_R, .resetvalue = cpu->reset_cbar },
816
- REGINFO_SENTINEL
817
};
818
/* We don't implement a r/w 64 bit CBAR currently */
819
assert(arm_feature(env, ARM_FEATURE_CBAR_RO));
820
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
821
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s),
822
offsetof(CPUARMState, cp15.vbar_ns) },
823
.resetvalue = 0 },
824
- REGINFO_SENTINEL
825
};
826
define_arm_cp_regs(cpu, vbar_cp_reginfo);
827
}
828
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
829
r->writefn);
830
}
831
}
832
- /* Bad type field probably means missing sentinel at end of reg list */
833
- assert(cptype_valid(r->type));
834
+
835
for (crm = crmmin; crm <= crmmax; crm++) {
836
for (opc1 = opc1min; opc1 <= opc1max; opc1++) {
837
for (opc2 = opc2min; opc2 <= opc2max; opc2++) {
838
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
839
}
840
}
841
842
-void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
843
- const ARMCPRegInfo *regs, void *opaque)
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
{
848
- /* Define a whole list of registers */
849
- const ARMCPRegInfo *r;
850
- for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
851
- define_one_arm_cp_reg_with_opaque(cpu, r, opaque);
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
}
857
858
@@ -XXX,XX +XXX,XX @@ void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
859
* user-space cannot alter any values and dynamic values pertaining to
860
* execution state are hidden from user space view anyway.
861
*/
862
-void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods)
863
+void modify_arm_cp_regs_with_len(ARMCPRegInfo *regs, size_t regs_len,
864
+ const ARMCPRegUserSpaceInfo *mods,
865
+ size_t mods_len)
866
{
867
- const ARMCPRegUserSpaceInfo *m;
868
- ARMCPRegInfo *r;
869
-
870
- for (m = mods; m->name; m++) {
871
+ for (size_t mi = 0; mi < mods_len; ++mi) {
872
+ const ARMCPRegUserSpaceInfo *m = mods + mi;
873
GPatternSpec *pat = NULL;
874
+
875
if (m->is_glob) {
876
pat = g_pattern_spec_new(m->name);
877
}
878
- for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
879
+ for (size_t ri = 0; ri < regs_len; ++ri) {
880
+ ARMCPRegInfo *r = regs + ri;
881
+
882
if (pat && g_pattern_match_string(pat, r->name)) {
883
r->type = ARM_CP_CONST;
884
r->access = PL0U_R;
885
--
37
--
886
2.25.1
38
2.34.1
887
39
888
40
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
2
3
Move ARMCPRegInfo and all related declarations to a new
3
This device implements the IM120417002 colors shield v1.1 for Arduino
4
internal header, out of the public cpu.h.
4
(which relies on the DM163 8x3-channel led driving logic) and features
5
a simple display of an 8x8 RGB matrix. The columns of the matrix are
6
driven by the DM163 and the rows are driven externally.
5
7
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Acked-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
9
Message-id: 20220501055028.646596-2-richard.henderson@linaro.org
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Message-id: 20240424200929.240921-2-ines.varhol@telecom-paris.fr
13
[PMM: updated to new reset hold method prototype]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
15
---
12
target/arm/cpregs.h | 413 +++++++++++++++++++++++++++++++++++++
16
docs/system/arm/b-l475e-iot01a.rst | 3 +-
13
target/arm/cpu.h | 368 ---------------------------------
17
include/hw/display/dm163.h | 59 +++++
14
hw/arm/pxa2xx.c | 1 +
18
hw/display/dm163.c | 349 +++++++++++++++++++++++++++++
15
hw/arm/pxa2xx_pic.c | 1 +
19
hw/display/Kconfig | 3 +
16
hw/intc/arm_gicv3_cpuif.c | 1 +
20
hw/display/meson.build | 1 +
17
hw/intc/arm_gicv3_kvm.c | 2 +
21
hw/display/trace-events | 14 ++
18
target/arm/cpu.c | 1 +
22
6 files changed, 428 insertions(+), 1 deletion(-)
19
target/arm/cpu64.c | 1 +
23
create mode 100644 include/hw/display/dm163.h
20
target/arm/cpu_tcg.c | 1 +
24
create mode 100644 hw/display/dm163.c
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
25
29
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
26
diff --git a/docs/system/arm/b-l475e-iot01a.rst b/docs/system/arm/b-l475e-iot01a.rst
27
index XXXXXXX..XXXXXXX 100644
28
--- a/docs/system/arm/b-l475e-iot01a.rst
29
+++ b/docs/system/arm/b-l475e-iot01a.rst
30
@@ -XXX,XX +XXX,XX @@ USART, I2C, SPI, CAN and USB OTG, as well as a variety of sensors.
31
Supported devices
32
"""""""""""""""""
33
34
-Currently B-L475E-IOT01A machine's only supports the following devices:
35
+Currently B-L475E-IOT01A machines support the following devices:
36
37
- Cortex-M4F based STM32L4x5 SoC
38
- STM32L4x5 EXTI (Extended interrupts and events controller)
39
@@ -XXX,XX +XXX,XX @@ Currently B-L475E-IOT01A machine's only supports the following devices:
40
- STM32L4x5 RCC (Reset and clock control)
41
- STM32L4x5 GPIOs (General-purpose I/Os)
42
- STM32L4x5 USARTs, UARTs and LPUART (Serial ports)
43
+- optional 8x8 led display (based on DM163 driver)
44
45
Missing devices
46
"""""""""""""""
47
diff --git a/include/hw/display/dm163.h b/include/hw/display/dm163.h
30
new file mode 100644
48
new file mode 100644
31
index XXXXXXX..XXXXXXX
49
index XXXXXXX..XXXXXXX
32
--- /dev/null
50
--- /dev/null
33
+++ b/target/arm/cpregs.h
51
+++ b/include/hw/display/dm163.h
34
@@ -XXX,XX +XXX,XX @@
52
@@ -XXX,XX +XXX,XX @@
35
+/*
53
+/*
36
+ * QEMU ARM CP Register access and descriptions
54
+ * QEMU DM163 8x3-channel constant current led driver
55
+ * driving columns of associated 8x8 RGB matrix.
37
+ *
56
+ *
38
+ * Copyright (c) 2022 Linaro Ltd
57
+ * Copyright (C) 2024 Samuel Tardieu <sam@rfc1149.net>
58
+ * Copyright (C) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
59
+ * Copyright (C) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
39
+ *
60
+ *
40
+ * This program is free software; you can redistribute it and/or
61
+ * SPDX-License-Identifier: GPL-2.0-or-later
41
+ * modify it under the terms of the GNU General Public License
62
+ */
42
+ * as published by the Free Software Foundation; either version 2
63
+
43
+ * of the License, or (at your option) any later version.
64
+#ifndef HW_DISPLAY_DM163_H
65
+#define HW_DISPLAY_DM163_H
66
+
67
+#include "qom/object.h"
68
+#include "hw/qdev-core.h"
69
+
70
+#define TYPE_DM163 "dm163"
71
+OBJECT_DECLARE_SIMPLE_TYPE(DM163State, DM163);
72
+
73
+#define RGB_MATRIX_NUM_ROWS 8
74
+#define RGB_MATRIX_NUM_COLS 8
75
+#define DM163_NUM_LEDS (RGB_MATRIX_NUM_COLS * 3)
76
+/* The last row is filled with 0 (turned off row) */
77
+#define COLOR_BUFFER_SIZE (RGB_MATRIX_NUM_ROWS + 1)
78
+
79
+typedef struct DM163State {
80
+ DeviceState parent_obj;
81
+
82
+ /* DM163 driver */
83
+ uint64_t bank0_shift_register[3];
84
+ uint64_t bank1_shift_register[3];
85
+ uint16_t latched_outputs[DM163_NUM_LEDS];
86
+ uint16_t outputs[DM163_NUM_LEDS];
87
+ qemu_irq sout;
88
+
89
+ uint8_t sin;
90
+ uint8_t dck;
91
+ uint8_t rst_b;
92
+ uint8_t lat_b;
93
+ uint8_t selbk;
94
+ uint8_t en_b;
95
+
96
+ /* IM120417002 colors shield */
97
+ uint8_t activated_rows;
98
+
99
+ /* 8x8 RGB matrix */
100
+ QemuConsole *console;
101
+ uint8_t redraw;
102
+ /* Rows currently being displayed on the matrix. */
103
+ /* The last row is filled with 0 (turned off row) */
104
+ uint32_t buffer[COLOR_BUFFER_SIZE][RGB_MATRIX_NUM_COLS];
105
+ uint8_t last_buffer_idx;
106
+ uint8_t buffer_idx_of_row[RGB_MATRIX_NUM_ROWS];
107
+ /* Used to simulate retinal persistence of rows */
108
+ uint8_t row_persistence_delay[RGB_MATRIX_NUM_ROWS];
109
+} DM163State;
110
+
111
+#endif /* HW_DISPLAY_DM163_H */
112
diff --git a/hw/display/dm163.c b/hw/display/dm163.c
113
new file mode 100644
114
index XXXXXXX..XXXXXXX
115
--- /dev/null
116
+++ b/hw/display/dm163.c
117
@@ -XXX,XX +XXX,XX @@
118
+/*
119
+ * QEMU DM163 8x3-channel constant current led driver
120
+ * driving columns of associated 8x8 RGB matrix.
44
+ *
121
+ *
45
+ * This program is distributed in the hope that it will be useful,
122
+ * Copyright (C) 2024 Samuel Tardieu <sam@rfc1149.net>
46
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
123
+ * Copyright (C) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
47
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
124
+ * Copyright (C) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
48
+ * GNU General Public License for more details.
49
+ *
125
+ *
50
+ * You should have received a copy of the GNU General Public License
126
+ * SPDX-License-Identifier: GPL-2.0-or-later
51
+ * along with this program; if not, see
52
+ * <http://www.gnu.org/licenses/gpl-2.0.html>
53
+ */
127
+ */
54
+
128
+
55
+#ifndef TARGET_ARM_CPREGS_H
56
+#define TARGET_ARM_CPREGS_H
57
+
58
+/*
129
+/*
59
+ * ARMCPRegInfo type field bits. If the SPECIAL bit is set this is a
130
+ * The reference used for the DM163 is the following :
60
+ * special-behaviour cp reg and bits [11..8] indicate what behaviour
131
+ * http://www.siti.com.tw/product/spec/LED/DM163.pdf
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
+ */
132
+ */
87
+#define ARM_CP_SPECIAL 0x0001
133
+
88
+#define ARM_CP_CONST 0x0002
134
+#include "qemu/osdep.h"
89
+#define ARM_CP_64BIT 0x0004
135
+#include "qapi/error.h"
90
+#define ARM_CP_SUPPRESS_TB_END 0x0008
136
+#include "migration/vmstate.h"
91
+#define ARM_CP_OVERRIDE 0x0010
137
+#include "hw/irq.h"
92
+#define ARM_CP_ALIAS 0x0020
138
+#include "hw/qdev-properties.h"
93
+#define ARM_CP_IO 0x0040
139
+#include "hw/display/dm163.h"
94
+#define ARM_CP_NO_RAW 0x0080
140
+#include "ui/console.h"
95
+#define ARM_CP_NOP (ARM_CP_SPECIAL | 0x0100)
141
+#include "trace.h"
96
+#define ARM_CP_WFI (ARM_CP_SPECIAL | 0x0200)
142
+
97
+#define ARM_CP_NZCV (ARM_CP_SPECIAL | 0x0300)
143
+#define LED_SQUARE_SIZE 100
98
+#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | 0x0400)
144
+/* Number of frames a row stays visible after being turned off. */
99
+#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | 0x0500)
145
+#define ROW_PERSISTENCE 3
100
+#define ARM_CP_DC_GVA (ARM_CP_SPECIAL | 0x0600)
146
+#define TURNED_OFF_ROW (COLOR_BUFFER_SIZE - 1)
101
+#define ARM_CP_DC_GZVA (ARM_CP_SPECIAL | 0x0700)
147
+
102
+#define ARM_LAST_SPECIAL ARM_CP_DC_GZVA
148
+static const VMStateDescription vmstate_dm163 = {
103
+#define ARM_CP_FPU 0x1000
149
+ .name = TYPE_DM163,
104
+#define ARM_CP_SVE 0x2000
150
+ .version_id = 1,
105
+#define ARM_CP_NO_GDB 0x4000
151
+ .minimum_version_id = 1,
106
+#define ARM_CP_RAISES_EXC 0x8000
152
+ .fields = (const VMStateField[]) {
107
+#define ARM_CP_NEWEL 0x10000
153
+ VMSTATE_UINT64_ARRAY(bank0_shift_register, DM163State, 3),
108
+/* Used only as a terminator for ARMCPRegInfo lists */
154
+ VMSTATE_UINT64_ARRAY(bank1_shift_register, DM163State, 3),
109
+#define ARM_CP_SENTINEL 0xfffff
155
+ VMSTATE_UINT16_ARRAY(latched_outputs, DM163State, DM163_NUM_LEDS),
110
+/* Mask of only the flag bits in a type field */
156
+ VMSTATE_UINT16_ARRAY(outputs, DM163State, DM163_NUM_LEDS),
111
+#define ARM_CP_FLAG_MASK 0x1f0ff
157
+ VMSTATE_UINT8(dck, DM163State),
112
+
158
+ VMSTATE_UINT8(en_b, DM163State),
113
+/*
159
+ VMSTATE_UINT8(lat_b, DM163State),
114
+ * Valid values for ARMCPRegInfo state field, indicating which of
160
+ VMSTATE_UINT8(rst_b, DM163State),
115
+ * the AArch32 and AArch64 execution states this register is visible in.
161
+ VMSTATE_UINT8(selbk, DM163State),
116
+ * If the reginfo doesn't explicitly specify then it is AArch32 only.
162
+ VMSTATE_UINT8(sin, DM163State),
117
+ * If the reginfo is declared to be visible in both states then a second
163
+ VMSTATE_UINT8(activated_rows, DM163State),
118
+ * reginfo is synthesised for the AArch32 view of the AArch64 register,
164
+ VMSTATE_UINT32_2DARRAY(buffer, DM163State, COLOR_BUFFER_SIZE,
119
+ * such that the AArch32 view is the lower 32 bits of the AArch64 one.
165
+ RGB_MATRIX_NUM_COLS),
120
+ * Note that we rely on the values of these enums as we iterate through
166
+ VMSTATE_UINT8(last_buffer_idx, DM163State),
121
+ * the various states in some places.
167
+ VMSTATE_UINT8_ARRAY(buffer_idx_of_row, DM163State, RGB_MATRIX_NUM_ROWS),
122
+ */
168
+ VMSTATE_UINT8_ARRAY(row_persistence_delay, DM163State,
123
+enum {
169
+ RGB_MATRIX_NUM_ROWS),
124
+ ARM_CP_STATE_AA32 = 0,
170
+ VMSTATE_END_OF_LIST()
125
+ ARM_CP_STATE_AA64 = 1,
171
+ }
126
+ ARM_CP_STATE_BOTH = 2,
127
+};
172
+};
128
+
173
+
129
+/*
174
+static void dm163_reset_hold(Object *obj, ResetType type)
130
+ * ARM CP register secure state flags. These flags identify security state
175
+{
131
+ * attributes for a given CP register entry.
176
+ DM163State *s = DM163(obj);
132
+ * The existence of both or neither secure and non-secure flags indicates that
177
+
133
+ * the register has both a secure and non-secure hash entry. A single one of
178
+ s->sin = 0;
134
+ * these flags causes the register to only be hashed for the specified
179
+ s->dck = 0;
135
+ * security state.
180
+ s->rst_b = 0;
136
+ * Although definitions may have any combination of the S/NS bits, each
181
+ /* Ensuring the first falling edge of lat_b isn't missed */
137
+ * registered entry will only have one to identify whether the entry is secure
182
+ s->lat_b = 1;
138
+ * or non-secure.
183
+ s->selbk = 0;
139
+ */
184
+ s->en_b = 0;
140
+enum {
185
+ /* Reset stops the PWM, not the shift and latched registers. */
141
+ ARM_CP_SECSTATE_S = (1 << 0), /* bit[0]: Secure state register */
186
+ memset(s->outputs, 0, sizeof(s->outputs));
142
+ ARM_CP_SECSTATE_NS = (1 << 1), /* bit[1]: Non-secure state register */
187
+
188
+ s->activated_rows = 0;
189
+ s->redraw = 0;
190
+ trace_dm163_redraw(s->redraw);
191
+ for (unsigned i = 0; i < COLOR_BUFFER_SIZE; i++) {
192
+ memset(s->buffer[i], 0, sizeof(s->buffer[0]));
193
+ }
194
+ s->last_buffer_idx = 0;
195
+ memset(s->buffer_idx_of_row, TURNED_OFF_ROW, sizeof(s->buffer_idx_of_row));
196
+ memset(s->row_persistence_delay, 0, sizeof(s->row_persistence_delay));
197
+}
198
+
199
+static void dm163_dck_gpio_handler(void *opaque, int line, int new_state)
200
+{
201
+ DM163State *s = opaque;
202
+
203
+ if (new_state && !s->dck) {
204
+ /*
205
+ * On raising dck, sample selbk to get the bank to use, and
206
+ * sample sin for the bit to enter into the bank shift buffer.
207
+ */
208
+ uint64_t *sb =
209
+ s->selbk ? s->bank1_shift_register : s->bank0_shift_register;
210
+ /* Output the outgoing bit on sout */
211
+ const bool sout = (s->selbk ? sb[2] & MAKE_64BIT_MASK(63, 1) :
212
+ sb[2] & MAKE_64BIT_MASK(15, 1)) != 0;
213
+ qemu_set_irq(s->sout, sout);
214
+ /* Enter sin into the shift buffer */
215
+ sb[2] = (sb[2] << 1) | ((sb[1] >> 63) & 1);
216
+ sb[1] = (sb[1] << 1) | ((sb[0] >> 63) & 1);
217
+ sb[0] = (sb[0] << 1) | s->sin;
218
+ }
219
+
220
+ s->dck = new_state;
221
+ trace_dm163_dck(new_state);
222
+}
223
+
224
+static void dm163_propagate_outputs(DM163State *s)
225
+{
226
+ s->last_buffer_idx = (s->last_buffer_idx + 1) % RGB_MATRIX_NUM_ROWS;
227
+ /* Values are output when reset is high and enable is low. */
228
+ if (s->rst_b && !s->en_b) {
229
+ memcpy(s->outputs, s->latched_outputs, sizeof(s->outputs));
230
+ } else {
231
+ memset(s->outputs, 0, sizeof(s->outputs));
232
+ }
233
+ for (unsigned x = 0; x < RGB_MATRIX_NUM_COLS; x++) {
234
+ /* Grouping the 3 RGB channels in a pixel value */
235
+ const uint16_t b = extract16(s->outputs[3 * x + 0], 6, 8);
236
+ const uint16_t g = extract16(s->outputs[3 * x + 1], 6, 8);
237
+ const uint16_t r = extract16(s->outputs[3 * x + 2], 6, 8);
238
+ uint32_t rgba = 0;
239
+
240
+ trace_dm163_channels(3 * x + 2, r);
241
+ trace_dm163_channels(3 * x + 1, g);
242
+ trace_dm163_channels(3 * x + 0, b);
243
+
244
+ rgba = deposit32(rgba, 0, 8, r);
245
+ rgba = deposit32(rgba, 8, 8, g);
246
+ rgba = deposit32(rgba, 16, 8, b);
247
+
248
+ /* Led values are sent from the last one to the first one */
249
+ s->buffer[s->last_buffer_idx][RGB_MATRIX_NUM_COLS - x - 1] = rgba;
250
+ }
251
+ for (unsigned row = 0; row < RGB_MATRIX_NUM_ROWS; row++) {
252
+ if (s->activated_rows & (1 << row)) {
253
+ s->buffer_idx_of_row[row] = s->last_buffer_idx;
254
+ s->redraw |= (1 << row);
255
+ trace_dm163_redraw(s->redraw);
256
+ }
257
+ }
258
+}
259
+
260
+static void dm163_en_b_gpio_handler(void *opaque, int line, int new_state)
261
+{
262
+ DM163State *s = opaque;
263
+
264
+ s->en_b = new_state;
265
+ dm163_propagate_outputs(s);
266
+ trace_dm163_en_b(new_state);
267
+}
268
+
269
+static uint8_t dm163_bank0(const DM163State *s, uint8_t led)
270
+{
271
+ /*
272
+ * Bank 0 uses 6 bits per led, so a value may be stored accross
273
+ * two uint64_t entries.
274
+ */
275
+ const uint8_t low_bit = 6 * led;
276
+ const uint8_t low_word = low_bit / 64;
277
+ const uint8_t high_word = (low_bit + 5) / 64;
278
+ const uint8_t low_shift = low_bit % 64;
279
+
280
+ if (low_word == high_word) {
281
+ /* Simple case: the value belongs to one entry. */
282
+ return extract64(s->bank0_shift_register[low_word], low_shift, 6);
283
+ }
284
+
285
+ const uint8_t nb_bits_in_low_word = 64 - low_shift;
286
+ const uint8_t nb_bits_in_high_word = 6 - nb_bits_in_low_word;
287
+
288
+ const uint64_t bits_in_low_word = \
289
+ extract64(s->bank0_shift_register[low_word], low_shift,
290
+ nb_bits_in_low_word);
291
+ const uint64_t bits_in_high_word = \
292
+ extract64(s->bank0_shift_register[high_word], 0,
293
+ nb_bits_in_high_word);
294
+ uint8_t val = 0;
295
+
296
+ val = deposit32(val, 0, nb_bits_in_low_word, bits_in_low_word);
297
+ val = deposit32(val, nb_bits_in_low_word, nb_bits_in_high_word,
298
+ bits_in_high_word);
299
+
300
+ return val;
301
+}
302
+
303
+static uint8_t dm163_bank1(const DM163State *s, uint8_t led)
304
+{
305
+ const uint64_t entry = s->bank1_shift_register[led / RGB_MATRIX_NUM_COLS];
306
+ return extract64(entry, 8 * (led % RGB_MATRIX_NUM_COLS), 8);
307
+}
308
+
309
+static void dm163_lat_b_gpio_handler(void *opaque, int line, int new_state)
310
+{
311
+ DM163State *s = opaque;
312
+
313
+ if (s->lat_b && !new_state) {
314
+ for (int led = 0; led < DM163_NUM_LEDS; led++) {
315
+ s->latched_outputs[led] = dm163_bank0(s, led) * dm163_bank1(s, led);
316
+ }
317
+ dm163_propagate_outputs(s);
318
+ }
319
+
320
+ s->lat_b = new_state;
321
+ trace_dm163_lat_b(new_state);
322
+}
323
+
324
+static void dm163_rst_b_gpio_handler(void *opaque, int line, int new_state)
325
+{
326
+ DM163State *s = opaque;
327
+
328
+ s->rst_b = new_state;
329
+ dm163_propagate_outputs(s);
330
+ trace_dm163_rst_b(new_state);
331
+}
332
+
333
+static void dm163_selbk_gpio_handler(void *opaque, int line, int new_state)
334
+{
335
+ DM163State *s = opaque;
336
+
337
+ s->selbk = new_state;
338
+ trace_dm163_selbk(new_state);
339
+}
340
+
341
+static void dm163_sin_gpio_handler(void *opaque, int line, int new_state)
342
+{
343
+ DM163State *s = opaque;
344
+
345
+ s->sin = new_state;
346
+ trace_dm163_sin(new_state);
347
+}
348
+
349
+static void dm163_rows_gpio_handler(void *opaque, int line, int new_state)
350
+{
351
+ DM163State *s = opaque;
352
+
353
+ if (new_state) {
354
+ s->activated_rows |= (1 << line);
355
+ s->buffer_idx_of_row[line] = s->last_buffer_idx;
356
+ s->redraw |= (1 << line);
357
+ trace_dm163_redraw(s->redraw);
358
+ } else {
359
+ s->activated_rows &= ~(1 << line);
360
+ s->row_persistence_delay[line] = ROW_PERSISTENCE;
361
+ }
362
+ trace_dm163_activated_rows(s->activated_rows);
363
+}
364
+
365
+static void dm163_invalidate_display(void *opaque)
366
+{
367
+ DM163State *s = (DM163State *)opaque;
368
+ s->redraw = 0xFF;
369
+ trace_dm163_redraw(s->redraw);
370
+}
371
+
372
+static void update_row_persistence_delay(DM163State *s, unsigned row)
373
+{
374
+ if (s->row_persistence_delay[row]) {
375
+ s->row_persistence_delay[row]--;
376
+ } else {
377
+ /*
378
+ * If the ROW_PERSISTENCE delay is up,
379
+ * the row is turned off.
380
+ */
381
+ s->buffer_idx_of_row[row] = TURNED_OFF_ROW;
382
+ s->redraw |= (1 << row);
383
+ trace_dm163_redraw(s->redraw);
384
+ }
385
+}
386
+
387
+static uint32_t *update_display_of_row(DM163State *s, uint32_t *dest,
388
+ unsigned row)
389
+{
390
+ for (unsigned _ = 0; _ < LED_SQUARE_SIZE; _++) {
391
+ for (int x = 0; x < RGB_MATRIX_NUM_COLS * LED_SQUARE_SIZE; x++) {
392
+ /* UI layer guarantees that there's 32 bits per pixel (Mar 2024) */
393
+ *dest++ = s->buffer[s->buffer_idx_of_row[row]][x / LED_SQUARE_SIZE];
394
+ }
395
+ }
396
+
397
+ dpy_gfx_update(s->console, 0, LED_SQUARE_SIZE * row,
398
+ RGB_MATRIX_NUM_COLS * LED_SQUARE_SIZE, LED_SQUARE_SIZE);
399
+ s->redraw &= ~(1 << row);
400
+ trace_dm163_redraw(s->redraw);
401
+
402
+ return dest;
403
+}
404
+
405
+static void dm163_update_display(void *opaque)
406
+{
407
+ DM163State *s = (DM163State *)opaque;
408
+ DisplaySurface *surface = qemu_console_surface(s->console);
409
+ uint32_t *dest;
410
+
411
+ dest = surface_data(surface);
412
+ for (unsigned row = 0; row < RGB_MATRIX_NUM_ROWS; row++) {
413
+ update_row_persistence_delay(s, row);
414
+ if (!extract8(s->redraw, row, 1)) {
415
+ dest += LED_SQUARE_SIZE * LED_SQUARE_SIZE * RGB_MATRIX_NUM_COLS;
416
+ continue;
417
+ }
418
+ dest = update_display_of_row(s, dest, row);
419
+ }
420
+}
421
+
422
+static const GraphicHwOps dm163_ops = {
423
+ .invalidate = dm163_invalidate_display,
424
+ .gfx_update = dm163_update_display,
143
+};
425
+};
144
+
426
+
145
+/*
427
+static void dm163_realize(DeviceState *dev, Error **errp)
146
+ * Return true if cptype is a valid type field. This is used to try to
428
+{
147
+ * catch errors where the sentinel has been accidentally left off the end
429
+ DM163State *s = DM163(dev);
148
+ * of a list of registers.
430
+
149
+ */
431
+ qdev_init_gpio_in(dev, dm163_rows_gpio_handler, RGB_MATRIX_NUM_ROWS);
150
+static inline bool cptype_valid(int cptype)
432
+ qdev_init_gpio_in(dev, dm163_sin_gpio_handler, 1);
151
+{
433
+ qdev_init_gpio_in(dev, dm163_dck_gpio_handler, 1);
152
+ return ((cptype & ~ARM_CP_FLAG_MASK) == 0)
434
+ qdev_init_gpio_in(dev, dm163_rst_b_gpio_handler, 1);
153
+ || ((cptype & ARM_CP_SPECIAL) &&
435
+ qdev_init_gpio_in(dev, dm163_lat_b_gpio_handler, 1);
154
+ ((cptype & ~ARM_CP_FLAG_MASK) <= ARM_LAST_SPECIAL));
436
+ qdev_init_gpio_in(dev, dm163_selbk_gpio_handler, 1);
155
+}
437
+ qdev_init_gpio_in(dev, dm163_en_b_gpio_handler, 1);
156
+
438
+ qdev_init_gpio_out_named(dev, &s->sout, "sout", 1);
157
+/*
439
+
158
+ * Access rights:
440
+ s->console = graphic_console_init(dev, 0, &dm163_ops, s);
159
+ * We define bits for Read and Write access for what rev C of the v7-AR ARM ARM
441
+ qemu_console_resize(s->console, RGB_MATRIX_NUM_COLS * LED_SQUARE_SIZE,
160
+ * defines as PL0 (user), PL1 (fiq/irq/svc/abt/und/sys, ie privileged), and
442
+ RGB_MATRIX_NUM_ROWS * LED_SQUARE_SIZE);
161
+ * PL2 (hyp). The other level which has Read and Write bits is Secure PL1
443
+}
162
+ * (ie any of the privileged modes in Secure state, or Monitor mode).
444
+
163
+ * If a register is accessible in one privilege level it's always accessible
445
+static void dm163_class_init(ObjectClass *klass, void *data)
164
+ * in higher privilege levels too. Since "Secure PL1" also follows this rule
446
+{
165
+ * (ie anything visible in PL2 is visible in S-PL1, some things are only
447
+ DeviceClass *dc = DEVICE_CLASS(klass);
166
+ * visible in S-PL1) but "Secure PL1" is a bit of a mouthful, we bend the
448
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
167
+ * terminology a little and call this PL3.
449
+
168
+ * In AArch64 things are somewhat simpler as the PLx bits line up exactly
450
+ dc->desc = "DM163";
169
+ * with the ELx exception levels.
451
+ dc->vmsd = &vmstate_dm163;
170
+ *
452
+ dc->realize = dm163_realize;
171
+ * If access permissions for a register are more complex than can be
453
+ rc->phases.hold = dm163_reset_hold;
172
+ * described with these bits, then use a laxer set of restrictions, and
454
+ set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
173
+ * do the more restrictive/complex check inside a helper function.
455
+}
174
+ */
456
+
175
+#define PL3_R 0x80
457
+static const TypeInfo dm163_types[] = {
176
+#define PL3_W 0x40
458
+ {
177
+#define PL2_R (0x20 | PL3_R)
459
+ .name = TYPE_DM163,
178
+#define PL2_W (0x10 | PL3_W)
460
+ .parent = TYPE_DEVICE,
179
+#define PL1_R (0x08 | PL2_R)
461
+ .instance_size = sizeof(DM163State),
180
+#define PL1_W (0x04 | PL2_W)
462
+ .class_init = dm163_class_init
181
+#define PL0_R (0x02 | PL1_R)
463
+ }
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
+};
464
+};
367
+
465
+
368
+/*
466
+DEFINE_TYPES(dm163_types)
369
+ * Macros which are lvalues for the field in CPUARMState for the
467
diff --git a/hw/display/Kconfig b/hw/display/Kconfig
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
468
index XXXXXXX..XXXXXXX 100644
450
--- a/target/arm/cpu.h
469
--- a/hw/display/Kconfig
451
+++ b/target/arm/cpu.h
470
+++ b/hw/display/Kconfig
452
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
471
@@ -XXX,XX +XXX,XX @@ config XLNX_DISPLAYPORT
453
return kvmid;
472
bool
454
}
473
# defaults to "N", enabled by specific boards
455
474
depends on PIXMAN
456
-/* ARMCPRegInfo type field bits. If the SPECIAL bit is set this is a
475
+
457
- * special-behaviour cp reg and bits [11..8] indicate what behaviour
476
+config DM163
458
- * it has. Otherwise it is a simple cp reg, where CONST indicates that
477
+ bool
459
- * TCG can assume the value to be constant (ie load at translate time)
478
diff --git a/hw/display/meson.build b/hw/display/meson.build
460
- * and 64BIT indicates a 64 bit wide coprocessor register. SUPPRESS_TB_END
461
- * indicates that the TB should not be ended after a write to this register
462
- * (the default is that the TB ends after cp writes). OVERRIDE permits
463
- * a register definition to override a previous definition for the
464
- * same (cp, is64, crn, crm, opc1, opc2) tuple: either the new or the
465
- * old must have the OVERRIDE bit set.
466
- * ALIAS indicates that this register is an alias view of some underlying
467
- * state which is also visible via another register, and that the other
468
- * register is handling migration and reset; registers marked ALIAS will not be
469
- * migrated but may have their state set by syncing of register state from KVM.
470
- * NO_RAW indicates that this register has no underlying state and does not
471
- * support raw access for state saving/loading; it will not be used for either
472
- * migration or KVM state synchronization. (Typically this is for "registers"
473
- * which are actually used as instructions for cache maintenance and so on.)
474
- * IO indicates that this register does I/O and therefore its accesses
475
- * need to be marked with gen_io_start() and also end the TB. In particular,
476
- * registers which implement clocks or timers require this.
477
- * RAISES_EXC is for when the read or write hook might raise an exception;
478
- * the generated code will synchronize the CPU state before calling the hook
479
- * so that it is safe for the hook to call raise_exception().
480
- * NEWEL is for writes to registers that might change the exception
481
- * level - typically on older ARM chips. For those cases we need to
482
- * re-read the new el when recomputing the translation flags.
483
- */
484
-#define ARM_CP_SPECIAL 0x0001
485
-#define ARM_CP_CONST 0x0002
486
-#define ARM_CP_64BIT 0x0004
487
-#define ARM_CP_SUPPRESS_TB_END 0x0008
488
-#define ARM_CP_OVERRIDE 0x0010
489
-#define ARM_CP_ALIAS 0x0020
490
-#define ARM_CP_IO 0x0040
491
-#define ARM_CP_NO_RAW 0x0080
492
-#define ARM_CP_NOP (ARM_CP_SPECIAL | 0x0100)
493
-#define ARM_CP_WFI (ARM_CP_SPECIAL | 0x0200)
494
-#define ARM_CP_NZCV (ARM_CP_SPECIAL | 0x0300)
495
-#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | 0x0400)
496
-#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | 0x0500)
497
-#define ARM_CP_DC_GVA (ARM_CP_SPECIAL | 0x0600)
498
-#define ARM_CP_DC_GZVA (ARM_CP_SPECIAL | 0x0700)
499
-#define ARM_LAST_SPECIAL ARM_CP_DC_GZVA
500
-#define ARM_CP_FPU 0x1000
501
-#define ARM_CP_SVE 0x2000
502
-#define ARM_CP_NO_GDB 0x4000
503
-#define ARM_CP_RAISES_EXC 0x8000
504
-#define ARM_CP_NEWEL 0x10000
505
-/* Used only as a terminator for ARMCPRegInfo lists */
506
-#define ARM_CP_SENTINEL 0xfffff
507
-/* Mask of only the flag bits in a type field */
508
-#define ARM_CP_FLAG_MASK 0x1f0ff
509
-
510
-/* Valid values for ARMCPRegInfo state field, indicating which of
511
- * the AArch32 and AArch64 execution states this register is visible in.
512
- * If the reginfo doesn't explicitly specify then it is AArch32 only.
513
- * If the reginfo is declared to be visible in both states then a second
514
- * reginfo is synthesised for the AArch32 view of the AArch64 register,
515
- * such that the AArch32 view is the lower 32 bits of the AArch64 one.
516
- * Note that we rely on the values of these enums as we iterate through
517
- * the various states in some places.
518
- */
519
-enum {
520
- ARM_CP_STATE_AA32 = 0,
521
- ARM_CP_STATE_AA64 = 1,
522
- ARM_CP_STATE_BOTH = 2,
523
-};
524
-
525
-/* ARM CP register secure state flags. These flags identify security state
526
- * attributes for a given CP register entry.
527
- * The existence of both or neither secure and non-secure flags indicates that
528
- * the register has both a secure and non-secure hash entry. A single one of
529
- * these flags causes the register to only be hashed for the specified
530
- * security state.
531
- * Although definitions may have any combination of the S/NS bits, each
532
- * registered entry will only have one to identify whether the entry is secure
533
- * or non-secure.
534
- */
535
-enum {
536
- ARM_CP_SECSTATE_S = (1 << 0), /* bit[0]: Secure state register */
537
- ARM_CP_SECSTATE_NS = (1 << 1), /* bit[1]: Non-secure state register */
538
-};
539
-
540
-/* Return true if cptype is a valid type field. This is used to try to
541
- * catch errors where the sentinel has been accidentally left off the end
542
- * of a list of registers.
543
- */
544
-static inline bool cptype_valid(int cptype)
545
-{
546
- return ((cptype & ~ARM_CP_FLAG_MASK) == 0)
547
- || ((cptype & ARM_CP_SPECIAL) &&
548
- ((cptype & ~ARM_CP_FLAG_MASK) <= ARM_LAST_SPECIAL));
549
-}
550
-
551
-/* Access rights:
552
- * We define bits for Read and Write access for what rev C of the v7-AR ARM ARM
553
- * defines as PL0 (user), PL1 (fiq/irq/svc/abt/und/sys, ie privileged), and
554
- * PL2 (hyp). The other level which has Read and Write bits is Secure PL1
555
- * (ie any of the privileged modes in Secure state, or Monitor mode).
556
- * If a register is accessible in one privilege level it's always accessible
557
- * in higher privilege levels too. Since "Secure PL1" also follows this rule
558
- * (ie anything visible in PL2 is visible in S-PL1, some things are only
559
- * visible in S-PL1) but "Secure PL1" is a bit of a mouthful, we bend the
560
- * terminology a little and call this PL3.
561
- * In AArch64 things are somewhat simpler as the PLx bits line up exactly
562
- * with the ELx exception levels.
563
- *
564
- * If access permissions for a register are more complex than can be
565
- * described with these bits, then use a laxer set of restrictions, and
566
- * do the more restrictive/complex check inside a helper function.
567
- */
568
-#define PL3_R 0x80
569
-#define PL3_W 0x40
570
-#define PL2_R (0x20 | PL3_R)
571
-#define PL2_W (0x10 | PL3_W)
572
-#define PL1_R (0x08 | PL2_R)
573
-#define PL1_W (0x04 | PL2_W)
574
-#define PL0_R (0x02 | PL1_R)
575
-#define PL0_W (0x01 | PL1_W)
576
-
577
-/*
578
- * For user-mode some registers are accessible to EL0 via a kernel
579
- * trap-and-emulate ABI. In this case we define the read permissions
580
- * as actually being PL0_R. However some bits of any given register
581
- * may still be masked.
582
- */
583
-#ifdef CONFIG_USER_ONLY
584
-#define PL0U_R PL0_R
585
-#else
586
-#define PL0U_R PL1_R
587
-#endif
588
-
589
-#define PL3_RW (PL3_R | PL3_W)
590
-#define PL2_RW (PL2_R | PL2_W)
591
-#define PL1_RW (PL1_R | PL1_W)
592
-#define PL0_RW (PL0_R | PL0_W)
593
-
594
/* Return the highest implemented Exception Level */
595
static inline int arm_highest_el(CPUARMState *env)
596
{
597
@@ -XXX,XX +XXX,XX @@ static inline int arm_current_el(CPUARMState *env)
598
}
599
}
600
601
-typedef struct ARMCPRegInfo ARMCPRegInfo;
602
-
603
-typedef enum CPAccessResult {
604
- /* Access is permitted */
605
- CP_ACCESS_OK = 0,
606
- /* Access fails due to a configurable trap or enable which would
607
- * result in a categorized exception syndrome giving information about
608
- * the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6,
609
- * 0xc or 0x18). The exception is taken to the usual target EL (EL1 or
610
- * PL1 if in EL0, otherwise to the current EL).
611
- */
612
- CP_ACCESS_TRAP = 1,
613
- /* Access fails and results in an exception syndrome 0x0 ("uncategorized").
614
- * Note that this is not a catch-all case -- the set of cases which may
615
- * result in this failure is specifically defined by the architecture.
616
- */
617
- CP_ACCESS_TRAP_UNCATEGORIZED = 2,
618
- /* As CP_ACCESS_TRAP, but for traps directly to EL2 or EL3 */
619
- CP_ACCESS_TRAP_EL2 = 3,
620
- CP_ACCESS_TRAP_EL3 = 4,
621
- /* As CP_ACCESS_UNCATEGORIZED, but for traps directly to EL2 or EL3 */
622
- CP_ACCESS_TRAP_UNCATEGORIZED_EL2 = 5,
623
- CP_ACCESS_TRAP_UNCATEGORIZED_EL3 = 6,
624
-} CPAccessResult;
625
-
626
-/* Access functions for coprocessor registers. These cannot fail and
627
- * may not raise exceptions.
628
- */
629
-typedef uint64_t CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque);
630
-typedef void CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
631
- uint64_t value);
632
-/* Access permission check functions for coprocessor registers. */
633
-typedef CPAccessResult CPAccessFn(CPUARMState *env,
634
- const ARMCPRegInfo *opaque,
635
- bool isread);
636
-/* Hook function for register reset */
637
-typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque);
638
-
639
-#define CP_ANY 0xff
640
-
641
-/* Definition of an ARM coprocessor register */
642
-struct ARMCPRegInfo {
643
- /* Name of register (useful mainly for debugging, need not be unique) */
644
- const char *name;
645
- /* Location of register: coprocessor number and (crn,crm,opc1,opc2)
646
- * tuple. Any of crm, opc1 and opc2 may be CP_ANY to indicate a
647
- * 'wildcard' field -- any value of that field in the MRC/MCR insn
648
- * will be decoded to this register. The register read and write
649
- * callbacks will be passed an ARMCPRegInfo with the crn/crm/opc1/opc2
650
- * used by the program, so it is possible to register a wildcard and
651
- * then behave differently on read/write if necessary.
652
- * For 64 bit registers, only crm and opc1 are relevant; crn and opc2
653
- * must both be zero.
654
- * For AArch64-visible registers, opc0 is also used.
655
- * Since there are no "coprocessors" in AArch64, cp is purely used as a
656
- * way to distinguish (for KVM's benefit) guest-visible system registers
657
- * from demuxed ones provided to preserve the "no side effects on
658
- * KVM register read/write from QEMU" semantics. cp==0x13 is guest
659
- * visible (to match KVM's encoding); cp==0 will be converted to
660
- * cp==0x13 when the ARMCPRegInfo is registered, for convenience.
661
- */
662
- uint8_t cp;
663
- uint8_t crn;
664
- uint8_t crm;
665
- uint8_t opc0;
666
- uint8_t opc1;
667
- uint8_t opc2;
668
- /* Execution state in which this register is visible: ARM_CP_STATE_* */
669
- int state;
670
- /* Register type: ARM_CP_* bits/values */
671
- int type;
672
- /* Access rights: PL*_[RW] */
673
- int access;
674
- /* Security state: ARM_CP_SECSTATE_* bits/values */
675
- int secure;
676
- /* The opaque pointer passed to define_arm_cp_regs_with_opaque() when
677
- * this register was defined: can be used to hand data through to the
678
- * register read/write functions, since they are passed the ARMCPRegInfo*.
679
- */
680
- void *opaque;
681
- /* Value of this register, if it is ARM_CP_CONST. Otherwise, if
682
- * fieldoffset is non-zero, the reset value of the register.
683
- */
684
- uint64_t resetvalue;
685
- /* Offset of the field in CPUARMState for this register.
686
- *
687
- * This is not needed if either:
688
- * 1. type is ARM_CP_CONST or one of the ARM_CP_SPECIALs
689
- * 2. both readfn and writefn are specified
690
- */
691
- ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
692
-
693
- /* Offsets of the secure and non-secure fields in CPUARMState for the
694
- * register if it is banked. These fields are only used during the static
695
- * registration of a register. During hashing the bank associated
696
- * with a given security state is copied to fieldoffset which is used from
697
- * there on out.
698
- *
699
- * It is expected that register definitions use either fieldoffset or
700
- * bank_fieldoffsets in the definition but not both. It is also expected
701
- * that both bank offsets are set when defining a banked register. This
702
- * use indicates that a register is banked.
703
- */
704
- ptrdiff_t bank_fieldoffsets[2];
705
-
706
- /* Function for making any access checks for this register in addition to
707
- * those specified by the 'access' permissions bits. If NULL, no extra
708
- * checks required. The access check is performed at runtime, not at
709
- * translate time.
710
- */
711
- CPAccessFn *accessfn;
712
- /* Function for handling reads of this register. If NULL, then reads
713
- * will be done by loading from the offset into CPUARMState specified
714
- * by fieldoffset.
715
- */
716
- CPReadFn *readfn;
717
- /* Function for handling writes of this register. If NULL, then writes
718
- * will be done by writing to the offset into CPUARMState specified
719
- * by fieldoffset.
720
- */
721
- CPWriteFn *writefn;
722
- /* Function for doing a "raw" read; used when we need to copy
723
- * coprocessor state to the kernel for KVM or out for
724
- * migration. This only needs to be provided if there is also a
725
- * readfn and it has side effects (for instance clear-on-read bits).
726
- */
727
- CPReadFn *raw_readfn;
728
- /* Function for doing a "raw" write; used when we need to copy KVM
729
- * kernel coprocessor state into userspace, or for inbound
730
- * migration. This only needs to be provided if there is also a
731
- * writefn and it masks out "unwritable" bits or has write-one-to-clear
732
- * or similar behaviour.
733
- */
734
- CPWriteFn *raw_writefn;
735
- /* Function for resetting the register. If NULL, then reset will be done
736
- * by writing resetvalue to the field specified in fieldoffset. If
737
- * fieldoffset is 0 then no reset will be done.
738
- */
739
- CPResetFn *resetfn;
740
-
741
- /*
742
- * "Original" writefn and readfn.
743
- * For ARMv8.1-VHE register aliases, we overwrite the read/write
744
- * accessor functions of various EL1/EL0 to perform the runtime
745
- * check for which sysreg should actually be modified, and then
746
- * forwards the operation. Before overwriting the accessors,
747
- * the original function is copied here, so that accesses that
748
- * really do go to the EL1/EL0 version proceed normally.
749
- * (The corresponding EL2 register is linked via opaque.)
750
- */
751
- CPReadFn *orig_readfn;
752
- CPWriteFn *orig_writefn;
753
-};
754
-
755
-/* Macros which are lvalues for the field in CPUARMState for the
756
- * ARMCPRegInfo *ri.
757
- */
758
-#define CPREG_FIELD32(env, ri) \
759
- (*(uint32_t *)((char *)(env) + (ri)->fieldoffset))
760
-#define CPREG_FIELD64(env, ri) \
761
- (*(uint64_t *)((char *)(env) + (ri)->fieldoffset))
762
-
763
-#define REGINFO_SENTINEL { .type = ARM_CP_SENTINEL }
764
-
765
-void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
766
- const ARMCPRegInfo *regs, void *opaque);
767
-void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
768
- const ARMCPRegInfo *regs, void *opaque);
769
-static inline void define_arm_cp_regs(ARMCPU *cpu, const ARMCPRegInfo *regs)
770
-{
771
- define_arm_cp_regs_with_opaque(cpu, regs, 0);
772
-}
773
-static inline void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs)
774
-{
775
- define_one_arm_cp_reg_with_opaque(cpu, regs, 0);
776
-}
777
-const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp);
778
-
779
-/*
780
- * Definition of an ARM co-processor register as viewed from
781
- * userspace. This is used for presenting sanitised versions of
782
- * registers to userspace when emulating the Linux AArch64 CPU
783
- * ID/feature ABI (advertised as HWCAP_CPUID).
784
- */
785
-typedef struct ARMCPRegUserSpaceInfo {
786
- /* Name of register */
787
- const char *name;
788
-
789
- /* Is the name actually a glob pattern */
790
- bool is_glob;
791
-
792
- /* Only some bits are exported to user space */
793
- uint64_t exported_bits;
794
-
795
- /* Fixed bits are applied after the mask */
796
- uint64_t fixed_bits;
797
-} ARMCPRegUserSpaceInfo;
798
-
799
-#define REGUSERINFO_SENTINEL { .name = NULL }
800
-
801
-void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods);
802
-
803
-/* CPWriteFn that can be used to implement writes-ignored behaviour */
804
-void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
805
- uint64_t value);
806
-/* CPReadFn that can be used for read-as-zero behaviour */
807
-uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri);
808
-
809
-/* CPResetFn that does nothing, for use if no reset is required even
810
- * if fieldoffset is non zero.
811
- */
812
-void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque);
813
-
814
-/* Return true if this reginfo struct's field in the cpu state struct
815
- * is 64 bits wide.
816
- */
817
-static inline bool cpreg_field_is_64bit(const ARMCPRegInfo *ri)
818
-{
819
- return (ri->state == ARM_CP_STATE_AA64) || (ri->type & ARM_CP_64BIT);
820
-}
821
-
822
-static inline bool cp_access_ok(int current_el,
823
- const ARMCPRegInfo *ri, int isread)
824
-{
825
- return (ri->access >> ((current_el * 2) + isread)) & 1;
826
-}
827
-
828
-/* Raw read of a coprocessor register (as needed for migration, etc) */
829
-uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri);
830
-
831
/**
832
* write_list_to_cpustate
833
* @cpu: ARMCPU
834
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
835
index XXXXXXX..XXXXXXX 100644
479
index XXXXXXX..XXXXXXX 100644
836
--- a/hw/arm/pxa2xx.c
480
--- a/hw/display/meson.build
837
+++ b/hw/arm/pxa2xx.c
481
+++ b/hw/display/meson.build
838
@@ -XXX,XX +XXX,XX @@
482
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_NEXTCUBE', if_true: files('next-fb.c'))
839
#include "qemu/cutils.h"
483
840
#include "qemu/log.h"
484
system_ss.add(when: 'CONFIG_VGA', if_true: files('vga.c'))
841
#include "qom/object.h"
485
system_ss.add(when: 'CONFIG_VIRTIO', if_true: files('virtio-dmabuf.c'))
842
+#include "target/arm/cpregs.h"
486
+system_ss.add(when: 'CONFIG_DM163', if_true: files('dm163.c'))
843
487
844
static struct {
488
if (config_all_devices.has_key('CONFIG_VGA_CIRRUS') or
845
hwaddr io_base;
489
config_all_devices.has_key('CONFIG_VGA_PCI') or
846
diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c
490
diff --git a/hw/display/trace-events b/hw/display/trace-events
847
index XXXXXXX..XXXXXXX 100644
491
index XXXXXXX..XXXXXXX 100644
848
--- a/hw/arm/pxa2xx_pic.c
492
--- a/hw/display/trace-events
849
+++ b/hw/arm/pxa2xx_pic.c
493
+++ b/hw/display/trace-events
850
@@ -XXX,XX +XXX,XX @@
494
@@ -XXX,XX +XXX,XX @@ macfb_ctrl_write(uint64_t addr, uint64_t value, unsigned int size) "addr 0x%"PRI
851
#include "hw/sysbus.h"
495
macfb_sense_read(uint32_t value) "video sense: 0x%"PRIx32
852
#include "migration/vmstate.h"
496
macfb_sense_write(uint32_t value) "video sense: 0x%"PRIx32
853
#include "qom/object.h"
497
macfb_update_mode(uint32_t width, uint32_t height, uint8_t depth) "setting mode to width %"PRId32 " height %"PRId32 " size %d"
854
+#include "target/arm/cpregs.h"
498
+
855
499
+# dm163.c
856
#define ICIP    0x00    /* Interrupt Controller IRQ Pending register */
500
+dm163_redraw(uint8_t redraw) "0x%02x"
857
#define ICMR    0x04    /* Interrupt Controller Mask register */
501
+dm163_dck(unsigned new_state) "dck : %u"
858
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
502
+dm163_en_b(unsigned new_state) "en_b : %u"
859
index XXXXXXX..XXXXXXX 100644
503
+dm163_rst_b(unsigned new_state) "rst_b : %u"
860
--- a/hw/intc/arm_gicv3_cpuif.c
504
+dm163_lat_b(unsigned new_state) "lat_b : %u"
861
+++ b/hw/intc/arm_gicv3_cpuif.c
505
+dm163_sin(unsigned new_state) "sin : %u"
862
@@ -XXX,XX +XXX,XX @@
506
+dm163_selbk(unsigned new_state) "selbk : %u"
863
#include "gicv3_internal.h"
507
+dm163_activated_rows(int new_state) "Activated rows : 0x%" PRIx32 ""
864
#include "hw/irq.h"
508
+dm163_bits_ppi(unsigned dest_width) "dest_width : %u"
865
#include "cpu.h"
509
+dm163_leds(int led, uint32_t value) "led %d: 0x%x"
866
+#include "target/arm/cpregs.h"
510
+dm163_channels(int channel, uint8_t value) "channel %d: 0x%x"
867
511
+dm163_refresh_rate(uint32_t rr) "refresh rate %d"
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
+
880
881
#ifdef DEBUG_GICV3_KVM
882
#define DPRINTF(fmt, ...) \
883
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
884
index XXXXXXX..XXXXXXX 100644
885
--- a/target/arm/cpu.c
886
+++ b/target/arm/cpu.c
887
@@ -XXX,XX +XXX,XX @@
888
#include "kvm_arm.h"
889
#include "disas/capstone.h"
890
#include "fpu/softfloat.h"
891
+#include "cpregs.h"
892
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
--
512
--
996
2.25.1
513
2.34.1
997
514
998
515
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
2
3
Rearrange the values of the enumerators of CPAccessResult
3
Exposing SYSCFG inputs to the SoC is practical in order to wire the SoC
4
so that we may directly extract the target el. For the two
4
to the optional DM163 display from the board code (GPIOs outputs need
5
special cases in access_check_cp_reg, use CPAccessResult.
5
to be connected to both SYSCFG inputs and DM163 inputs).
6
6
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
STM32L4x5 SYSCFG in-irq interception needed to be changed accordingly.
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
10
Message-id: 20220501055028.646596-3-richard.henderson@linaro.org
10
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Message-id: 20240424200929.240921-3-ines.varhol@telecom-paris.fr
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
14
---
13
target/arm/cpregs.h | 26 ++++++++++++--------
15
hw/arm/stm32l4x5_soc.c | 6 ++++--
14
target/arm/op_helper.c | 56 +++++++++++++++++++++---------------------
16
tests/qtest/stm32l4x5_gpio-test.c | 13 ++++++++-----
15
2 files changed, 44 insertions(+), 38 deletions(-)
17
tests/qtest/stm32l4x5_syscfg-test.c | 17 ++++++++++-------
18
3 files changed, 22 insertions(+), 14 deletions(-)
16
19
17
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
20
diff --git a/hw/arm/stm32l4x5_soc.c b/hw/arm/stm32l4x5_soc.c
18
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpregs.h
22
--- a/hw/arm/stm32l4x5_soc.c
20
+++ b/target/arm/cpregs.h
23
+++ b/hw/arm/stm32l4x5_soc.c
21
@@ -XXX,XX +XXX,XX @@ static inline bool cptype_valid(int cptype)
24
@@ -XXX,XX +XXX,XX @@
22
typedef enum CPAccessResult {
25
/*
23
/* Access is permitted */
26
* STM32L4x5 SoC family
24
CP_ACCESS_OK = 0,
27
*
25
+
28
- * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
26
+ /*
29
- * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
27
+ * Combined with one of the following, the low 2 bits indicate the
30
+ * Copyright (c) 2023-2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
28
+ * target exception level. If 0, the exception is taken to the usual
31
+ * Copyright (c) 2023-2024 Inès Varhol <ines.varhol@telecom-paris.fr>
29
+ * target EL (EL1 or PL1 if in EL0, otherwise to the current EL).
32
*
30
+ */
33
* SPDX-License-Identifier: GPL-2.0-or-later
31
+ CP_ACCESS_EL_MASK = 3,
34
*
32
+
35
@@ -XXX,XX +XXX,XX @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
33
/*
34
* Access fails due to a configurable trap or enable which would
35
* result in a categorized exception syndrome giving information about
36
* the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6,
37
- * 0xc or 0x18). The exception is taken to the usual target EL (EL1 or
38
- * PL1 if in EL0, otherwise to the current EL).
39
+ * 0xc or 0x18).
40
*/
41
- CP_ACCESS_TRAP = 1,
42
+ CP_ACCESS_TRAP = (1 << 2),
43
+ CP_ACCESS_TRAP_EL2 = CP_ACCESS_TRAP | 2,
44
+ CP_ACCESS_TRAP_EL3 = CP_ACCESS_TRAP | 3,
45
+
46
/*
47
* Access fails and results in an exception syndrome 0x0 ("uncategorized").
48
* Note that this is not a catch-all case -- the set of cases which may
49
* result in this failure is specifically defined by the architecture.
50
*/
51
- CP_ACCESS_TRAP_UNCATEGORIZED = 2,
52
- /* As CP_ACCESS_TRAP, but for traps directly to EL2 or EL3 */
53
- CP_ACCESS_TRAP_EL2 = 3,
54
- CP_ACCESS_TRAP_EL3 = 4,
55
- /* As CP_ACCESS_UNCATEGORIZED, but for traps directly to EL2 or EL3 */
56
- CP_ACCESS_TRAP_UNCATEGORIZED_EL2 = 5,
57
- CP_ACCESS_TRAP_UNCATEGORIZED_EL3 = 6,
58
+ CP_ACCESS_TRAP_UNCATEGORIZED = (2 << 2),
59
+ CP_ACCESS_TRAP_UNCATEGORIZED_EL2 = CP_ACCESS_TRAP_UNCATEGORIZED | 2,
60
+ CP_ACCESS_TRAP_UNCATEGORIZED_EL3 = CP_ACCESS_TRAP_UNCATEGORIZED | 3,
61
} CPAccessResult;
62
63
typedef struct ARMCPRegInfo ARMCPRegInfo;
64
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/op_helper.c
67
+++ b/target/arm/op_helper.c
68
@@ -XXX,XX +XXX,XX @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
69
uint32_t isread)
70
{
71
const ARMCPRegInfo *ri = rip;
72
+ CPAccessResult res = CP_ACCESS_OK;
73
int target_el;
74
75
if (arm_feature(env, ARM_FEATURE_XSCALE) && ri->cp < 14
76
&& extract32(env->cp15.c15_cpar, ri->cp, 1) == 0) {
77
- raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env));
78
+ res = CP_ACCESS_TRAP;
79
+ goto fail;
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
}
36
}
92
}
37
}
93
38
94
- if (!ri->accessfn) {
39
+ qdev_pass_gpios(DEVICE(&s->syscfg), dev_soc, NULL);
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
+
40
+
154
raise_exception(env, EXCP_UDEF, syndrome, target_el);
41
/* EXTI device */
42
busdev = SYS_BUS_DEVICE(&s->exti);
43
if (!sysbus_realize(busdev, errp)) {
44
diff --git a/tests/qtest/stm32l4x5_gpio-test.c b/tests/qtest/stm32l4x5_gpio-test.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/tests/qtest/stm32l4x5_gpio-test.c
47
+++ b/tests/qtest/stm32l4x5_gpio-test.c
48
@@ -XXX,XX +XXX,XX @@
49
#define OTYPER_PUSH_PULL 0
50
#define OTYPER_OPEN_DRAIN 1
51
52
+/* SoC forwards GPIOs to SysCfg */
53
+#define SYSCFG "/machine/soc"
54
+
55
const uint32_t moder_reset[NUM_GPIOS] = {
56
0xABFFFFFF,
57
0xFFFFFEBF,
58
@@ -XXX,XX +XXX,XX @@ static void test_gpio_output_mode(const void *data)
59
uint32_t gpio = test_gpio_addr(data);
60
unsigned int gpio_id = get_gpio_id(gpio);
61
62
- qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
63
+ qtest_irq_intercept_in(global_qtest, SYSCFG);
64
65
/* Set a bit in ODR and check nothing happens */
66
gpio_set_bit(gpio, ODR, pin, 1);
67
@@ -XXX,XX +XXX,XX @@ static void test_gpio_input_mode(const void *data)
68
uint32_t gpio = test_gpio_addr(data);
69
unsigned int gpio_id = get_gpio_id(gpio);
70
71
- qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
72
+ qtest_irq_intercept_in(global_qtest, SYSCFG);
73
74
/* Configure a line as input, raise it, and check that the pin is high */
75
gpio_set_2bits(gpio, MODER, pin, MODER_INPUT);
76
@@ -XXX,XX +XXX,XX @@ static void test_pull_up_pull_down(const void *data)
77
uint32_t gpio = test_gpio_addr(data);
78
unsigned int gpio_id = get_gpio_id(gpio);
79
80
- qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
81
+ qtest_irq_intercept_in(global_qtest, SYSCFG);
82
83
/* Configure a line as input with pull-up, check the line is set high */
84
gpio_set_2bits(gpio, MODER, pin, MODER_INPUT);
85
@@ -XXX,XX +XXX,XX @@ static void test_push_pull(const void *data)
86
uint32_t gpio = test_gpio_addr(data);
87
uint32_t gpio2 = GPIO_BASE_ADDR + (GPIO_H - gpio);
88
89
- qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
90
+ qtest_irq_intercept_in(global_qtest, SYSCFG);
91
92
/* Setting a line high externally, configuring it in push-pull output */
93
/* And checking the pin was disconnected */
94
@@ -XXX,XX +XXX,XX @@ static void test_open_drain(const void *data)
95
uint32_t gpio = test_gpio_addr(data);
96
uint32_t gpio2 = GPIO_BASE_ADDR + (GPIO_H - gpio);
97
98
- qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
99
+ qtest_irq_intercept_in(global_qtest, SYSCFG);
100
101
/* Setting a line high externally, configuring it in open-drain output */
102
/* And checking the pin was disconnected */
103
diff --git a/tests/qtest/stm32l4x5_syscfg-test.c b/tests/qtest/stm32l4x5_syscfg-test.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/tests/qtest/stm32l4x5_syscfg-test.c
106
+++ b/tests/qtest/stm32l4x5_syscfg-test.c
107
@@ -XXX,XX +XXX,XX @@
108
/*
109
* QTest testcase for STM32L4x5_SYSCFG
110
*
111
- * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
112
- * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
113
+ * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
114
+ * Copyright (c) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
115
*
116
* This work is licensed under the terms of the GNU GPL, version 2 or later.
117
* See the COPYING file in the top-level directory.
118
@@ -XXX,XX +XXX,XX @@
119
#define SYSCFG_SWPR2 0x28
120
#define INVALID_ADDR 0x2C
121
122
+/* SoC forwards GPIOs to SysCfg */
123
+#define SYSCFG "/machine/soc"
124
+#define EXTI "/machine/soc/exti"
125
+
126
static void syscfg_writel(unsigned int offset, uint32_t value)
127
{
128
writel(SYSCFG_BASE_ADDR + offset, value);
129
@@ -XXX,XX +XXX,XX @@ static uint32_t syscfg_readl(unsigned int offset)
130
131
static void syscfg_set_irq(int num, int level)
132
{
133
- qtest_set_irq_in(global_qtest, "/machine/soc/syscfg",
134
- NULL, num, level);
135
+ qtest_set_irq_in(global_qtest, SYSCFG, NULL, num, level);
155
}
136
}
156
137
138
static void system_reset(void)
139
@@ -XXX,XX +XXX,XX @@ static void test_interrupt(void)
140
* Test that GPIO rising lines result in an irq
141
* with the right configuration
142
*/
143
- qtest_irq_intercept_in(global_qtest, "/machine/soc/exti");
144
+ qtest_irq_intercept_in(global_qtest, EXTI);
145
146
/* GPIOA is the default source for EXTI lines 0 to 15 */
147
148
@@ -XXX,XX +XXX,XX @@ static void test_irq_pin_multiplexer(void)
149
* Test that syscfg irq sets the right exti irq
150
*/
151
152
- qtest_irq_intercept_in(global_qtest, "/machine/soc/exti");
153
+ qtest_irq_intercept_in(global_qtest, EXTI);
154
155
syscfg_set_irq(0, 1);
156
157
@@ -XXX,XX +XXX,XX @@ static void test_irq_gpio_multiplexer(void)
158
* Test that an irq is generated only by the right GPIO
159
*/
160
161
- qtest_irq_intercept_in(global_qtest, "/machine/soc/exti");
162
+ qtest_irq_intercept_in(global_qtest, EXTI);
163
164
/* GPIOA is the default source for EXTI lines 0 to 15 */
165
157
--
166
--
158
2.25.1
167
2.34.1
159
168
160
169
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
2
3
Give this enum a name and use in ARMCPRegInfo,
3
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
4
add_cpreg_to_hashtable and define_one_arm_cp_reg_with_opaque.
4
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
5
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Message-id: 20240424200929.240921-4-ines.varhol@telecom-paris.fr
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220501055028.646596-9-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
8
---
12
target/arm/cpregs.h | 6 +++---
9
hw/arm/b-l475e-iot01a.c | 46 ++++++++++++++++++++++++++++-------------
13
target/arm/helper.c | 6 ++++--
10
1 file changed, 32 insertions(+), 14 deletions(-)
14
2 files changed, 7 insertions(+), 5 deletions(-)
15
11
16
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
12
diff --git a/hw/arm/b-l475e-iot01a.c b/hw/arm/b-l475e-iot01a.c
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpregs.h
14
--- a/hw/arm/b-l475e-iot01a.c
19
+++ b/target/arm/cpregs.h
15
+++ b/hw/arm/b-l475e-iot01a.c
20
@@ -XXX,XX +XXX,XX @@ enum {
16
@@ -XXX,XX +XXX,XX @@
21
* Note that we rely on the values of these enums as we iterate through
17
* B-L475E-IOT01A Discovery Kit machine
22
* the various states in some places.
18
* (B-L475E-IOT01A IoT Node)
23
*/
19
*
24
-enum {
20
- * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
25
+typedef enum {
21
- * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
26
ARM_CP_STATE_AA32 = 0,
22
+ * Copyright (c) 2023-2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
27
ARM_CP_STATE_AA64 = 1,
23
+ * Copyright (c) 2023-2024 Inès Varhol <ines.varhol@telecom-paris.fr>
28
ARM_CP_STATE_BOTH = 2,
24
*
29
-};
25
* SPDX-License-Identifier: GPL-2.0-or-later
30
+} CPState;
26
*
31
27
@@ -XXX,XX +XXX,XX @@
32
/*
28
33
* ARM CP register secure state flags. These flags identify security state
29
/* B-L475E-IOT01A implementation is derived from netduinoplus2 */
34
@@ -XXX,XX +XXX,XX @@ struct ARMCPRegInfo {
30
35
uint8_t opc1;
31
-static void b_l475e_iot01a_init(MachineState *machine)
36
uint8_t opc2;
32
+#define TYPE_B_L475E_IOT01A MACHINE_TYPE_NAME("b-l475e-iot01a")
37
/* Execution state in which this register is visible: ARM_CP_STATE_* */
33
+OBJECT_DECLARE_SIMPLE_TYPE(Bl475eMachineState, B_L475E_IOT01A)
38
- int state;
34
+
39
+ CPState state;
35
+typedef struct Bl475eMachineState {
40
/* Register type: ARM_CP_* bits/values */
36
+ MachineState parent_obj;
41
int type;
37
+
42
/* Access rights: PL*_[RW] */
38
+ Stm32l4x5SocState soc;
43
diff --git a/target/arm/helper.c b/target/arm/helper.c
39
+} Bl475eMachineState;
44
index XXXXXXX..XXXXXXX 100644
40
+
45
--- a/target/arm/helper.c
41
+static void bl475e_init(MachineState *machine)
46
+++ b/target/arm/helper.c
42
{
47
@@ -XXX,XX +XXX,XX @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
43
+ Bl475eMachineState *s = B_L475E_IOT01A(machine);
44
const Stm32l4x5SocClass *sc;
45
- DeviceState *dev;
46
47
- dev = qdev_new(TYPE_STM32L4X5XG_SOC);
48
- object_property_add_child(OBJECT(machine), "soc", OBJECT(dev));
49
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
50
+ object_initialize_child(OBJECT(machine), "soc", &s->soc,
51
+ TYPE_STM32L4X5XG_SOC);
52
+ sysbus_realize(SYS_BUS_DEVICE(&s->soc), &error_fatal);
53
54
- sc = STM32L4X5_SOC_GET_CLASS(dev);
55
- armv7m_load_kernel(ARM_CPU(first_cpu),
56
- machine->kernel_filename,
57
- 0, sc->flash_size);
58
+ sc = STM32L4X5_SOC_GET_CLASS(&s->soc);
59
+ armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0,
60
+ sc->flash_size);
48
}
61
}
49
62
50
static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
63
-static void b_l475e_iot01a_machine_init(MachineClass *mc)
51
- void *opaque, int state, int secstate,
64
+static void bl475e_machine_init(ObjectClass *oc, void *data)
52
+ void *opaque, CPState state, int secstate,
53
int crm, int opc1, int opc2,
54
const char *name)
55
{
65
{
56
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
66
+ MachineClass *mc = MACHINE_CLASS(oc);
57
* bits; the ARM_CP_64BIT* flag applies only to the AArch32 view of
67
static const char *machine_valid_cpu_types[] = {
58
* the register, if any.
68
ARM_CPU_TYPE_NAME("cortex-m4"),
59
*/
69
NULL
60
- int crm, opc1, opc2, state;
70
};
61
+ int crm, opc1, opc2;
71
mc->desc = "B-L475E-IOT01A Discovery Kit (Cortex-M4)";
62
int crmmin = (r->crm == CP_ANY) ? 0 : r->crm;
72
- mc->init = b_l475e_iot01a_init;
63
int crmmax = (r->crm == CP_ANY) ? 15 : r->crm;
73
+ mc->init = bl475e_init;
64
int opc1min = (r->opc1 == CP_ANY) ? 0 : r->opc1;
74
mc->valid_cpu_types = machine_valid_cpu_types;
65
int opc1max = (r->opc1 == CP_ANY) ? 7 : r->opc1;
75
66
int opc2min = (r->opc2 == CP_ANY) ? 0 : r->opc2;
76
/* SRAM pre-allocated as part of the SoC instantiation */
67
int opc2max = (r->opc2 == CP_ANY) ? 7 : r->opc2;
77
mc->default_ram_size = 0;
68
+ CPState state;
78
}
79
80
-DEFINE_MACHINE("b-l475e-iot01a", b_l475e_iot01a_machine_init)
81
+static const TypeInfo bl475e_machine_type[] = {
82
+ {
83
+ .name = TYPE_B_L475E_IOT01A,
84
+ .parent = TYPE_MACHINE,
85
+ .instance_size = sizeof(Bl475eMachineState),
86
+ .class_init = bl475e_machine_init,
87
+ }
88
+};
69
+
89
+
70
/* 64 bit registers have only CRm and Opc1 fields */
90
+DEFINE_TYPES(bl475e_machine_type)
71
assert(!((r->type & ARM_CP_64BIT) && (r->opc2 || r->crn)));
72
/* op0 only exists in the AArch64 encodings */
73
--
91
--
74
2.25.1
92
2.34.1
75
93
76
94
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
2
3
Perform the override check early, so that it is still done
3
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
4
even when we decide to discard an unreachable cpreg.
4
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
5
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Use assert not printf+abort.
6
Message-id: 20240424200929.240921-5-ines.varhol@telecom-paris.fr
7
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20220501055028.646596-18-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
8
---
13
target/arm/helper.c | 22 ++++++++--------------
9
hw/arm/b-l475e-iot01a.c | 59 +++++++++++++++++++++++++++++++++++++++--
14
1 file changed, 8 insertions(+), 14 deletions(-)
10
hw/arm/Kconfig | 1 +
11
2 files changed, 58 insertions(+), 2 deletions(-)
15
12
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/hw/arm/b-l475e-iot01a.c b/hw/arm/b-l475e-iot01a.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
15
--- a/hw/arm/b-l475e-iot01a.c
19
+++ b/target/arm/helper.c
16
+++ b/hw/arm/b-l475e-iot01a.c
20
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
17
@@ -XXX,XX +XXX,XX @@
21
g_assert_not_reached();
18
#include "hw/boards.h"
22
}
19
#include "hw/qdev-properties.h"
23
20
#include "qemu/error-report.h"
24
+ /* Overriding of an existing definition must be explicitly requested. */
21
-#include "hw/arm/stm32l4x5_soc.h"
25
+ if (!(r->type & ARM_CP_OVERRIDE)) {
22
#include "hw/arm/boot.h"
26
+ const ARMCPRegInfo *oldreg = get_arm_cp_reginfo(cpu->cp_regs, key);
23
+#include "hw/core/split-irq.h"
27
+ if (oldreg) {
24
+#include "hw/arm/stm32l4x5_soc.h"
28
+ assert(oldreg->type & ARM_CP_OVERRIDE);
25
+#include "hw/gpio/stm32l4x5_gpio.h"
26
+#include "hw/display/dm163.h"
27
28
-/* B-L475E-IOT01A implementation is derived from netduinoplus2 */
29
+/* B-L475E-IOT01A implementation is inspired from netduinoplus2 and arduino */
30
+
31
+/*
32
+ * There are actually 14 input pins in the DM163 device.
33
+ * Here the DM163 input pin EN isn't connected to the STM32L4x5
34
+ * GPIOs as the IM120417002 colors shield doesn't actually use
35
+ * this pin to drive the RGB matrix.
36
+ */
37
+#define NUM_DM163_INPUTS 13
38
+
39
+static const unsigned dm163_input[NUM_DM163_INPUTS] = {
40
+ 1 * GPIO_NUM_PINS + 2, /* ROW0 PB2 */
41
+ 0 * GPIO_NUM_PINS + 15, /* ROW1 PA15 */
42
+ 0 * GPIO_NUM_PINS + 2, /* ROW2 PA2 */
43
+ 0 * GPIO_NUM_PINS + 7, /* ROW3 PA7 */
44
+ 0 * GPIO_NUM_PINS + 6, /* ROW4 PA6 */
45
+ 0 * GPIO_NUM_PINS + 5, /* ROW5 PA5 */
46
+ 1 * GPIO_NUM_PINS + 0, /* ROW6 PB0 */
47
+ 0 * GPIO_NUM_PINS + 3, /* ROW7 PA3 */
48
+ 0 * GPIO_NUM_PINS + 4, /* SIN (SDA) PA4 */
49
+ 1 * GPIO_NUM_PINS + 1, /* DCK (SCK) PB1 */
50
+ 2 * GPIO_NUM_PINS + 3, /* RST_B (RST) PC3 */
51
+ 2 * GPIO_NUM_PINS + 4, /* LAT_B (LAT) PC4 */
52
+ 2 * GPIO_NUM_PINS + 5, /* SELBK (SB) PC5 */
53
+};
54
55
#define TYPE_B_L475E_IOT01A MACHINE_TYPE_NAME("b-l475e-iot01a")
56
OBJECT_DECLARE_SIMPLE_TYPE(Bl475eMachineState, B_L475E_IOT01A)
57
@@ -XXX,XX +XXX,XX @@ typedef struct Bl475eMachineState {
58
MachineState parent_obj;
59
60
Stm32l4x5SocState soc;
61
+ SplitIRQ gpio_splitters[NUM_DM163_INPUTS];
62
+ DM163State dm163;
63
} Bl475eMachineState;
64
65
static void bl475e_init(MachineState *machine)
66
{
67
Bl475eMachineState *s = B_L475E_IOT01A(machine);
68
const Stm32l4x5SocClass *sc;
69
+ DeviceState *dev, *gpio_out_splitter;
70
+ unsigned gpio, pin;
71
72
object_initialize_child(OBJECT(machine), "soc", &s->soc,
73
TYPE_STM32L4X5XG_SOC);
74
@@ -XXX,XX +XXX,XX @@ static void bl475e_init(MachineState *machine)
75
sc = STM32L4X5_SOC_GET_CLASS(&s->soc);
76
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0,
77
sc->flash_size);
78
+
79
+ if (object_class_by_name(TYPE_DM163)) {
80
+ object_initialize_child(OBJECT(machine), "dm163",
81
+ &s->dm163, TYPE_DM163);
82
+ dev = DEVICE(&s->dm163);
83
+ qdev_realize(dev, NULL, &error_abort);
84
+
85
+ for (unsigned i = 0; i < NUM_DM163_INPUTS; i++) {
86
+ object_initialize_child(OBJECT(machine), "gpio-out-splitters[*]",
87
+ &s->gpio_splitters[i], TYPE_SPLIT_IRQ);
88
+ gpio_out_splitter = DEVICE(&s->gpio_splitters[i]);
89
+ qdev_prop_set_uint32(gpio_out_splitter, "num-lines", 2);
90
+ qdev_realize(gpio_out_splitter, NULL, &error_fatal);
91
+
92
+ qdev_connect_gpio_out(gpio_out_splitter, 0,
93
+ qdev_get_gpio_in(DEVICE(&s->soc), dm163_input[i]));
94
+ qdev_connect_gpio_out(gpio_out_splitter, 1,
95
+ qdev_get_gpio_in(dev, i));
96
+ gpio = dm163_input[i] / GPIO_NUM_PINS;
97
+ pin = dm163_input[i] % GPIO_NUM_PINS;
98
+ qdev_connect_gpio_out(DEVICE(&s->soc.gpio[gpio]), pin,
99
+ qdev_get_gpio_in(DEVICE(gpio_out_splitter), 0));
29
+ }
100
+ }
30
+ }
101
+ }
31
+
32
/* Combine cpreg and name into one allocation. */
33
name_len = strlen(name) + 1;
34
r2 = g_malloc(sizeof(*r2) + name_len);
35
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
36
assert(!raw_accessors_invalid(r2));
37
}
38
39
- /* Overriding of an existing definition must be explicitly
40
- * requested.
41
- */
42
- if (!(r->type & ARM_CP_OVERRIDE)) {
43
- const ARMCPRegInfo *oldreg = get_arm_cp_reginfo(cpu->cp_regs, key);
44
- if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) {
45
- fprintf(stderr, "Register redefined: cp=%d %d bit "
46
- "crn=%d crm=%d opc1=%d opc2=%d, "
47
- "was %s, now %s\n", r2->cp, 32 + 32 * is64,
48
- r2->crn, r2->crm, r2->opc1, r2->opc2,
49
- oldreg->name, r2->name);
50
- g_assert_not_reached();
51
- }
52
- }
53
g_hash_table_insert(cpu->cp_regs, (gpointer)(uintptr_t)key, r2);
54
}
102
}
55
103
104
static void bl475e_machine_init(ObjectClass *oc, void *data)
105
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
106
index XXXXXXX..XXXXXXX 100644
107
--- a/hw/arm/Kconfig
108
+++ b/hw/arm/Kconfig
109
@@ -XXX,XX +XXX,XX @@ config B_L475E_IOT01A
110
default y
111
depends on TCG && ARM
112
select STM32L4X5_SOC
113
+ imply DM163
114
115
config STM32L4X5_SOC
116
bool
56
--
117
--
57
2.25.1
118
2.34.1
119
120
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
2
3
This controls whether the PACI{A,B}SP instructions trap with BTYPE=3
3
`test_dm163_bank()`
4
(indirect branch from register other than x16/x17). The linux kernel
4
Checks that the pin "sout" of the DM163 led driver outputs the values
5
sets this in bti_enable().
5
received on pin "sin" with the expected latency (depending on the bank).
6
6
7
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/998
7
`test_dm163_gpio_connection()`
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Check that changes to relevant STM32L4x5 GPIO pins are propagated to the
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
DM163 device.
10
Message-id: 20220427042312.294300-1-richard.henderson@linaro.org
10
11
[PMM: remove stray change to makefile comment]
11
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
12
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
13
Acked-by: Thomas Huth <thuth@redhat.com>
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
15
Message-id: 20240424200929.240921-6-ines.varhol@telecom-paris.fr
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
17
---
14
target/arm/cpu.c | 2 ++
18
tests/qtest/dm163-test.c | 194 +++++++++++++++++++++++++++++++++++++++
15
tests/tcg/aarch64/bti-3.c | 42 +++++++++++++++++++++++++++++++
19
tests/qtest/meson.build | 2 +
16
tests/tcg/aarch64/Makefile.target | 6 ++---
20
2 files changed, 196 insertions(+)
17
3 files changed, 47 insertions(+), 3 deletions(-)
21
create mode 100644 tests/qtest/dm163-test.c
18
create mode 100644 tests/tcg/aarch64/bti-3.c
22
19
23
diff --git a/tests/qtest/dm163-test.c b/tests/qtest/dm163-test.c
20
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.c
23
+++ b/target/arm/cpu.c
24
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
25
/* Enable all PAC keys. */
26
env->cp15.sctlr_el[1] |= (SCTLR_EnIA | SCTLR_EnIB |
27
SCTLR_EnDA | SCTLR_EnDB);
28
+ /* Trap on btype=3 for PACIxSP. */
29
+ env->cp15.sctlr_el[1] |= SCTLR_BT0;
30
/* and to the FP/Neon instructions */
31
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3);
32
/* and to the SVE instructions */
33
diff --git a/tests/tcg/aarch64/bti-3.c b/tests/tcg/aarch64/bti-3.c
34
new file mode 100644
24
new file mode 100644
35
index XXXXXXX..XXXXXXX
25
index XXXXXXX..XXXXXXX
36
--- /dev/null
26
--- /dev/null
37
+++ b/tests/tcg/aarch64/bti-3.c
27
+++ b/tests/qtest/dm163-test.c
38
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@
39
+/*
29
+/*
40
+ * BTI vs PACIASP
30
+ * QTest testcase for DM163
31
+ *
32
+ * Copyright (C) 2024 Samuel Tardieu <sam@rfc1149.net>
33
+ * Copyright (C) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
34
+ * Copyright (C) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
35
+ *
36
+ * SPDX-License-Identifier: GPL-2.0-or-later
41
+ */
37
+ */
42
+
38
+
43
+#include "bti-crt.inc.c"
39
+#include "qemu/osdep.h"
44
+
40
+#include "libqtest.h"
45
+static void skip2_sigill(int sig, siginfo_t *info, ucontext_t *uc)
41
+
46
+{
42
+enum DM163_INPUTS {
47
+ uc->uc_mcontext.pc += 8;
43
+ SIN = 8,
48
+ uc->uc_mcontext.pstate = 1;
44
+ DCK = 9,
49
+}
45
+ RST_B = 10,
50
+
46
+ LAT_B = 11,
51
+#define BTYPE_1() \
47
+ SELBK = 12,
52
+ asm("mov %0,#1; adr x16, 1f; br x16; 1: hint #25; mov %0,#0" \
48
+ EN_B = 13
53
+ : "=r"(skipped) : : "x16", "x30")
49
+};
54
+
50
+
55
+#define BTYPE_2() \
51
+#define DEVICE_NAME "/machine/dm163"
56
+ asm("mov %0,#1; adr x16, 1f; blr x16; 1: hint #25; mov %0,#0" \
52
+#define GPIO_OUT(name, value) qtest_set_irq_in(qts, DEVICE_NAME, NULL, name, \
57
+ : "=r"(skipped) : : "x16", "x30")
53
+ value)
58
+
54
+#define GPIO_PULSE(name) \
59
+#define BTYPE_3() \
55
+ do { \
60
+ asm("mov %0,#1; adr x15, 1f; br x15; 1: hint #25; mov %0,#0" \
56
+ GPIO_OUT(name, 1); \
61
+ : "=r"(skipped) : : "x15", "x30")
57
+ GPIO_OUT(name, 0); \
62
+
58
+ } while (0)
63
+#define TEST(WHICH, EXPECT) \
59
+
64
+ do { WHICH(); fail += skipped ^ EXPECT; } while (0)
60
+
65
+
61
+static void rise_gpio_pin_dck(QTestState *qts)
66
+int main()
62
+{
67
+{
63
+ /* Configure output mode for pin PB1 */
68
+ int fail = 0;
64
+ qtest_writel(qts, 0x48000400, 0xFFFFFEB7);
69
+ int skipped;
65
+ /* Write 1 in ODR for PB1 */
70
+
66
+ qtest_writel(qts, 0x48000414, 0x00000002);
71
+ /* Signal-like with SA_SIGINFO. */
67
+}
72
+ signal_info(SIGILL, skip2_sigill);
68
+
73
+
69
+static void lower_gpio_pin_dck(QTestState *qts)
74
+ /* With SCTLR_EL1.BT0 set, PACIASP is not compatible with type=3. */
70
+{
75
+ TEST(BTYPE_1, 0);
71
+ /* Configure output mode for pin PB1 */
76
+ TEST(BTYPE_2, 0);
72
+ qtest_writel(qts, 0x48000400, 0xFFFFFEB7);
77
+ TEST(BTYPE_3, 1);
73
+ /* Write 0 in ODR for PB1 */
78
+
74
+ qtest_writel(qts, 0x48000414, 0x00000000);
79
+ return fail;
75
+}
80
+}
76
+
81
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
77
+static void rise_gpio_pin_selbk(QTestState *qts)
78
+{
79
+ /* Configure output mode for pin PC5 */
80
+ qtest_writel(qts, 0x48000800, 0xFFFFF7FF);
81
+ /* Write 1 in ODR for PC5 */
82
+ qtest_writel(qts, 0x48000814, 0x00000020);
83
+}
84
+
85
+static void lower_gpio_pin_selbk(QTestState *qts)
86
+{
87
+ /* Configure output mode for pin PC5 */
88
+ qtest_writel(qts, 0x48000800, 0xFFFFF7FF);
89
+ /* Write 0 in ODR for PC5 */
90
+ qtest_writel(qts, 0x48000814, 0x00000000);
91
+}
92
+
93
+static void rise_gpio_pin_lat_b(QTestState *qts)
94
+{
95
+ /* Configure output mode for pin PC4 */
96
+ qtest_writel(qts, 0x48000800, 0xFFFFFDFF);
97
+ /* Write 1 in ODR for PC4 */
98
+ qtest_writel(qts, 0x48000814, 0x00000010);
99
+}
100
+
101
+static void lower_gpio_pin_lat_b(QTestState *qts)
102
+{
103
+ /* Configure output mode for pin PC4 */
104
+ qtest_writel(qts, 0x48000800, 0xFFFFFDFF);
105
+ /* Write 0 in ODR for PC4 */
106
+ qtest_writel(qts, 0x48000814, 0x00000000);
107
+}
108
+
109
+static void rise_gpio_pin_rst_b(QTestState *qts)
110
+{
111
+ /* Configure output mode for pin PC3 */
112
+ qtest_writel(qts, 0x48000800, 0xFFFFFF7F);
113
+ /* Write 1 in ODR for PC3 */
114
+ qtest_writel(qts, 0x48000814, 0x00000008);
115
+}
116
+
117
+static void lower_gpio_pin_rst_b(QTestState *qts)
118
+{
119
+ /* Configure output mode for pin PC3 */
120
+ qtest_writel(qts, 0x48000800, 0xFFFFFF7F);
121
+ /* Write 0 in ODR for PC3 */
122
+ qtest_writel(qts, 0x48000814, 0x00000000);
123
+}
124
+
125
+static void rise_gpio_pin_sin(QTestState *qts)
126
+{
127
+ /* Configure output mode for pin PA4 */
128
+ qtest_writel(qts, 0x48000000, 0xFFFFFDFF);
129
+ /* Write 1 in ODR for PA4 */
130
+ qtest_writel(qts, 0x48000014, 0x00000010);
131
+}
132
+
133
+static void lower_gpio_pin_sin(QTestState *qts)
134
+{
135
+ /* Configure output mode for pin PA4 */
136
+ qtest_writel(qts, 0x48000000, 0xFFFFFDFF);
137
+ /* Write 0 in ODR for PA4 */
138
+ qtest_writel(qts, 0x48000014, 0x00000000);
139
+}
140
+
141
+static void test_dm163_bank(const void *opaque)
142
+{
143
+ const unsigned bank = (uintptr_t) opaque;
144
+ const int width = bank ? 192 : 144;
145
+
146
+ QTestState *qts = qtest_initf("-M b-l475e-iot01a");
147
+ qtest_irq_intercept_out_named(qts, DEVICE_NAME, "sout");
148
+ GPIO_OUT(RST_B, 1);
149
+ GPIO_OUT(EN_B, 0);
150
+ GPIO_OUT(DCK, 0);
151
+ GPIO_OUT(SELBK, bank);
152
+ GPIO_OUT(LAT_B, 1);
153
+
154
+ /* Fill bank with zeroes */
155
+ GPIO_OUT(SIN, 0);
156
+ for (int i = 0; i < width; i++) {
157
+ GPIO_PULSE(DCK);
158
+ }
159
+ /* Fill bank with ones, check that we get the previous zeroes */
160
+ GPIO_OUT(SIN, 1);
161
+ for (int i = 0; i < width; i++) {
162
+ GPIO_PULSE(DCK);
163
+ g_assert(!qtest_get_irq(qts, 0));
164
+ }
165
+
166
+ /* Pulse one more bit in the bank, check that we get a one */
167
+ GPIO_PULSE(DCK);
168
+ g_assert(qtest_get_irq(qts, 0));
169
+
170
+ qtest_quit(qts);
171
+}
172
+
173
+static void test_dm163_gpio_connection(void)
174
+{
175
+ QTestState *qts = qtest_init("-M b-l475e-iot01a");
176
+ qtest_irq_intercept_in(qts, DEVICE_NAME);
177
+
178
+ g_assert_false(qtest_get_irq(qts, SIN));
179
+ g_assert_false(qtest_get_irq(qts, DCK));
180
+ g_assert_false(qtest_get_irq(qts, RST_B));
181
+ g_assert_false(qtest_get_irq(qts, LAT_B));
182
+ g_assert_false(qtest_get_irq(qts, SELBK));
183
+
184
+ rise_gpio_pin_dck(qts);
185
+ g_assert_true(qtest_get_irq(qts, DCK));
186
+ lower_gpio_pin_dck(qts);
187
+ g_assert_false(qtest_get_irq(qts, DCK));
188
+
189
+ rise_gpio_pin_lat_b(qts);
190
+ g_assert_true(qtest_get_irq(qts, LAT_B));
191
+ lower_gpio_pin_lat_b(qts);
192
+ g_assert_false(qtest_get_irq(qts, LAT_B));
193
+
194
+ rise_gpio_pin_selbk(qts);
195
+ g_assert_true(qtest_get_irq(qts, SELBK));
196
+ lower_gpio_pin_selbk(qts);
197
+ g_assert_false(qtest_get_irq(qts, SELBK));
198
+
199
+ rise_gpio_pin_rst_b(qts);
200
+ g_assert_true(qtest_get_irq(qts, RST_B));
201
+ lower_gpio_pin_rst_b(qts);
202
+ g_assert_false(qtest_get_irq(qts, RST_B));
203
+
204
+ rise_gpio_pin_sin(qts);
205
+ g_assert_true(qtest_get_irq(qts, SIN));
206
+ lower_gpio_pin_sin(qts);
207
+ g_assert_false(qtest_get_irq(qts, SIN));
208
+
209
+ g_assert_false(qtest_get_irq(qts, DCK));
210
+ g_assert_false(qtest_get_irq(qts, LAT_B));
211
+ g_assert_false(qtest_get_irq(qts, SELBK));
212
+ g_assert_false(qtest_get_irq(qts, RST_B));
213
+}
214
+
215
+int main(int argc, char **argv)
216
+{
217
+ g_test_init(&argc, &argv, NULL);
218
+ qtest_add_data_func("/dm163/bank0", (void *)0, test_dm163_bank);
219
+ qtest_add_data_func("/dm163/bank1", (void *)1, test_dm163_bank);
220
+ qtest_add_func("/dm163/gpio_connection", test_dm163_gpio_connection);
221
+ return g_test_run();
222
+}
223
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
82
index XXXXXXX..XXXXXXX 100644
224
index XXXXXXX..XXXXXXX 100644
83
--- a/tests/tcg/aarch64/Makefile.target
225
--- a/tests/qtest/meson.build
84
+++ b/tests/tcg/aarch64/Makefile.target
226
+++ b/tests/qtest/meson.build
85
@@ -XXX,XX +XXX,XX @@ endif
227
@@ -XXX,XX +XXX,XX @@ qtests_arm = \
86
# BTI Tests
228
(config_all_devices.has_key('CONFIG_MICROBIT') ? ['microbit-test'] : []) + \
87
# bti-1 tests the elf notes, so we require special compiler support.
229
(config_all_devices.has_key('CONFIG_STM32L4X5_SOC') ? qtests_stm32l4x5 : []) + \
88
ifneq ($(CROSS_CC_HAS_ARMV8_BTI),)
230
(config_all_devices.has_key('CONFIG_FSI_APB2OPB_ASPEED') ? ['aspeed_fsi-test'] : []) + \
89
-AARCH64_TESTS += bti-1
231
+ (config_all_devices.has_key('CONFIG_STM32L4X5_SOC') and
90
-bti-1: CFLAGS += -mbranch-protection=standard
232
+ config_all_devices.has_key('CONFIG_DM163')? ['dm163-test'] : []) + \
91
-bti-1: LDFLAGS += -nostdlib
233
['arm-cpu-features',
92
+AARCH64_TESTS += bti-1 bti-3
234
'boot-serial-test']
93
+bti-1 bti-3: CFLAGS += -mbranch-protection=standard
235
94
+bti-1 bti-3: LDFLAGS += -nostdlib
95
endif
96
# bti-2 tests PROT_BTI, so no special compiler support required.
97
AARCH64_TESTS += bti-2
98
--
236
--
99
2.25.1
237
2.34.1
238
239
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Create a typedef as well, and use it in ARMCPRegInfo.
4
This won't be perfect for debugging, but it'll nicely
5
display the most common cases.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220501055028.646596-8-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpregs.h | 44 +++++++++++++++++++++++---------------------
13
target/arm/helper.c | 2 +-
14
2 files changed, 24 insertions(+), 22 deletions(-)
15
16
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpregs.h
19
+++ b/target/arm/cpregs.h
20
@@ -XXX,XX +XXX,XX @@ enum {
21
* described with these bits, then use a laxer set of restrictions, and
22
* do the more restrictive/complex check inside a helper function.
23
*/
24
-#define PL3_R 0x80
25
-#define PL3_W 0x40
26
-#define PL2_R (0x20 | PL3_R)
27
-#define PL2_W (0x10 | PL3_W)
28
-#define PL1_R (0x08 | PL2_R)
29
-#define PL1_W (0x04 | PL2_W)
30
-#define PL0_R (0x02 | PL1_R)
31
-#define PL0_W (0x01 | PL1_W)
32
+typedef enum {
33
+ PL3_R = 0x80,
34
+ PL3_W = 0x40,
35
+ PL2_R = 0x20 | PL3_R,
36
+ PL2_W = 0x10 | PL3_W,
37
+ PL1_R = 0x08 | PL2_R,
38
+ PL1_W = 0x04 | PL2_W,
39
+ PL0_R = 0x02 | PL1_R,
40
+ PL0_W = 0x01 | PL1_W,
41
42
-/*
43
- * For user-mode some registers are accessible to EL0 via a kernel
44
- * trap-and-emulate ABI. In this case we define the read permissions
45
- * as actually being PL0_R. However some bits of any given register
46
- * may still be masked.
47
- */
48
+ /*
49
+ * For user-mode some registers are accessible to EL0 via a kernel
50
+ * trap-and-emulate ABI. In this case we define the read permissions
51
+ * as actually being PL0_R. However some bits of any given register
52
+ * may still be masked.
53
+ */
54
#ifdef CONFIG_USER_ONLY
55
-#define PL0U_R PL0_R
56
+ PL0U_R = PL0_R,
57
#else
58
-#define PL0U_R PL1_R
59
+ PL0U_R = PL1_R,
60
#endif
61
62
-#define PL3_RW (PL3_R | PL3_W)
63
-#define PL2_RW (PL2_R | PL2_W)
64
-#define PL1_RW (PL1_R | PL1_W)
65
-#define PL0_RW (PL0_R | PL0_W)
66
+ PL3_RW = PL3_R | PL3_W,
67
+ PL2_RW = PL2_R | PL2_W,
68
+ PL1_RW = PL1_R | PL1_W,
69
+ PL0_RW = PL0_R | PL0_W,
70
+} CPAccessRights;
71
72
typedef enum CPAccessResult {
73
/* Access is permitted */
74
@@ -XXX,XX +XXX,XX @@ struct ARMCPRegInfo {
75
/* Register type: ARM_CP_* bits/values */
76
int type;
77
/* Access rights: PL*_[RW] */
78
- int access;
79
+ CPAccessRights access;
80
/* Security state: ARM_CP_SECSTATE_* bits/values */
81
int secure;
82
/*
83
diff --git a/target/arm/helper.c b/target/arm/helper.c
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
--
97
2.25.1
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Give this enum a name and use in ARMCPRegInfo and add_cpreg_to_hashtable.
4
Add the enumerator ARM_CP_SECSTATE_BOTH to clarify how 0
5
is handled in define_one_arm_cp_reg_with_opaque.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220501055028.646596-10-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpregs.h | 7 ++++---
13
target/arm/helper.c | 7 +++++--
14
2 files changed, 9 insertions(+), 5 deletions(-)
15
16
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpregs.h
19
+++ b/target/arm/cpregs.h
20
@@ -XXX,XX +XXX,XX @@ typedef enum {
21
* registered entry will only have one to identify whether the entry is secure
22
* or non-secure.
23
*/
24
-enum {
25
+typedef enum {
26
+ ARM_CP_SECSTATE_BOTH = 0, /* define one cpreg for each secstate */
27
ARM_CP_SECSTATE_S = (1 << 0), /* bit[0]: Secure state register */
28
ARM_CP_SECSTATE_NS = (1 << 1), /* bit[1]: Non-secure state register */
29
-};
30
+} CPSecureState;
31
32
/*
33
* Access rights:
34
@@ -XXX,XX +XXX,XX @@ struct ARMCPRegInfo {
35
/* Access rights: PL*_[RW] */
36
CPAccessRights access;
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
}
49
50
static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
51
- void *opaque, CPState state, int secstate,
52
+ void *opaque, CPState state,
53
+ CPSecureState secstate,
54
int crm, int opc1, int opc2,
55
const char *name)
56
{
57
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
58
r->secure, crm, opc1, opc2,
59
r->name);
60
break;
61
- default:
62
+ case ARM_CP_SECSTATE_BOTH:
63
name = g_strdup_printf("%s_S", r->name);
64
add_cpreg_to_hashtable(cpu, r, opaque, state,
65
ARM_CP_SECSTATE_S,
66
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
67
ARM_CP_SECSTATE_NS,
68
crm, opc1, opc2, r->name);
69
break;
70
+ default:
71
+ g_assert_not_reached();
72
}
73
} else {
74
/* AArch64 registers get mapped to non-secure instance
75
--
76
2.25.1
diff view generated by jsdifflib