1
First arm pullreq of the 2.11 cycle. I know I still have some
1
Hi; here's a target-arm pullreq for rc0; these are all bugfixes
2
more stuff on my queue to review, but 36 patches is big enough
2
and similar minor stuff.
3
as it is; I expect I'll do another pull later this week.
4
3
5
thanks
4
thanks
6
-- PMM
5
-- PMM
7
6
8
The following changes since commit 32f0f68bb77289b75a82925f712bb52e16eac3ba:
7
The following changes since commit 0462a32b4f63b2448b4a196381138afd50719dc4:
9
8
10
Merge remote-tracking branch 'remotes/ehabkost/tags/x86-and-machine-pull-request' into staging (2017-09-01 17:28:54 +0100)
9
Merge tag 'for-upstream' of https://repo.or.cz/qemu/kevin into staging (2025-03-14 09:31:13 +0800)
11
10
12
are available in the git repository at:
11
are available in the Git repository at:
13
12
14
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20170904
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20250314-1
15
14
16
for you to fetch changes up to 1e35c4ce33a94cf78dbf639695cb877ef35920b0:
15
for you to fetch changes up to a019e15edfd62beae1e2f6adc0fa7415ba20b14c:
17
16
18
arm_gicv3_kvm: Fix compile warning (2017-09-04 12:09:32 +0100)
17
meson.build: Set RUST_BACKTRACE for all tests (2025-03-14 12:54:33 +0000)
19
18
20
----------------------------------------------------------------
19
----------------------------------------------------------------
21
target-arm:
20
target-arm queue:
22
* collection of M profile cleanups and minor bugfixes
21
* Correctly handle corner cases of guest attempting an exception
23
* loader: handle ELF files with overlapping zero-init data
22
return to AArch32 when target EL is AArch64 only
24
* virt: allow PMU instantiation with userspace irqchip
23
* MAINTAINERS: Fix status for Arm boards I "maintain"
25
* wdt_aspeed: Add support for the reset width register
24
* tests/functional: Bump up arm_replay timeout
26
* cpu: Define new cpu_transaction_failed() hook
25
* Revert "hw/char/pl011: Warn when using disabled receiver"
27
* arm: Support generating CPU exceptions on memory
26
* util/cacheflush: Make first DSB unconditional on aarch64
28
transaction failures (bus faults)
27
* target/arm: Fix SVE/SME access check logic
29
* Mark some SoC devices as not user-creatable
28
* meson.build: Set RUST_BACKTRACE for all tests
30
* arm: Fix aa64 ldp register writeback
31
* arm_gicv3_kvm: Fix compile warning
32
29
33
----------------------------------------------------------------
30
----------------------------------------------------------------
34
Andrew Jeffery (2):
31
Joe Komlodi (1):
35
watchdog: wdt_aspeed: Add support for the reset width register
32
util/cacheflush: Make first DSB unconditional on aarch64
36
aspeed_soc: Propagate silicon-rev to watchdog
37
33
38
Andrew Jones (4):
34
Paolo Bonzini (1):
39
hw/arm/virt: add pmu interrupt state
35
Revert "hw/char/pl011: Warn when using disabled receiver"
40
target/arm/kvm: pmu: split init and set-irq stages
41
hw/arm/virt: allow pmu instantiation with userspace irqchip
42
target/arm/kvm: pmu: improve error handling
43
36
44
Peter Maydell (25):
37
Peter Maydell (13):
45
target/arm: Use MMUAccessType enum rather than int
38
target/arm: Move A32_BANKED_REG_{GET,SET} macros to cpregs.h
46
target/arm: Don't trap WFI/WFE for M profile
39
target/arm: Un-inline access_secure_reg()
47
target/arm: Consolidate PMSA handling in get_phys_addr()
40
linux-user/aarch64: Remove unused get/put_user macros
48
target/arm: Tighten up Thumb decode where new v8M insns will be
41
linux-user/arm: Remove unused get_put_user macros
49
hw/intc/armv7m_nvic.c: Remove out of date comment
42
target/arm: Move arm_cpu_data_is_big_endian() etc to internals.h
50
target/arm: Remove incorrect comment about MPU_CTRL
43
target/arm: Move arm_current_el() and arm_el_is_aa64() to internals.h
51
target/arm: Fix outdated comment about exception exit
44
target/arm: SCR_EL3.RW should be treated as 1 if EL2 doesn't support AArch32
52
target/arm: Define and use XPSR bit masks
45
target/arm: HCR_EL2.RW should be RAO/WI if EL1 doesn't support AArch32
53
target/arm: Don't store M profile PRIMASK and FAULTMASK in daif
46
target/arm: Add cpu local variable to exception_return helper
54
target/arm: Don't use cpsr_write/cpsr_read to transfer M profile XPSR
47
target/arm: Forbid return to AArch32 when CPU is AArch64-only
55
target/arm: Make arm_cpu_dump_state() handle the M-profile XPSR
48
MAINTAINERS: Fix status for Arm boards I "maintain"
56
target/arm: Don't calculate lr in arm_v7m_cpu_do_interrupt() until needed
49
tests/functional: Bump up arm_replay timeout
57
target/arm: Create and use new function arm_v7m_is_handler_mode()
50
meson.build: Set RUST_BACKTRACE for all tests
58
armv7m_nvic.h: Move from include/hw/arm to include/hw/intc
59
nvic: Implement "user accesses BusFault" SCS region behaviour
60
loader: Handle ELF files with overlapping zero-initialized data
61
loader: Ignore zero-sized ELF segments
62
memory.h: Move MemTxResult type to memattrs.h
63
cpu: Define new cpu_transaction_failed() hook
64
cputlb: Support generating CPU exceptions on memory transaction failures
65
boards.h: Define new flag ignore_memory_transaction_failures
66
hw/arm: Set ignore_memory_transaction_failures for most ARM boards
67
target/arm: Factor out fault delivery code
68
target/arm: Allow deliver_fault() caller to specify EA bit
69
target/arm: Implement new do_transaction_failed hook
70
51
71
Philippe Mathieu-Daudé (1):
52
Richard Henderson (2):
72
hw/arm: use defined type name instead of hard-coded string
53
target/arm: Make DisasContext.{fp, sve}_access_checked tristate
54
target/arm: Simplify pstate_sm check in sve_access_check
73
55
74
Pranith Kumar (1):
56
MAINTAINERS | 14 ++--
75
arm_gicv3_kvm: Fix compile warning
57
meson.build | 9 ++-
76
58
target/arm/cpregs.h | 28 +++++++
77
Richard Henderson (1):
59
target/arm/cpu.h | 153 +-----------------------------------
78
target/arm: Fix aa64 ldp register writeback
60
target/arm/internals.h | 135 +++++++++++++++++++++++++++++++
79
61
target/arm/tcg/translate-a64.h | 2 +-
80
Thomas Huth (2):
62
target/arm/tcg/translate.h | 10 ++-
81
hw/arm/aspeed_soc: Mark devices as user_creatable = false
63
hw/char/pl011.c | 19 ++---
82
hw/arm/digic: Mark device with user_creatable = false
64
hw/intc/arm_gicv3_cpuif.c | 1 +
83
65
linux-user/aarch64/cpu_loop.c | 48 -----------
84
include/exec/memattrs.h | 10 +++
66
linux-user/arm/cpu_loop.c | 43 +---------
85
include/exec/memory.h | 10 ---
67
target/arm/arch_dump.c | 1 +
86
include/hw/arm/armv7m.h | 2 +-
68
target/arm/helper.c | 16 +++-
87
include/hw/boards.h | 11 +++
69
target/arm/tcg/helper-a64.c | 12 ++-
88
include/hw/elf_ops.h | 72 +++++++++++++--
70
target/arm/tcg/hflags.c | 9 +++
89
include/hw/{arm => intc}/armv7m_nvic.h | 0
71
target/arm/tcg/translate-a64.c | 37 ++++-----
90
include/hw/watchdog/wdt_aspeed.h | 2 +
72
util/cacheflush.c | 4 +-
91
include/qom/cpu.h | 27 ++++++
73
.gitlab-ci.d/buildtest-template.yml | 1 -
92
softmmu_template.h | 4 +-
74
18 files changed, 257 insertions(+), 285 deletions(-)
93
target/arm/cpu.h | 56 +++++++++---
94
target/arm/internals.h | 15 +++-
95
target/arm/kvm_arm.h | 9 +-
96
accel/tcg/cputlb.c | 32 ++++++-
97
hw/arm/armv7m.c | 4 +-
98
hw/arm/aspeed.c | 3 +
99
hw/arm/aspeed_soc.c | 4 +
100
hw/arm/collie.c | 1 +
101
hw/arm/cubieboard.c | 1 +
102
hw/arm/digic.c | 2 +
103
hw/arm/digic_boards.c | 1 +
104
hw/arm/exynos4210.c | 4 +-
105
hw/arm/exynos4_boards.c | 2 +
106
hw/arm/gumstix.c | 2 +
107
hw/arm/highbank.c | 13 ++-
108
hw/arm/imx25_pdk.c | 1 +
109
hw/arm/integratorcp.c | 1 +
110
hw/arm/kzm.c | 1 +
111
hw/arm/mainstone.c | 1 +
112
hw/arm/musicpal.c | 1 +
113
hw/arm/netduino2.c | 1 +
114
hw/arm/nseries.c | 2 +
115
hw/arm/omap_sx1.c | 2 +
116
hw/arm/palm.c | 1 +
117
hw/arm/raspi.c | 1 +
118
hw/arm/realview.c | 10 ++-
119
hw/arm/sabrelite.c | 1 +
120
hw/arm/spitz.c | 4 +
121
hw/arm/stellaris.c | 2 +
122
hw/arm/tosa.c | 1 +
123
hw/arm/versatilepb.c | 2 +
124
hw/arm/vexpress.c | 7 +-
125
hw/arm/virt.c | 12 ++-
126
hw/arm/xilinx_zynq.c | 15 ++--
127
hw/arm/xlnx-ep108.c | 2 +
128
hw/arm/z2.c | 1 +
129
hw/intc/arm_gicv3_kvm.c | 2 +-
130
hw/intc/armv7m_nvic.c | 68 +++++++++-----
131
hw/watchdog/wdt_aspeed.c | 93 ++++++++++++++++---
132
qom/cpu.c | 7 ++
133
target/arm/cpu.c | 8 +-
134
target/arm/helper.c | 124 ++++++++++++-------------
135
target/arm/kvm.c | 6 +-
136
target/arm/kvm32.c | 7 +-
137
target/arm/kvm64.c | 63 +++++++------
138
target/arm/machine.c | 54 ++++++++++-
139
target/arm/op_helper.c | 160 ++++++++++++++++++++++-----------
140
target/arm/translate-a64.c | 29 +++---
141
target/arm/translate.c | 106 ++++++++++++++++------
142
58 files changed, 795 insertions(+), 288 deletions(-)
143
rename include/hw/{arm => intc}/armv7m_nvic.h (100%)
144
diff view generated by jsdifflib
1
The M profile XPSR is almost the same format as the A profile CPSR,
1
The A32_BANKED_REG_{GET,SET} macros are only used inside target/arm;
2
but not quite. Define some XPSR_* macros and use them where we
2
move their definitions to cpregs.h. There's no need to have them
3
definitely dealing with an XPSR rather than reusing the CPSR ones.
3
defined in all the code that includes cpu.h.
4
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 1501692241-23310-9-git-send-email-peter.maydell@linaro.org
9
---
7
---
10
target/arm/cpu.h | 38 ++++++++++++++++++++++++++++----------
8
target/arm/cpregs.h | 28 ++++++++++++++++++++++++++++
11
target/arm/helper.c | 15 ++++++++-------
9
target/arm/cpu.h | 27 ---------------------------
12
2 files changed, 36 insertions(+), 17 deletions(-)
10
2 files changed, 28 insertions(+), 27 deletions(-)
13
11
12
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpregs.h
15
+++ b/target/arm/cpregs.h
16
@@ -XXX,XX +XXX,XX @@ static inline bool arm_cpreg_traps_in_nv(const ARMCPRegInfo *ri)
17
return ri->opc1 == 4 || ri->opc1 == 5;
18
}
19
20
+/* Macros for accessing a specified CP register bank */
21
+#define A32_BANKED_REG_GET(_env, _regname, _secure) \
22
+ ((_secure) ? (_env)->cp15._regname##_s : (_env)->cp15._regname##_ns)
23
+
24
+#define A32_BANKED_REG_SET(_env, _regname, _secure, _val) \
25
+ do { \
26
+ if (_secure) { \
27
+ (_env)->cp15._regname##_s = (_val); \
28
+ } else { \
29
+ (_env)->cp15._regname##_ns = (_val); \
30
+ } \
31
+ } while (0)
32
+
33
+/*
34
+ * Macros for automatically accessing a specific CP register bank depending on
35
+ * the current secure state of the system. These macros are not intended for
36
+ * supporting instruction translation reads/writes as these are dependent
37
+ * solely on the SCR.NS bit and not the mode.
38
+ */
39
+#define A32_BANKED_CURRENT_REG_GET(_env, _regname) \
40
+ A32_BANKED_REG_GET((_env), _regname, \
41
+ (arm_is_secure(_env) && !arm_el_is_aa64((_env), 3)))
42
+
43
+#define A32_BANKED_CURRENT_REG_SET(_env, _regname, _val) \
44
+ A32_BANKED_REG_SET((_env), _regname, \
45
+ (arm_is_secure(_env) && !arm_el_is_aa64((_env), 3)), \
46
+ (_val))
47
+
48
#endif /* TARGET_ARM_CPREGS_H */
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
49
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
51
--- a/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
52
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ void pmccntr_sync(CPUARMState *env);
53
@@ -XXX,XX +XXX,XX @@ static inline bool access_secure_reg(CPUARMState *env)
19
/* Mask of bits which may be set by exception return copying them from SPSR */
54
return ret;
20
#define CPSR_ERET_MASK (~CPSR_RESERVED)
21
22
+/* Bit definitions for M profile XPSR. Most are the same as CPSR. */
23
+#define XPSR_EXCP 0x1ffU
24
+#define XPSR_SPREALIGN (1U << 9) /* Only set in exception stack frames */
25
+#define XPSR_IT_2_7 CPSR_IT_2_7
26
+#define XPSR_GE CPSR_GE
27
+#define XPSR_SFPA (1U << 20) /* Only set in exception stack frames */
28
+#define XPSR_T (1U << 24) /* Not the same as CPSR_T ! */
29
+#define XPSR_IT_0_1 CPSR_IT_0_1
30
+#define XPSR_Q CPSR_Q
31
+#define XPSR_V CPSR_V
32
+#define XPSR_C CPSR_C
33
+#define XPSR_Z CPSR_Z
34
+#define XPSR_N CPSR_N
35
+#define XPSR_NZCV CPSR_NZCV
36
+#define XPSR_IT CPSR_IT
37
+
38
#define TTBCR_N (7U << 0) /* TTBCR.EAE==0 */
39
#define TTBCR_T0SZ (7U << 0) /* TTBCR.EAE==1 */
40
#define TTBCR_PD0 (1U << 4)
41
@@ -XXX,XX +XXX,XX @@ static inline uint32_t xpsr_read(CPUARMState *env)
42
/* Set the xPSR. Note that some bits of mask must be all-set or all-clear. */
43
static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
44
{
45
- if (mask & CPSR_NZCV) {
46
- env->ZF = (~val) & CPSR_Z;
47
+ if (mask & XPSR_NZCV) {
48
+ env->ZF = (~val) & XPSR_Z;
49
env->NF = val;
50
env->CF = (val >> 29) & 1;
51
env->VF = (val << 3) & 0x80000000;
52
}
53
- if (mask & CPSR_Q)
54
- env->QF = ((val & CPSR_Q) != 0);
55
- if (mask & (1 << 24))
56
- env->thumb = ((val & (1 << 24)) != 0);
57
- if (mask & CPSR_IT_0_1) {
58
+ if (mask & XPSR_Q) {
59
+ env->QF = ((val & XPSR_Q) != 0);
60
+ }
61
+ if (mask & XPSR_T) {
62
+ env->thumb = ((val & XPSR_T) != 0);
63
+ }
64
+ if (mask & XPSR_IT_0_1) {
65
env->condexec_bits &= ~3;
66
env->condexec_bits |= (val >> 25) & 3;
67
}
68
- if (mask & CPSR_IT_2_7) {
69
+ if (mask & XPSR_IT_2_7) {
70
env->condexec_bits &= 3;
71
env->condexec_bits |= (val >> 8) & 0xfc;
72
}
73
- if (mask & 0x1ff) {
74
- env->v7m.exception = val & 0x1ff;
75
+ if (mask & XPSR_EXCP) {
76
+ env->v7m.exception = val & XPSR_EXCP;
77
}
78
}
55
}
79
56
80
diff --git a/target/arm/helper.c b/target/arm/helper.c
57
-/* Macros for accessing a specified CP register bank */
81
index XXXXXXX..XXXXXXX 100644
58
-#define A32_BANKED_REG_GET(_env, _regname, _secure) \
82
--- a/target/arm/helper.c
59
- ((_secure) ? (_env)->cp15._regname##_s : (_env)->cp15._regname##_ns)
83
+++ b/target/arm/helper.c
60
-
84
@@ -XXX,XX +XXX,XX @@ static void v7m_push_stack(ARMCPU *cpu)
61
-#define A32_BANKED_REG_SET(_env, _regname, _secure, _val) \
85
/* Align stack pointer if the guest wants that */
62
- do { \
86
if ((env->regs[13] & 4) && (env->v7m.ccr & R_V7M_CCR_STKALIGN_MASK)) {
63
- if (_secure) { \
87
env->regs[13] -= 4;
64
- (_env)->cp15._regname##_s = (_val); \
88
- xpsr |= 0x200;
65
- } else { \
89
+ xpsr |= XPSR_SPREALIGN;
66
- (_env)->cp15._regname##_ns = (_val); \
90
}
67
- } \
91
/* Switch to the handler mode. */
68
- } while (0)
92
v7m_push(env, xpsr);
69
-
93
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
70
-/* Macros for automatically accessing a specific CP register bank depending on
94
env->regs[15] &= ~1U;
71
- * the current secure state of the system. These macros are not intended for
95
}
72
- * supporting instruction translation reads/writes as these are dependent
96
xpsr = v7m_pop(env);
73
- * solely on the SCR.NS bit and not the mode.
97
- xpsr_write(env, xpsr, 0xfffffdff);
74
- */
98
+ xpsr_write(env, xpsr, ~XPSR_SPREALIGN);
75
-#define A32_BANKED_CURRENT_REG_GET(_env, _regname) \
99
/* Undo stack alignment. */
76
- A32_BANKED_REG_GET((_env), _regname, \
100
- if (xpsr & 0x200)
77
- (arm_is_secure(_env) && !arm_el_is_aa64((_env), 3)))
101
+ if (xpsr & XPSR_SPREALIGN) {
78
-
102
env->regs[13] |= 4;
79
-#define A32_BANKED_CURRENT_REG_SET(_env, _regname, _val) \
103
+ }
80
- A32_BANKED_REG_SET((_env), _regname, \
104
81
- (arm_is_secure(_env) && !arm_el_is_aa64((_env), 3)), \
105
/* The restored xPSR exception field will be zero if we're
82
- (_val))
106
* resuming in Thread mode. If that doesn't match what the
83
-
107
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
84
uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
108
case 0 ... 7: /* xPSR sub-fields */
85
uint32_t cur_el, bool secure);
109
mask = 0;
86
110
if ((reg & 1) && el) {
111
- mask |= 0x000001ff; /* IPSR (unpriv. reads as zero) */
112
+ mask |= XPSR_EXCP; /* IPSR (unpriv. reads as zero) */
113
}
114
if (!(reg & 4)) {
115
- mask |= 0xf8000000; /* APSR */
116
+ mask |= XPSR_NZCV | XPSR_Q; /* APSR */
117
}
118
/* EPSR reads as zero */
119
return xpsr_read(env) & mask;
120
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
121
uint32_t apsrmask = 0;
122
123
if (mask & 8) {
124
- apsrmask |= 0xf8000000; /* APSR NZCVQ */
125
+ apsrmask |= XPSR_NZCV | XPSR_Q;
126
}
127
if ((mask & 4) && arm_feature(env, ARM_FEATURE_THUMB_DSP)) {
128
- apsrmask |= 0x000f0000; /* APSR GE[3:0] */
129
+ apsrmask |= XPSR_GE;
130
}
131
xpsr_write(env, val, apsrmask);
132
}
133
--
87
--
134
2.7.4
88
2.43.0
135
136
diff view generated by jsdifflib
1
Add a utility function for testing whether the CPU is in Handler
1
We would like to move arm_el_is_aa64() to internals.h; however, it is
2
mode; this is just a check whether v7m.exception is non-zero, but
2
used by access_secure_reg(). Make that function not be inline, so
3
we do it in several places and it makes the code a bit easier
3
that it can stay in cpu.h.
4
to read to not have to mentally figure out what the test is testing.
4
5
access_secure_reg() is used only in two places:
6
* in hflags.c
7
* in the user-mode arm emulators, to decide whether to store
8
the TLS value in the secure or non-secure banked field
9
10
The second of these is not on a super-hot path that would care about
11
the inlining (and incidentally will always use the NS banked field
12
because our user-mode CPUs never set ARM_FEATURE_EL3); put the
13
definition of access_secure_reg() in hflags.c, near its only use
14
inside target/arm.
5
15
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 1501692241-23310-14-git-send-email-peter.maydell@linaro.org
11
---
18
---
12
target/arm/cpu.h | 10 ++++++++--
19
target/arm/cpu.h | 12 +++---------
13
target/arm/helper.c | 8 ++++----
20
target/arm/tcg/hflags.c | 9 +++++++++
14
2 files changed, 12 insertions(+), 6 deletions(-)
21
2 files changed, 12 insertions(+), 9 deletions(-)
15
22
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
25
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
26
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ static inline int arm_highest_el(CPUARMState *env)
27
@@ -XXX,XX +XXX,XX @@ static inline bool arm_el_is_aa64(CPUARMState *env, int el)
21
return 1;
28
return aa64;
22
}
29
}
23
30
24
+/* Return true if a v7M CPU is in Handler mode */
31
-/* Function for determining whether guest cp register reads and writes should
25
+static inline bool arm_v7m_is_handler_mode(CPUARMState *env)
32
+/*
33
+ * Function for determining whether guest cp register reads and writes should
34
* access the secure or non-secure bank of a cp register. When EL3 is
35
* operating in AArch32 state, the NS-bit determines whether the secure
36
* instance of a cp register should be used. When EL3 is AArch64 (or if
37
* it doesn't exist at all) then there is no register banking, and all
38
* accesses are to the non-secure version.
39
*/
40
-static inline bool access_secure_reg(CPUARMState *env)
41
-{
42
- bool ret = (arm_feature(env, ARM_FEATURE_EL3) &&
43
- !arm_el_is_aa64(env, 3) &&
44
- !(env->cp15.scr_el3 & SCR_NS));
45
-
46
- return ret;
47
-}
48
+bool access_secure_reg(CPUARMState *env);
49
50
uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
51
uint32_t cur_el, bool secure);
52
diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/tcg/hflags.c
55
+++ b/target/arm/tcg/hflags.c
56
@@ -XXX,XX +XXX,XX @@ static bool aprofile_require_alignment(CPUARMState *env, int el, uint64_t sctlr)
57
#endif
58
}
59
60
+bool access_secure_reg(CPUARMState *env)
26
+{
61
+{
27
+ return env->v7m.exception != 0;
62
+ bool ret = (arm_feature(env, ARM_FEATURE_EL3) &&
63
+ !arm_el_is_aa64(env, 3) &&
64
+ !(env->cp15.scr_el3 & SCR_NS));
65
+
66
+ return ret;
28
+}
67
+}
29
+
68
+
30
/* Return the current Exception Level (as per ARMv8; note that this differs
69
static CPUARMTBFlags rebuild_hflags_common(CPUARMState *env, int fp_el,
31
* from the ARMv7 Privilege Level).
70
ARMMMUIdx mmu_idx,
32
*/
71
CPUARMTBFlags flags)
33
static inline int arm_current_el(CPUARMState *env)
34
{
35
if (arm_feature(env, ARM_FEATURE_M)) {
36
- return !((env->v7m.exception == 0) && (env->v7m.control & 1));
37
+ return arm_v7m_is_handler_mode(env) || !(env->v7m.control & 1);
38
}
39
40
if (is_a64(env)) {
41
@@ -XXX,XX +XXX,XX @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
42
}
43
*flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT;
44
45
- if (env->v7m.exception != 0) {
46
+ if (arm_v7m_is_handler_mode(env)) {
47
*flags |= ARM_TBFLAG_HANDLER_MASK;
48
}
49
50
diff --git a/target/arm/helper.c b/target/arm/helper.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/helper.c
53
+++ b/target/arm/helper.c
54
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
55
* that jumps to magic addresses don't have magic behaviour unless
56
* we're in Handler mode (compare pseudocode BXWritePC()).
57
*/
58
- assert(env->v7m.exception != 0);
59
+ assert(arm_v7m_is_handler_mode(env));
60
61
/* In the spec pseudocode ExceptionReturn() is called directly
62
* from BXWritePC() and gets the full target PC value including
63
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
64
* resuming in Thread mode. If that doesn't match what the
65
* exception return type specified then this is a UsageFault.
66
*/
67
- if (return_to_handler == (env->v7m.exception == 0)) {
68
+ if (return_to_handler != arm_v7m_is_handler_mode(env)) {
69
/* Take an INVPC UsageFault by pushing the stack again. */
70
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
71
env->v7m.cfsr |= R_V7M_CFSR_INVPC_MASK;
72
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
73
if (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) {
74
lr |= 4;
75
}
76
- if (env->v7m.exception == 0) {
77
+ if (!arm_v7m_is_handler_mode(env)) {
78
lr |= 8;
79
}
80
81
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
82
* switch_v7m_sp() deals with updating the SPSEL bit in
83
* env->v7m.control, so we only need update the others.
84
*/
85
- if (env->v7m.exception == 0) {
86
+ if (!arm_v7m_is_handler_mode(env)) {
87
switch_v7m_sp(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 0);
88
}
89
env->v7m.control &= ~R_V7M_CONTROL_NPRIV_MASK;
90
--
72
--
91
2.7.4
73
2.43.0
92
93
diff view generated by jsdifflib
1
Currently we have a rather half-baked setup for allowing CPUs to
1
At the top of linux-user/aarch64/cpu_loop.c we define a set of
2
generate exceptions on accesses to invalid memory: the CPU has a
2
macros for reading and writing data and code words, but we never
3
cpu_unassigned_access() hook which the memory system calls in
3
use these macros. Delete them.
4
unassigned_mem_write() and unassigned_mem_read() if the current_cpu
5
pointer is non-NULL. This was originally designed before we
6
implemented the MemTxResult type that allows memory operations to
7
report a success or failure code, which is why the hook is called
8
right at the bottom of the memory system. The major problem with
9
this is that it means that the hook can be called even when the
10
access was not actually done by the CPU: for instance if the CPU
11
writes to a DMA engine register which causes the DMA engine to begin
12
a transaction which has been set up by the guest to operate on
13
invalid memory then this will casue the CPU to take an exception
14
incorrectly. Another minor problem is that currently if a device
15
returns a transaction error then this won't turn into a CPU exception
16
at all.
17
18
The right way to do this is to have allow the CPU to respond
19
to memory system transaction failures at the point where the
20
CPU specific code calls into the memory system.
21
22
Define a new QOM CPU method and utility function
23
cpu_transaction_failed() which is called in these cases.
24
The functionality here overlaps with the existing
25
cpu_unassigned_access() because individual target CPUs will
26
need some work to convert them to the new system. When this
27
transition is complete we can remove the old cpu_unassigned_access()
28
code.
29
4
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
32
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
33
---
7
---
34
include/qom/cpu.h | 22 ++++++++++++++++++++++
8
linux-user/aarch64/cpu_loop.c | 48 -----------------------------------
35
1 file changed, 22 insertions(+)
9
1 file changed, 48 deletions(-)
36
10
37
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
11
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
38
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
39
--- a/include/qom/cpu.h
13
--- a/linux-user/aarch64/cpu_loop.c
40
+++ b/include/qom/cpu.h
14
+++ b/linux-user/aarch64/cpu_loop.c
41
@@ -XXX,XX +XXX,XX @@ struct TranslationBlock;
15
@@ -XXX,XX +XXX,XX @@
42
* @has_work: Callback for checking if there is work to do.
16
#include "target/arm/syndrome.h"
43
* @do_interrupt: Callback for interrupt handling.
17
#include "target/arm/cpu-features.h"
44
* @do_unassigned_access: Callback for unassigned access handling.
18
45
+ * (this is deprecated: new targets should use do_transaction_failed instead)
19
-#define get_user_code_u32(x, gaddr, env) \
46
* @do_unaligned_access: Callback for unaligned access handling, if
20
- ({ abi_long __r = get_user_u32((x), (gaddr)); \
47
* the target defines #ALIGNED_ONLY.
21
- if (!__r && bswap_code(arm_sctlr_b(env))) { \
48
+ * @do_transaction_failed: Callback for handling failed memory transactions
22
- (x) = bswap32(x); \
49
+ * (ie bus faults or external aborts; not MMU faults)
23
- } \
50
* @virtio_is_big_endian: Callback to return %true if a CPU which supports
24
- __r; \
51
* runtime configurable endianness is currently big-endian. Non-configurable
25
- })
52
* CPUs can use the default implementation of this method. This method should
26
-
53
@@ -XXX,XX +XXX,XX @@ typedef struct CPUClass {
27
-#define get_user_code_u16(x, gaddr, env) \
54
void (*do_unaligned_access)(CPUState *cpu, vaddr addr,
28
- ({ abi_long __r = get_user_u16((x), (gaddr)); \
55
MMUAccessType access_type,
29
- if (!__r && bswap_code(arm_sctlr_b(env))) { \
56
int mmu_idx, uintptr_t retaddr);
30
- (x) = bswap16(x); \
57
+ void (*do_transaction_failed)(CPUState *cpu, hwaddr physaddr, vaddr addr,
31
- } \
58
+ unsigned size, MMUAccessType access_type,
32
- __r; \
59
+ int mmu_idx, MemTxAttrs attrs,
33
- })
60
+ MemTxResult response, uintptr_t retaddr);
34
-
61
bool (*virtio_is_big_endian)(CPUState *cpu);
35
-#define get_user_data_u32(x, gaddr, env) \
62
int (*memory_rw_debug)(CPUState *cpu, vaddr addr,
36
- ({ abi_long __r = get_user_u32((x), (gaddr)); \
63
uint8_t *buf, int len, bool is_write);
37
- if (!__r && arm_cpu_bswap_data(env)) { \
64
@@ -XXX,XX +XXX,XX @@ static inline void cpu_unaligned_access(CPUState *cpu, vaddr addr,
38
- (x) = bswap32(x); \
65
39
- } \
66
cc->do_unaligned_access(cpu, addr, access_type, mmu_idx, retaddr);
40
- __r; \
67
}
41
- })
68
+
42
-
69
+static inline void cpu_transaction_failed(CPUState *cpu, hwaddr physaddr,
43
-#define get_user_data_u16(x, gaddr, env) \
70
+ vaddr addr, unsigned size,
44
- ({ abi_long __r = get_user_u16((x), (gaddr)); \
71
+ MMUAccessType access_type,
45
- if (!__r && arm_cpu_bswap_data(env)) { \
72
+ int mmu_idx, MemTxAttrs attrs,
46
- (x) = bswap16(x); \
73
+ MemTxResult response,
47
- } \
74
+ uintptr_t retaddr)
48
- __r; \
75
+{
49
- })
76
+ CPUClass *cc = CPU_GET_CLASS(cpu);
50
-
77
+
51
-#define put_user_data_u32(x, gaddr, env) \
78
+ if (cc->do_transaction_failed) {
52
- ({ typeof(x) __x = (x); \
79
+ cc->do_transaction_failed(cpu, physaddr, addr, size, access_type,
53
- if (arm_cpu_bswap_data(env)) { \
80
+ mmu_idx, attrs, response, retaddr);
54
- __x = bswap32(__x); \
81
+ }
55
- } \
82
+}
56
- put_user_u32(__x, (gaddr)); \
83
#endif
57
- })
84
58
-
85
#endif /* NEED_CPU_H */
59
-#define put_user_data_u16(x, gaddr, env) \
60
- ({ typeof(x) __x = (x); \
61
- if (arm_cpu_bswap_data(env)) { \
62
- __x = bswap16(__x); \
63
- } \
64
- put_user_u16(__x, (gaddr)); \
65
- })
66
-
67
/* AArch64 main loop */
68
void cpu_loop(CPUARMState *env)
69
{
86
--
70
--
87
2.7.4
71
2.43.0
88
89
diff view generated by jsdifflib
1
For external aborts, we will want to be able to specify the EA
1
In linux-user/arm/cpu_loop.c we define a full set of get/put
2
(external abort type) bit in the syndrome field. Allow callers of
2
macros for both code and data (since the endianness handling
3
deliver_fault() to do that by adding a field to ARMMMUFaultInfo which
3
is different between the two). However the only one we actually
4
we use when constructing the syndrome values.
4
use is get_user_code_u32(). Remove the rest.
5
6
We leave a comment noting how data-side accesses should be handled
7
for big-endian, because that's a subtle point and we just removed the
8
macros that were effectively documenting it.
5
9
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
---
12
---
10
target/arm/internals.h | 2 ++
13
linux-user/arm/cpu_loop.c | 43 ++++-----------------------------------
11
target/arm/op_helper.c | 10 +++++-----
14
1 file changed, 4 insertions(+), 39 deletions(-)
12
2 files changed, 7 insertions(+), 5 deletions(-)
13
15
14
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/internals.h
18
--- a/linux-user/arm/cpu_loop.c
17
+++ b/target/arm/internals.h
19
+++ b/linux-user/arm/cpu_loop.c
18
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu);
20
@@ -XXX,XX +XXX,XX @@
19
* @s2addr: Address that caused a fault at stage 2
21
__r; \
20
* @stage2: True if we faulted at stage 2
22
})
21
* @s1ptw: True if we faulted at stage 2 while doing a stage 1 page-table walk
23
22
+ * @ea: True if we should set the EA (external abort type) bit in syndrome
24
-#define get_user_code_u16(x, gaddr, env) \
23
*/
25
- ({ abi_long __r = get_user_u16((x), (gaddr)); \
24
typedef struct ARMMMUFaultInfo ARMMMUFaultInfo;
26
- if (!__r && bswap_code(arm_sctlr_b(env))) { \
25
struct ARMMMUFaultInfo {
27
- (x) = bswap16(x); \
26
target_ulong s2addr;
28
- } \
27
bool stage2;
29
- __r; \
28
bool s1ptw;
30
- })
29
+ bool ea;
31
-
30
};
32
-#define get_user_data_u32(x, gaddr, env) \
31
33
- ({ abi_long __r = get_user_u32((x), (gaddr)); \
32
/* Do a page table walk and add page to TLB if possible */
34
- if (!__r && arm_cpu_bswap_data(env)) { \
33
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
35
- (x) = bswap32(x); \
34
index XXXXXXX..XXXXXXX 100644
36
- } \
35
--- a/target/arm/op_helper.c
37
- __r; \
36
+++ b/target/arm/op_helper.c
38
- })
37
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(neon_tbl)(CPUARMState *env, uint32_t ireg, uint32_t def,
39
-
38
40
-#define get_user_data_u16(x, gaddr, env) \
39
static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
41
- ({ abi_long __r = get_user_u16((x), (gaddr)); \
40
unsigned int target_el,
42
- if (!__r && arm_cpu_bswap_data(env)) { \
41
- bool same_el,
43
- (x) = bswap16(x); \
42
+ bool same_el, bool ea,
44
- } \
43
bool s1ptw, bool is_write,
45
- __r; \
44
int fsc)
46
- })
45
{
47
-
46
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
48
-#define put_user_data_u32(x, gaddr, env) \
47
*/
49
- ({ typeof(x) __x = (x); \
48
if (!(template_syn & ARM_EL_ISV) || target_el != 2 || s1ptw) {
50
- if (arm_cpu_bswap_data(env)) { \
49
syn = syn_data_abort_no_iss(same_el,
51
- __x = bswap32(__x); \
50
- 0, 0, s1ptw, is_write, fsc);
52
- } \
51
+ ea, 0, s1ptw, is_write, fsc);
53
- put_user_u32(__x, (gaddr)); \
52
} else {
54
- })
53
/* Fields: IL, ISV, SAS, SSE, SRT, SF and AR come from the template
55
-
54
* syndrome created at translation time.
56
-#define put_user_data_u16(x, gaddr, env) \
55
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
57
- ({ typeof(x) __x = (x); \
56
*/
58
- if (arm_cpu_bswap_data(env)) { \
57
syn = syn_data_abort_with_iss(same_el,
59
- __x = bswap16(__x); \
58
0, 0, 0, 0, 0,
60
- } \
59
- 0, 0, s1ptw, is_write, fsc,
61
- put_user_u16(__x, (gaddr)); \
60
+ ea, 0, s1ptw, is_write, fsc,
62
- })
61
false);
63
+/*
62
/* Merge the runtime syndrome with the template syndrome. */
64
+ * Note that if we need to do data accesses here, they should do a
63
syn |= template_syn;
65
+ * bswap if arm_cpu_bswap_data() returns true.
64
@@ -XXX,XX +XXX,XX @@ static void deliver_fault(ARMCPU *cpu, vaddr addr, MMUAccessType access_type,
66
+ */
65
}
67
66
68
/*
67
if (access_type == MMU_INST_FETCH) {
69
* Similar to code in accel/tcg/user-exec.c, but outside the execution loop.
68
- syn = syn_insn_abort(same_el, 0, fi->s1ptw, fsc);
69
+ syn = syn_insn_abort(same_el, fi->ea, fi->s1ptw, fsc);
70
exc = EXCP_PREFETCH_ABORT;
71
} else {
72
syn = merge_syn_data_abort(env->exception.syndrome, target_el,
73
- same_el, fi->s1ptw,
74
+ same_el, fi->ea, fi->s1ptw,
75
access_type == MMU_DATA_STORE,
76
fsc);
77
if (access_type == MMU_DATA_STORE
78
--
70
--
79
2.7.4
71
2.43.0
80
81
diff view generated by jsdifflib
1
Implement the new do_transaction_failed hook for ARM, which should
1
The arm_cpu_data_is_big_endian() and related functions are now used
2
cause the CPU to take a prefetch abort or data abort.
2
only in target/arm; they can be moved to internals.h.
3
4
The motivation here is that we would like to move arm_current_el()
5
to internals.h.
3
6
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
---
9
---
8
target/arm/internals.h | 10 ++++++++++
10
target/arm/cpu.h | 48 ------------------------------------------
9
target/arm/cpu.c | 1 +
11
target/arm/internals.h | 48 ++++++++++++++++++++++++++++++++++++++++++
10
target/arm/op_helper.c | 43 +++++++++++++++++++++++++++++++++++++++++++
12
2 files changed, 48 insertions(+), 48 deletions(-)
11
3 files changed, 54 insertions(+)
12
13
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ static inline bool arm_sctlr_b(CPUARMState *env)
19
20
uint64_t arm_sctlr(CPUARMState *env, int el);
21
22
-static inline bool arm_cpu_data_is_big_endian_a32(CPUARMState *env,
23
- bool sctlr_b)
24
-{
25
-#ifdef CONFIG_USER_ONLY
26
- /*
27
- * In system mode, BE32 is modelled in line with the
28
- * architecture (as word-invariant big-endianness), where loads
29
- * and stores are done little endian but from addresses which
30
- * are adjusted by XORing with the appropriate constant. So the
31
- * endianness to use for the raw data access is not affected by
32
- * SCTLR.B.
33
- * In user mode, however, we model BE32 as byte-invariant
34
- * big-endianness (because user-only code cannot tell the
35
- * difference), and so we need to use a data access endianness
36
- * that depends on SCTLR.B.
37
- */
38
- if (sctlr_b) {
39
- return true;
40
- }
41
-#endif
42
- /* In 32bit endianness is determined by looking at CPSR's E bit */
43
- return env->uncached_cpsr & CPSR_E;
44
-}
45
-
46
-static inline bool arm_cpu_data_is_big_endian_a64(int el, uint64_t sctlr)
47
-{
48
- return sctlr & (el ? SCTLR_EE : SCTLR_E0E);
49
-}
50
-
51
-/* Return true if the processor is in big-endian mode. */
52
-static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
53
-{
54
- if (!is_a64(env)) {
55
- return arm_cpu_data_is_big_endian_a32(env, arm_sctlr_b(env));
56
- } else {
57
- int cur_el = arm_current_el(env);
58
- uint64_t sctlr = arm_sctlr(env, cur_el);
59
- return arm_cpu_data_is_big_endian_a64(cur_el, sctlr);
60
- }
61
-}
62
-
63
#include "exec/cpu-all.h"
64
65
/*
66
@@ -XXX,XX +XXX,XX @@ static inline bool bswap_code(bool sctlr_b)
67
#endif
68
}
69
70
-#ifdef CONFIG_USER_ONLY
71
-static inline bool arm_cpu_bswap_data(CPUARMState *env)
72
-{
73
- return TARGET_BIG_ENDIAN ^ arm_cpu_data_is_big_endian(env);
74
-}
75
-#endif
76
-
77
void cpu_get_tb_cpu_state(CPUARMState *env, vaddr *pc,
78
uint64_t *cs_base, uint32_t *flags);
79
13
diff --git a/target/arm/internals.h b/target/arm/internals.h
80
diff --git a/target/arm/internals.h b/target/arm/internals.h
14
index XXXXXXX..XXXXXXX 100644
81
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/internals.h
82
--- a/target/arm/internals.h
16
+++ b/target/arm/internals.h
83
+++ b/target/arm/internals.h
17
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
84
@@ -XXX,XX +XXX,XX @@ static inline FloatRoundMode arm_rmode_to_sf(ARMFPRounding rmode)
18
MMUAccessType access_type,
85
return arm_rmode_to_sf_map[rmode];
19
int mmu_idx, uintptr_t retaddr);
20
21
+/* arm_cpu_do_transaction_failed: handle a memory system error response
22
+ * (eg "no device/memory present at address") by raising an external abort
23
+ * exception
24
+ */
25
+void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
26
+ vaddr addr, unsigned size,
27
+ MMUAccessType access_type,
28
+ int mmu_idx, MemTxAttrs attrs,
29
+ MemTxResult response, uintptr_t retaddr);
30
+
31
/* Call the EL change hook if one has been registered */
32
static inline void arm_call_el_change_hook(ARMCPU *cpu)
33
{
34
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/cpu.c
37
+++ b/target/arm/cpu.c
38
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
39
#else
40
cc->do_interrupt = arm_cpu_do_interrupt;
41
cc->do_unaligned_access = arm_cpu_do_unaligned_access;
42
+ cc->do_transaction_failed = arm_cpu_do_transaction_failed;
43
cc->get_phys_page_attrs_debug = arm_cpu_get_phys_page_attrs_debug;
44
cc->asidx_from_attrs = arm_asidx_from_attrs;
45
cc->vmsd = &vmstate_arm_cpu;
46
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/op_helper.c
49
+++ b/target/arm/op_helper.c
50
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
51
deliver_fault(cpu, vaddr, access_type, fsr, fsc, &fi);
52
}
86
}
53
87
54
+/* arm_cpu_do_transaction_failed: handle a memory system error response
88
+static inline bool arm_cpu_data_is_big_endian_a32(CPUARMState *env,
55
+ * (eg "no device/memory present at address") by raising an external abort
89
+ bool sctlr_b)
56
+ * exception
57
+ */
58
+void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
59
+ vaddr addr, unsigned size,
60
+ MMUAccessType access_type,
61
+ int mmu_idx, MemTxAttrs attrs,
62
+ MemTxResult response, uintptr_t retaddr)
63
+{
90
+{
64
+ ARMCPU *cpu = ARM_CPU(cs);
91
+#ifdef CONFIG_USER_ONLY
65
+ CPUARMState *env = &cpu->env;
92
+ /*
66
+ uint32_t fsr, fsc;
93
+ * In system mode, BE32 is modelled in line with the
67
+ ARMMMUFaultInfo fi = {};
94
+ * architecture (as word-invariant big-endianness), where loads
68
+ ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
95
+ * and stores are done little endian but from addresses which
69
+
96
+ * are adjusted by XORing with the appropriate constant. So the
70
+ if (retaddr) {
97
+ * endianness to use for the raw data access is not affected by
71
+ /* now we have a real cpu fault */
98
+ * SCTLR.B.
72
+ cpu_restore_state(cs, retaddr);
99
+ * In user mode, however, we model BE32 as byte-invariant
100
+ * big-endianness (because user-only code cannot tell the
101
+ * difference), and so we need to use a data access endianness
102
+ * that depends on SCTLR.B.
103
+ */
104
+ if (sctlr_b) {
105
+ return true;
73
+ }
106
+ }
74
+
107
+#endif
75
+ /* The EA bit in syndromes and fault status registers is an
108
+ /* In 32bit endianness is determined by looking at CPSR's E bit */
76
+ * IMPDEF classification of external aborts. ARM implementations
109
+ return env->uncached_cpsr & CPSR_E;
77
+ * usually use this to indicate AXI bus Decode error (0) or
78
+ * Slave error (1); in QEMU we follow that.
79
+ */
80
+ fi.ea = (response != MEMTX_DECODE_ERROR);
81
+
82
+ /* The fault status register format depends on whether we're using
83
+ * the LPAE long descriptor format, or the short descriptor format.
84
+ */
85
+ if (arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
86
+ /* long descriptor form, STATUS 0b010000: synchronous ext abort */
87
+ fsr = (fi.ea << 12) | (1 << 9) | 0x10;
88
+ } else {
89
+ /* short descriptor form, FSR 0b01000 : synchronous ext abort */
90
+ fsr = (fi.ea << 12) | 0x8;
91
+ }
92
+ fsc = 0x10;
93
+
94
+ deliver_fault(cpu, addr, access_type, fsr, fsc, &fi);
95
+}
110
+}
96
+
111
+
97
#endif /* !defined(CONFIG_USER_ONLY) */
112
+static inline bool arm_cpu_data_is_big_endian_a64(int el, uint64_t sctlr)
98
113
+{
99
uint32_t HELPER(add_setq)(CPUARMState *env, uint32_t a, uint32_t b)
114
+ return sctlr & (el ? SCTLR_EE : SCTLR_E0E);
115
+}
116
+
117
+/* Return true if the processor is in big-endian mode. */
118
+static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
119
+{
120
+ if (!is_a64(env)) {
121
+ return arm_cpu_data_is_big_endian_a32(env, arm_sctlr_b(env));
122
+ } else {
123
+ int cur_el = arm_current_el(env);
124
+ uint64_t sctlr = arm_sctlr(env, cur_el);
125
+ return arm_cpu_data_is_big_endian_a64(cur_el, sctlr);
126
+ }
127
+}
128
+
129
+#ifdef CONFIG_USER_ONLY
130
+static inline bool arm_cpu_bswap_data(CPUARMState *env)
131
+{
132
+ return TARGET_BIG_ENDIAN ^ arm_cpu_data_is_big_endian(env);
133
+}
134
+#endif
135
+
136
static inline void aarch64_save_sp(CPUARMState *env, int el)
137
{
138
if (env->pstate & PSTATE_SP) {
100
--
139
--
101
2.7.4
140
2.43.0
102
103
diff view generated by jsdifflib
1
We currently store the M profile CPU register state PRIMASK and
1
The functions arm_current_el() and arm_el_is_aa64() are used only in
2
FAULTMASK in the daif field of the CPU state in its I and F
2
target/arm and in hw/intc/arm_gicv3_cpuif.c. They're functions that
3
bits. This is a legacy from the original implementation, which
3
query internal state of the CPU. Move them out of cpu.h and into
4
tried to share the cpu_exec_interrupt code between A profile
4
internals.h.
5
and M profile. We've since separated out the two cases because
5
6
they are significantly different, so now there is no common
6
This means we need to include internals.h in arm_gicv3_cpuif.c, but
7
code between M and A profile which looks at env->daif: all the
7
this is justifiable because that file is implementing the GICv3 CPU
8
uses are either in A-only or M-only code paths. Sharing the state
8
interface, which really is part of the CPU proper; we just ended up
9
fields now is just confusing, and will make things awkward
9
implementing it in code in hw/intc/ for historical reasons.
10
when we implement v8M, where the PRIMASK and FAULTMASK
10
11
registers are banked between security states.
11
The motivation for this move is that we'd like to change
12
12
arm_el_is_aa64() to add a condition that uses cpu_isar_feature();
13
Switch M profile over to using v7m.faultmask and v7m.primask
13
but we don't want to include cpu-features.h in cpu.h.
14
fields for these registers.
15
14
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Message-id: 1501692241-23310-10-git-send-email-peter.maydell@linaro.org
19
---
17
---
20
target/arm/cpu.h | 4 +++-
18
target/arm/cpu.h | 66 --------------------------------------
21
hw/intc/armv7m_nvic.c | 4 ++--
19
target/arm/internals.h | 67 +++++++++++++++++++++++++++++++++++++++
22
target/arm/cpu.c | 5 -----
20
hw/intc/arm_gicv3_cpuif.c | 1 +
23
target/arm/helper.c | 18 +++++-------------
21
target/arm/arch_dump.c | 1 +
24
target/arm/machine.c | 33 +++++++++++++++++++++++++++++++++
22
4 files changed, 69 insertions(+), 66 deletions(-)
25
5 files changed, 43 insertions(+), 21 deletions(-)
26
23
27
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
24
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
28
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/cpu.h
26
--- a/target/arm/cpu.h
30
+++ b/target/arm/cpu.h
27
+++ b/target/arm/cpu.h
31
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
28
@@ -XXX,XX +XXX,XX @@ uint64_t arm_hcr_el2_eff_secstate(CPUARMState *env, ARMSecuritySpace space);
32
uint32_t bfar; /* BusFault Address */
29
uint64_t arm_hcr_el2_eff(CPUARMState *env);
33
unsigned mpu_ctrl; /* MPU_CTRL */
30
uint64_t arm_hcrx_el2_eff(CPUARMState *env);
34
int exception;
31
35
+ uint32_t primask;
32
-/* Return true if the specified exception level is running in AArch64 state. */
36
+ uint32_t faultmask;
33
-static inline bool arm_el_is_aa64(CPUARMState *env, int el)
37
} v7m;
34
-{
38
35
- /* This isn't valid for EL0 (if we're in EL0, is_a64() is what you want,
39
/* Information associated with an exception about to be taken:
36
- * and if we're not in EL0 then the state of EL0 isn't well defined.)
40
@@ -XXX,XX +XXX,XX @@ static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
37
- */
41
* we're in a HardFault or NMI handler.
38
- assert(el >= 1 && el <= 3);
42
*/
39
- bool aa64 = arm_feature(env, ARM_FEATURE_AARCH64);
43
if ((env->v7m.exception > 0 && env->v7m.exception <= 3)
40
-
44
- || env->daif & PSTATE_F) {
41
- /* The highest exception level is always at the maximum supported
45
+ || env->v7m.faultmask) {
42
- * register width, and then lower levels have a register width controlled
46
return arm_to_core_mmu_idx(ARMMMUIdx_MNegPri);
43
- * by bits in the SCR or HCR registers.
47
}
44
- */
48
45
- if (el == 3) {
49
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
46
- return aa64;
50
index XXXXXXX..XXXXXXX 100644
47
- }
51
--- a/hw/intc/armv7m_nvic.c
48
-
52
+++ b/hw/intc/armv7m_nvic.c
49
- if (arm_feature(env, ARM_FEATURE_EL3) &&
53
@@ -XXX,XX +XXX,XX @@ static inline int nvic_exec_prio(NVICState *s)
50
- ((env->cp15.scr_el3 & SCR_NS) || !(env->cp15.scr_el3 & SCR_EEL2))) {
54
CPUARMState *env = &s->cpu->env;
51
- aa64 = aa64 && (env->cp15.scr_el3 & SCR_RW);
55
int running;
52
- }
56
53
-
57
- if (env->daif & PSTATE_F) { /* FAULTMASK */
54
- if (el == 2) {
58
+ if (env->v7m.faultmask) {
55
- return aa64;
59
running = -1;
56
- }
60
- } else if (env->daif & PSTATE_I) { /* PRIMASK */
57
-
61
+ } else if (env->v7m.primask) {
58
- if (arm_is_el2_enabled(env)) {
62
running = 0;
59
- aa64 = aa64 && (env->cp15.hcr_el2 & HCR_RW);
63
} else if (env->v7m.basepri > 0) {
60
- }
64
running = env->v7m.basepri & nvic_gprio_mask(s);
61
-
65
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
62
- return aa64;
66
index XXXXXXX..XXXXXXX 100644
63
-}
67
--- a/target/arm/cpu.c
64
-
68
+++ b/target/arm/cpu.c
65
/*
69
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
66
* Function for determining whether guest cp register reads and writes should
70
uint32_t initial_pc; /* Loaded from 0x4 */
67
* access the secure or non-secure bank of a cp register. When EL3 is
71
uint8_t *rom;
68
@@ -XXX,XX +XXX,XX @@ static inline bool arm_v7m_is_handler_mode(CPUARMState *env)
72
69
return env->v7m.exception != 0;
73
- /* For M profile we store FAULTMASK and PRIMASK in the
70
}
74
- * PSTATE F and I bits; these are both clear at reset.
71
75
- */
72
-/* Return the current Exception Level (as per ARMv8; note that this differs
76
- env->daif &= ~(PSTATE_I | PSTATE_F);
73
- * from the ARMv7 Privilege Level).
77
-
74
- */
78
/* The reset value of this bit is IMPDEF, but ARM recommends
75
-static inline int arm_current_el(CPUARMState *env)
79
* that it resets to 1, so QEMU always does that rather than making
76
-{
80
* it dependent on CPU model.
77
- if (arm_feature(env, ARM_FEATURE_M)) {
81
diff --git a/target/arm/helper.c b/target/arm/helper.c
78
- return arm_v7m_is_handler_mode(env) ||
82
index XXXXXXX..XXXXXXX 100644
79
- !(env->v7m.control[env->v7m.secure] & 1);
83
--- a/target/arm/helper.c
80
- }
84
+++ b/target/arm/helper.c
81
-
85
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
82
- if (is_a64(env)) {
86
83
- return extract32(env->pstate, 2, 2);
87
if (env->v7m.exception != ARMV7M_EXCP_NMI) {
84
- }
88
/* Auto-clear FAULTMASK on return from other than NMI */
85
-
89
- env->daif &= ~PSTATE_F;
86
- switch (env->uncached_cpsr & 0x1f) {
90
+ env->v7m.faultmask = 0;
87
- case ARM_CPU_MODE_USR:
91
}
88
- return 0;
92
89
- case ARM_CPU_MODE_HYP:
93
switch (armv7m_nvic_complete_irq(env->nvic, env->v7m.exception)) {
90
- return 2;
94
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
91
- case ARM_CPU_MODE_MON:
95
return (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) ?
92
- return 3;
96
env->regs[13] : env->v7m.other_sp;
93
- default:
97
case 16: /* PRIMASK */
94
- if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
98
- return (env->daif & PSTATE_I) != 0;
95
- /* If EL3 is 32-bit then all secure privileged modes run in
99
+ return env->v7m.primask;
96
- * EL3
100
case 17: /* BASEPRI */
97
- */
101
case 18: /* BASEPRI_MAX */
98
- return 3;
102
return env->v7m.basepri;
103
case 19: /* FAULTMASK */
104
- return (env->daif & PSTATE_F) != 0;
105
+ return env->v7m.faultmask;
106
default:
107
qemu_log_mask(LOG_GUEST_ERROR, "Attempt to read unknown special"
108
" register %d\n", reg);
109
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
110
}
111
break;
112
case 16: /* PRIMASK */
113
- if (val & 1) {
114
- env->daif |= PSTATE_I;
115
- } else {
116
- env->daif &= ~PSTATE_I;
117
- }
99
- }
118
+ env->v7m.primask = val & 1;
100
-
119
break;
101
- return 1;
120
case 17: /* BASEPRI */
102
- }
121
env->v7m.basepri = val & 0xff;
103
-}
122
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
104
-
123
env->v7m.basepri = val;
105
/**
124
break;
106
* write_list_to_cpustate
125
case 19: /* FAULTMASK */
107
* @cpu: ARMCPU
126
- if (val & 1) {
108
diff --git a/target/arm/internals.h b/target/arm/internals.h
127
- env->daif |= PSTATE_F;
109
index XXXXXXX..XXXXXXX 100644
128
- } else {
110
--- a/target/arm/internals.h
129
- env->daif &= ~PSTATE_F;
111
+++ b/target/arm/internals.h
130
- }
112
@@ -XXX,XX +XXX,XX @@ static inline FloatRoundMode arm_rmode_to_sf(ARMFPRounding rmode)
131
+ env->v7m.faultmask = val & 1;
113
return arm_rmode_to_sf_map[rmode];
132
break;
133
case 20: /* CONTROL */
134
/* Writing to the SPSEL bit only has an effect if we are in
135
diff --git a/target/arm/machine.c b/target/arm/machine.c
136
index XXXXXXX..XXXXXXX 100644
137
--- a/target/arm/machine.c
138
+++ b/target/arm/machine.c
139
@@ -XXX,XX +XXX,XX @@ static bool m_needed(void *opaque)
140
return arm_feature(env, ARM_FEATURE_M);
141
}
114
}
142
115
143
+static const VMStateDescription vmstate_m_faultmask_primask = {
116
+/* Return true if the specified exception level is running in AArch64 state. */
144
+ .name = "cpu/m/faultmask-primask",
117
+static inline bool arm_el_is_aa64(CPUARMState *env, int el)
145
+ .version_id = 1,
118
+{
146
+ .minimum_version_id = 1,
119
+ /*
147
+ .fields = (VMStateField[]) {
120
+ * This isn't valid for EL0 (if we're in EL0, is_a64() is what you want,
148
+ VMSTATE_UINT32(env.v7m.faultmask, ARMCPU),
121
+ * and if we're not in EL0 then the state of EL0 isn't well defined.)
149
+ VMSTATE_UINT32(env.v7m.primask, ARMCPU),
122
+ */
150
+ VMSTATE_END_OF_LIST()
123
+ assert(el >= 1 && el <= 3);
151
+ }
124
+ bool aa64 = arm_feature(env, ARM_FEATURE_AARCH64);
152
+};
125
+
153
+
126
+ /*
154
static const VMStateDescription vmstate_m = {
127
+ * The highest exception level is always at the maximum supported
155
.name = "cpu/m",
128
+ * register width, and then lower levels have a register width controlled
156
.version_id = 4,
129
+ * by bits in the SCR or HCR registers.
157
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
130
+ */
158
VMSTATE_UINT32(env.v7m.mpu_ctrl, ARMCPU),
131
+ if (el == 3) {
159
VMSTATE_INT32(env.v7m.exception, ARMCPU),
132
+ return aa64;
160
VMSTATE_END_OF_LIST()
133
+ }
161
+ },
134
+
162
+ .subsections = (const VMStateDescription*[]) {
135
+ if (arm_feature(env, ARM_FEATURE_EL3) &&
163
+ &vmstate_m_faultmask_primask,
136
+ ((env->cp15.scr_el3 & SCR_NS) || !(env->cp15.scr_el3 & SCR_EEL2))) {
164
+ NULL
137
+ aa64 = aa64 && (env->cp15.scr_el3 & SCR_RW);
165
}
138
+ }
166
};
139
+
167
140
+ if (el == 2) {
168
@@ -XXX,XX +XXX,XX @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
141
+ return aa64;
169
CPUARMState *env = &cpu->env;
142
+ }
170
uint32_t val = qemu_get_be32(f);
143
+
171
144
+ if (arm_is_el2_enabled(env)) {
145
+ aa64 = aa64 && (env->cp15.hcr_el2 & HCR_RW);
146
+ }
147
+
148
+ return aa64;
149
+}
150
+
151
+/*
152
+ * Return the current Exception Level (as per ARMv8; note that this differs
153
+ * from the ARMv7 Privilege Level).
154
+ */
155
+static inline int arm_current_el(CPUARMState *env)
156
+{
172
+ if (arm_feature(env, ARM_FEATURE_M)) {
157
+ if (arm_feature(env, ARM_FEATURE_M)) {
173
+ /* If the I or F bits are set then this is a migration from
158
+ return arm_v7m_is_handler_mode(env) ||
174
+ * an old QEMU which still stored the M profile FAULTMASK
159
+ !(env->v7m.control[env->v7m.secure] & 1);
175
+ * and PRIMASK in env->daif. Set v7m.faultmask and v7m.primask
160
+ }
176
+ * accordingly, and then clear the bits so they don't confuse
161
+
177
+ * cpsr_write(). For a new QEMU, the bits here will always be
162
+ if (is_a64(env)) {
178
+ * clear, and the data is transferred using the
163
+ return extract32(env->pstate, 2, 2);
179
+ * vmstate_m_faultmask_primask subsection.
164
+ }
180
+ */
165
+
181
+ if (val & CPSR_F) {
166
+ switch (env->uncached_cpsr & 0x1f) {
182
+ env->v7m.faultmask = 1;
167
+ case ARM_CPU_MODE_USR:
168
+ return 0;
169
+ case ARM_CPU_MODE_HYP:
170
+ return 2;
171
+ case ARM_CPU_MODE_MON:
172
+ return 3;
173
+ default:
174
+ if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
175
+ /* If EL3 is 32-bit then all secure privileged modes run in EL3 */
176
+ return 3;
183
+ }
177
+ }
184
+ if (val & CPSR_I) {
178
+
185
+ env->v7m.primask = 1;
179
+ return 1;
186
+ }
180
+ }
187
+ val &= ~(CPSR_F | CPSR_I);
181
+}
188
+ }
182
+
189
+
183
static inline bool arm_cpu_data_is_big_endian_a32(CPUARMState *env,
190
env->aarch64 = ((val & PSTATE_nRW) == 0);
184
bool sctlr_b)
191
185
{
192
if (is_a64(env)) {
186
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
187
index XXXXXXX..XXXXXXX 100644
188
--- a/hw/intc/arm_gicv3_cpuif.c
189
+++ b/hw/intc/arm_gicv3_cpuif.c
190
@@ -XXX,XX +XXX,XX @@
191
#include "cpu.h"
192
#include "target/arm/cpregs.h"
193
#include "target/arm/cpu-features.h"
194
+#include "target/arm/internals.h"
195
#include "system/tcg.h"
196
#include "system/qtest.h"
197
198
diff --git a/target/arm/arch_dump.c b/target/arm/arch_dump.c
199
index XXXXXXX..XXXXXXX 100644
200
--- a/target/arm/arch_dump.c
201
+++ b/target/arm/arch_dump.c
202
@@ -XXX,XX +XXX,XX @@
203
#include "elf.h"
204
#include "system/dump.h"
205
#include "cpu-features.h"
206
+#include "internals.h"
207
208
/* struct user_pt_regs from arch/arm64/include/uapi/asm/ptrace.h */
209
struct aarch64_user_regs {
193
--
210
--
194
2.7.4
211
2.43.0
195
196
diff view generated by jsdifflib
1
In the ARM get_phys_addr() code, switch to using the MMUAccessType
1
The definition of SCR_EL3.RW says that its effective value is 1 if:
2
enum and its MMU_* values rather than int and literal 0/1/2.
2
- EL2 is implemented and does not support AArch32, and SCR_EL3.NS is 1
3
- the effective value of SCR_EL3.{EEL2,NS} is {1,0} (i.e. we are
4
Secure and Secure EL2 is disabled)
5
6
We implement the second of these in arm_el_is_aa64(), but forgot the
7
first.
8
9
Provide a new function arm_scr_rw_eff() to return the effective
10
value of SCR_EL3.RW, and use it in arm_el_is_aa64() and the other
11
places that currently look directly at the bit value.
12
13
(scr_write() enforces that the RW bit is RAO/WI if neither EL1 nor
14
EL2 have AArch32 support, but if EL1 does but EL2 does not then the
15
bit must still be writeable.)
16
17
This will mean that if code at EL3 attempts to perform an exception
18
return to AArch32 EL2 when EL2 is AArch64-only we will correctly
19
handle this as an illegal exception return: it will be caught by the
20
"return to an EL which is configured for a different register width"
21
check in HELPER(exception_return).
22
23
We do already have some CPU types which don't implement AArch32
24
above EL0, so this is technically a bug; it doesn't seem worth
25
backporting to stable because no sensible guest code will be
26
deliberately attempting to set the RW bit to a value corresponding
27
to an unimplemented execution state and then checking that we
28
did the right thing.
3
29
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 1501692241-23310-2-git-send-email-peter.maydell@linaro.org
9
---
32
---
10
target/arm/internals.h | 3 ++-
33
target/arm/internals.h | 26 +++++++++++++++++++++++---
11
target/arm/helper.c | 30 +++++++++++++++---------------
34
target/arm/helper.c | 4 ++--
12
2 files changed, 17 insertions(+), 16 deletions(-)
35
2 files changed, 25 insertions(+), 5 deletions(-)
13
36
14
diff --git a/target/arm/internals.h b/target/arm/internals.h
37
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/internals.h
39
--- a/target/arm/internals.h
17
+++ b/target/arm/internals.h
40
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@ struct ARMMMUFaultInfo {
41
@@ -XXX,XX +XXX,XX @@ static inline FloatRoundMode arm_rmode_to_sf(ARMFPRounding rmode)
19
};
42
return arm_rmode_to_sf_map[rmode];
20
43
}
21
/* Do a page table walk and add page to TLB if possible */
44
22
-bool arm_tlb_fill(CPUState *cpu, vaddr address, int rw, int mmu_idx,
45
+/* Return the effective value of SCR_EL3.RW */
23
+bool arm_tlb_fill(CPUState *cpu, vaddr address,
46
+static inline bool arm_scr_rw_eff(CPUARMState *env)
24
+ MMUAccessType access_type, int mmu_idx,
47
+{
25
uint32_t *fsr, ARMMMUFaultInfo *fi);
48
+ /*
26
49
+ * SCR_EL3.RW has an effective value of 1 if:
27
/* Return true if the stage 1 translation regime is using LPAE format page
50
+ * - we are NS and EL2 is implemented but doesn't support AArch32
51
+ * - we are S and EL2 is enabled (in which case it must be AArch64)
52
+ */
53
+ ARMCPU *cpu = env_archcpu(env);
54
+
55
+ if (env->cp15.scr_el3 & SCR_RW) {
56
+ return true;
57
+ }
58
+ if (env->cp15.scr_el3 & SCR_NS) {
59
+ return arm_feature(env, ARM_FEATURE_EL2) &&
60
+ !cpu_isar_feature(aa64_aa32_el2, cpu);
61
+ } else {
62
+ return env->cp15.scr_el3 & SCR_EEL2;
63
+ }
64
+}
65
+
66
/* Return true if the specified exception level is running in AArch64 state. */
67
static inline bool arm_el_is_aa64(CPUARMState *env, int el)
68
{
69
@@ -XXX,XX +XXX,XX @@ static inline bool arm_el_is_aa64(CPUARMState *env, int el)
70
return aa64;
71
}
72
73
- if (arm_feature(env, ARM_FEATURE_EL3) &&
74
- ((env->cp15.scr_el3 & SCR_NS) || !(env->cp15.scr_el3 & SCR_EEL2))) {
75
- aa64 = aa64 && (env->cp15.scr_el3 & SCR_RW);
76
+ if (arm_feature(env, ARM_FEATURE_EL3)) {
77
+ aa64 = aa64 && arm_scr_rw_eff(env);
78
}
79
80
if (el == 2) {
28
diff --git a/target/arm/helper.c b/target/arm/helper.c
81
diff --git a/target/arm/helper.c b/target/arm/helper.c
29
index XXXXXXX..XXXXXXX 100644
82
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/helper.c
83
--- a/target/arm/helper.c
31
+++ b/target/arm/helper.c
84
+++ b/target/arm/helper.c
32
@@ -XXX,XX +XXX,XX @@
85
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
33
86
uint64_t hcr_el2;
34
#ifndef CONFIG_USER_ONLY
87
35
static bool get_phys_addr(CPUARMState *env, target_ulong address,
88
if (arm_feature(env, ARM_FEATURE_EL3)) {
36
- int access_type, ARMMMUIdx mmu_idx,
89
- rw = ((env->cp15.scr_el3 & SCR_RW) == SCR_RW);
37
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
90
+ rw = arm_scr_rw_eff(env);
38
hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
39
target_ulong *page_size, uint32_t *fsr,
40
ARMMMUFaultInfo *fi);
41
42
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
43
- int access_type, ARMMMUIdx mmu_idx,
44
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
45
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
46
target_ulong *page_size_ptr, uint32_t *fsr,
47
ARMMMUFaultInfo *fi);
48
@@ -XXX,XX +XXX,XX @@ static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri,
49
}
50
51
static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
52
- int access_type, ARMMMUIdx mmu_idx)
53
+ MMUAccessType access_type, ARMMMUIdx mmu_idx)
54
{
55
hwaddr phys_addr;
56
target_ulong page_size;
57
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
58
59
static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
60
{
61
- int access_type = ri->opc2 & 1;
62
+ MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD;
63
uint64_t par64;
64
ARMMMUIdx mmu_idx;
65
int el = arm_current_el(env);
66
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
67
static void ats1h_write(CPUARMState *env, const ARMCPRegInfo *ri,
68
uint64_t value)
69
{
70
- int access_type = ri->opc2 & 1;
71
+ MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD;
72
uint64_t par64;
73
74
par64 = do_ats_write(env, value, access_type, ARMMMUIdx_S2NS);
75
@@ -XXX,XX +XXX,XX @@ static CPAccessResult at_s1e2_access(CPUARMState *env, const ARMCPRegInfo *ri,
76
static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
77
uint64_t value)
78
{
79
- int access_type = ri->opc2 & 1;
80
+ MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD;
81
ARMMMUIdx mmu_idx;
82
int secure = arm_is_secure_below_el3(env);
83
84
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
85
}
86
87
static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
88
- int access_type, ARMMMUIdx mmu_idx,
89
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
90
hwaddr *phys_ptr, int *prot,
91
target_ulong *page_size, uint32_t *fsr,
92
ARMMMUFaultInfo *fi)
93
@@ -XXX,XX +XXX,XX @@ do_fault:
94
}
95
96
static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
97
- int access_type, ARMMMUIdx mmu_idx,
98
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
99
hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
100
target_ulong *page_size, uint32_t *fsr,
101
ARMMMUFaultInfo *fi)
102
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
103
if (pxn && !regime_is_user(env, mmu_idx)) {
104
xn = 1;
105
}
106
- if (xn && access_type == 2)
107
+ if (xn && access_type == MMU_INST_FETCH)
108
goto do_fault;
109
110
if (arm_feature(env, ARM_FEATURE_V6K) &&
111
@@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
112
}
113
114
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
115
- int access_type, ARMMMUIdx mmu_idx,
116
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
117
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
118
target_ulong *page_size_ptr, uint32_t *fsr,
119
ARMMMUFaultInfo *fi)
120
@@ -XXX,XX +XXX,XX @@ static inline bool m_is_system_region(CPUARMState *env, uint32_t address)
121
}
122
123
static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
124
- int access_type, ARMMMUIdx mmu_idx,
125
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
126
hwaddr *phys_ptr, int *prot, uint32_t *fsr)
127
{
128
ARMCPU *cpu = arm_env_get_cpu(env);
129
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
130
}
131
132
static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
133
- int access_type, ARMMMUIdx mmu_idx,
134
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
135
hwaddr *phys_ptr, int *prot, uint32_t *fsr)
136
{
137
int n;
138
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
139
return true;
140
}
141
142
- if (access_type == 2) {
143
+ if (access_type == MMU_INST_FETCH) {
144
mask = env->cp15.pmsav5_insn_ap;
145
} else {
91
} else {
146
mask = env->cp15.pmsav5_data_ap;
92
/*
147
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
93
* Either EL2 is the highest EL (and so the EL2 register width
148
* @fsr: set to the DFSR/IFSR value on failure
94
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
149
*/
95
150
static bool get_phys_addr(CPUARMState *env, target_ulong address,
96
switch (new_el) {
151
- int access_type, ARMMMUIdx mmu_idx,
97
case 3:
152
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
98
- is_aa64 = (env->cp15.scr_el3 & SCR_RW) != 0;
153
hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
99
+ is_aa64 = arm_scr_rw_eff(env);
154
target_ulong *page_size, uint32_t *fsr,
100
break;
155
ARMMMUFaultInfo *fi)
101
case 2:
156
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
102
hcr = arm_hcr_el2_eff(env);
157
* fsr with ARM DFSR/IFSR fault register format value on failure.
158
*/
159
bool arm_tlb_fill(CPUState *cs, vaddr address,
160
- int access_type, int mmu_idx, uint32_t *fsr,
161
+ MMUAccessType access_type, int mmu_idx, uint32_t *fsr,
162
ARMMMUFaultInfo *fi)
163
{
164
ARMCPU *cpu = ARM_CPU(cs);
165
--
103
--
166
2.7.4
104
2.43.0
167
168
diff view generated by jsdifflib
1
Currently get_phys_addr() has PMSAv7 handling before the
1
When EL1 doesn't support AArch32, the HCR_EL2.RW bit is supposed to
2
"is translation disabled?" check, and then PMSAv5 after it.
2
be RAO/WI. Enforce the RAO/WI behaviour.
3
Tidy this up by making the PMSAv5 code handle the "MPU disabled"
3
4
case itself, so that we have all the PMSA code in one place.
4
Note that we handle "reset value should honour RES1 bits" in the same
5
This will make adding the PMSAv8 code slightly cleaner, and
5
way that SCR_EL3 does, via a reset function.
6
also means that pre-v7 PMSA cores benefit from the MPU lookup
6
7
logging that the PMSAv7 codepath had.
7
We do already have some CPU types which don't implement AArch32
8
above EL0, so this is technically a bug; it doesn't seem worth
9
backporting to stable because no sensible guest code will be
10
deliberately attempting to set the RW bit to a value corresponding
11
to an unimplemented execution state and then checking that we
12
did the right thing.
8
13
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 1501692241-23310-4-git-send-email-peter.maydell@linaro.org
14
---
16
---
15
target/arm/helper.c | 38 ++++++++++++++++++++++----------------
17
target/arm/helper.c | 12 ++++++++++++
16
1 file changed, 22 insertions(+), 16 deletions(-)
18
1 file changed, 12 insertions(+)
17
19
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.c
22
--- a/target/arm/helper.c
21
+++ b/target/arm/helper.c
23
+++ b/target/arm/helper.c
22
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
24
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
23
uint32_t base;
25
/* Clear RES0 bits. */
24
bool is_user = regime_is_user(env, mmu_idx);
26
value &= valid_mask;
25
27
26
+ if (regime_translation_disabled(env, mmu_idx)) {
28
+ /* RW is RAO/WI if EL1 is AArch64 only */
27
+ /* MPU disabled. */
29
+ if (!cpu_isar_feature(aa64_aa32_el1, cpu)) {
28
+ *phys_ptr = address;
30
+ value |= HCR_RW;
29
+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
30
+ return false;
31
+ }
31
+ }
32
+
32
+
33
*phys_ptr = address;
33
/*
34
for (n = 7; n >= 0; n--) {
34
* These bits change the MMU setup:
35
base = env->cp15.c6_region[n];
35
* HCR_VM enables stage 2 translation
36
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
36
@@ -XXX,XX +XXX,XX @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
37
}
37
do_hcr_write(env, value, MAKE_64BIT_MASK(32, 32));
38
}
38
}
39
39
40
- /* pmsav7 has special handling for when MPU is disabled so call it before
40
+static void hcr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
41
- * the common MMU/MPU disabled check below.
41
+{
42
- */
42
+ /* hcr_write will set the RES1 bits on an AArch64-only CPU */
43
- if (arm_feature(env, ARM_FEATURE_PMSA) &&
43
+ hcr_write(env, ri, 0);
44
- arm_feature(env, ARM_FEATURE_V7)) {
44
+}
45
+ if (arm_feature(env, ARM_FEATURE_PMSA)) {
46
bool ret;
47
*page_size = TARGET_PAGE_SIZE;
48
- ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
49
- phys_ptr, prot, fsr);
50
- qemu_log_mask(CPU_LOG_MMU, "PMSAv7 MPU lookup for %s at 0x%08" PRIx32
51
+
45
+
52
+ if (arm_feature(env, ARM_FEATURE_V7)) {
46
/*
53
+ /* PMSAv7 */
47
* Return the effective value of HCR_EL2, at the given security state.
54
+ ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
48
* Bits that are not included here:
55
+ phys_ptr, prot, fsr);
49
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
56
+ } else {
50
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
57
+ /* Pre-v7 MPU */
51
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
58
+ ret = get_phys_addr_pmsav5(env, address, access_type, mmu_idx,
52
.nv2_redirect_offset = 0x78,
59
+ phys_ptr, prot, fsr);
53
+ .resetfn = hcr_reset,
60
+ }
54
.writefn = hcr_write, .raw_writefn = raw_write },
61
+ qemu_log_mask(CPU_LOG_MMU, "PMSA MPU lookup for %s at 0x%08" PRIx32
55
{ .name = "HCR", .state = ARM_CP_STATE_AA32,
62
" mmu_idx %u -> %s (prot %c%c%c)\n",
56
.type = ARM_CP_ALIAS | ARM_CP_IO,
63
access_type == MMU_DATA_LOAD ? "reading" :
64
(access_type == MMU_DATA_STORE ? "writing" : "execute"),
65
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
66
return ret;
67
}
68
69
+ /* Definitely a real MMU, not an MPU */
70
+
71
if (regime_translation_disabled(env, mmu_idx)) {
72
- /* MMU/MPU disabled. */
73
+ /* MMU disabled. */
74
*phys_ptr = address;
75
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
76
*page_size = TARGET_PAGE_SIZE;
77
return 0;
78
}
79
80
- if (arm_feature(env, ARM_FEATURE_PMSA)) {
81
- /* Pre-v7 MPU */
82
- *page_size = TARGET_PAGE_SIZE;
83
- return get_phys_addr_pmsav5(env, address, access_type, mmu_idx,
84
- phys_ptr, prot, fsr);
85
- }
86
-
87
if (regime_using_lpae_format(env, mmu_idx)) {
88
return get_phys_addr_lpae(env, address, access_type, mmu_idx, phys_ptr,
89
attrs, prot, page_size, fsr, fi);
90
--
57
--
91
2.7.4
58
2.43.0
92
93
diff view generated by jsdifflib
1
For M profile the XPSR is a similar but not identical format to the
1
We already call env_archcpu() multiple times within the
2
A profile CPSR/SPSR. (For instance the Thumb bit is in a different
2
exception_return helper function, and we're about to want to
3
place.) For guest accesses we make the M profile code go through
3
add another use of the ARMCPU pointer. Add a local variable
4
xpsr_read() and xpsr_write() which handle the different layout.
4
cpu so we can call env_archcpu() just once.
5
However for migration we use cpsr_read() and cpsr_write() to
6
marshal state into and out of the migration data stream. This
7
is pretty confusing and works more by luck than anything else.
8
Make M profile migration use xpsr_read() and xpsr_write() instead.
9
10
The most complicated part of this is handling the possibility
11
that the migration source is an older QEMU which hands us a
12
CPSR format value; helpfully we can always tell the two apart.
13
5
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 1501692241-23310-11-git-send-email-peter.maydell@linaro.org
17
---
8
---
18
target/arm/machine.c | 49 ++++++++++++++++++++++++++++++++++---------------
9
target/arm/tcg/helper-a64.c | 7 ++++---
19
1 file changed, 34 insertions(+), 15 deletions(-)
10
1 file changed, 4 insertions(+), 3 deletions(-)
20
11
21
diff --git a/target/arm/machine.c b/target/arm/machine.c
12
diff --git a/target/arm/tcg/helper-a64.c b/target/arm/tcg/helper-a64.c
22
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/machine.c
14
--- a/target/arm/tcg/helper-a64.c
24
+++ b/target/arm/machine.c
15
+++ b/target/arm/tcg/helper-a64.c
25
@@ -XXX,XX +XXX,XX @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
16
@@ -XXX,XX +XXX,XX @@ static void cpsr_write_from_spsr_elx(CPUARMState *env,
26
uint32_t val = qemu_get_be32(f);
17
27
18
void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
28
if (arm_feature(env, ARM_FEATURE_M)) {
19
{
29
- /* If the I or F bits are set then this is a migration from
20
+ ARMCPU *cpu = env_archcpu(env);
30
- * an old QEMU which still stored the M profile FAULTMASK
21
int cur_el = arm_current_el(env);
31
- * and PRIMASK in env->daif. Set v7m.faultmask and v7m.primask
22
unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el);
32
- * accordingly, and then clear the bits so they don't confuse
23
uint32_t spsr = env->banked_spsr[spsr_idx];
33
- * cpsr_write(). For a new QEMU, the bits here will always be
24
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
34
- * clear, and the data is transferred using the
35
- * vmstate_m_faultmask_primask subsection.
36
- */
37
- if (val & CPSR_F) {
38
- env->v7m.faultmask = 1;
39
- }
40
- if (val & CPSR_I) {
41
- env->v7m.primask = 1;
42
+ if (val & XPSR_EXCP) {
43
+ /* This is a CPSR format value from an older QEMU. (We can tell
44
+ * because values transferred in XPSR format always have zero
45
+ * for the EXCP field, and CPSR format will always have bit 4
46
+ * set in CPSR_M.) Rearrange it into XPSR format. The significant
47
+ * differences are that the T bit is not in the same place, the
48
+ * primask/faultmask info may be in the CPSR I and F bits, and
49
+ * we do not want the mode bits.
50
+ */
51
+ uint32_t newval = val;
52
+
53
+ newval &= (CPSR_NZCV | CPSR_Q | CPSR_IT | CPSR_GE);
54
+ if (val & CPSR_T) {
55
+ newval |= XPSR_T;
56
+ }
57
+ /* If the I or F bits are set then this is a migration from
58
+ * an old QEMU which still stored the M profile FAULTMASK
59
+ * and PRIMASK in env->daif. For a new QEMU, the data is
60
+ * transferred using the vmstate_m_faultmask_primask subsection.
61
+ */
62
+ if (val & CPSR_F) {
63
+ env->v7m.faultmask = 1;
64
+ }
65
+ if (val & CPSR_I) {
66
+ env->v7m.primask = 1;
67
+ }
68
+ val = newval;
69
}
70
- val &= ~(CPSR_F | CPSR_I);
71
+ /* Ignore the low bits, they are handled by vmstate_m. */
72
+ xpsr_write(env, val, ~XPSR_EXCP);
73
+ return 0;
74
}
25
}
75
26
76
env->aarch64 = ((val & PSTATE_nRW) == 0);
27
bql_lock();
77
@@ -XXX,XX +XXX,XX @@ static int put_cpsr(QEMUFile *f, void *opaque, size_t size,
28
- arm_call_pre_el_change_hook(env_archcpu(env));
78
CPUARMState *env = &cpu->env;
29
+ arm_call_pre_el_change_hook(cpu);
79
uint32_t val;
30
bql_unlock();
80
31
81
- if (is_a64(env)) {
32
if (!return_to_aa64) {
82
+ if (arm_feature(env, ARM_FEATURE_M)) {
33
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
83
+ /* The low 9 bits are v7m.exception, which is handled by vmstate_m. */
34
int tbii;
84
+ val = xpsr_read(env) & ~XPSR_EXCP;
35
85
+ } else if (is_a64(env)) {
36
env->aarch64 = true;
86
val = pstate_read(env);
37
- spsr &= aarch64_pstate_valid_mask(&env_archcpu(env)->isar);
87
} else {
38
+ spsr &= aarch64_pstate_valid_mask(&cpu->isar);
88
val = cpsr_read(env);
39
pstate_write(env, spsr);
40
if (!arm_singlestep_active(env)) {
41
env->pstate &= ~PSTATE_SS;
42
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
43
aarch64_sve_change_el(env, cur_el, new_el, return_to_aa64);
44
45
bql_lock();
46
- arm_call_el_change_hook(env_archcpu(env));
47
+ arm_call_el_change_hook(cpu);
48
bql_unlock();
49
50
return;
89
--
51
--
90
2.7.4
52
2.43.0
91
92
diff view generated by jsdifflib
1
M profile cores can never trap on WFI or WFE instructions. Check for
1
In the Arm ARM, rule R_TYTWB states that returning to AArch32
2
M profile in check_wfx_trap() to ensure this.
2
is an illegal exception return if:
3
* AArch32 is not supported at any exception level
4
* the target EL is configured for AArch64 via SCR_EL3.RW
5
or HCR_EL2.RW or via CPU state at reset
3
6
4
The existing code will do the right thing for v7M cores because
7
We check the second of these, but not the first (which can only be
5
the hcr_el2 and scr_el3 registers will be all-zeroes and so we
8
relevant for the case of a return to EL0, because if AArch32 is not
6
won't attempt to trap, but when we start setting ARM_FEATURE_V8
9
supported at one of the higher ELs then the RW bits will have an
7
for v8M cores the v8A handling of SCTLR.nTWE and .nTWI will not
10
effective value of 1 and the the "configured for AArch64" condition
8
give the right results.
11
will hold also).
12
13
Add the missing condition. Although this is technically a bug
14
(because we have one AArch64-only CPU: a64fx) it isn't worth
15
backporting to stable because no sensible guest code will
16
deliberately try to return to a nonexistent execution state
17
to check that it gets an illegal exception return.
9
18
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 1501692241-23310-3-git-send-email-peter.maydell@linaro.org
14
---
21
---
15
target/arm/op_helper.c | 5 +++++
22
target/arm/tcg/helper-a64.c | 5 +++++
16
1 file changed, 5 insertions(+)
23
1 file changed, 5 insertions(+)
17
24
18
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
25
diff --git a/target/arm/tcg/helper-a64.c b/target/arm/tcg/helper-a64.c
19
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/op_helper.c
27
--- a/target/arm/tcg/helper-a64.c
21
+++ b/target/arm/op_helper.c
28
+++ b/target/arm/tcg/helper-a64.c
22
@@ -XXX,XX +XXX,XX @@ static inline int check_wfx_trap(CPUARMState *env, bool is_wfe)
29
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
23
int cur_el = arm_current_el(env);
30
goto illegal_return;
24
uint64_t mask;
31
}
25
32
26
+ if (arm_feature(env, ARM_FEATURE_M)) {
33
+ if (!return_to_aa64 && !cpu_isar_feature(aa64_aa32, cpu)) {
27
+ /* M profile cores can never trap WFI/WFE. */
34
+ /* Return to AArch32 when CPU is AArch64-only */
28
+ return 0;
35
+ goto illegal_return;
29
+ }
36
+ }
30
+
37
+
31
/* If we are currently in EL0 then we need to check if SCTLR is set up for
38
if (new_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
32
* WFx instructions being trapped to EL1. These trap bits don't exist in v7.
39
goto illegal_return;
33
*/
40
}
34
--
41
--
35
2.7.4
42
2.43.0
36
37
diff view generated by jsdifflib
Deleted patch
1
Tighten up the T32 decoder in the places where new v8M instructions
2
will be:
3
* TT/TTT/TTA/TTAT are in what was nominally LDREX/STREX r15, ...
4
which is UNPREDICTABLE:
5
make the UNPREDICTABLE behaviour be to UNDEF
6
* BXNS/BLXNS are distinguished from BX/BLX via the low 3 bits,
7
which in previous architectural versions are SBZ:
8
enforce the SBZ via UNDEF rather than ignoring it, and move
9
the "ARCH(5)" UNDEF case up so we don't leak a TCG temporary
10
* SG is in the encoding which would be LDRD/STRD with rn = r15;
11
this is UNPREDICTABLE and we currently UNDEF:
12
move this check further up the code so that we don't leak
13
TCG temporaries in the UNDEF case and have a better place
14
to put the SG decode.
15
1
16
This means that if a v8M binary is accidentally run on v7M
17
or if a test case hits something that we haven't implemented
18
yet the behaviour will be obvious (UNDEF) rather than obscure
19
(plough on treating it as a different instruction).
20
21
In the process, add some comments about the instruction patterns
22
at these points in the decode. Our Thumb and ARM decoders are
23
very difficult to understand currently, but gradually adding
24
comments like this should help to clarify what exactly has
25
been decoded when.
26
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
29
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
30
Message-id: 1501692241-23310-5-git-send-email-peter.maydell@linaro.org
31
---
32
target/arm/translate.c | 48 +++++++++++++++++++++++++++++++++++++++---------
33
1 file changed, 39 insertions(+), 9 deletions(-)
34
35
diff --git a/target/arm/translate.c b/target/arm/translate.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/translate.c
38
+++ b/target/arm/translate.c
39
@@ -XXX,XX +XXX,XX @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
40
abort();
41
case 4:
42
if (insn & (1 << 22)) {
43
- /* Other load/store, table branch. */
44
+ /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
45
+ * - load/store doubleword, load/store exclusive, ldacq/strel,
46
+ * table branch.
47
+ */
48
if (insn & 0x01200000) {
49
- /* Load/store doubleword. */
50
+ /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
51
+ * - load/store dual (post-indexed)
52
+ * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
53
+ * - load/store dual (literal and immediate)
54
+ * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
55
+ * - load/store dual (pre-indexed)
56
+ */
57
if (rn == 15) {
58
+ if (insn & (1 << 21)) {
59
+ /* UNPREDICTABLE */
60
+ goto illegal_op;
61
+ }
62
addr = tcg_temp_new_i32();
63
tcg_gen_movi_i32(addr, s->pc & ~3);
64
} else {
65
@@ -XXX,XX +XXX,XX @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
66
}
67
if (insn & (1 << 21)) {
68
/* Base writeback. */
69
- if (rn == 15)
70
- goto illegal_op;
71
tcg_gen_addi_i32(addr, addr, offset - 4);
72
store_reg(s, rn, addr);
73
} else {
74
tcg_temp_free_i32(addr);
75
}
76
} else if ((insn & (1 << 23)) == 0) {
77
- /* Load/store exclusive word. */
78
+ /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
79
+ * - load/store exclusive word
80
+ */
81
+ if (rs == 15) {
82
+ goto illegal_op;
83
+ }
84
addr = tcg_temp_local_new_i32();
85
load_reg_var(s, addr, rn);
86
tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
87
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
88
break;
89
}
90
if (insn & (1 << 10)) {
91
- /* data processing extended or blx */
92
+ /* 0b0100_01xx_xxxx_xxxx
93
+ * - data processing extended, branch and exchange
94
+ */
95
rd = (insn & 7) | ((insn >> 4) & 8);
96
rm = (insn >> 3) & 0xf;
97
op = (insn >> 8) & 3;
98
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
99
tmp = load_reg(s, rm);
100
store_reg(s, rd, tmp);
101
break;
102
- case 3:/* branch [and link] exchange thumb register */
103
- tmp = load_reg(s, rm);
104
- if (insn & (1 << 7)) {
105
+ case 3:
106
+ {
107
+ /* 0b0100_0111_xxxx_xxxx
108
+ * - branch [and link] exchange thumb register
109
+ */
110
+ bool link = insn & (1 << 7);
111
+
112
+ if (insn & 7) {
113
+ goto undef;
114
+ }
115
+ if (link) {
116
ARCH(5);
117
+ }
118
+ tmp = load_reg(s, rm);
119
+ if (link) {
120
val = (uint32_t)s->pc | 1;
121
tmp2 = tcg_temp_new_i32();
122
tcg_gen_movi_i32(tmp2, val);
123
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
124
}
125
break;
126
}
127
+ }
128
break;
129
}
130
131
--
132
2.7.4
133
134
diff view generated by jsdifflib
Deleted patch
1
Remove an out of date comment which says there's only one
2
item in the NVIC container region -- we put systick into its
3
own device object a while back and so now there are two
4
things in the container.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 1501692241-23310-6-git-send-email-peter.maydell@linaro.org
10
---
11
hw/intc/armv7m_nvic.c | 4 ----
12
1 file changed, 4 deletions(-)
13
14
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/armv7m_nvic.c
17
+++ b/hw/intc/armv7m_nvic.c
18
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
19
* 0xd00..0xd3c - SCS registers
20
* 0xd40..0xeff - Reserved or Not implemented
21
* 0xf00 - STIR
22
- *
23
- * At the moment there is only one thing in the container region,
24
- * but we leave it in place to allow us to pull systick out into
25
- * its own device object later.
26
*/
27
memory_region_init(&s->container, OBJECT(s), "nvic", 0x1000);
28
/* The system register region goes at the bottom of the priority
29
--
30
2.7.4
31
32
diff view generated by jsdifflib
Deleted patch
1
Remove the comment that claims that some MPU_CTRL bits are stored
2
in sctlr_el[1]. This has never been true since MPU_CTRL was added
3
in commit 29c483a50607 -- the comment is a leftover from
4
Michael Davidsaver's original implementation, which I modified
5
not to use sctlr_el[1]; I forgot to delete the comment then.
6
1
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 1501692241-23310-7-git-send-email-peter.maydell@linaro.org
11
---
12
target/arm/cpu.h | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
20
uint32_t dfsr; /* Debug Fault Status Register */
21
uint32_t mmfar; /* MemManage Fault Address */
22
uint32_t bfar; /* BusFault Address */
23
- unsigned mpu_ctrl; /* MPU_CTRL (some bits kept in sctlr_el[1]) */
24
+ unsigned mpu_ctrl; /* MPU_CTRL */
25
int exception;
26
} v7m;
27
28
--
29
2.7.4
30
31
diff view generated by jsdifflib
Deleted patch
1
When we switched our handling of exception exit to detect
2
the magic addresses at translate time rather than via
3
a do_unassigned_access hook, we forgot to update a
4
comment; correct the omission.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 1501692241-23310-8-git-send-email-peter.maydell@linaro.org
10
---
11
target/arm/helper.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
19
bool rettobase = false;
20
21
/* We can only get here from an EXCP_EXCEPTION_EXIT, and
22
- * arm_v7m_do_unassigned_access() enforces the architectural rule
23
+ * gen_bx_excret() enforces the architectural rule
24
* that jumps to magic addresses don't have magic behaviour unless
25
* we're in Handler mode (compare pseudocode BXWritePC()).
26
*/
27
--
28
2.7.4
29
30
diff view generated by jsdifflib
Deleted patch
1
Make the arm_cpu_dump_state() debug logging handle the M-profile XPSR
2
rather than assuming it's an A-profile CPSR. On M profile the PSR
3
line of a register dump will now look like this:
4
1
5
XPSR=41000000 -Z-- T priv-thread
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 1501692241-23310-12-git-send-email-peter.maydell@linaro.org
11
---
12
target/arm/translate.c | 58 ++++++++++++++++++++++++++++++++++----------------
13
1 file changed, 40 insertions(+), 18 deletions(-)
14
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.c
18
+++ b/target/arm/translate.c
19
@@ -XXX,XX +XXX,XX @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
20
ARMCPU *cpu = ARM_CPU(cs);
21
CPUARMState *env = &cpu->env;
22
int i;
23
- uint32_t psr;
24
- const char *ns_status;
25
26
if (is_a64(env)) {
27
aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
28
@@ -XXX,XX +XXX,XX @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
29
else
30
cpu_fprintf(f, " ");
31
}
32
- psr = cpsr_read(env);
33
34
- if (arm_feature(env, ARM_FEATURE_EL3) &&
35
- (psr & CPSR_M) != ARM_CPU_MODE_MON) {
36
- ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
37
+ if (arm_feature(env, ARM_FEATURE_M)) {
38
+ uint32_t xpsr = xpsr_read(env);
39
+ const char *mode;
40
+
41
+ if (xpsr & XPSR_EXCP) {
42
+ mode = "handler";
43
+ } else {
44
+ if (env->v7m.control & R_V7M_CONTROL_NPRIV_MASK) {
45
+ mode = "unpriv-thread";
46
+ } else {
47
+ mode = "priv-thread";
48
+ }
49
+ }
50
+
51
+ cpu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s\n",
52
+ xpsr,
53
+ xpsr & XPSR_N ? 'N' : '-',
54
+ xpsr & XPSR_Z ? 'Z' : '-',
55
+ xpsr & XPSR_C ? 'C' : '-',
56
+ xpsr & XPSR_V ? 'V' : '-',
57
+ xpsr & XPSR_T ? 'T' : 'A',
58
+ mode);
59
} else {
60
- ns_status = "";
61
- }
62
-
63
- cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
64
- psr,
65
- psr & (1 << 31) ? 'N' : '-',
66
- psr & (1 << 30) ? 'Z' : '-',
67
- psr & (1 << 29) ? 'C' : '-',
68
- psr & (1 << 28) ? 'V' : '-',
69
- psr & CPSR_T ? 'T' : 'A',
70
- ns_status,
71
- cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
72
+ uint32_t psr = cpsr_read(env);
73
+ const char *ns_status = "";
74
+
75
+ if (arm_feature(env, ARM_FEATURE_EL3) &&
76
+ (psr & CPSR_M) != ARM_CPU_MODE_MON) {
77
+ ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
78
+ }
79
+
80
+ cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
81
+ psr,
82
+ psr & CPSR_N ? 'N' : '-',
83
+ psr & CPSR_Z ? 'Z' : '-',
84
+ psr & CPSR_C ? 'C' : '-',
85
+ psr & CPSR_V ? 'V' : '-',
86
+ psr & CPSR_T ? 'T' : 'A',
87
+ ns_status,
88
+ cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
89
+ }
90
91
if (flags & CPU_DUMP_FPU) {
92
int numvfpregs = 0;
93
--
94
2.7.4
95
96
diff view generated by jsdifflib
Deleted patch
1
Move the code in arm_v7m_cpu_do_interrupt() that calculates the
2
magic LR value down to when we're actually going to use it.
3
Having the calculation and use so far apart makes the code
4
a little harder to understand than it needs to be.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 1501692241-23310-13-git-send-email-peter.maydell@linaro.org
11
---
12
target/arm/helper.c | 15 ++++++++-------
13
1 file changed, 8 insertions(+), 7 deletions(-)
14
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
18
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
20
21
arm_log_exception(cs->exception_index);
22
23
- lr = 0xfffffff1;
24
- if (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) {
25
- lr |= 4;
26
- }
27
- if (env->v7m.exception == 0)
28
- lr |= 8;
29
-
30
/* For exceptions we just mark as pending on the NVIC, and let that
31
handle it. */
32
switch (cs->exception_index) {
33
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
34
return; /* Never happens. Keep compiler happy. */
35
}
36
37
+ lr = 0xfffffff1;
38
+ if (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) {
39
+ lr |= 4;
40
+ }
41
+ if (env->v7m.exception == 0) {
42
+ lr |= 8;
43
+ }
44
+
45
v7m_push_stack(cpu);
46
v7m_exception_taken(cpu, lr);
47
qemu_log_mask(CPU_LOG_INT, "... as %d\n", env->v7m.exception);
48
--
49
2.7.4
50
51
diff view generated by jsdifflib
Deleted patch
1
The armv7m_nvic.h header file was accidentally placed in
2
include/hw/arm; move it to include/hw/intc to match where
3
its corresponding .c file lives.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 1501692241-23310-15-git-send-email-peter.maydell@linaro.org
10
---
11
include/hw/arm/armv7m.h | 2 +-
12
include/hw/{arm => intc}/armv7m_nvic.h | 0
13
hw/intc/armv7m_nvic.c | 2 +-
14
3 files changed, 2 insertions(+), 2 deletions(-)
15
rename include/hw/{arm => intc}/armv7m_nvic.h (100%)
16
17
diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/armv7m.h
20
+++ b/include/hw/arm/armv7m.h
21
@@ -XXX,XX +XXX,XX @@
22
#define HW_ARM_ARMV7M_H
23
24
#include "hw/sysbus.h"
25
-#include "hw/arm/armv7m_nvic.h"
26
+#include "hw/intc/armv7m_nvic.h"
27
28
#define TYPE_BITBAND "ARM,bitband-memory"
29
#define BITBAND(obj) OBJECT_CHECK(BitBandState, (obj), TYPE_BITBAND)
30
diff --git a/include/hw/arm/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
31
similarity index 100%
32
rename from include/hw/arm/armv7m_nvic.h
33
rename to include/hw/intc/armv7m_nvic.h
34
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/intc/armv7m_nvic.c
37
+++ b/hw/intc/armv7m_nvic.c
38
@@ -XXX,XX +XXX,XX @@
39
#include "hw/sysbus.h"
40
#include "qemu/timer.h"
41
#include "hw/arm/arm.h"
42
-#include "hw/arm/armv7m_nvic.h"
43
+#include "hw/intc/armv7m_nvic.h"
44
#include "target/arm/cpu.h"
45
#include "exec/exec-all.h"
46
#include "qemu/log.h"
47
--
48
2.7.4
49
50
diff view generated by jsdifflib
Deleted patch
1
The ARMv7M architecture specifies that most of the addresses in the
2
PPB region (which includes the NVIC, systick and system registers)
3
are not accessible to unprivileged accesses, which should
4
BusFault with a few exceptions:
5
* the STIR is configurably user-accessible
6
* the ITM (which we don't implement at all) is always
7
user-accessible
8
1
9
Implement this by switching the register access functions
10
to the _with_attrs scheme that lets us distinguish user
11
mode accesses.
12
13
This allows us to pull the handling of the CCR.USERSETMPEND
14
flag up to the level where we can make it generate a BusFault
15
as it should for non-permitted accesses.
16
17
Note that until the core ARM CPU code implements turning
18
MEMTX_ERROR into a BusFault the registers will continue to
19
act as RAZ/WI to user accesses.
20
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Message-id: 1501692241-23310-16-git-send-email-peter.maydell@linaro.org
25
---
26
hw/intc/armv7m_nvic.c | 58 ++++++++++++++++++++++++++++++++++++---------------
27
1 file changed, 41 insertions(+), 17 deletions(-)
28
29
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/intc/armv7m_nvic.c
32
+++ b/hw/intc/armv7m_nvic.c
33
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
34
}
35
case 0xf00: /* Software Triggered Interrupt Register */
36
{
37
- /* user mode can only write to STIR if CCR.USERSETMPEND permits it */
38
int excnum = (value & 0x1ff) + NVIC_FIRST_IRQ;
39
- if (excnum < s->num_irq &&
40
- (arm_current_el(&cpu->env) ||
41
- (cpu->env.v7m.ccr & R_V7M_CCR_USERSETMPEND_MASK))) {
42
+ if (excnum < s->num_irq) {
43
armv7m_nvic_set_pending(s, excnum);
44
}
45
break;
46
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
47
}
48
}
49
50
-static uint64_t nvic_sysreg_read(void *opaque, hwaddr addr,
51
- unsigned size)
52
+static bool nvic_user_access_ok(NVICState *s, hwaddr offset)
53
+{
54
+ /* Return true if unprivileged access to this register is permitted. */
55
+ switch (offset) {
56
+ case 0xf00: /* STIR: accessible only if CCR.USERSETMPEND permits */
57
+ return s->cpu->env.v7m.ccr & R_V7M_CCR_USERSETMPEND_MASK;
58
+ default:
59
+ /* All other user accesses cause a BusFault unconditionally */
60
+ return false;
61
+ }
62
+}
63
+
64
+static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
65
+ uint64_t *data, unsigned size,
66
+ MemTxAttrs attrs)
67
{
68
NVICState *s = (NVICState *)opaque;
69
uint32_t offset = addr;
70
unsigned i, startvec, end;
71
uint32_t val;
72
73
+ if (attrs.user && !nvic_user_access_ok(s, addr)) {
74
+ /* Generate BusFault for unprivileged accesses */
75
+ return MEMTX_ERROR;
76
+ }
77
+
78
switch (offset) {
79
/* reads of set and clear both return the status */
80
case 0x100 ... 0x13f: /* NVIC Set enable */
81
@@ -XXX,XX +XXX,XX @@ static uint64_t nvic_sysreg_read(void *opaque, hwaddr addr,
82
}
83
84
trace_nvic_sysreg_read(addr, val, size);
85
- return val;
86
+ *data = val;
87
+ return MEMTX_OK;
88
}
89
90
-static void nvic_sysreg_write(void *opaque, hwaddr addr,
91
- uint64_t value, unsigned size)
92
+static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
93
+ uint64_t value, unsigned size,
94
+ MemTxAttrs attrs)
95
{
96
NVICState *s = (NVICState *)opaque;
97
uint32_t offset = addr;
98
@@ -XXX,XX +XXX,XX @@ static void nvic_sysreg_write(void *opaque, hwaddr addr,
99
100
trace_nvic_sysreg_write(addr, value, size);
101
102
+ if (attrs.user && !nvic_user_access_ok(s, addr)) {
103
+ /* Generate BusFault for unprivileged accesses */
104
+ return MEMTX_ERROR;
105
+ }
106
+
107
switch (offset) {
108
case 0x100 ... 0x13f: /* NVIC Set enable */
109
offset += 0x80;
110
@@ -XXX,XX +XXX,XX @@ static void nvic_sysreg_write(void *opaque, hwaddr addr,
111
}
112
}
113
nvic_irq_update(s);
114
- return;
115
+ return MEMTX_OK;
116
case 0x200 ... 0x23f: /* NVIC Set pend */
117
/* the special logic in armv7m_nvic_set_pending()
118
* is not needed since IRQs are never escalated
119
@@ -XXX,XX +XXX,XX @@ static void nvic_sysreg_write(void *opaque, hwaddr addr,
120
}
121
}
122
nvic_irq_update(s);
123
- return;
124
+ return MEMTX_OK;
125
case 0x300 ... 0x33f: /* NVIC Active */
126
- return; /* R/O */
127
+ return MEMTX_OK; /* R/O */
128
case 0x400 ... 0x5ef: /* NVIC Priority */
129
startvec = 8 * (offset - 0x400) + NVIC_FIRST_IRQ; /* vector # */
130
131
@@ -XXX,XX +XXX,XX @@ static void nvic_sysreg_write(void *opaque, hwaddr addr,
132
set_prio(s, startvec + i, (value >> (i * 8)) & 0xff);
133
}
134
nvic_irq_update(s);
135
- return;
136
+ return MEMTX_OK;
137
case 0xd18 ... 0xd23: /* System Handler Priority. */
138
for (i = 0; i < size; i++) {
139
unsigned hdlidx = (offset - 0xd14) + i;
140
set_prio(s, hdlidx, (value >> (i * 8)) & 0xff);
141
}
142
nvic_irq_update(s);
143
- return;
144
+ return MEMTX_OK;
145
}
146
if (size == 4) {
147
nvic_writel(s, offset, value);
148
- return;
149
+ return MEMTX_OK;
150
}
151
qemu_log_mask(LOG_GUEST_ERROR,
152
"NVIC: Bad write of size %d at offset 0x%x\n", size, offset);
153
+ /* This is UNPREDICTABLE; treat as RAZ/WI */
154
+ return MEMTX_OK;
155
}
156
157
static const MemoryRegionOps nvic_sysreg_ops = {
158
- .read = nvic_sysreg_read,
159
- .write = nvic_sysreg_write,
160
+ .read_with_attrs = nvic_sysreg_read,
161
+ .write_with_attrs = nvic_sysreg_write,
162
.endianness = DEVICE_NATIVE_ENDIAN,
163
};
164
165
--
166
2.7.4
167
168
diff view generated by jsdifflib
Deleted patch
1
For embedded systems, notably ARM, one common use of ELF
2
file segments is that the 'physical addresses' represent load addresses
3
and the 'virtual addresses' execution addresses, such that
4
the load addresses are packed into ROM or flash, and the
5
relocation and zero-initialization of data is done at runtime.
6
This means that the 'memsz' in the segment header represents
7
the runtime size of the segment, but the size that needs to
8
be loaded is only the 'filesz'. In particular, paddr+memsz
9
may overlap with the next segment to be loaded, as in this
10
example:
11
1
12
0x70000001 off 0x00007f68 vaddr 0x00008150 paddr 0x00008150 align 2**2
13
filesz 0x00000008 memsz 0x00000008 flags r--
14
LOAD off 0x000000f4 vaddr 0x00000000 paddr 0x00000000 align 2**2
15
filesz 0x00000124 memsz 0x00000124 flags r--
16
LOAD off 0x00000218 vaddr 0x00000400 paddr 0x00000400 align 2**3
17
filesz 0x00007d58 memsz 0x00007d58 flags r-x
18
LOAD off 0x00007f70 vaddr 0x20000140 paddr 0x00008158 align 2**3
19
filesz 0x00000a80 memsz 0x000022f8 flags rw-
20
LOAD off 0x000089f0 vaddr 0x20002438 paddr 0x00008bd8 align 2**0
21
filesz 0x00000000 memsz 0x00004000 flags rw-
22
LOAD off 0x000089f0 vaddr 0x20000000 paddr 0x20000000 align 2**0
23
filesz 0x00000000 memsz 0x00000140 flags rw-
24
25
where the segment at paddr 0x8158 has a memsz of 0x2258 and
26
would overlap with the segment at paddr 0x8bd8 if QEMU's loader
27
tried to honour it. (At runtime the segments will not overlap
28
since their vaddrs are more widely spaced than their paddrs.)
29
30
Currently if you try to load an ELF file like this with QEMU then
31
it will fail with an error "rom: requested regions overlap",
32
because we create a ROM image for each segment using the memsz
33
as the size.
34
35
Support ELF files using this scheme, by truncating the
36
zero-initialized part of the segment if it would overlap another
37
segment. This will retain the existing loader behaviour for
38
all ELF files we currently accept, and also accept ELF files
39
which only need 'filesz' bytes to be loaded.
40
41
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
42
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
43
Message-id: 1502116754-18867-2-git-send-email-peter.maydell@linaro.org
44
---
45
include/hw/elf_ops.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
46
1 file changed, 48 insertions(+)
47
48
diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h
49
index XXXXXXX..XXXXXXX 100644
50
--- a/include/hw/elf_ops.h
51
+++ b/include/hw/elf_ops.h
52
@@ -XXX,XX +XXX,XX @@ static int glue(load_elf, SZ)(const char *name, int fd,
53
goto fail;
54
}
55
}
56
+
57
+ /* The ELF spec is somewhat vague about the purpose of the
58
+ * physical address field. One common use in the embedded world
59
+ * is that physical address field specifies the load address
60
+ * and the virtual address field specifies the execution address.
61
+ * Segments are packed into ROM or flash, and the relocation
62
+ * and zero-initialization of data is done at runtime. This
63
+ * means that the memsz header represents the runtime size of the
64
+ * segment, but the filesz represents the loadtime size. If
65
+ * we try to honour the memsz value for an ELF file like this
66
+ * we will end up with overlapping segments (which the
67
+ * loader.c code will later reject).
68
+ * We support ELF files using this scheme by by checking whether
69
+ * paddr + memsz for this segment would overlap with any other
70
+ * segment. If so, then we assume it's using this scheme and
71
+ * truncate the loaded segment to the filesz size.
72
+ * If the segment considered as being memsz size doesn't overlap
73
+ * then we use memsz for the segment length, to handle ELF files
74
+ * which assume that the loader will do the zero-initialization.
75
+ */
76
+ if (mem_size > file_size) {
77
+ /* If this segment's zero-init portion overlaps another
78
+ * segment's data or zero-init portion, then truncate this one.
79
+ * Invalid ELF files where the segments overlap even when
80
+ * only file_size bytes are loaded will be rejected by
81
+ * the ROM overlap check in loader.c, so we don't try to
82
+ * explicitly detect those here.
83
+ */
84
+ int j;
85
+ elf_word zero_start = ph->p_paddr + file_size;
86
+ elf_word zero_end = ph->p_paddr + mem_size;
87
+
88
+ for (j = 0; j < ehdr.e_phnum; j++) {
89
+ struct elf_phdr *jph = &phdr[j];
90
+
91
+ if (i != j && jph->p_type == PT_LOAD) {
92
+ elf_word other_start = jph->p_paddr;
93
+ elf_word other_end = jph->p_paddr + jph->p_memsz;
94
+
95
+ if (!(other_start >= zero_end ||
96
+ zero_start >= other_end)) {
97
+ mem_size = file_size;
98
+ break;
99
+ }
100
+ }
101
+ }
102
+ }
103
+
104
/* address_offset is hack for kernel images that are
105
linked at the wrong physical address. */
106
if (translate_fn) {
107
--
108
2.7.4
109
110
diff view generated by jsdifflib
Deleted patch
1
Some ELF files have program headers that specify segments that
2
are of zero size. Ignore them, rather than trying to create
3
zero-length ROM blobs for them, because the zero-length blob
4
can falsely trigger the overlapping-ROM-blobs check.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Hua Yanghao <huayanghao@gmail.com>
10
Message-id: 1502116754-18867-3-git-send-email-peter.maydell@linaro.org
11
---
12
include/hw/elf_ops.h | 24 +++++++++++++++++-------
13
1 file changed, 17 insertions(+), 7 deletions(-)
14
15
diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/elf_ops.h
18
+++ b/include/hw/elf_ops.h
19
@@ -XXX,XX +XXX,XX @@ static int glue(load_elf, SZ)(const char *name, int fd,
20
*pentry = ehdr.e_entry - ph->p_vaddr + ph->p_paddr;
21
}
22
23
- if (load_rom) {
24
- snprintf(label, sizeof(label), "phdr #%d: %s", i, name);
25
-
26
- /* rom_add_elf_program() seize the ownership of 'data' */
27
- rom_add_elf_program(label, data, file_size, mem_size, addr, as);
28
- } else {
29
- cpu_physical_memory_write(addr, data, file_size);
30
+ if (mem_size == 0) {
31
+ /* Some ELF files really do have segments of zero size;
32
+ * just ignore them rather than trying to create empty
33
+ * ROM blobs, because the zero-length blob can falsely
34
+ * trigger the overlapping-ROM-blobs check.
35
+ */
36
g_free(data);
37
+ } else {
38
+ if (load_rom) {
39
+ snprintf(label, sizeof(label), "phdr #%d: %s", i, name);
40
+
41
+ /* rom_add_elf_program() seize the ownership of 'data' */
42
+ rom_add_elf_program(label, data, file_size, mem_size,
43
+ addr, as);
44
+ } else {
45
+ cpu_physical_memory_write(addr, data, file_size);
46
+ g_free(data);
47
+ }
48
}
49
50
total_size += mem_size;
51
--
52
2.7.4
53
54
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
---
7
hw/arm/armv7m.c | 4 ++--
8
hw/arm/exynos4210.c | 4 ++--
9
hw/arm/highbank.c | 11 +++++++----
10
hw/arm/realview.c | 6 ++++--
11
hw/arm/vexpress.c | 6 ++++--
12
hw/arm/xilinx_zynq.c | 14 ++++++++------
13
6 files changed, 27 insertions(+), 18 deletions(-)
14
15
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/armv7m.c
18
+++ b/hw/arm/armv7m.c
19
@@ -XXX,XX +XXX,XX @@ static void armv7m_instance_init(Object *obj)
20
&error_abort);
21
memory_region_init(&s->container, obj, "armv7m-container", UINT64_MAX);
22
23
- object_initialize(&s->nvic, sizeof(s->nvic), "armv7m_nvic");
24
+ object_initialize(&s->nvic, sizeof(s->nvic), TYPE_NVIC);
25
qdev_set_parent_bus(DEVICE(&s->nvic), sysbus_get_default());
26
object_property_add_alias(obj, "num-irq",
27
OBJECT(&s->nvic), "num-irq", &error_abort);
28
@@ -XXX,XX +XXX,XX @@ DeviceState *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
29
cpu_model = "cortex-m3";
30
}
31
32
- armv7m = qdev_create(NULL, "armv7m");
33
+ armv7m = qdev_create(NULL, TYPE_ARMV7M);
34
qdev_prop_set_uint32(armv7m, "num-irq", num_irq);
35
qdev_prop_set_string(armv7m, "cpu-model", cpu_model);
36
object_property_set_link(OBJECT(armv7m), OBJECT(get_system_memory()),
37
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/arm/exynos4210.c
40
+++ b/hw/arm/exynos4210.c
41
@@ -XXX,XX +XXX,XX @@
42
#include "hw/arm/arm.h"
43
#include "hw/loader.h"
44
#include "hw/arm/exynos4210.h"
45
-#include "hw/sd/sd.h"
46
+#include "hw/sd/sdhci.h"
47
#include "hw/usb/hcd-ehci.h"
48
49
#define EXYNOS4210_CHIPID_ADDR 0x10000000
50
@@ -XXX,XX +XXX,XX @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem)
51
BlockBackend *blk;
52
DriveInfo *di;
53
54
- dev = qdev_create(NULL, "generic-sdhci");
55
+ dev = qdev_create(NULL, TYPE_SYSBUS_SDHCI);
56
qdev_prop_set_uint32(dev, "capareg", EXYNOS4210_SDHCI_CAPABILITIES);
57
qdev_init_nofail(dev);
58
59
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/arm/highbank.c
62
+++ b/hw/arm/highbank.c
63
@@ -XXX,XX +XXX,XX @@
64
#include "exec/address-spaces.h"
65
#include "qemu/error-report.h"
66
#include "hw/char/pl011.h"
67
+#include "hw/ide/ahci.h"
68
+#include "hw/cpu/a9mpcore.h"
69
+#include "hw/cpu/a15mpcore.h"
70
71
#define SMP_BOOT_ADDR 0x100
72
#define SMP_BOOT_REG 0x40
73
@@ -XXX,XX +XXX,XX @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
74
busdev = SYS_BUS_DEVICE(dev);
75
sysbus_mmio_map(busdev, 0, 0xfff12000);
76
77
- dev = qdev_create(NULL, "a9mpcore_priv");
78
+ dev = qdev_create(NULL, TYPE_A9MPCORE_PRIV);
79
break;
80
case CALXEDA_MIDWAY:
81
- dev = qdev_create(NULL, "a15mpcore_priv");
82
+ dev = qdev_create(NULL, TYPE_A15MPCORE_PRIV);
83
break;
84
}
85
qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
86
@@ -XXX,XX +XXX,XX @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
87
sysbus_connect_irq(busdev, 0, pic[18]);
88
pl011_create(0xfff36000, pic[20], serial_hds[0]);
89
90
- dev = qdev_create(NULL, "highbank-regs");
91
+ dev = qdev_create(NULL, TYPE_HIGHBANK_REGISTERS);
92
qdev_init_nofail(dev);
93
busdev = SYS_BUS_DEVICE(dev);
94
sysbus_mmio_map(busdev, 0, 0xfff3c000);
95
@@ -XXX,XX +XXX,XX @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
96
sysbus_create_simple("pl031", 0xfff35000, pic[19]);
97
sysbus_create_simple("pl022", 0xfff39000, pic[23]);
98
99
- sysbus_create_simple("sysbus-ahci", 0xffe08000, pic[83]);
100
+ sysbus_create_simple(TYPE_SYSBUS_AHCI, 0xffe08000, pic[83]);
101
102
if (nd_table[0].used) {
103
qemu_check_nic_model(&nd_table[0], "xgmac");
104
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/hw/arm/realview.c
107
+++ b/hw/arm/realview.c
108
@@ -XXX,XX +XXX,XX @@
109
#include "exec/address-spaces.h"
110
#include "qemu/error-report.h"
111
#include "hw/char/pl011.h"
112
+#include "hw/cpu/a9mpcore.h"
113
+#include "hw/intc/realview_gic.h"
114
115
#define SMP_BOOT_ADDR 0xe0000000
116
#define SMP_BOOTREG_ADDR 0x10000030
117
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
118
sysbus_mmio_map(SYS_BUS_DEVICE(sysctl), 0, 0x10000000);
119
120
if (is_mpcore) {
121
- dev = qdev_create(NULL, is_pb ? "a9mpcore_priv": "realview_mpcore");
122
+ dev = qdev_create(NULL, is_pb ? TYPE_A9MPCORE_PRIV : "realview_mpcore");
123
qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
124
qdev_init_nofail(dev);
125
busdev = SYS_BUS_DEVICE(dev);
126
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
127
} else {
128
uint32_t gic_addr = is_pb ? 0x1e000000 : 0x10040000;
129
/* For now just create the nIRQ GIC, and ignore the others. */
130
- dev = sysbus_create_simple("realview_gic", gic_addr, cpu_irq[0]);
131
+ dev = sysbus_create_simple(TYPE_REALVIEW_GIC, gic_addr, cpu_irq[0]);
132
}
133
for (n = 0; n < 64; n++) {
134
pic[n] = qdev_get_gpio_in(dev, n);
135
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
136
index XXXXXXX..XXXXXXX 100644
137
--- a/hw/arm/vexpress.c
138
+++ b/hw/arm/vexpress.c
139
@@ -XXX,XX +XXX,XX @@
140
#include "qemu/error-report.h"
141
#include <libfdt.h>
142
#include "hw/char/pl011.h"
143
+#include "hw/cpu/a9mpcore.h"
144
+#include "hw/cpu/a15mpcore.h"
145
146
#define VEXPRESS_BOARD_ID 0x8e0
147
#define VEXPRESS_FLASH_SIZE (64 * 1024 * 1024)
148
@@ -XXX,XX +XXX,XX @@ static void a9_daughterboard_init(const VexpressMachineState *vms,
149
memory_region_add_subregion(sysmem, 0x60000000, ram);
150
151
/* 0x1e000000 A9MPCore (SCU) private memory region */
152
- init_cpus(cpu_model, "a9mpcore_priv", 0x1e000000, pic, vms->secure);
153
+ init_cpus(cpu_model, TYPE_A9MPCORE_PRIV, 0x1e000000, pic, vms->secure);
154
155
/* Daughterboard peripherals : 0x10020000 .. 0x20000000 */
156
157
@@ -XXX,XX +XXX,XX @@ static void a15_daughterboard_init(const VexpressMachineState *vms,
158
memory_region_add_subregion(sysmem, 0x80000000, ram);
159
160
/* 0x2c000000 A15MPCore private memory region (GIC) */
161
- init_cpus(cpu_model, "a15mpcore_priv", 0x2c000000, pic, vms->secure);
162
+ init_cpus(cpu_model, TYPE_A15MPCORE_PRIV, 0x2c000000, pic, vms->secure);
163
164
/* A15 daughterboard peripherals: */
165
166
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
167
index XXXXXXX..XXXXXXX 100644
168
--- a/hw/arm/xilinx_zynq.c
169
+++ b/hw/arm/xilinx_zynq.c
170
@@ -XXX,XX +XXX,XX @@
171
#include "hw/misc/zynq-xadc.h"
172
#include "hw/ssi/ssi.h"
173
#include "qemu/error-report.h"
174
-#include "hw/sd/sd.h"
175
+#include "hw/sd/sdhci.h"
176
#include "hw/char/cadence_uart.h"
177
+#include "hw/net/cadence_gem.h"
178
+#include "hw/cpu/a9mpcore.h"
179
180
#define NUM_SPI_FLASHES 4
181
#define NUM_QSPI_FLASHES 2
182
@@ -XXX,XX +XXX,XX @@ static void gem_init(NICInfo *nd, uint32_t base, qemu_irq irq)
183
DeviceState *dev;
184
SysBusDevice *s;
185
186
- dev = qdev_create(NULL, "cadence_gem");
187
+ dev = qdev_create(NULL, TYPE_CADENCE_GEM);
188
if (nd->used) {
189
- qemu_check_nic_model(nd, "cadence_gem");
190
+ qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
191
qdev_set_nic_properties(dev, nd);
192
}
193
qdev_init_nofail(dev);
194
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
195
qdev_init_nofail(dev);
196
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xF8000000);
197
198
- dev = qdev_create(NULL, "a9mpcore_priv");
199
+ dev = qdev_create(NULL, TYPE_A9MPCORE_PRIV);
200
qdev_prop_set_uint32(dev, "num-cpu", 1);
201
qdev_init_nofail(dev);
202
busdev = SYS_BUS_DEVICE(dev);
203
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
204
gem_init(&nd_table[0], 0xE000B000, pic[54-IRQ_OFFSET]);
205
gem_init(&nd_table[1], 0xE000C000, pic[77-IRQ_OFFSET]);
206
207
- dev = qdev_create(NULL, "generic-sdhci");
208
+ dev = qdev_create(NULL, TYPE_SYSBUS_SDHCI);
209
qdev_init_nofail(dev);
210
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xE0100000);
211
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[56-IRQ_OFFSET]);
212
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
213
qdev_prop_set_drive(carddev, "drive", blk, &error_fatal);
214
object_property_set_bool(OBJECT(carddev), true, "realized", &error_fatal);
215
216
- dev = qdev_create(NULL, "generic-sdhci");
217
+ dev = qdev_create(NULL, TYPE_SYSBUS_SDHCI);
218
qdev_init_nofail(dev);
219
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xE0101000);
220
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[79-IRQ_OFFSET]);
221
--
222
2.7.4
223
224
diff view generated by jsdifflib
Deleted patch
1
From: Andrew Jones <drjones@redhat.com>
2
1
3
Mimicking gicv3-maintenance-interrupt, add the PMU's interrupt to
4
CPU state.
5
6
Signed-off-by: Andrew Jones <drjones@redhat.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 1500471597-2517-2-git-send-email-drjones@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/cpu.h | 2 ++
12
hw/arm/virt.c | 3 +++
13
target/arm/cpu.c | 2 ++
14
3 files changed, 7 insertions(+)
15
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
21
qemu_irq gt_timer_outputs[NUM_GTIMERS];
22
/* GPIO output for GICv3 maintenance interrupt signal */
23
qemu_irq gicv3_maintenance_interrupt;
24
+ /* GPIO output for the PMU interrupt */
25
+ qemu_irq pmu_interrupt;
26
27
/* MemoryRegion to use for secure physical accesses */
28
MemoryRegion *secure_memory;
29
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/virt.c
32
+++ b/hw/arm/virt.c
33
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
34
qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 0,
35
qdev_get_gpio_in(gicdev, ppibase
36
+ ARCH_GICV3_MAINT_IRQ));
37
+ qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
38
+ qdev_get_gpio_in(gicdev, ppibase
39
+ + VIRTUAL_PMU_IRQ));
40
41
sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
42
sysbus_connect_irq(gicbusdev, i + smp_cpus,
43
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/cpu.c
46
+++ b/target/arm/cpu.c
47
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_initfn(Object *obj)
48
49
qdev_init_gpio_out_named(DEVICE(cpu), &cpu->gicv3_maintenance_interrupt,
50
"gicv3-maintenance-interrupt", 1);
51
+ qdev_init_gpio_out_named(DEVICE(cpu), &cpu->pmu_interrupt,
52
+ "pmu-interrupt", 1);
53
#endif
54
55
/* DTB consumers generally don't in fact care what the 'compatible'
56
--
57
2.7.4
58
59
diff view generated by jsdifflib
Deleted patch
1
From: Andrew Jones <drjones@redhat.com>
2
1
3
When adding a PMU with a userspace irqchip we skip the set-irq
4
stage of device creation. Split the 'create' function into two
5
functions 'init' and 'set-irq' so they may be called separately.
6
7
Signed-off-by: Andrew Jones <drjones@redhat.com>
8
Reviewed-by: Christoffer Dall <cdall@linaro.org>
9
Message-id: 1500471597-2517-3-git-send-email-drjones@redhat.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/kvm_arm.h | 10 ++++++++--
13
hw/arm/virt.c | 11 +++++++++--
14
target/arm/kvm32.c | 8 +++++++-
15
target/arm/kvm64.c | 52 +++++++++++++++++++++++++---------------------------
16
4 files changed, 49 insertions(+), 32 deletions(-)
17
18
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/kvm_arm.h
21
+++ b/target/arm/kvm_arm.h
22
@@ -XXX,XX +XXX,XX @@ int kvm_arm_sync_mpstate_to_qemu(ARMCPU *cpu);
23
24
int kvm_arm_vgic_probe(void);
25
26
-int kvm_arm_pmu_create(CPUState *cs, int irq);
27
+int kvm_arm_pmu_set_irq(CPUState *cs, int irq);
28
+int kvm_arm_pmu_init(CPUState *cs);
29
30
#else
31
32
@@ -XXX,XX +XXX,XX @@ static inline int kvm_arm_vgic_probe(void)
33
return 0;
34
}
35
36
-static inline int kvm_arm_pmu_create(CPUState *cs, int irq)
37
+static inline int kvm_arm_pmu_set_irq(CPUState *cs, int irq)
38
+{
39
+ return 0;
40
+}
41
+
42
+static inline int kvm_arm_pmu_init(CPUState *cs)
43
{
44
return 0;
45
}
46
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/virt.c
49
+++ b/hw/arm/virt.c
50
@@ -XXX,XX +XXX,XX @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
51
52
CPU_FOREACH(cpu) {
53
armcpu = ARM_CPU(cpu);
54
- if (!arm_feature(&armcpu->env, ARM_FEATURE_PMU) ||
55
- (kvm_enabled() && !kvm_arm_pmu_create(cpu, PPI(VIRTUAL_PMU_IRQ)))) {
56
+ if (!arm_feature(&armcpu->env, ARM_FEATURE_PMU)) {
57
return;
58
}
59
+ if (kvm_enabled()) {
60
+ if (!kvm_arm_pmu_set_irq(cpu, PPI(VIRTUAL_PMU_IRQ))) {
61
+ return;
62
+ }
63
+ if (!kvm_arm_pmu_init(cpu)) {
64
+ return;
65
+ }
66
+ }
67
}
68
69
if (vms->gic_version == 2) {
70
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/arm/kvm32.c
73
+++ b/target/arm/kvm32.c
74
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_hw_debug_active(CPUState *cs)
75
return false;
76
}
77
78
-int kvm_arm_pmu_create(CPUState *cs, int irq)
79
+int kvm_arm_pmu_set_irq(CPUState *cs, int irq)
80
+{
81
+ qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
82
+ return 0;
83
+}
84
+
85
+int kvm_arm_pmu_init(CPUState *cs)
86
{
87
qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
88
return 0;
89
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/target/arm/kvm64.c
92
+++ b/target/arm/kvm64.c
93
@@ -XXX,XX +XXX,XX @@ static CPUWatchpoint *find_hw_watchpoint(CPUState *cpu, target_ulong addr)
94
return NULL;
95
}
96
97
-static bool kvm_arm_pmu_support_ctrl(CPUState *cs, struct kvm_device_attr *attr)
98
-{
99
- return kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr) == 0;
100
-}
101
-
102
-int kvm_arm_pmu_create(CPUState *cs, int irq)
103
+static bool kvm_arm_pmu_set_attr(CPUState *cs, struct kvm_device_attr *attr)
104
{
105
int err;
106
107
- struct kvm_device_attr attr = {
108
- .group = KVM_ARM_VCPU_PMU_V3_CTRL,
109
- .addr = (intptr_t)&irq,
110
- .attr = KVM_ARM_VCPU_PMU_V3_IRQ,
111
- .flags = 0,
112
- };
113
-
114
- if (!kvm_arm_pmu_support_ctrl(cs, &attr)) {
115
- return 0;
116
+ err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr);
117
+ if (err != 0) {
118
+ return false;
119
}
120
121
- err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, &attr);
122
+ err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, attr);
123
if (err < 0) {
124
fprintf(stderr, "KVM_SET_DEVICE_ATTR failed: %s\n",
125
strerror(-err));
126
abort();
127
}
128
129
- attr.group = KVM_ARM_VCPU_PMU_V3_CTRL;
130
- attr.attr = KVM_ARM_VCPU_PMU_V3_INIT;
131
- attr.addr = 0;
132
- attr.flags = 0;
133
+ return true;
134
+}
135
136
- err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, &attr);
137
- if (err < 0) {
138
- fprintf(stderr, "KVM_SET_DEVICE_ATTR failed: %s\n",
139
- strerror(-err));
140
- abort();
141
- }
142
+int kvm_arm_pmu_init(CPUState *cs)
143
+{
144
+ struct kvm_device_attr attr = {
145
+ .group = KVM_ARM_VCPU_PMU_V3_CTRL,
146
+ .attr = KVM_ARM_VCPU_PMU_V3_INIT,
147
+ };
148
+
149
+ return kvm_arm_pmu_set_attr(cs, &attr);
150
+}
151
+
152
+int kvm_arm_pmu_set_irq(CPUState *cs, int irq)
153
+{
154
+ struct kvm_device_attr attr = {
155
+ .group = KVM_ARM_VCPU_PMU_V3_CTRL,
156
+ .addr = (intptr_t)&irq,
157
+ .attr = KVM_ARM_VCPU_PMU_V3_IRQ,
158
+ };
159
160
- return 1;
161
+ return kvm_arm_pmu_set_attr(cs, &attr);
162
}
163
164
static inline void set_feature(uint64_t *features, int feature)
165
--
166
2.7.4
167
168
diff view generated by jsdifflib
Deleted patch
1
From: Andrew Jones <drjones@redhat.com>
2
1
3
Move the in-kernel-irqchip test to only guard the set-irq
4
stage, not the init stage of the PMU. Also add the PMU to
5
the KVM device irq line synchronization to enable its use.
6
7
Signed-off-by: Andrew Jones <drjones@redhat.com>
8
Reviewed-by: Christoffer Dall <cdall@linaro.org>
9
Message-id: 1500471597-2517-4-git-send-email-drjones@redhat.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/arm/virt.c | 3 ++-
14
target/arm/kvm.c | 6 +++++-
15
target/arm/kvm64.c | 3 +--
16
3 files changed, 8 insertions(+), 4 deletions(-)
17
18
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/virt.c
21
+++ b/hw/arm/virt.c
22
@@ -XXX,XX +XXX,XX @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
23
return;
24
}
25
if (kvm_enabled()) {
26
- if (!kvm_arm_pmu_set_irq(cpu, PPI(VIRTUAL_PMU_IRQ))) {
27
+ if (kvm_irqchip_in_kernel() &&
28
+ !kvm_arm_pmu_set_irq(cpu, PPI(VIRTUAL_PMU_IRQ))) {
29
return;
30
}
31
if (!kvm_arm_pmu_init(cpu)) {
32
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/kvm.c
35
+++ b/target/arm/kvm.c
36
@@ -XXX,XX +XXX,XX @@ MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
37
switched_level &= ~KVM_ARM_DEV_EL1_PTIMER;
38
}
39
40
- /* XXX PMU IRQ is missing */
41
+ if (switched_level & KVM_ARM_DEV_PMU) {
42
+ qemu_set_irq(cpu->pmu_interrupt,
43
+ !!(run->s.regs.device_irq_level & KVM_ARM_DEV_PMU));
44
+ switched_level &= ~KVM_ARM_DEV_PMU;
45
+ }
46
47
if (switched_level) {
48
qemu_log_mask(LOG_UNIMP, "%s: unhandled in-kernel device IRQ %x\n",
49
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/kvm64.c
52
+++ b/target/arm/kvm64.c
53
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
54
if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
55
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_EL1_32BIT;
56
}
57
- if (!kvm_irqchip_in_kernel() ||
58
- !kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PMU_V3)) {
59
+ if (!kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PMU_V3)) {
60
cpu->has_pmu = false;
61
}
62
if (cpu->has_pmu) {
63
--
64
2.7.4
65
66
diff view generated by jsdifflib
1
We currently have some similar code in tlb_fill() and in
1
I'm down as the only listed maintainer for quite a lot of Arm SoC and
2
arm_cpu_do_unaligned_access() for delivering a data abort or prefetch
2
board types. In some cases this is only as the "maintainer of last
3
abort. We're also going to want to do the same thing to handle
3
resort" and I'm not in practice doing anything beyond patch review
4
external aborts. Factor out the common code into a new function
4
and the odd bit of tidyup.
5
deliver_fault().
5
6
Move these entries in MAINTAINERS from "Maintained" to "Odd Fixes",
7
to better represent reality. Entries for other boards and SoCs where
8
I do more actively care (or where there is a listed co-maintainer)
9
remain as they are.
6
10
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Acked-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
13
Message-id: 20250307152838.3226398-1-peter.maydell@linaro.org
10
---
14
---
11
target/arm/op_helper.c | 110 +++++++++++++++++++++++++------------------------
15
MAINTAINERS | 14 +++++++-------
12
1 file changed, 57 insertions(+), 53 deletions(-)
16
1 file changed, 7 insertions(+), 7 deletions(-)
13
17
14
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
18
diff --git a/MAINTAINERS b/MAINTAINERS
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/op_helper.c
20
--- a/MAINTAINERS
17
+++ b/target/arm/op_helper.c
21
+++ b/MAINTAINERS
18
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
22
@@ -XXX,XX +XXX,XX @@ F: docs/system/arm/kzm.rst
19
return syn;
23
Integrator CP
20
}
24
M: Peter Maydell <peter.maydell@linaro.org>
21
25
L: qemu-arm@nongnu.org
22
+static void deliver_fault(ARMCPU *cpu, vaddr addr, MMUAccessType access_type,
26
-S: Maintained
23
+ uint32_t fsr, uint32_t fsc, ARMMMUFaultInfo *fi)
27
+S: Odd Fixes
24
+{
28
F: hw/arm/integratorcp.c
25
+ CPUARMState *env = &cpu->env;
29
F: hw/misc/arm_integrator_debug.c
26
+ int target_el;
30
F: include/hw/misc/arm_integrator_debug.h
27
+ bool same_el;
31
@@ -XXX,XX +XXX,XX @@ F: docs/system/arm/mps2.rst
28
+ uint32_t syn, exc;
32
Musca
29
+
33
M: Peter Maydell <peter.maydell@linaro.org>
30
+ target_el = exception_target_el(env);
34
L: qemu-arm@nongnu.org
31
+ if (fi->stage2) {
35
-S: Maintained
32
+ target_el = 2;
36
+S: Odd Fixes
33
+ env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
37
F: hw/arm/musca.c
34
+ }
38
F: docs/system/arm/musca.rst
35
+ same_el = (arm_current_el(env) == target_el);
39
36
+
40
@@ -XXX,XX +XXX,XX @@ F: tests/functional/test_aarch64_raspi4.py
37
+ if (fsc == 0x3f) {
41
Real View
38
+ /* Caller doesn't have a long-format fault status code. This
42
M: Peter Maydell <peter.maydell@linaro.org>
39
+ * should only happen if this fault will never actually be reported
43
L: qemu-arm@nongnu.org
40
+ * to an EL that uses a syndrome register. Check that here.
44
-S: Maintained
41
+ * 0x3f is a (currently) reserved FSC code, in case the constructed
45
+S: Odd Fixes
42
+ * syndrome does leak into the guest somehow.
46
F: hw/arm/realview*
43
+ */
47
F: hw/cpu/realview_mpcore.c
44
+ assert(target_el != 2 && !arm_el_is_aa64(env, target_el));
48
F: hw/intc/realview_gic.c
45
+ }
49
@@ -XXX,XX +XXX,XX @@ F: tests/functional/test_arm_collie.py
46
+
50
Stellaris
47
+ if (access_type == MMU_INST_FETCH) {
51
M: Peter Maydell <peter.maydell@linaro.org>
48
+ syn = syn_insn_abort(same_el, 0, fi->s1ptw, fsc);
52
L: qemu-arm@nongnu.org
49
+ exc = EXCP_PREFETCH_ABORT;
53
-S: Maintained
50
+ } else {
54
+S: Odd Fixes
51
+ syn = merge_syn_data_abort(env->exception.syndrome, target_el,
55
F: hw/*/stellaris*
52
+ same_el, fi->s1ptw,
56
F: hw/display/ssd03*
53
+ access_type == MMU_DATA_STORE,
57
F: include/hw/input/gamepad.h
54
+ fsc);
58
@@ -XXX,XX +XXX,XX @@ F: docs/system/arm/stm32.rst
55
+ if (access_type == MMU_DATA_STORE
59
Versatile Express
56
+ && arm_feature(env, ARM_FEATURE_V6)) {
60
M: Peter Maydell <peter.maydell@linaro.org>
57
+ fsr |= (1 << 11);
61
L: qemu-arm@nongnu.org
58
+ }
62
-S: Maintained
59
+ exc = EXCP_DATA_ABORT;
63
+S: Odd Fixes
60
+ }
64
F: hw/arm/vexpress.c
61
+
65
F: hw/display/sii9022.c
62
+ env->exception.vaddress = addr;
66
F: docs/system/arm/vexpress.rst
63
+ env->exception.fsr = fsr;
67
@@ -XXX,XX +XXX,XX @@ F: tests/functional/test_arm_vexpress.py
64
+ raise_exception(env, exc, syn, target_el);
68
Versatile PB
65
+}
69
M: Peter Maydell <peter.maydell@linaro.org>
66
+
70
L: qemu-arm@nongnu.org
67
/* try to fill the TLB and return an exception if error. If retaddr is
71
-S: Maintained
68
* NULL, it means that the function was called in C code (i.e. not
72
+S: Odd Fixes
69
* from generated code or from helper.c)
73
F: hw/*/versatile*
70
@@ -XXX,XX +XXX,XX @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
74
F: hw/i2c/arm_sbcon_i2c.c
71
ret = arm_tlb_fill(cs, addr, access_type, mmu_idx, &fsr, &fi);
75
F: include/hw/i2c/arm_sbcon_i2c.h
72
if (unlikely(ret)) {
76
@@ -XXX,XX +XXX,XX @@ F: include/hw/hyperv/vmbus*.h
73
ARMCPU *cpu = ARM_CPU(cs);
77
OMAP
74
- CPUARMState *env = &cpu->env;
78
M: Peter Maydell <peter.maydell@linaro.org>
75
- uint32_t syn, exc, fsc;
79
L: qemu-arm@nongnu.org
76
- unsigned int target_el;
80
-S: Maintained
77
- bool same_el;
81
+S: Odd Fixes
78
+ uint32_t fsc;
82
F: hw/*/omap*
79
83
F: include/hw/arm/omap.h
80
if (retaddr) {
84
F: docs/system/arm/sx1.rst
81
/* now we have a real cpu fault */
82
cpu_restore_state(cs, retaddr);
83
}
84
85
- target_el = exception_target_el(env);
86
- if (fi.stage2) {
87
- target_el = 2;
88
- env->cp15.hpfar_el2 = extract64(fi.s2addr, 12, 47) << 4;
89
- }
90
- same_el = arm_current_el(env) == target_el;
91
-
92
if (fsr & (1 << 9)) {
93
/* LPAE format fault status register : bottom 6 bits are
94
* status code in the same form as needed for syndrome
95
@@ -XXX,XX +XXX,XX @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
96
fsc = extract32(fsr, 0, 6);
97
} else {
98
/* Short format FSR : this fault will never actually be reported
99
- * to an EL that uses a syndrome register. Check that here,
100
- * and use a (currently) reserved FSR code in case the constructed
101
- * syndrome does leak into the guest somehow.
102
+ * to an EL that uses a syndrome register. Use a (currently)
103
+ * reserved FSR code in case the constructed syndrome does leak
104
+ * into the guest somehow. deliver_fault will assert that
105
+ * we don't target an EL using the syndrome.
106
*/
107
- assert(target_el != 2 && !arm_el_is_aa64(env, target_el));
108
fsc = 0x3f;
109
}
110
111
- /* For insn and data aborts we assume there is no instruction syndrome
112
- * information; this is always true for exceptions reported to EL1.
113
- */
114
- if (access_type == MMU_INST_FETCH) {
115
- syn = syn_insn_abort(same_el, 0, fi.s1ptw, fsc);
116
- exc = EXCP_PREFETCH_ABORT;
117
- } else {
118
- syn = merge_syn_data_abort(env->exception.syndrome, target_el,
119
- same_el, fi.s1ptw,
120
- access_type == MMU_DATA_STORE, fsc);
121
- if (access_type == MMU_DATA_STORE
122
- && arm_feature(env, ARM_FEATURE_V6)) {
123
- fsr |= (1 << 11);
124
- }
125
- exc = EXCP_DATA_ABORT;
126
- }
127
-
128
- env->exception.vaddress = addr;
129
- env->exception.fsr = fsr;
130
- raise_exception(env, exc, syn, target_el);
131
+ deliver_fault(cpu, addr, access_type, fsr, fsc, &fi);
132
}
133
}
134
135
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
136
{
137
ARMCPU *cpu = ARM_CPU(cs);
138
CPUARMState *env = &cpu->env;
139
- int target_el;
140
- bool same_el;
141
- uint32_t syn;
142
+ uint32_t fsr, fsc;
143
+ ARMMMUFaultInfo fi = {};
144
ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
145
146
if (retaddr) {
147
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
148
cpu_restore_state(cs, retaddr);
149
}
150
151
- target_el = exception_target_el(env);
152
- same_el = (arm_current_el(env) == target_el);
153
-
154
- env->exception.vaddress = vaddr;
155
-
156
/* the DFSR for an alignment fault depends on whether we're using
157
* the LPAE long descriptor format, or the short descriptor format
158
*/
159
if (arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
160
- env->exception.fsr = (1 << 9) | 0x21;
161
+ fsr = (1 << 9) | 0x21;
162
} else {
163
- env->exception.fsr = 0x1;
164
- }
165
-
166
- if (access_type == MMU_DATA_STORE && arm_feature(env, ARM_FEATURE_V6)) {
167
- env->exception.fsr |= (1 << 11);
168
+ fsr = 0x1;
169
}
170
+ fsc = 0x21;
171
172
- syn = merge_syn_data_abort(env->exception.syndrome, target_el,
173
- same_el, 0, access_type == MMU_DATA_STORE,
174
- 0x21);
175
- raise_exception(env, EXCP_DATA_ABORT, syn, target_el);
176
+ deliver_fault(cpu, vaddr, access_type, fsr, fsc, &fi);
177
}
178
179
#endif /* !defined(CONFIG_USER_ONLY) */
180
--
85
--
181
2.7.4
86
2.43.0
182
87
183
88
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
QEMU currently shows some unexpected behavior when the user trys to
3
The guest does not control whether characters are sent on the UART.
4
do a "device_add digic" on an unrelated ARM machine like integratorcp
4
Sending them before the guest happens to boot will now result in a
5
in "-nographic" mode (the device_add command does not immediately
5
"guest error" log entry that is only because of timing, even if the
6
return to the monitor prompt), and trying to "device_del" the device
6
guest _would_ later setup the receiver correctly.
7
later results in a "qemu/qdev-monitor.c:872:qdev_unplug: assertion
8
failed: (hotplug_ctrl)" error condition.
9
Looking at the realize function of the device, it uses serial_hds
10
directly and this means that the device can not be added a second
11
time, so let's simply mark it with "user_creatable = false" now.
12
7
13
Signed-off-by: Thomas Huth <thuth@redhat.com>
8
This reverts the bulk of commit abf2b6a028670bd2890bb3aee7e103fe53e4b0df,
9
and instead adds a comment about why we don't check the enable bits.
10
11
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Cc: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
14
Message-id: 20250311153717.206129-1-pbonzini@redhat.com
15
[PMM: expanded comment]
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
18
---
17
hw/arm/digic.c | 2 ++
19
hw/char/pl011.c | 19 ++++++++++---------
18
1 file changed, 2 insertions(+)
20
1 file changed, 10 insertions(+), 9 deletions(-)
19
21
20
diff --git a/hw/arm/digic.c b/hw/arm/digic.c
22
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
21
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/digic.c
24
--- a/hw/char/pl011.c
23
+++ b/hw/arm/digic.c
25
+++ b/hw/char/pl011.c
24
@@ -XXX,XX +XXX,XX @@ static void digic_class_init(ObjectClass *oc, void *data)
26
@@ -XXX,XX +XXX,XX @@ static int pl011_can_receive(void *opaque)
25
DeviceClass *dc = DEVICE_CLASS(oc);
27
unsigned fifo_depth = pl011_get_fifo_depth(s);
26
28
unsigned fifo_available = fifo_depth - s->read_count;
27
dc->realize = digic_realize;
29
28
+ /* Reason: Uses serial_hds in the realize function --> not usable twice */
30
- if (!(s->cr & CR_UARTEN)) {
29
+ dc->user_creatable = false;
31
- qemu_log_mask(LOG_GUEST_ERROR,
32
- "PL011 receiving data on disabled UART\n");
33
- }
34
- if (!(s->cr & CR_RXE)) {
35
- qemu_log_mask(LOG_GUEST_ERROR,
36
- "PL011 receiving data on disabled RX UART\n");
37
- }
38
- trace_pl011_can_receive(s->lcr, s->read_count, fifo_depth, fifo_available);
39
+ /*
40
+ * In theory we should check the UART and RX enable bits here and
41
+ * return 0 if they are not set (so the guest can't receive data
42
+ * until you have enabled the UART). In practice we suspect there
43
+ * is at least some guest code out there which has been tested only
44
+ * on QEMU and which never bothers to enable the UART because we
45
+ * historically never enforced that. So we effectively keep the
46
+ * UART continuously enabled regardless of the enable bits.
47
+ */
48
49
+ trace_pl011_can_receive(s->lcr, s->read_count, fifo_depth, fifo_available);
50
return fifo_available;
30
}
51
}
31
52
32
static const TypeInfo digic_type_info = {
33
--
53
--
34
2.7.4
54
2.43.0
35
55
36
56
diff view generated by jsdifflib
1
From: Andrew Jeffery <andrew@aj.id.au>
1
From: Joe Komlodi <komlodi@google.com>
2
2
3
This is required to configure differences in behaviour between the
3
On ARM hosts with CTR_EL0.DIC and CTR_EL0.IDC set, this would only cause
4
AST2400 and AST2500 watchdog IPs.
4
an ISB to be executed during cache maintenance, which could lead to QEMU
5
executing TBs containing garbage instructions.
5
6
6
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
7
This seems to be because the ISB finishes executing instructions and
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
flushes the pipeline, but the ISB doesn't guarantee that writes from the
9
executed instructions are committed. If a small enough TB is created, it's
10
possible that the writes setting up the TB aren't committed by the time the
11
TB is executed.
12
13
This function is intended to be a port of the gcc implementation
14
(https://github.com/gcc-mirror/gcc/blob/85b46d0795ac76bc192cb8f88b646a647acf98c1/libgcc/config/aarch64/sync-cache.c#L67)
15
which makes the first DSB unconditional, so we can fix the synchronization
16
issue by doing that as well.
17
18
Cc: qemu-stable@nongnu.org
19
Fixes: 664a79735e4deb1 ("util: Specialize flush_idcache_range for aarch64")
20
Signed-off-by: Joe Komlodi <komlodi@google.com>
21
Message-id: 20250310203622.1827940-2-komlodi@google.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
25
---
11
hw/arm/aspeed_soc.c | 2 ++
26
util/cacheflush.c | 4 +++-
12
1 file changed, 2 insertions(+)
27
1 file changed, 3 insertions(+), 1 deletion(-)
13
28
14
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
29
diff --git a/util/cacheflush.c b/util/cacheflush.c
15
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/aspeed_soc.c
31
--- a/util/cacheflush.c
17
+++ b/hw/arm/aspeed_soc.c
32
+++ b/util/cacheflush.c
18
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
33
@@ -XXX,XX +XXX,XX @@ void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len)
19
object_initialize(&s->wdt[i], sizeof(s->wdt[i]), TYPE_ASPEED_WDT);
34
for (p = rw & -dcache_lsize; p < rw + len; p += dcache_lsize) {
20
object_property_add_child(obj, "wdt[*]", OBJECT(&s->wdt[i]), NULL);
35
asm volatile("dc\tcvau, %0" : : "r" (p) : "memory");
21
qdev_set_parent_bus(DEVICE(&s->wdt[i]), sysbus_get_default());
36
}
22
+ qdev_prop_set_uint32(DEVICE(&s->wdt[i]), "silicon-rev",
37
- asm volatile("dsb\tish" : : : "memory");
23
+ sc->info->silicon_rev);
24
}
38
}
25
39
26
object_initialize(&s->ftgmac100, sizeof(s->ftgmac100), TYPE_FTGMAC100);
40
+ /* DSB unconditionally to ensure any outstanding writes are committed. */
41
+ asm volatile("dsb\tish" : : : "memory");
42
+
43
/*
44
* If CTR_EL0.DIC is enabled, Instruction cache cleaning to the Point
45
* of Unification is not required for instruction to data coherence.
27
--
46
--
28
2.7.4
47
2.43.0
29
30
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
If a KVM PMU init or set-irq attr call fails we just silently stop
3
The check for fp_excp_el in assert_fp_access_checked is
4
the PMU DT node generation. The only way they could fail, though,
4
incorrect. For SME, with StreamingMode enabled, the access
5
is if the attr's respective KVM has-attr call fails. But that should
5
is really against the streaming mode vectors, and access
6
never happen if KVM advertises the PMU capability, because both
6
to the normal fp registers is allowed to be disabled.
7
attrs have been available since the capability was introduced. Let's
7
C.f. sme_enabled_check.
8
just abort if this should-never-happen stuff does happen, because,
9
if it does, then something is obviously horribly wrong.
10
8
11
Signed-off-by: Andrew Jones <drjones@redhat.com>
9
Convert sve_access_checked to match, even though we don't
12
Reviewed-by: Christoffer Dall <cdall@linaro.org>
10
currently check the exception state.
13
Message-id: 1500471597-2517-5-git-send-email-drjones@redhat.com
11
12
Cc: qemu-stable@nongnu.org
13
Fixes: 3d74825f4d6 ("target/arm: Add SME enablement checks")
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20250307190415.982049-2-richard.henderson@linaro.org
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
18
---
17
target/arm/kvm_arm.h | 15 ++++-----------
19
target/arm/tcg/translate-a64.h | 2 +-
18
hw/arm/virt.c | 9 +++------
20
target/arm/tcg/translate.h | 10 +++++++---
19
target/arm/kvm32.c | 3 +--
21
target/arm/tcg/translate-a64.c | 17 +++++++++--------
20
target/arm/kvm64.c | 28 ++++++++++++++++++++--------
22
3 files changed, 17 insertions(+), 12 deletions(-)
21
4 files changed, 28 insertions(+), 27 deletions(-)
22
23
23
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
24
diff --git a/target/arm/tcg/translate-a64.h b/target/arm/tcg/translate-a64.h
24
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/kvm_arm.h
26
--- a/target/arm/tcg/translate-a64.h
26
+++ b/target/arm/kvm_arm.h
27
+++ b/target/arm/tcg/translate-a64.h
27
@@ -XXX,XX +XXX,XX @@ int kvm_arm_sync_mpstate_to_qemu(ARMCPU *cpu);
28
@@ -XXX,XX +XXX,XX @@ TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
28
29
static inline void assert_fp_access_checked(DisasContext *s)
29
int kvm_arm_vgic_probe(void);
30
{
30
31
#ifdef CONFIG_DEBUG_TCG
31
-int kvm_arm_pmu_set_irq(CPUState *cs, int irq);
32
- if (unlikely(!s->fp_access_checked || s->fp_excp_el)) {
32
-int kvm_arm_pmu_init(CPUState *cs);
33
+ if (unlikely(s->fp_access_checked <= 0)) {
33
+void kvm_arm_pmu_set_irq(CPUState *cs, int irq);
34
fprintf(stderr, "target-arm: FP access check missing for "
34
+void kvm_arm_pmu_init(CPUState *cs);
35
"instruction 0x%08x\n", s->insn);
35
36
abort();
36
#else
37
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
37
38
index XXXXXXX..XXXXXXX 100644
38
@@ -XXX,XX +XXX,XX @@ static inline int kvm_arm_vgic_probe(void)
39
--- a/target/arm/tcg/translate.h
39
return 0;
40
+++ b/target/arm/tcg/translate.h
41
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
42
bool aarch64;
43
bool thumb;
44
bool lse2;
45
- /* Because unallocated encodings generate different exception syndrome
46
+ /*
47
+ * Because unallocated encodings generate different exception syndrome
48
* information from traps due to FP being disabled, we can't do a single
49
* "is fp access disabled" check at a high level in the decode tree.
50
* To help in catching bugs where the access check was forgotten in some
51
* code path, we set this flag when the access check is done, and assert
52
* that it is set at the point where we actually touch the FP regs.
53
+ * 0: not checked,
54
+ * 1: checked, access ok
55
+ * -1: checked, access denied
56
*/
57
- bool fp_access_checked;
58
- bool sve_access_checked;
59
+ int8_t fp_access_checked;
60
+ int8_t sve_access_checked;
61
/* ARMv8 single-step state (this is distinct from the QEMU gdbstub
62
* single-step support).
63
*/
64
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/tcg/translate-a64.c
67
+++ b/target/arm/tcg/translate-a64.c
68
@@ -XXX,XX +XXX,XX @@ static bool fp_access_check_only(DisasContext *s)
69
{
70
if (s->fp_excp_el) {
71
assert(!s->fp_access_checked);
72
- s->fp_access_checked = true;
73
+ s->fp_access_checked = -1;
74
75
gen_exception_insn_el(s, 0, EXCP_UDEF,
76
syn_fp_access_trap(1, 0xe, false, 0),
77
s->fp_excp_el);
78
return false;
79
}
80
- s->fp_access_checked = true;
81
+ s->fp_access_checked = 1;
82
return true;
40
}
83
}
41
84
42
-static inline int kvm_arm_pmu_set_irq(CPUState *cs, int irq)
85
@@ -XXX,XX +XXX,XX @@ bool sve_access_check(DisasContext *s)
43
-{
86
syn_sve_access_trap(), s->sve_excp_el);
44
- return 0;
87
goto fail_exit;
45
-}
46
-
47
-static inline int kvm_arm_pmu_init(CPUState *cs)
48
-{
49
- return 0;
50
-}
51
+static inline void kvm_arm_pmu_set_irq(CPUState *cs, int irq) {}
52
+static inline void kvm_arm_pmu_init(CPUState *cs) {}
53
54
#endif
55
56
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/arm/virt.c
59
+++ b/hw/arm/virt.c
60
@@ -XXX,XX +XXX,XX @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
61
return;
62
}
63
if (kvm_enabled()) {
64
- if (kvm_irqchip_in_kernel() &&
65
- !kvm_arm_pmu_set_irq(cpu, PPI(VIRTUAL_PMU_IRQ))) {
66
- return;
67
- }
68
- if (!kvm_arm_pmu_init(cpu)) {
69
- return;
70
+ if (kvm_irqchip_in_kernel()) {
71
+ kvm_arm_pmu_set_irq(cpu, PPI(VIRTUAL_PMU_IRQ));
72
}
73
+ kvm_arm_pmu_init(cpu);
74
}
75
}
88
}
76
89
- s->sve_access_checked = true;
77
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
90
+ s->sve_access_checked = 1;
78
index XXXXXXX..XXXXXXX 100644
91
return fp_access_check(s);
79
--- a/target/arm/kvm32.c
92
80
+++ b/target/arm/kvm32.c
93
fail_exit:
81
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_hw_debug_active(CPUState *cs)
94
/* Assert that we only raise one exception per instruction. */
95
assert(!s->sve_access_checked);
96
- s->sve_access_checked = true;
97
+ s->sve_access_checked = -1;
82
return false;
98
return false;
83
}
99
}
84
100
85
-int kvm_arm_pmu_set_irq(CPUState *cs, int irq)
101
@@ -XXX,XX +XXX,XX @@ bool sme_enabled_check(DisasContext *s)
86
+void kvm_arm_pmu_set_irq(CPUState *cs, int irq)
102
* sme_excp_el by itself for cpregs access checks.
87
{
103
*/
88
qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
104
if (!s->fp_excp_el || s->sme_excp_el < s->fp_excp_el) {
89
- return 0;
105
- s->fp_access_checked = true;
106
- return sme_access_check(s);
107
+ bool ret = sme_access_check(s);
108
+ s->fp_access_checked = (ret ? 1 : -1);
109
+ return ret;
110
}
111
return fp_access_check_only(s);
90
}
112
}
91
113
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
92
int kvm_arm_pmu_init(CPUState *cs)
114
s->insn = insn;
93
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
115
s->base.pc_next = pc + 4;
94
index XXXXXXX..XXXXXXX 100644
116
95
--- a/target/arm/kvm64.c
117
- s->fp_access_checked = false;
96
+++ b/target/arm/kvm64.c
118
- s->sve_access_checked = false;
97
@@ -XXX,XX +XXX,XX @@ static bool kvm_arm_pmu_set_attr(CPUState *cs, struct kvm_device_attr *attr)
119
+ s->fp_access_checked = 0;
98
120
+ s->sve_access_checked = 0;
99
err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr);
121
100
if (err != 0) {
122
if (s->pstate_il) {
101
+ error_report("PMU: KVM_HAS_DEVICE_ATTR: %s", strerror(-err));
123
/*
102
return false;
103
}
104
105
err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, attr);
106
- if (err < 0) {
107
- fprintf(stderr, "KVM_SET_DEVICE_ATTR failed: %s\n",
108
- strerror(-err));
109
- abort();
110
+ if (err != 0) {
111
+ error_report("PMU: KVM_SET_DEVICE_ATTR: %s", strerror(-err));
112
+ return false;
113
}
114
115
return true;
116
}
117
118
-int kvm_arm_pmu_init(CPUState *cs)
119
+void kvm_arm_pmu_init(CPUState *cs)
120
{
121
struct kvm_device_attr attr = {
122
.group = KVM_ARM_VCPU_PMU_V3_CTRL,
123
.attr = KVM_ARM_VCPU_PMU_V3_INIT,
124
};
125
126
- return kvm_arm_pmu_set_attr(cs, &attr);
127
+ if (!ARM_CPU(cs)->has_pmu) {
128
+ return;
129
+ }
130
+ if (!kvm_arm_pmu_set_attr(cs, &attr)) {
131
+ error_report("failed to init PMU");
132
+ abort();
133
+ }
134
}
135
136
-int kvm_arm_pmu_set_irq(CPUState *cs, int irq)
137
+void kvm_arm_pmu_set_irq(CPUState *cs, int irq)
138
{
139
struct kvm_device_attr attr = {
140
.group = KVM_ARM_VCPU_PMU_V3_CTRL,
141
@@ -XXX,XX +XXX,XX @@ int kvm_arm_pmu_set_irq(CPUState *cs, int irq)
142
.attr = KVM_ARM_VCPU_PMU_V3_IRQ,
143
};
144
145
- return kvm_arm_pmu_set_attr(cs, &attr);
146
+ if (!ARM_CPU(cs)->has_pmu) {
147
+ return;
148
+ }
149
+ if (!kvm_arm_pmu_set_attr(cs, &attr)) {
150
+ error_report("failed to set irq for PMU");
151
+ abort();
152
+ }
153
}
154
155
static inline void set_feature(uint64_t *features, int feature)
156
--
124
--
157
2.7.4
125
2.43.0
158
159
diff view generated by jsdifflib
Deleted patch
1
From: Andrew Jeffery <andrew@aj.id.au>
2
1
3
The reset width register controls how the pulse on the SoC's WDTRST{1,2}
4
pins behaves. A pulse is emitted if the external reset bit is set in
5
WDT_CTRL. On the AST2500 WDT_RESET_WIDTH can consume magic bit patterns
6
to configure push-pull/open-drain and active-high/active-low
7
behaviours and thus needs some special handling in the write path.
8
9
As some of the capabilities depend on the SoC version a silicon-rev
10
property is introduced, which is used to guard version-specific
11
behaviour.
12
13
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
14
Reviewed-by: Cédric Le Goater <clg@kaod.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
include/hw/watchdog/wdt_aspeed.h | 2 +
18
hw/watchdog/wdt_aspeed.c | 93 +++++++++++++++++++++++++++++++++++-----
19
2 files changed, 84 insertions(+), 11 deletions(-)
20
21
diff --git a/include/hw/watchdog/wdt_aspeed.h b/include/hw/watchdog/wdt_aspeed.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/watchdog/wdt_aspeed.h
24
+++ b/include/hw/watchdog/wdt_aspeed.h
25
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedWDTState {
26
uint32_t regs[ASPEED_WDT_REGS_MAX];
27
28
uint32_t pclk_freq;
29
+ uint32_t silicon_rev;
30
+ uint32_t ext_pulse_width_mask;
31
} AspeedWDTState;
32
33
#endif /* ASPEED_WDT_H */
34
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/watchdog/wdt_aspeed.c
37
+++ b/hw/watchdog/wdt_aspeed.c
38
@@ -XXX,XX +XXX,XX @@
39
*/
40
41
#include "qemu/osdep.h"
42
+
43
+#include "qapi/error.h"
44
#include "qemu/log.h"
45
+#include "qemu/timer.h"
46
#include "sysemu/watchdog.h"
47
+#include "hw/misc/aspeed_scu.h"
48
#include "hw/sysbus.h"
49
-#include "qemu/timer.h"
50
#include "hw/watchdog/wdt_aspeed.h"
51
52
-#define WDT_STATUS (0x00 / 4)
53
-#define WDT_RELOAD_VALUE (0x04 / 4)
54
-#define WDT_RESTART (0x08 / 4)
55
-#define WDT_CTRL (0x0C / 4)
56
+#define WDT_STATUS (0x00 / 4)
57
+#define WDT_RELOAD_VALUE (0x04 / 4)
58
+#define WDT_RESTART (0x08 / 4)
59
+#define WDT_CTRL (0x0C / 4)
60
#define WDT_CTRL_RESET_MODE_SOC (0x00 << 5)
61
#define WDT_CTRL_RESET_MODE_FULL_CHIP (0x01 << 5)
62
#define WDT_CTRL_1MHZ_CLK BIT(4)
63
@@ -XXX,XX +XXX,XX @@
64
#define WDT_CTRL_WDT_INTR BIT(2)
65
#define WDT_CTRL_RESET_SYSTEM BIT(1)
66
#define WDT_CTRL_ENABLE BIT(0)
67
+#define WDT_RESET_WIDTH (0x18 / 4)
68
+#define WDT_RESET_WIDTH_ACTIVE_HIGH BIT(31)
69
+#define WDT_POLARITY_MASK (0xFF << 24)
70
+#define WDT_ACTIVE_HIGH_MAGIC (0xA5 << 24)
71
+#define WDT_ACTIVE_LOW_MAGIC (0x5A << 24)
72
+#define WDT_RESET_WIDTH_PUSH_PULL BIT(30)
73
+#define WDT_DRIVE_TYPE_MASK (0xFF << 24)
74
+#define WDT_PUSH_PULL_MAGIC (0xA8 << 24)
75
+#define WDT_OPEN_DRAIN_MAGIC (0x8A << 24)
76
77
-#define WDT_TIMEOUT_STATUS (0x10 / 4)
78
-#define WDT_TIMEOUT_CLEAR (0x14 / 4)
79
-#define WDT_RESET_WDITH (0x18 / 4)
80
+#define WDT_TIMEOUT_STATUS (0x10 / 4)
81
+#define WDT_TIMEOUT_CLEAR (0x14 / 4)
82
83
-#define WDT_RESTART_MAGIC 0x4755
84
+#define WDT_RESTART_MAGIC 0x4755
85
86
static bool aspeed_wdt_is_enabled(const AspeedWDTState *s)
87
{
88
return s->regs[WDT_CTRL] & WDT_CTRL_ENABLE;
89
}
90
91
+static bool is_ast2500(const AspeedWDTState *s)
92
+{
93
+ switch (s->silicon_rev) {
94
+ case AST2500_A0_SILICON_REV:
95
+ case AST2500_A1_SILICON_REV:
96
+ return true;
97
+ case AST2400_A0_SILICON_REV:
98
+ case AST2400_A1_SILICON_REV:
99
+ default:
100
+ break;
101
+ }
102
+
103
+ return false;
104
+}
105
+
106
static uint64_t aspeed_wdt_read(void *opaque, hwaddr offset, unsigned size)
107
{
108
AspeedWDTState *s = ASPEED_WDT(opaque);
109
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_wdt_read(void *opaque, hwaddr offset, unsigned size)
110
return 0;
111
case WDT_CTRL:
112
return s->regs[WDT_CTRL];
113
+ case WDT_RESET_WIDTH:
114
+ return s->regs[WDT_RESET_WIDTH];
115
case WDT_TIMEOUT_STATUS:
116
case WDT_TIMEOUT_CLEAR:
117
- case WDT_RESET_WDITH:
118
qemu_log_mask(LOG_UNIMP,
119
"%s: uninmplemented read at offset 0x%" HWADDR_PRIx "\n",
120
__func__, offset);
121
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
122
timer_del(s->timer);
123
}
124
break;
125
+ case WDT_RESET_WIDTH:
126
+ {
127
+ uint32_t property = data & WDT_POLARITY_MASK;
128
+
129
+ if (property && is_ast2500(s)) {
130
+ if (property == WDT_ACTIVE_HIGH_MAGIC) {
131
+ s->regs[WDT_RESET_WIDTH] |= WDT_RESET_WIDTH_ACTIVE_HIGH;
132
+ } else if (property == WDT_ACTIVE_LOW_MAGIC) {
133
+ s->regs[WDT_RESET_WIDTH] &= ~WDT_RESET_WIDTH_ACTIVE_HIGH;
134
+ } else if (property == WDT_PUSH_PULL_MAGIC) {
135
+ s->regs[WDT_RESET_WIDTH] |= WDT_RESET_WIDTH_PUSH_PULL;
136
+ } else if (property == WDT_OPEN_DRAIN_MAGIC) {
137
+ s->regs[WDT_RESET_WIDTH] &= ~WDT_RESET_WIDTH_PUSH_PULL;
138
+ }
139
+ }
140
+ s->regs[WDT_RESET_WIDTH] &= ~s->ext_pulse_width_mask;
141
+ s->regs[WDT_RESET_WIDTH] |= data & s->ext_pulse_width_mask;
142
+ break;
143
+ }
144
case WDT_TIMEOUT_STATUS:
145
case WDT_TIMEOUT_CLEAR:
146
- case WDT_RESET_WDITH:
147
qemu_log_mask(LOG_UNIMP,
148
"%s: uninmplemented write at offset 0x%" HWADDR_PRIx "\n",
149
__func__, offset);
150
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_reset(DeviceState *dev)
151
s->regs[WDT_RELOAD_VALUE] = 0x03EF1480;
152
s->regs[WDT_RESTART] = 0;
153
s->regs[WDT_CTRL] = 0;
154
+ s->regs[WDT_RESET_WIDTH] = 0xFF;
155
156
timer_del(s->timer);
157
}
158
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_realize(DeviceState *dev, Error **errp)
159
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
160
AspeedWDTState *s = ASPEED_WDT(dev);
161
162
+ if (!is_supported_silicon_rev(s->silicon_rev)) {
163
+ error_setg(errp, "Unknown silicon revision: 0x%" PRIx32,
164
+ s->silicon_rev);
165
+ return;
166
+ }
167
+
168
+ switch (s->silicon_rev) {
169
+ case AST2400_A0_SILICON_REV:
170
+ case AST2400_A1_SILICON_REV:
171
+ s->ext_pulse_width_mask = 0xff;
172
+ break;
173
+ case AST2500_A0_SILICON_REV:
174
+ case AST2500_A1_SILICON_REV:
175
+ s->ext_pulse_width_mask = 0xfffff;
176
+ break;
177
+ default:
178
+ g_assert_not_reached();
179
+ }
180
+
181
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, aspeed_wdt_timer_expired, dev);
182
183
/* FIXME: This setting should be derived from the SCU hw strapping
184
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_realize(DeviceState *dev, Error **errp)
185
sysbus_init_mmio(sbd, &s->iomem);
186
}
187
188
+static Property aspeed_wdt_properties[] = {
189
+ DEFINE_PROP_UINT32("silicon-rev", AspeedWDTState, silicon_rev, 0),
190
+ DEFINE_PROP_END_OF_LIST(),
191
+};
192
+
193
static void aspeed_wdt_class_init(ObjectClass *klass, void *data)
194
{
195
DeviceClass *dc = DEVICE_CLASS(klass);
196
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_class_init(ObjectClass *klass, void *data)
197
dc->reset = aspeed_wdt_reset;
198
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
199
dc->vmsd = &vmstate_aspeed_wdt;
200
+ dc->props = aspeed_wdt_properties;
201
}
202
203
static const TypeInfo aspeed_wdt_info = {
204
--
205
2.7.4
206
207
diff view generated by jsdifflib
Deleted patch
1
Move the MemTxResult type to memattrs.h. We're going to want to
2
use it in cpu/qom.h, which doesn't want to include all of
3
memory.h. In practice MemTxResult and MemTxAttrs are pretty
4
closely linked since both are used for the new-style
5
read_with_attrs and write_with_attrs callbacks, so memattrs.h
6
is a reasonable home for this rather than creating a whole
7
new header file for it.
8
1
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
13
---
14
include/exec/memattrs.h | 10 ++++++++++
15
include/exec/memory.h | 10 ----------
16
2 files changed, 10 insertions(+), 10 deletions(-)
17
18
diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/exec/memattrs.h
21
+++ b/include/exec/memattrs.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct MemTxAttrs {
23
*/
24
#define MEMTXATTRS_UNSPECIFIED ((MemTxAttrs) { .unspecified = 1 })
25
26
+/* New-style MMIO accessors can indicate that the transaction failed.
27
+ * A zero (MEMTX_OK) response means success; anything else is a failure
28
+ * of some kind. The memory subsystem will bitwise-OR together results
29
+ * if it is synthesizing an operation from multiple smaller accesses.
30
+ */
31
+#define MEMTX_OK 0
32
+#define MEMTX_ERROR (1U << 0) /* device returned an error */
33
+#define MEMTX_DECODE_ERROR (1U << 1) /* nothing at that address */
34
+typedef uint32_t MemTxResult;
35
+
36
#endif
37
diff --git a/include/exec/memory.h b/include/exec/memory.h
38
index XXXXXXX..XXXXXXX 100644
39
--- a/include/exec/memory.h
40
+++ b/include/exec/memory.h
41
@@ -XXX,XX +XXX,XX @@ static inline void iommu_notifier_init(IOMMUNotifier *n, IOMMUNotify fn,
42
n->end = end;
43
}
44
45
-/* New-style MMIO accessors can indicate that the transaction failed.
46
- * A zero (MEMTX_OK) response means success; anything else is a failure
47
- * of some kind. The memory subsystem will bitwise-OR together results
48
- * if it is synthesizing an operation from multiple smaller accesses.
49
- */
50
-#define MEMTX_OK 0
51
-#define MEMTX_ERROR (1U << 0) /* device returned an error */
52
-#define MEMTX_DECODE_ERROR (1U << 1) /* nothing at that address */
53
-typedef uint32_t MemTxResult;
54
-
55
/*
56
* Memory region callbacks
57
*/
58
--
59
2.7.4
60
61
diff view generated by jsdifflib
Deleted patch
1
Call the new cpu_transaction_failed() hook at the places where
2
CPU generated code interacts with the memory system:
3
io_readx()
4
io_writex()
5
get_page_addr_code()
6
1
7
Any access from C code (eg via cpu_physical_memory_rw(),
8
address_space_rw(), ld/st_*_phys()) will *not* trigger CPU exceptions
9
via cpu_transaction_failed(). Handling for transactions failures for
10
this kind of call should be done by using a function which returns a
11
MemTxResult and treating the failure case appropriately in the
12
calling code.
13
14
In an ideal world we would not generate CPU exceptions for
15
instruction fetch failures in get_page_addr_code() but instead wait
16
until the code translation process tried a load and it failed;
17
however that change would require too great a restructuring and
18
redesign to attempt at this point.
19
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
22
---
23
softmmu_template.h | 4 ++--
24
accel/tcg/cputlb.c | 32 ++++++++++++++++++++++++++++++--
25
2 files changed, 32 insertions(+), 4 deletions(-)
26
27
diff --git a/softmmu_template.h b/softmmu_template.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/softmmu_template.h
30
+++ b/softmmu_template.h
31
@@ -XXX,XX +XXX,XX @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
32
uintptr_t retaddr)
33
{
34
CPUIOTLBEntry *iotlbentry = &env->iotlb[mmu_idx][index];
35
- return io_readx(env, iotlbentry, addr, retaddr, DATA_SIZE);
36
+ return io_readx(env, iotlbentry, mmu_idx, addr, retaddr, DATA_SIZE);
37
}
38
#endif
39
40
@@ -XXX,XX +XXX,XX @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env,
41
uintptr_t retaddr)
42
{
43
CPUIOTLBEntry *iotlbentry = &env->iotlb[mmu_idx][index];
44
- return io_writex(env, iotlbentry, val, addr, retaddr, DATA_SIZE);
45
+ return io_writex(env, iotlbentry, mmu_idx, val, addr, retaddr, DATA_SIZE);
46
}
47
48
void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
49
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/accel/tcg/cputlb.c
52
+++ b/accel/tcg/cputlb.c
53
@@ -XXX,XX +XXX,XX @@ static inline ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
54
}
55
56
static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
57
+ int mmu_idx,
58
target_ulong addr, uintptr_t retaddr, int size)
59
{
60
CPUState *cpu = ENV_GET_CPU(env);
61
@@ -XXX,XX +XXX,XX @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
62
MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs);
63
uint64_t val;
64
bool locked = false;
65
+ MemTxResult r;
66
67
physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
68
cpu->mem_io_pc = retaddr;
69
@@ -XXX,XX +XXX,XX @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
70
qemu_mutex_lock_iothread();
71
locked = true;
72
}
73
- memory_region_dispatch_read(mr, physaddr, &val, size, iotlbentry->attrs);
74
+ r = memory_region_dispatch_read(mr, physaddr,
75
+ &val, size, iotlbentry->attrs);
76
+ if (r != MEMTX_OK) {
77
+ cpu_transaction_failed(cpu, physaddr, addr, size, MMU_DATA_LOAD,
78
+ mmu_idx, iotlbentry->attrs, r, retaddr);
79
+ }
80
if (locked) {
81
qemu_mutex_unlock_iothread();
82
}
83
@@ -XXX,XX +XXX,XX @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
84
}
85
86
static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
87
+ int mmu_idx,
88
uint64_t val, target_ulong addr,
89
uintptr_t retaddr, int size)
90
{
91
@@ -XXX,XX +XXX,XX @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
92
hwaddr physaddr = iotlbentry->addr;
93
MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs);
94
bool locked = false;
95
+ MemTxResult r;
96
97
physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
98
if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu->can_do_io) {
99
@@ -XXX,XX +XXX,XX @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
100
qemu_mutex_lock_iothread();
101
locked = true;
102
}
103
- memory_region_dispatch_write(mr, physaddr, val, size, iotlbentry->attrs);
104
+ r = memory_region_dispatch_write(mr, physaddr,
105
+ val, size, iotlbentry->attrs);
106
+ if (r != MEMTX_OK) {
107
+ cpu_transaction_failed(cpu, physaddr, addr, size, MMU_DATA_STORE,
108
+ mmu_idx, iotlbentry->attrs, r, retaddr);
109
+ }
110
if (locked) {
111
qemu_mutex_unlock_iothread();
112
}
113
@@ -XXX,XX +XXX,XX @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
114
MemoryRegion *mr;
115
CPUState *cpu = ENV_GET_CPU(env);
116
CPUIOTLBEntry *iotlbentry;
117
+ hwaddr physaddr;
118
119
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
120
mmu_idx = cpu_mmu_index(env, true);
121
@@ -XXX,XX +XXX,XX @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
122
}
123
qemu_mutex_unlock_iothread();
124
125
+ /* Give the new-style cpu_transaction_failed() hook first chance
126
+ * to handle this.
127
+ * This is not the ideal place to detect and generate CPU
128
+ * exceptions for instruction fetch failure (for instance
129
+ * we don't know the length of the access that the CPU would
130
+ * use, and it would be better to go ahead and try the access
131
+ * and use the MemTXResult it produced). However it is the
132
+ * simplest place we have currently available for the check.
133
+ */
134
+ physaddr = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
135
+ cpu_transaction_failed(cpu, physaddr, addr, 0, MMU_INST_FETCH, mmu_idx,
136
+ iotlbentry->attrs, MEMTX_DECODE_ERROR, 0);
137
+
138
cpu_unassigned_access(cpu, addr, false, true, 0, 4);
139
/* The CPU's unassigned access hook might have longjumped out
140
* with an exception. If it didn't (or there was no hook) then
141
--
142
2.7.4
143
144
diff view generated by jsdifflib
Deleted patch
1
Define a new MachineClass field ignore_memory_transaction_failures.
2
If this is flag is true then the CPU will ignore memory transaction
3
failures which should cause the CPU to take an exception due to an
4
access to an unassigned physical address; the transaction will
5
instead return zero (for a read) or be ignored (for a write). This
6
should be set only by legacy board models which rely on the old
7
RAZ/WI behaviour for handling devices that QEMU does not yet model.
8
New board models should instead use "unimplemented-device" for all
9
memory ranges where the guest will attempt to probe for a device that
10
QEMU doesn't implement and a stub device is required.
11
1
12
We need this for ARM boards, where we're about to implement support for
13
generating external aborts on memory transaction failures. Too many
14
of our legacy board models rely on the RAZ/WI behaviour and we
15
would break currently working guests when their "probe for device"
16
code provoked an external abort rather than a RAZ.
17
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
20
include/hw/boards.h | 11 +++++++++++
21
include/qom/cpu.h | 7 ++++++-
22
qom/cpu.c | 7 +++++++
23
3 files changed, 24 insertions(+), 1 deletion(-)
24
25
diff --git a/include/hw/boards.h b/include/hw/boards.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/boards.h
28
+++ b/include/hw/boards.h
29
@@ -XXX,XX +XXX,XX @@ typedef struct {
30
* size than the target architecture's minimum. (Attempting to create
31
* such a CPU will fail.) Note that changing this is a migration
32
* compatibility break for the machine.
33
+ * @ignore_memory_transaction_failures:
34
+ * If this is flag is true then the CPU will ignore memory transaction
35
+ * failures which should cause the CPU to take an exception due to an
36
+ * access to an unassigned physical address; the transaction will instead
37
+ * return zero (for a read) or be ignored (for a write). This should be
38
+ * set only by legacy board models which rely on the old RAZ/WI behaviour
39
+ * for handling devices that QEMU does not yet model. New board models
40
+ * should instead use "unimplemented-device" for all memory ranges where
41
+ * the guest will attempt to probe for a device that QEMU doesn't
42
+ * implement and a stub device is required.
43
*/
44
struct MachineClass {
45
/*< private >*/
46
@@ -XXX,XX +XXX,XX @@ struct MachineClass {
47
bool rom_file_has_mr;
48
int minimum_page_bits;
49
bool has_hotpluggable_cpus;
50
+ bool ignore_memory_transaction_failures;
51
int numa_mem_align_shift;
52
void (*numa_auto_assign_ram)(MachineClass *mc, NodeInfo *nodes,
53
int nb_nodes, ram_addr_t size);
54
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
55
index XXXXXXX..XXXXXXX 100644
56
--- a/include/qom/cpu.h
57
+++ b/include/qom/cpu.h
58
@@ -XXX,XX +XXX,XX @@ struct qemu_work_item;
59
* @trace_dstate_delayed: Delayed changes to trace_dstate (includes all changes
60
* to @trace_dstate).
61
* @trace_dstate: Dynamic tracing state of events for this vCPU (bitmask).
62
+ * @ignore_memory_transaction_failures: Cached copy of the MachineState
63
+ * flag of the same name: allows the board to suppress calling of the
64
+ * CPU do_transaction_failed hook function.
65
*
66
* State of one CPU core or thread.
67
*/
68
@@ -XXX,XX +XXX,XX @@ struct CPUState {
69
*/
70
bool throttle_thread_scheduled;
71
72
+ bool ignore_memory_transaction_failures;
73
+
74
/* Note that this is accessed at the start of every TB via a negative
75
offset from AREG0. Leave this field at the end so as to make the
76
(absolute value) offset as small as possible. This reduces code
77
@@ -XXX,XX +XXX,XX @@ static inline void cpu_transaction_failed(CPUState *cpu, hwaddr physaddr,
78
{
79
CPUClass *cc = CPU_GET_CLASS(cpu);
80
81
- if (cc->do_transaction_failed) {
82
+ if (!cpu->ignore_memory_transaction_failures && cc->do_transaction_failed) {
83
cc->do_transaction_failed(cpu, physaddr, addr, size, access_type,
84
mmu_idx, attrs, response, retaddr);
85
}
86
diff --git a/qom/cpu.c b/qom/cpu.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/qom/cpu.c
89
+++ b/qom/cpu.c
90
@@ -XXX,XX +XXX,XX @@
91
#include "exec/cpu-common.h"
92
#include "qemu/error-report.h"
93
#include "sysemu/sysemu.h"
94
+#include "hw/boards.h"
95
#include "hw/qdev-properties.h"
96
#include "trace-root.h"
97
98
@@ -XXX,XX +XXX,XX @@ static void cpu_common_parse_features(const char *typename, char *features,
99
static void cpu_common_realizefn(DeviceState *dev, Error **errp)
100
{
101
CPUState *cpu = CPU(dev);
102
+ Object *machine = qdev_get_machine();
103
+ ObjectClass *oc = object_get_class(machine);
104
+ MachineClass *mc = MACHINE_CLASS(oc);
105
+
106
+ cpu->ignore_memory_transaction_failures =
107
+ mc->ignore_memory_transaction_failures;
108
109
if (dev->hotplugged) {
110
cpu_synchronize_post_init(cpu);
111
--
112
2.7.4
113
114
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
For "ldp x0, x1, [x0]", if the second load is on a second page and
3
In StreamingMode, fp_access_checked is handled already.
4
the second page is unmapped, the exception would be raised with x0
4
We cannot fall through to fp_access_check lest we fall
5
already modified. This means the instruction couldn't be restarted.
5
foul of the double-check assertion.
6
6
7
Cc: qemu-arm@nongnu.org
8
Cc: qemu-stable@nongnu.org
7
Cc: qemu-stable@nongnu.org
9
Reported-by: Andrew <andrew@fubar.geek.nz>
8
Fixes: 285b1d5fcef ("target/arm: Handle SME in sve_access_check")
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20170825224833.4463-1-richard.henderson@linaro.org
10
Message-id: 20250307190415.982049-3-richard.henderson@linaro.org
12
Fixes: https://bugs.launchpad.net/qemu/+bug/1713066
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
[PMM: tweaked comment format]
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
[PMM: move declaration of 'ret' to top of block]
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
14
---
18
target/arm/translate-a64.c | 29 +++++++++++++++++------------
15
target/arm/tcg/translate-a64.c | 22 +++++++++++-----------
19
1 file changed, 17 insertions(+), 12 deletions(-)
16
1 file changed, 11 insertions(+), 11 deletions(-)
20
17
21
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
18
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
22
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/translate-a64.c
20
--- a/target/arm/tcg/translate-a64.c
24
+++ b/target/arm/translate-a64.c
21
+++ b/target/arm/tcg/translate-a64.c
25
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn)
22
@@ -XXX,XX +XXX,XX @@ static int fp_access_check_vector_hsd(DisasContext *s, bool is_q, MemOp esz)
26
} else {
23
bool sve_access_check(DisasContext *s)
27
do_fp_st(s, rt, tcg_addr, size);
24
{
28
}
25
if (s->pstate_sm || !dc_isar_feature(aa64_sve, s)) {
29
- } else {
26
+ bool ret;
30
- TCGv_i64 tcg_rt = cpu_reg(s, rt);
27
+
31
- if (is_load) {
28
assert(dc_isar_feature(aa64_sme, s));
32
- do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false,
29
- if (!sme_sm_enabled_check(s)) {
33
- false, 0, false, false);
30
- goto fail_exit;
34
- } else {
35
- do_gpr_st(s, tcg_rt, tcg_addr, size,
36
- false, 0, false, false);
37
- }
31
- }
38
- }
32
- } else if (s->sve_excp_el) {
39
- tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
33
+ ret = sme_sm_enabled_check(s);
40
- if (is_vector) {
34
+ s->sve_access_checked = (ret ? 1 : -1);
41
+ tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
35
+ return ret;
42
if (is_load) {
36
+ }
43
do_fp_ld(s, rt2, tcg_addr, size);
37
+ if (s->sve_excp_el) {
44
} else {
38
+ /* Assert that we only raise one exception per instruction. */
45
do_fp_st(s, rt2, tcg_addr, size);
39
+ assert(!s->sve_access_checked);
46
}
40
gen_exception_insn_el(s, 0, EXCP_UDEF,
47
} else {
41
syn_sve_access_trap(), s->sve_excp_el);
48
+ TCGv_i64 tcg_rt = cpu_reg(s, rt);
42
- goto fail_exit;
49
TCGv_i64 tcg_rt2 = cpu_reg(s, rt2);
43
+ s->sve_access_checked = -1;
50
+
44
+ return false;
51
if (is_load) {
45
}
52
+ TCGv_i64 tmp = tcg_temp_new_i64();
46
s->sve_access_checked = 1;
53
+
47
return fp_access_check(s);
54
+ /* Do not modify tcg_rt before recognizing any exception
48
-
55
+ * from the second load.
49
- fail_exit:
56
+ */
50
- /* Assert that we only raise one exception per instruction. */
57
+ do_gpr_ld(s, tmp, tcg_addr, size, is_signed, false,
51
- assert(!s->sve_access_checked);
58
+ false, 0, false, false);
52
- s->sve_access_checked = -1;
59
+ tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
53
- return false;
60
do_gpr_ld(s, tcg_rt2, tcg_addr, size, is_signed, false,
54
}
61
false, 0, false, false);
55
62
+
56
/*
63
+ tcg_gen_mov_i64(tcg_rt, tmp);
64
+ tcg_temp_free_i64(tmp);
65
} else {
66
+ do_gpr_st(s, tcg_rt, tcg_addr, size,
67
+ false, 0, false, false);
68
+ tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
69
do_gpr_st(s, tcg_rt2, tcg_addr, size,
70
false, 0, false, false);
71
}
72
--
57
--
73
2.7.4
58
2.43.0
74
75
diff view generated by jsdifflib
1
Set the MachineClass flag ignore_memory_transaction_failures
1
We want to capture potential Rust backtraces on panics in our test
2
for almost all ARM boards. This means they retain the legacy
2
logs, which isn't Rust's default behaviour. Set RUST_BACKTRACE=1 in
3
behaviour that accesses to unimplemented addresses will RAZ/WI
3
the add_test_setup environments, so that all our tests get run with
4
rather than aborting, when a subsequent commit adds support
4
this environment variable set.
5
for external aborts.
6
5
7
The exceptions are:
6
This makes the setting of that variable in the gitlab CI template
8
* virt -- we know that guests won't try to prod devices
7
redundant, so we can remove it.
9
that we don't describe in the device tree or ACPI tables
10
* mps2 -- this board was written to use unimplemented-device
11
for all the ranges with devices we don't yet handle
12
13
New boards should not set the flag, but instead be written
14
like the mps2.
15
8
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
For the Xilinx boards:
10
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
18
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Message-id: 20250310102950.3752908-1-peter.maydell@linaro.org
19
---
13
---
20
hw/arm/aspeed.c | 3 +++
14
meson.build | 9 ++++++---
21
hw/arm/collie.c | 1 +
15
.gitlab-ci.d/buildtest-template.yml | 1 -
22
hw/arm/cubieboard.c | 1 +
16
2 files changed, 6 insertions(+), 4 deletions(-)
23
hw/arm/digic_boards.c | 1 +
24
hw/arm/exynos4_boards.c | 2 ++
25
hw/arm/gumstix.c | 2 ++
26
hw/arm/highbank.c | 2 ++
27
hw/arm/imx25_pdk.c | 1 +
28
hw/arm/integratorcp.c | 1 +
29
hw/arm/kzm.c | 1 +
30
hw/arm/mainstone.c | 1 +
31
hw/arm/musicpal.c | 1 +
32
hw/arm/netduino2.c | 1 +
33
hw/arm/nseries.c | 2 ++
34
hw/arm/omap_sx1.c | 2 ++
35
hw/arm/palm.c | 1 +
36
hw/arm/raspi.c | 1 +
37
hw/arm/realview.c | 4 ++++
38
hw/arm/sabrelite.c | 1 +
39
hw/arm/spitz.c | 4 ++++
40
hw/arm/stellaris.c | 2 ++
41
hw/arm/tosa.c | 1 +
42
hw/arm/versatilepb.c | 2 ++
43
hw/arm/vexpress.c | 1 +
44
hw/arm/xilinx_zynq.c | 1 +
45
hw/arm/xlnx-ep108.c | 2 ++
46
hw/arm/z2.c | 1 +
47
27 files changed, 43 insertions(+)
48
17
49
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
18
diff --git a/meson.build b/meson.build
50
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/aspeed.c
20
--- a/meson.build
52
+++ b/hw/arm/aspeed.c
21
+++ b/meson.build
53
@@ -XXX,XX +XXX,XX @@ static void palmetto_bmc_class_init(ObjectClass *oc, void *data)
22
@@ -XXX,XX +XXX,XX @@ project('qemu', ['c'], meson_version: '>=1.5.0',
54
mc->no_floppy = 1;
23
55
mc->no_cdrom = 1;
24
meson.add_devenv({ 'MESON_BUILD_ROOT' : meson.project_build_root() })
56
mc->no_parallel = 1;
25
57
+ mc->ignore_memory_transaction_failures = true;
26
-add_test_setup('quick', exclude_suites: ['slow', 'thorough'], is_default: true)
58
}
27
-add_test_setup('slow', exclude_suites: ['thorough'], env: ['G_TEST_SLOW=1', 'SPEED=slow'])
59
28
-add_test_setup('thorough', env: ['G_TEST_SLOW=1', 'SPEED=thorough'])
60
static const TypeInfo palmetto_bmc_type = {
29
+add_test_setup('quick', exclude_suites: ['slow', 'thorough'], is_default: true,
61
@@ -XXX,XX +XXX,XX @@ static void ast2500_evb_class_init(ObjectClass *oc, void *data)
30
+ env: ['RUST_BACKTRACE=1'])
62
mc->no_floppy = 1;
31
+add_test_setup('slow', exclude_suites: ['thorough'],
63
mc->no_cdrom = 1;
32
+ env: ['G_TEST_SLOW=1', 'SPEED=slow', 'RUST_BACKTRACE=1'])
64
mc->no_parallel = 1;
33
+add_test_setup('thorough',
65
+ mc->ignore_memory_transaction_failures = true;
34
+ env: ['G_TEST_SLOW=1', 'SPEED=thorough', 'RUST_BACKTRACE=1'])
66
}
35
67
36
meson.add_postconf_script(find_program('scripts/symlink-install-tree.py'))
68
static const TypeInfo ast2500_evb_type = {
37
69
@@ -XXX,XX +XXX,XX @@ static void romulus_bmc_class_init(ObjectClass *oc, void *data)
38
diff --git a/.gitlab-ci.d/buildtest-template.yml b/.gitlab-ci.d/buildtest-template.yml
70
mc->no_floppy = 1;
71
mc->no_cdrom = 1;
72
mc->no_parallel = 1;
73
+ mc->ignore_memory_transaction_failures = true;
74
}
75
76
static const TypeInfo romulus_bmc_type = {
77
diff --git a/hw/arm/collie.c b/hw/arm/collie.c
78
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/arm/collie.c
40
--- a/.gitlab-ci.d/buildtest-template.yml
80
+++ b/hw/arm/collie.c
41
+++ b/.gitlab-ci.d/buildtest-template.yml
81
@@ -XXX,XX +XXX,XX @@ static void collie_machine_init(MachineClass *mc)
42
@@ -XXX,XX +XXX,XX @@
82
{
43
stage: test
83
mc->desc = "Sharp SL-5500 (Collie) PDA (SA-1110)";
44
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:$QEMU_CI_CONTAINER_TAG
84
mc->init = collie_init;
45
script:
85
+ mc->ignore_memory_transaction_failures = true;
46
- - export RUST_BACKTRACE=1
86
}
47
- source scripts/ci/gitlab-ci-section
87
48
- section_start buildenv "Setting up to run tests"
88
DEFINE_MACHINE("collie", collie_machine_init)
49
- scripts/git-submodule.sh update roms/SLOF
89
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/hw/arm/cubieboard.c
92
+++ b/hw/arm/cubieboard.c
93
@@ -XXX,XX +XXX,XX @@ static void cubieboard_machine_init(MachineClass *mc)
94
mc->init = cubieboard_init;
95
mc->block_default_type = IF_IDE;
96
mc->units_per_default_bus = 1;
97
+ mc->ignore_memory_transaction_failures = true;
98
}
99
100
DEFINE_MACHINE("cubieboard", cubieboard_machine_init)
101
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
102
index XXXXXXX..XXXXXXX 100644
103
--- a/hw/arm/digic_boards.c
104
+++ b/hw/arm/digic_boards.c
105
@@ -XXX,XX +XXX,XX @@ static void canon_a1100_machine_init(MachineClass *mc)
106
{
107
mc->desc = "Canon PowerShot A1100 IS";
108
mc->init = &canon_a1100_init;
109
+ mc->ignore_memory_transaction_failures = true;
110
}
111
112
DEFINE_MACHINE("canon-a1100", canon_a1100_machine_init)
113
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/hw/arm/exynos4_boards.c
116
+++ b/hw/arm/exynos4_boards.c
117
@@ -XXX,XX +XXX,XX @@ static void nuri_class_init(ObjectClass *oc, void *data)
118
mc->desc = "Samsung NURI board (Exynos4210)";
119
mc->init = nuri_init;
120
mc->max_cpus = EXYNOS4210_NCPUS;
121
+ mc->ignore_memory_transaction_failures = true;
122
}
123
124
static const TypeInfo nuri_type = {
125
@@ -XXX,XX +XXX,XX @@ static void smdkc210_class_init(ObjectClass *oc, void *data)
126
mc->desc = "Samsung SMDKC210 board (Exynos4210)";
127
mc->init = smdkc210_init;
128
mc->max_cpus = EXYNOS4210_NCPUS;
129
+ mc->ignore_memory_transaction_failures = true;
130
}
131
132
static const TypeInfo smdkc210_type = {
133
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/hw/arm/gumstix.c
136
+++ b/hw/arm/gumstix.c
137
@@ -XXX,XX +XXX,XX @@ static void connex_class_init(ObjectClass *oc, void *data)
138
139
mc->desc = "Gumstix Connex (PXA255)";
140
mc->init = connex_init;
141
+ mc->ignore_memory_transaction_failures = true;
142
}
143
144
static const TypeInfo connex_type = {
145
@@ -XXX,XX +XXX,XX @@ static void verdex_class_init(ObjectClass *oc, void *data)
146
147
mc->desc = "Gumstix Verdex (PXA270)";
148
mc->init = verdex_init;
149
+ mc->ignore_memory_transaction_failures = true;
150
}
151
152
static const TypeInfo verdex_type = {
153
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
154
index XXXXXXX..XXXXXXX 100644
155
--- a/hw/arm/highbank.c
156
+++ b/hw/arm/highbank.c
157
@@ -XXX,XX +XXX,XX @@ static void highbank_class_init(ObjectClass *oc, void *data)
158
mc->block_default_type = IF_IDE;
159
mc->units_per_default_bus = 1;
160
mc->max_cpus = 4;
161
+ mc->ignore_memory_transaction_failures = true;
162
}
163
164
static const TypeInfo highbank_type = {
165
@@ -XXX,XX +XXX,XX @@ static void midway_class_init(ObjectClass *oc, void *data)
166
mc->block_default_type = IF_IDE;
167
mc->units_per_default_bus = 1;
168
mc->max_cpus = 4;
169
+ mc->ignore_memory_transaction_failures = true;
170
}
171
172
static const TypeInfo midway_type = {
173
diff --git a/hw/arm/imx25_pdk.c b/hw/arm/imx25_pdk.c
174
index XXXXXXX..XXXXXXX 100644
175
--- a/hw/arm/imx25_pdk.c
176
+++ b/hw/arm/imx25_pdk.c
177
@@ -XXX,XX +XXX,XX @@ static void imx25_pdk_machine_init(MachineClass *mc)
178
{
179
mc->desc = "ARM i.MX25 PDK board (ARM926)";
180
mc->init = imx25_pdk_init;
181
+ mc->ignore_memory_transaction_failures = true;
182
}
183
184
DEFINE_MACHINE("imx25-pdk", imx25_pdk_machine_init)
185
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
186
index XXXXXXX..XXXXXXX 100644
187
--- a/hw/arm/integratorcp.c
188
+++ b/hw/arm/integratorcp.c
189
@@ -XXX,XX +XXX,XX @@ static void integratorcp_machine_init(MachineClass *mc)
190
{
191
mc->desc = "ARM Integrator/CP (ARM926EJ-S)";
192
mc->init = integratorcp_init;
193
+ mc->ignore_memory_transaction_failures = true;
194
}
195
196
DEFINE_MACHINE("integratorcp", integratorcp_machine_init)
197
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
198
index XXXXXXX..XXXXXXX 100644
199
--- a/hw/arm/kzm.c
200
+++ b/hw/arm/kzm.c
201
@@ -XXX,XX +XXX,XX @@ static void kzm_machine_init(MachineClass *mc)
202
{
203
mc->desc = "ARM KZM Emulation Baseboard (ARM1136)";
204
mc->init = kzm_init;
205
+ mc->ignore_memory_transaction_failures = true;
206
}
207
208
DEFINE_MACHINE("kzm", kzm_machine_init)
209
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
210
index XXXXXXX..XXXXXXX 100644
211
--- a/hw/arm/mainstone.c
212
+++ b/hw/arm/mainstone.c
213
@@ -XXX,XX +XXX,XX @@ static void mainstone2_machine_init(MachineClass *mc)
214
{
215
mc->desc = "Mainstone II (PXA27x)";
216
mc->init = mainstone_init;
217
+ mc->ignore_memory_transaction_failures = true;
218
}
219
220
DEFINE_MACHINE("mainstone", mainstone2_machine_init)
221
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
222
index XXXXXXX..XXXXXXX 100644
223
--- a/hw/arm/musicpal.c
224
+++ b/hw/arm/musicpal.c
225
@@ -XXX,XX +XXX,XX @@ static void musicpal_machine_init(MachineClass *mc)
226
{
227
mc->desc = "Marvell 88w8618 / MusicPal (ARM926EJ-S)";
228
mc->init = musicpal_init;
229
+ mc->ignore_memory_transaction_failures = true;
230
}
231
232
DEFINE_MACHINE("musicpal", musicpal_machine_init)
233
diff --git a/hw/arm/netduino2.c b/hw/arm/netduino2.c
234
index XXXXXXX..XXXXXXX 100644
235
--- a/hw/arm/netduino2.c
236
+++ b/hw/arm/netduino2.c
237
@@ -XXX,XX +XXX,XX @@ static void netduino2_machine_init(MachineClass *mc)
238
{
239
mc->desc = "Netduino 2 Machine";
240
mc->init = netduino2_init;
241
+ mc->ignore_memory_transaction_failures = true;
242
}
243
244
DEFINE_MACHINE("netduino2", netduino2_machine_init)
245
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
246
index XXXXXXX..XXXXXXX 100644
247
--- a/hw/arm/nseries.c
248
+++ b/hw/arm/nseries.c
249
@@ -XXX,XX +XXX,XX @@ static void n800_class_init(ObjectClass *oc, void *data)
250
mc->desc = "Nokia N800 tablet aka. RX-34 (OMAP2420)";
251
mc->init = n800_init;
252
mc->default_boot_order = "";
253
+ mc->ignore_memory_transaction_failures = true;
254
}
255
256
static const TypeInfo n800_type = {
257
@@ -XXX,XX +XXX,XX @@ static void n810_class_init(ObjectClass *oc, void *data)
258
mc->desc = "Nokia N810 tablet aka. RX-44 (OMAP2420)";
259
mc->init = n810_init;
260
mc->default_boot_order = "";
261
+ mc->ignore_memory_transaction_failures = true;
262
}
263
264
static const TypeInfo n810_type = {
265
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
266
index XXXXXXX..XXXXXXX 100644
267
--- a/hw/arm/omap_sx1.c
268
+++ b/hw/arm/omap_sx1.c
269
@@ -XXX,XX +XXX,XX @@ static void sx1_machine_v2_class_init(ObjectClass *oc, void *data)
270
271
mc->desc = "Siemens SX1 (OMAP310) V2";
272
mc->init = sx1_init_v2;
273
+ mc->ignore_memory_transaction_failures = true;
274
}
275
276
static const TypeInfo sx1_machine_v2_type = {
277
@@ -XXX,XX +XXX,XX @@ static void sx1_machine_v1_class_init(ObjectClass *oc, void *data)
278
279
mc->desc = "Siemens SX1 (OMAP310) V1";
280
mc->init = sx1_init_v1;
281
+ mc->ignore_memory_transaction_failures = true;
282
}
283
284
static const TypeInfo sx1_machine_v1_type = {
285
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
286
index XXXXXXX..XXXXXXX 100644
287
--- a/hw/arm/palm.c
288
+++ b/hw/arm/palm.c
289
@@ -XXX,XX +XXX,XX @@ static void palmte_machine_init(MachineClass *mc)
290
{
291
mc->desc = "Palm Tungsten|E aka. Cheetah PDA (OMAP310)";
292
mc->init = palmte_init;
293
+ mc->ignore_memory_transaction_failures = true;
294
}
295
296
DEFINE_MACHINE("cheetah", palmte_machine_init)
297
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
298
index XXXXXXX..XXXXXXX 100644
299
--- a/hw/arm/raspi.c
300
+++ b/hw/arm/raspi.c
301
@@ -XXX,XX +XXX,XX @@ static void raspi2_machine_init(MachineClass *mc)
302
mc->no_cdrom = 1;
303
mc->max_cpus = BCM2836_NCPUS;
304
mc->default_ram_size = 1024 * 1024 * 1024;
305
+ mc->ignore_memory_transaction_failures = true;
306
};
307
DEFINE_MACHINE("raspi2", raspi2_machine_init)
308
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
309
index XXXXXXX..XXXXXXX 100644
310
--- a/hw/arm/realview.c
311
+++ b/hw/arm/realview.c
312
@@ -XXX,XX +XXX,XX @@ static void realview_eb_class_init(ObjectClass *oc, void *data)
313
mc->desc = "ARM RealView Emulation Baseboard (ARM926EJ-S)";
314
mc->init = realview_eb_init;
315
mc->block_default_type = IF_SCSI;
316
+ mc->ignore_memory_transaction_failures = true;
317
}
318
319
static const TypeInfo realview_eb_type = {
320
@@ -XXX,XX +XXX,XX @@ static void realview_eb_mpcore_class_init(ObjectClass *oc, void *data)
321
mc->init = realview_eb_mpcore_init;
322
mc->block_default_type = IF_SCSI;
323
mc->max_cpus = 4;
324
+ mc->ignore_memory_transaction_failures = true;
325
}
326
327
static const TypeInfo realview_eb_mpcore_type = {
328
@@ -XXX,XX +XXX,XX @@ static void realview_pb_a8_class_init(ObjectClass *oc, void *data)
329
330
mc->desc = "ARM RealView Platform Baseboard for Cortex-A8";
331
mc->init = realview_pb_a8_init;
332
+ mc->ignore_memory_transaction_failures = true;
333
}
334
335
static const TypeInfo realview_pb_a8_type = {
336
@@ -XXX,XX +XXX,XX @@ static void realview_pbx_a9_class_init(ObjectClass *oc, void *data)
337
mc->desc = "ARM RealView Platform Baseboard Explore for Cortex-A9";
338
mc->init = realview_pbx_a9_init;
339
mc->max_cpus = 4;
340
+ mc->ignore_memory_transaction_failures = true;
341
}
342
343
static const TypeInfo realview_pbx_a9_type = {
344
diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c
345
index XXXXXXX..XXXXXXX 100644
346
--- a/hw/arm/sabrelite.c
347
+++ b/hw/arm/sabrelite.c
348
@@ -XXX,XX +XXX,XX @@ static void sabrelite_machine_init(MachineClass *mc)
349
mc->desc = "Freescale i.MX6 Quad SABRE Lite Board (Cortex A9)";
350
mc->init = sabrelite_init;
351
mc->max_cpus = FSL_IMX6_NUM_CPUS;
352
+ mc->ignore_memory_transaction_failures = true;
353
}
354
355
DEFINE_MACHINE("sabrelite", sabrelite_machine_init)
356
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
357
index XXXXXXX..XXXXXXX 100644
358
--- a/hw/arm/spitz.c
359
+++ b/hw/arm/spitz.c
360
@@ -XXX,XX +XXX,XX @@ static void akitapda_class_init(ObjectClass *oc, void *data)
361
362
mc->desc = "Sharp SL-C1000 (Akita) PDA (PXA270)";
363
mc->init = akita_init;
364
+ mc->ignore_memory_transaction_failures = true;
365
}
366
367
static const TypeInfo akitapda_type = {
368
@@ -XXX,XX +XXX,XX @@ static void spitzpda_class_init(ObjectClass *oc, void *data)
369
mc->desc = "Sharp SL-C3000 (Spitz) PDA (PXA270)";
370
mc->init = spitz_init;
371
mc->block_default_type = IF_IDE;
372
+ mc->ignore_memory_transaction_failures = true;
373
}
374
375
static const TypeInfo spitzpda_type = {
376
@@ -XXX,XX +XXX,XX @@ static void borzoipda_class_init(ObjectClass *oc, void *data)
377
mc->desc = "Sharp SL-C3100 (Borzoi) PDA (PXA270)";
378
mc->init = borzoi_init;
379
mc->block_default_type = IF_IDE;
380
+ mc->ignore_memory_transaction_failures = true;
381
}
382
383
static const TypeInfo borzoipda_type = {
384
@@ -XXX,XX +XXX,XX @@ static void terrierpda_class_init(ObjectClass *oc, void *data)
385
mc->desc = "Sharp SL-C3200 (Terrier) PDA (PXA270)";
386
mc->init = terrier_init;
387
mc->block_default_type = IF_IDE;
388
+ mc->ignore_memory_transaction_failures = true;
389
}
390
391
static const TypeInfo terrierpda_type = {
392
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
393
index XXXXXXX..XXXXXXX 100644
394
--- a/hw/arm/stellaris.c
395
+++ b/hw/arm/stellaris.c
396
@@ -XXX,XX +XXX,XX @@ static void lm3s811evb_class_init(ObjectClass *oc, void *data)
397
398
mc->desc = "Stellaris LM3S811EVB";
399
mc->init = lm3s811evb_init;
400
+ mc->ignore_memory_transaction_failures = true;
401
}
402
403
static const TypeInfo lm3s811evb_type = {
404
@@ -XXX,XX +XXX,XX @@ static void lm3s6965evb_class_init(ObjectClass *oc, void *data)
405
406
mc->desc = "Stellaris LM3S6965EVB";
407
mc->init = lm3s6965evb_init;
408
+ mc->ignore_memory_transaction_failures = true;
409
}
410
411
static const TypeInfo lm3s6965evb_type = {
412
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
413
index XXXXXXX..XXXXXXX 100644
414
--- a/hw/arm/tosa.c
415
+++ b/hw/arm/tosa.c
416
@@ -XXX,XX +XXX,XX @@ static void tosapda_machine_init(MachineClass *mc)
417
mc->desc = "Sharp SL-6000 (Tosa) PDA (PXA255)";
418
mc->init = tosa_init;
419
mc->block_default_type = IF_IDE;
420
+ mc->ignore_memory_transaction_failures = true;
421
}
422
423
DEFINE_MACHINE("tosa", tosapda_machine_init)
424
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
425
index XXXXXXX..XXXXXXX 100644
426
--- a/hw/arm/versatilepb.c
427
+++ b/hw/arm/versatilepb.c
428
@@ -XXX,XX +XXX,XX @@ static void versatilepb_class_init(ObjectClass *oc, void *data)
429
mc->desc = "ARM Versatile/PB (ARM926EJ-S)";
430
mc->init = vpb_init;
431
mc->block_default_type = IF_SCSI;
432
+ mc->ignore_memory_transaction_failures = true;
433
}
434
435
static const TypeInfo versatilepb_type = {
436
@@ -XXX,XX +XXX,XX @@ static void versatileab_class_init(ObjectClass *oc, void *data)
437
mc->desc = "ARM Versatile/AB (ARM926EJ-S)";
438
mc->init = vab_init;
439
mc->block_default_type = IF_SCSI;
440
+ mc->ignore_memory_transaction_failures = true;
441
}
442
443
static const TypeInfo versatileab_type = {
444
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
445
index XXXXXXX..XXXXXXX 100644
446
--- a/hw/arm/vexpress.c
447
+++ b/hw/arm/vexpress.c
448
@@ -XXX,XX +XXX,XX @@ static void vexpress_class_init(ObjectClass *oc, void *data)
449
mc->desc = "ARM Versatile Express";
450
mc->init = vexpress_common_init;
451
mc->max_cpus = 4;
452
+ mc->ignore_memory_transaction_failures = true;
453
}
454
455
static void vexpress_a9_class_init(ObjectClass *oc, void *data)
456
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
457
index XXXXXXX..XXXXXXX 100644
458
--- a/hw/arm/xilinx_zynq.c
459
+++ b/hw/arm/xilinx_zynq.c
460
@@ -XXX,XX +XXX,XX @@ static void zynq_machine_init(MachineClass *mc)
461
mc->init = zynq_init;
462
mc->max_cpus = 1;
463
mc->no_sdcard = 1;
464
+ mc->ignore_memory_transaction_failures = true;
465
}
466
467
DEFINE_MACHINE("xilinx-zynq-a9", zynq_machine_init)
468
diff --git a/hw/arm/xlnx-ep108.c b/hw/arm/xlnx-ep108.c
469
index XXXXXXX..XXXXXXX 100644
470
--- a/hw/arm/xlnx-ep108.c
471
+++ b/hw/arm/xlnx-ep108.c
472
@@ -XXX,XX +XXX,XX @@ static void xlnx_ep108_machine_init(MachineClass *mc)
473
mc->init = xlnx_ep108_init;
474
mc->block_default_type = IF_IDE;
475
mc->units_per_default_bus = 1;
476
+ mc->ignore_memory_transaction_failures = true;
477
}
478
479
DEFINE_MACHINE("xlnx-ep108", xlnx_ep108_machine_init)
480
@@ -XXX,XX +XXX,XX @@ static void xlnx_zcu102_machine_init(MachineClass *mc)
481
mc->init = xlnx_ep108_init;
482
mc->block_default_type = IF_IDE;
483
mc->units_per_default_bus = 1;
484
+ mc->ignore_memory_transaction_failures = true;
485
}
486
487
DEFINE_MACHINE("xlnx-zcu102", xlnx_zcu102_machine_init)
488
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
489
index XXXXXXX..XXXXXXX 100644
490
--- a/hw/arm/z2.c
491
+++ b/hw/arm/z2.c
492
@@ -XXX,XX +XXX,XX @@ static void z2_machine_init(MachineClass *mc)
493
{
494
mc->desc = "Zipit Z2 (PXA27x)";
495
mc->init = z2_init;
496
+ mc->ignore_memory_transaction_failures = true;
497
}
498
499
DEFINE_MACHINE("z2", z2_machine_init)
500
--
50
--
501
2.7.4
51
2.43.0
502
52
503
53
diff view generated by jsdifflib
Deleted patch
1
From: Thomas Huth <thuth@redhat.com>
2
1
3
QEMU currently aborts if the user is accidentially trying to
4
do something like this:
5
6
$ aarch64-softmmu/qemu-system-aarch64 -S -M integratorcp -nographic
7
QEMU 2.9.93 monitor - type 'help' for more information
8
(qemu) device_add ast2400
9
Unexpected error in error_set_from_qdev_prop_error()
10
at hw/core/qdev-properties.c:1032:
11
Aborted (core dumped)
12
13
The ast2400 SoC devices are clearly not creatable by the user since
14
they are using the serial_hds and nd_table arrays directly in their
15
realize function, so mark them with user_creatable = false.
16
17
Signed-off-by: Thomas Huth <thuth@redhat.com>
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Cédric Le Goater <clg@kaod.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
22
hw/arm/aspeed_soc.c | 2 ++
23
1 file changed, 2 insertions(+)
24
25
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/aspeed_soc.c
28
+++ b/hw/arm/aspeed_soc.c
29
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_class_init(ObjectClass *oc, void *data)
30
31
sc->info = (AspeedSoCInfo *) data;
32
dc->realize = aspeed_soc_realize;
33
+ /* Reason: Uses serial_hds and nd_table in realize() directly */
34
+ dc->user_creatable = false;
35
}
36
37
static const TypeInfo aspeed_soc_type_info = {
38
--
39
2.7.4
40
41
diff view generated by jsdifflib
Deleted patch
1
From: Pranith Kumar <bobby.prani@gmail.com>
2
1
3
Fix the following warning:
4
5
/home/pranith/qemu/hw/intc/arm_gicv3_kvm.c:296:17: warning: logical not is only applied to the left hand side of this bitwise operator [-Wlogical-not-parentheses]
6
if (!c->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) {
7
^ ~
8
/home/pranith/qemu/hw/intc/arm_gicv3_kvm.c:296:17: note: add parentheses after the '!' to evaluate the bitwise operator first
9
if (!c->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) {
10
^
11
/home/pranith/qemu/hw/intc/arm_gicv3_kvm.c:296:17: note: add parentheses around left hand side expression to silence this warning
12
if (!c->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) {
13
^
14
15
This logic error meant we were not setting the PTZ
16
bit when we should -- luckily as the comment suggests
17
this wouldn't have had any effects beyond making GIC
18
initialization take a little longer.
19
20
Signed-off-by: Pranith Kumar <bobby.prani@gmail.com>
21
Message-id: 20170829173226.7625-1-bobby.prani@gmail.com
22
Cc: qemu-stable@nongnu.org
23
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
---
26
hw/intc/arm_gicv3_kvm.c | 2 +-
27
1 file changed, 1 insertion(+), 1 deletion(-)
28
29
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/intc/arm_gicv3_kvm.c
32
+++ b/hw/intc/arm_gicv3_kvm.c
33
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_put(GICv3State *s)
34
kvm_gicr_access(s, GICR_PROPBASER + 4, ncpu, &regh, true);
35
36
reg64 = c->gicr_pendbaser;
37
- if (!c->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) {
38
+ if (!(c->gicr_ctlr & GICR_CTLR_ENABLE_LPIS)) {
39
/* Setting PTZ is advised if LPIs are disabled, to reduce
40
* GIC initialization time.
41
*/
42
--
43
2.7.4
44
45
diff view generated by jsdifflib