1
First arm pullreq of the 2.11 cycle. I know I still have some
1
target-arm queue: mostly patches from me this time round.
2
more stuff on my queue to review, but 36 patches is big enough
2
Nothing too exciting.
3
as it is; I expect I'll do another pull later this week.
4
3
5
thanks
6
-- PMM
4
-- PMM
7
5
8
The following changes since commit 32f0f68bb77289b75a82925f712bb52e16eac3ba:
6
The following changes since commit 78ac2eebbab9150edf5d0d00e3648f5ebb599001:
9
7
10
Merge remote-tracking branch 'remotes/ehabkost/tags/x86-and-machine-pull-request' into staging (2017-09-01 17:28:54 +0100)
8
Merge tag 'artist-cursor-fix-final-pull-request' of https://github.com/hdeller/qemu-hppa into staging (2022-05-18 09:32:15 -0700)
11
9
12
are available in the git repository at:
10
are available in the Git repository at:
13
11
14
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20170904
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220519
15
13
16
for you to fetch changes up to 1e35c4ce33a94cf78dbf639695cb877ef35920b0:
14
for you to fetch changes up to fab8ad39fb75a0d9f097db67b2a334444754e88e:
17
15
18
arm_gicv3_kvm: Fix compile warning (2017-09-04 12:09:32 +0100)
16
target/arm: Use FIELD definitions for CPACR, CPTR_ELx (2022-05-19 18:34:10 +0100)
19
17
20
----------------------------------------------------------------
18
----------------------------------------------------------------
21
target-arm:
19
target-arm queue:
22
* collection of M profile cleanups and minor bugfixes
20
* Implement FEAT_S2FWB
23
* loader: handle ELF files with overlapping zero-init data
21
* Implement FEAT_IDST
24
* virt: allow PMU instantiation with userspace irqchip
22
* Drop unsupported_encoding() macro
25
* wdt_aspeed: Add support for the reset width register
23
* hw/intc/arm_gicv3: Use correct number of priority bits for the CPU
26
* cpu: Define new cpu_transaction_failed() hook
24
* Fix aarch64 debug register names
27
* arm: Support generating CPU exceptions on memory
25
* hw/adc/zynq-xadc: Use qemu_irq typedef
28
transaction failures (bus faults)
26
* target/arm/helper.c: Delete stray obsolete comment
29
* Mark some SoC devices as not user-creatable
27
* Make number of counters in PMCR follow the CPU
30
* arm: Fix aa64 ldp register writeback
28
* hw/arm/virt: Fix dtb nits
31
* arm_gicv3_kvm: Fix compile warning
29
* ptimer: Rename PTIMER_POLICY_DEFAULT to PTIMER_POLICY_LEGACY
30
* target/arm: Fix PAuth keys access checks for disabled SEL2
31
* Enable FEAT_HCX for -cpu max
32
* Use FIELD definitions for CPACR, CPTR_ELx
32
33
33
----------------------------------------------------------------
34
----------------------------------------------------------------
34
Andrew Jeffery (2):
35
Chris Howard (1):
35
watchdog: wdt_aspeed: Add support for the reset width register
36
Fix aarch64 debug register names.
36
aspeed_soc: Propagate silicon-rev to watchdog
37
37
38
Andrew Jones (4):
38
Florian Lugou (1):
39
hw/arm/virt: add pmu interrupt state
39
target/arm: Fix PAuth keys access checks for disabled SEL2
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
40
44
Peter Maydell (25):
41
Peter Maydell (17):
45
target/arm: Use MMUAccessType enum rather than int
42
target/arm: Postpone interpretation of stage 2 descriptor attribute bits
46
target/arm: Don't trap WFI/WFE for M profile
43
target/arm: Factor out FWB=0 specific part of combine_cacheattrs()
47
target/arm: Consolidate PMSA handling in get_phys_addr()
44
target/arm: Implement FEAT_S2FWB
48
target/arm: Tighten up Thumb decode where new v8M insns will be
45
target/arm: Enable FEAT_S2FWB for -cpu max
49
hw/intc/armv7m_nvic.c: Remove out of date comment
46
target/arm: Implement FEAT_IDST
50
target/arm: Remove incorrect comment about MPU_CTRL
47
target/arm: Drop unsupported_encoding() macro
51
target/arm: Fix outdated comment about exception exit
48
hw/intc/arm_gicv3_cpuif: Handle CPUs that don't specify GICv3 parameters
52
target/arm: Define and use XPSR bit masks
49
hw/intc/arm_gicv3: report correct PRIbits field in ICV_CTLR_EL1
53
target/arm: Don't store M profile PRIMASK and FAULTMASK in daif
50
hw/intc/arm_gicv3_kvm.c: Stop using GIC_MIN_BPR constant
54
target/arm: Don't use cpsr_write/cpsr_read to transfer M profile XPSR
51
hw/intc/arm_gicv3: Support configurable number of physical priority bits
55
target/arm: Make arm_cpu_dump_state() handle the M-profile XPSR
52
hw/intc/arm_gicv3: Use correct number of priority bits for the CPU
56
target/arm: Don't calculate lr in arm_v7m_cpu_do_interrupt() until needed
53
hw/intc/arm_gicv3: Provide ich_num_aprs()
57
target/arm: Create and use new function arm_v7m_is_handler_mode()
54
target/arm/helper.c: Delete stray obsolete comment
58
armv7m_nvic.h: Move from include/hw/arm to include/hw/intc
55
target/arm: Make number of counters in PMCR follow the CPU
59
nvic: Implement "user accesses BusFault" SCS region behaviour
56
hw/arm/virt: Fix incorrect non-secure flash dtb node name
60
loader: Handle ELF files with overlapping zero-initialized data
57
hw/arm/virt: Drop #size-cells and #address-cells from gpio-keys dtb node
61
loader: Ignore zero-sized ELF segments
58
ptimer: Rename PTIMER_POLICY_DEFAULT to PTIMER_POLICY_LEGACY
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
59
71
Philippe Mathieu-Daudé (1):
60
Philippe Mathieu-Daudé (1):
72
hw/arm: use defined type name instead of hard-coded string
61
hw/adc/zynq-xadc: Use qemu_irq typedef
73
62
74
Pranith Kumar (1):
63
Richard Henderson (2):
75
arm_gicv3_kvm: Fix compile warning
64
target/arm: Enable FEAT_HCX for -cpu max
65
target/arm: Use FIELD definitions for CPACR, CPTR_ELx
76
66
77
Richard Henderson (1):
67
docs/system/arm/emulation.rst | 2 +
78
target/arm: Fix aa64 ldp register writeback
68
include/hw/adc/zynq-xadc.h | 3 +-
69
include/hw/intc/arm_gicv3_common.h | 8 +-
70
include/hw/ptimer.h | 16 +-
71
target/arm/cpregs.h | 24 +++
72
target/arm/cpu.h | 76 +++++++-
73
target/arm/internals.h | 11 +-
74
target/arm/translate-a64.h | 9 -
75
hw/adc/zynq-xadc.c | 4 +-
76
hw/arm/boot.c | 2 +-
77
hw/arm/musicpal.c | 2 +-
78
hw/arm/virt.c | 4 +-
79
hw/core/machine.c | 4 +-
80
hw/dma/xilinx_axidma.c | 2 +-
81
hw/dma/xlnx_csu_dma.c | 2 +-
82
hw/intc/arm_gicv3_common.c | 5 +
83
hw/intc/arm_gicv3_cpuif.c | 225 +++++++++++++++++-------
84
hw/intc/arm_gicv3_kvm.c | 16 +-
85
hw/m68k/mcf5206.c | 2 +-
86
hw/m68k/mcf5208.c | 2 +-
87
hw/net/can/xlnx-zynqmp-can.c | 2 +-
88
hw/net/fsl_etsec/etsec.c | 2 +-
89
hw/net/lan9118.c | 2 +-
90
hw/rtc/exynos4210_rtc.c | 4 +-
91
hw/timer/allwinner-a10-pit.c | 2 +-
92
hw/timer/altera_timer.c | 2 +-
93
hw/timer/arm_timer.c | 2 +-
94
hw/timer/digic-timer.c | 2 +-
95
hw/timer/etraxfs_timer.c | 6 +-
96
hw/timer/exynos4210_mct.c | 6 +-
97
hw/timer/exynos4210_pwm.c | 2 +-
98
hw/timer/grlib_gptimer.c | 2 +-
99
hw/timer/imx_epit.c | 4 +-
100
hw/timer/imx_gpt.c | 2 +-
101
hw/timer/mss-timer.c | 2 +-
102
hw/timer/sh_timer.c | 2 +-
103
hw/timer/slavio_timer.c | 2 +-
104
hw/timer/xilinx_timer.c | 2 +-
105
target/arm/cpu.c | 11 +-
106
target/arm/cpu64.c | 30 ++++
107
target/arm/cpu_tcg.c | 6 +
108
target/arm/helper.c | 348 ++++++++++++++++++++++++++++---------
109
target/arm/kvm64.c | 12 ++
110
target/arm/op_helper.c | 9 +
111
target/arm/translate-a64.c | 36 +++-
112
tests/unit/ptimer-test.c | 6 +-
113
46 files changed, 697 insertions(+), 228 deletions(-)
79
114
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
1
For external aborts, we will want to be able to specify the EA
1
In the original Arm v8 two-stage translation, both stage 1 and stage
2
(external abort type) bit in the syndrome field. Allow callers of
2
2 specify memory attributes (memory type, cacheability,
3
deliver_fault() to do that by adding a field to ARMMMUFaultInfo which
3
shareability); these are then combined to produce the overall memory
4
we use when constructing the syndrome values.
4
attributes for the whole stage 1+2 access. In QEMU we implement this
5
by having get_phys_addr() fill in an ARMCacheAttrs struct, and we
6
convert both the stage 1 and stage 2 attribute bit formats to the
7
same encoding (an 8-bit attribute value matching the MAIR_EL1 fields,
8
plus a 2-bit shareability value).
9
10
The new FEAT_S2FWB feature allows the guest to enable a different
11
interpretation of the attribute bits in the stage 2 descriptors.
12
These bits can now be used to control details of how the stage 1 and
13
2 attributes should be combined (for instance they can say "always
14
use the stage 1 attributes" or "ignore the stage 1 attributes and
15
always be Device memory"). This means we need to pass the raw bit
16
information for stage 2 down to the function which combines the stage
17
1 and stage 2 information.
18
19
Add a field to ARMCacheAttrs that indicates whether the attrs field
20
should be interpreted as MAIR format, or as the raw stage 2 attribute
21
bits from the descriptor, and store the appropriate values when
22
filling in cacheattrs.
23
24
We only need to interpret the attrs field in a few places:
25
* in do_ats_write(), where we know to expect a MAIR value
26
(there is no ATS instruction to do a stage-2-only walk)
27
* in S1_ptw_translate(), where we want to know whether the
28
combined S1 + S2 attributes indicate Device memory that
29
should provoke a fault
30
* in combine_cacheattrs(), which does the S1 + S2 combining
31
Update those places accordingly.
5
32
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
34
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
35
Message-id: 20220505183950.2781801-2-peter.maydell@linaro.org
9
---
36
---
10
target/arm/internals.h | 2 ++
37
target/arm/internals.h | 7 ++++++-
11
target/arm/op_helper.c | 10 +++++-----
38
target/arm/helper.c | 42 ++++++++++++++++++++++++++++++++++++------
12
2 files changed, 7 insertions(+), 5 deletions(-)
39
2 files changed, 42 insertions(+), 7 deletions(-)
13
40
14
diff --git a/target/arm/internals.h b/target/arm/internals.h
41
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/internals.h
43
--- a/target/arm/internals.h
17
+++ b/target/arm/internals.h
44
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu);
45
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
19
* @s2addr: Address that caused a fault at stage 2
46
20
* @stage2: True if we faulted at stage 2
47
/* Cacheability and shareability attributes for a memory access */
21
* @s1ptw: True if we faulted at stage 2 while doing a stage 1 page-table walk
48
typedef struct ARMCacheAttrs {
22
+ * @ea: True if we should set the EA (external abort type) bit in syndrome
49
- unsigned int attrs:8; /* as in the MAIR register encoding */
50
+ /*
51
+ * If is_s2_format is true, attrs is the S2 descriptor bits [5:2]
52
+ * Otherwise, attrs is the same as the MAIR_EL1 8-bit format
53
+ */
54
+ unsigned int attrs:8;
55
unsigned int shareability:2; /* as in the SH field of the VMSAv8-64 PTEs */
56
+ bool is_s2_format:1;
57
} ARMCacheAttrs;
58
59
bool get_phys_addr(CPUARMState *env, target_ulong address,
60
diff --git a/target/arm/helper.c b/target/arm/helper.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/helper.c
63
+++ b/target/arm/helper.c
64
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
65
ret = get_phys_addr(env, value, access_type, mmu_idx, &phys_addr, &attrs,
66
&prot, &page_size, &fi, &cacheattrs);
67
68
+ /*
69
+ * ATS operations only do S1 or S1+S2 translations, so we never
70
+ * have to deal with the ARMCacheAttrs format for S2 only.
71
+ */
72
+ assert(!cacheattrs.is_s2_format);
73
+
74
if (ret) {
75
/*
76
* Some kinds of translation fault must cause exceptions rather
77
@@ -XXX,XX +XXX,XX @@ static bool get_level1_table_address(CPUARMState *env, ARMMMUIdx mmu_idx,
78
return true;
79
}
80
81
+static bool ptw_attrs_are_device(CPUARMState *env, ARMCacheAttrs cacheattrs)
82
+{
83
+ /*
84
+ * For an S1 page table walk, the stage 1 attributes are always
85
+ * some form of "this is Normal memory". The combined S1+S2
86
+ * attributes are therefore only Device if stage 2 specifies Device.
87
+ * With HCR_EL2.FWB == 0 this is when descriptor bits [5:4] are 0b00,
88
+ * ie when cacheattrs.attrs bits [3:2] are 0b00.
89
+ */
90
+ assert(cacheattrs.is_s2_format);
91
+ return (cacheattrs.attrs & 0xc) == 0;
92
+}
93
+
94
/* Translate a S1 pagetable walk through S2 if needed. */
95
static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
96
hwaddr addr, bool *is_secure,
97
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
98
return ~0;
99
}
100
if ((arm_hcr_el2_eff(env) & HCR_PTW) &&
101
- (cacheattrs.attrs & 0xf0) == 0) {
102
+ ptw_attrs_are_device(env, cacheattrs)) {
103
/*
104
* PTW set and S1 walk touched S2 Device memory:
105
* generate Permission fault.
106
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
107
}
108
109
if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
110
- cacheattrs->attrs = convert_stage2_attrs(env, extract32(attrs, 0, 4));
111
+ cacheattrs->is_s2_format = true;
112
+ cacheattrs->attrs = extract32(attrs, 0, 4);
113
} else {
114
/* Index into MAIR registers for cache attributes */
115
uint8_t attrindx = extract32(attrs, 0, 3);
116
uint64_t mair = env->cp15.mair_el[regime_el(env, mmu_idx)];
117
assert(attrindx <= 7);
118
+ cacheattrs->is_s2_format = false;
119
cacheattrs->attrs = extract64(mair, attrindx * 8, 8);
120
}
121
122
@@ -XXX,XX +XXX,XX @@ static uint8_t combine_cacheattr_nibble(uint8_t s1, uint8_t s2)
123
/* Combine S1 and S2 cacheability/shareability attributes, per D4.5.4
124
* and CombineS1S2Desc()
125
*
126
+ * @env: CPUARMState
127
* @s1: Attributes from stage 1 walk
128
* @s2: Attributes from stage 2 walk
23
*/
129
*/
24
typedef struct ARMMMUFaultInfo ARMMMUFaultInfo;
130
-static ARMCacheAttrs combine_cacheattrs(ARMCacheAttrs s1, ARMCacheAttrs s2)
25
struct ARMMMUFaultInfo {
131
+static ARMCacheAttrs combine_cacheattrs(CPUARMState *env,
26
target_ulong s2addr;
132
+ ARMCacheAttrs s1, ARMCacheAttrs s2)
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
{
133
{
46
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
134
uint8_t s1lo, s2lo, s1hi, s2hi;
47
*/
135
ARMCacheAttrs ret;
48
if (!(template_syn & ARM_EL_ISV) || target_el != 2 || s1ptw) {
136
bool tagged = false;
49
syn = syn_data_abort_no_iss(same_el,
137
+ uint8_t s2_mair_attrs;
50
- 0, 0, s1ptw, is_write, fsc);
138
+
51
+ ea, 0, s1ptw, is_write, fsc);
139
+ assert(s2.is_s2_format && !s1.is_s2_format);
52
} else {
140
+ ret.is_s2_format = false;
53
/* Fields: IL, ISV, SAS, SSE, SRT, SF and AR come from the template
141
+
54
* syndrome created at translation time.
142
+ s2_mair_attrs = convert_stage2_attrs(env, s2.attrs);
55
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
143
56
*/
144
if (s1.attrs == 0xf0) {
57
syn = syn_data_abort_with_iss(same_el,
145
tagged = true;
58
0, 0, 0, 0, 0,
146
@@ -XXX,XX +XXX,XX @@ static ARMCacheAttrs combine_cacheattrs(ARMCacheAttrs s1, ARMCacheAttrs s2)
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
}
147
}
66
148
67
if (access_type == MMU_INST_FETCH) {
149
s1lo = extract32(s1.attrs, 0, 4);
68
- syn = syn_insn_abort(same_el, 0, fi->s1ptw, fsc);
150
- s2lo = extract32(s2.attrs, 0, 4);
69
+ syn = syn_insn_abort(same_el, fi->ea, fi->s1ptw, fsc);
151
+ s2lo = extract32(s2_mair_attrs, 0, 4);
70
exc = EXCP_PREFETCH_ABORT;
152
s1hi = extract32(s1.attrs, 4, 4);
71
} else {
153
- s2hi = extract32(s2.attrs, 4, 4);
72
syn = merge_syn_data_abort(env->exception.syndrome, target_el,
154
+ s2hi = extract32(s2_mair_attrs, 4, 4);
73
- same_el, fi->s1ptw,
155
74
+ same_el, fi->ea, fi->s1ptw,
156
/* Combine shareability attributes (table D4-43) */
75
access_type == MMU_DATA_STORE,
157
if (s1.shareability == 2 || s2.shareability == 2) {
76
fsc);
158
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
77
if (access_type == MMU_DATA_STORE
159
}
160
cacheattrs->shareability = 0;
161
}
162
- *cacheattrs = combine_cacheattrs(*cacheattrs, cacheattrs2);
163
+ *cacheattrs = combine_cacheattrs(env, *cacheattrs, cacheattrs2);
164
165
/* Check if IPA translates to secure or non-secure PA space. */
166
if (arm_is_secure_below_el3(env)) {
167
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
168
/* Fill in cacheattr a-la AArch64.TranslateAddressS1Off. */
169
hcr = arm_hcr_el2_eff(env);
170
cacheattrs->shareability = 0;
171
+ cacheattrs->is_s2_format = false;
172
if (hcr & HCR_DC) {
173
if (hcr & HCR_DCT) {
174
memattr = 0xf0; /* Tagged, Normal, WB, RWA */
78
--
175
--
79
2.7.4
176
2.25.1
80
81
diff view generated by jsdifflib
1
The ARMv7M architecture specifies that most of the addresses in the
1
Factor out the part of combine_cacheattrs() that is specific to
2
PPB region (which includes the NVIC, systick and system registers)
2
handling HCR_EL2.FWB == 0. This is the part where we combine the
3
are not accessible to unprivileged accesses, which should
3
memory type and cacheability attributes.
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
4
9
Implement this by switching the register access functions
5
The "force Outer Shareable for Device or Normal Inner-NC Outer-NC"
10
to the _with_attrs scheme that lets us distinguish user
6
logic remains in combine_cacheattrs() because it holds regardless
11
mode accesses.
7
(this is the equivalent of the pseudocode EffectiveShareability()
12
8
function).
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
9
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
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>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Message-id: 1501692241-23310-16-git-send-email-peter.maydell@linaro.org
12
Message-id: 20220505183950.2781801-3-peter.maydell@linaro.org
25
---
13
---
26
hw/intc/armv7m_nvic.c | 58 ++++++++++++++++++++++++++++++++++++---------------
14
target/arm/helper.c | 88 +++++++++++++++++++++++++--------------------
27
1 file changed, 41 insertions(+), 17 deletions(-)
15
1 file changed, 50 insertions(+), 38 deletions(-)
28
16
29
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
30
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/intc/armv7m_nvic.c
19
--- a/target/arm/helper.c
32
+++ b/hw/intc/armv7m_nvic.c
20
+++ b/target/arm/helper.c
33
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
21
@@ -XXX,XX +XXX,XX @@ static uint8_t combine_cacheattr_nibble(uint8_t s1, uint8_t s2)
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
}
22
}
48
}
23
}
49
24
50
-static uint64_t nvic_sysreg_read(void *opaque, hwaddr addr,
25
+/*
51
- unsigned size)
26
+ * Combine the memory type and cacheability attributes of
52
+static bool nvic_user_access_ok(NVICState *s, hwaddr offset)
27
+ * s1 and s2 for the HCR_EL2.FWB == 0 case, returning the
28
+ * combined attributes in MAIR_EL1 format.
29
+ */
30
+static uint8_t combined_attrs_nofwb(CPUARMState *env,
31
+ ARMCacheAttrs s1, ARMCacheAttrs s2)
53
+{
32
+{
54
+ /* Return true if unprivileged access to this register is permitted. */
33
+ uint8_t s1lo, s2lo, s1hi, s2hi, s2_mair_attrs, ret_attrs;
55
+ switch (offset) {
34
+
56
+ case 0xf00: /* STIR: accessible only if CCR.USERSETMPEND permits */
35
+ s2_mair_attrs = convert_stage2_attrs(env, s2.attrs);
57
+ return s->cpu->env.v7m.ccr & R_V7M_CCR_USERSETMPEND_MASK;
36
+
58
+ default:
37
+ s1lo = extract32(s1.attrs, 0, 4);
59
+ /* All other user accesses cause a BusFault unconditionally */
38
+ s2lo = extract32(s2_mair_attrs, 0, 4);
60
+ return false;
39
+ s1hi = extract32(s1.attrs, 4, 4);
40
+ s2hi = extract32(s2_mair_attrs, 4, 4);
41
+
42
+ /* Combine memory type and cacheability attributes */
43
+ if (s1hi == 0 || s2hi == 0) {
44
+ /* Device has precedence over normal */
45
+ if (s1lo == 0 || s2lo == 0) {
46
+ /* nGnRnE has precedence over anything */
47
+ ret_attrs = 0;
48
+ } else if (s1lo == 4 || s2lo == 4) {
49
+ /* non-Reordering has precedence over Reordering */
50
+ ret_attrs = 4; /* nGnRE */
51
+ } else if (s1lo == 8 || s2lo == 8) {
52
+ /* non-Gathering has precedence over Gathering */
53
+ ret_attrs = 8; /* nGRE */
54
+ } else {
55
+ ret_attrs = 0xc; /* GRE */
56
+ }
57
+ } else { /* Normal memory */
58
+ /* Outer/inner cacheability combine independently */
59
+ ret_attrs = combine_cacheattr_nibble(s1hi, s2hi) << 4
60
+ | combine_cacheattr_nibble(s1lo, s2lo);
61
+ }
61
+ }
62
+ return ret_attrs;
62
+}
63
+}
63
+
64
+
64
+static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
65
/* Combine S1 and S2 cacheability/shareability attributes, per D4.5.4
65
+ uint64_t *data, unsigned size,
66
* and CombineS1S2Desc()
66
+ MemTxAttrs attrs)
67
*
68
@@ -XXX,XX +XXX,XX @@ static uint8_t combine_cacheattr_nibble(uint8_t s1, uint8_t s2)
69
static ARMCacheAttrs combine_cacheattrs(CPUARMState *env,
70
ARMCacheAttrs s1, ARMCacheAttrs s2)
67
{
71
{
68
NVICState *s = (NVICState *)opaque;
72
- uint8_t s1lo, s2lo, s1hi, s2hi;
69
uint32_t offset = addr;
73
ARMCacheAttrs ret;
70
unsigned i, startvec, end;
74
bool tagged = false;
71
uint32_t val;
75
- uint8_t s2_mair_attrs;
72
76
73
+ if (attrs.user && !nvic_user_access_ok(s, addr)) {
77
assert(s2.is_s2_format && !s1.is_s2_format);
74
+ /* Generate BusFault for unprivileged accesses */
78
ret.is_s2_format = false;
75
+ return MEMTX_ERROR;
79
76
+ }
80
- s2_mair_attrs = convert_stage2_attrs(env, s2.attrs);
77
+
81
-
78
switch (offset) {
82
if (s1.attrs == 0xf0) {
79
/* reads of set and clear both return the status */
83
tagged = true;
80
case 0x100 ... 0x13f: /* NVIC Set enable */
84
s1.attrs = 0xff;
81
@@ -XXX,XX +XXX,XX @@ static uint64_t nvic_sysreg_read(void *opaque, hwaddr addr,
82
}
85
}
83
86
84
trace_nvic_sysreg_read(addr, val, size);
87
- s1lo = extract32(s1.attrs, 0, 4);
85
- return val;
88
- s2lo = extract32(s2_mair_attrs, 0, 4);
86
+ *data = val;
89
- s1hi = extract32(s1.attrs, 4, 4);
87
+ return MEMTX_OK;
90
- s2hi = extract32(s2_mair_attrs, 4, 4);
88
}
91
-
89
92
/* Combine shareability attributes (table D4-43) */
90
-static void nvic_sysreg_write(void *opaque, hwaddr addr,
93
if (s1.shareability == 2 || s2.shareability == 2) {
91
- uint64_t value, unsigned size)
94
/* if either are outer-shareable, the result is outer-shareable */
92
+static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
95
@@ -XXX,XX +XXX,XX @@ static ARMCacheAttrs combine_cacheattrs(CPUARMState *env,
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
}
96
}
146
if (size == 4) {
97
147
nvic_writel(s, offset, value);
98
/* Combine memory type and cacheability attributes */
148
- return;
99
- if (s1hi == 0 || s2hi == 0) {
149
+ return MEMTX_OK;
100
- /* Device has precedence over normal */
101
- if (s1lo == 0 || s2lo == 0) {
102
- /* nGnRnE has precedence over anything */
103
- ret.attrs = 0;
104
- } else if (s1lo == 4 || s2lo == 4) {
105
- /* non-Reordering has precedence over Reordering */
106
- ret.attrs = 4; /* nGnRE */
107
- } else if (s1lo == 8 || s2lo == 8) {
108
- /* non-Gathering has precedence over Gathering */
109
- ret.attrs = 8; /* nGRE */
110
- } else {
111
- ret.attrs = 0xc; /* GRE */
112
- }
113
+ ret.attrs = combined_attrs_nofwb(env, s1, s2);
114
115
- /* Any location for which the resultant memory type is any
116
- * type of Device memory is always treated as Outer Shareable.
117
- */
118
+ /*
119
+ * Any location for which the resultant memory type is any
120
+ * type of Device memory is always treated as Outer Shareable.
121
+ * Any location for which the resultant memory type is Normal
122
+ * Inner Non-cacheable, Outer Non-cacheable is always treated
123
+ * as Outer Shareable.
124
+ * TODO: FEAT_XS adds another value (0x40) also meaning iNCoNC
125
+ */
126
+ if ((ret.attrs & 0xf0) == 0 || ret.attrs == 0x44) {
127
ret.shareability = 2;
128
- } else { /* Normal memory */
129
- /* Outer/inner cacheability combine independently */
130
- ret.attrs = combine_cacheattr_nibble(s1hi, s2hi) << 4
131
- | combine_cacheattr_nibble(s1lo, s2lo);
132
-
133
- if (ret.attrs == 0x44) {
134
- /* Any location for which the resultant memory type is Normal
135
- * Inner Non-cacheable, Outer Non-cacheable is always treated
136
- * as Outer Shareable.
137
- */
138
- ret.shareability = 2;
139
- }
150
}
140
}
151
qemu_log_mask(LOG_GUEST_ERROR,
141
152
"NVIC: Bad write of size %d at offset 0x%x\n", size, offset);
142
/* TODO: CombineS1S2Desc does not consider transient, only WB, RWA. */
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
--
143
--
166
2.7.4
144
2.25.1
167
168
diff view generated by jsdifflib
1
Add a utility function for testing whether the CPU is in Handler
1
Implement the handling of FEAT_S2FWB; the meat of this is in the new
2
mode; this is just a check whether v7m.exception is non-zero, but
2
combined_attrs_fwb() function which combines S1 and S2 attributes
3
we do it in several places and it makes the code a bit easier
3
when HCR_EL2.FWB is set.
4
to read to not have to mentally figure out what the test is testing.
5
4
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
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>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 1501692241-23310-14-git-send-email-peter.maydell@linaro.org
7
Message-id: 20220505183950.2781801-4-peter.maydell@linaro.org
11
---
8
---
12
target/arm/cpu.h | 10 ++++++++--
9
target/arm/cpu.h | 5 +++
13
target/arm/helper.c | 8 ++++----
10
target/arm/helper.c | 84 +++++++++++++++++++++++++++++++++++++++++++--
14
2 files changed, 12 insertions(+), 6 deletions(-)
11
2 files changed, 86 insertions(+), 3 deletions(-)
15
12
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
15
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
16
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ static inline int arm_highest_el(CPUARMState *env)
17
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_st(const ARMISARegisters *id)
21
return 1;
18
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, ST) != 0;
22
}
19
}
23
20
24
+/* Return true if a v7M CPU is in Handler mode */
21
+static inline bool isar_feature_aa64_fwb(const ARMISARegisters *id)
25
+static inline bool arm_v7m_is_handler_mode(CPUARMState *env)
26
+{
22
+{
27
+ return env->v7m.exception != 0;
23
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, FWB) != 0;
28
+}
24
+}
29
+
25
+
30
/* Return the current Exception Level (as per ARMv8; note that this differs
26
static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
31
* from the ARMv7 Privilege Level).
32
*/
33
static inline int arm_current_el(CPUARMState *env)
34
{
27
{
35
if (arm_feature(env, ARM_FEATURE_M)) {
28
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
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
29
diff --git a/target/arm/helper.c b/target/arm/helper.c
51
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/helper.c
31
--- a/target/arm/helper.c
53
+++ b/target/arm/helper.c
32
+++ b/target/arm/helper.c
54
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
33
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
55
* that jumps to magic addresses don't have magic behaviour unless
34
if (cpu_isar_feature(aa64_scxtnum, cpu)) {
56
* we're in Handler mode (compare pseudocode BXWritePC()).
35
valid_mask |= HCR_ENSCXT;
36
}
37
+ if (cpu_isar_feature(aa64_fwb, cpu)) {
38
+ valid_mask |= HCR_FWB;
39
+ }
40
}
41
42
/* Clear RES0 bits. */
43
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
44
* HCR_PTW forbids certain page-table setups
45
* HCR_DC disables stage1 and enables stage2 translation
46
* HCR_DCT enables tagging on (disabled) stage1 translation
47
+ * HCR_FWB changes the interpretation of stage2 descriptor bits
57
*/
48
*/
58
- assert(env->v7m.exception != 0);
49
- if ((env->cp15.hcr_el2 ^ value) & (HCR_VM | HCR_PTW | HCR_DC | HCR_DCT)) {
59
+ assert(arm_v7m_is_handler_mode(env));
50
+ if ((env->cp15.hcr_el2 ^ value) &
60
51
+ (HCR_VM | HCR_PTW | HCR_DC | HCR_DCT | HCR_FWB)) {
61
/* In the spec pseudocode ExceptionReturn() is called directly
52
tlb_flush(CPU(cpu));
62
* from BXWritePC() and gets the full target PC value including
53
}
63
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
54
env->cp15.hcr_el2 = value;
64
* resuming in Thread mode. If that doesn't match what the
55
@@ -XXX,XX +XXX,XX @@ static bool ptw_attrs_are_device(CPUARMState *env, ARMCacheAttrs cacheattrs)
65
* exception return type specified then this is a UsageFault.
56
* attributes are therefore only Device if stage 2 specifies Device.
57
* With HCR_EL2.FWB == 0 this is when descriptor bits [5:4] are 0b00,
58
* ie when cacheattrs.attrs bits [3:2] are 0b00.
59
+ * With HCR_EL2.FWB == 1 this is when descriptor bit [4] is 0, ie
60
+ * when cacheattrs.attrs bit [2] is 0.
66
*/
61
*/
67
- if (return_to_handler == (env->v7m.exception == 0)) {
62
assert(cacheattrs.is_s2_format);
68
+ if (return_to_handler != arm_v7m_is_handler_mode(env)) {
63
- return (cacheattrs.attrs & 0xc) == 0;
69
/* Take an INVPC UsageFault by pushing the stack again. */
64
+ if (arm_hcr_el2_eff(env) & HCR_FWB) {
70
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
65
+ return (cacheattrs.attrs & 0x4) == 0;
71
env->v7m.cfsr |= R_V7M_CFSR_INVPC_MASK;
66
+ } else {
72
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
67
+ return (cacheattrs.attrs & 0xc) == 0;
73
if (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) {
68
+ }
74
lr |= 4;
69
}
70
71
/* Translate a S1 pagetable walk through S2 if needed. */
72
@@ -XXX,XX +XXX,XX @@ static uint8_t combined_attrs_nofwb(CPUARMState *env,
73
return ret_attrs;
74
}
75
76
+static uint8_t force_cacheattr_nibble_wb(uint8_t attr)
77
+{
78
+ /*
79
+ * Given the 4 bits specifying the outer or inner cacheability
80
+ * in MAIR format, return a value specifying Normal Write-Back,
81
+ * with the allocation and transient hints taken from the input
82
+ * if the input specified some kind of cacheable attribute.
83
+ */
84
+ if (attr == 0 || attr == 4) {
85
+ /*
86
+ * 0 == an UNPREDICTABLE encoding
87
+ * 4 == Non-cacheable
88
+ * Either way, force Write-Back RW allocate non-transient
89
+ */
90
+ return 0xf;
91
+ }
92
+ /* Change WriteThrough to WriteBack, keep allocation and transient hints */
93
+ return attr | 4;
94
+}
95
+
96
+/*
97
+ * Combine the memory type and cacheability attributes of
98
+ * s1 and s2 for the HCR_EL2.FWB == 1 case, returning the
99
+ * combined attributes in MAIR_EL1 format.
100
+ */
101
+static uint8_t combined_attrs_fwb(CPUARMState *env,
102
+ ARMCacheAttrs s1, ARMCacheAttrs s2)
103
+{
104
+ switch (s2.attrs) {
105
+ case 7:
106
+ /* Use stage 1 attributes */
107
+ return s1.attrs;
108
+ case 6:
109
+ /*
110
+ * Force Normal Write-Back. Note that if S1 is Normal cacheable
111
+ * then we take the allocation hints from it; otherwise it is
112
+ * RW allocate, non-transient.
113
+ */
114
+ if ((s1.attrs & 0xf0) == 0) {
115
+ /* S1 is Device */
116
+ return 0xff;
117
+ }
118
+ /* Need to check the Inner and Outer nibbles separately */
119
+ return force_cacheattr_nibble_wb(s1.attrs & 0xf) |
120
+ force_cacheattr_nibble_wb(s1.attrs >> 4) << 4;
121
+ case 5:
122
+ /* If S1 attrs are Device, use them; otherwise Normal Non-cacheable */
123
+ if ((s1.attrs & 0xf0) == 0) {
124
+ return s1.attrs;
125
+ }
126
+ return 0x44;
127
+ case 0 ... 3:
128
+ /* Force Device, of subtype specified by S2 */
129
+ return s2.attrs << 2;
130
+ default:
131
+ /*
132
+ * RESERVED values (including RES0 descriptor bit [5] being nonzero);
133
+ * arbitrarily force Device.
134
+ */
135
+ return 0;
136
+ }
137
+}
138
+
139
/* Combine S1 and S2 cacheability/shareability attributes, per D4.5.4
140
* and CombineS1S2Desc()
141
*
142
@@ -XXX,XX +XXX,XX @@ static ARMCacheAttrs combine_cacheattrs(CPUARMState *env,
75
}
143
}
76
- if (env->v7m.exception == 0) {
144
77
+ if (!arm_v7m_is_handler_mode(env)) {
145
/* Combine memory type and cacheability attributes */
78
lr |= 8;
146
- ret.attrs = combined_attrs_nofwb(env, s1, s2);
79
}
147
+ if (arm_hcr_el2_eff(env) & HCR_FWB) {
80
148
+ ret.attrs = combined_attrs_fwb(env, s1, s2);
81
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
149
+ } else {
82
* switch_v7m_sp() deals with updating the SPSEL bit in
150
+ ret.attrs = combined_attrs_nofwb(env, s1, s2);
83
* env->v7m.control, so we only need update the others.
151
+ }
84
*/
152
85
- if (env->v7m.exception == 0) {
153
/*
86
+ if (!arm_v7m_is_handler_mode(env)) {
154
* Any location for which the resultant memory type is any
87
switch_v7m_sp(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 0);
88
}
89
env->v7m.control &= ~R_V7M_CONTROL_NPRIV_MASK;
90
--
155
--
91
2.7.4
156
2.25.1
92
93
diff view generated by jsdifflib
1
Currently we have a rather half-baked setup for allowing CPUs to
1
Enable the FEAT_S2FWB for -cpu max. Since FEAT_S2FWB requires that
2
generate exceptions on accesses to invalid memory: the CPU has a
2
CLIDR_EL1.{LoUU,LoUIS} are zero, we explicitly squash these (the
3
cpu_unassigned_access() hook which the memory system calls in
3
inherited CLIDR_EL1 value from the Cortex-A57 has them as 1).
4
unassigned_mem_write() and unassigned_mem_read() if the current_cpu
5
pointer is non-NULL. This was originally designed before we
6
implemented the MemTxResult type that allows memory operations to
7
report a success or failure code, which is why the hook is called
8
right at the bottom of the memory system. The major problem with
9
this is that it means that the hook can be called even when the
10
access was not actually done by the CPU: for instance if the CPU
11
writes to a DMA engine register which causes the DMA engine to begin
12
a transaction which has been set up by the guest to operate on
13
invalid memory then this will casue the CPU to take an exception
14
incorrectly. Another minor problem is that currently if a device
15
returns a transaction error then this won't turn into a CPU exception
16
at all.
17
18
The right way to do this is to have allow the CPU to respond
19
to memory system transaction failures at the point where the
20
CPU specific code calls into the memory system.
21
22
Define a new QOM CPU method and utility function
23
cpu_transaction_failed() which is called in these cases.
24
The functionality here overlaps with the existing
25
cpu_unassigned_access() because individual target CPUs will
26
need some work to convert them to the new system. When this
27
transition is complete we can remove the old cpu_unassigned_access()
28
code.
29
4
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
32
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Message-id: 20220505183950.2781801-5-peter.maydell@linaro.org
33
---
8
---
34
include/qom/cpu.h | 22 ++++++++++++++++++++++
9
docs/system/arm/emulation.rst | 1 +
35
1 file changed, 22 insertions(+)
10
target/arm/cpu64.c | 11 +++++++++++
11
2 files changed, 12 insertions(+)
36
12
37
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
13
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
38
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
39
--- a/include/qom/cpu.h
15
--- a/docs/system/arm/emulation.rst
40
+++ b/include/qom/cpu.h
16
+++ b/docs/system/arm/emulation.rst
41
@@ -XXX,XX +XXX,XX @@ struct TranslationBlock;
17
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
42
* @has_work: Callback for checking if there is work to do.
18
- FEAT_RAS (Reliability, availability, and serviceability)
43
* @do_interrupt: Callback for interrupt handling.
19
- FEAT_RDM (Advanced SIMD rounding double multiply accumulate instructions)
44
* @do_unassigned_access: Callback for unassigned access handling.
20
- FEAT_RNG (Random number generator)
45
+ * (this is deprecated: new targets should use do_transaction_failed instead)
21
+- FEAT_S2FWB (Stage 2 forced Write-Back)
46
* @do_unaligned_access: Callback for unaligned access handling, if
22
- FEAT_SB (Speculation Barrier)
47
* the target defines #ALIGNED_ONLY.
23
- FEAT_SEL2 (Secure EL2)
48
+ * @do_transaction_failed: Callback for handling failed memory transactions
24
- FEAT_SHA1 (SHA1 instructions)
49
+ * (ie bus faults or external aborts; not MMU faults)
25
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
50
* @virtio_is_big_endian: Callback to return %true if a CPU which supports
26
index XXXXXXX..XXXXXXX 100644
51
* runtime configurable endianness is currently big-endian. Non-configurable
27
--- a/target/arm/cpu64.c
52
* CPUs can use the default implementation of this method. This method should
28
+++ b/target/arm/cpu64.c
53
@@ -XXX,XX +XXX,XX @@ typedef struct CPUClass {
29
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
54
void (*do_unaligned_access)(CPUState *cpu, vaddr addr,
30
{
55
MMUAccessType access_type,
31
ARMCPU *cpu = ARM_CPU(obj);
56
int mmu_idx, uintptr_t retaddr);
32
uint64_t t;
57
+ void (*do_transaction_failed)(CPUState *cpu, hwaddr physaddr, vaddr addr,
33
+ uint32_t u;
58
+ unsigned size, MMUAccessType access_type,
34
59
+ int mmu_idx, MemTxAttrs attrs,
35
if (kvm_enabled() || hvf_enabled()) {
60
+ MemTxResult response, uintptr_t retaddr);
36
/* With KVM or HVF, '-cpu max' is identical to '-cpu host' */
61
bool (*virtio_is_big_endian)(CPUState *cpu);
37
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
62
int (*memory_rw_debug)(CPUState *cpu, vaddr addr,
38
t = FIELD_DP64(t, MIDR_EL1, REVISION, 0);
63
uint8_t *buf, int len, bool is_write);
39
cpu->midr = t;
64
@@ -XXX,XX +XXX,XX @@ static inline void cpu_unaligned_access(CPUState *cpu, vaddr addr,
40
65
41
+ /*
66
cc->do_unaligned_access(cpu, addr, access_type, mmu_idx, retaddr);
42
+ * We're going to set FEAT_S2FWB, which mandates that CLIDR_EL1.{LoUU,LoUIS}
67
}
43
+ * are zero.
44
+ */
45
+ u = cpu->clidr;
46
+ u = FIELD_DP32(u, CLIDR_EL1, LOUIS, 0);
47
+ u = FIELD_DP32(u, CLIDR_EL1, LOUU, 0);
48
+ cpu->clidr = u;
68
+
49
+
69
+static inline void cpu_transaction_failed(CPUState *cpu, hwaddr physaddr,
50
t = cpu->isar.id_aa64isar0;
70
+ vaddr addr, unsigned size,
51
t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* FEAT_PMULL */
71
+ MMUAccessType access_type,
52
t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1); /* FEAT_SHA1 */
72
+ int mmu_idx, MemTxAttrs attrs,
53
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
73
+ MemTxResult response,
54
t = FIELD_DP64(t, ID_AA64MMFR2, IESB, 1); /* FEAT_IESB */
74
+ uintptr_t retaddr)
55
t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1); /* FEAT_LVA */
75
+{
56
t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* FEAT_TTST */
76
+ CPUClass *cc = CPU_GET_CLASS(cpu);
57
+ t = FIELD_DP64(t, ID_AA64MMFR2, FWB, 1); /* FEAT_S2FWB */
77
+
58
t = FIELD_DP64(t, ID_AA64MMFR2, TTL, 1); /* FEAT_TTL */
78
+ if (cc->do_transaction_failed) {
59
t = FIELD_DP64(t, ID_AA64MMFR2, BBM, 2); /* FEAT_BBM at level 2 */
79
+ cc->do_transaction_failed(cpu, physaddr, addr, size, access_type,
60
cpu->isar.id_aa64mmfr2 = t;
80
+ mmu_idx, attrs, response, retaddr);
81
+ }
82
+}
83
#endif
84
85
#endif /* NEED_CPU_H */
86
--
61
--
87
2.7.4
62
2.25.1
88
89
diff view generated by jsdifflib
1
We currently have some similar code in tlb_fill() and in
1
The Armv8.4 feature FEAT_IDST specifies that exceptions generated by
2
arm_cpu_do_unaligned_access() for delivering a data abort or prefetch
2
read accesses to the feature ID space should report a syndrome code
3
abort. We're also going to want to do the same thing to handle
3
of 0x18 (EC_SYSTEMREGISTERTRAP) rather than 0x00 (EC_UNCATEGORIZED).
4
external aborts. Factor out the common code into a new function
4
The feature ID space is defined to be:
5
deliver_fault().
5
op0 == 3, op1 == {0,1,3}, CRn == 0, CRm == {0-7}, op2 == {0-7}
6
7
In our implementation we might return the EC_UNCATEGORIZED syndrome
8
value for a system register access in four cases:
9
* no reginfo struct in the hashtable
10
* cp_access_ok() fails (ie ri->access doesn't permit the access)
11
* ri->accessfn returns CP_ACCESS_TRAP_UNCATEGORIZED at runtime
12
* ri->type includes ARM_CP_RAISES_EXC, and the readfn raises
13
an UNDEF exception at runtime
14
15
We have very few regdefs that set ARM_CP_RAISES_EXC, and none of
16
them are in the feature ID space. (In the unlikely event that any
17
are added in future they would need to take care of setting the
18
correct syndrome themselves.) This patch deals with the other
19
three cases, and enables FEAT_IDST for AArch64 -cpu max.
6
20
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Acked-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
23
Message-id: 20220509155457.3560724-1-peter.maydell@linaro.org
10
---
24
---
11
target/arm/op_helper.c | 110 +++++++++++++++++++++++++------------------------
25
docs/system/arm/emulation.rst | 1 +
12
1 file changed, 57 insertions(+), 53 deletions(-)
26
target/arm/cpregs.h | 24 ++++++++++++++++++++++++
27
target/arm/cpu.h | 5 +++++
28
target/arm/cpu64.c | 1 +
29
target/arm/op_helper.c | 9 +++++++++
30
target/arm/translate-a64.c | 28 ++++++++++++++++++++++++++--
31
6 files changed, 66 insertions(+), 2 deletions(-)
13
32
33
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
34
index XXXXXXX..XXXXXXX 100644
35
--- a/docs/system/arm/emulation.rst
36
+++ b/docs/system/arm/emulation.rst
37
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
38
- FEAT_FlagM2 (Enhancements to flag manipulation instructions)
39
- FEAT_HPDS (Hierarchical permission disables)
40
- FEAT_I8MM (AArch64 Int8 matrix multiplication instructions)
41
+- FEAT_IDST (ID space trap handling)
42
- FEAT_IESB (Implicit error synchronization event)
43
- FEAT_JSCVT (JavaScript conversion instructions)
44
- FEAT_LOR (Limited ordering regions)
45
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/cpregs.h
48
+++ b/target/arm/cpregs.h
49
@@ -XXX,XX +XXX,XX @@ static inline bool cp_access_ok(int current_el,
50
/* Raw read of a coprocessor register (as needed for migration, etc) */
51
uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri);
52
53
+/*
54
+ * Return true if the cp register encoding is in the "feature ID space" as
55
+ * defined by FEAT_IDST (and thus should be reported with ER_ELx.EC
56
+ * as EC_SYSTEMREGISTERTRAP rather than EC_UNCATEGORIZED).
57
+ */
58
+static inline bool arm_cpreg_encoding_in_idspace(uint8_t opc0, uint8_t opc1,
59
+ uint8_t opc2,
60
+ uint8_t crn, uint8_t crm)
61
+{
62
+ return opc0 == 3 && (opc1 == 0 || opc1 == 1 || opc1 == 3) &&
63
+ crn == 0 && crm < 8;
64
+}
65
+
66
+/*
67
+ * As arm_cpreg_encoding_in_idspace(), but take the encoding from an
68
+ * ARMCPRegInfo.
69
+ */
70
+static inline bool arm_cpreg_in_idspace(const ARMCPRegInfo *ri)
71
+{
72
+ return ri->state == ARM_CP_STATE_AA64 &&
73
+ arm_cpreg_encoding_in_idspace(ri->opc0, ri->opc1, ri->opc2,
74
+ ri->crn, ri->crm);
75
+}
76
+
77
#endif /* TARGET_ARM_CPREGS_H */
78
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
79
index XXXXXXX..XXXXXXX 100644
80
--- a/target/arm/cpu.h
81
+++ b/target/arm/cpu.h
82
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_fwb(const ARMISARegisters *id)
83
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, FWB) != 0;
84
}
85
86
+static inline bool isar_feature_aa64_ids(const ARMISARegisters *id)
87
+{
88
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, IDS) != 0;
89
+}
90
+
91
static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
92
{
93
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
94
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
95
index XXXXXXX..XXXXXXX 100644
96
--- a/target/arm/cpu64.c
97
+++ b/target/arm/cpu64.c
98
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
99
t = FIELD_DP64(t, ID_AA64MMFR2, IESB, 1); /* FEAT_IESB */
100
t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1); /* FEAT_LVA */
101
t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* FEAT_TTST */
102
+ t = FIELD_DP64(t, ID_AA64MMFR2, IDS, 1); /* FEAT_IDST */
103
t = FIELD_DP64(t, ID_AA64MMFR2, FWB, 1); /* FEAT_S2FWB */
104
t = FIELD_DP64(t, ID_AA64MMFR2, TTL, 1); /* FEAT_TTL */
105
t = FIELD_DP64(t, ID_AA64MMFR2, BBM, 2); /* FEAT_BBM at level 2 */
14
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
106
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
15
index XXXXXXX..XXXXXXX 100644
107
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/op_helper.c
108
--- a/target/arm/op_helper.c
17
+++ b/target/arm/op_helper.c
109
+++ b/target/arm/op_helper.c
18
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
110
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mrs_banked)(CPUARMState *env, uint32_t tgtmode, uint32_t regno)
19
return syn;
111
void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
112
uint32_t isread)
113
{
114
+ ARMCPU *cpu = env_archcpu(env);
115
const ARMCPRegInfo *ri = rip;
116
CPAccessResult res = CP_ACCESS_OK;
117
int target_el;
118
@@ -XXX,XX +XXX,XX @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
119
case CP_ACCESS_TRAP:
120
break;
121
case CP_ACCESS_TRAP_UNCATEGORIZED:
122
+ if (cpu_isar_feature(aa64_ids, cpu) && isread &&
123
+ arm_cpreg_in_idspace(ri)) {
124
+ /*
125
+ * FEAT_IDST says this should be reported as EC_SYSTEMREGISTERTRAP,
126
+ * not EC_UNCATEGORIZED
127
+ */
128
+ break;
129
+ }
130
syndrome = syn_uncategorized();
131
break;
132
default:
133
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/target/arm/translate-a64.c
136
+++ b/target/arm/translate-a64.c
137
@@ -XXX,XX +XXX,XX @@ static void gen_set_nzcv(TCGv_i64 tcg_rt)
138
tcg_temp_free_i32(nzcv);
20
}
139
}
21
140
22
+static void deliver_fault(ARMCPU *cpu, vaddr addr, MMUAccessType access_type,
141
+static void gen_sysreg_undef(DisasContext *s, bool isread,
23
+ uint32_t fsr, uint32_t fsc, ARMMMUFaultInfo *fi)
142
+ uint8_t op0, uint8_t op1, uint8_t op2,
143
+ uint8_t crn, uint8_t crm, uint8_t rt)
24
+{
144
+{
25
+ CPUARMState *env = &cpu->env;
145
+ /*
26
+ int target_el;
146
+ * Generate code to emit an UNDEF with correct syndrome
27
+ bool same_el;
147
+ * information for a failed system register access.
28
+ uint32_t syn, exc;
148
+ * This is EC_UNCATEGORIZED (ie a standard UNDEF) in most cases,
149
+ * but if FEAT_IDST is implemented then read accesses to registers
150
+ * in the feature ID space are reported with the EC_SYSTEMREGISTERTRAP
151
+ * syndrome.
152
+ */
153
+ uint32_t syndrome;
29
+
154
+
30
+ target_el = exception_target_el(env);
155
+ if (isread && dc_isar_feature(aa64_ids, s) &&
31
+ if (fi->stage2) {
156
+ arm_cpreg_encoding_in_idspace(op0, op1, op2, crn, crm)) {
32
+ target_el = 2;
157
+ syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
33
+ env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
158
+ } else {
159
+ syndrome = syn_uncategorized();
34
+ }
160
+ }
35
+ same_el = (arm_current_el(env) == target_el);
161
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syndrome,
36
+
162
+ default_exception_el(s));
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
+}
163
+}
66
+
164
+
67
/* try to fill the TLB and return an exception if error. If retaddr is
165
/* MRS - move from system register
68
* NULL, it means that the function was called in C code (i.e. not
166
* MSR (register) - move to system register
69
* from generated code or from helper.c)
167
* SYS
70
@@ -XXX,XX +XXX,XX @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
168
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
71
ret = arm_tlb_fill(cs, addr, access_type, mmu_idx, &fsr, &fi);
169
qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch64 "
72
if (unlikely(ret)) {
170
"system register op0:%d op1:%d crn:%d crm:%d op2:%d\n",
73
ARMCPU *cpu = ARM_CPU(cs);
171
isread ? "read" : "write", op0, op1, crn, crm, op2);
74
- CPUARMState *env = &cpu->env;
172
- unallocated_encoding(s);
75
- uint32_t syn, exc, fsc;
173
+ gen_sysreg_undef(s, isread, op0, op1, op2, crn, crm, rt);
76
- unsigned int target_el;
174
return;
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
}
175
}
133
}
176
134
177
/* Check access permissions */
135
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
178
if (!cp_access_ok(s->current_el, ri, isread)) {
136
{
179
- unallocated_encoding(s);
137
ARMCPU *cpu = ARM_CPU(cs);
180
+ gen_sysreg_undef(s, isread, op0, op1, op2, crn, crm, rt);
138
CPUARMState *env = &cpu->env;
181
return;
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
}
182
}
150
183
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
--
184
--
181
2.7.4
185
2.25.1
182
183
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The unsupported_encoding() macro logs a LOG_UNIMP message and then
2
generates code to raise the usual exception for an unallocated
3
encoding. Back when we were still implementing the A64 decoder this
4
was helpful for flagging up when guest code was using something we
5
hadn't yet implemented. Now we completely cover the A64 instruction
6
set it is barely used. The only remaining uses are for five
7
instructions whose semantics are "UNDEF, unless being run under
8
external halting debug":
9
* HLT (when not being used for semihosting)
10
* DCPSR1, DCPS2, DCPS3
11
* DRPS
2
12
3
For "ldp x0, x1, [x0]", if the second load is on a second page and
13
QEMU doesn't implement external halting debug, so for us the UNDEF is
4
the second page is unmapped, the exception would be raised with x0
14
the architecturally correct behaviour (because it's not possible to
5
already modified. This means the instruction couldn't be restarted.
15
execute these instructions with halting debug enabled). The
16
LOG_UNIMP doesn't serve a useful purpose; replace these uses of
17
unsupported_encoding() with unallocated_encoding(), and delete the
18
macro.
6
19
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>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20220509160443.3561604-1-peter.maydell@linaro.org
17
---
24
---
18
target/arm/translate-a64.c | 29 +++++++++++++++++------------
25
target/arm/translate-a64.h | 9 ---------
19
1 file changed, 17 insertions(+), 12 deletions(-)
26
target/arm/translate-a64.c | 8 ++++----
27
2 files changed, 4 insertions(+), 13 deletions(-)
20
28
29
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate-a64.h
32
+++ b/target/arm/translate-a64.h
33
@@ -XXX,XX +XXX,XX @@
34
#ifndef TARGET_ARM_TRANSLATE_A64_H
35
#define TARGET_ARM_TRANSLATE_A64_H
36
37
-#define unsupported_encoding(s, insn) \
38
- do { \
39
- qemu_log_mask(LOG_UNIMP, \
40
- "%s:%d: unsupported instruction encoding 0x%08x " \
41
- "at pc=%016" PRIx64 "\n", \
42
- __FILE__, __LINE__, insn, s->pc_curr); \
43
- unallocated_encoding(s); \
44
- } while (0)
45
-
46
TCGv_i64 new_tmp_a64(DisasContext *s);
47
TCGv_i64 new_tmp_a64_local(DisasContext *s);
48
TCGv_i64 new_tmp_a64_zero(DisasContext *s);
21
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
49
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
22
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/translate-a64.c
51
--- a/target/arm/translate-a64.c
24
+++ b/target/arm/translate-a64.c
52
+++ b/target/arm/translate-a64.c
25
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn)
53
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
54
* with our 32-bit semihosting).
55
*/
56
if (s->current_el == 0) {
57
- unsupported_encoding(s, insn);
58
+ unallocated_encoding(s);
59
break;
60
}
61
#endif
62
gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
26
} else {
63
} else {
27
do_fp_st(s, rt, tcg_addr, size);
64
- unsupported_encoding(s, insn);
65
+ unallocated_encoding(s);
28
}
66
}
29
- } else {
67
break;
30
- TCGv_i64 tcg_rt = cpu_reg(s, rt);
68
case 5:
31
- if (is_load) {
69
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
32
- do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false,
70
break;
33
- false, 0, false, false);
71
}
34
- } else {
72
/* DCPS1, DCPS2, DCPS3 */
35
- do_gpr_st(s, tcg_rt, tcg_addr, size,
73
- unsupported_encoding(s, insn);
36
- false, 0, false, false);
74
+ unallocated_encoding(s);
37
- }
75
break;
38
- }
76
default:
39
- tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
77
unallocated_encoding(s);
40
- if (is_vector) {
78
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
41
+ tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
79
if (op3 != 0 || op4 != 0 || rn != 0x1f) {
42
if (is_load) {
80
goto do_unallocated;
43
do_fp_ld(s, rt2, tcg_addr, size);
44
} else {
81
} else {
45
do_fp_st(s, rt2, tcg_addr, size);
82
- unsupported_encoding(s, insn);
83
+ unallocated_encoding(s);
46
}
84
}
47
} else {
85
return;
48
+ TCGv_i64 tcg_rt = cpu_reg(s, rt);
86
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
--
87
--
73
2.7.4
88
2.25.1
74
89
75
90
diff view generated by jsdifflib
1
For M profile the XPSR is a similar but not identical format to the
1
We allow a GICv3 to be connected to any CPU, but we don't do anything
2
A profile CPSR/SPSR. (For instance the Thumb bit is in a different
2
to handle the case where the CPU type doesn't in hardware have a
3
place.) For guest accesses we make the M profile code go through
3
GICv3 CPU interface and so the various GIC configuration fields
4
xpsr_read() and xpsr_write() which handle the different layout.
4
(gic_num_lrs, vprebits, vpribits) are not specified.
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
5
10
The most complicated part of this is handling the possibility
6
The current behaviour is that we will add the EL1 CPU interface
11
that the migration source is an older QEMU which hands us a
7
registers, but will not put in the EL2 CPU interface registers, even
12
CPSR format value; helpfully we can always tell the two apart.
8
if the CPU has EL2, which will leave the GIC in a broken state and
9
probably result in the guest crashing as it tries to set it up. This
10
only affects the virt board when using the cortex-a15 or cortex-a7
11
CPU types (both 32-bit) with -machine gic-version=3 (or 'max')
12
and -machine virtualization=on.
13
14
Instead of failing to set up the EL2 registers, if the CPU doesn't
15
define the GIC configuration set it to a reasonable default, matching
16
the standard configuration for most Arm CPUs.
13
17
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 1501692241-23310-11-git-send-email-peter.maydell@linaro.org
20
Message-id: 20220512151457.3899052-2-peter.maydell@linaro.org
17
---
21
---
18
target/arm/machine.c | 49 ++++++++++++++++++++++++++++++++++---------------
22
hw/intc/arm_gicv3_cpuif.c | 18 +++++++++++++-----
19
1 file changed, 34 insertions(+), 15 deletions(-)
23
1 file changed, 13 insertions(+), 5 deletions(-)
20
24
21
diff --git a/target/arm/machine.c b/target/arm/machine.c
25
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
22
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/machine.c
27
--- a/hw/intc/arm_gicv3_cpuif.c
24
+++ b/target/arm/machine.c
28
+++ b/hw/intc/arm_gicv3_cpuif.c
25
@@ -XXX,XX +XXX,XX @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
29
@@ -XXX,XX +XXX,XX @@ void gicv3_init_cpuif(GICv3State *s)
26
uint32_t val = qemu_get_be32(f);
30
ARMCPU *cpu = ARM_CPU(qemu_get_cpu(i));
27
31
GICv3CPUState *cs = &s->cpu[i];
28
if (arm_feature(env, ARM_FEATURE_M)) {
32
29
- /* If the I or F bits are set then this is a migration from
33
+ /*
30
- * an old QEMU which still stored the M profile FAULTMASK
34
+ * If the CPU doesn't define a GICv3 configuration, probably because
31
- * and PRIMASK in env->daif. Set v7m.faultmask and v7m.primask
35
+ * in real hardware it doesn't have one, then we use default values
32
- * accordingly, and then clear the bits so they don't confuse
36
+ * matching the one used by most Arm CPUs. This applies to:
33
- * cpsr_write(). For a new QEMU, the bits here will always be
37
+ * cpu->gic_num_lrs
34
- * clear, and the data is transferred using the
38
+ * cpu->gic_vpribits
35
- * vmstate_m_faultmask_primask subsection.
39
+ * cpu->gic_vprebits
36
- */
40
+ */
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
+
41
+
53
+ newval &= (CPSR_NZCV | CPSR_Q | CPSR_IT | CPSR_GE);
42
/* Note that we can't just use the GICv3CPUState as an opaque pointer
54
+ if (val & CPSR_T) {
43
* in define_arm_cp_regs_with_opaque(), because when we're called back
55
+ newval |= XPSR_T;
44
* it might be with code translated by CPU 0 but run by CPU 1, in
56
+ }
45
@@ -XXX,XX +XXX,XX @@ void gicv3_init_cpuif(GICv3State *s)
57
+ /* If the I or F bits are set then this is a migration from
46
* get back to the GICv3CPUState from the CPUARMState.
58
+ * an old QEMU which still stored the M profile FAULTMASK
47
*/
59
+ * and PRIMASK in env->daif. For a new QEMU, the data is
48
define_arm_cp_regs(cpu, gicv3_cpuif_reginfo);
60
+ * transferred using the vmstate_m_faultmask_primask subsection.
49
- if (arm_feature(&cpu->env, ARM_FEATURE_EL2)
61
+ */
50
- && cpu->gic_num_lrs) {
62
+ if (val & CPSR_F) {
51
+ if (arm_feature(&cpu->env, ARM_FEATURE_EL2)) {
63
+ env->v7m.faultmask = 1;
52
int j;
64
+ }
53
65
+ if (val & CPSR_I) {
54
- cs->num_list_regs = cpu->gic_num_lrs;
66
+ env->v7m.primask = 1;
55
- cs->vpribits = cpu->gic_vpribits;
67
+ }
56
- cs->vprebits = cpu->gic_vprebits;
68
+ val = newval;
57
+ cs->num_list_regs = cpu->gic_num_lrs ?: 4;
69
}
58
+ cs->vpribits = cpu->gic_vpribits ?: 5;
70
- val &= ~(CPSR_F | CPSR_I);
59
+ cs->vprebits = cpu->gic_vprebits ?: 5;
71
+ /* Ignore the low bits, they are handled by vmstate_m. */
60
72
+ xpsr_write(env, val, ~XPSR_EXCP);
61
/* Check against architectural constraints: getting these
73
+ return 0;
62
* wrong would be a bug in the CPU code defining these,
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
--
63
--
90
2.7.4
64
2.25.1
91
92
diff view generated by jsdifflib
1
For embedded systems, notably ARM, one common use of ELF
1
As noted in the comment, the PRIbits field in ICV_CTLR_EL1 is
2
file segments is that the 'physical addresses' represent load addresses
2
supposed to match the ICH_VTR_EL2 PRIbits setting; that is, it is the
3
and the 'virtual addresses' execution addresses, such that
3
virtual priority bit setting, not the physical priority bit setting.
4
the load addresses are packed into ROM or flash, and the
4
(For QEMU currently we always implement 8 bits of physical priority,
5
relocation and zero-initialization of data is done at runtime.
5
so the PRIbits field was previously 7, since it is defined to be
6
This means that the 'memsz' in the segment header represents
6
"priority bits - 1".)
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
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
7
41
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
42
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
43
Message-id: 1502116754-18867-2-git-send-email-peter.maydell@linaro.org
10
Message-id: 20220512151457.3899052-3-peter.maydell@linaro.org
11
Message-id: 20220506162129.2896966-2-peter.maydell@linaro.org
44
---
12
---
45
include/hw/elf_ops.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
13
hw/intc/arm_gicv3_cpuif.c | 2 +-
46
1 file changed, 48 insertions(+)
14
1 file changed, 1 insertion(+), 1 deletion(-)
47
15
48
diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h
16
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
49
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
50
--- a/include/hw/elf_ops.h
18
--- a/hw/intc/arm_gicv3_cpuif.c
51
+++ b/include/hw/elf_ops.h
19
+++ b/hw/intc/arm_gicv3_cpuif.c
52
@@ -XXX,XX +XXX,XX @@ static int glue(load_elf, SZ)(const char *name, int fd,
20
@@ -XXX,XX +XXX,XX @@ static uint64_t icv_ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
53
goto fail;
21
* should match the ones reported in ich_vtr_read().
54
}
22
*/
55
}
23
value = ICC_CTLR_EL1_A3V | (1 << ICC_CTLR_EL1_IDBITS_SHIFT) |
56
+
24
- (7 << ICC_CTLR_EL1_PRIBITS_SHIFT);
57
+ /* The ELF spec is somewhat vague about the purpose of the
25
+ ((cs->vpribits - 1) << ICC_CTLR_EL1_PRIBITS_SHIFT);
58
+ * physical address field. One common use in the embedded world
26
59
+ * is that physical address field specifies the load address
27
if (cs->ich_vmcr_el2 & ICH_VMCR_EL2_VEOIM) {
60
+ * and the virtual address field specifies the execution address.
28
value |= ICC_CTLR_EL1_EOIMODE;
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
--
29
--
108
2.7.4
30
2.25.1
109
110
diff view generated by jsdifflib
1
From: Pranith Kumar <bobby.prani@gmail.com>
1
The GIC_MIN_BPR constant defines the minimum BPR value that the TCG
2
emulated GICv3 supports. We're currently using this also as the
3
value we reset the KVM GICv3 ICC_BPR registers to, but this is only
4
right by accident.
2
5
3
Fix the following warning:
6
We want to make the emulated GICv3 use a configurable number of
7
priority bits, which means that GIC_MIN_BPR will no longer be a
8
constant. Replace the uses in the KVM reset code with literal 0,
9
plus a constant explaining why this is reasonable.
4
10
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>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20220512151457.3899052-4-peter.maydell@linaro.org
14
Message-id: 20220506162129.2896966-3-peter.maydell@linaro.org
25
---
15
---
26
hw/intc/arm_gicv3_kvm.c | 2 +-
16
hw/intc/arm_gicv3_kvm.c | 16 +++++++++++++---
27
1 file changed, 1 insertion(+), 1 deletion(-)
17
1 file changed, 13 insertions(+), 3 deletions(-)
28
18
29
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
19
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
30
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/intc/arm_gicv3_kvm.c
21
--- a/hw/intc/arm_gicv3_kvm.c
32
+++ b/hw/intc/arm_gicv3_kvm.c
22
+++ b/hw/intc/arm_gicv3_kvm.c
33
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_put(GICv3State *s)
23
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_icc_reset(CPUARMState *env, const ARMCPRegInfo *ri)
34
kvm_gicr_access(s, GICR_PROPBASER + 4, ncpu, &regh, true);
24
s = c->gic;
35
25
36
reg64 = c->gicr_pendbaser;
26
c->icc_pmr_el1 = 0;
37
- if (!c->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) {
27
- c->icc_bpr[GICV3_G0] = GIC_MIN_BPR;
38
+ if (!(c->gicr_ctlr & GICR_CTLR_ENABLE_LPIS)) {
28
- c->icc_bpr[GICV3_G1] = GIC_MIN_BPR;
39
/* Setting PTZ is advised if LPIs are disabled, to reduce
29
- c->icc_bpr[GICV3_G1NS] = GIC_MIN_BPR;
40
* GIC initialization time.
30
+ /*
41
*/
31
+ * Architecturally the reset value of the ICC_BPR registers
32
+ * is UNKNOWN. We set them all to 0 here; when the kernel
33
+ * uses these values to program the ICH_VMCR_EL2 fields that
34
+ * determine the guest-visible ICC_BPR register values, the
35
+ * hardware's "writing a value less than the minimum sets
36
+ * the field to the minimum value" behaviour will result in
37
+ * them effectively resetting to the correct minimum value
38
+ * for the host GIC.
39
+ */
40
+ c->icc_bpr[GICV3_G0] = 0;
41
+ c->icc_bpr[GICV3_G1] = 0;
42
+ c->icc_bpr[GICV3_G1NS] = 0;
43
44
c->icc_sre_el1 = 0x7;
45
memset(c->icc_apr, 0, sizeof(c->icc_apr));
42
--
46
--
43
2.7.4
47
2.25.1
44
45
diff view generated by jsdifflib
1
Move the MemTxResult type to memattrs.h. We're going to want to
1
The GICv3 code has always supported a configurable number of virtual
2
use it in cpu/qom.h, which doesn't want to include all of
2
priority and preemption bits, but our implementation currently
3
memory.h. In practice MemTxResult and MemTxAttrs are pretty
3
hardcodes the number of physical priority bits at 8. This is not
4
closely linked since both are used for the new-style
4
what most hardware implementations provide; for instance the
5
read_with_attrs and write_with_attrs callbacks, so memattrs.h
5
Cortex-A53 provides only 5 bits of physical priority.
6
is a reasonable home for this rather than creating a whole
6
7
new header file for it.
7
Make the number of physical priority/preemption bits driven by fields
8
in the GICv3CPUState, the way that we already do for virtual
9
priority/preemption bits. We set cs->pribits to 8, so there is no
10
behavioural change in this commit. A following commit will add the
11
machinery for CPUs to set this to the correct value for their
12
implementation.
13
14
Note that changing the number of priority bits would be a migration
15
compatibility break, because the semantics of the icc_apr[][] array
16
changes.
8
17
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
20
Message-id: 20220512151457.3899052-5-peter.maydell@linaro.org
12
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
21
Message-id: 20220506162129.2896966-4-peter.maydell@linaro.org
13
---
22
---
14
include/exec/memattrs.h | 10 ++++++++++
23
include/hw/intc/arm_gicv3_common.h | 7 +-
15
include/exec/memory.h | 10 ----------
24
hw/intc/arm_gicv3_cpuif.c | 182 ++++++++++++++++++++---------
16
2 files changed, 10 insertions(+), 10 deletions(-)
25
2 files changed, 130 insertions(+), 59 deletions(-)
17
26
18
diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h
27
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
19
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
20
--- a/include/exec/memattrs.h
29
--- a/include/hw/intc/arm_gicv3_common.h
21
+++ b/include/exec/memattrs.h
30
+++ b/include/hw/intc/arm_gicv3_common.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct MemTxAttrs {
31
@@ -XXX,XX +XXX,XX @@
23
*/
32
/* Maximum number of list registers (architectural limit) */
24
#define MEMTXATTRS_UNSPECIFIED ((MemTxAttrs) { .unspecified = 1 })
33
#define GICV3_LR_MAX 16
25
34
26
+/* New-style MMIO accessors can indicate that the transaction failed.
35
-/* Minimum BPR for Secure, or when security not enabled */
27
+ * A zero (MEMTX_OK) response means success; anything else is a failure
36
-#define GIC_MIN_BPR 0
28
+ * of some kind. The memory subsystem will bitwise-OR together results
37
-/* Minimum BPR for Nonsecure when security is enabled */
29
+ * if it is synthesizing an operation from multiple smaller accesses.
38
-#define GIC_MIN_BPR_NS (GIC_MIN_BPR + 1)
30
+ */
39
-
31
+#define MEMTX_OK 0
40
/* For some distributor fields we want to model the array of 32-bit
32
+#define MEMTX_ERROR (1U << 0) /* device returned an error */
41
* register values which hold various bitmaps corresponding to enabled,
33
+#define MEMTX_DECODE_ERROR (1U << 1) /* nothing at that address */
42
* pending, etc bits. These macros and functions facilitate that; the
34
+typedef uint32_t MemTxResult;
43
@@ -XXX,XX +XXX,XX @@ struct GICv3CPUState {
35
+
44
int num_list_regs;
36
#endif
45
int vpribits; /* number of virtual priority bits */
37
diff --git a/include/exec/memory.h b/include/exec/memory.h
46
int vprebits; /* number of virtual preemption bits */
47
+ int pribits; /* number of physical priority bits */
48
+ int prebits; /* number of physical preemption bits */
49
50
/* Current highest priority pending interrupt for this CPU.
51
* This is cached information that can be recalculated from the
52
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
38
index XXXXXXX..XXXXXXX 100644
53
index XXXXXXX..XXXXXXX 100644
39
--- a/include/exec/memory.h
54
--- a/hw/intc/arm_gicv3_cpuif.c
40
+++ b/include/exec/memory.h
55
+++ b/hw/intc/arm_gicv3_cpuif.c
41
@@ -XXX,XX +XXX,XX @@ static inline void iommu_notifier_init(IOMMUNotifier *n, IOMMUNotify fn,
56
@@ -XXX,XX +XXX,XX @@ static uint64_t icv_iar_read(CPUARMState *env, const ARMCPRegInfo *ri)
42
n->end = end;
57
return intid;
43
}
58
}
44
59
45
-/* New-style MMIO accessors can indicate that the transaction failed.
60
+static uint32_t icc_fullprio_mask(GICv3CPUState *cs)
46
- * A zero (MEMTX_OK) response means success; anything else is a failure
61
+{
47
- * of some kind. The memory subsystem will bitwise-OR together results
62
+ /*
48
- * if it is synthesizing an operation from multiple smaller accesses.
63
+ * Return a mask word which clears the unimplemented priority bits
49
- */
64
+ * from a priority value for a physical interrupt. (Not to be confused
50
-#define MEMTX_OK 0
65
+ * with the group priority, whose mask depends on the value of BPR
51
-#define MEMTX_ERROR (1U << 0) /* device returned an error */
66
+ * for the interrupt group.)
52
-#define MEMTX_DECODE_ERROR (1U << 1) /* nothing at that address */
67
+ */
53
-typedef uint32_t MemTxResult;
68
+ return ~0U << (8 - cs->pribits);
54
-
69
+}
55
/*
70
+
56
* Memory region callbacks
71
+static inline int icc_min_bpr(GICv3CPUState *cs)
57
*/
72
+{
73
+ /* The minimum BPR for the physical interface. */
74
+ return 7 - cs->prebits;
75
+}
76
+
77
+static inline int icc_min_bpr_ns(GICv3CPUState *cs)
78
+{
79
+ return icc_min_bpr(cs) + 1;
80
+}
81
+
82
+static inline int icc_num_aprs(GICv3CPUState *cs)
83
+{
84
+ /* Return the number of APR registers (1, 2, or 4) */
85
+ int aprmax = 1 << MAX(cs->prebits - 5, 0);
86
+ assert(aprmax <= ARRAY_SIZE(cs->icc_apr[0]));
87
+ return aprmax;
88
+}
89
+
90
static int icc_highest_active_prio(GICv3CPUState *cs)
91
{
92
/* Calculate the current running priority based on the set bits
93
@@ -XXX,XX +XXX,XX @@ static int icc_highest_active_prio(GICv3CPUState *cs)
94
*/
95
int i;
96
97
- for (i = 0; i < ARRAY_SIZE(cs->icc_apr[0]); i++) {
98
+ for (i = 0; i < icc_num_aprs(cs); i++) {
99
uint32_t apr = cs->icc_apr[GICV3_G0][i] |
100
cs->icc_apr[GICV3_G1][i] | cs->icc_apr[GICV3_G1NS][i];
101
102
if (!apr) {
103
continue;
104
}
105
- return (i * 32 + ctz32(apr)) << (GIC_MIN_BPR + 1);
106
+ return (i * 32 + ctz32(apr)) << (icc_min_bpr(cs) + 1);
107
}
108
/* No current active interrupts: return idle priority */
109
return 0xff;
110
@@ -XXX,XX +XXX,XX @@ static void icc_pmr_write(CPUARMState *env, const ARMCPRegInfo *ri,
111
112
trace_gicv3_icc_pmr_write(gicv3_redist_affid(cs), value);
113
114
- value &= 0xff;
115
+ value &= icc_fullprio_mask(cs);
116
117
if (arm_feature(env, ARM_FEATURE_EL3) && !arm_is_secure(env) &&
118
(env->cp15.scr_el3 & SCR_FIQ)) {
119
@@ -XXX,XX +XXX,XX @@ static void icc_activate_irq(GICv3CPUState *cs, int irq)
120
*/
121
uint32_t mask = icc_gprio_mask(cs, cs->hppi.grp);
122
int prio = cs->hppi.prio & mask;
123
- int aprbit = prio >> 1;
124
+ int aprbit = prio >> (8 - cs->prebits);
125
int regno = aprbit / 32;
126
int regbit = aprbit % 32;
127
128
@@ -XXX,XX +XXX,XX @@ static void icc_drop_prio(GICv3CPUState *cs, int grp)
129
*/
130
int i;
131
132
- for (i = 0; i < ARRAY_SIZE(cs->icc_apr[grp]); i++) {
133
+ for (i = 0; i < icc_num_aprs(cs); i++) {
134
uint64_t *papr = &cs->icc_apr[grp][i];
135
136
if (!*papr) {
137
@@ -XXX,XX +XXX,XX @@ static void icc_bpr_write(CPUARMState *env, const ARMCPRegInfo *ri,
138
return;
139
}
140
141
- minval = (grp == GICV3_G1NS) ? GIC_MIN_BPR_NS : GIC_MIN_BPR;
142
+ minval = (grp == GICV3_G1NS) ? icc_min_bpr_ns(cs) : icc_min_bpr(cs);
143
if (value < minval) {
144
value = minval;
145
}
146
@@ -XXX,XX +XXX,XX @@ static void icc_reset(CPUARMState *env, const ARMCPRegInfo *ri)
147
148
cs->icc_ctlr_el1[GICV3_S] = ICC_CTLR_EL1_A3V |
149
(1 << ICC_CTLR_EL1_IDBITS_SHIFT) |
150
- (7 << ICC_CTLR_EL1_PRIBITS_SHIFT);
151
+ ((cs->pribits - 1) << ICC_CTLR_EL1_PRIBITS_SHIFT);
152
cs->icc_ctlr_el1[GICV3_NS] = ICC_CTLR_EL1_A3V |
153
(1 << ICC_CTLR_EL1_IDBITS_SHIFT) |
154
- (7 << ICC_CTLR_EL1_PRIBITS_SHIFT);
155
+ ((cs->pribits - 1) << ICC_CTLR_EL1_PRIBITS_SHIFT);
156
cs->icc_pmr_el1 = 0;
157
- cs->icc_bpr[GICV3_G0] = GIC_MIN_BPR;
158
- cs->icc_bpr[GICV3_G1] = GIC_MIN_BPR;
159
- cs->icc_bpr[GICV3_G1NS] = GIC_MIN_BPR_NS;
160
+ cs->icc_bpr[GICV3_G0] = icc_min_bpr(cs);
161
+ cs->icc_bpr[GICV3_G1] = icc_min_bpr(cs);
162
+ cs->icc_bpr[GICV3_G1NS] = icc_min_bpr_ns(cs);
163
memset(cs->icc_apr, 0, sizeof(cs->icc_apr));
164
memset(cs->icc_igrpen, 0, sizeof(cs->icc_igrpen));
165
cs->icc_ctlr_el3 = ICC_CTLR_EL3_NDS | ICC_CTLR_EL3_A3V |
166
(1 << ICC_CTLR_EL3_IDBITS_SHIFT) |
167
- (7 << ICC_CTLR_EL3_PRIBITS_SHIFT);
168
+ ((cs->pribits - 1) << ICC_CTLR_EL3_PRIBITS_SHIFT);
169
170
memset(cs->ich_apr, 0, sizeof(cs->ich_apr));
171
cs->ich_hcr_el2 = 0;
172
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
173
.readfn = icc_ap_read,
174
.writefn = icc_ap_write,
175
},
176
- { .name = "ICC_AP0R1_EL1", .state = ARM_CP_STATE_BOTH,
177
- .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 5,
178
- .type = ARM_CP_IO | ARM_CP_NO_RAW,
179
- .access = PL1_RW, .accessfn = gicv3_fiq_access,
180
- .readfn = icc_ap_read,
181
- .writefn = icc_ap_write,
182
- },
183
- { .name = "ICC_AP0R2_EL1", .state = ARM_CP_STATE_BOTH,
184
- .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 6,
185
- .type = ARM_CP_IO | ARM_CP_NO_RAW,
186
- .access = PL1_RW, .accessfn = gicv3_fiq_access,
187
- .readfn = icc_ap_read,
188
- .writefn = icc_ap_write,
189
- },
190
- { .name = "ICC_AP0R3_EL1", .state = ARM_CP_STATE_BOTH,
191
- .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 7,
192
- .type = ARM_CP_IO | ARM_CP_NO_RAW,
193
- .access = PL1_RW, .accessfn = gicv3_fiq_access,
194
- .readfn = icc_ap_read,
195
- .writefn = icc_ap_write,
196
- },
197
/* All the ICC_AP1R*_EL1 registers are banked */
198
{ .name = "ICC_AP1R0_EL1", .state = ARM_CP_STATE_BOTH,
199
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 0,
200
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
201
.readfn = icc_ap_read,
202
.writefn = icc_ap_write,
203
},
204
- { .name = "ICC_AP1R1_EL1", .state = ARM_CP_STATE_BOTH,
205
- .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 1,
206
- .type = ARM_CP_IO | ARM_CP_NO_RAW,
207
- .access = PL1_RW, .accessfn = gicv3_irq_access,
208
- .readfn = icc_ap_read,
209
- .writefn = icc_ap_write,
210
- },
211
- { .name = "ICC_AP1R2_EL1", .state = ARM_CP_STATE_BOTH,
212
- .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 2,
213
- .type = ARM_CP_IO | ARM_CP_NO_RAW,
214
- .access = PL1_RW, .accessfn = gicv3_irq_access,
215
- .readfn = icc_ap_read,
216
- .writefn = icc_ap_write,
217
- },
218
- { .name = "ICC_AP1R3_EL1", .state = ARM_CP_STATE_BOTH,
219
- .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 3,
220
- .type = ARM_CP_IO | ARM_CP_NO_RAW,
221
- .access = PL1_RW, .accessfn = gicv3_irq_access,
222
- .readfn = icc_ap_read,
223
- .writefn = icc_ap_write,
224
- },
225
{ .name = "ICC_DIR_EL1", .state = ARM_CP_STATE_BOTH,
226
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 11, .opc2 = 1,
227
.type = ARM_CP_IO | ARM_CP_NO_RAW,
228
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
229
},
230
};
231
232
+static const ARMCPRegInfo gicv3_cpuif_icc_apxr1_reginfo[] = {
233
+ { .name = "ICC_AP0R1_EL1", .state = ARM_CP_STATE_BOTH,
234
+ .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 5,
235
+ .type = ARM_CP_IO | ARM_CP_NO_RAW,
236
+ .access = PL1_RW, .accessfn = gicv3_fiq_access,
237
+ .readfn = icc_ap_read,
238
+ .writefn = icc_ap_write,
239
+ },
240
+ { .name = "ICC_AP1R1_EL1", .state = ARM_CP_STATE_BOTH,
241
+ .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 1,
242
+ .type = ARM_CP_IO | ARM_CP_NO_RAW,
243
+ .access = PL1_RW, .accessfn = gicv3_irq_access,
244
+ .readfn = icc_ap_read,
245
+ .writefn = icc_ap_write,
246
+ },
247
+};
248
+
249
+static const ARMCPRegInfo gicv3_cpuif_icc_apxr23_reginfo[] = {
250
+ { .name = "ICC_AP0R2_EL1", .state = ARM_CP_STATE_BOTH,
251
+ .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 6,
252
+ .type = ARM_CP_IO | ARM_CP_NO_RAW,
253
+ .access = PL1_RW, .accessfn = gicv3_fiq_access,
254
+ .readfn = icc_ap_read,
255
+ .writefn = icc_ap_write,
256
+ },
257
+ { .name = "ICC_AP0R3_EL1", .state = ARM_CP_STATE_BOTH,
258
+ .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 7,
259
+ .type = ARM_CP_IO | ARM_CP_NO_RAW,
260
+ .access = PL1_RW, .accessfn = gicv3_fiq_access,
261
+ .readfn = icc_ap_read,
262
+ .writefn = icc_ap_write,
263
+ },
264
+ { .name = "ICC_AP1R2_EL1", .state = ARM_CP_STATE_BOTH,
265
+ .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 2,
266
+ .type = ARM_CP_IO | ARM_CP_NO_RAW,
267
+ .access = PL1_RW, .accessfn = gicv3_irq_access,
268
+ .readfn = icc_ap_read,
269
+ .writefn = icc_ap_write,
270
+ },
271
+ { .name = "ICC_AP1R3_EL1", .state = ARM_CP_STATE_BOTH,
272
+ .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 3,
273
+ .type = ARM_CP_IO | ARM_CP_NO_RAW,
274
+ .access = PL1_RW, .accessfn = gicv3_irq_access,
275
+ .readfn = icc_ap_read,
276
+ .writefn = icc_ap_write,
277
+ },
278
+};
279
+
280
static uint64_t ich_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
281
{
282
GICv3CPUState *cs = icc_cs_from_env(env);
283
@@ -XXX,XX +XXX,XX @@ void gicv3_init_cpuif(GICv3State *s)
284
* get back to the GICv3CPUState from the CPUARMState.
285
*/
286
define_arm_cp_regs(cpu, gicv3_cpuif_reginfo);
287
+
288
+ /*
289
+ * For the moment, retain the existing behaviour of 8 priority bits;
290
+ * in a following commit we will take this from the CPU state,
291
+ * as we do for the virtual priority bits.
292
+ */
293
+ cs->pribits = 8;
294
+ /*
295
+ * The GICv3 has separate ID register fields for virtual priority
296
+ * and preemption bit values, but only a single ID register field
297
+ * for the physical priority bits. The preemption bit count is
298
+ * always the same as the priority bit count, except that 8 bits
299
+ * of priority means 7 preemption bits. We precalculate the
300
+ * preemption bits because it simplifies the code and makes the
301
+ * parallels between the virtual and physical bits of the GIC
302
+ * a bit clearer.
303
+ */
304
+ cs->prebits = cs->pribits;
305
+ if (cs->prebits == 8) {
306
+ cs->prebits--;
307
+ }
308
+ /*
309
+ * Check that CPU code defining pribits didn't violate
310
+ * architectural constraints our implementation relies on.
311
+ */
312
+ g_assert(cs->pribits >= 4 && cs->pribits <= 8);
313
+
314
+ /*
315
+ * gicv3_cpuif_reginfo[] defines ICC_AP*R0_EL1; add definitions
316
+ * for ICC_AP*R{1,2,3}_EL1 if the prebits value requires them.
317
+ */
318
+ if (cs->prebits >= 6) {
319
+ define_arm_cp_regs(cpu, gicv3_cpuif_icc_apxr1_reginfo);
320
+ }
321
+ if (cs->prebits == 7) {
322
+ define_arm_cp_regs(cpu, gicv3_cpuif_icc_apxr23_reginfo);
323
+ }
324
+
325
if (arm_feature(&cpu->env, ARM_FEATURE_EL2)) {
326
int j;
327
58
--
328
--
59
2.7.4
329
2.25.1
60
61
diff view generated by jsdifflib
1
The M profile XPSR is almost the same format as the A profile CPSR,
1
Make the GICv3 set its number of bits of physical priority from the
2
but not quite. Define some XPSR_* macros and use them where we
2
implementation-specific value provided in the CPU state struct, in
3
definitely dealing with an XPSR rather than reusing the CPSR ones.
3
the same way we already do for virtual priority bits. Because this
4
would be a migration compatibility break, we provide a property
5
force-8-bit-prio which is enabled for 7.0 and earlier versioned board
6
models to retain the legacy "always use 8 bits" behaviour.
4
7
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
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>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 1501692241-23310-9-git-send-email-peter.maydell@linaro.org
10
Message-id: 20220512151457.3899052-6-peter.maydell@linaro.org
11
Message-id: 20220506162129.2896966-5-peter.maydell@linaro.org
9
---
12
---
10
target/arm/cpu.h | 38 ++++++++++++++++++++++++++++----------
13
include/hw/intc/arm_gicv3_common.h | 1 +
11
target/arm/helper.c | 15 ++++++++-------
14
target/arm/cpu.h | 1 +
12
2 files changed, 36 insertions(+), 17 deletions(-)
15
hw/core/machine.c | 4 +++-
16
hw/intc/arm_gicv3_common.c | 5 +++++
17
hw/intc/arm_gicv3_cpuif.c | 15 +++++++++++----
18
target/arm/cpu64.c | 6 ++++++
19
6 files changed, 27 insertions(+), 5 deletions(-)
13
20
21
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/intc/arm_gicv3_common.h
24
+++ b/include/hw/intc/arm_gicv3_common.h
25
@@ -XXX,XX +XXX,XX @@ struct GICv3State {
26
uint32_t revision;
27
bool lpi_enable;
28
bool security_extn;
29
+ bool force_8bit_prio;
30
bool irq_reset_nonsecure;
31
bool gicd_no_migration_shift_bug;
32
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
33
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
35
--- a/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
36
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ void pmccntr_sync(CPUARMState *env);
37
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
19
/* Mask of bits which may be set by exception return copying them from SPSR */
38
int gic_num_lrs; /* number of list registers */
20
#define CPSR_ERET_MASK (~CPSR_RESERVED)
39
int gic_vpribits; /* number of virtual priority bits */
21
40
int gic_vprebits; /* number of virtual preemption bits */
22
+/* Bit definitions for M profile XPSR. Most are the same as CPSR. */
41
+ int gic_pribits; /* number of physical priority bits */
23
+#define XPSR_EXCP 0x1ffU
42
24
+#define XPSR_SPREALIGN (1U << 9) /* Only set in exception stack frames */
43
/* Whether the cfgend input is high (i.e. this CPU should reset into
25
+#define XPSR_IT_2_7 CPSR_IT_2_7
44
* big-endian mode). This setting isn't used directly: instead it modifies
26
+#define XPSR_GE CPSR_GE
45
diff --git a/hw/core/machine.c b/hw/core/machine.c
27
+#define XPSR_SFPA (1U << 20) /* Only set in exception stack frames */
46
index XXXXXXX..XXXXXXX 100644
28
+#define XPSR_T (1U << 24) /* Not the same as CPSR_T ! */
47
--- a/hw/core/machine.c
29
+#define XPSR_IT_0_1 CPSR_IT_0_1
48
+++ b/hw/core/machine.c
30
+#define XPSR_Q CPSR_Q
49
@@ -XXX,XX +XXX,XX @@
31
+#define XPSR_V CPSR_V
50
#include "hw/virtio/virtio-pci.h"
32
+#define XPSR_C CPSR_C
51
#include "qom/object_interfaces.h"
33
+#define XPSR_Z CPSR_Z
52
34
+#define XPSR_N CPSR_N
53
-GlobalProperty hw_compat_7_0[] = {};
35
+#define XPSR_NZCV CPSR_NZCV
54
+GlobalProperty hw_compat_7_0[] = {
36
+#define XPSR_IT CPSR_IT
55
+ { "arm-gicv3-common", "force-8-bit-prio", "on" },
56
+};
57
const size_t hw_compat_7_0_len = G_N_ELEMENTS(hw_compat_7_0);
58
59
GlobalProperty hw_compat_6_2[] = {
60
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/intc/arm_gicv3_common.c
63
+++ b/hw/intc/arm_gicv3_common.c
64
@@ -XXX,XX +XXX,XX @@ static Property arm_gicv3_common_properties[] = {
65
DEFINE_PROP_UINT32("revision", GICv3State, revision, 3),
66
DEFINE_PROP_BOOL("has-lpi", GICv3State, lpi_enable, 0),
67
DEFINE_PROP_BOOL("has-security-extensions", GICv3State, security_extn, 0),
68
+ /*
69
+ * Compatibility property: force 8 bits of physical priority, even
70
+ * if the CPU being emulated should have fewer.
71
+ */
72
+ DEFINE_PROP_BOOL("force-8-bit-prio", GICv3State, force_8bit_prio, 0),
73
DEFINE_PROP_ARRAY("redist-region-count", GICv3State, nb_redist_regions,
74
redist_region_count, qdev_prop_uint32, uint32_t),
75
DEFINE_PROP_LINK("sysmem", GICv3State, dma, TYPE_MEMORY_REGION,
76
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/hw/intc/arm_gicv3_cpuif.c
79
+++ b/hw/intc/arm_gicv3_cpuif.c
80
@@ -XXX,XX +XXX,XX @@ void gicv3_init_cpuif(GICv3State *s)
81
* cpu->gic_num_lrs
82
* cpu->gic_vpribits
83
* cpu->gic_vprebits
84
+ * cpu->gic_pribits
85
*/
86
87
/* Note that we can't just use the GICv3CPUState as an opaque pointer
88
@@ -XXX,XX +XXX,XX @@ void gicv3_init_cpuif(GICv3State *s)
89
define_arm_cp_regs(cpu, gicv3_cpuif_reginfo);
90
91
/*
92
- * For the moment, retain the existing behaviour of 8 priority bits;
93
- * in a following commit we will take this from the CPU state,
94
- * as we do for the virtual priority bits.
95
+ * The CPU implementation specifies the number of supported
96
+ * bits of physical priority. For backwards compatibility
97
+ * of migration, we have a compat property that forces use
98
+ * of 8 priority bits regardless of what the CPU really has.
99
*/
100
- cs->pribits = 8;
101
+ if (s->force_8bit_prio) {
102
+ cs->pribits = 8;
103
+ } else {
104
+ cs->pribits = cpu->gic_pribits ?: 5;
105
+ }
37
+
106
+
38
#define TTBCR_N (7U << 0) /* TTBCR.EAE==0 */
107
/*
39
#define TTBCR_T0SZ (7U << 0) /* TTBCR.EAE==1 */
108
* The GICv3 has separate ID register fields for virtual priority
40
#define TTBCR_PD0 (1U << 4)
109
* and preemption bit values, but only a single ID register field
41
@@ -XXX,XX +XXX,XX @@ static inline uint32_t xpsr_read(CPUARMState *env)
110
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
42
/* Set the xPSR. Note that some bits of mask must be all-set or all-clear. */
111
index XXXXXXX..XXXXXXX 100644
43
static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
112
--- a/target/arm/cpu64.c
44
{
113
+++ b/target/arm/cpu64.c
45
- if (mask & CPSR_NZCV) {
114
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
46
- env->ZF = (~val) & CPSR_Z;
115
cpu->gic_num_lrs = 4;
47
+ if (mask & XPSR_NZCV) {
116
cpu->gic_vpribits = 5;
48
+ env->ZF = (~val) & XPSR_Z;
117
cpu->gic_vprebits = 5;
49
env->NF = val;
118
+ cpu->gic_pribits = 5;
50
env->CF = (val >> 29) & 1;
119
define_cortex_a72_a57_a53_cp_reginfo(cpu);
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
}
120
}
79
121
80
diff --git a/target/arm/helper.c b/target/arm/helper.c
122
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
81
index XXXXXXX..XXXXXXX 100644
123
cpu->gic_num_lrs = 4;
82
--- a/target/arm/helper.c
124
cpu->gic_vpribits = 5;
83
+++ b/target/arm/helper.c
125
cpu->gic_vprebits = 5;
84
@@ -XXX,XX +XXX,XX @@ static void v7m_push_stack(ARMCPU *cpu)
126
+ cpu->gic_pribits = 5;
85
/* Align stack pointer if the guest wants that */
127
define_cortex_a72_a57_a53_cp_reginfo(cpu);
86
if ((env->regs[13] & 4) && (env->v7m.ccr & R_V7M_CCR_STKALIGN_MASK)) {
128
}
87
env->regs[13] -= 4;
129
88
- xpsr |= 0x200;
130
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
89
+ xpsr |= XPSR_SPREALIGN;
131
cpu->gic_num_lrs = 4;
90
}
132
cpu->gic_vpribits = 5;
91
/* Switch to the handler mode. */
133
cpu->gic_vprebits = 5;
92
v7m_push(env, xpsr);
134
+ cpu->gic_pribits = 5;
93
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
135
define_cortex_a72_a57_a53_cp_reginfo(cpu);
94
env->regs[15] &= ~1U;
136
}
95
}
137
96
xpsr = v7m_pop(env);
138
@@ -XXX,XX +XXX,XX @@ static void aarch64_a76_initfn(Object *obj)
97
- xpsr_write(env, xpsr, 0xfffffdff);
139
cpu->gic_num_lrs = 4;
98
+ xpsr_write(env, xpsr, ~XPSR_SPREALIGN);
140
cpu->gic_vpribits = 5;
99
/* Undo stack alignment. */
141
cpu->gic_vprebits = 5;
100
- if (xpsr & 0x200)
142
+ cpu->gic_pribits = 5;
101
+ if (xpsr & XPSR_SPREALIGN) {
143
102
env->regs[13] |= 4;
144
/* From B5.1 AdvSIMD AArch64 register summary */
103
+ }
145
cpu->isar.mvfr0 = 0x10110222;
104
146
@@ -XXX,XX +XXX,XX @@ static void aarch64_neoverse_n1_initfn(Object *obj)
105
/* The restored xPSR exception field will be zero if we're
147
cpu->gic_num_lrs = 4;
106
* resuming in Thread mode. If that doesn't match what the
148
cpu->gic_vpribits = 5;
107
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
149
cpu->gic_vprebits = 5;
108
case 0 ... 7: /* xPSR sub-fields */
150
+ cpu->gic_pribits = 5;
109
mask = 0;
151
110
if ((reg & 1) && el) {
152
/* From B5.1 AdvSIMD AArch64 register summary */
111
- mask |= 0x000001ff; /* IPSR (unpriv. reads as zero) */
153
cpu->isar.mvfr0 = 0x10110222;
112
+ mask |= XPSR_EXCP; /* IPSR (unpriv. reads as zero) */
154
@@ -XXX,XX +XXX,XX @@ static void aarch64_a64fx_initfn(Object *obj)
113
}
155
cpu->gic_num_lrs = 4;
114
if (!(reg & 4)) {
156
cpu->gic_vpribits = 5;
115
- mask |= 0xf8000000; /* APSR */
157
cpu->gic_vprebits = 5;
116
+ mask |= XPSR_NZCV | XPSR_Q; /* APSR */
158
+ cpu->gic_pribits = 5;
117
}
159
118
/* EPSR reads as zero */
160
/* Suppport of A64FX's vector length are 128,256 and 512bit only */
119
return xpsr_read(env) & mask;
161
aarch64_add_sve_properties(obj);
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
--
162
--
134
2.7.4
163
2.25.1
135
136
diff view generated by jsdifflib
1
Implement the new do_transaction_failed hook for ARM, which should
1
We previously open-coded the expression for the number of virtual APR
2
cause the CPU to take a prefetch abort or data abort.
2
registers and the assertion that it was not going to cause us to
3
overflow the cs->ich_apr[] array. Factor this out into a new
4
ich_num_aprs() function, for consistency with the icc_num_aprs()
5
function we just added for the physical APR handling.
3
6
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Message-id: 20220512151457.3899052-7-peter.maydell@linaro.org
10
Message-id: 20220506162129.2896966-6-peter.maydell@linaro.org
7
---
11
---
8
target/arm/internals.h | 10 ++++++++++
12
hw/intc/arm_gicv3_cpuif.c | 16 ++++++++++------
9
target/arm/cpu.c | 1 +
13
1 file changed, 10 insertions(+), 6 deletions(-)
10
target/arm/op_helper.c | 43 +++++++++++++++++++++++++++++++++++++++++++
11
3 files changed, 54 insertions(+)
12
14
13
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/internals.h
17
--- a/hw/intc/arm_gicv3_cpuif.c
16
+++ b/target/arm/internals.h
18
+++ b/hw/intc/arm_gicv3_cpuif.c
17
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
19
@@ -XXX,XX +XXX,XX @@ static inline int icv_min_vbpr(GICv3CPUState *cs)
18
MMUAccessType access_type,
20
return 7 - cs->vprebits;
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
}
21
}
53
22
54
+/* arm_cpu_do_transaction_failed: handle a memory system error response
23
+static inline int ich_num_aprs(GICv3CPUState *cs)
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
+{
24
+{
64
+ ARMCPU *cpu = ARM_CPU(cs);
25
+ /* Return the number of virtual APR registers (1, 2, or 4) */
65
+ CPUARMState *env = &cpu->env;
26
+ int aprmax = 1 << (cs->vprebits - 5);
66
+ uint32_t fsr, fsc;
27
+ assert(aprmax <= ARRAY_SIZE(cs->ich_apr[0]));
67
+ ARMMMUFaultInfo fi = {};
28
+ return aprmax;
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
+}
29
+}
96
+
30
+
97
#endif /* !defined(CONFIG_USER_ONLY) */
31
/* Simple accessor functions for LR fields */
98
32
static uint32_t ich_lr_vintid(uint64_t lr)
99
uint32_t HELPER(add_setq)(CPUARMState *env, uint32_t a, uint32_t b)
33
{
34
@@ -XXX,XX +XXX,XX @@ static int ich_highest_active_virt_prio(GICv3CPUState *cs)
35
* in the ICH Active Priority Registers.
36
*/
37
int i;
38
- int aprmax = 1 << (cs->vprebits - 5);
39
-
40
- assert(aprmax <= ARRAY_SIZE(cs->ich_apr[0]));
41
+ int aprmax = ich_num_aprs(cs);
42
43
for (i = 0; i < aprmax; i++) {
44
uint32_t apr = cs->ich_apr[GICV3_G0][i] |
45
@@ -XXX,XX +XXX,XX @@ static int icv_drop_prio(GICv3CPUState *cs)
46
* 32 bits are actually relevant.
47
*/
48
int i;
49
- int aprmax = 1 << (cs->vprebits - 5);
50
-
51
- assert(aprmax <= ARRAY_SIZE(cs->ich_apr[0]));
52
+ int aprmax = ich_num_aprs(cs);
53
54
for (i = 0; i < aprmax; i++) {
55
uint64_t *papr0 = &cs->ich_apr[GICV3_G0][i];
100
--
56
--
101
2.7.4
57
2.25.1
102
103
diff view generated by jsdifflib
1
Currently get_phys_addr() has PMSAv7 handling before the
1
From: Chris Howard <cvz185@web.de>
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
2
3
Give all the debug registers their correct names including the
4
index, rather than having multiple registers all with the
5
same name string, which is confusing when viewed over the
6
gdbstub interface.
7
8
Signed-off-by: CHRIS HOWARD <cvz185@web.de>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 4127D8CA-D54A-47C7-A039-0DB7361E30C0@web.de
11
[PMM: expanded commit message]
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
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
---
13
---
15
target/arm/helper.c | 38 ++++++++++++++++++++++----------------
14
target/arm/helper.c | 16 ++++++++++++----
16
1 file changed, 22 insertions(+), 16 deletions(-)
15
1 file changed, 12 insertions(+), 4 deletions(-)
17
16
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.c
19
--- a/target/arm/helper.c
21
+++ b/target/arm/helper.c
20
+++ b/target/arm/helper.c
22
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
21
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
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
}
22
}
39
23
40
- /* pmsav7 has special handling for when MPU is disabled so call it before
24
for (i = 0; i < brps; i++) {
41
- * the common MMU/MPU disabled check below.
25
+ char *dbgbvr_el1_name = g_strdup_printf("DBGBVR%d_EL1", i);
42
- */
26
+ char *dbgbcr_el1_name = g_strdup_printf("DBGBCR%d_EL1", i);
43
- if (arm_feature(env, ARM_FEATURE_PMSA) &&
27
ARMCPRegInfo dbgregs[] = {
44
- arm_feature(env, ARM_FEATURE_V7)) {
28
- { .name = "DBGBVR", .state = ARM_CP_STATE_BOTH,
45
+ if (arm_feature(env, ARM_FEATURE_PMSA)) {
29
+ { .name = dbgbvr_el1_name, .state = ARM_CP_STATE_BOTH,
46
bool ret;
30
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,
47
*page_size = TARGET_PAGE_SIZE;
31
.access = PL1_RW, .accessfn = access_tda,
48
- ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
32
.fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]),
49
- phys_ptr, prot, fsr);
33
.writefn = dbgbvr_write, .raw_writefn = raw_write
50
- qemu_log_mask(CPU_LOG_MMU, "PMSAv7 MPU lookup for %s at 0x%08" PRIx32
34
},
51
+
35
- { .name = "DBGBCR", .state = ARM_CP_STATE_BOTH,
52
+ if (arm_feature(env, ARM_FEATURE_V7)) {
36
+ { .name = dbgbcr_el1_name, .state = ARM_CP_STATE_BOTH,
53
+ /* PMSAv7 */
37
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5,
54
+ ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
38
.access = PL1_RW, .accessfn = access_tda,
55
+ phys_ptr, prot, fsr);
39
.fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]),
56
+ } else {
40
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
57
+ /* Pre-v7 MPU */
41
},
58
+ ret = get_phys_addr_pmsav5(env, address, access_type, mmu_idx,
42
};
59
+ phys_ptr, prot, fsr);
43
define_arm_cp_regs(cpu, dbgregs);
60
+ }
44
+ g_free(dbgbvr_el1_name);
61
+ qemu_log_mask(CPU_LOG_MMU, "PMSA MPU lookup for %s at 0x%08" PRIx32
45
+ g_free(dbgbcr_el1_name);
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
}
46
}
68
47
69
+ /* Definitely a real MMU, not an MPU */
48
for (i = 0; i < wrps; i++) {
70
+
49
+ char *dbgwvr_el1_name = g_strdup_printf("DBGWVR%d_EL1", i);
71
if (regime_translation_disabled(env, mmu_idx)) {
50
+ char *dbgwcr_el1_name = g_strdup_printf("DBGWCR%d_EL1", i);
72
- /* MMU/MPU disabled. */
51
ARMCPRegInfo dbgregs[] = {
73
+ /* MMU disabled. */
52
- { .name = "DBGWVR", .state = ARM_CP_STATE_BOTH,
74
*phys_ptr = address;
53
+ { .name = dbgwvr_el1_name, .state = ARM_CP_STATE_BOTH,
75
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
54
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,
76
*page_size = TARGET_PAGE_SIZE;
55
.access = PL1_RW, .accessfn = access_tda,
77
return 0;
56
.fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]),
57
.writefn = dbgwvr_write, .raw_writefn = raw_write
58
},
59
- { .name = "DBGWCR", .state = ARM_CP_STATE_BOTH,
60
+ { .name = dbgwcr_el1_name, .state = ARM_CP_STATE_BOTH,
61
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7,
62
.access = PL1_RW, .accessfn = access_tda,
63
.fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]),
64
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
65
},
66
};
67
define_arm_cp_regs(cpu, dbgregs);
68
+ g_free(dbgwvr_el1_name);
69
+ g_free(dbgwcr_el1_name);
78
}
70
}
79
71
}
80
- if (arm_feature(env, ARM_FEATURE_PMSA)) {
72
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
--
73
--
91
2.7.4
74
2.25.1
92
93
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Except hw/core/irq.c which implements the forward-declared opaque
4
qemu_irq structure, hw/adc/zynq-xadc.{c,h} are the only files not
5
using the typedef. Fix this single exception.
6
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Bernhard Beschow <shentey@gmail.com>
9
Message-id: 20220509202035.50335-1-philippe.mathieu.daude@gmail.com
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
---
11
---
7
hw/arm/armv7m.c | 4 ++--
12
include/hw/adc/zynq-xadc.h | 3 +--
8
hw/arm/exynos4210.c | 4 ++--
13
hw/adc/zynq-xadc.c | 4 ++--
9
hw/arm/highbank.c | 11 +++++++----
14
2 files changed, 3 insertions(+), 4 deletions(-)
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
15
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
16
diff --git a/include/hw/adc/zynq-xadc.h b/include/hw/adc/zynq-xadc.h
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/armv7m.c
18
--- a/include/hw/adc/zynq-xadc.h
18
+++ b/hw/arm/armv7m.c
19
+++ b/include/hw/adc/zynq-xadc.h
19
@@ -XXX,XX +XXX,XX @@ static void armv7m_instance_init(Object *obj)
20
@@ -XXX,XX +XXX,XX @@ struct ZynqXADCState {
20
&error_abort);
21
uint16_t xadc_dfifo[ZYNQ_XADC_FIFO_DEPTH];
21
memory_region_init(&s->container, obj, "armv7m-container", UINT64_MAX);
22
uint16_t xadc_dfifo_entries;
22
23
23
- object_initialize(&s->nvic, sizeof(s->nvic), "armv7m_nvic");
24
- struct IRQState *qemu_irq;
24
+ object_initialize(&s->nvic, sizeof(s->nvic), TYPE_NVIC);
25
-
25
qdev_set_parent_bus(DEVICE(&s->nvic), sysbus_get_default());
26
+ qemu_irq irq;
26
object_property_add_alias(obj, "num-irq",
27
};
27
OBJECT(&s->nvic), "num-irq", &error_abort);
28
28
@@ -XXX,XX +XXX,XX @@ DeviceState *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
29
#endif /* ZYNQ_XADC_H */
29
cpu_model = "cortex-m3";
30
diff --git a/hw/adc/zynq-xadc.c b/hw/adc/zynq-xadc.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/adc/zynq-xadc.c
33
+++ b/hw/adc/zynq-xadc.c
34
@@ -XXX,XX +XXX,XX @@ static void zynq_xadc_update_ints(ZynqXADCState *s)
35
s->regs[INT_STS] |= INT_DFIFO_GTH;
30
}
36
}
31
37
32
- armv7m = qdev_create(NULL, "armv7m");
38
- qemu_set_irq(s->qemu_irq, !!(s->regs[INT_STS] & ~s->regs[INT_MASK]));
33
+ armv7m = qdev_create(NULL, TYPE_ARMV7M);
39
+ qemu_set_irq(s->irq, !!(s->regs[INT_STS] & ~s->regs[INT_MASK]));
34
qdev_prop_set_uint32(armv7m, "num-irq", num_irq);
40
}
35
qdev_prop_set_string(armv7m, "cpu-model", cpu_model);
41
36
object_property_set_link(OBJECT(armv7m), OBJECT(get_system_memory()),
42
static void zynq_xadc_reset(DeviceState *d)
37
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
43
@@ -XXX,XX +XXX,XX @@ static void zynq_xadc_init(Object *obj)
38
index XXXXXXX..XXXXXXX 100644
44
memory_region_init_io(&s->iomem, obj, &xadc_ops, s, "zynq-xadc",
39
--- a/hw/arm/exynos4210.c
45
ZYNQ_XADC_MMIO_SIZE);
40
+++ b/hw/arm/exynos4210.c
46
sysbus_init_mmio(sbd, &s->iomem);
41
@@ -XXX,XX +XXX,XX @@
47
- sysbus_init_irq(sbd, &s->qemu_irq);
42
#include "hw/arm/arm.h"
48
+ sysbus_init_irq(sbd, &s->irq);
43
#include "hw/loader.h"
49
}
44
#include "hw/arm/exynos4210.h"
50
45
-#include "hw/sd/sd.h"
51
static const VMStateDescription vmstate_zynq_xadc = {
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
--
52
--
222
2.7.4
53
2.25.1
223
54
224
55
diff view generated by jsdifflib
1
Move the code in arm_v7m_cpu_do_interrupt() that calculates the
1
In commit 88ce6c6ee85d we switched from directly fishing the number
2
magic LR value down to when we're actually going to use it.
2
of breakpoints and watchpoints out of the ID register fields to
3
Having the calculation and use so far apart makes the code
3
abstracting out functions to do this job, but we forgot to delete the
4
a little harder to understand than it needs to be.
4
now-obsolete comment in define_debug_regs() about the relation
5
between the ID field value and the actual number of breakpoints and
6
watchpoints. Delete the obsolete comment.
5
7
8
Reported-by: CHRIS HOWARD <cvz185@web.de>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 1501692241-23310-13-git-send-email-peter.maydell@linaro.org
12
Message-id: 20220513131801.4082712-1-peter.maydell@linaro.org
11
---
13
---
12
target/arm/helper.c | 15 ++++++++-------
14
target/arm/helper.c | 1 -
13
1 file changed, 8 insertions(+), 7 deletions(-)
15
1 file changed, 1 deletion(-)
14
16
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
19
--- a/target/arm/helper.c
18
+++ b/target/arm/helper.c
20
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
21
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
20
22
define_one_arm_cp_reg(cpu, &dbgdidr);
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
}
23
}
36
24
37
+ lr = 0xfffffff1;
25
- /* Note that all these register fields hold "number of Xs minus 1". */
38
+ if (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) {
26
brps = arm_num_brps(cpu);
39
+ lr |= 4;
27
wrps = arm_num_wrps(cpu);
40
+ }
28
ctx_cmps = arm_num_ctx_cmps(cpu);
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
--
29
--
49
2.7.4
30
2.25.1
50
31
51
32
diff view generated by jsdifflib
1
In the ARM get_phys_addr() code, switch to using the MMUAccessType
1
Currently we give all the v7-and-up CPUs a PMU with 4 counters. This
2
enum and its MMU_* values rather than int and literal 0/1/2.
2
means that we don't provide the 6 counters that are required by the
3
Arm BSA (Base System Architecture) specification if the CPU supports
4
the Virtualization extensions.
5
6
Instead of having a single PMCR_NUM_COUNTERS, make each CPU type
7
specify the PMCR reset value (obtained from the appropriate TRM), and
8
use the 'N' field of that value to define the number of counters
9
provided.
10
11
This means that we now supply 6 counters instead of 4 for:
12
Cortex-A9, Cortex-A15, Cortex-A53, Cortex-A57, Cortex-A72,
13
Cortex-A76, Neoverse-N1, '-cpu max'
14
This CPU goes from 4 to 8 counters:
15
A64FX
16
These CPUs remain with 4 counters:
17
Cortex-A7, Cortex-A8
18
This CPU goes down from 4 to 3 counters:
19
Cortex-R5
20
21
Note that because we now use the PMCR reset value of the specific
22
implementation, we no longer set the LC bit out of reset. This has
23
an UNKNOWN value out of reset for all cores with any AArch32 support,
24
so guest software should be setting it anyway if it wants it.
25
26
This change was originally landed in commit f7fb73b8cdd3f7 (during
27
the 6.0 release cycle) but was then reverted by commit
28
21c2dd77a6aa517 before that release because it did not work with KVM.
29
This version fixes that by creating the scratch vCPU in
30
kvm_arm_get_host_cpu_features() with the KVM_ARM_VCPU_PMU_V3 feature
31
if KVM supports it, and then only asking KVM for the PMCR_EL0 value
32
if the vCPU has a PMU.
3
33
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
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>
35
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 1501692241-23310-2-git-send-email-peter.maydell@linaro.org
36
[PMM: Added the correct value for a64fx]
37
Message-id: 20220513122852.4063586-1-peter.maydell@linaro.org
9
---
38
---
10
target/arm/internals.h | 3 ++-
39
target/arm/cpu.h | 1 +
11
target/arm/helper.c | 30 +++++++++++++++---------------
40
target/arm/internals.h | 4 +++-
12
2 files changed, 17 insertions(+), 16 deletions(-)
41
target/arm/cpu64.c | 11 +++++++++++
13
42
target/arm/cpu_tcg.c | 6 ++++++
43
target/arm/helper.c | 25 ++++++++++++++-----------
44
target/arm/kvm64.c | 12 ++++++++++++
45
6 files changed, 47 insertions(+), 12 deletions(-)
46
47
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/cpu.h
50
+++ b/target/arm/cpu.h
51
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
52
uint64_t id_aa64dfr0;
53
uint64_t id_aa64dfr1;
54
uint64_t id_aa64zfr0;
55
+ uint64_t reset_pmcr_el0;
56
} isar;
57
uint64_t midr;
58
uint32_t revidr;
14
diff --git a/target/arm/internals.h b/target/arm/internals.h
59
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
60
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/internals.h
61
--- a/target/arm/internals.h
17
+++ b/target/arm/internals.h
62
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@ struct ARMMMUFaultInfo {
63
@@ -XXX,XX +XXX,XX @@ enum MVEECIState {
19
};
64
20
65
static inline uint32_t pmu_num_counters(CPUARMState *env)
21
/* Do a page table walk and add page to TLB if possible */
66
{
22
-bool arm_tlb_fill(CPUState *cpu, vaddr address, int rw, int mmu_idx,
67
- return (env->cp15.c9_pmcr & PMCRN_MASK) >> PMCRN_SHIFT;
23
+bool arm_tlb_fill(CPUState *cpu, vaddr address,
68
+ ARMCPU *cpu = env_archcpu(env);
24
+ MMUAccessType access_type, int mmu_idx,
69
+
25
uint32_t *fsr, ARMMMUFaultInfo *fi);
70
+ return (cpu->isar.reset_pmcr_el0 & PMCRN_MASK) >> PMCRN_SHIFT;
26
71
}
27
/* Return true if the stage 1 translation regime is using LPAE format page
72
73
/* Bits allowed to be set/cleared for PMCNTEN* and PMINTEN* */
74
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/arm/cpu64.c
77
+++ b/target/arm/cpu64.c
78
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
79
cpu->isar.id_aa64isar0 = 0x00011120;
80
cpu->isar.id_aa64mmfr0 = 0x00001124;
81
cpu->isar.dbgdidr = 0x3516d000;
82
+ cpu->isar.reset_pmcr_el0 = 0x41013000;
83
cpu->clidr = 0x0a200023;
84
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
85
cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */
86
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
87
cpu->isar.id_aa64isar0 = 0x00011120;
88
cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
89
cpu->isar.dbgdidr = 0x3516d000;
90
+ cpu->isar.reset_pmcr_el0 = 0x41033000;
91
cpu->clidr = 0x0a200023;
92
cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
93
cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */
94
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
95
cpu->isar.id_aa64isar0 = 0x00011120;
96
cpu->isar.id_aa64mmfr0 = 0x00001124;
97
cpu->isar.dbgdidr = 0x3516d000;
98
+ cpu->isar.reset_pmcr_el0 = 0x41023000;
99
cpu->clidr = 0x0a200023;
100
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
101
cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */
102
@@ -XXX,XX +XXX,XX @@ static void aarch64_a76_initfn(Object *obj)
103
cpu->isar.mvfr0 = 0x10110222;
104
cpu->isar.mvfr1 = 0x13211111;
105
cpu->isar.mvfr2 = 0x00000043;
106
+
107
+ /* From D5.1 AArch64 PMU register summary */
108
+ cpu->isar.reset_pmcr_el0 = 0x410b3000;
109
}
110
111
static void aarch64_neoverse_n1_initfn(Object *obj)
112
@@ -XXX,XX +XXX,XX @@ static void aarch64_neoverse_n1_initfn(Object *obj)
113
cpu->isar.mvfr0 = 0x10110222;
114
cpu->isar.mvfr1 = 0x13211111;
115
cpu->isar.mvfr2 = 0x00000043;
116
+
117
+ /* From D5.1 AArch64 PMU register summary */
118
+ cpu->isar.reset_pmcr_el0 = 0x410c3000;
119
}
120
121
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
122
@@ -XXX,XX +XXX,XX @@ static void aarch64_a64fx_initfn(Object *obj)
123
set_bit(1, cpu->sve_vq_supported); /* 256bit */
124
set_bit(3, cpu->sve_vq_supported); /* 512bit */
125
126
+ cpu->isar.reset_pmcr_el0 = 0x46014040;
127
+
128
/* TODO: Add A64FX specific HPC extension registers */
129
}
130
131
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/target/arm/cpu_tcg.c
134
+++ b/target/arm/cpu_tcg.c
135
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
136
cpu->ccsidr[1] = 0x2007e01a; /* 16k L1 icache. */
137
cpu->ccsidr[2] = 0xf0000000; /* No L2 icache. */
138
cpu->reset_auxcr = 2;
139
+ cpu->isar.reset_pmcr_el0 = 0x41002000;
140
define_arm_cp_regs(cpu, cortexa8_cp_reginfo);
141
}
142
143
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
144
cpu->clidr = (1 << 27) | (1 << 24) | 3;
145
cpu->ccsidr[0] = 0xe00fe019; /* 16k L1 dcache. */
146
cpu->ccsidr[1] = 0x200fe019; /* 16k L1 icache. */
147
+ cpu->isar.reset_pmcr_el0 = 0x41093000;
148
define_arm_cp_regs(cpu, cortexa9_cp_reginfo);
149
}
150
151
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
152
cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
153
cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
154
cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */
155
+ cpu->isar.reset_pmcr_el0 = 0x41072000;
156
define_arm_cp_regs(cpu, cortexa15_cp_reginfo); /* Same as A15 */
157
}
158
159
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
160
cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
161
cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
162
cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */
163
+ cpu->isar.reset_pmcr_el0 = 0x410F3000;
164
define_arm_cp_regs(cpu, cortexa15_cp_reginfo);
165
}
166
167
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
168
cpu->isar.id_isar6 = 0x0;
169
cpu->mp_is_up = true;
170
cpu->pmsav7_dregion = 16;
171
+ cpu->isar.reset_pmcr_el0 = 0x41151800;
172
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
173
}
174
175
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
176
cpu->isar.id_isar5 = 0x00011121;
177
cpu->isar.id_isar6 = 0;
178
cpu->isar.dbgdidr = 0x3516d000;
179
+ cpu->isar.reset_pmcr_el0 = 0x41013000;
180
cpu->clidr = 0x0a200023;
181
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
182
cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */
28
diff --git a/target/arm/helper.c b/target/arm/helper.c
183
diff --git a/target/arm/helper.c b/target/arm/helper.c
29
index XXXXXXX..XXXXXXX 100644
184
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/helper.c
185
--- a/target/arm/helper.c
31
+++ b/target/arm/helper.c
186
+++ b/target/arm/helper.c
32
@@ -XXX,XX +XXX,XX @@
187
@@ -XXX,XX +XXX,XX @@
188
#include "cpregs.h"
189
190
#define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */
191
-#define PMCR_NUM_COUNTERS 4 /* QEMU IMPDEF choice */
33
192
34
#ifndef CONFIG_USER_ONLY
193
#ifndef CONFIG_USER_ONLY
35
static bool get_phys_addr(CPUARMState *env, target_ulong address,
194
36
- int access_type, ARMMMUIdx mmu_idx,
195
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
37
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
196
.resetvalue = 0,
38
hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
197
.writefn = gt_hyp_ctl_write, .raw_writefn = raw_write },
39
target_ulong *page_size, uint32_t *fsr,
198
#endif
40
ARMMMUFaultInfo *fi);
199
- /* The only field of MDCR_EL2 that has a defined architectural reset value
41
200
- * is MDCR_EL2.HPMN which should reset to the value of PMCR_EL0.N.
42
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
201
- */
43
- int access_type, ARMMMUIdx mmu_idx,
202
- { .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH,
44
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
203
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1,
45
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
204
- .access = PL2_RW, .resetvalue = PMCR_NUM_COUNTERS,
46
target_ulong *page_size_ptr, uint32_t *fsr,
205
- .fieldoffset = offsetof(CPUARMState, cp15.mdcr_el2), },
47
ARMMMUFaultInfo *fi);
206
{ .name = "HPFAR", .state = ARM_CP_STATE_AA32,
48
@@ -XXX,XX +XXX,XX @@ static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri,
207
.cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4,
49
}
208
.access = PL2_RW, .accessfn = access_el3_aa32ns,
50
209
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
51
static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
210
* field as main ID register, and we implement four counters in
52
- int access_type, ARMMMUIdx mmu_idx)
211
* addition to the cycle count register.
53
+ MMUAccessType access_type, ARMMMUIdx mmu_idx)
212
*/
54
{
213
- unsigned int i, pmcrn = PMCR_NUM_COUNTERS;
55
hwaddr phys_addr;
214
+ unsigned int i, pmcrn = pmu_num_counters(&cpu->env);
56
target_ulong page_size;
215
ARMCPRegInfo pmcr = {
57
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
216
.name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
58
217
.access = PL0_RW,
59
static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
218
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
60
{
219
.access = PL0_RW, .accessfn = pmreg_access,
61
- int access_type = ri->opc2 & 1;
220
.type = ARM_CP_IO,
62
+ MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD;
221
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
63
uint64_t par64;
222
- .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT) |
64
ARMMMUIdx mmu_idx;
223
- PMCRLC,
65
int el = arm_current_el(env);
224
+ .resetvalue = cpu->isar.reset_pmcr_el0,
66
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
225
.writefn = pmcr_write, .raw_writefn = raw_write,
67
static void ats1h_write(CPUARMState *env, const ARMCPRegInfo *ri,
226
};
68
uint64_t value)
227
+
69
{
228
define_one_arm_cp_reg(cpu, &pmcr);
70
- int access_type = ri->opc2 & 1;
229
define_one_arm_cp_reg(cpu, &pmcr64);
71
+ MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD;
230
for (i = 0; i < pmcrn; i++) {
72
uint64_t par64;
231
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
73
232
.type = ARM_CP_EL3_NO_EL2_C_NZ,
74
par64 = do_ats_write(env, value, access_type, ARMMMUIdx_S2NS);
233
.fieldoffset = offsetof(CPUARMState, cp15.vmpidr_el2) },
75
@@ -XXX,XX +XXX,XX @@ static CPAccessResult at_s1e2_access(CPUARMState *env, const ARMCPRegInfo *ri,
234
};
76
static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
235
+ /*
77
uint64_t value)
236
+ * The only field of MDCR_EL2 that has a defined architectural reset
78
{
237
+ * value is MDCR_EL2.HPMN which should reset to the value of PMCR_EL0.N.
79
- int access_type = ri->opc2 & 1;
238
+ */
80
+ MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD;
239
+ ARMCPRegInfo mdcr_el2 = {
81
ARMMMUIdx mmu_idx;
240
+ .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH,
82
int secure = arm_is_secure_below_el3(env);
241
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1,
83
242
+ .access = PL2_RW, .resetvalue = pmu_num_counters(env),
84
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
243
+ .fieldoffset = offsetof(CPUARMState, cp15.mdcr_el2),
85
}
244
+ };
86
245
+ define_one_arm_cp_reg(cpu, &mdcr_el2);
87
static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
246
define_arm_cp_regs(cpu, vpidr_regs);
88
- int access_type, ARMMMUIdx mmu_idx,
247
define_arm_cp_regs(cpu, el2_cp_reginfo);
89
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
248
if (arm_feature(env, ARM_FEATURE_V8)) {
90
hwaddr *phys_ptr, int *prot,
249
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
91
target_ulong *page_size, uint32_t *fsr,
250
index XXXXXXX..XXXXXXX 100644
92
ARMMMUFaultInfo *fi)
251
--- a/target/arm/kvm64.c
93
@@ -XXX,XX +XXX,XX @@ do_fault:
252
+++ b/target/arm/kvm64.c
94
}
253
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
95
254
*/
96
static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
255
int fdarray[3];
97
- int access_type, ARMMMUIdx mmu_idx,
256
bool sve_supported;
98
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
257
+ bool pmu_supported = false;
99
hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
258
uint64_t features = 0;
100
target_ulong *page_size, uint32_t *fsr,
259
uint64_t t;
101
ARMMMUFaultInfo *fi)
260
int err;
102
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
261
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
103
if (pxn && !regime_is_user(env, mmu_idx)) {
262
1 << KVM_ARM_VCPU_PTRAUTH_GENERIC);
104
xn = 1;
263
}
264
265
+ if (kvm_arm_pmu_supported()) {
266
+ init.features[0] |= 1 << KVM_ARM_VCPU_PMU_V3;
267
+ pmu_supported = true;
268
+ }
269
+
270
if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) {
271
return false;
272
}
273
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
274
dbgdidr |= (1 << 15); /* RES1 bit */
275
ahcf->isar.dbgdidr = dbgdidr;
105
}
276
}
106
- if (xn && access_type == 2)
277
+
107
+ if (xn && access_type == MMU_INST_FETCH)
278
+ if (pmu_supported) {
108
goto do_fault;
279
+ /* PMCR_EL0 is only accessible if the vCPU has feature PMU_V3 */
109
280
+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.reset_pmcr_el0,
110
if (arm_feature(env, ARM_FEATURE_V6K) &&
281
+ ARM64_SYS_REG(3, 3, 9, 12, 0));
111
@@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
282
+ }
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
}
283
}
141
284
142
- if (access_type == 2) {
285
sve_supported = ioctl(fdarray[0], KVM_CHECK_EXTENSION, KVM_CAP_ARM_SVE) > 0;
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
--
286
--
166
2.7.4
287
2.25.1
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
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
1
From: Andrew Jones <drjones@redhat.com>
1
In the virt board with secure=on we put two nodes in the dtb
2
for flash devices: one for the secure-only flash, and one
3
for the non-secure flash. We get the reg properties for these
4
correct, but in the DT node name, which by convention includes
5
the base address of devices, we used the wrong address. Fix it.
2
6
3
If a KVM PMU init or set-irq attr call fails we just silently stop
7
Spotted by dtc, which will complain
4
the PMU DT node generation. The only way they could fail, though,
8
Warning (unique_unit_address): /flash@0: duplicate unit-address (also used in node /secflash@0)
5
is if the attr's respective KVM has-attr call fails. But that should
9
if you dump the dtb from QEMU with -machine dumpdtb=file.dtb
6
never happen if KVM advertises the PMU capability, because both
10
and then decompile it with dtc.
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
11
11
Signed-off-by: Andrew Jones <drjones@redhat.com>
12
Reviewed-by: Christoffer Dall <cdall@linaro.org>
13
Message-id: 1500471597-2517-5-git-send-email-drjones@redhat.com
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20220513131316.4081539-2-peter.maydell@linaro.org
16
---
15
---
17
target/arm/kvm_arm.h | 15 ++++-----------
16
hw/arm/virt.c | 2 +-
18
hw/arm/virt.c | 9 +++------
17
1 file changed, 1 insertion(+), 1 deletion(-)
19
target/arm/kvm32.c | 3 +--
20
target/arm/kvm64.c | 28 ++++++++++++++++++++--------
21
4 files changed, 28 insertions(+), 27 deletions(-)
22
18
23
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/kvm_arm.h
26
+++ b/target/arm/kvm_arm.h
27
@@ -XXX,XX +XXX,XX @@ int kvm_arm_sync_mpstate_to_qemu(ARMCPU *cpu);
28
29
int kvm_arm_vgic_probe(void);
30
31
-int kvm_arm_pmu_set_irq(CPUState *cs, int irq);
32
-int kvm_arm_pmu_init(CPUState *cs);
33
+void kvm_arm_pmu_set_irq(CPUState *cs, int irq);
34
+void kvm_arm_pmu_init(CPUState *cs);
35
36
#else
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
19
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
57
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/arm/virt.c
21
--- a/hw/arm/virt.c
59
+++ b/hw/arm/virt.c
22
+++ b/hw/arm/virt.c
60
@@ -XXX,XX +XXX,XX @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
23
@@ -XXX,XX +XXX,XX @@ static void virt_flash_fdt(VirtMachineState *vms,
61
return;
24
qemu_fdt_setprop_string(ms->fdt, nodename, "secure-status", "okay");
62
}
25
g_free(nodename);
63
if (kvm_enabled()) {
26
64
- if (kvm_irqchip_in_kernel() &&
27
- nodename = g_strdup_printf("/flash@%" PRIx64, flashbase);
65
- !kvm_arm_pmu_set_irq(cpu, PPI(VIRTUAL_PMU_IRQ))) {
28
+ nodename = g_strdup_printf("/flash@%" PRIx64, flashbase + flashsize);
66
- return;
29
qemu_fdt_add_subnode(ms->fdt, nodename);
67
- }
30
qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "cfi-flash");
68
- if (!kvm_arm_pmu_init(cpu)) {
31
qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg",
69
- return;
70
+ if (kvm_irqchip_in_kernel()) {
71
+ kvm_arm_pmu_set_irq(cpu, PPI(VIRTUAL_PMU_IRQ));
72
}
73
+ kvm_arm_pmu_init(cpu);
74
}
75
}
76
77
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/kvm32.c
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
}
104
105
err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, attr);
106
- if (err < 0) {
107
- fprintf(stderr, "KVM_SET_DEVICE_ATTR failed: %s\n",
108
- strerror(-err));
109
- abort();
110
+ if (err != 0) {
111
+ error_report("PMU: KVM_SET_DEVICE_ATTR: %s", strerror(-err));
112
+ return false;
113
}
114
115
return true;
116
}
117
118
-int kvm_arm_pmu_init(CPUState *cs)
119
+void kvm_arm_pmu_init(CPUState *cs)
120
{
121
struct kvm_device_attr attr = {
122
.group = KVM_ARM_VCPU_PMU_V3_CTRL,
123
.attr = KVM_ARM_VCPU_PMU_V3_INIT,
124
};
125
126
- return kvm_arm_pmu_set_attr(cs, &attr);
127
+ if (!ARM_CPU(cs)->has_pmu) {
128
+ return;
129
+ }
130
+ if (!kvm_arm_pmu_set_attr(cs, &attr)) {
131
+ error_report("failed to init PMU");
132
+ abort();
133
+ }
134
}
135
136
-int kvm_arm_pmu_set_irq(CPUState *cs, int irq)
137
+void kvm_arm_pmu_set_irq(CPUState *cs, int irq)
138
{
139
struct kvm_device_attr attr = {
140
.group = KVM_ARM_VCPU_PMU_V3_CTRL,
141
@@ -XXX,XX +XXX,XX @@ int kvm_arm_pmu_set_irq(CPUState *cs, int irq)
142
.attr = KVM_ARM_VCPU_PMU_V3_IRQ,
143
};
144
145
- return kvm_arm_pmu_set_attr(cs, &attr);
146
+ if (!ARM_CPU(cs)->has_pmu) {
147
+ return;
148
+ }
149
+ if (!kvm_arm_pmu_set_attr(cs, &attr)) {
150
+ error_report("failed to set irq for PMU");
151
+ abort();
152
+ }
153
}
154
155
static inline void set_feature(uint64_t *features, int feature)
156
--
32
--
157
2.7.4
33
2.25.1
158
159
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
The virt board generates a gpio-keys node in the dtb, but it
2
incorrectly gives this node #size-cells and #address-cells
3
properties. If you dump the dtb with 'machine dumpdtb=file.dtb'
4
and run it through dtc, dtc will warn about this:
2
5
3
Move the in-kernel-irqchip test to only guard the set-irq
6
Warning (avoid_unnecessary_addr_size): /gpio-keys: unnecessary #address-cells/#size-cells without "ranges" or child "reg" property
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
7
Signed-off-by: Andrew Jones <drjones@redhat.com>
8
Remove the bogus properties.
8
Reviewed-by: Christoffer Dall <cdall@linaro.org>
9
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>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20220513131316.4081539-3-peter.maydell@linaro.org
12
---
13
---
13
hw/arm/virt.c | 3 ++-
14
hw/arm/virt.c | 2 --
14
target/arm/kvm.c | 6 +++++-
15
1 file changed, 2 deletions(-)
15
target/arm/kvm64.c | 3 +--
16
3 files changed, 8 insertions(+), 4 deletions(-)
17
16
18
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
19
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/virt.c
19
--- a/hw/arm/virt.c
21
+++ b/hw/arm/virt.c
20
+++ b/hw/arm/virt.c
22
@@ -XXX,XX +XXX,XX @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
21
@@ -XXX,XX +XXX,XX @@ static void create_gpio_keys(char *fdt, DeviceState *pl061_dev,
23
return;
22
24
}
23
qemu_fdt_add_subnode(fdt, "/gpio-keys");
25
if (kvm_enabled()) {
24
qemu_fdt_setprop_string(fdt, "/gpio-keys", "compatible", "gpio-keys");
26
- if (!kvm_arm_pmu_set_irq(cpu, PPI(VIRTUAL_PMU_IRQ))) {
25
- qemu_fdt_setprop_cell(fdt, "/gpio-keys", "#size-cells", 0);
27
+ if (kvm_irqchip_in_kernel() &&
26
- qemu_fdt_setprop_cell(fdt, "/gpio-keys", "#address-cells", 1);
28
+ !kvm_arm_pmu_set_irq(cpu, PPI(VIRTUAL_PMU_IRQ))) {
27
29
return;
28
qemu_fdt_add_subnode(fdt, "/gpio-keys/poweroff");
30
}
29
qemu_fdt_setprop_string(fdt, "/gpio-keys/poweroff",
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
--
30
--
64
2.7.4
31
2.25.1
65
66
diff view generated by jsdifflib
1
Set the MachineClass flag ignore_memory_transaction_failures
1
The traditional ptimer behaviour includes a collection of weird edge
2
for almost all ARM boards. This means they retain the legacy
2
case behaviours. In 2016 we improved the ptimer implementation to
3
behaviour that accesses to unimplemented addresses will RAZ/WI
3
fix these and generally make the behaviour more flexible, with
4
rather than aborting, when a subsequent commit adds support
4
ptimers opting in to the new behaviour by passing an appropriate set
5
for external aborts.
5
of policy flags to ptimer_init(). For backwards-compatibility, we
6
defined PTIMER_POLICY_DEFAULT (which sets no flags) to give the old
7
weird behaviour.
6
8
7
The exceptions are:
9
This turns out to be a poor choice of name, because people writing
8
* virt -- we know that guests won't try to prod devices
10
new devices which use ptimers are misled into thinking that the
9
that we don't describe in the device tree or ACPI tables
11
default is probably a sensible choice of flags, when in fact it is
10
* mps2 -- this board was written to use unimplemented-device
12
almost always not what you want. Rename PTIMER_POLICY_DEFAULT to
11
for all the ranges with devices we don't yet handle
13
PTIMER_POLICY_LEGACY and beef up the comment to more clearly say that
14
new devices should not be using it.
12
15
13
New boards should not set the flag, but instead be written
16
The code-change part of this commit was produced by
14
like the mps2.
17
sed -i -e 's/PTIMER_POLICY_DEFAULT/PTIMER_POLICY_LEGACY/g' $(git grep -l PTIMER_POLICY_DEFAULT)
18
with the exception of a test name string change in
19
tests/unit/ptimer-test.c which was added manually.
15
20
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
For the Xilinx boards:
22
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
18
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Message-id: 20220516103058.162280-1-peter.maydell@linaro.org
19
---
25
---
20
hw/arm/aspeed.c | 3 +++
26
include/hw/ptimer.h | 16 ++++++++++++----
21
hw/arm/collie.c | 1 +
27
hw/arm/musicpal.c | 2 +-
22
hw/arm/cubieboard.c | 1 +
28
hw/dma/xilinx_axidma.c | 2 +-
23
hw/arm/digic_boards.c | 1 +
29
hw/dma/xlnx_csu_dma.c | 2 +-
24
hw/arm/exynos4_boards.c | 2 ++
30
hw/m68k/mcf5206.c | 2 +-
25
hw/arm/gumstix.c | 2 ++
31
hw/m68k/mcf5208.c | 2 +-
26
hw/arm/highbank.c | 2 ++
32
hw/net/can/xlnx-zynqmp-can.c | 2 +-
27
hw/arm/imx25_pdk.c | 1 +
33
hw/net/fsl_etsec/etsec.c | 2 +-
28
hw/arm/integratorcp.c | 1 +
34
hw/net/lan9118.c | 2 +-
29
hw/arm/kzm.c | 1 +
35
hw/rtc/exynos4210_rtc.c | 4 ++--
30
hw/arm/mainstone.c | 1 +
36
hw/timer/allwinner-a10-pit.c | 2 +-
31
hw/arm/musicpal.c | 1 +
37
hw/timer/altera_timer.c | 2 +-
32
hw/arm/netduino2.c | 1 +
38
hw/timer/arm_timer.c | 2 +-
33
hw/arm/nseries.c | 2 ++
39
hw/timer/digic-timer.c | 2 +-
34
hw/arm/omap_sx1.c | 2 ++
40
hw/timer/etraxfs_timer.c | 6 +++---
35
hw/arm/palm.c | 1 +
41
hw/timer/exynos4210_mct.c | 6 +++---
36
hw/arm/raspi.c | 1 +
42
hw/timer/exynos4210_pwm.c | 2 +-
37
hw/arm/realview.c | 4 ++++
43
hw/timer/grlib_gptimer.c | 2 +-
38
hw/arm/sabrelite.c | 1 +
44
hw/timer/imx_epit.c | 4 ++--
39
hw/arm/spitz.c | 4 ++++
45
hw/timer/imx_gpt.c | 2 +-
40
hw/arm/stellaris.c | 2 ++
46
hw/timer/mss-timer.c | 2 +-
41
hw/arm/tosa.c | 1 +
47
hw/timer/sh_timer.c | 2 +-
42
hw/arm/versatilepb.c | 2 ++
48
hw/timer/slavio_timer.c | 2 +-
43
hw/arm/vexpress.c | 1 +
49
hw/timer/xilinx_timer.c | 2 +-
44
hw/arm/xilinx_zynq.c | 1 +
50
tests/unit/ptimer-test.c | 6 +++---
45
hw/arm/xlnx-ep108.c | 2 ++
51
25 files changed, 44 insertions(+), 36 deletions(-)
46
hw/arm/z2.c | 1 +
47
27 files changed, 43 insertions(+)
48
52
49
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
53
diff --git a/include/hw/ptimer.h b/include/hw/ptimer.h
50
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/aspeed.c
55
--- a/include/hw/ptimer.h
52
+++ b/hw/arm/aspeed.c
56
+++ b/include/hw/ptimer.h
53
@@ -XXX,XX +XXX,XX @@ static void palmetto_bmc_class_init(ObjectClass *oc, void *data)
57
@@ -XXX,XX +XXX,XX @@
54
mc->no_floppy = 1;
58
* to stderr when the guest attempts to enable the timer.
55
mc->no_cdrom = 1;
59
*/
56
mc->no_parallel = 1;
60
57
+ mc->ignore_memory_transaction_failures = true;
61
-/* The default ptimer policy retains backward compatibility with the legacy
58
}
62
- * timers. Custom policies are adjusting the default one. Consider providing
59
63
- * a correct policy for your timer.
60
static const TypeInfo palmetto_bmc_type = {
64
+/*
61
@@ -XXX,XX +XXX,XX @@ static void ast2500_evb_class_init(ObjectClass *oc, void *data)
65
+ * The 'legacy' ptimer policy retains backward compatibility with the
62
mc->no_floppy = 1;
66
+ * traditional ptimer behaviour from before policy flags were introduced.
63
mc->no_cdrom = 1;
67
+ * It has several weird behaviours which don't match typical hardware
64
mc->no_parallel = 1;
68
+ * timer behaviour. For a new device using ptimers, you should not
65
+ mc->ignore_memory_transaction_failures = true;
69
+ * use PTIMER_POLICY_LEGACY, but instead check the actual behaviour
66
}
70
+ * that you need and specify the right set of policy flags to get that.
67
71
+ *
68
static const TypeInfo ast2500_evb_type = {
72
+ * If you are overhauling an existing device that uses PTIMER_POLICY_LEGACY
69
@@ -XXX,XX +XXX,XX @@ static void romulus_bmc_class_init(ObjectClass *oc, void *data)
73
+ * and are in a position to check or test the real hardware behaviour,
70
mc->no_floppy = 1;
74
+ * consider updating it to specify the right policy flags.
71
mc->no_cdrom = 1;
75
*
72
mc->no_parallel = 1;
76
* The rough edges of the default policy:
73
+ mc->ignore_memory_transaction_failures = true;
77
* - Starting to run with a period = 0 emits error message and stops the
74
}
78
@@ -XXX,XX +XXX,XX @@
75
79
* since the last period, effectively restarting the timer with a
76
static const TypeInfo romulus_bmc_type = {
80
* counter = counter value at the moment of change (.i.e. one less).
77
diff --git a/hw/arm/collie.c b/hw/arm/collie.c
81
*/
78
index XXXXXXX..XXXXXXX 100644
82
-#define PTIMER_POLICY_DEFAULT 0
79
--- a/hw/arm/collie.c
83
+#define PTIMER_POLICY_LEGACY 0
80
+++ b/hw/arm/collie.c
84
81
@@ -XXX,XX +XXX,XX @@ static void collie_machine_init(MachineClass *mc)
85
/* Periodic timer counter stays with "0" for a one period before wrapping
82
{
86
* around. */
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
87
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
222
index XXXXXXX..XXXXXXX 100644
88
index XXXXXXX..XXXXXXX 100644
223
--- a/hw/arm/musicpal.c
89
--- a/hw/arm/musicpal.c
224
+++ b/hw/arm/musicpal.c
90
+++ b/hw/arm/musicpal.c
225
@@ -XXX,XX +XXX,XX @@ static void musicpal_machine_init(MachineClass *mc)
91
@@ -XXX,XX +XXX,XX @@ static void mv88w8618_timer_init(SysBusDevice *dev, mv88w8618_timer_state *s,
92
sysbus_init_irq(dev, &s->irq);
93
s->freq = freq;
94
95
- s->ptimer = ptimer_init(mv88w8618_timer_tick, s, PTIMER_POLICY_DEFAULT);
96
+ s->ptimer = ptimer_init(mv88w8618_timer_tick, s, PTIMER_POLICY_LEGACY);
97
}
98
99
static uint64_t mv88w8618_pit_read(void *opaque, hwaddr offset,
100
diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/hw/dma/xilinx_axidma.c
103
+++ b/hw/dma/xilinx_axidma.c
104
@@ -XXX,XX +XXX,XX @@ static void xilinx_axidma_realize(DeviceState *dev, Error **errp)
105
106
st->dma = s;
107
st->nr = i;
108
- st->ptimer = ptimer_init(timer_hit, st, PTIMER_POLICY_DEFAULT);
109
+ st->ptimer = ptimer_init(timer_hit, st, PTIMER_POLICY_LEGACY);
110
ptimer_transaction_begin(st->ptimer);
111
ptimer_set_freq(st->ptimer, s->freqhz);
112
ptimer_transaction_commit(st->ptimer);
113
diff --git a/hw/dma/xlnx_csu_dma.c b/hw/dma/xlnx_csu_dma.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/hw/dma/xlnx_csu_dma.c
116
+++ b/hw/dma/xlnx_csu_dma.c
117
@@ -XXX,XX +XXX,XX @@ static void xlnx_csu_dma_realize(DeviceState *dev, Error **errp)
118
sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
119
120
s->src_timer = ptimer_init(xlnx_csu_dma_src_timeout_hit,
121
- s, PTIMER_POLICY_DEFAULT);
122
+ s, PTIMER_POLICY_LEGACY);
123
124
s->attr = MEMTXATTRS_UNSPECIFIED;
125
126
diff --git a/hw/m68k/mcf5206.c b/hw/m68k/mcf5206.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/hw/m68k/mcf5206.c
129
+++ b/hw/m68k/mcf5206.c
130
@@ -XXX,XX +XXX,XX @@ static m5206_timer_state *m5206_timer_init(qemu_irq irq)
131
m5206_timer_state *s;
132
133
s = g_new0(m5206_timer_state, 1);
134
- s->timer = ptimer_init(m5206_timer_trigger, s, PTIMER_POLICY_DEFAULT);
135
+ s->timer = ptimer_init(m5206_timer_trigger, s, PTIMER_POLICY_LEGACY);
136
s->irq = irq;
137
m5206_timer_reset(s);
138
return s;
139
diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c
140
index XXXXXXX..XXXXXXX 100644
141
--- a/hw/m68k/mcf5208.c
142
+++ b/hw/m68k/mcf5208.c
143
@@ -XXX,XX +XXX,XX @@ static void mcf5208_sys_init(MemoryRegion *address_space, qemu_irq *pic)
144
/* Timers. */
145
for (i = 0; i < 2; i++) {
146
s = g_new0(m5208_timer_state, 1);
147
- s->timer = ptimer_init(m5208_timer_trigger, s, PTIMER_POLICY_DEFAULT);
148
+ s->timer = ptimer_init(m5208_timer_trigger, s, PTIMER_POLICY_LEGACY);
149
memory_region_init_io(&s->iomem, NULL, &m5208_timer_ops, s,
150
"m5208-timer", 0x00004000);
151
memory_region_add_subregion(address_space, 0xfc080000 + 0x4000 * i,
152
diff --git a/hw/net/can/xlnx-zynqmp-can.c b/hw/net/can/xlnx-zynqmp-can.c
153
index XXXXXXX..XXXXXXX 100644
154
--- a/hw/net/can/xlnx-zynqmp-can.c
155
+++ b/hw/net/can/xlnx-zynqmp-can.c
156
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_can_realize(DeviceState *dev, Error **errp)
157
158
/* Allocate a new timer. */
159
s->can_timer = ptimer_init(xlnx_zynqmp_can_ptimer_cb, s,
160
- PTIMER_POLICY_DEFAULT);
161
+ PTIMER_POLICY_LEGACY);
162
163
ptimer_transaction_begin(s->can_timer);
164
165
diff --git a/hw/net/fsl_etsec/etsec.c b/hw/net/fsl_etsec/etsec.c
166
index XXXXXXX..XXXXXXX 100644
167
--- a/hw/net/fsl_etsec/etsec.c
168
+++ b/hw/net/fsl_etsec/etsec.c
169
@@ -XXX,XX +XXX,XX @@ static void etsec_realize(DeviceState *dev, Error **errp)
170
object_get_typename(OBJECT(dev)), dev->id, etsec);
171
qemu_format_nic_info_str(qemu_get_queue(etsec->nic), etsec->conf.macaddr.a);
172
173
- etsec->ptimer = ptimer_init(etsec_timer_hit, etsec, PTIMER_POLICY_DEFAULT);
174
+ etsec->ptimer = ptimer_init(etsec_timer_hit, etsec, PTIMER_POLICY_LEGACY);
175
ptimer_transaction_begin(etsec->ptimer);
176
ptimer_set_freq(etsec->ptimer, 100);
177
ptimer_transaction_commit(etsec->ptimer);
178
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
179
index XXXXXXX..XXXXXXX 100644
180
--- a/hw/net/lan9118.c
181
+++ b/hw/net/lan9118.c
182
@@ -XXX,XX +XXX,XX @@ static void lan9118_realize(DeviceState *dev, Error **errp)
183
s->pmt_ctrl = 1;
184
s->txp = &s->tx_packet;
185
186
- s->timer = ptimer_init(lan9118_tick, s, PTIMER_POLICY_DEFAULT);
187
+ s->timer = ptimer_init(lan9118_tick, s, PTIMER_POLICY_LEGACY);
188
ptimer_transaction_begin(s->timer);
189
ptimer_set_freq(s->timer, 10000);
190
ptimer_set_limit(s->timer, 0xffff, 1);
191
diff --git a/hw/rtc/exynos4210_rtc.c b/hw/rtc/exynos4210_rtc.c
192
index XXXXXXX..XXXXXXX 100644
193
--- a/hw/rtc/exynos4210_rtc.c
194
+++ b/hw/rtc/exynos4210_rtc.c
195
@@ -XXX,XX +XXX,XX @@ static void exynos4210_rtc_init(Object *obj)
196
Exynos4210RTCState *s = EXYNOS4210_RTC(obj);
197
SysBusDevice *dev = SYS_BUS_DEVICE(obj);
198
199
- s->ptimer = ptimer_init(exynos4210_rtc_tick, s, PTIMER_POLICY_DEFAULT);
200
+ s->ptimer = ptimer_init(exynos4210_rtc_tick, s, PTIMER_POLICY_LEGACY);
201
ptimer_transaction_begin(s->ptimer);
202
ptimer_set_freq(s->ptimer, RTC_BASE_FREQ);
203
exynos4210_rtc_update_freq(s, 0);
204
ptimer_transaction_commit(s->ptimer);
205
206
s->ptimer_1Hz = ptimer_init(exynos4210_rtc_1Hz_tick,
207
- s, PTIMER_POLICY_DEFAULT);
208
+ s, PTIMER_POLICY_LEGACY);
209
ptimer_transaction_begin(s->ptimer_1Hz);
210
ptimer_set_freq(s->ptimer_1Hz, RTC_BASE_FREQ);
211
ptimer_transaction_commit(s->ptimer_1Hz);
212
diff --git a/hw/timer/allwinner-a10-pit.c b/hw/timer/allwinner-a10-pit.c
213
index XXXXXXX..XXXXXXX 100644
214
--- a/hw/timer/allwinner-a10-pit.c
215
+++ b/hw/timer/allwinner-a10-pit.c
216
@@ -XXX,XX +XXX,XX @@ static void a10_pit_init(Object *obj)
217
218
tc->container = s;
219
tc->index = i;
220
- s->timer[i] = ptimer_init(a10_pit_timer_cb, tc, PTIMER_POLICY_DEFAULT);
221
+ s->timer[i] = ptimer_init(a10_pit_timer_cb, tc, PTIMER_POLICY_LEGACY);
222
}
223
}
224
225
diff --git a/hw/timer/altera_timer.c b/hw/timer/altera_timer.c
226
index XXXXXXX..XXXXXXX 100644
227
--- a/hw/timer/altera_timer.c
228
+++ b/hw/timer/altera_timer.c
229
@@ -XXX,XX +XXX,XX @@ static void altera_timer_realize(DeviceState *dev, Error **errp)
230
return;
231
}
232
233
- t->ptimer = ptimer_init(timer_hit, t, PTIMER_POLICY_DEFAULT);
234
+ t->ptimer = ptimer_init(timer_hit, t, PTIMER_POLICY_LEGACY);
235
ptimer_transaction_begin(t->ptimer);
236
ptimer_set_freq(t->ptimer, t->freq_hz);
237
ptimer_transaction_commit(t->ptimer);
238
diff --git a/hw/timer/arm_timer.c b/hw/timer/arm_timer.c
239
index XXXXXXX..XXXXXXX 100644
240
--- a/hw/timer/arm_timer.c
241
+++ b/hw/timer/arm_timer.c
242
@@ -XXX,XX +XXX,XX @@ static arm_timer_state *arm_timer_init(uint32_t freq)
243
s->freq = freq;
244
s->control = TIMER_CTRL_IE;
245
246
- s->timer = ptimer_init(arm_timer_tick, s, PTIMER_POLICY_DEFAULT);
247
+ s->timer = ptimer_init(arm_timer_tick, s, PTIMER_POLICY_LEGACY);
248
vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_arm_timer, s);
249
return s;
250
}
251
diff --git a/hw/timer/digic-timer.c b/hw/timer/digic-timer.c
252
index XXXXXXX..XXXXXXX 100644
253
--- a/hw/timer/digic-timer.c
254
+++ b/hw/timer/digic-timer.c
255
@@ -XXX,XX +XXX,XX @@ static void digic_timer_init(Object *obj)
226
{
256
{
227
mc->desc = "Marvell 88w8618 / MusicPal (ARM926EJ-S)";
257
DigicTimerState *s = DIGIC_TIMER(obj);
228
mc->init = musicpal_init;
258
229
+ mc->ignore_memory_transaction_failures = true;
259
- s->ptimer = ptimer_init(digic_timer_tick, NULL, PTIMER_POLICY_DEFAULT);
260
+ s->ptimer = ptimer_init(digic_timer_tick, NULL, PTIMER_POLICY_LEGACY);
261
262
/*
263
* FIXME: there is no documentation on Digic timer
264
diff --git a/hw/timer/etraxfs_timer.c b/hw/timer/etraxfs_timer.c
265
index XXXXXXX..XXXXXXX 100644
266
--- a/hw/timer/etraxfs_timer.c
267
+++ b/hw/timer/etraxfs_timer.c
268
@@ -XXX,XX +XXX,XX @@ static void etraxfs_timer_realize(DeviceState *dev, Error **errp)
269
ETRAXTimerState *t = ETRAX_TIMER(dev);
270
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
271
272
- t->ptimer_t0 = ptimer_init(timer0_hit, t, PTIMER_POLICY_DEFAULT);
273
- t->ptimer_t1 = ptimer_init(timer1_hit, t, PTIMER_POLICY_DEFAULT);
274
- t->ptimer_wd = ptimer_init(watchdog_hit, t, PTIMER_POLICY_DEFAULT);
275
+ t->ptimer_t0 = ptimer_init(timer0_hit, t, PTIMER_POLICY_LEGACY);
276
+ t->ptimer_t1 = ptimer_init(timer1_hit, t, PTIMER_POLICY_LEGACY);
277
+ t->ptimer_wd = ptimer_init(watchdog_hit, t, PTIMER_POLICY_LEGACY);
278
279
sysbus_init_irq(sbd, &t->irq);
280
sysbus_init_irq(sbd, &t->nmi);
281
diff --git a/hw/timer/exynos4210_mct.c b/hw/timer/exynos4210_mct.c
282
index XXXXXXX..XXXXXXX 100644
283
--- a/hw/timer/exynos4210_mct.c
284
+++ b/hw/timer/exynos4210_mct.c
285
@@ -XXX,XX +XXX,XX @@ static void exynos4210_mct_init(Object *obj)
286
287
/* Global timer */
288
s->g_timer.ptimer_frc = ptimer_init(exynos4210_gfrc_event, s,
289
- PTIMER_POLICY_DEFAULT);
290
+ PTIMER_POLICY_LEGACY);
291
memset(&s->g_timer.reg, 0, sizeof(struct gregs));
292
293
/* Local timers */
294
for (i = 0; i < 2; i++) {
295
s->l_timer[i].tick_timer.ptimer_tick =
296
ptimer_init(exynos4210_ltick_event, &s->l_timer[i],
297
- PTIMER_POLICY_DEFAULT);
298
+ PTIMER_POLICY_LEGACY);
299
s->l_timer[i].ptimer_frc =
300
ptimer_init(exynos4210_lfrc_event, &s->l_timer[i],
301
- PTIMER_POLICY_DEFAULT);
302
+ PTIMER_POLICY_LEGACY);
303
s->l_timer[i].id = i;
304
}
305
306
diff --git a/hw/timer/exynos4210_pwm.c b/hw/timer/exynos4210_pwm.c
307
index XXXXXXX..XXXXXXX 100644
308
--- a/hw/timer/exynos4210_pwm.c
309
+++ b/hw/timer/exynos4210_pwm.c
310
@@ -XXX,XX +XXX,XX @@ static void exynos4210_pwm_init(Object *obj)
311
sysbus_init_irq(dev, &s->timer[i].irq);
312
s->timer[i].ptimer = ptimer_init(exynos4210_pwm_tick,
313
&s->timer[i],
314
- PTIMER_POLICY_DEFAULT);
315
+ PTIMER_POLICY_LEGACY);
316
s->timer[i].id = i;
317
s->timer[i].parent = s;
318
}
319
diff --git a/hw/timer/grlib_gptimer.c b/hw/timer/grlib_gptimer.c
320
index XXXXXXX..XXXXXXX 100644
321
--- a/hw/timer/grlib_gptimer.c
322
+++ b/hw/timer/grlib_gptimer.c
323
@@ -XXX,XX +XXX,XX @@ static void grlib_gptimer_realize(DeviceState *dev, Error **errp)
324
325
timer->unit = unit;
326
timer->ptimer = ptimer_init(grlib_gptimer_hit, timer,
327
- PTIMER_POLICY_DEFAULT);
328
+ PTIMER_POLICY_LEGACY);
329
timer->id = i;
330
331
/* One IRQ line for each timer */
332
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
333
index XXXXXXX..XXXXXXX 100644
334
--- a/hw/timer/imx_epit.c
335
+++ b/hw/timer/imx_epit.c
336
@@ -XXX,XX +XXX,XX @@ static void imx_epit_realize(DeviceState *dev, Error **errp)
337
0x00001000);
338
sysbus_init_mmio(sbd, &s->iomem);
339
340
- s->timer_reload = ptimer_init(imx_epit_reload, s, PTIMER_POLICY_DEFAULT);
341
+ s->timer_reload = ptimer_init(imx_epit_reload, s, PTIMER_POLICY_LEGACY);
342
343
- s->timer_cmp = ptimer_init(imx_epit_cmp, s, PTIMER_POLICY_DEFAULT);
344
+ s->timer_cmp = ptimer_init(imx_epit_cmp, s, PTIMER_POLICY_LEGACY);
230
}
345
}
231
346
232
DEFINE_MACHINE("musicpal", musicpal_machine_init)
347
static void imx_epit_class_init(ObjectClass *klass, void *data)
233
diff --git a/hw/arm/netduino2.c b/hw/arm/netduino2.c
348
diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
234
index XXXXXXX..XXXXXXX 100644
349
index XXXXXXX..XXXXXXX 100644
235
--- a/hw/arm/netduino2.c
350
--- a/hw/timer/imx_gpt.c
236
+++ b/hw/arm/netduino2.c
351
+++ b/hw/timer/imx_gpt.c
237
@@ -XXX,XX +XXX,XX @@ static void netduino2_machine_init(MachineClass *mc)
352
@@ -XXX,XX +XXX,XX @@ static void imx_gpt_realize(DeviceState *dev, Error **errp)
353
0x00001000);
354
sysbus_init_mmio(sbd, &s->iomem);
355
356
- s->timer = ptimer_init(imx_gpt_timeout, s, PTIMER_POLICY_DEFAULT);
357
+ s->timer = ptimer_init(imx_gpt_timeout, s, PTIMER_POLICY_LEGACY);
358
}
359
360
static void imx_gpt_class_init(ObjectClass *klass, void *data)
361
diff --git a/hw/timer/mss-timer.c b/hw/timer/mss-timer.c
362
index XXXXXXX..XXXXXXX 100644
363
--- a/hw/timer/mss-timer.c
364
+++ b/hw/timer/mss-timer.c
365
@@ -XXX,XX +XXX,XX @@ static void mss_timer_init(Object *obj)
366
for (i = 0; i < NUM_TIMERS; i++) {
367
struct Msf2Timer *st = &t->timers[i];
368
369
- st->ptimer = ptimer_init(timer_hit, st, PTIMER_POLICY_DEFAULT);
370
+ st->ptimer = ptimer_init(timer_hit, st, PTIMER_POLICY_LEGACY);
371
ptimer_transaction_begin(st->ptimer);
372
ptimer_set_freq(st->ptimer, t->freq_hz);
373
ptimer_transaction_commit(st->ptimer);
374
diff --git a/hw/timer/sh_timer.c b/hw/timer/sh_timer.c
375
index XXXXXXX..XXXXXXX 100644
376
--- a/hw/timer/sh_timer.c
377
+++ b/hw/timer/sh_timer.c
378
@@ -XXX,XX +XXX,XX @@ static void *sh_timer_init(uint32_t freq, int feat, qemu_irq irq)
379
s->enabled = 0;
380
s->irq = irq;
381
382
- s->timer = ptimer_init(sh_timer_tick, s, PTIMER_POLICY_DEFAULT);
383
+ s->timer = ptimer_init(sh_timer_tick, s, PTIMER_POLICY_LEGACY);
384
385
sh_timer_write(s, OFFSET_TCOR >> 2, s->tcor);
386
sh_timer_write(s, OFFSET_TCNT >> 2, s->tcnt);
387
diff --git a/hw/timer/slavio_timer.c b/hw/timer/slavio_timer.c
388
index XXXXXXX..XXXXXXX 100644
389
--- a/hw/timer/slavio_timer.c
390
+++ b/hw/timer/slavio_timer.c
391
@@ -XXX,XX +XXX,XX @@ static void slavio_timer_init(Object *obj)
392
tc->timer_index = i;
393
394
s->cputimer[i].timer = ptimer_init(slavio_timer_irq, tc,
395
- PTIMER_POLICY_DEFAULT);
396
+ PTIMER_POLICY_LEGACY);
397
ptimer_transaction_begin(s->cputimer[i].timer);
398
ptimer_set_period(s->cputimer[i].timer, TIMER_PERIOD);
399
ptimer_transaction_commit(s->cputimer[i].timer);
400
diff --git a/hw/timer/xilinx_timer.c b/hw/timer/xilinx_timer.c
401
index XXXXXXX..XXXXXXX 100644
402
--- a/hw/timer/xilinx_timer.c
403
+++ b/hw/timer/xilinx_timer.c
404
@@ -XXX,XX +XXX,XX @@ static void xilinx_timer_realize(DeviceState *dev, Error **errp)
405
406
xt->parent = t;
407
xt->nr = i;
408
- xt->ptimer = ptimer_init(timer_hit, xt, PTIMER_POLICY_DEFAULT);
409
+ xt->ptimer = ptimer_init(timer_hit, xt, PTIMER_POLICY_LEGACY);
410
ptimer_transaction_begin(xt->ptimer);
411
ptimer_set_freq(xt->ptimer, t->freq_hz);
412
ptimer_transaction_commit(xt->ptimer);
413
diff --git a/tests/unit/ptimer-test.c b/tests/unit/ptimer-test.c
414
index XXXXXXX..XXXXXXX 100644
415
--- a/tests/unit/ptimer-test.c
416
+++ b/tests/unit/ptimer-test.c
417
@@ -XXX,XX +XXX,XX @@ static void add_ptimer_tests(uint8_t policy)
418
char policy_name[256] = "";
419
char *tmp;
420
421
- if (policy == PTIMER_POLICY_DEFAULT) {
422
- g_sprintf(policy_name, "default");
423
+ if (policy == PTIMER_POLICY_LEGACY) {
424
+ g_sprintf(policy_name, "legacy");
425
}
426
427
if (policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD) {
428
@@ -XXX,XX +XXX,XX @@ static void add_ptimer_tests(uint8_t policy)
429
static void add_all_ptimer_policies_comb_tests(void)
238
{
430
{
239
mc->desc = "Netduino 2 Machine";
431
int last_policy = PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT;
240
mc->init = netduino2_init;
432
- int policy = PTIMER_POLICY_DEFAULT;
241
+ mc->ignore_memory_transaction_failures = true;
433
+ int policy = PTIMER_POLICY_LEGACY;
242
}
434
243
435
for (; policy < (last_policy << 1); policy++) {
244
DEFINE_MACHINE("netduino2", netduino2_machine_init)
436
if ((policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) &&
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
--
437
--
501
2.7.4
438
2.25.1
502
503
diff view generated by jsdifflib
1
When we switched our handling of exception exit to detect
1
From: Florian Lugou <florian.lugou@provenrun.com>
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
2
3
As per the description of the HCR_EL2.APK field in the ARMv8 ARM,
4
Pointer Authentication keys accesses should only be trapped to Secure
5
EL2 if it is enabled.
6
7
Signed-off-by: Florian Lugou <florian.lugou@provenrun.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220517145242.1215271-1-florian.lugou@provenrun.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
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
---
11
target/arm/helper.c | 2 +-
12
target/arm/helper.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
19
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_pauth(CPUARMState *env, const ARMCPRegInfo *ri,
19
bool rettobase = false;
20
int el = arm_current_el(env);
20
21
21
/* We can only get here from an EXCP_EXCEPTION_EXIT, and
22
if (el < 2 &&
22
- * arm_v7m_do_unassigned_access() enforces the architectural rule
23
- arm_feature(env, ARM_FEATURE_EL2) &&
23
+ * gen_bx_excret() enforces the architectural rule
24
+ arm_is_el2_enabled(env) &&
24
* that jumps to magic addresses don't have magic behaviour unless
25
!(arm_hcr_el2_eff(env) & HCR_APK)) {
25
* we're in Handler mode (compare pseudocode BXWritePC()).
26
return CP_ACCESS_TRAP_EL2;
26
*/
27
}
27
--
28
--
28
2.7.4
29
2.25.1
29
30
diff view generated by jsdifflib
1
We currently store the M profile CPU register state PRIMASK and
1
From: Richard Henderson <richard.henderson@linaro.org>
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
2
13
Switch M profile over to using v7m.faultmask and v7m.primask
3
This feature adds a new register, HCRX_EL2, which controls
14
fields for these registers.
4
many of the newer AArch64 features. So far the register is
5
effectively RES0, because none of the new features are done.
15
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220517054850.177016-2-richard.henderson@linaro.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
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
---
11
---
20
target/arm/cpu.h | 4 +++-
12
target/arm/cpu.h | 20 ++++++++++++++++++
21
hw/intc/armv7m_nvic.c | 4 ++--
13
target/arm/cpu64.c | 1 +
22
target/arm/cpu.c | 5 -----
14
target/arm/helper.c | 50 +++++++++++++++++++++++++++++++++++++++++++++
23
target/arm/helper.c | 18 +++++-------------
15
3 files changed, 71 insertions(+)
24
target/arm/machine.c | 33 +++++++++++++++++++++++++++++++++
25
5 files changed, 43 insertions(+), 21 deletions(-)
26
16
27
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
28
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/cpu.h
19
--- a/target/arm/cpu.h
30
+++ b/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
31
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
21
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
32
uint32_t bfar; /* BusFault Address */
22
uint32_t pmsav5_data_ap; /* PMSAv5 MPU data access permissions */
33
unsigned mpu_ctrl; /* MPU_CTRL */
23
uint32_t pmsav5_insn_ap; /* PMSAv5 MPU insn access permissions */
34
int exception;
24
uint64_t hcr_el2; /* Hypervisor configuration register */
35
+ uint32_t primask;
25
+ uint64_t hcrx_el2; /* Extended Hypervisor configuration register */
36
+ uint32_t faultmask;
26
uint64_t scr_el3; /* Secure configuration register. */
37
} v7m;
27
union { /* Fault status registers. */
38
28
struct {
39
/* Information associated with an exception about to be taken:
29
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
40
@@ -XXX,XX +XXX,XX @@ static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
30
#define HCR_TWEDEN (1ULL << 59)
41
* we're in a HardFault or NMI handler.
31
#define HCR_TWEDEL MAKE_64BIT_MASK(60, 4)
42
*/
32
43
if ((env->v7m.exception > 0 && env->v7m.exception <= 3)
33
+#define HCRX_ENAS0 (1ULL << 0)
44
- || env->daif & PSTATE_F) {
34
+#define HCRX_ENALS (1ULL << 1)
45
+ || env->v7m.faultmask) {
35
+#define HCRX_ENASR (1ULL << 2)
46
return arm_to_core_mmu_idx(ARMMMUIdx_MNegPri);
36
+#define HCRX_FNXS (1ULL << 3)
47
}
37
+#define HCRX_FGTNXS (1ULL << 4)
48
38
+#define HCRX_SMPME (1ULL << 5)
49
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
39
+#define HCRX_TALLINT (1ULL << 6)
40
+#define HCRX_VINMI (1ULL << 7)
41
+#define HCRX_VFNMI (1ULL << 8)
42
+#define HCRX_CMOW (1ULL << 9)
43
+#define HCRX_MCE2 (1ULL << 10)
44
+#define HCRX_MSCEN (1ULL << 11)
45
+
46
#define HPFAR_NS (1ULL << 63)
47
48
#define SCR_NS (1U << 0)
49
@@ -XXX,XX +XXX,XX @@ static inline bool arm_is_el2_enabled(CPUARMState *env)
50
* Not included here is HCR_RW.
51
*/
52
uint64_t arm_hcr_el2_eff(CPUARMState *env);
53
+uint64_t arm_hcrx_el2_eff(CPUARMState *env);
54
55
/* Return true if the specified exception level is running in AArch64 state. */
56
static inline bool arm_el_is_aa64(CPUARMState *env, int el)
57
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ats1e1(const ARMISARegisters *id)
58
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 2;
59
}
60
61
+static inline bool isar_feature_aa64_hcx(const ARMISARegisters *id)
62
+{
63
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HCX) != 0;
64
+}
65
+
66
static inline bool isar_feature_aa64_uao(const ARMISARegisters *id)
67
{
68
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, UAO) != 0;
69
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
50
index XXXXXXX..XXXXXXX 100644
70
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/intc/armv7m_nvic.c
71
--- a/target/arm/cpu64.c
52
+++ b/hw/intc/armv7m_nvic.c
72
+++ b/target/arm/cpu64.c
53
@@ -XXX,XX +XXX,XX @@ static inline int nvic_exec_prio(NVICState *s)
73
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
54
CPUARMState *env = &s->cpu->env;
74
t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1); /* FEAT_LOR */
55
int running;
75
t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* FEAT_PAN2 */
56
76
t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* FEAT_XNX */
57
- if (env->daif & PSTATE_F) { /* FAULTMASK */
77
+ t = FIELD_DP64(t, ID_AA64MMFR1, HCX, 1); /* FEAT_HCX */
58
+ if (env->v7m.faultmask) {
78
cpu->isar.id_aa64mmfr1 = t;
59
running = -1;
79
60
- } else if (env->daif & PSTATE_I) { /* PRIMASK */
80
t = cpu->isar.id_aa64mmfr2;
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
81
diff --git a/target/arm/helper.c b/target/arm/helper.c
82
index XXXXXXX..XXXXXXX 100644
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/helper.c
83
--- a/target/arm/helper.c
84
+++ b/target/arm/helper.c
84
+++ b/target/arm/helper.c
85
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
85
@@ -XXX,XX +XXX,XX @@ uint64_t arm_hcr_el2_eff(CPUARMState *env)
86
86
return ret;
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
}
87
}
142
88
143
+static const VMStateDescription vmstate_m_faultmask_primask = {
89
+static void hcrx_write(CPUARMState *env, const ARMCPRegInfo *ri,
144
+ .name = "cpu/m/faultmask-primask",
90
+ uint64_t value)
145
+ .version_id = 1,
91
+{
146
+ .minimum_version_id = 1,
92
+ uint64_t valid_mask = 0;
147
+ .fields = (VMStateField[]) {
93
+
148
+ VMSTATE_UINT32(env.v7m.faultmask, ARMCPU),
94
+ /* No features adding bits to HCRX are implemented. */
149
+ VMSTATE_UINT32(env.v7m.primask, ARMCPU),
95
+
150
+ VMSTATE_END_OF_LIST()
96
+ /* Clear RES0 bits. */
97
+ env->cp15.hcrx_el2 = value & valid_mask;
98
+}
99
+
100
+static CPAccessResult access_hxen(CPUARMState *env, const ARMCPRegInfo *ri,
101
+ bool isread)
102
+{
103
+ if (arm_current_el(env) < 3
104
+ && arm_feature(env, ARM_FEATURE_EL3)
105
+ && !(env->cp15.scr_el3 & SCR_HXEN)) {
106
+ return CP_ACCESS_TRAP_EL3;
151
+ }
107
+ }
108
+ return CP_ACCESS_OK;
109
+}
110
+
111
+static const ARMCPRegInfo hcrx_el2_reginfo = {
112
+ .name = "HCRX_EL2", .state = ARM_CP_STATE_AA64,
113
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 2,
114
+ .access = PL2_RW, .writefn = hcrx_write, .accessfn = access_hxen,
115
+ .fieldoffset = offsetof(CPUARMState, cp15.hcrx_el2),
152
+};
116
+};
153
+
117
+
154
static const VMStateDescription vmstate_m = {
118
+/* Return the effective value of HCRX_EL2. */
155
.name = "cpu/m",
119
+uint64_t arm_hcrx_el2_eff(CPUARMState *env)
156
.version_id = 4,
120
+{
157
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
121
+ /*
158
VMSTATE_UINT32(env.v7m.mpu_ctrl, ARMCPU),
122
+ * The bits in this register behave as 0 for all purposes other than
159
VMSTATE_INT32(env.v7m.exception, ARMCPU),
123
+ * direct reads of the register if:
160
VMSTATE_END_OF_LIST()
124
+ * - EL2 is not enabled in the current security state,
161
+ },
125
+ * - SCR_EL3.HXEn is 0.
162
+ .subsections = (const VMStateDescription*[]) {
126
+ */
163
+ &vmstate_m_faultmask_primask,
127
+ if (!arm_is_el2_enabled(env)
164
+ NULL
128
+ || (arm_feature(env, ARM_FEATURE_EL3)
129
+ && !(env->cp15.scr_el3 & SCR_HXEN))) {
130
+ return 0;
131
+ }
132
+ return env->cp15.hcrx_el2;
133
+}
134
+
135
static void cptr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
136
uint64_t value)
137
{
138
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
139
define_arm_cp_regs(cpu, zcr_reginfo);
165
}
140
}
166
};
141
167
142
+ if (cpu_isar_feature(aa64_hcx, cpu)) {
168
@@ -XXX,XX +XXX,XX @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
143
+ define_one_arm_cp_reg(cpu, &hcrx_el2_reginfo);
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
+ }
144
+ }
189
+
145
+
190
env->aarch64 = ((val & PSTATE_nRW) == 0);
146
#ifdef TARGET_AARCH64
191
147
if (cpu_isar_feature(aa64_pauth, cpu)) {
192
if (is_a64(env)) {
148
define_arm_cp_regs(cpu, pauth_reginfo);
193
--
149
--
194
2.7.4
150
2.25.1
195
196
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
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
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
1
From: Andrew Jones <drjones@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Mimicking gicv3-maintenance-interrupt, add the PMU's interrupt to
3
We had a few CPTR_* bits defined, but missed quite a few.
4
CPU state.
4
Complete all of the fields up to ARMv9.2.
5
Use FIELD_EX64 instead of manual extract32.
5
6
6
Signed-off-by: Andrew Jones <drjones@redhat.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 1500471597-2517-2-git-send-email-drjones@redhat.com
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220517054850.177016-3-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/cpu.h | 2 ++
12
target/arm/cpu.h | 44 +++++++++++++++++++++++++++++++-----
12
hw/arm/virt.c | 3 +++
13
hw/arm/boot.c | 2 +-
13
target/arm/cpu.c | 2 ++
14
target/arm/cpu.c | 11 ++++++---
14
3 files changed, 7 insertions(+)
15
target/arm/helper.c | 54 ++++++++++++++++++++++-----------------------
16
4 files changed, 75 insertions(+), 36 deletions(-)
15
17
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
20
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
22
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
21
qemu_irq gt_timer_outputs[NUM_GTIMERS];
23
#define SCTLR_SPINTMASK (1ULL << 62) /* FEAT_NMI */
22
/* GPIO output for GICv3 maintenance interrupt signal */
24
#define SCTLR_TIDCP (1ULL << 63) /* FEAT_TIDCP1 */
23
qemu_irq gicv3_maintenance_interrupt;
25
24
+ /* GPIO output for the PMU interrupt */
26
-#define CPTR_TCPAC (1U << 31)
25
+ qemu_irq pmu_interrupt;
27
-#define CPTR_TTA (1U << 20)
26
28
-#define CPTR_TFP (1U << 10)
27
/* MemoryRegion to use for secure physical accesses */
29
-#define CPTR_TZ (1U << 8) /* CPTR_EL2 */
28
MemoryRegion *secure_memory;
30
-#define CPTR_EZ (1U << 8) /* CPTR_EL3 */
29
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
31
+/* Bit definitions for CPACR (AArch32 only) */
32
+FIELD(CPACR, CP10, 20, 2)
33
+FIELD(CPACR, CP11, 22, 2)
34
+FIELD(CPACR, TRCDIS, 28, 1) /* matches CPACR_EL1.TTA */
35
+FIELD(CPACR, D32DIS, 30, 1) /* up to v7; RAZ in v8 */
36
+FIELD(CPACR, ASEDIS, 31, 1)
37
+
38
+/* Bit definitions for CPACR_EL1 (AArch64 only) */
39
+FIELD(CPACR_EL1, ZEN, 16, 2)
40
+FIELD(CPACR_EL1, FPEN, 20, 2)
41
+FIELD(CPACR_EL1, SMEN, 24, 2)
42
+FIELD(CPACR_EL1, TTA, 28, 1) /* matches CPACR.TRCDIS */
43
+
44
+/* Bit definitions for HCPTR (AArch32 only) */
45
+FIELD(HCPTR, TCP10, 10, 1)
46
+FIELD(HCPTR, TCP11, 11, 1)
47
+FIELD(HCPTR, TASE, 15, 1)
48
+FIELD(HCPTR, TTA, 20, 1)
49
+FIELD(HCPTR, TAM, 30, 1) /* matches CPTR_EL2.TAM */
50
+FIELD(HCPTR, TCPAC, 31, 1) /* matches CPTR_EL2.TCPAC */
51
+
52
+/* Bit definitions for CPTR_EL2 (AArch64 only) */
53
+FIELD(CPTR_EL2, TZ, 8, 1) /* !E2H */
54
+FIELD(CPTR_EL2, TFP, 10, 1) /* !E2H, matches HCPTR.TCP10 */
55
+FIELD(CPTR_EL2, TSM, 12, 1) /* !E2H */
56
+FIELD(CPTR_EL2, ZEN, 16, 2) /* E2H */
57
+FIELD(CPTR_EL2, FPEN, 20, 2) /* E2H */
58
+FIELD(CPTR_EL2, SMEN, 24, 2) /* E2H */
59
+FIELD(CPTR_EL2, TTA, 28, 1)
60
+FIELD(CPTR_EL2, TAM, 30, 1) /* matches HCPTR.TAM */
61
+FIELD(CPTR_EL2, TCPAC, 31, 1) /* matches HCPTR.TCPAC */
62
+
63
+/* Bit definitions for CPTR_EL3 (AArch64 only) */
64
+FIELD(CPTR_EL3, EZ, 8, 1)
65
+FIELD(CPTR_EL3, TFP, 10, 1)
66
+FIELD(CPTR_EL3, ESM, 12, 1)
67
+FIELD(CPTR_EL3, TTA, 20, 1)
68
+FIELD(CPTR_EL3, TAM, 30, 1)
69
+FIELD(CPTR_EL3, TCPAC, 31, 1)
70
71
#define MDCR_EPMAD (1U << 21)
72
#define MDCR_EDAD (1U << 20)
73
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
30
index XXXXXXX..XXXXXXX 100644
74
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/virt.c
75
--- a/hw/arm/boot.c
32
+++ b/hw/arm/virt.c
76
+++ b/hw/arm/boot.c
33
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
77
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
34
qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 0,
78
env->cp15.scr_el3 |= SCR_ATA;
35
qdev_get_gpio_in(gicdev, ppibase
79
}
36
+ ARCH_GICV3_MAINT_IRQ));
80
if (cpu_isar_feature(aa64_sve, cpu)) {
37
+ qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
81
- env->cp15.cptr_el[3] |= CPTR_EZ;
38
+ qdev_get_gpio_in(gicdev, ppibase
82
+ env->cp15.cptr_el[3] |= R_CPTR_EL3_EZ_MASK;
39
+ + VIRTUAL_PMU_IRQ));
83
}
40
84
/* AArch64 kernels never boot in secure mode */
41
sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
85
assert(!info->secure_boot);
42
sysbus_connect_irq(gicbusdev, i + smp_cpus,
43
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
86
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
44
index XXXXXXX..XXXXXXX 100644
87
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/cpu.c
88
--- a/target/arm/cpu.c
46
+++ b/target/arm/cpu.c
89
+++ b/target/arm/cpu.c
47
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_initfn(Object *obj)
90
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
48
91
/* Trap on btype=3 for PACIxSP. */
49
qdev_init_gpio_out_named(DEVICE(cpu), &cpu->gicv3_maintenance_interrupt,
92
env->cp15.sctlr_el[1] |= SCTLR_BT0;
50
"gicv3-maintenance-interrupt", 1);
93
/* and to the FP/Neon instructions */
51
+ qdev_init_gpio_out_named(DEVICE(cpu), &cpu->pmu_interrupt,
94
- env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3);
52
+ "pmu-interrupt", 1);
95
+ env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
96
+ CPACR_EL1, FPEN, 3);
97
/* and to the SVE instructions */
98
- env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 16, 2, 3);
99
+ env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
100
+ CPACR_EL1, ZEN, 3);
101
/* with reasonable vector length */
102
if (cpu_isar_feature(aa64_sve, cpu)) {
103
env->vfp.zcr_el[1] =
104
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
105
} else {
106
#if defined(CONFIG_USER_ONLY)
107
/* Userspace expects access to cp10 and cp11 for FP/Neon */
108
- env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 4, 0xf);
109
+ env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
110
+ CPACR, CP10, 3);
111
+ env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
112
+ CPACR, CP11, 3);
53
#endif
113
#endif
54
114
}
55
/* DTB consumers generally don't in fact care what the 'compatible'
115
116
diff --git a/target/arm/helper.c b/target/arm/helper.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/target/arm/helper.c
119
+++ b/target/arm/helper.c
120
@@ -XXX,XX +XXX,XX @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
121
*/
122
if (cpu_isar_feature(aa32_vfp_simd, env_archcpu(env))) {
123
/* VFP coprocessor: cp10 & cp11 [23:20] */
124
- mask |= (1 << 31) | (1 << 30) | (0xf << 20);
125
+ mask |= R_CPACR_ASEDIS_MASK |
126
+ R_CPACR_D32DIS_MASK |
127
+ R_CPACR_CP11_MASK |
128
+ R_CPACR_CP10_MASK;
129
130
if (!arm_feature(env, ARM_FEATURE_NEON)) {
131
/* ASEDIS [31] bit is RAO/WI */
132
- value |= (1 << 31);
133
+ value |= R_CPACR_ASEDIS_MASK;
134
}
135
136
/* VFPv3 and upwards with NEON implement 32 double precision
137
@@ -XXX,XX +XXX,XX @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
138
*/
139
if (!cpu_isar_feature(aa32_simd_r32, env_archcpu(env))) {
140
/* D32DIS [30] is RAO/WI if D16-31 are not implemented. */
141
- value |= (1 << 30);
142
+ value |= R_CPACR_D32DIS_MASK;
143
}
144
}
145
value &= mask;
146
@@ -XXX,XX +XXX,XX @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
147
*/
148
if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
149
!arm_is_secure(env) && !extract32(env->cp15.nsacr, 10, 1)) {
150
- value &= ~(0xf << 20);
151
- value |= env->cp15.cpacr_el1 & (0xf << 20);
152
+ mask = R_CPACR_CP11_MASK | R_CPACR_CP10_MASK;
153
+ value = (value & ~mask) | (env->cp15.cpacr_el1 & mask);
154
}
155
156
env->cp15.cpacr_el1 = value;
157
@@ -XXX,XX +XXX,XX @@ static uint64_t cpacr_read(CPUARMState *env, const ARMCPRegInfo *ri)
158
159
if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
160
!arm_is_secure(env) && !extract32(env->cp15.nsacr, 10, 1)) {
161
- value &= ~(0xf << 20);
162
+ value = ~(R_CPACR_CP11_MASK | R_CPACR_CP10_MASK);
163
}
164
return value;
165
}
166
@@ -XXX,XX +XXX,XX @@ static CPAccessResult cpacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
167
if (arm_feature(env, ARM_FEATURE_V8)) {
168
/* Check if CPACR accesses are to be trapped to EL2 */
169
if (arm_current_el(env) == 1 && arm_is_el2_enabled(env) &&
170
- (env->cp15.cptr_el[2] & CPTR_TCPAC)) {
171
+ FIELD_EX64(env->cp15.cptr_el[2], CPTR_EL2, TCPAC)) {
172
return CP_ACCESS_TRAP_EL2;
173
/* Check if CPACR accesses are to be trapped to EL3 */
174
} else if (arm_current_el(env) < 3 &&
175
- (env->cp15.cptr_el[3] & CPTR_TCPAC)) {
176
+ FIELD_EX64(env->cp15.cptr_el[3], CPTR_EL3, TCPAC)) {
177
return CP_ACCESS_TRAP_EL3;
178
}
179
}
180
@@ -XXX,XX +XXX,XX @@ static CPAccessResult cptr_access(CPUARMState *env, const ARMCPRegInfo *ri,
181
bool isread)
182
{
183
/* Check if CPTR accesses are set to trap to EL3 */
184
- if (arm_current_el(env) == 2 && (env->cp15.cptr_el[3] & CPTR_TCPAC)) {
185
+ if (arm_current_el(env) == 2 &&
186
+ FIELD_EX64(env->cp15.cptr_el[3], CPTR_EL3, TCPAC)) {
187
return CP_ACCESS_TRAP_EL3;
188
}
189
190
@@ -XXX,XX +XXX,XX @@ static void cptr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
191
*/
192
if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
193
!arm_is_secure(env) && !extract32(env->cp15.nsacr, 10, 1)) {
194
- value &= ~(0x3 << 10);
195
- value |= env->cp15.cptr_el[2] & (0x3 << 10);
196
+ uint64_t mask = R_HCPTR_TCP11_MASK | R_HCPTR_TCP10_MASK;
197
+ value = (value & ~mask) | (env->cp15.cptr_el[2] & mask);
198
}
199
env->cp15.cptr_el[2] = value;
200
}
201
@@ -XXX,XX +XXX,XX @@ static uint64_t cptr_el2_read(CPUARMState *env, const ARMCPRegInfo *ri)
202
203
if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
204
!arm_is_secure(env) && !extract32(env->cp15.nsacr, 10, 1)) {
205
- value |= 0x3 << 10;
206
+ value |= R_HCPTR_TCP11_MASK | R_HCPTR_TCP10_MASK;
207
}
208
return value;
209
}
210
@@ -XXX,XX +XXX,XX @@ int sve_exception_el(CPUARMState *env, int el)
211
uint64_t hcr_el2 = arm_hcr_el2_eff(env);
212
213
if (el <= 1 && (hcr_el2 & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
214
- /* Check CPACR.ZEN. */
215
- switch (extract32(env->cp15.cpacr_el1, 16, 2)) {
216
+ switch (FIELD_EX64(env->cp15.cpacr_el1, CPACR_EL1, ZEN)) {
217
case 1:
218
if (el != 0) {
219
break;
220
@@ -XXX,XX +XXX,XX @@ int sve_exception_el(CPUARMState *env, int el)
221
}
222
223
/* Check CPACR.FPEN. */
224
- switch (extract32(env->cp15.cpacr_el1, 20, 2)) {
225
+ switch (FIELD_EX64(env->cp15.cpacr_el1, CPACR_EL1, FPEN)) {
226
case 1:
227
if (el != 0) {
228
break;
229
@@ -XXX,XX +XXX,XX @@ int sve_exception_el(CPUARMState *env, int el)
230
*/
231
if (el <= 2) {
232
if (hcr_el2 & HCR_E2H) {
233
- /* Check CPTR_EL2.ZEN. */
234
- switch (extract32(env->cp15.cptr_el[2], 16, 2)) {
235
+ switch (FIELD_EX64(env->cp15.cptr_el[2], CPTR_EL2, ZEN)) {
236
case 1:
237
if (el != 0 || !(hcr_el2 & HCR_TGE)) {
238
break;
239
@@ -XXX,XX +XXX,XX @@ int sve_exception_el(CPUARMState *env, int el)
240
return 2;
241
}
242
243
- /* Check CPTR_EL2.FPEN. */
244
- switch (extract32(env->cp15.cptr_el[2], 20, 2)) {
245
+ switch (FIELD_EX32(env->cp15.cptr_el[2], CPTR_EL2, FPEN)) {
246
case 1:
247
if (el == 2 || !(hcr_el2 & HCR_TGE)) {
248
break;
249
@@ -XXX,XX +XXX,XX @@ int sve_exception_el(CPUARMState *env, int el)
250
return 0;
251
}
252
} else if (arm_is_el2_enabled(env)) {
253
- if (env->cp15.cptr_el[2] & CPTR_TZ) {
254
+ if (FIELD_EX64(env->cp15.cptr_el[2], CPTR_EL2, TZ)) {
255
return 2;
256
}
257
- if (env->cp15.cptr_el[2] & CPTR_TFP) {
258
+ if (FIELD_EX64(env->cp15.cptr_el[2], CPTR_EL2, TFP)) {
259
return 0;
260
}
261
}
262
@@ -XXX,XX +XXX,XX @@ int sve_exception_el(CPUARMState *env, int el)
263
264
/* CPTR_EL3. Since EZ is negative we must check for EL3. */
265
if (arm_feature(env, ARM_FEATURE_EL3)
266
- && !(env->cp15.cptr_el[3] & CPTR_EZ)) {
267
+ && !FIELD_EX64(env->cp15.cptr_el[3], CPTR_EL3, EZ)) {
268
return 3;
269
}
270
#endif
271
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
272
* This register is ignored if E2H+TGE are both set.
273
*/
274
if ((hcr_el2 & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
275
- int fpen = extract32(env->cp15.cpacr_el1, 20, 2);
276
+ int fpen = FIELD_EX64(env->cp15.cpacr_el1, CPACR_EL1, FPEN);
277
278
switch (fpen) {
279
case 0:
280
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
281
*/
282
if (cur_el <= 2) {
283
if (hcr_el2 & HCR_E2H) {
284
- /* Check CPTR_EL2.FPEN. */
285
- switch (extract32(env->cp15.cptr_el[2], 20, 2)) {
286
+ switch (FIELD_EX64(env->cp15.cptr_el[2], CPTR_EL2, FPEN)) {
287
case 1:
288
if (cur_el != 0 || !(hcr_el2 & HCR_TGE)) {
289
break;
290
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
291
return 2;
292
}
293
} else if (arm_is_el2_enabled(env)) {
294
- if (env->cp15.cptr_el[2] & CPTR_TFP) {
295
+ if (FIELD_EX64(env->cp15.cptr_el[2], CPTR_EL2, TFP)) {
296
return 2;
297
}
298
}
299
}
300
301
/* CPTR_EL3 : present in v8 */
302
- if (env->cp15.cptr_el[3] & CPTR_TFP) {
303
+ if (FIELD_EX64(env->cp15.cptr_el[3], CPTR_EL3, TFP)) {
304
/* Trap all FP ops to EL3 */
305
return 3;
306
}
56
--
307
--
57
2.7.4
308
2.25.1
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 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
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
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