1
First arm pullreq of the 2.11 cycle. I know I still have some
1
The following changes since commit e3debd5e7d0ce031356024878a0a18b9d109354a:
2
more stuff on my queue to review, but 36 patches is big enough
3
as it is; I expect I'll do another pull later this week.
4
2
5
thanks
3
Merge tag 'pull-request-2023-03-24' of https://gitlab.com/thuth/qemu into staging (2023-03-24 16:08:46 +0000)
6
-- PMM
7
4
8
The following changes since commit 32f0f68bb77289b75a82925f712bb52e16eac3ba:
5
are available in the Git repository at:
9
6
10
Merge remote-tracking branch 'remotes/ehabkost/tags/x86-and-machine-pull-request' into staging (2017-09-01 17:28:54 +0100)
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230328
11
8
12
are available in the git repository at:
9
for you to fetch changes up to 46e3b237c52e0c48bfd81bce020b51fbe300b23a:
13
10
14
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20170904
11
target/arm/gdbstub: Only advertise M-profile features if TCG available (2023-03-28 10:53:40 +0100)
15
16
for you to fetch changes up to 1e35c4ce33a94cf78dbf639695cb877ef35920b0:
17
18
arm_gicv3_kvm: Fix compile warning (2017-09-04 12:09:32 +0100)
19
12
20
----------------------------------------------------------------
13
----------------------------------------------------------------
21
target-arm:
14
target-arm queue:
22
* collection of M profile cleanups and minor bugfixes
15
* fix part of the "TCG-disabled builds are broken" issue
23
* loader: handle ELF files with overlapping zero-init data
24
* virt: allow PMU instantiation with userspace irqchip
25
* wdt_aspeed: Add support for the reset width register
26
* cpu: Define new cpu_transaction_failed() hook
27
* arm: Support generating CPU exceptions on memory
28
transaction failures (bus faults)
29
* Mark some SoC devices as not user-creatable
30
* arm: Fix aa64 ldp register writeback
31
* arm_gicv3_kvm: Fix compile warning
32
16
33
----------------------------------------------------------------
17
----------------------------------------------------------------
34
Andrew Jeffery (2):
18
Philippe Mathieu-Daudé (1):
35
watchdog: wdt_aspeed: Add support for the reset width register
19
target/arm/gdbstub: Only advertise M-profile features if TCG available
36
aspeed_soc: Propagate silicon-rev to watchdog
37
20
38
Andrew Jones (4):
21
target/arm/gdbstub.c | 5 +++--
39
hw/arm/virt: add pmu interrupt state
22
1 file changed, 3 insertions(+), 2 deletions(-)
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
23
44
Peter Maydell (25):
45
target/arm: Use MMUAccessType enum rather than int
46
target/arm: Don't trap WFI/WFE for M profile
47
target/arm: Consolidate PMSA handling in get_phys_addr()
48
target/arm: Tighten up Thumb decode where new v8M insns will be
49
hw/intc/armv7m_nvic.c: Remove out of date comment
50
target/arm: Remove incorrect comment about MPU_CTRL
51
target/arm: Fix outdated comment about exception exit
52
target/arm: Define and use XPSR bit masks
53
target/arm: Don't store M profile PRIMASK and FAULTMASK in daif
54
target/arm: Don't use cpsr_write/cpsr_read to transfer M profile XPSR
55
target/arm: Make arm_cpu_dump_state() handle the M-profile XPSR
56
target/arm: Don't calculate lr in arm_v7m_cpu_do_interrupt() until needed
57
target/arm: Create and use new function arm_v7m_is_handler_mode()
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
71
Philippe Mathieu-Daudé (1):
72
hw/arm: use defined type name instead of hard-coded string
73
74
Pranith Kumar (1):
75
arm_gicv3_kvm: Fix compile warning
76
77
Richard Henderson (1):
78
target/arm: Fix aa64 ldp register writeback
79
80
Thomas Huth (2):
81
hw/arm/aspeed_soc: Mark devices as user_creatable = false
82
hw/arm/digic: Mark device with user_creatable = false
83
84
include/exec/memattrs.h | 10 +++
85
include/exec/memory.h | 10 ---
86
include/hw/arm/armv7m.h | 2 +-
87
include/hw/boards.h | 11 +++
88
include/hw/elf_ops.h | 72 +++++++++++++--
89
include/hw/{arm => intc}/armv7m_nvic.h | 0
90
include/hw/watchdog/wdt_aspeed.h | 2 +
91
include/qom/cpu.h | 27 ++++++
92
softmmu_template.h | 4 +-
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
Deleted patch
1
In the ARM get_phys_addr() code, switch to using the MMUAccessType
2
enum and its MMU_* values rather than int and literal 0/1/2.
3
1
4
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>
8
Message-id: 1501692241-23310-2-git-send-email-peter.maydell@linaro.org
9
---
10
target/arm/internals.h | 3 ++-
11
target/arm/helper.c | 30 +++++++++++++++---------------
12
2 files changed, 17 insertions(+), 16 deletions(-)
13
14
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/internals.h
17
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@ struct ARMMMUFaultInfo {
19
};
20
21
/* Do a page table walk and add page to TLB if possible */
22
-bool arm_tlb_fill(CPUState *cpu, vaddr address, int rw, int mmu_idx,
23
+bool arm_tlb_fill(CPUState *cpu, vaddr address,
24
+ MMUAccessType access_type, int mmu_idx,
25
uint32_t *fsr, ARMMMUFaultInfo *fi);
26
27
/* Return true if the stage 1 translation regime is using LPAE format page
28
diff --git a/target/arm/helper.c b/target/arm/helper.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/helper.c
31
+++ b/target/arm/helper.c
32
@@ -XXX,XX +XXX,XX @@
33
34
#ifndef CONFIG_USER_ONLY
35
static bool get_phys_addr(CPUARMState *env, target_ulong address,
36
- int access_type, ARMMMUIdx mmu_idx,
37
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
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 {
146
mask = env->cp15.pmsav5_data_ap;
147
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
148
* @fsr: set to the DFSR/IFSR value on failure
149
*/
150
static bool get_phys_addr(CPUARMState *env, target_ulong address,
151
- int access_type, ARMMMUIdx mmu_idx,
152
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
153
hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
154
target_ulong *page_size, uint32_t *fsr,
155
ARMMMUFaultInfo *fi)
156
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
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
--
166
2.7.4
167
168
diff view generated by jsdifflib
Deleted patch
1
M profile cores can never trap on WFI or WFE instructions. Check for
2
M profile in check_wfx_trap() to ensure this.
3
1
4
The existing code will do the right thing for v7M cores because
5
the hcr_el2 and scr_el3 registers will be all-zeroes and so we
6
won't attempt to trap, but when we start setting ARM_FEATURE_V8
7
for v8M cores the v8A handling of SCTLR.nTWE and .nTWI will not
8
give the right results.
9
10
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>
13
Message-id: 1501692241-23310-3-git-send-email-peter.maydell@linaro.org
14
---
15
target/arm/op_helper.c | 5 +++++
16
1 file changed, 5 insertions(+)
17
18
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/op_helper.c
21
+++ b/target/arm/op_helper.c
22
@@ -XXX,XX +XXX,XX @@ static inline int check_wfx_trap(CPUARMState *env, bool is_wfe)
23
int cur_el = arm_current_el(env);
24
uint64_t mask;
25
26
+ if (arm_feature(env, ARM_FEATURE_M)) {
27
+ /* M profile cores can never trap WFI/WFE. */
28
+ return 0;
29
+ }
30
+
31
/* If we are currently in EL0 then we need to check if SCTLR is set up for
32
* WFx instructions being trapped to EL1. These trap bits don't exist in v7.
33
*/
34
--
35
2.7.4
36
37
diff view generated by jsdifflib
Deleted patch
1
Currently get_phys_addr() has PMSAv7 handling before the
2
"is translation disabled?" check, and then PMSAv5 after it.
3
Tidy this up by making the PMSAv5 code handle the "MPU disabled"
4
case itself, so that we have all the PMSA code in one place.
5
This will make adding the PMSAv8 code slightly cleaner, and
6
also means that pre-v7 PMSA cores benefit from the MPU lookup
7
logging that the PMSAv7 codepath had.
8
1
9
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>
13
Message-id: 1501692241-23310-4-git-send-email-peter.maydell@linaro.org
14
---
15
target/arm/helper.c | 38 ++++++++++++++++++++++----------------
16
1 file changed, 22 insertions(+), 16 deletions(-)
17
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.c
21
+++ b/target/arm/helper.c
22
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
23
uint32_t base;
24
bool is_user = regime_is_user(env, mmu_idx);
25
26
+ if (regime_translation_disabled(env, mmu_idx)) {
27
+ /* MPU disabled. */
28
+ *phys_ptr = address;
29
+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
30
+ return false;
31
+ }
32
+
33
*phys_ptr = address;
34
for (n = 7; n >= 0; n--) {
35
base = env->cp15.c6_region[n];
36
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
37
}
38
}
39
40
- /* pmsav7 has special handling for when MPU is disabled so call it before
41
- * the common MMU/MPU disabled check below.
42
- */
43
- if (arm_feature(env, ARM_FEATURE_PMSA) &&
44
- arm_feature(env, ARM_FEATURE_V7)) {
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
+
52
+ if (arm_feature(env, ARM_FEATURE_V7)) {
53
+ /* PMSAv7 */
54
+ ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
55
+ phys_ptr, prot, fsr);
56
+ } else {
57
+ /* Pre-v7 MPU */
58
+ ret = get_phys_addr_pmsav5(env, address, access_type, mmu_idx,
59
+ phys_ptr, prot, fsr);
60
+ }
61
+ qemu_log_mask(CPU_LOG_MMU, "PMSA MPU lookup for %s at 0x%08" PRIx32
62
" mmu_idx %u -> %s (prot %c%c%c)\n",
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
--
91
2.7.4
92
93
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
The M profile XPSR is almost the same format as the A profile CPSR,
2
but not quite. Define some XPSR_* macros and use them where we
3
definitely dealing with an XPSR rather than reusing the CPSR ones.
4
1
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>
8
Message-id: 1501692241-23310-9-git-send-email-peter.maydell@linaro.org
9
---
10
target/arm/cpu.h | 38 ++++++++++++++++++++++++++++----------
11
target/arm/helper.c | 15 ++++++++-------
12
2 files changed, 36 insertions(+), 17 deletions(-)
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 @@ void pmccntr_sync(CPUARMState *env);
19
/* Mask of bits which may be set by exception return copying them from SPSR */
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
}
79
80
diff --git a/target/arm/helper.c b/target/arm/helper.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/helper.c
83
+++ b/target/arm/helper.c
84
@@ -XXX,XX +XXX,XX @@ static void v7m_push_stack(ARMCPU *cpu)
85
/* Align stack pointer if the guest wants that */
86
if ((env->regs[13] & 4) && (env->v7m.ccr & R_V7M_CCR_STKALIGN_MASK)) {
87
env->regs[13] -= 4;
88
- xpsr |= 0x200;
89
+ xpsr |= XPSR_SPREALIGN;
90
}
91
/* Switch to the handler mode. */
92
v7m_push(env, xpsr);
93
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
94
env->regs[15] &= ~1U;
95
}
96
xpsr = v7m_pop(env);
97
- xpsr_write(env, xpsr, 0xfffffdff);
98
+ xpsr_write(env, xpsr, ~XPSR_SPREALIGN);
99
/* Undo stack alignment. */
100
- if (xpsr & 0x200)
101
+ if (xpsr & XPSR_SPREALIGN) {
102
env->regs[13] |= 4;
103
+ }
104
105
/* The restored xPSR exception field will be zero if we're
106
* resuming in Thread mode. If that doesn't match what the
107
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
108
case 0 ... 7: /* xPSR sub-fields */
109
mask = 0;
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
--
134
2.7.4
135
136
diff view generated by jsdifflib
Deleted patch
1
We currently store the M profile CPU register state PRIMASK and
2
FAULTMASK in the daif field of the CPU state in its I and F
3
bits. This is a legacy from the original implementation, which
4
tried to share the cpu_exec_interrupt code between A profile
5
and M profile. We've since separated out the two cases because
6
they are significantly different, so now there is no common
7
code between M and A profile which looks at env->daif: all the
8
uses are either in A-only or M-only code paths. Sharing the state
9
fields now is just confusing, and will make things awkward
10
when we implement v8M, where the PRIMASK and FAULTMASK
11
registers are banked between security states.
12
1
13
Switch M profile over to using v7m.faultmask and v7m.primask
14
fields for these registers.
15
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Message-id: 1501692241-23310-10-git-send-email-peter.maydell@linaro.org
19
---
20
target/arm/cpu.h | 4 +++-
21
hw/intc/armv7m_nvic.c | 4 ++--
22
target/arm/cpu.c | 5 -----
23
target/arm/helper.c | 18 +++++-------------
24
target/arm/machine.c | 33 +++++++++++++++++++++++++++++++++
25
5 files changed, 43 insertions(+), 21 deletions(-)
26
27
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/cpu.h
30
+++ b/target/arm/cpu.h
31
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
32
uint32_t bfar; /* BusFault Address */
33
unsigned mpu_ctrl; /* MPU_CTRL */
34
int exception;
35
+ uint32_t primask;
36
+ uint32_t faultmask;
37
} v7m;
38
39
/* Information associated with an exception about to be taken:
40
@@ -XXX,XX +XXX,XX @@ static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
41
* we're in a HardFault or NMI handler.
42
*/
43
if ((env->v7m.exception > 0 && env->v7m.exception <= 3)
44
- || env->daif & PSTATE_F) {
45
+ || env->v7m.faultmask) {
46
return arm_to_core_mmu_idx(ARMMMUIdx_MNegPri);
47
}
48
49
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/intc/armv7m_nvic.c
52
+++ b/hw/intc/armv7m_nvic.c
53
@@ -XXX,XX +XXX,XX @@ static inline int nvic_exec_prio(NVICState *s)
54
CPUARMState *env = &s->cpu->env;
55
int running;
56
57
- if (env->daif & PSTATE_F) { /* FAULTMASK */
58
+ if (env->v7m.faultmask) {
59
running = -1;
60
- } else if (env->daif & PSTATE_I) { /* PRIMASK */
61
+ } else if (env->v7m.primask) {
62
running = 0;
63
} else if (env->v7m.basepri > 0) {
64
running = env->v7m.basepri & nvic_gprio_mask(s);
65
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/cpu.c
68
+++ b/target/arm/cpu.c
69
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
70
uint32_t initial_pc; /* Loaded from 0x4 */
71
uint8_t *rom;
72
73
- /* For M profile we store FAULTMASK and PRIMASK in the
74
- * PSTATE F and I bits; these are both clear at reset.
75
- */
76
- env->daif &= ~(PSTATE_I | PSTATE_F);
77
-
78
/* The reset value of this bit is IMPDEF, but ARM recommends
79
* that it resets to 1, so QEMU always does that rather than making
80
* it dependent on CPU model.
81
diff --git a/target/arm/helper.c b/target/arm/helper.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/helper.c
84
+++ b/target/arm/helper.c
85
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
86
87
if (env->v7m.exception != ARMV7M_EXCP_NMI) {
88
/* Auto-clear FAULTMASK on return from other than NMI */
89
- env->daif &= ~PSTATE_F;
90
+ env->v7m.faultmask = 0;
91
}
92
93
switch (armv7m_nvic_complete_irq(env->nvic, env->v7m.exception)) {
94
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
95
return (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) ?
96
env->regs[13] : env->v7m.other_sp;
97
case 16: /* PRIMASK */
98
- return (env->daif & PSTATE_I) != 0;
99
+ return env->v7m.primask;
100
case 17: /* BASEPRI */
101
case 18: /* BASEPRI_MAX */
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
- }
118
+ env->v7m.primask = val & 1;
119
break;
120
case 17: /* BASEPRI */
121
env->v7m.basepri = val & 0xff;
122
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
123
env->v7m.basepri = val;
124
break;
125
case 19: /* FAULTMASK */
126
- if (val & 1) {
127
- env->daif |= PSTATE_F;
128
- } else {
129
- env->daif &= ~PSTATE_F;
130
- }
131
+ env->v7m.faultmask = val & 1;
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
}
142
143
+static const VMStateDescription vmstate_m_faultmask_primask = {
144
+ .name = "cpu/m/faultmask-primask",
145
+ .version_id = 1,
146
+ .minimum_version_id = 1,
147
+ .fields = (VMStateField[]) {
148
+ VMSTATE_UINT32(env.v7m.faultmask, ARMCPU),
149
+ VMSTATE_UINT32(env.v7m.primask, ARMCPU),
150
+ VMSTATE_END_OF_LIST()
151
+ }
152
+};
153
+
154
static const VMStateDescription vmstate_m = {
155
.name = "cpu/m",
156
.version_id = 4,
157
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
158
VMSTATE_UINT32(env.v7m.mpu_ctrl, ARMCPU),
159
VMSTATE_INT32(env.v7m.exception, ARMCPU),
160
VMSTATE_END_OF_LIST()
161
+ },
162
+ .subsections = (const VMStateDescription*[]) {
163
+ &vmstate_m_faultmask_primask,
164
+ NULL
165
}
166
};
167
168
@@ -XXX,XX +XXX,XX @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
169
CPUARMState *env = &cpu->env;
170
uint32_t val = qemu_get_be32(f);
171
172
+ if (arm_feature(env, ARM_FEATURE_M)) {
173
+ /* If the I or F bits are set then this is a migration from
174
+ * an old QEMU which still stored the M profile FAULTMASK
175
+ * and PRIMASK in env->daif. Set v7m.faultmask and v7m.primask
176
+ * accordingly, and then clear the bits so they don't confuse
177
+ * cpsr_write(). For a new QEMU, the bits here will always be
178
+ * clear, and the data is transferred using the
179
+ * vmstate_m_faultmask_primask subsection.
180
+ */
181
+ if (val & CPSR_F) {
182
+ env->v7m.faultmask = 1;
183
+ }
184
+ if (val & CPSR_I) {
185
+ env->v7m.primask = 1;
186
+ }
187
+ val &= ~(CPSR_F | CPSR_I);
188
+ }
189
+
190
env->aarch64 = ((val & PSTATE_nRW) == 0);
191
192
if (is_a64(env)) {
193
--
194
2.7.4
195
196
diff view generated by jsdifflib
Deleted patch
1
For M profile the XPSR is a similar but not identical format to the
2
A profile CPSR/SPSR. (For instance the Thumb bit is in a different
3
place.) For guest accesses we make the M profile code go through
4
xpsr_read() and xpsr_write() which handle the different layout.
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
1
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
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 1501692241-23310-11-git-send-email-peter.maydell@linaro.org
17
---
18
target/arm/machine.c | 49 ++++++++++++++++++++++++++++++++++---------------
19
1 file changed, 34 insertions(+), 15 deletions(-)
20
21
diff --git a/target/arm/machine.c b/target/arm/machine.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/machine.c
24
+++ b/target/arm/machine.c
25
@@ -XXX,XX +XXX,XX @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
26
uint32_t val = qemu_get_be32(f);
27
28
if (arm_feature(env, ARM_FEATURE_M)) {
29
- /* If the I or F bits are set then this is a migration from
30
- * an old QEMU which still stored the M profile FAULTMASK
31
- * and PRIMASK in env->daif. Set v7m.faultmask and v7m.primask
32
- * accordingly, and then clear the bits so they don't confuse
33
- * cpsr_write(). For a new QEMU, the bits here will always be
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
}
75
76
env->aarch64 = ((val & PSTATE_nRW) == 0);
77
@@ -XXX,XX +XXX,XX @@ static int put_cpsr(QEMUFile *f, void *opaque, size_t size,
78
CPUARMState *env = &cpu->env;
79
uint32_t val;
80
81
- if (is_a64(env)) {
82
+ if (arm_feature(env, ARM_FEATURE_M)) {
83
+ /* The low 9 bits are v7m.exception, which is handled by vmstate_m. */
84
+ val = xpsr_read(env) & ~XPSR_EXCP;
85
+ } else if (is_a64(env)) {
86
val = pstate_read(env);
87
} else {
88
val = cpsr_read(env);
89
--
90
2.7.4
91
92
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
Add a utility function for testing whether the CPU is in Handler
2
mode; this is just a check whether v7m.exception is non-zero, but
3
we do it in several places and it makes the code a bit easier
4
to read to not have to mentally figure out what the test is testing.
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-14-git-send-email-peter.maydell@linaro.org
11
---
12
target/arm/cpu.h | 10 ++++++++--
13
target/arm/helper.c | 8 ++++----
14
2 files changed, 12 insertions(+), 6 deletions(-)
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 @@ static inline int arm_highest_el(CPUARMState *env)
21
return 1;
22
}
23
24
+/* Return true if a v7M CPU is in Handler mode */
25
+static inline bool arm_v7m_is_handler_mode(CPUARMState *env)
26
+{
27
+ return env->v7m.exception != 0;
28
+}
29
+
30
/* Return the current Exception Level (as per ARMv8; note that this differs
31
* from the ARMv7 Privilege Level).
32
*/
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
--
91
2.7.4
92
93
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
From: Andrew Jones <drjones@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
If a KVM PMU init or set-irq attr call fails we just silently stop
3
Cortex-M profile is only emulable from TCG accelerator. Restrict
4
the PMU DT node generation. The only way they could fail, though,
4
the GDBstub features to its availability in order to avoid a link
5
is if the attr's respective KVM has-attr call fails. But that should
5
error when TCG is not enabled:
6
never happen if KVM advertises the PMU capability, because both
7
attrs have been available since the capability was introduced. Let's
8
just abort if this should-never-happen stuff does happen, because,
9
if it does, then something is obviously horribly wrong.
10
6
11
Signed-off-by: Andrew Jones <drjones@redhat.com>
7
Undefined symbols for architecture arm64:
12
Reviewed-by: Christoffer Dall <cdall@linaro.org>
8
"_arm_v7m_get_sp_ptr", referenced from:
13
Message-id: 1500471597-2517-5-git-send-email-drjones@redhat.com
9
_m_sysreg_get in target_arm_gdbstub.c.o
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
"_arm_v7m_mrs_control", referenced from:
11
_arm_gdb_get_m_systemreg in target_arm_gdbstub.c.o
12
ld: symbol(s) not found for architecture arm64
13
clang: error: linker command failed with exit code 1 (use -v to see invocation)
14
15
Fixes: 7d8b28b8b5 ("target/arm: Implement gdbstub m-profile systemreg and secext")
16
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
19
Message-id: 20230322142902.69511-3-philmd@linaro.org
20
[PMM: add #include since I cherry-picked this patch from the series]
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
22
---
17
target/arm/kvm_arm.h | 15 ++++-----------
23
target/arm/gdbstub.c | 5 +++--
18
hw/arm/virt.c | 9 +++------
24
1 file changed, 3 insertions(+), 2 deletions(-)
19
target/arm/kvm32.c | 3 +--
20
target/arm/kvm64.c | 28 ++++++++++++++++++++--------
21
4 files changed, 28 insertions(+), 27 deletions(-)
22
25
23
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
26
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
24
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/kvm_arm.h
28
--- a/target/arm/gdbstub.c
26
+++ b/target/arm/kvm_arm.h
29
+++ b/target/arm/gdbstub.c
27
@@ -XXX,XX +XXX,XX @@ int kvm_arm_sync_mpstate_to_qemu(ARMCPU *cpu);
30
@@ -XXX,XX +XXX,XX @@
28
31
#include "cpu.h"
29
int kvm_arm_vgic_probe(void);
32
#include "exec/gdbstub.h"
30
33
#include "gdbstub/helpers.h"
31
-int kvm_arm_pmu_set_irq(CPUState *cs, int irq);
34
+#include "sysemu/tcg.h"
32
-int kvm_arm_pmu_init(CPUState *cs);
35
#include "internals.h"
33
+void kvm_arm_pmu_set_irq(CPUState *cs, int irq);
36
#include "cpregs.h"
34
+void kvm_arm_pmu_init(CPUState *cs);
37
35
38
@@ -XXX,XX +XXX,XX @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
36
#else
39
2, "arm-vfp-sysregs.xml", 0);
37
38
@@ -XXX,XX +XXX,XX @@ static inline int kvm_arm_vgic_probe(void)
39
return 0;
40
}
41
42
-static inline int kvm_arm_pmu_set_irq(CPUState *cs, int irq)
43
-{
44
- return 0;
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
}
40
}
75
}
41
}
76
42
- if (cpu_isar_feature(aa32_mve, cpu)) {
77
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
43
+ if (cpu_isar_feature(aa32_mve, cpu) && tcg_enabled()) {
78
index XXXXXXX..XXXXXXX 100644
44
gdb_register_coprocessor(cs, mve_gdb_get_reg, mve_gdb_set_reg,
79
--- a/target/arm/kvm32.c
45
1, "arm-m-profile-mve.xml", 0);
80
+++ b/target/arm/kvm32.c
81
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_hw_debug_active(CPUState *cs)
82
return false;
83
}
84
85
-int kvm_arm_pmu_set_irq(CPUState *cs, int irq)
86
+void kvm_arm_pmu_set_irq(CPUState *cs, int irq)
87
{
88
qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
89
- return 0;
90
}
91
92
int kvm_arm_pmu_init(CPUState *cs)
93
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/target/arm/kvm64.c
96
+++ b/target/arm/kvm64.c
97
@@ -XXX,XX +XXX,XX @@ static bool kvm_arm_pmu_set_attr(CPUState *cs, struct kvm_device_attr *attr)
98
99
err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr);
100
if (err != 0) {
101
+ error_report("PMU: KVM_HAS_DEVICE_ATTR: %s", strerror(-err));
102
return false;
103
}
46
}
104
47
@@ -XXX,XX +XXX,XX @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
105
err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, attr);
48
arm_gen_dynamic_sysreg_xml(cs, cs->gdb_num_regs),
106
- if (err < 0) {
49
"system-registers.xml", 0);
107
- fprintf(stderr, "KVM_SET_DEVICE_ATTR failed: %s\n",
50
108
- strerror(-err));
51
- if (arm_feature(env, ARM_FEATURE_M)) {
109
- abort();
52
+ if (arm_feature(env, ARM_FEATURE_M) && tcg_enabled()) {
110
+ if (err != 0) {
53
gdb_register_coprocessor(cs,
111
+ error_report("PMU: KVM_SET_DEVICE_ATTR: %s", strerror(-err));
54
arm_gdb_get_m_systemreg, arm_gdb_set_m_systemreg,
112
+ return false;
55
arm_gen_dynamic_m_systemreg_xml(cs, cs->gdb_num_regs),
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
--
56
--
157
2.7.4
57
2.34.1
158
58
159
59
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
From: Andrew Jeffery <andrew@aj.id.au>
2
1
3
This is required to configure differences in behaviour between the
4
AST2400 and AST2500 watchdog IPs.
5
6
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/arm/aspeed_soc.c | 2 ++
12
1 file changed, 2 insertions(+)
13
14
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/aspeed_soc.c
17
+++ b/hw/arm/aspeed_soc.c
18
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
19
object_initialize(&s->wdt[i], sizeof(s->wdt[i]), TYPE_ASPEED_WDT);
20
object_property_add_child(obj, "wdt[*]", OBJECT(&s->wdt[i]), NULL);
21
qdev_set_parent_bus(DEVICE(&s->wdt[i]), sysbus_get_default());
22
+ qdev_prop_set_uint32(DEVICE(&s->wdt[i]), "silicon-rev",
23
+ sc->info->silicon_rev);
24
}
25
26
object_initialize(&s->ftgmac100, sizeof(s->ftgmac100), TYPE_FTGMAC100);
27
--
28
2.7.4
29
30
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
Currently we have a rather half-baked setup for allowing CPUs to
2
generate exceptions on accesses to invalid memory: the CPU has a
3
cpu_unassigned_access() hook which the memory system calls in
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
1
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
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
32
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
33
---
34
include/qom/cpu.h | 22 ++++++++++++++++++++++
35
1 file changed, 22 insertions(+)
36
37
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
38
index XXXXXXX..XXXXXXX 100644
39
--- a/include/qom/cpu.h
40
+++ b/include/qom/cpu.h
41
@@ -XXX,XX +XXX,XX @@ struct TranslationBlock;
42
* @has_work: Callback for checking if there is work to do.
43
* @do_interrupt: Callback for interrupt handling.
44
* @do_unassigned_access: Callback for unassigned access handling.
45
+ * (this is deprecated: new targets should use do_transaction_failed instead)
46
* @do_unaligned_access: Callback for unaligned access handling, if
47
* the target defines #ALIGNED_ONLY.
48
+ * @do_transaction_failed: Callback for handling failed memory transactions
49
+ * (ie bus faults or external aborts; not MMU faults)
50
* @virtio_is_big_endian: Callback to return %true if a CPU which supports
51
* runtime configurable endianness is currently big-endian. Non-configurable
52
* CPUs can use the default implementation of this method. This method should
53
@@ -XXX,XX +XXX,XX @@ typedef struct CPUClass {
54
void (*do_unaligned_access)(CPUState *cpu, vaddr addr,
55
MMUAccessType access_type,
56
int mmu_idx, uintptr_t retaddr);
57
+ void (*do_transaction_failed)(CPUState *cpu, hwaddr physaddr, vaddr addr,
58
+ unsigned size, MMUAccessType access_type,
59
+ int mmu_idx, MemTxAttrs attrs,
60
+ MemTxResult response, uintptr_t retaddr);
61
bool (*virtio_is_big_endian)(CPUState *cpu);
62
int (*memory_rw_debug)(CPUState *cpu, vaddr addr,
63
uint8_t *buf, int len, bool is_write);
64
@@ -XXX,XX +XXX,XX @@ static inline void cpu_unaligned_access(CPUState *cpu, vaddr addr,
65
66
cc->do_unaligned_access(cpu, addr, access_type, mmu_idx, retaddr);
67
}
68
+
69
+static inline void cpu_transaction_failed(CPUState *cpu, hwaddr physaddr,
70
+ vaddr addr, unsigned size,
71
+ MMUAccessType access_type,
72
+ int mmu_idx, MemTxAttrs attrs,
73
+ MemTxResult response,
74
+ uintptr_t retaddr)
75
+{
76
+ CPUClass *cc = CPU_GET_CLASS(cpu);
77
+
78
+ if (cc->do_transaction_failed) {
79
+ cc->do_transaction_failed(cpu, physaddr, addr, size, access_type,
80
+ mmu_idx, attrs, response, retaddr);
81
+ }
82
+}
83
#endif
84
85
#endif /* NEED_CPU_H */
86
--
87
2.7.4
88
89
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
Deleted patch
1
Set the MachineClass flag ignore_memory_transaction_failures
2
for almost all ARM boards. This means they retain the legacy
3
behaviour that accesses to unimplemented addresses will RAZ/WI
4
rather than aborting, when a subsequent commit adds support
5
for external aborts.
6
1
7
The exceptions are:
8
* virt -- we know that guests won't try to prod devices
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
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
For the Xilinx boards:
18
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
19
---
20
hw/arm/aspeed.c | 3 +++
21
hw/arm/collie.c | 1 +
22
hw/arm/cubieboard.c | 1 +
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
49
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/aspeed.c
52
+++ b/hw/arm/aspeed.c
53
@@ -XXX,XX +XXX,XX @@ static void palmetto_bmc_class_init(ObjectClass *oc, void *data)
54
mc->no_floppy = 1;
55
mc->no_cdrom = 1;
56
mc->no_parallel = 1;
57
+ mc->ignore_memory_transaction_failures = true;
58
}
59
60
static const TypeInfo palmetto_bmc_type = {
61
@@ -XXX,XX +XXX,XX @@ static void ast2500_evb_class_init(ObjectClass *oc, void *data)
62
mc->no_floppy = 1;
63
mc->no_cdrom = 1;
64
mc->no_parallel = 1;
65
+ mc->ignore_memory_transaction_failures = true;
66
}
67
68
static const TypeInfo ast2500_evb_type = {
69
@@ -XXX,XX +XXX,XX @@ static void romulus_bmc_class_init(ObjectClass *oc, void *data)
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
79
--- a/hw/arm/collie.c
80
+++ b/hw/arm/collie.c
81
@@ -XXX,XX +XXX,XX @@ static void collie_machine_init(MachineClass *mc)
82
{
83
mc->desc = "Sharp SL-5500 (Collie) PDA (SA-1110)";
84
mc->init = collie_init;
85
+ mc->ignore_memory_transaction_failures = true;
86
}
87
88
DEFINE_MACHINE("collie", collie_machine_init)
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
--
501
2.7.4
502
503
diff view generated by jsdifflib
Deleted patch
1
We currently have some similar code in tlb_fill() and in
2
arm_cpu_do_unaligned_access() for delivering a data abort or prefetch
3
abort. We're also going to want to do the same thing to handle
4
external aborts. Factor out the common code into a new function
5
deliver_fault().
6
1
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Acked-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
---
11
target/arm/op_helper.c | 110 +++++++++++++++++++++++++------------------------
12
1 file changed, 57 insertions(+), 53 deletions(-)
13
14
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/op_helper.c
17
+++ b/target/arm/op_helper.c
18
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
19
return syn;
20
}
21
22
+static void deliver_fault(ARMCPU *cpu, vaddr addr, MMUAccessType access_type,
23
+ uint32_t fsr, uint32_t fsc, ARMMMUFaultInfo *fi)
24
+{
25
+ CPUARMState *env = &cpu->env;
26
+ int target_el;
27
+ bool same_el;
28
+ uint32_t syn, exc;
29
+
30
+ target_el = exception_target_el(env);
31
+ if (fi->stage2) {
32
+ target_el = 2;
33
+ env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
34
+ }
35
+ same_el = (arm_current_el(env) == target_el);
36
+
37
+ if (fsc == 0x3f) {
38
+ /* Caller doesn't have a long-format fault status code. This
39
+ * should only happen if this fault will never actually be reported
40
+ * to an EL that uses a syndrome register. Check that here.
41
+ * 0x3f is a (currently) reserved FSC code, in case the constructed
42
+ * syndrome does leak into the guest somehow.
43
+ */
44
+ assert(target_el != 2 && !arm_el_is_aa64(env, target_el));
45
+ }
46
+
47
+ if (access_type == MMU_INST_FETCH) {
48
+ syn = syn_insn_abort(same_el, 0, fi->s1ptw, fsc);
49
+ exc = EXCP_PREFETCH_ABORT;
50
+ } else {
51
+ syn = merge_syn_data_abort(env->exception.syndrome, target_el,
52
+ same_el, fi->s1ptw,
53
+ access_type == MMU_DATA_STORE,
54
+ fsc);
55
+ if (access_type == MMU_DATA_STORE
56
+ && arm_feature(env, ARM_FEATURE_V6)) {
57
+ fsr |= (1 << 11);
58
+ }
59
+ exc = EXCP_DATA_ABORT;
60
+ }
61
+
62
+ env->exception.vaddress = addr;
63
+ env->exception.fsr = fsr;
64
+ raise_exception(env, exc, syn, target_el);
65
+}
66
+
67
/* try to fill the TLB and return an exception if error. If retaddr is
68
* NULL, it means that the function was called in C code (i.e. not
69
* from generated code or from helper.c)
70
@@ -XXX,XX +XXX,XX @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
71
ret = arm_tlb_fill(cs, addr, access_type, mmu_idx, &fsr, &fi);
72
if (unlikely(ret)) {
73
ARMCPU *cpu = ARM_CPU(cs);
74
- CPUARMState *env = &cpu->env;
75
- uint32_t syn, exc, fsc;
76
- unsigned int target_el;
77
- bool same_el;
78
+ uint32_t fsc;
79
80
if (retaddr) {
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
--
181
2.7.4
182
183
diff view generated by jsdifflib
Deleted patch
1
For external aborts, we will want to be able to specify the EA
2
(external abort type) bit in the syndrome field. Allow callers of
3
deliver_fault() to do that by adding a field to ARMMMUFaultInfo which
4
we use when constructing the syndrome values.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
---
10
target/arm/internals.h | 2 ++
11
target/arm/op_helper.c | 10 +++++-----
12
2 files changed, 7 insertions(+), 5 deletions(-)
13
14
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/internals.h
17
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu);
19
* @s2addr: Address that caused a fault at stage 2
20
* @stage2: True if we faulted at stage 2
21
* @s1ptw: True if we faulted at stage 2 while doing a stage 1 page-table walk
22
+ * @ea: True if we should set the EA (external abort type) bit in syndrome
23
*/
24
typedef struct ARMMMUFaultInfo ARMMMUFaultInfo;
25
struct ARMMMUFaultInfo {
26
target_ulong s2addr;
27
bool stage2;
28
bool s1ptw;
29
+ bool ea;
30
};
31
32
/* Do a page table walk and add page to TLB if possible */
33
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/op_helper.c
36
+++ b/target/arm/op_helper.c
37
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(neon_tbl)(CPUARMState *env, uint32_t ireg, uint32_t def,
38
39
static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
40
unsigned int target_el,
41
- bool same_el,
42
+ bool same_el, bool ea,
43
bool s1ptw, bool is_write,
44
int fsc)
45
{
46
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
47
*/
48
if (!(template_syn & ARM_EL_ISV) || target_el != 2 || s1ptw) {
49
syn = syn_data_abort_no_iss(same_el,
50
- 0, 0, s1ptw, is_write, fsc);
51
+ ea, 0, s1ptw, is_write, fsc);
52
} else {
53
/* Fields: IL, ISV, SAS, SSE, SRT, SF and AR come from the template
54
* syndrome created at translation time.
55
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
56
*/
57
syn = syn_data_abort_with_iss(same_el,
58
0, 0, 0, 0, 0,
59
- 0, 0, s1ptw, is_write, fsc,
60
+ ea, 0, s1ptw, is_write, fsc,
61
false);
62
/* Merge the runtime syndrome with the template syndrome. */
63
syn |= template_syn;
64
@@ -XXX,XX +XXX,XX @@ static void deliver_fault(ARMCPU *cpu, vaddr addr, MMUAccessType access_type,
65
}
66
67
if (access_type == MMU_INST_FETCH) {
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
--
79
2.7.4
80
81
diff view generated by jsdifflib
Deleted patch
1
Implement the new do_transaction_failed hook for ARM, which should
2
cause the CPU to take a prefetch abort or data abort.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
---
8
target/arm/internals.h | 10 ++++++++++
9
target/arm/cpu.c | 1 +
10
target/arm/op_helper.c | 43 +++++++++++++++++++++++++++++++++++++++++++
11
3 files changed, 54 insertions(+)
12
13
diff --git a/target/arm/internals.h b/target/arm/internals.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/internals.h
16
+++ b/target/arm/internals.h
17
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
18
MMUAccessType access_type,
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
}
53
54
+/* arm_cpu_do_transaction_failed: handle a memory system error response
55
+ * (eg "no device/memory present at address") by raising an external abort
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
+{
64
+ ARMCPU *cpu = ARM_CPU(cs);
65
+ CPUARMState *env = &cpu->env;
66
+ uint32_t fsr, fsc;
67
+ ARMMMUFaultInfo fi = {};
68
+ ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
69
+
70
+ if (retaddr) {
71
+ /* now we have a real cpu fault */
72
+ cpu_restore_state(cs, retaddr);
73
+ }
74
+
75
+ /* The EA bit in syndromes and fault status registers is an
76
+ * IMPDEF classification of external aborts. ARM implementations
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
+}
96
+
97
#endif /* !defined(CONFIG_USER_ONLY) */
98
99
uint32_t HELPER(add_setq)(CPUARMState *env, uint32_t a, uint32_t b)
100
--
101
2.7.4
102
103
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: Thomas Huth <thuth@redhat.com>
2
1
3
QEMU currently shows some unexpected behavior when the user trys to
4
do a "device_add digic" on an unrelated ARM machine like integratorcp
5
in "-nographic" mode (the device_add command does not immediately
6
return to the monitor prompt), and trying to "device_del" the device
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
13
Signed-off-by: Thomas Huth <thuth@redhat.com>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/arm/digic.c | 2 ++
18
1 file changed, 2 insertions(+)
19
20
diff --git a/hw/arm/digic.c b/hw/arm/digic.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/digic.c
23
+++ b/hw/arm/digic.c
24
@@ -XXX,XX +XXX,XX @@ static void digic_class_init(ObjectClass *oc, void *data)
25
DeviceClass *dc = DEVICE_CLASS(oc);
26
27
dc->realize = digic_realize;
28
+ /* Reason: Uses serial_hds in the realize function --> not usable twice */
29
+ dc->user_creatable = false;
30
}
31
32
static const TypeInfo digic_type_info = {
33
--
34
2.7.4
35
36
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
For "ldp x0, x1, [x0]", if the second load is on a second page and
4
the second page is unmapped, the exception would be raised with x0
5
already modified. This means the instruction couldn't be restarted.
6
7
Cc: qemu-arm@nongnu.org
8
Cc: qemu-stable@nongnu.org
9
Reported-by: Andrew <andrew@fubar.geek.nz>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20170825224833.4463-1-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>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
target/arm/translate-a64.c | 29 +++++++++++++++++------------
19
1 file changed, 17 insertions(+), 12 deletions(-)
20
21
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/translate-a64.c
24
+++ b/target/arm/translate-a64.c
25
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn)
26
} else {
27
do_fp_st(s, rt, tcg_addr, size);
28
}
29
- } else {
30
- TCGv_i64 tcg_rt = cpu_reg(s, rt);
31
- if (is_load) {
32
- do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false,
33
- false, 0, false, false);
34
- } else {
35
- do_gpr_st(s, tcg_rt, tcg_addr, size,
36
- false, 0, false, false);
37
- }
38
- }
39
- tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
40
- if (is_vector) {
41
+ tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
42
if (is_load) {
43
do_fp_ld(s, rt2, tcg_addr, size);
44
} else {
45
do_fp_st(s, rt2, tcg_addr, size);
46
}
47
} else {
48
+ TCGv_i64 tcg_rt = cpu_reg(s, rt);
49
TCGv_i64 tcg_rt2 = cpu_reg(s, rt2);
50
+
51
if (is_load) {
52
+ TCGv_i64 tmp = tcg_temp_new_i64();
53
+
54
+ /* Do not modify tcg_rt before recognizing any exception
55
+ * from the second load.
56
+ */
57
+ do_gpr_ld(s, tmp, tcg_addr, size, is_signed, false,
58
+ false, 0, false, false);
59
+ tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
60
do_gpr_ld(s, tcg_rt2, tcg_addr, size, is_signed, false,
61
false, 0, false, false);
62
+
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
--
73
2.7.4
74
75
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