1
target-arm queue: mostly just cleanup/minor stuff, but this does
1
First pullreq for arm of the 4.1 series, since I'm back from
2
include the raspi3 board model.
2
holiday now. This is mostly my M-profile FPU series and Philippe's
3
devices.h cleanup. I have a pile of other patchsets to work through
4
in my to-review folder, but 42 patches is definitely quite
5
big enough to send now...
3
6
7
thanks
4
-- PMM
8
-- PMM
5
9
6
The following changes since commit 9f9c53368b219a9115eddb39f0ff5ad19c977134:
10
The following changes since commit 413a99a92c13ec408dcf2adaa87918dc81e890c8:
7
11
8
Merge remote-tracking branch 'remotes/vivier/tags/m68k-for-2.12-pull-request' into staging (2018-02-15 10:14:11 +0000)
12
Add Nios II semihosting support. (2019-04-29 16:09:51 +0100)
9
13
10
are available in the Git repository at:
14
are available in the Git repository at:
11
15
12
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180215
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190429
13
17
14
for you to fetch changes up to e545f0f9be1f9e60951017c1e6558216732cc14e:
18
for you to fetch changes up to 437cc27ddfded3bbab6afd5ac1761e0e195edba7:
15
19
16
target/arm: Implement v8M MSPLIM and PSPLIM registers (2018-02-15 13:48:11 +0000)
20
hw/devices: Move SMSC 91C111 declaration into a new header (2019-04-29 17:57:21 +0100)
17
21
18
----------------------------------------------------------------
22
----------------------------------------------------------------
19
target-arm queue:
23
target-arm queue:
20
* aspeed: code cleanup to use unimplemented_device
24
* remove "bag of random stuff" hw/devices.h header
21
* add 'raspi3' RaspberryPi 3 machine model
25
* implement FPU for Cortex-M and enable it for Cortex-M4 and -M33
22
* more SVE prep work
26
* hw/dma: Compile the bcm2835_dma device as common object
23
* v8M: add minor missing registers
27
* configure: Remove --source-path option
24
* v7M: fix bug where we weren't migrating v7m.other_sp
28
* hw/ssi/xilinx_spips: Avoid variable length array
25
* v7M: fix bugs in handling of interrupt registers for
29
* hw/arm/smmuv3: Remove SMMUNotifierNode
26
external interrupts beyond 32
27
30
28
----------------------------------------------------------------
31
----------------------------------------------------------------
29
Pekka Enberg (3):
32
Eric Auger (1):
30
bcm2836: Make CPU type configurable
33
hw/arm/smmuv3: Remove SMMUNotifierNode
31
raspi: Raspberry Pi 3 support
32
raspi: Add "raspi3" machine type
33
34
34
Peter Maydell (11):
35
Peter Maydell (28):
35
hw/intc/armv7m_nvic: Don't hardcode M profile ID registers in NVIC
36
hw/ssi/xilinx_spips: Avoid variable length array
36
hw/intc/armv7m_nvic: Fix ICSR PENDNMISET/CLR handling
37
configure: Remove --source-path option
37
hw/intc/armv7m_nvic: Implement M profile cache maintenance ops
38
target/arm: Make sure M-profile FPSCR RES0 bits are not settable
38
hw/intc/armv7m_nvic: Implement v8M CPPWR register
39
hw/intc/armv7m_nvic: Allow reading of M-profile MVFR* registers
39
hw/intc/armv7m_nvic: Implement cache ID registers
40
target/arm: Implement dummy versions of M-profile FP-related registers
40
hw/intc/armv7m_nvic: Implement SCR
41
target/arm: Disable most VFP sysregs for M-profile
41
target/arm: Implement writing to CONTROL_NS for v8M
42
target/arm: Honour M-profile FP enable bits
42
hw/intc/armv7m_nvic: Fix byte-to-interrupt number conversions
43
target/arm: Decode FP instructions for M profile
43
target/arm: Add AIRCR to vmstate struct
44
target/arm: Clear CONTROL_S.SFPA in SG insn if FPU present
44
target/arm: Migrate v7m.other_sp
45
target/arm: Handle SFPA and FPCA bits in reads and writes of CONTROL
45
target/arm: Implement v8M MSPLIM and PSPLIM registers
46
target/arm/helper: don't return early for STKOF faults during stacking
47
target/arm: Handle floating point registers in exception entry
48
target/arm: Implement v7m_update_fpccr()
49
target/arm: Clear CONTROL.SFPA in BXNS and BLXNS
50
target/arm: Clean excReturn bits when tail chaining
51
target/arm: Allow for floating point in callee stack integrity check
52
target/arm: Handle floating point registers in exception return
53
target/arm: Move NS TBFLAG from bit 19 to bit 6
54
target/arm: Overlap VECSTRIDE and XSCALE_CPAR TB flags
55
target/arm: Set FPCCR.S when executing M-profile floating point insns
56
target/arm: Activate M-profile floating point context when FPCCR.ASPEN is set
57
target/arm: New helper function arm_v7m_mmu_idx_all()
58
target/arm: New function armv7m_nvic_set_pending_lazyfp()
59
target/arm: Add lazy-FP-stacking support to v7m_stack_write()
60
target/arm: Implement M-profile lazy FP state preservation
61
target/arm: Implement VLSTM for v7M CPUs with an FPU
62
target/arm: Implement VLLDM for v7M CPUs with an FPU
63
target/arm: Enable FPU for Cortex-M4 and Cortex-M33
46
64
47
Philippe Mathieu-Daudé (2):
65
Philippe Mathieu-Daudé (13):
48
hw/arm/aspeed: directly map the serial device to the system address space
66
hw/dma: Compile the bcm2835_dma device as common object
49
hw/arm/aspeed: simplify using the 'unimplemented device' for aspeed_soc.io
67
hw/arm/aspeed: Use TYPE_TMP105/TYPE_PCA9552 instead of hardcoded string
68
hw/arm/nseries: Use TYPE_TMP105 instead of hardcoded string
69
hw/display/tc6393xb: Remove unused functions
70
hw/devices: Move TC6393XB declarations into a new header
71
hw/devices: Move Blizzard declarations into a new header
72
hw/devices: Move CBus declarations into a new header
73
hw/devices: Move Gamepad declarations into a new header
74
hw/devices: Move TI touchscreen declarations into a new header
75
hw/devices: Move LAN9118 declarations into a new header
76
hw/net/ne2000-isa: Add guards to the header
77
hw/net/lan9118: Export TYPE_LAN9118 and use it instead of hardcoded string
78
hw/devices: Move SMSC 91C111 declaration into a new header
50
79
51
Richard Henderson (5):
80
configure | 10 +-
52
target/arm: Remove ARM_CP_64BIT from ZCR_EL registers
81
hw/dma/Makefile.objs | 2 +-
53
target/arm: Enforce FP access to FPCR/FPSR
82
include/hw/arm/omap.h | 6 +-
54
target/arm: Suppress TB end for FPCR/FPSR
83
include/hw/arm/smmu-common.h | 8 +-
55
target/arm: Enforce access to ZCR_EL at translation
84
include/hw/devices.h | 62 ---
56
target/arm: Handle SVE registers when using clear_vec_high
85
include/hw/display/blizzard.h | 22 ++
86
include/hw/display/tc6393xb.h | 24 ++
87
include/hw/input/gamepad.h | 19 +
88
include/hw/input/tsc2xxx.h | 36 ++
89
include/hw/misc/cbus.h | 32 ++
90
include/hw/net/lan9118.h | 21 +
91
include/hw/net/ne2000-isa.h | 6 +
92
include/hw/net/smc91c111.h | 19 +
93
include/qemu/typedefs.h | 1 -
94
target/arm/cpu.h | 95 ++++-
95
target/arm/helper.h | 5 +
96
target/arm/translate.h | 3 +
97
hw/arm/aspeed.c | 13 +-
98
hw/arm/exynos4_boards.c | 3 +-
99
hw/arm/gumstix.c | 2 +-
100
hw/arm/integratorcp.c | 2 +-
101
hw/arm/kzm.c | 2 +-
102
hw/arm/mainstone.c | 2 +-
103
hw/arm/mps2-tz.c | 3 +-
104
hw/arm/mps2.c | 2 +-
105
hw/arm/nseries.c | 7 +-
106
hw/arm/palm.c | 2 +-
107
hw/arm/realview.c | 3 +-
108
hw/arm/smmu-common.c | 6 +-
109
hw/arm/smmuv3.c | 28 +-
110
hw/arm/stellaris.c | 2 +-
111
hw/arm/tosa.c | 2 +-
112
hw/arm/versatilepb.c | 2 +-
113
hw/arm/vexpress.c | 2 +-
114
hw/display/blizzard.c | 2 +-
115
hw/display/tc6393xb.c | 18 +-
116
hw/input/stellaris_input.c | 2 +-
117
hw/input/tsc2005.c | 2 +-
118
hw/input/tsc210x.c | 4 +-
119
hw/intc/armv7m_nvic.c | 261 +++++++++++++
120
hw/misc/cbus.c | 2 +-
121
hw/net/lan9118.c | 3 +-
122
hw/net/smc91c111.c | 2 +-
123
hw/ssi/xilinx_spips.c | 6 +-
124
target/arm/cpu.c | 20 +
125
target/arm/helper.c | 873 +++++++++++++++++++++++++++++++++++++++---
126
target/arm/machine.c | 16 +
127
target/arm/translate.c | 150 +++++++-
128
target/arm/vfp_helper.c | 8 +
129
MAINTAINERS | 7 +
130
50 files changed, 1595 insertions(+), 235 deletions(-)
131
delete mode 100644 include/hw/devices.h
132
create mode 100644 include/hw/display/blizzard.h
133
create mode 100644 include/hw/display/tc6393xb.h
134
create mode 100644 include/hw/input/gamepad.h
135
create mode 100644 include/hw/input/tsc2xxx.h
136
create mode 100644 include/hw/misc/cbus.h
137
create mode 100644 include/hw/net/lan9118.h
138
create mode 100644 include/hw/net/smc91c111.h
57
139
58
include/hw/arm/aspeed_soc.h | 1 -
59
include/hw/arm/bcm2836.h | 1 +
60
target/arm/cpu.h | 71 ++++++++++++-----
61
target/arm/internals.h | 6 ++
62
hw/arm/aspeed_soc.c | 35 ++-------
63
hw/arm/bcm2836.c | 17 +++--
64
hw/arm/raspi.c | 57 +++++++++++---
65
hw/intc/armv7m_nvic.c | 98 ++++++++++++++++++------
66
target/arm/cpu.c | 28 +++++++
67
target/arm/helper.c | 84 +++++++++++++++-----
68
target/arm/machine.c | 84 ++++++++++++++++++++
69
target/arm/translate-a64.c | 181 ++++++++++++++++++++------------------------
70
12 files changed, 452 insertions(+), 211 deletions(-)
71
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Eric Auger <eric.auger@redhat.com>
2
2
3
When storing to an AdvSIMD FP register, all of the high
3
The SMMUNotifierNode struct is not necessary and brings extra
4
bits of the SVE register are zeroed. Therefore, call it
4
complexity so let's remove it. We now directly track the SMMUDevices
5
more often with is_q as a parameter.
5
which have registered IOMMU MR notifiers.
6
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
This is inspired from the same transformation on intel-iommu
8
Message-id: 20180211205848.4568-6-richard.henderson@linaro.org
8
done in commit b4a4ba0d68f50f218ee3957b6638dbee32a5eeef
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
("intel-iommu: remove IntelIOMMUNotifierNode")
10
11
Signed-off-by: Eric Auger <eric.auger@redhat.com>
12
Reviewed-by: Peter Xu <peterx@redhat.com>
13
Message-id: 20190409160219.19026-1-eric.auger@redhat.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
15
---
12
target/arm/translate-a64.c | 162 +++++++++++++++++----------------------------
16
include/hw/arm/smmu-common.h | 8 ++------
13
1 file changed, 62 insertions(+), 100 deletions(-)
17
hw/arm/smmu-common.c | 6 +++---
18
hw/arm/smmuv3.c | 28 +++++++---------------------
19
3 files changed, 12 insertions(+), 30 deletions(-)
14
20
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
21
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
16
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
23
--- a/include/hw/arm/smmu-common.h
18
+++ b/target/arm/translate-a64.c
24
+++ b/include/hw/arm/smmu-common.h
19
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 read_fp_sreg(DisasContext *s, int reg)
25
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUDevice {
20
return v;
26
AddressSpace as;
21
}
27
uint32_t cfg_cache_hits;
22
28
uint32_t cfg_cache_misses;
23
+/* Clear the bits above an N-bit vector, for N = (is_q ? 128 : 64).
29
+ QLIST_ENTRY(SMMUDevice) next;
24
+ * If SVE is not enabled, then there are only 128 bits in the vector.
30
} SMMUDevice;
25
+ */
31
26
+static void clear_vec_high(DisasContext *s, bool is_q, int rd)
32
-typedef struct SMMUNotifierNode {
27
+{
33
- SMMUDevice *sdev;
28
+ unsigned ofs = fp_reg_offset(s, rd, MO_64);
34
- QLIST_ENTRY(SMMUNotifierNode) next;
29
+ unsigned vsz = vec_full_reg_size(s);
35
-} SMMUNotifierNode;
30
+
36
-
31
+ if (!is_q) {
37
typedef struct SMMUPciBus {
32
+ TCGv_i64 tcg_zero = tcg_const_i64(0);
38
PCIBus *bus;
33
+ tcg_gen_st_i64(tcg_zero, cpu_env, ofs + 8);
39
SMMUDevice *pbdev[0]; /* Parent array is sparse, so dynamically alloc */
34
+ tcg_temp_free_i64(tcg_zero);
40
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUState {
35
+ }
41
GHashTable *iotlb;
36
+ if (vsz > 16) {
42
SMMUPciBus *smmu_pcibus_by_bus_num[SMMU_PCI_BUS_MAX];
37
+ tcg_gen_gvec_dup8i(ofs + 16, vsz - 16, vsz - 16, 0);
43
PCIBus *pci_bus;
38
+ }
44
- QLIST_HEAD(, SMMUNotifierNode) notifiers_list;
39
+}
45
+ QLIST_HEAD(, SMMUDevice) devices_with_notifiers;
40
+
46
uint8_t bus_num;
41
static void write_fp_dreg(DisasContext *s, int reg, TCGv_i64 v)
47
PCIBus *primary_bus;
48
} SMMUState;
49
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/smmu-common.c
52
+++ b/hw/arm/smmu-common.c
53
@@ -XXX,XX +XXX,XX @@ inline void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
54
/* Unmap all notifiers of all mr's */
55
void smmu_inv_notifiers_all(SMMUState *s)
42
{
56
{
43
- TCGv_i64 tcg_zero = tcg_const_i64(0);
57
- SMMUNotifierNode *node;
44
+ unsigned ofs = fp_reg_offset(s, reg, MO_64);
58
+ SMMUDevice *sdev;
45
59
46
- tcg_gen_st_i64(v, cpu_env, fp_reg_offset(s, reg, MO_64));
60
- QLIST_FOREACH(node, &s->notifiers_list, next) {
47
- tcg_gen_st_i64(tcg_zero, cpu_env, fp_reg_hi_offset(s, reg));
61
- smmu_inv_notifiers_mr(&node->sdev->iommu);
48
- tcg_temp_free_i64(tcg_zero);
62
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
49
+ tcg_gen_st_i64(v, cpu_env, ofs);
63
+ smmu_inv_notifiers_mr(&sdev->iommu);
50
+ clear_vec_high(s, false, reg);
51
}
52
53
static void write_fp_sreg(DisasContext *s, int reg, TCGv_i32 v)
54
@@ -XXX,XX +XXX,XX @@ static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size)
55
56
tcg_temp_free_i64(tmplo);
57
tcg_temp_free_i64(tmphi);
58
+
59
+ clear_vec_high(s, true, destidx);
60
}
61
62
/*
63
@@ -XXX,XX +XXX,XX @@ static void write_vec_element_i32(DisasContext *s, TCGv_i32 tcg_src,
64
}
64
}
65
}
65
}
66
66
67
-/* Clear the high 64 bits of a 128 bit vector (in general non-quad
67
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
68
- * vector ops all need to do this).
68
index XXXXXXX..XXXXXXX 100644
69
- */
69
--- a/hw/arm/smmuv3.c
70
-static void clear_vec_high(DisasContext *s, int rd)
70
+++ b/hw/arm/smmuv3.c
71
-{
71
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
72
- TCGv_i64 tcg_zero = tcg_const_i64(0);
72
/* invalidate an asid/iova tuple in all mr's */
73
static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova)
74
{
75
- SMMUNotifierNode *node;
76
+ SMMUDevice *sdev;
77
78
- QLIST_FOREACH(node, &s->notifiers_list, next) {
79
- IOMMUMemoryRegion *mr = &node->sdev->iommu;
80
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
81
+ IOMMUMemoryRegion *mr = &sdev->iommu;
82
IOMMUNotifier *n;
83
84
trace_smmuv3_inv_notifiers_iova(mr->parent_obj.name, asid, iova);
85
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
86
SMMUDevice *sdev = container_of(iommu, SMMUDevice, iommu);
87
SMMUv3State *s3 = sdev->smmu;
88
SMMUState *s = &(s3->smmu_state);
89
- SMMUNotifierNode *node = NULL;
90
- SMMUNotifierNode *next_node = NULL;
91
92
if (new & IOMMU_NOTIFIER_MAP) {
93
int bus_num = pci_bus_num(sdev->bus);
94
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
95
96
if (old == IOMMU_NOTIFIER_NONE) {
97
trace_smmuv3_notify_flag_add(iommu->parent_obj.name);
98
- node = g_malloc0(sizeof(*node));
99
- node->sdev = sdev;
100
- QLIST_INSERT_HEAD(&s->notifiers_list, node, next);
101
- return;
102
- }
73
-
103
-
74
- write_vec_element(s, tcg_zero, rd, 1, MO_64);
104
- /* update notifier node with new flags */
75
- tcg_temp_free_i64(tcg_zero);
105
- QLIST_FOREACH_SAFE(node, &s->notifiers_list, next, next_node) {
76
-}
106
- if (node->sdev == sdev) {
77
-
107
- if (new == IOMMU_NOTIFIER_NONE) {
78
/* Store from vector register to memory */
108
- trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
79
static void do_vec_st(DisasContext *s, int srcidx, int element,
109
- QLIST_REMOVE(node, next);
80
TCGv_i64 tcg_addr, int size)
110
- g_free(node);
81
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
111
- }
82
/* For non-quad operations, setting a slice of the low
112
- return;
83
* 64 bits of the register clears the high 64 bits (in
84
* the ARM ARM pseudocode this is implicit in the fact
85
- * that 'rval' is a 64 bit wide variable). We optimize
86
- * by noticing that we only need to do this the first
87
- * time we touch a register.
88
+ * that 'rval' is a 64 bit wide variable).
89
+ * For quad operations, we might still need to zero the
90
+ * high bits of SVE. We optimize by noticing that we only
91
+ * need to do this the first time we touch a register.
92
*/
93
- if (!is_q && e == 0 && (r == 0 || xs == selem - 1)) {
94
- clear_vec_high(s, tt);
95
+ if (e == 0 && (r == 0 || xs == selem - 1)) {
96
+ clear_vec_high(s, is_q, tt);
97
}
98
}
99
tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes);
100
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
101
write_vec_element(s, tcg_tmp, rt, 0, MO_64);
102
if (is_q) {
103
write_vec_element(s, tcg_tmp, rt, 1, MO_64);
104
- } else {
105
- clear_vec_high(s, rt);
106
}
107
tcg_temp_free_i64(tcg_tmp);
108
+ clear_vec_high(s, is_q, rt);
109
} else {
110
/* Load/store one element per register */
111
if (is_load) {
112
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_sqshrn(DisasContext *s, bool is_scalar, bool is_q,
113
}
114
115
if (!is_q) {
116
- clear_vec_high(s, rd);
117
write_vec_element(s, tcg_final, rd, 0, MO_64);
118
} else {
119
write_vec_element(s, tcg_final, rd, 1, MO_64);
120
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_sqshrn(DisasContext *s, bool is_scalar, bool is_q,
121
tcg_temp_free_i64(tcg_rd);
122
tcg_temp_free_i32(tcg_rd_narrowed);
123
tcg_temp_free_i64(tcg_final);
124
- return;
125
+
126
+ clear_vec_high(s, is_q, rd);
127
}
128
129
/* SQSHLU, UQSHL, SQSHL: saturating left shifts */
130
@@ -XXX,XX +XXX,XX @@ static void handle_simd_qshl(DisasContext *s, bool scalar, bool is_q,
131
tcg_temp_free_i64(tcg_op);
132
}
133
tcg_temp_free_i64(tcg_shift);
134
-
135
- if (!is_q) {
136
- clear_vec_high(s, rd);
137
- }
113
- }
138
+ clear_vec_high(s, is_q, rd);
114
+ QLIST_INSERT_HEAD(&s->devices_with_notifiers, sdev, next);
139
} else {
115
+ } else if (new == IOMMU_NOTIFIER_NONE) {
140
TCGv_i32 tcg_shift = tcg_const_i32(shift);
116
+ trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
141
static NeonGenTwoOpEnvFn * const fns[2][2][3] = {
117
+ QLIST_REMOVE(sdev, next);
142
@@ -XXX,XX +XXX,XX @@ static void handle_simd_qshl(DisasContext *s, bool scalar, bool is_q,
143
}
144
tcg_temp_free_i32(tcg_shift);
145
146
- if (!is_q && !scalar) {
147
- clear_vec_high(s, rd);
148
+ if (!scalar) {
149
+ clear_vec_high(s, is_q, rd);
150
}
151
}
118
}
152
}
119
}
153
@@ -XXX,XX +XXX,XX @@ static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn,
154
}
155
}
156
157
- if (!is_double && elements == 2) {
158
- clear_vec_high(s, rd);
159
- }
160
-
161
tcg_temp_free_i64(tcg_int);
162
tcg_temp_free_ptr(tcg_fpst);
163
tcg_temp_free_i32(tcg_shift);
164
+
165
+ clear_vec_high(s, elements << size == 16, rd);
166
}
167
168
/* UCVTF/SCVTF - Integer to FP conversion */
169
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
170
write_vec_element(s, tcg_op, rd, pass, MO_64);
171
tcg_temp_free_i64(tcg_op);
172
}
173
- if (!is_q) {
174
- clear_vec_high(s, rd);
175
- }
176
+ clear_vec_high(s, is_q, rd);
177
} else {
178
int maxpass = is_scalar ? 1 : is_q ? 4 : 2;
179
for (pass = 0; pass < maxpass; pass++) {
180
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
181
}
182
tcg_temp_free_i32(tcg_op);
183
}
184
- if (!is_q && !is_scalar) {
185
- clear_vec_high(s, rd);
186
+ if (!is_scalar) {
187
+ clear_vec_high(s, is_q, rd);
188
}
189
}
190
191
@@ -XXX,XX +XXX,XX @@ static void handle_3same_float(DisasContext *s, int size, int elements,
192
193
tcg_temp_free_ptr(fpst);
194
195
- if ((elements << size) < 4) {
196
- /* scalar, or non-quad vector op */
197
- clear_vec_high(s, rd);
198
- }
199
+ clear_vec_high(s, elements * (size ? 8 : 4) > 8, rd);
200
}
201
202
/* AdvSIMD scalar three same
203
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
204
}
205
write_vec_element(s, tcg_res, rd, pass, MO_64);
206
}
207
- if (is_scalar) {
208
- clear_vec_high(s, rd);
209
- }
210
-
211
tcg_temp_free_i64(tcg_res);
212
tcg_temp_free_i64(tcg_zero);
213
tcg_temp_free_i64(tcg_op);
214
+
215
+ clear_vec_high(s, !is_scalar, rd);
216
} else {
217
TCGv_i32 tcg_op = tcg_temp_new_i32();
218
TCGv_i32 tcg_zero = tcg_const_i32(0);
219
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
220
tcg_temp_free_i32(tcg_res);
221
tcg_temp_free_i32(tcg_zero);
222
tcg_temp_free_i32(tcg_op);
223
- if (!is_q && !is_scalar) {
224
- clear_vec_high(s, rd);
225
+ if (!is_scalar) {
226
+ clear_vec_high(s, is_q, rd);
227
}
228
}
229
230
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_reciprocal(DisasContext *s, int opcode,
231
}
232
write_vec_element(s, tcg_res, rd, pass, MO_64);
233
}
234
- if (is_scalar) {
235
- clear_vec_high(s, rd);
236
- }
237
-
238
tcg_temp_free_i64(tcg_res);
239
tcg_temp_free_i64(tcg_op);
240
+ clear_vec_high(s, !is_scalar, rd);
241
} else {
242
TCGv_i32 tcg_op = tcg_temp_new_i32();
243
TCGv_i32 tcg_res = tcg_temp_new_i32();
244
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_reciprocal(DisasContext *s, int opcode,
245
}
246
tcg_temp_free_i32(tcg_res);
247
tcg_temp_free_i32(tcg_op);
248
- if (!is_q && !is_scalar) {
249
- clear_vec_high(s, rd);
250
+ if (!is_scalar) {
251
+ clear_vec_high(s, is_q, rd);
252
}
253
}
254
tcg_temp_free_ptr(fpst);
255
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_narrow(DisasContext *s, bool scalar,
256
write_vec_element_i32(s, tcg_res[pass], rd, destelt + pass, MO_32);
257
tcg_temp_free_i32(tcg_res[pass]);
258
}
259
- if (!is_q) {
260
- clear_vec_high(s, rd);
261
- }
262
+ clear_vec_high(s, is_q, rd);
263
}
264
265
/* Remaining saturating accumulating ops */
266
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_satacc(DisasContext *s, bool is_scalar, bool is_u,
267
}
268
write_vec_element(s, tcg_rd, rd, pass, MO_64);
269
}
270
- if (is_scalar) {
271
- clear_vec_high(s, rd);
272
- }
273
-
274
tcg_temp_free_i64(tcg_rd);
275
tcg_temp_free_i64(tcg_rn);
276
+ clear_vec_high(s, !is_scalar, rd);
277
} else {
278
TCGv_i32 tcg_rn = tcg_temp_new_i32();
279
TCGv_i32 tcg_rd = tcg_temp_new_i32();
280
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_satacc(DisasContext *s, bool is_scalar, bool is_u,
281
}
282
write_vec_element_i32(s, tcg_rd, rd, pass, MO_32);
283
}
284
-
285
- if (!is_q) {
286
- clear_vec_high(s, rd);
287
- }
288
-
289
tcg_temp_free_i32(tcg_rd);
290
tcg_temp_free_i32(tcg_rn);
291
+ clear_vec_high(s, is_q, rd);
292
}
293
}
294
295
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
296
tcg_temp_free_i64(tcg_round);
297
298
done:
299
- if (!is_q) {
300
- clear_vec_high(s, rd);
301
- }
302
+ clear_vec_high(s, is_q, rd);
303
}
304
305
static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
306
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_shrn(DisasContext *s, bool is_q,
307
}
308
309
if (!is_q) {
310
- clear_vec_high(s, rd);
311
write_vec_element(s, tcg_final, rd, 0, MO_64);
312
} else {
313
write_vec_element(s, tcg_final, rd, 1, MO_64);
314
}
315
-
316
if (round) {
317
tcg_temp_free_i64(tcg_round);
318
}
319
tcg_temp_free_i64(tcg_rn);
320
tcg_temp_free_i64(tcg_rd);
321
tcg_temp_free_i64(tcg_final);
322
- return;
323
+
324
+ clear_vec_high(s, is_q, rd);
325
}
326
327
328
@@ -XXX,XX +XXX,XX @@ static void handle_3rd_narrowing(DisasContext *s, int is_q, int is_u, int size,
329
write_vec_element_i32(s, tcg_res[pass], rd, pass + part, MO_32);
330
tcg_temp_free_i32(tcg_res[pass]);
331
}
332
- if (!is_q) {
333
- clear_vec_high(s, rd);
334
- }
335
+ clear_vec_high(s, is_q, rd);
336
}
337
338
static void handle_pmull_64(DisasContext *s, int is_q, int rd, int rn, int rm)
339
@@ -XXX,XX +XXX,XX @@ static void handle_simd_3same_pair(DisasContext *s, int is_q, int u, int opcode,
340
write_vec_element_i32(s, tcg_res[pass], rd, pass, MO_32);
341
tcg_temp_free_i32(tcg_res[pass]);
342
}
343
- if (!is_q) {
344
- clear_vec_high(s, rd);
345
- }
346
+ clear_vec_high(s, is_q, rd);
347
}
348
349
if (fpst) {
350
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
351
tcg_temp_free_i32(tcg_op2);
352
}
353
}
354
-
355
- if (!is_q) {
356
- clear_vec_high(s, rd);
357
- }
358
+ clear_vec_high(s, is_q, rd);
359
}
360
361
/* AdvSIMD three same
362
@@ -XXX,XX +XXX,XX @@ static void handle_rev(DisasContext *s, int opcode, bool u,
363
write_vec_element(s, tcg_tmp, rd, i, grp_size);
364
tcg_temp_free_i64(tcg_tmp);
365
}
366
- if (!is_q) {
367
- clear_vec_high(s, rd);
368
- }
369
+ clear_vec_high(s, is_q, rd);
370
} else {
371
int revmask = (1 << grp_size) - 1;
372
int esize = 8 << size;
373
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
374
tcg_temp_free_i32(tcg_op);
375
}
376
}
377
- if (!is_q) {
378
- clear_vec_high(s, rd);
379
- }
380
+ clear_vec_high(s, is_q, rd);
381
382
if (need_rmode) {
383
gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
384
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
385
tcg_temp_free_i64(tcg_res);
386
}
387
388
- if (is_scalar) {
389
- clear_vec_high(s, rd);
390
- }
391
-
392
tcg_temp_free_i64(tcg_idx);
393
+ clear_vec_high(s, !is_scalar, rd);
394
} else if (!is_long) {
395
/* 32 bit floating point, or 16 or 32 bit integer.
396
* For the 16 bit scalar case we use the usual Neon helpers and
397
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
398
}
399
400
tcg_temp_free_i32(tcg_idx);
401
-
402
- if (!is_q) {
403
- clear_vec_high(s, rd);
404
- }
405
+ clear_vec_high(s, is_q, rd);
406
} else {
407
/* long ops: 16x16->32 or 32x32->64 */
408
TCGv_i64 tcg_res[2];
409
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
410
}
411
tcg_temp_free_i64(tcg_idx);
412
413
- if (is_scalar) {
414
- clear_vec_high(s, rd);
415
- }
416
+ clear_vec_high(s, !is_scalar, rd);
417
} else {
418
TCGv_i32 tcg_idx = tcg_temp_new_i32();
419
120
420
--
121
--
421
2.16.1
122
2.20.1
422
123
423
124
diff view generated by jsdifflib
New patch
1
In the stripe8() function we use a variable length array; however
2
we know that the maximum length required is MAX_NUM_BUSSES. Use
3
a fixed-length array and an assert instead.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
10
Message-id: 20190328152635.2794-1-peter.maydell@linaro.org
11
---
12
hw/ssi/xilinx_spips.c | 6 ++++--
13
1 file changed, 4 insertions(+), 2 deletions(-)
14
15
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/ssi/xilinx_spips.c
18
+++ b/hw/ssi/xilinx_spips.c
19
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_reset(DeviceState *d)
20
21
static inline void stripe8(uint8_t *x, int num, bool dir)
22
{
23
- uint8_t r[num];
24
- memset(r, 0, sizeof(uint8_t) * num);
25
+ uint8_t r[MAX_NUM_BUSSES];
26
int idx[2] = {0, 0};
27
int bit[2] = {0, 7};
28
int d = dir;
29
30
+ assert(num <= MAX_NUM_BUSSES);
31
+ memset(r, 0, sizeof(uint8_t) * num);
32
+
33
for (idx[0] = 0; idx[0] < num; ++idx[0]) {
34
for (bit[0] = 7; bit[0] >= 0; bit[0]--) {
35
r[idx[!d]] |= x[idx[d]] & 1 << bit[d] ? 1 << bit[!d] : 0;
36
--
37
2.20.1
38
39
diff view generated by jsdifflib
New patch
1
Normally configure identifies the source path by looking
2
at the location where the configure script itself exists.
3
We also provide a --source-path option which lets the user
4
manually override this.
1
5
6
There isn't really an obvious use case for the --source-path
7
option, and in commit 927128222b0a91f56c13a in 2017 we
8
accidentally added some logic that looks at $source_path
9
before the command line option that overrides it has been
10
processed.
11
12
The fact that nobody complained suggests that there isn't
13
any use of this option and we aren't testing it either;
14
remove it. This allows us to move the "make $source_path
15
absolute" logic up so that there is no window in the script
16
where $source_path is set but not yet absolute.
17
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
20
Message-id: 20190318134019.23729-1-peter.maydell@linaro.org
21
---
22
configure | 10 ++--------
23
1 file changed, 2 insertions(+), 8 deletions(-)
24
25
diff --git a/configure b/configure
26
index XXXXXXX..XXXXXXX 100755
27
--- a/configure
28
+++ b/configure
29
@@ -XXX,XX +XXX,XX @@ ld_has() {
30
31
# default parameters
32
source_path=$(dirname "$0")
33
+# make source path absolute
34
+source_path=$(cd "$source_path"; pwd)
35
cpu=""
36
iasl="iasl"
37
interp_prefix="/usr/gnemul/qemu-%M"
38
@@ -XXX,XX +XXX,XX @@ for opt do
39
;;
40
--cxx=*) CXX="$optarg"
41
;;
42
- --source-path=*) source_path="$optarg"
43
- ;;
44
--cpu=*) cpu="$optarg"
45
;;
46
--extra-cflags=*) QEMU_CFLAGS="$QEMU_CFLAGS $optarg"
47
@@ -XXX,XX +XXX,XX @@ if test "$debug_info" = "yes"; then
48
LDFLAGS="-g $LDFLAGS"
49
fi
50
51
-# make source path absolute
52
-source_path=$(cd "$source_path"; pwd)
53
-
54
# running configure in the source tree?
55
# we know that's the case if configure is there.
56
if test -f "./configure"; then
57
@@ -XXX,XX +XXX,XX @@ for opt do
58
;;
59
--interp-prefix=*) interp_prefix="$optarg"
60
;;
61
- --source-path=*)
62
- ;;
63
--cross-prefix=*)
64
;;
65
--cc=*)
66
@@ -XXX,XX +XXX,XX @@ $(echo Available targets: $default_target_list | \
67
--target-list-exclude=LIST exclude a set of targets from the default target-list
68
69
Advanced options (experts only):
70
- --source-path=PATH path of source code [$source_path]
71
--cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]
72
--cc=CC use C compiler CC [$cc]
73
--iasl=IASL use ACPI compiler IASL [$iasl]
74
--
75
2.20.1
76
77
diff view generated by jsdifflib
1
The Coprocessor Power Control Register (CPPWR) is new in v8M.
1
Enforce that for M-profile various FPSCR bits which are RES0 there
2
It allows software to control whether coprocessors are allowed
2
but have defined meanings on A-profile are never settable. This
3
to power down and lose their state. QEMU doesn't have any
3
ensures that M-profile code can't enable the A-profile behaviour
4
notion of power control, so we choose the IMPDEF option of
4
(notably vector length/stride handling) by accident.
5
making the whole register RAZ/WI (indicating that no coprocessors
6
can ever power down and lose state).
7
5
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180209165810.6668-5-peter.maydell@linaro.org
8
Message-id: 20190416125744.27770-2-peter.maydell@linaro.org
11
---
9
---
12
hw/intc/armv7m_nvic.c | 14 ++++++++++++++
10
target/arm/vfp_helper.c | 8 ++++++++
13
1 file changed, 14 insertions(+)
11
1 file changed, 8 insertions(+)
14
12
15
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
13
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/intc/armv7m_nvic.c
15
--- a/target/arm/vfp_helper.c
18
+++ b/hw/intc/armv7m_nvic.c
16
+++ b/target/arm/vfp_helper.c
19
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
17
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
20
switch (offset) {
18
val &= ~FPCR_FZ16;
21
case 4: /* Interrupt Control Type. */
19
}
22
return ((s->num_irq - NVIC_FIRST_IRQ) / 32) - 1;
20
23
+ case 0xc: /* CPPWR */
21
+ if (arm_feature(env, ARM_FEATURE_M)) {
24
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
22
+ /*
25
+ goto bad_offset;
23
+ * M profile FPSCR is RES0 for the QC, STRIDE, FZ16, LEN bits
26
+ }
24
+ * and also for the trapped-exception-handling bits IxE.
27
+ /* We make the IMPDEF choice that nothing can ever go into a
28
+ * non-retentive power state, which allows us to RAZ/WI this.
29
+ */
25
+ */
30
+ return 0;
26
+ val &= 0xf7c0009f;
31
case 0x380 ... 0x3bf: /* NVIC_ITNS<n> */
27
+ }
32
{
28
+
33
int startvec = 8 * (offset - 0x380) + NVIC_FIRST_IRQ;
29
/*
34
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
30
* We don't implement trapped exception handling, so the
35
ARMCPU *cpu = s->cpu;
31
* trap enable bits, IDE|IXE|UFE|OFE|DZE|IOE are all RAZ/WI (not RES0!)
36
37
switch (offset) {
38
+ case 0xc: /* CPPWR */
39
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
40
+ goto bad_offset;
41
+ }
42
+ /* Make the IMPDEF choice to RAZ/WI this. */
43
+ break;
44
case 0x380 ... 0x3bf: /* NVIC_ITNS<n> */
45
{
46
int startvec = 8 * (offset - 0x380) + NVIC_FIRST_IRQ;
47
--
32
--
48
2.16.1
33
2.20.1
49
34
50
35
diff view generated by jsdifflib
1
For M profile cores, cache maintenance operations are done by
1
For M-profile the MVFR* ID registers are memory mapped, in the
2
writing to special registers in the system register space.
2
range we implement via the NVIC. Allow them to be read.
3
For QEMU, cache operations are always NOPs, since we don't
3
(If the CPU has no FPU, these registers are defined to be RAZ.)
4
implement the cache. Implementing these explicitly avoids
5
a spurious LOG_GUEST_ERROR when the guest uses them.
6
4
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180209165810.6668-4-peter.maydell@linaro.org
7
Message-id: 20190416125744.27770-3-peter.maydell@linaro.org
10
---
8
---
11
hw/intc/armv7m_nvic.c | 12 ++++++++++++
9
hw/intc/armv7m_nvic.c | 6 ++++++
12
1 file changed, 12 insertions(+)
10
1 file changed, 6 insertions(+)
13
11
14
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
12
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
15
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/armv7m_nvic.c
14
--- a/hw/intc/armv7m_nvic.c
17
+++ b/hw/intc/armv7m_nvic.c
15
+++ b/hw/intc/armv7m_nvic.c
18
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
16
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
17
return 0;
19
}
18
}
20
break;
19
return cpu->env.v7m.sfar;
21
}
20
+ case 0xf40: /* MVFR0 */
22
+ case 0xf50: /* ICIALLU */
21
+ return cpu->isar.mvfr0;
23
+ case 0xf58: /* ICIMVAU */
22
+ case 0xf44: /* MVFR1 */
24
+ case 0xf5c: /* DCIMVAC */
23
+ return cpu->isar.mvfr1;
25
+ case 0xf60: /* DCISW */
24
+ case 0xf48: /* MVFR2 */
26
+ case 0xf64: /* DCCMVAU */
25
+ return cpu->isar.mvfr2;
27
+ case 0xf68: /* DCCMVAC */
28
+ case 0xf6c: /* DCCSW */
29
+ case 0xf70: /* DCCIMVAC */
30
+ case 0xf74: /* DCCISW */
31
+ case 0xf78: /* BPIALL */
32
+ /* Cache and branch predictor maintenance: for QEMU these always NOP */
33
+ break;
34
default:
26
default:
35
bad_offset:
27
bad_offset:
36
qemu_log_mask(LOG_GUEST_ERROR,
28
qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
37
--
29
--
38
2.16.1
30
2.20.1
39
31
40
32
diff view generated by jsdifflib
1
M profile cores have a similar setup for cache ID registers
1
The M-profile floating point support has three associated config
2
to A profile:
2
registers: FPCAR, FPCCR and FPDSCR. It also makes the registers
3
* Cache Level ID Register (CLIDR) is a fixed value
3
CPACR and NSACR have behaviour other than reads-as-zero.
4
* Cache Type Register (CTR) is a fixed value
4
Add support for all of these as simple reads-as-written registers.
5
* Cache Size ID Registers (CCSIDR) are a bank of registers;
5
We will hook up actual functionality later.
6
which one you see is selected by the Cache Size Selection
6
7
Register (CSSELR)
7
The main complexity here is handling the FPCCR register, which
8
8
has a mix of banked and unbanked bits.
9
The only difference is that they're in the NVIC memory mapped
9
10
register space rather than being coprocessor registers.
10
Note that we don't share storage with the A-profile
11
Implement the M profile view of them.
11
cpu->cp15.nsacr and cpu->cp15.cpacr_el1, though the behaviour
12
12
is quite similar, for two reasons:
13
Since neither Cortex-M3 nor Cortex-M4 implement caches,
13
* the M profile CPACR is banked between security states
14
we don't need to update their init functions and can leave
14
* it preserves the invariant that M profile uses no state
15
the ctr/clidr/ccsidr[] fields in their ARMCPU structs at zero.
15
inside the cp15 substruct
16
Newer cores (like the Cortex-M33) will want to be able to
17
set these ID registers to non-zero values, though.
18
16
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Message-id: 20180209165810.6668-6-peter.maydell@linaro.org
19
Message-id: 20190416125744.27770-4-peter.maydell@linaro.org
22
---
20
---
23
target/arm/cpu.h | 26 ++++++++++++++++++++++++++
21
target/arm/cpu.h | 34 ++++++++++++
24
hw/intc/armv7m_nvic.c | 16 ++++++++++++++++
22
hw/intc/armv7m_nvic.c | 125 ++++++++++++++++++++++++++++++++++++++++++
25
target/arm/machine.c | 36 ++++++++++++++++++++++++++++++++++++
23
target/arm/cpu.c | 5 ++
26
3 files changed, 78 insertions(+)
24
target/arm/machine.c | 16 ++++++
25
4 files changed, 180 insertions(+)
27
26
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
27
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
29
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
29
--- a/target/arm/cpu.h
31
+++ b/target/arm/cpu.h
30
+++ b/target/arm/cpu.h
32
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
31
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
33
uint32_t faultmask[M_REG_NUM_BANKS];
32
uint32_t scr[M_REG_NUM_BANKS];
34
uint32_t aircr; /* only holds r/w state if security extn implemented */
33
uint32_t msplim[M_REG_NUM_BANKS];
35
uint32_t secure; /* Is CPU in Secure state? (not guest visible) */
34
uint32_t psplim[M_REG_NUM_BANKS];
36
+ uint32_t csselr[M_REG_NUM_BANKS];
35
+ uint32_t fpcar[M_REG_NUM_BANKS];
36
+ uint32_t fpccr[M_REG_NUM_BANKS];
37
+ uint32_t fpdscr[M_REG_NUM_BANKS];
38
+ uint32_t cpacr[M_REG_NUM_BANKS];
39
+ uint32_t nsacr;
37
} v7m;
40
} v7m;
38
41
39
/* Information associated with an exception about to be taken:
42
/* Information associated with an exception about to be taken:
40
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_MPU_CTRL, ENABLE, 0, 1)
43
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_CSSELR, LEVEL, 1, 3)
41
FIELD(V7M_MPU_CTRL, HFNMIENA, 1, 1)
44
*/
42
FIELD(V7M_MPU_CTRL, PRIVDEFENA, 2, 1)
45
FIELD(V7M_CSSELR, INDEX, 0, 4)
43
46
44
+/* v7M CLIDR bits */
47
+/* v7M FPCCR bits */
45
+FIELD(V7M_CLIDR, CTYPE_ALL, 0, 21)
48
+FIELD(V7M_FPCCR, LSPACT, 0, 1)
46
+FIELD(V7M_CLIDR, LOUIS, 21, 3)
49
+FIELD(V7M_FPCCR, USER, 1, 1)
47
+FIELD(V7M_CLIDR, LOC, 24, 3)
50
+FIELD(V7M_FPCCR, S, 2, 1)
48
+FIELD(V7M_CLIDR, LOUU, 27, 3)
51
+FIELD(V7M_FPCCR, THREAD, 3, 1)
49
+FIELD(V7M_CLIDR, ICB, 30, 2)
52
+FIELD(V7M_FPCCR, HFRDY, 4, 1)
50
+
53
+FIELD(V7M_FPCCR, MMRDY, 5, 1)
51
+FIELD(V7M_CSSELR, IND, 0, 1)
54
+FIELD(V7M_FPCCR, BFRDY, 6, 1)
52
+FIELD(V7M_CSSELR, LEVEL, 1, 3)
55
+FIELD(V7M_FPCCR, SFRDY, 7, 1)
53
+/* We use the combination of InD and Level to index into cpu->ccsidr[];
56
+FIELD(V7M_FPCCR, MONRDY, 8, 1)
54
+ * define a mask for this and check that it doesn't permit running off
57
+FIELD(V7M_FPCCR, SPLIMVIOL, 9, 1)
55
+ * the end of the array.
58
+FIELD(V7M_FPCCR, UFRDY, 10, 1)
56
+ */
59
+FIELD(V7M_FPCCR, RES0, 11, 15)
57
+FIELD(V7M_CSSELR, INDEX, 0, 4)
60
+FIELD(V7M_FPCCR, TS, 26, 1)
58
+
61
+FIELD(V7M_FPCCR, CLRONRETS, 27, 1)
59
+QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
62
+FIELD(V7M_FPCCR, CLRONRET, 28, 1)
60
+
63
+FIELD(V7M_FPCCR, LSPENS, 29, 1)
61
/* If adding a feature bit which corresponds to a Linux ELF
64
+FIELD(V7M_FPCCR, LSPEN, 30, 1)
62
* HWCAP bit, remember to update the feature-bit-to-hwcap
65
+FIELD(V7M_FPCCR, ASPEN, 31, 1)
63
* mapping in linux-user/elfload.c:get_elf_hwcap().
66
+/* These bits are banked. Others are non-banked and live in the M_REG_S bank */
64
@@ -XXX,XX +XXX,XX @@ static inline int arm_debug_target_el(CPUARMState *env)
67
+#define R_V7M_FPCCR_BANKED_MASK \
65
}
68
+ (R_V7M_FPCCR_LSPACT_MASK | \
66
}
69
+ R_V7M_FPCCR_USER_MASK | \
67
70
+ R_V7M_FPCCR_THREAD_MASK | \
68
+static inline bool arm_v7m_csselr_razwi(ARMCPU *cpu)
71
+ R_V7M_FPCCR_MMRDY_MASK | \
69
+{
72
+ R_V7M_FPCCR_SPLIMVIOL_MASK | \
70
+ /* If all the CLIDR.Ctypem bits are 0 there are no caches, and
73
+ R_V7M_FPCCR_UFRDY_MASK | \
71
+ * CSSELR is RAZ/WI.
74
+ R_V7M_FPCCR_ASPEN_MASK)
72
+ */
75
+
73
+ return (cpu->clidr & R_V7M_CLIDR_CTYPE_ALL_MASK) != 0;
76
/*
74
+}
77
* System register ID fields.
75
+
78
*/
76
static inline bool aa64_generate_debug_exceptions(CPUARMState *env)
77
{
78
if (arm_is_secure(env)) {
79
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
79
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
80
index XXXXXXX..XXXXXXX 100644
80
index XXXXXXX..XXXXXXX 100644
81
--- a/hw/intc/armv7m_nvic.c
81
--- a/hw/intc/armv7m_nvic.c
82
+++ b/hw/intc/armv7m_nvic.c
82
+++ b/hw/intc/armv7m_nvic.c
83
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
83
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
84
return cpu->id_isar4;
84
}
85
case 0xd74: /* ISAR5. */
85
case 0xd84: /* CSSELR */
86
return cpu->id_isar5;
86
return cpu->env.v7m.csselr[attrs.secure];
87
+ case 0xd78: /* CLIDR */
87
+ case 0xd88: /* CPACR */
88
+ return cpu->clidr;
88
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
89
+ case 0xd7c: /* CTR */
89
+ return 0;
90
+ return cpu->ctr;
90
+ }
91
+ case 0xd80: /* CSSIDR */
91
+ return cpu->env.v7m.cpacr[attrs.secure];
92
+ {
92
+ case 0xd8c: /* NSACR */
93
+ int idx = cpu->env.v7m.csselr[attrs.secure] & R_V7M_CSSELR_INDEX_MASK;
93
+ if (!attrs.secure || !arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
94
+ return cpu->ccsidr[idx];
94
+ return 0;
95
+ }
95
+ }
96
+ case 0xd84: /* CSSELR */
96
+ return cpu->env.v7m.nsacr;
97
+ return cpu->env.v7m.csselr[attrs.secure];
98
/* TODO: Implement debug registers. */
97
/* TODO: Implement debug registers. */
99
case 0xd90: /* MPU_TYPE */
98
case 0xd90: /* MPU_TYPE */
100
/* Unified MPU; if the MPU is not present this value is zero */
99
/* Unified MPU; if the MPU is not present this value is zero */
100
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
101
return 0;
102
}
103
return cpu->env.v7m.sfar;
104
+ case 0xf34: /* FPCCR */
105
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
106
+ return 0;
107
+ }
108
+ if (attrs.secure) {
109
+ return cpu->env.v7m.fpccr[M_REG_S];
110
+ } else {
111
+ /*
112
+ * NS can read LSPEN, CLRONRET and MONRDY. It can read
113
+ * BFRDY and HFRDY if AIRCR.BFHFNMINS != 0;
114
+ * other non-banked bits RAZ.
115
+ * TODO: MONRDY should RAZ/WI if DEMCR.SDME is set.
116
+ */
117
+ uint32_t value = cpu->env.v7m.fpccr[M_REG_S];
118
+ uint32_t mask = R_V7M_FPCCR_LSPEN_MASK |
119
+ R_V7M_FPCCR_CLRONRET_MASK |
120
+ R_V7M_FPCCR_MONRDY_MASK;
121
+
122
+ if (s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
123
+ mask |= R_V7M_FPCCR_BFRDY_MASK | R_V7M_FPCCR_HFRDY_MASK;
124
+ }
125
+
126
+ value &= mask;
127
+
128
+ value |= cpu->env.v7m.fpccr[M_REG_NS];
129
+ return value;
130
+ }
131
+ case 0xf38: /* FPCAR */
132
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
133
+ return 0;
134
+ }
135
+ return cpu->env.v7m.fpcar[attrs.secure];
136
+ case 0xf3c: /* FPDSCR */
137
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
138
+ return 0;
139
+ }
140
+ return cpu->env.v7m.fpdscr[attrs.secure];
141
case 0xf40: /* MVFR0 */
142
return cpu->isar.mvfr0;
143
case 0xf44: /* MVFR1 */
101
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
144
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
102
qemu_log_mask(LOG_UNIMP,
145
cpu->env.v7m.csselr[attrs.secure] = value & R_V7M_CSSELR_INDEX_MASK;
103
"NVIC: Aux fault status registers unimplemented\n");
146
}
104
break;
147
break;
105
+ case 0xd84: /* CSSELR */
148
+ case 0xd88: /* CPACR */
106
+ if (!arm_v7m_csselr_razwi(cpu)) {
149
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
107
+ cpu->env.v7m.csselr[attrs.secure] = value & R_V7M_CSSELR_INDEX_MASK;
150
+ /* We implement only the Floating Point extension's CP10/CP11 */
151
+ cpu->env.v7m.cpacr[attrs.secure] = value & (0xf << 20);
152
+ }
153
+ break;
154
+ case 0xd8c: /* NSACR */
155
+ if (attrs.secure && arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
156
+ /* We implement only the Floating Point extension's CP10/CP11 */
157
+ cpu->env.v7m.nsacr = value & (3 << 10);
108
+ }
158
+ }
109
+ break;
159
+ break;
110
case 0xd90: /* MPU_TYPE */
160
case 0xd90: /* MPU_TYPE */
111
return; /* RO */
161
return; /* RO */
112
case 0xd94: /* MPU_CTRL */
162
case 0xd94: /* MPU_CTRL */
163
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
164
}
165
break;
166
}
167
+ case 0xf34: /* FPCCR */
168
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
169
+ /* Not all bits here are banked. */
170
+ uint32_t fpccr_s;
171
+
172
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
173
+ /* Don't allow setting of bits not present in v7M */
174
+ value &= (R_V7M_FPCCR_LSPACT_MASK |
175
+ R_V7M_FPCCR_USER_MASK |
176
+ R_V7M_FPCCR_THREAD_MASK |
177
+ R_V7M_FPCCR_HFRDY_MASK |
178
+ R_V7M_FPCCR_MMRDY_MASK |
179
+ R_V7M_FPCCR_BFRDY_MASK |
180
+ R_V7M_FPCCR_MONRDY_MASK |
181
+ R_V7M_FPCCR_LSPEN_MASK |
182
+ R_V7M_FPCCR_ASPEN_MASK);
183
+ }
184
+ value &= ~R_V7M_FPCCR_RES0_MASK;
185
+
186
+ if (!attrs.secure) {
187
+ /* Some non-banked bits are configurably writable by NS */
188
+ fpccr_s = cpu->env.v7m.fpccr[M_REG_S];
189
+ if (!(fpccr_s & R_V7M_FPCCR_LSPENS_MASK)) {
190
+ uint32_t lspen = FIELD_EX32(value, V7M_FPCCR, LSPEN);
191
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, LSPEN, lspen);
192
+ }
193
+ if (!(fpccr_s & R_V7M_FPCCR_CLRONRETS_MASK)) {
194
+ uint32_t cor = FIELD_EX32(value, V7M_FPCCR, CLRONRET);
195
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, CLRONRET, cor);
196
+ }
197
+ if ((s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
198
+ uint32_t hfrdy = FIELD_EX32(value, V7M_FPCCR, HFRDY);
199
+ uint32_t bfrdy = FIELD_EX32(value, V7M_FPCCR, BFRDY);
200
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, HFRDY, hfrdy);
201
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, BFRDY, bfrdy);
202
+ }
203
+ /* TODO MONRDY should RAZ/WI if DEMCR.SDME is set */
204
+ {
205
+ uint32_t monrdy = FIELD_EX32(value, V7M_FPCCR, MONRDY);
206
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, MONRDY, monrdy);
207
+ }
208
+
209
+ /*
210
+ * All other non-banked bits are RAZ/WI from NS; write
211
+ * just the banked bits to fpccr[M_REG_NS].
212
+ */
213
+ value &= R_V7M_FPCCR_BANKED_MASK;
214
+ cpu->env.v7m.fpccr[M_REG_NS] = value;
215
+ } else {
216
+ fpccr_s = value;
217
+ }
218
+ cpu->env.v7m.fpccr[M_REG_S] = fpccr_s;
219
+ }
220
+ break;
221
+ case 0xf38: /* FPCAR */
222
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
223
+ value &= ~7;
224
+ cpu->env.v7m.fpcar[attrs.secure] = value;
225
+ }
226
+ break;
227
+ case 0xf3c: /* FPDSCR */
228
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
229
+ value &= 0x07c00000;
230
+ cpu->env.v7m.fpdscr[attrs.secure] = value;
231
+ }
232
+ break;
233
case 0xf50: /* ICIALLU */
234
case 0xf58: /* ICIMVAU */
235
case 0xf5c: /* DCIMVAC */
236
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
237
index XXXXXXX..XXXXXXX 100644
238
--- a/target/arm/cpu.c
239
+++ b/target/arm/cpu.c
240
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
241
env->v7m.ccr[M_REG_S] |= R_V7M_CCR_UNALIGN_TRP_MASK;
242
}
243
244
+ if (arm_feature(env, ARM_FEATURE_VFP)) {
245
+ env->v7m.fpccr[M_REG_NS] = R_V7M_FPCCR_ASPEN_MASK;
246
+ env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK |
247
+ R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK;
248
+ }
249
/* Unlike A/R profile, M profile defines the reset LR value */
250
env->regs[14] = 0xffffffff;
251
113
diff --git a/target/arm/machine.c b/target/arm/machine.c
252
diff --git a/target/arm/machine.c b/target/arm/machine.c
114
index XXXXXXX..XXXXXXX 100644
253
index XXXXXXX..XXXXXXX 100644
115
--- a/target/arm/machine.c
254
--- a/target/arm/machine.c
116
+++ b/target/arm/machine.c
255
+++ b/target/arm/machine.c
117
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_faultmask_primask = {
256
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_v8m = {
118
}
257
}
119
};
258
};
120
259
121
+/* CSSELR is in a subsection because we didn't implement it previously.
260
+static const VMStateDescription vmstate_m_fp = {
122
+ * Migration from an old implementation will leave it at zero, which
261
+ .name = "cpu/m/fp",
123
+ * is OK since the only CPUs in the old implementation make the
124
+ * register RAZ/WI.
125
+ * Since there was no version of QEMU which implemented the CSSELR for
126
+ * just non-secure, we transfer both banks here rather than putting
127
+ * the secure banked version in the m-security subsection.
128
+ */
129
+static bool csselr_vmstate_validate(void *opaque, int version_id)
130
+{
131
+ ARMCPU *cpu = opaque;
132
+
133
+ return cpu->env.v7m.csselr[M_REG_NS] <= R_V7M_CSSELR_INDEX_MASK
134
+ && cpu->env.v7m.csselr[M_REG_S] <= R_V7M_CSSELR_INDEX_MASK;
135
+}
136
+
137
+static bool m_csselr_needed(void *opaque)
138
+{
139
+ ARMCPU *cpu = opaque;
140
+
141
+ return !arm_v7m_csselr_razwi(cpu);
142
+}
143
+
144
+static const VMStateDescription vmstate_m_csselr = {
145
+ .name = "cpu/m/csselr",
146
+ .version_id = 1,
262
+ .version_id = 1,
147
+ .minimum_version_id = 1,
263
+ .minimum_version_id = 1,
148
+ .needed = m_csselr_needed,
264
+ .needed = vfp_needed,
149
+ .fields = (VMStateField[]) {
265
+ .fields = (VMStateField[]) {
150
+ VMSTATE_UINT32_ARRAY(env.v7m.csselr, ARMCPU, M_REG_NUM_BANKS),
266
+ VMSTATE_UINT32_ARRAY(env.v7m.fpcar, ARMCPU, M_REG_NUM_BANKS),
151
+ VMSTATE_VALIDATE("CSSELR is valid", csselr_vmstate_validate),
267
+ VMSTATE_UINT32_ARRAY(env.v7m.fpccr, ARMCPU, M_REG_NUM_BANKS),
268
+ VMSTATE_UINT32_ARRAY(env.v7m.fpdscr, ARMCPU, M_REG_NUM_BANKS),
269
+ VMSTATE_UINT32_ARRAY(env.v7m.cpacr, ARMCPU, M_REG_NUM_BANKS),
270
+ VMSTATE_UINT32(env.v7m.nsacr, ARMCPU),
152
+ VMSTATE_END_OF_LIST()
271
+ VMSTATE_END_OF_LIST()
153
+ }
272
+ }
154
+};
273
+};
155
+
274
+
156
static const VMStateDescription vmstate_m = {
275
static const VMStateDescription vmstate_m = {
157
.name = "cpu/m",
276
.name = "cpu/m",
158
.version_id = 4,
277
.version_id = 4,
159
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
278
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
160
},
279
&vmstate_m_scr,
161
.subsections = (const VMStateDescription*[]) {
280
&vmstate_m_other_sp,
162
&vmstate_m_faultmask_primask,
281
&vmstate_m_v8m,
163
+ &vmstate_m_csselr,
282
+ &vmstate_m_fp,
164
NULL
283
NULL
165
}
284
}
166
};
285
};
167
--
286
--
168
2.16.1
287
2.20.1
169
288
170
289
diff view generated by jsdifflib
New patch
1
The only "system register" that M-profile floating point exposes
2
via the VMRS/VMRS instructions is FPSCR, and it does not have
3
the odd special case for rd==15. Add a check to ensure we only
4
expose FPSCR.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-5-peter.maydell@linaro.org
9
---
10
target/arm/translate.c | 19 +++++++++++++++++--
11
1 file changed, 17 insertions(+), 2 deletions(-)
12
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
16
+++ b/target/arm/translate.c
17
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
18
}
19
}
20
} else { /* !dp */
21
+ bool is_sysreg;
22
+
23
if ((insn & 0x6f) != 0x00)
24
return 1;
25
rn = VFP_SREG_N(insn);
26
+
27
+ is_sysreg = extract32(insn, 21, 1);
28
+
29
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
30
+ /*
31
+ * The only M-profile VFP vmrs/vmsr sysreg is FPSCR.
32
+ * Writes to R15 are UNPREDICTABLE; we choose to undef.
33
+ */
34
+ if (is_sysreg && (rd == 15 || (rn >> 1) != ARM_VFP_FPSCR)) {
35
+ return 1;
36
+ }
37
+ }
38
+
39
if (insn & ARM_CP_RW_BIT) {
40
/* vfp->arm */
41
- if (insn & (1 << 21)) {
42
+ if (is_sysreg) {
43
/* system register */
44
rn >>= 1;
45
46
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
47
}
48
} else {
49
/* arm->vfp */
50
- if (insn & (1 << 21)) {
51
+ if (is_sysreg) {
52
rn >>= 1;
53
/* system register */
54
switch (rn) {
55
--
56
2.20.1
57
58
diff view generated by jsdifflib
New patch
1
Like AArch64, M-profile floating point has no FPEXC enable
2
bit to gate floating point; so always set the VFPEN TB flag.
1
3
4
M-profile also has CPACR and NSACR similar to A-profile;
5
they behave slightly differently:
6
* the CPACR is banked between Secure and Non-Secure
7
* if the NSACR forces a trap then this is taken to
8
the Secure state, not the Non-Secure state
9
10
Honour the CPACR and NSACR settings. The NSACR handling
11
requires us to borrow the exception.target_el field
12
(usually meaningless for M profile) to distinguish the
13
NOCP UsageFault taken to Secure state from the more
14
usual fault taken to the current security state.
15
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Message-id: 20190416125744.27770-6-peter.maydell@linaro.org
19
---
20
target/arm/helper.c | 55 +++++++++++++++++++++++++++++++++++++++---
21
target/arm/translate.c | 10 ++++++--
22
2 files changed, 60 insertions(+), 5 deletions(-)
23
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.c
27
+++ b/target/arm/helper.c
28
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
29
return target_el;
30
}
31
32
+/*
33
+ * Return true if the v7M CPACR permits access to the FPU for the specified
34
+ * security state and privilege level.
35
+ */
36
+static bool v7m_cpacr_pass(CPUARMState *env, bool is_secure, bool is_priv)
37
+{
38
+ switch (extract32(env->v7m.cpacr[is_secure], 20, 2)) {
39
+ case 0:
40
+ case 2: /* UNPREDICTABLE: we treat like 0 */
41
+ return false;
42
+ case 1:
43
+ return is_priv;
44
+ case 3:
45
+ return true;
46
+ default:
47
+ g_assert_not_reached();
48
+ }
49
+}
50
+
51
static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
52
ARMMMUIdx mmu_idx, bool ignfault)
53
{
54
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
55
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNDEFINSTR_MASK;
56
break;
57
case EXCP_NOCP:
58
- armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
59
- env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_NOCP_MASK;
60
+ {
61
+ /*
62
+ * NOCP might be directed to something other than the current
63
+ * security state if this fault is because of NSACR; we indicate
64
+ * the target security state using exception.target_el.
65
+ */
66
+ int target_secstate;
67
+
68
+ if (env->exception.target_el == 3) {
69
+ target_secstate = M_REG_S;
70
+ } else {
71
+ target_secstate = env->v7m.secure;
72
+ }
73
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, target_secstate);
74
+ env->v7m.cfsr[target_secstate] |= R_V7M_CFSR_NOCP_MASK;
75
break;
76
+ }
77
case EXCP_INVSTATE:
78
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
79
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVSTATE_MASK;
80
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
81
return 0;
82
}
83
84
+ if (arm_feature(env, ARM_FEATURE_M)) {
85
+ /* CPACR can cause a NOCP UsageFault taken to current security state */
86
+ if (!v7m_cpacr_pass(env, env->v7m.secure, cur_el != 0)) {
87
+ return 1;
88
+ }
89
+
90
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) && !env->v7m.secure) {
91
+ if (!extract32(env->v7m.nsacr, 10, 1)) {
92
+ /* FP insns cause a NOCP UsageFault taken to Secure */
93
+ return 3;
94
+ }
95
+ }
96
+
97
+ return 0;
98
+ }
99
+
100
/* The CPACR controls traps to EL1, or PL1 if we're 32 bit:
101
* 0, 2 : trap EL0 and EL1/PL1 accesses
102
* 1 : trap only EL0 accesses
103
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
104
flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, arm_sctlr_b(env));
105
flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
106
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
107
- || arm_el_is_aa64(env, 1)) {
108
+ || arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
109
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
110
}
111
flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
112
diff --git a/target/arm/translate.c b/target/arm/translate.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/translate.c
115
+++ b/target/arm/translate.c
116
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
117
* for attempts to execute invalid vfp/neon encodings with FP disabled.
118
*/
119
if (s->fp_excp_el) {
120
- gen_exception_insn(s, 4, EXCP_UDEF,
121
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
122
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
123
+ gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
124
+ s->fp_excp_el);
125
+ } else {
126
+ gen_exception_insn(s, 4, EXCP_UDEF,
127
+ syn_fp_access_trap(1, 0xe, false),
128
+ s->fp_excp_el);
129
+ }
130
return 0;
131
}
132
133
--
134
2.20.1
135
136
diff view generated by jsdifflib
New patch
1
Correct the decode of the M-profile "coprocessor and
2
floating-point instructions" space:
3
* op0 == 0b11 is always unallocated
4
* if the CPU has an FPU then all insns with op1 == 0b101
5
are floating point and go to disas_vfp_insn()
1
6
7
For the moment we leave VLLDM and VLSTM as NOPs; in
8
a later commit we will fill in the proper implementation
9
for the case where an FPU is present.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20190416125744.27770-7-peter.maydell@linaro.org
14
---
15
target/arm/translate.c | 26 ++++++++++++++++++++++----
16
1 file changed, 22 insertions(+), 4 deletions(-)
17
18
diff --git a/target/arm/translate.c b/target/arm/translate.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate.c
21
+++ b/target/arm/translate.c
22
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
23
case 6: case 7: case 14: case 15:
24
/* Coprocessor. */
25
if (arm_dc_feature(s, ARM_FEATURE_M)) {
26
- /* We don't currently implement M profile FP support,
27
- * so this entire space should give a NOCP fault, with
28
- * the exception of the v8M VLLDM and VLSTM insns, which
29
- * must be NOPs in Secure state and UNDEF in Nonsecure state.
30
+ /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
31
+ if (extract32(insn, 24, 2) == 3) {
32
+ goto illegal_op; /* op0 = 0b11 : unallocated */
33
+ }
34
+
35
+ /*
36
+ * Decode VLLDM and VLSTM first: these are nonstandard because:
37
+ * * if there is no FPU then these insns must NOP in
38
+ * Secure state and UNDEF in Nonsecure state
39
+ * * if there is an FPU then these insns do not have
40
+ * the usual behaviour that disas_vfp_insn() provides of
41
+ * being controlled by CPACR/NSACR enable bits or the
42
+ * lazy-stacking logic.
43
*/
44
if (arm_dc_feature(s, ARM_FEATURE_V8) &&
45
(insn & 0xffa00f00) == 0xec200a00) {
46
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
47
/* Just NOP since FP support is not implemented */
48
break;
49
}
50
+ if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
51
+ ((insn >> 8) & 0xe) == 10) {
52
+ /* FP, and the CPU supports it */
53
+ if (disas_vfp_insn(s, insn)) {
54
+ goto illegal_op;
55
+ }
56
+ break;
57
+ }
58
+
59
/* All other insns: NOCP */
60
gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
61
default_exception_el(s));
62
--
63
2.20.1
64
65
diff view generated by jsdifflib
New patch
1
If the floating point extension is present, then the SG instruction
2
must clear the CONTROL_S.SFPA bit. Implement this.
1
3
4
(On a no-FPU system the bit will always be zero, so we don't need
5
to make the clearing of the bit conditional on ARM_FEATURE_VFP.)
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-8-peter.maydell@linaro.org
10
---
11
target/arm/helper.c | 1 +
12
1 file changed, 1 insertion(+)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
19
qemu_log_mask(CPU_LOG_INT, "...really an SG instruction at 0x%08" PRIx32
20
", executing it\n", env->regs[15]);
21
env->regs[14] &= ~1;
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
23
switch_v7m_security_state(env, true);
24
xpsr_write(env, 0, XPSR_IT);
25
env->regs[15] += 4;
26
--
27
2.20.1
28
29
diff view generated by jsdifflib
1
In commit 50f11062d4c896 we added support for MSR/MRS access
1
The M-profile CONTROL register has two bits -- SFPA and FPCA --
2
to the NS banked special registers, but we forgot to implement
2
which relate to floating-point support, and should be RES0 otherwise.
3
the support for writing to CONTROL_NS. Correct the omission.
3
Handle them correctly in the MSR/MRS register access code.
4
Neither is banked between security states, so they are stored
5
in v7m.control[M_REG_S] regardless of current security state.
4
6
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180209165810.6668-8-peter.maydell@linaro.org
9
Message-id: 20190416125744.27770-9-peter.maydell@linaro.org
8
---
10
---
9
target/arm/helper.c | 10 ++++++++++
11
target/arm/helper.c | 57 ++++++++++++++++++++++++++++++++++++++-------
10
1 file changed, 10 insertions(+)
12
1 file changed, 49 insertions(+), 8 deletions(-)
11
13
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
16
--- a/target/arm/helper.c
15
+++ b/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
19
return xpsr_read(env) & mask;
20
break;
21
case 20: /* CONTROL */
22
- return env->v7m.control[env->v7m.secure];
23
+ {
24
+ uint32_t value = env->v7m.control[env->v7m.secure];
25
+ if (!env->v7m.secure) {
26
+ /* SFPA is RAZ/WI from NS; FPCA is stored in the M_REG_S bank */
27
+ value |= env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK;
28
+ }
29
+ return value;
30
+ }
31
case 0x94: /* CONTROL_NS */
32
/* We have to handle this here because unprivileged Secure code
33
* can read the NS CONTROL register.
34
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
35
if (!env->v7m.secure) {
36
return 0;
37
}
38
- return env->v7m.control[M_REG_NS];
39
+ return env->v7m.control[M_REG_NS] |
40
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK);
41
}
42
43
if (el == 0) {
16
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
44
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
45
*/
46
uint32_t mask = extract32(maskreg, 8, 4);
47
uint32_t reg = extract32(maskreg, 0, 8);
48
+ int cur_el = arm_current_el(env);
49
50
- if (arm_current_el(env) == 0 && reg > 7) {
51
- /* only xPSR sub-fields may be written by unprivileged */
52
+ if (cur_el == 0 && reg > 7 && reg != 20) {
53
+ /*
54
+ * only xPSR sub-fields and CONTROL.SFPA may be written by
55
+ * unprivileged code
56
+ */
57
return;
58
}
59
60
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
61
env->v7m.control[M_REG_NS] &= ~R_V7M_CONTROL_NPRIV_MASK;
62
env->v7m.control[M_REG_NS] |= val & R_V7M_CONTROL_NPRIV_MASK;
17
}
63
}
18
env->v7m.faultmask[M_REG_NS] = val & 1;
64
+ /*
65
+ * SFPA is RAZ/WI from NS. FPCA is RO if NSACR.CP10 == 0,
66
+ * RES0 if the FPU is not present, and is stored in the S bank
67
+ */
68
+ if (arm_feature(env, ARM_FEATURE_VFP) &&
69
+ extract32(env->v7m.nsacr, 10, 1)) {
70
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
71
+ env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK;
72
+ }
19
return;
73
return;
20
+ case 0x94: /* CONTROL_NS */
21
+ if (!env->v7m.secure) {
22
+ return;
23
+ }
24
+ write_v7m_control_spsel_for_secstate(env,
25
+ val & R_V7M_CONTROL_SPSEL_MASK,
26
+ M_REG_NS);
27
+ env->v7m.control[M_REG_NS] &= ~R_V7M_CONTROL_NPRIV_MASK;
28
+ env->v7m.control[M_REG_NS] |= val & R_V7M_CONTROL_NPRIV_MASK;
29
+ return;
30
case 0x98: /* SP_NS */
74
case 0x98: /* SP_NS */
31
{
75
{
32
/* This gives the non-secure SP selected based on whether we're
76
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
77
env->v7m.faultmask[env->v7m.secure] = val & 1;
78
break;
79
case 20: /* CONTROL */
80
- /* Writing to the SPSEL bit only has an effect if we are in
81
+ /*
82
+ * Writing to the SPSEL bit only has an effect if we are in
83
* thread mode; other bits can be updated by any privileged code.
84
* write_v7m_control_spsel() deals with updating the SPSEL bit in
85
* env->v7m.control, so we only need update the others.
86
* For v7M, we must just ignore explicit writes to SPSEL in handler
87
* mode; for v8M the write is permitted but will have no effect.
88
+ * All these bits are writes-ignored from non-privileged code,
89
+ * except for SFPA.
90
*/
91
- if (arm_feature(env, ARM_FEATURE_V8) ||
92
- !arm_v7m_is_handler_mode(env)) {
93
+ if (cur_el > 0 && (arm_feature(env, ARM_FEATURE_V8) ||
94
+ !arm_v7m_is_handler_mode(env))) {
95
write_v7m_control_spsel(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 0);
96
}
97
- if (arm_feature(env, ARM_FEATURE_M_MAIN)) {
98
+ if (cur_el > 0 && arm_feature(env, ARM_FEATURE_M_MAIN)) {
99
env->v7m.control[env->v7m.secure] &= ~R_V7M_CONTROL_NPRIV_MASK;
100
env->v7m.control[env->v7m.secure] |= val & R_V7M_CONTROL_NPRIV_MASK;
101
}
102
+ if (arm_feature(env, ARM_FEATURE_VFP)) {
103
+ /*
104
+ * SFPA is RAZ/WI from NS or if no FPU.
105
+ * FPCA is RO if NSACR.CP10 == 0, RES0 if the FPU is not present.
106
+ * Both are stored in the S bank.
107
+ */
108
+ if (env->v7m.secure) {
109
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
110
+ env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_SFPA_MASK;
111
+ }
112
+ if (cur_el > 0 &&
113
+ (env->v7m.secure || !arm_feature(env, ARM_FEATURE_M_SECURITY) ||
114
+ extract32(env->v7m.nsacr, 10, 1))) {
115
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
116
+ env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK;
117
+ }
118
+ }
119
break;
120
default:
121
bad_reg:
33
--
122
--
34
2.16.1
123
2.20.1
35
124
36
125
diff view generated by jsdifflib
New patch
1
Currently the code in v7m_push_stack() which detects a violation
2
of the v8M stack limit simply returns early if it does so. This
3
is OK for the current integer-only code, but won't work for the
4
floating point handling we're about to add. We need to continue
5
executing the rest of the function so that we check for other
6
exceptions like not having permission to use the FPU and so
7
that we correctly set the FPCCR state if we are doing lazy
8
stacking. Refactor to avoid the early return.
1
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20190416125744.27770-10-peter.maydell@linaro.org
13
---
14
target/arm/helper.c | 23 ++++++++++++++++++-----
15
1 file changed, 18 insertions(+), 5 deletions(-)
16
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
20
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
22
* should ignore further stack faults trying to process
23
* that derived exception.)
24
*/
25
- bool stacked_ok;
26
+ bool stacked_ok = true, limitviol = false;
27
CPUARMState *env = &cpu->env;
28
uint32_t xpsr = xpsr_read(env);
29
uint32_t frameptr = env->regs[13];
30
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
31
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
32
env->v7m.secure);
33
env->regs[13] = limit;
34
- return true;
35
+ /*
36
+ * We won't try to perform any further memory accesses but
37
+ * we must continue through the following code to check for
38
+ * permission faults during FPU state preservation, and we
39
+ * must update FPCCR if lazy stacking is enabled.
40
+ */
41
+ limitviol = true;
42
+ stacked_ok = false;
43
}
44
}
45
46
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
47
* (which may be taken in preference to the one we started with
48
* if it has higher priority).
49
*/
50
- stacked_ok =
51
+ stacked_ok = stacked_ok &&
52
v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, false) &&
53
v7m_stack_write(cpu, frameptr + 4, env->regs[1], mmu_idx, false) &&
54
v7m_stack_write(cpu, frameptr + 8, env->regs[2], mmu_idx, false) &&
55
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
56
v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
57
v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
58
59
- /* Update SP regardless of whether any of the stack accesses failed. */
60
- env->regs[13] = frameptr;
61
+ /*
62
+ * If we broke a stack limit then SP was already updated earlier;
63
+ * otherwise we update SP regardless of whether any of the stack
64
+ * accesses failed or we took some other kind of fault.
65
+ */
66
+ if (!limitviol) {
67
+ env->regs[13] = frameptr;
68
+ }
69
70
return !stacked_ok;
71
}
72
--
73
2.20.1
74
75
diff view generated by jsdifflib
New patch
1
Handle floating point registers in exception entry.
2
This corresponds to the FP-specific parts of the pseudocode
3
functions ActivateException() and PushStack().
1
4
5
We defer the code corresponding to UpdateFPCCR() to a later patch.
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-11-peter.maydell@linaro.org
10
---
11
target/arm/helper.c | 98 +++++++++++++++++++++++++++++++++++++++++++--
12
1 file changed, 95 insertions(+), 3 deletions(-)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
19
switch_v7m_security_state(env, targets_secure);
20
write_v7m_control_spsel(env, 0);
21
arm_clear_exclusive(env);
22
+ /* Clear SFPA and FPCA (has no effect if no FPU) */
23
+ env->v7m.control[M_REG_S] &=
24
+ ~(R_V7M_CONTROL_FPCA_MASK | R_V7M_CONTROL_SFPA_MASK);
25
/* Clear IT bits */
26
env->condexec_bits = 0;
27
env->regs[14] = lr;
28
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
29
uint32_t xpsr = xpsr_read(env);
30
uint32_t frameptr = env->regs[13];
31
ARMMMUIdx mmu_idx = arm_mmu_idx(env);
32
+ uint32_t framesize;
33
+ bool nsacr_cp10 = extract32(env->v7m.nsacr, 10, 1);
34
+
35
+ if ((env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) &&
36
+ (env->v7m.secure || nsacr_cp10)) {
37
+ if (env->v7m.secure &&
38
+ env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK) {
39
+ framesize = 0xa8;
40
+ } else {
41
+ framesize = 0x68;
42
+ }
43
+ } else {
44
+ framesize = 0x20;
45
+ }
46
47
/* Align stack pointer if the guest wants that */
48
if ((frameptr & 4) &&
49
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
50
xpsr |= XPSR_SPREALIGN;
51
}
52
53
- frameptr -= 0x20;
54
+ xpsr &= ~XPSR_SFPA;
55
+ if (env->v7m.secure &&
56
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
57
+ xpsr |= XPSR_SFPA;
58
+ }
59
+
60
+ frameptr -= framesize;
61
62
if (arm_feature(env, ARM_FEATURE_V8)) {
63
uint32_t limit = v7m_sp_limit(env);
64
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
65
v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
66
v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
67
68
+ if (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) {
69
+ /* FPU is active, try to save its registers */
70
+ bool fpccr_s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
71
+ bool lspact = env->v7m.fpccr[fpccr_s] & R_V7M_FPCCR_LSPACT_MASK;
72
+
73
+ if (lspact && arm_feature(env, ARM_FEATURE_M_SECURITY)) {
74
+ qemu_log_mask(CPU_LOG_INT,
75
+ "...SecureFault because LSPACT and FPCA both set\n");
76
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
77
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
78
+ } else if (!env->v7m.secure && !nsacr_cp10) {
79
+ qemu_log_mask(CPU_LOG_INT,
80
+ "...Secure UsageFault with CFSR.NOCP because "
81
+ "NSACR.CP10 prevents stacking FP regs\n");
82
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
83
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
84
+ } else {
85
+ if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) {
86
+ /* Lazy stacking disabled, save registers now */
87
+ int i;
88
+ bool cpacr_pass = v7m_cpacr_pass(env, env->v7m.secure,
89
+ arm_current_el(env) != 0);
90
+
91
+ if (stacked_ok && !cpacr_pass) {
92
+ /*
93
+ * Take UsageFault if CPACR forbids access. The pseudocode
94
+ * here does a full CheckCPEnabled() but we know the NSACR
95
+ * check can never fail as we have already handled that.
96
+ */
97
+ qemu_log_mask(CPU_LOG_INT,
98
+ "...UsageFault with CFSR.NOCP because "
99
+ "CPACR.CP10 prevents stacking FP regs\n");
100
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
101
+ env->v7m.secure);
102
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_NOCP_MASK;
103
+ stacked_ok = false;
104
+ }
105
+
106
+ for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
107
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
108
+ uint32_t faddr = frameptr + 0x20 + 4 * i;
109
+ uint32_t slo = extract64(dn, 0, 32);
110
+ uint32_t shi = extract64(dn, 32, 32);
111
+
112
+ if (i >= 16) {
113
+ faddr += 8; /* skip the slot for the FPSCR */
114
+ }
115
+ stacked_ok = stacked_ok &&
116
+ v7m_stack_write(cpu, faddr, slo, mmu_idx, false) &&
117
+ v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, false);
118
+ }
119
+ stacked_ok = stacked_ok &&
120
+ v7m_stack_write(cpu, frameptr + 0x60,
121
+ vfp_get_fpscr(env), mmu_idx, false);
122
+ if (cpacr_pass) {
123
+ for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
124
+ *aa32_vfp_dreg(env, i / 2) = 0;
125
+ }
126
+ vfp_set_fpscr(env, 0);
127
+ }
128
+ } else {
129
+ /* Lazy stacking enabled, save necessary info to stack later */
130
+ /* TODO : equivalent of UpdateFPCCR() pseudocode */
131
+ }
132
+ }
133
+ }
134
+
135
/*
136
* If we broke a stack limit then SP was already updated earlier;
137
* otherwise we update SP regardless of whether any of the stack
138
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
139
140
if (arm_feature(env, ARM_FEATURE_V8)) {
141
lr = R_V7M_EXCRET_RES1_MASK |
142
- R_V7M_EXCRET_DCRS_MASK |
143
- R_V7M_EXCRET_FTYPE_MASK;
144
+ R_V7M_EXCRET_DCRS_MASK;
145
/* The S bit indicates whether we should return to Secure
146
* or NonSecure (ie our current state).
147
* The ES bit indicates whether we're taking this exception
148
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
149
if (env->v7m.secure) {
150
lr |= R_V7M_EXCRET_S_MASK;
151
}
152
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
153
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
154
+ }
155
} else {
156
lr = R_V7M_EXCRET_RES1_MASK |
157
R_V7M_EXCRET_S_MASK |
158
--
159
2.20.1
160
161
diff view generated by jsdifflib
1
In many of the NVIC registers relating to interrupts, we
1
Implement the code which updates the FPCCR register on an
2
have to convert from a byte offset within a register set
2
exception entry where we are going to use lazy FP stacking.
3
into the number of the first interrupt which is affected.
3
We have to defer to the NVIC to determine whether the
4
We were getting this wrong for:
4
various exceptions are currently ready or not.
5
* reads of NVIC_ISPR<n>, NVIC_ISER<n>, NVIC_ICPR<n>, NVIC_ICER<n>,
6
NVIC_IABR<n> -- in all these cases we were missing the "* 8"
7
needed to convert from the byte offset to the interrupt number
8
(since all these registers use one bit per interrupt)
9
* writes of NVIC_IPR<n> had the opposite problem of a spurious
10
"* 8" (since these registers use one byte per interrupt)
11
5
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20190416125744.27770-12-peter.maydell@linaro.org
14
Message-id: 20180209165810.6668-9-peter.maydell@linaro.org
15
---
8
---
16
hw/intc/armv7m_nvic.c | 8 ++++----
9
target/arm/cpu.h | 14 +++++++++
17
1 file changed, 4 insertions(+), 4 deletions(-)
10
hw/intc/armv7m_nvic.c | 34 ++++++++++++++++++++++
11
target/arm/helper.c | 67 ++++++++++++++++++++++++++++++++++++++++++-
12
3 files changed, 114 insertions(+), 1 deletion(-)
18
13
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_acknowledge_irq(void *opaque);
19
* (Ignoring -1, this is the same as the RETTOBASE value before completion.)
20
*/
21
int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure);
22
+/**
23
+ * armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
24
+ * @opaque: the NVIC
25
+ * @irq: the exception number to mark pending
26
+ * @secure: false for non-banked exceptions or for the nonsecure
27
+ * version of a banked exception, true for the secure version of a banked
28
+ * exception.
29
+ *
30
+ * Return whether an exception is "ready", i.e. whether the exception is
31
+ * enabled and is configured at a priority which would allow it to
32
+ * interrupt the current execution priority. This controls whether the
33
+ * RDY bit for it in the FPCCR is set.
34
+ */
35
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure);
36
/**
37
* armv7m_nvic_raw_execution_priority: return the raw execution priority
38
* @opaque: the NVIC
19
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
39
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
20
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/intc/armv7m_nvic.c
41
--- a/hw/intc/armv7m_nvic.c
22
+++ b/hw/intc/armv7m_nvic.c
42
+++ b/hw/intc/armv7m_nvic.c
23
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
43
@@ -XXX,XX +XXX,XX @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
24
/* fall through */
44
return ret;
25
case 0x180 ... 0x1bf: /* NVIC Clear enable */
45
}
26
val = 0;
46
27
- startvec = offset - 0x180 + NVIC_FIRST_IRQ; /* vector # */
47
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
28
+ startvec = 8 * (offset - 0x180) + NVIC_FIRST_IRQ; /* vector # */
48
+{
29
49
+ /*
30
for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
50
+ * Return whether an exception is "ready", i.e. it is enabled and is
31
if (s->vectors[startvec + i].enabled &&
51
+ * configured at a priority which would allow it to interrupt the
32
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
52
+ * current execution priority.
33
/* fall through */
53
+ *
34
case 0x280 ... 0x2bf: /* NVIC Clear pend */
54
+ * irq and secure have the same semantics as for armv7m_nvic_set_pending():
35
val = 0;
55
+ * for non-banked exceptions secure is always false; for banked exceptions
36
- startvec = offset - 0x280 + NVIC_FIRST_IRQ; /* vector # */
56
+ * it indicates which of the exceptions is required.
37
+ startvec = 8 * (offset - 0x280) + NVIC_FIRST_IRQ; /* vector # */
57
+ */
38
for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
58
+ NVICState *s = (NVICState *)opaque;
39
if (s->vectors[startvec + i].pending &&
59
+ bool banked = exc_is_banked(irq);
40
(attrs.secure || s->itns[startvec + i])) {
60
+ VecInfo *vec;
41
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
61
+ int running = nvic_exec_prio(s);
42
break;
62
+
43
case 0x300 ... 0x33f: /* NVIC Active */
63
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
44
val = 0;
64
+ assert(!secure || banked);
45
- startvec = offset - 0x300 + NVIC_FIRST_IRQ; /* vector # */
65
+
46
+ startvec = 8 * (offset - 0x300) + NVIC_FIRST_IRQ; /* vector # */
66
+ /*
47
67
+ * HardFault is an odd special case: we always check against -1,
48
for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
68
+ * even if we're secure and HardFault has priority -3; we never
49
if (s->vectors[startvec + i].active &&
69
+ * need to check for enabled state.
50
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
70
+ */
51
case 0x300 ... 0x33f: /* NVIC Active */
71
+ if (irq == ARMV7M_EXCP_HARD) {
52
return MEMTX_OK; /* R/O */
72
+ return running > -1;
53
case 0x400 ... 0x5ef: /* NVIC Priority */
73
+ }
54
- startvec = 8 * (offset - 0x400) + NVIC_FIRST_IRQ; /* vector # */
74
+
55
+ startvec = (offset - 0x400) + NVIC_FIRST_IRQ; /* vector # */
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
56
76
+
57
for (i = 0; i < size && startvec + i < s->num_irq; i++) {
77
+ return vec->enabled &&
58
if (attrs.secure || s->itns[startvec + i]) {
78
+ exc_group_prio(s, vec->prio, secure) < running;
79
+}
80
+
81
/* callback when external interrupt line is changed */
82
static void set_irq_level(void *opaque, int n, int level)
83
{
84
diff --git a/target/arm/helper.c b/target/arm/helper.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/helper.c
87
+++ b/target/arm/helper.c
88
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
89
env->thumb = addr & 1;
90
}
91
92
+static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
93
+ bool apply_splim)
94
+{
95
+ /*
96
+ * Like the pseudocode UpdateFPCCR: save state in FPCAR and FPCCR
97
+ * that we will need later in order to do lazy FP reg stacking.
98
+ */
99
+ bool is_secure = env->v7m.secure;
100
+ void *nvic = env->nvic;
101
+ /*
102
+ * Some bits are unbanked and live always in fpccr[M_REG_S]; some bits
103
+ * are banked and we want to update the bit in the bank for the
104
+ * current security state; and in one case we want to specifically
105
+ * update the NS banked version of a bit even if we are secure.
106
+ */
107
+ uint32_t *fpccr_s = &env->v7m.fpccr[M_REG_S];
108
+ uint32_t *fpccr_ns = &env->v7m.fpccr[M_REG_NS];
109
+ uint32_t *fpccr = &env->v7m.fpccr[is_secure];
110
+ bool hfrdy, bfrdy, mmrdy, ns_ufrdy, s_ufrdy, sfrdy, monrdy;
111
+
112
+ env->v7m.fpcar[is_secure] = frameptr & ~0x7;
113
+
114
+ if (apply_splim && arm_feature(env, ARM_FEATURE_V8)) {
115
+ bool splimviol;
116
+ uint32_t splim = v7m_sp_limit(env);
117
+ bool ign = armv7m_nvic_neg_prio_requested(nvic, is_secure) &&
118
+ (env->v7m.ccr[is_secure] & R_V7M_CCR_STKOFHFNMIGN_MASK);
119
+
120
+ splimviol = !ign && frameptr < splim;
121
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, SPLIMVIOL, splimviol);
122
+ }
123
+
124
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, LSPACT, 1);
125
+
126
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, S, is_secure);
127
+
128
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, USER, arm_current_el(env) == 0);
129
+
130
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, THREAD,
131
+ !arm_v7m_is_handler_mode(env));
132
+
133
+ hfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_HARD, false);
134
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, HFRDY, hfrdy);
135
+
136
+ bfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_BUS, false);
137
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, BFRDY, bfrdy);
138
+
139
+ mmrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_MEM, is_secure);
140
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, MMRDY, mmrdy);
141
+
142
+ ns_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, false);
143
+ *fpccr_ns = FIELD_DP32(*fpccr_ns, V7M_FPCCR, UFRDY, ns_ufrdy);
144
+
145
+ monrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_DEBUG, false);
146
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, MONRDY, monrdy);
147
+
148
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
149
+ s_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, true);
150
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, UFRDY, s_ufrdy);
151
+
152
+ sfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_SECURE, false);
153
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, SFRDY, sfrdy);
154
+ }
155
+}
156
+
157
static bool v7m_push_stack(ARMCPU *cpu)
158
{
159
/* Do the "set up stack frame" part of exception entry,
160
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
161
}
162
} else {
163
/* Lazy stacking enabled, save necessary info to stack later */
164
- /* TODO : equivalent of UpdateFPCCR() pseudocode */
165
+ v7m_update_fpccr(env, frameptr + 0x20, true);
166
}
167
}
168
}
59
--
169
--
60
2.16.1
170
2.20.1
61
171
62
172
diff view generated by jsdifflib
1
In commit commit 3b2e934463121 we added support for the AIRCR
1
For v8M floating point support, transitions from Secure
2
register holding state, but forgot to add it to the vmstate
2
to Non-secure state via BLNS and BLXNS must clear the
3
structs. Since it only holds r/w state if the security extension
3
CONTROL.SFPA bit. (This corresponds to the pseudocode
4
is implemented, we can just add it to vmstate_m_security.
4
BranchToNS() function.)
5
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180209165810.6668-10-peter.maydell@linaro.org
8
Message-id: 20190416125744.27770-13-peter.maydell@linaro.org
9
---
9
---
10
target/arm/machine.c | 4 ++++
10
target/arm/helper.c | 4 ++++
11
1 file changed, 4 insertions(+)
11
1 file changed, 4 insertions(+)
12
12
13
diff --git a/target/arm/machine.c b/target/arm/machine.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/machine.c
15
--- a/target/arm/helper.c
16
+++ b/target/arm/machine.c
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_security = {
17
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest)
18
VMSTATE_VALIDATE("SAU_RNR is valid", sau_rnr_vmstate_validate),
18
/* translate.c should have made BXNS UNDEF unless we're secure */
19
VMSTATE_UINT32(env.sau.ctrl, ARMCPU),
19
assert(env->v7m.secure);
20
VMSTATE_UINT32(env.v7m.scr[M_REG_S], ARMCPU),
20
21
+ /* AIRCR is not secure-only, but our implementation is R/O if the
21
+ if (!(dest & 1)) {
22
+ * security extension is unimplemented, so we migrate it here.
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
23
+ */
23
+ }
24
+ VMSTATE_UINT32(env.v7m.aircr, ARMCPU),
24
switch_v7m_security_state(env, dest & 1);
25
VMSTATE_END_OF_LIST()
25
env->thumb = 1;
26
env->regs[15] = dest & ~1;
27
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
28
*/
29
write_v7m_exception(env, 1);
26
}
30
}
27
};
31
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
32
switch_v7m_security_state(env, 0);
33
env->thumb = 1;
34
env->regs[15] = dest;
28
--
35
--
29
2.16.1
36
2.20.1
30
37
31
38
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The TailChain() pseudocode specifies that a tail chaining
2
exception should sanitize the excReturn all-ones bits and
3
(if there is no FPU) the excReturn FType bits; we weren't
4
doing this.
2
5
3
Nothing in either register affects the TB.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20180211205848.4568-4-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-14-peter.maydell@linaro.org
9
---
9
---
10
target/arm/helper.c | 4 ++--
10
target/arm/helper.c | 8 ++++++++
11
1 file changed, 2 insertions(+), 2 deletions(-)
11
1 file changed, 8 insertions(+)
12
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
15
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
17
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
18
.writefn = aa64_daif_write, .resetfn = arm_cp_reset_ignore },
18
qemu_log_mask(CPU_LOG_INT, "...taking pending %s exception %d\n",
19
{ .name = "FPCR", .state = ARM_CP_STATE_AA64,
19
targets_secure ? "secure" : "nonsecure", exc);
20
.opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 4,
20
21
- .access = PL0_RW, .type = ARM_CP_FPU,
21
+ if (dotailchain) {
22
+ .access = PL0_RW, .type = ARM_CP_FPU | ARM_CP_SUPPRESS_TB_END,
22
+ /* Sanitize LR FType and PREFIX bits */
23
.readfn = aa64_fpcr_read, .writefn = aa64_fpcr_write },
23
+ if (!arm_feature(env, ARM_FEATURE_VFP)) {
24
{ .name = "FPSR", .state = ARM_CP_STATE_AA64,
24
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
25
.opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 4,
25
+ }
26
- .access = PL0_RW, .type = ARM_CP_FPU,
26
+ lr = deposit32(lr, 24, 8, 0xff);
27
+ .access = PL0_RW, .type = ARM_CP_FPU | ARM_CP_SUPPRESS_TB_END,
27
+ }
28
.readfn = aa64_fpsr_read, .writefn = aa64_fpsr_write },
28
+
29
{ .name = "DCZID_EL0", .state = ARM_CP_STATE_AA64,
29
if (arm_feature(env, ARM_FEATURE_V8)) {
30
.opc0 = 3, .opc1 = 3, .opc2 = 7, .crn = 0, .crm = 0,
30
if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
31
(lr & R_V7M_EXCRET_S_MASK)) {
31
--
32
--
32
2.16.1
33
2.20.1
33
34
34
35
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The magic value pushed onto the callee stack as an integrity
2
check is different if floating point is present.
2
3
3
Because they are ARM_CP_STATE_AA64, ARM_CP_64BIT is implied.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20180211205848.4568-2-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20190416125744.27770-15-peter.maydell@linaro.org
9
---
7
---
10
target/arm/helper.c | 8 ++++----
8
target/arm/helper.c | 22 +++++++++++++++++++---
11
1 file changed, 4 insertions(+), 4 deletions(-)
9
1 file changed, 19 insertions(+), 3 deletions(-)
12
10
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
13
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
14
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
15
@@ -XXX,XX +XXX,XX @@ load_fail:
18
static const ARMCPRegInfo zcr_el1_reginfo = {
16
return false;
19
.name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
17
}
20
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
18
21
- .access = PL1_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
19
+static uint32_t v7m_integrity_sig(CPUARMState *env, uint32_t lr)
22
+ .access = PL1_RW, .accessfn = zcr_access,
20
+{
23
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
21
+ /*
24
.writefn = zcr_write, .raw_writefn = raw_write
22
+ * Return the integrity signature value for the callee-saves
25
};
23
+ * stack frame section. @lr is the exception return payload/LR value
26
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo zcr_el1_reginfo = {
24
+ * whose FType bit forms bit 0 of the signature if FP is present.
27
static const ARMCPRegInfo zcr_el2_reginfo = {
25
+ */
28
.name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
26
+ uint32_t sig = 0xfefa125a;
29
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
27
+
30
- .access = PL2_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
28
+ if (!arm_feature(env, ARM_FEATURE_VFP) || (lr & R_V7M_EXCRET_FTYPE_MASK)) {
31
+ .access = PL2_RW, .accessfn = zcr_access,
29
+ sig |= 1;
32
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
30
+ }
33
.writefn = zcr_write, .raw_writefn = raw_write
31
+ return sig;
34
};
32
+}
35
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo zcr_el2_reginfo = {
33
+
36
static const ARMCPRegInfo zcr_no_el2_reginfo = {
34
static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
37
.name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
35
bool ignore_faults)
38
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
36
{
39
- .access = PL2_RW, .type = ARM_CP_64BIT,
37
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
40
+ .access = PL2_RW,
38
bool stacked_ok;
41
.readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore
39
uint32_t limit;
42
};
40
bool want_psp;
43
41
+ uint32_t sig;
44
static const ARMCPRegInfo zcr_el3_reginfo = {
42
45
.name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
43
if (dotailchain) {
46
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
44
bool mode = lr & R_V7M_EXCRET_MODE_MASK;
47
- .access = PL3_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
45
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
48
+ .access = PL3_RW, .accessfn = zcr_access,
46
/* Write as much of the stack frame as we can. A write failure may
49
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
47
* cause us to pend a derived exception.
50
.writefn = zcr_write, .raw_writefn = raw_write
48
*/
51
};
49
+ sig = v7m_integrity_sig(env, lr);
50
stacked_ok =
51
- v7m_stack_write(cpu, frameptr, 0xfefa125b, mmu_idx, ignore_faults) &&
52
+ v7m_stack_write(cpu, frameptr, sig, mmu_idx, ignore_faults) &&
53
v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
54
ignore_faults) &&
55
v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
56
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
57
if (return_to_secure &&
58
((excret & R_V7M_EXCRET_ES_MASK) == 0 ||
59
(excret & R_V7M_EXCRET_DCRS_MASK) == 0)) {
60
- uint32_t expected_sig = 0xfefa125b;
61
uint32_t actual_sig;
62
63
pop_ok = v7m_stack_read(cpu, &actual_sig, frameptr, mmu_idx);
64
65
- if (pop_ok && expected_sig != actual_sig) {
66
+ if (pop_ok && v7m_integrity_sig(env, excret) != actual_sig) {
67
/* Take a SecureFault on the current stack */
68
env->v7m.sfsr |= R_V7M_SFSR_INVIS_MASK;
69
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
52
--
70
--
53
2.16.1
71
2.20.1
54
72
55
73
diff view generated by jsdifflib
1
The PENDNMISET/CLR bits in the ICSR should be RAZ/WI from
1
Handle floating point registers in exception return.
2
NonSecure state if the AIRCR.BFHFNMINS bit is zero. We had
2
This corresponds to pseudocode functions ValidateExceptionReturn(),
3
misimplemented this as making the bits RAZ/WI from both
3
ExceptionReturn(), PopStack() and ConsumeExcStackFrame().
4
Secure and NonSecure states. Fix this bug by checking
5
attrs.secure so that Secure code can pend and unpend NMIs.
6
4
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180209165810.6668-3-peter.maydell@linaro.org
7
Message-id: 20190416125744.27770-16-peter.maydell@linaro.org
10
---
8
---
11
hw/intc/armv7m_nvic.c | 6 +++---
9
target/arm/helper.c | 142 +++++++++++++++++++++++++++++++++++++++++++-
12
1 file changed, 3 insertions(+), 3 deletions(-)
10
1 file changed, 141 insertions(+), 1 deletion(-)
13
11
14
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/armv7m_nvic.c
14
--- a/target/arm/helper.c
17
+++ b/hw/intc/armv7m_nvic.c
15
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
16
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
17
bool rettobase = false;
18
bool exc_secure = false;
19
bool return_to_secure;
20
+ bool ftype;
21
+ bool restore_s16_s31;
22
23
/* If we're not in Handler mode then jumps to magic exception-exit
24
* addresses don't have magic behaviour. However for the v8M
25
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
26
excret);
27
}
28
29
+ ftype = excret & R_V7M_EXCRET_FTYPE_MASK;
30
+
31
+ if (!arm_feature(env, ARM_FEATURE_VFP) && !ftype) {
32
+ qemu_log_mask(LOG_GUEST_ERROR, "M profile: zero FTYPE in exception "
33
+ "exit PC value 0x%" PRIx32 " is UNPREDICTABLE "
34
+ "if FPU not present\n",
35
+ excret);
36
+ ftype = true;
37
+ }
38
+
39
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
40
/* EXC_RETURN.ES validation check (R_SMFL). We must do this before
41
* we pick which FAULTMASK to clear.
42
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
43
*/
44
write_v7m_control_spsel_for_secstate(env, return_to_sp_process, exc_secure);
45
46
+ /*
47
+ * Clear scratch FP values left in caller saved registers; this
48
+ * must happen before any kind of tail chaining.
49
+ */
50
+ if ((env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_CLRONRET_MASK) &&
51
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
52
+ if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
53
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
54
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
55
+ qemu_log_mask(CPU_LOG_INT, "...taking SecureFault on existing "
56
+ "stackframe: error during lazy state deactivation\n");
57
+ v7m_exception_taken(cpu, excret, true, false);
58
+ return;
59
+ } else {
60
+ /* Clear s0..s15 and FPSCR */
61
+ int i;
62
+
63
+ for (i = 0; i < 16; i += 2) {
64
+ *aa32_vfp_dreg(env, i / 2) = 0;
65
+ }
66
+ vfp_set_fpscr(env, 0);
67
+ }
68
+ }
69
+
70
if (sfault) {
71
env->v7m.sfsr |= R_V7M_SFSR_INVER_MASK;
72
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
73
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
19
}
74
}
20
}
75
}
21
/* NMIPENDSET */
76
22
- if ((cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) &&
77
+ if (!ftype) {
23
- s->vectors[ARMV7M_EXCP_NMI].pending) {
78
+ /* FP present and we need to handle it */
24
+ if ((attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK))
79
+ if (!return_to_secure &&
25
+ && s->vectors[ARMV7M_EXCP_NMI].pending) {
80
+ (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK)) {
26
val |= (1 << 31);
81
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
27
}
82
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
28
/* ISRPREEMPT: RES0 when halting debug not implemented */
83
+ qemu_log_mask(CPU_LOG_INT,
29
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
84
+ "...taking SecureFault on existing stackframe: "
30
break;
85
+ "Secure LSPACT set but exception return is "
86
+ "not to secure state\n");
87
+ v7m_exception_taken(cpu, excret, true, false);
88
+ return;
89
+ }
90
+
91
+ restore_s16_s31 = return_to_secure &&
92
+ (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
93
+
94
+ if (env->v7m.fpccr[return_to_secure] & R_V7M_FPCCR_LSPACT_MASK) {
95
+ /* State in FPU is still valid, just clear LSPACT */
96
+ env->v7m.fpccr[return_to_secure] &= ~R_V7M_FPCCR_LSPACT_MASK;
97
+ } else {
98
+ int i;
99
+ uint32_t fpscr;
100
+ bool cpacr_pass, nsacr_pass;
101
+
102
+ cpacr_pass = v7m_cpacr_pass(env, return_to_secure,
103
+ return_to_priv);
104
+ nsacr_pass = return_to_secure ||
105
+ extract32(env->v7m.nsacr, 10, 1);
106
+
107
+ if (!cpacr_pass) {
108
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
109
+ return_to_secure);
110
+ env->v7m.cfsr[return_to_secure] |= R_V7M_CFSR_NOCP_MASK;
111
+ qemu_log_mask(CPU_LOG_INT,
112
+ "...taking UsageFault on existing "
113
+ "stackframe: CPACR.CP10 prevents unstacking "
114
+ "FP regs\n");
115
+ v7m_exception_taken(cpu, excret, true, false);
116
+ return;
117
+ } else if (!nsacr_pass) {
118
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, true);
119
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_INVPC_MASK;
120
+ qemu_log_mask(CPU_LOG_INT,
121
+ "...taking Secure UsageFault on existing "
122
+ "stackframe: NSACR.CP10 prevents unstacking "
123
+ "FP regs\n");
124
+ v7m_exception_taken(cpu, excret, true, false);
125
+ return;
126
+ }
127
+
128
+ for (i = 0; i < (restore_s16_s31 ? 32 : 16); i += 2) {
129
+ uint32_t slo, shi;
130
+ uint64_t dn;
131
+ uint32_t faddr = frameptr + 0x20 + 4 * i;
132
+
133
+ if (i >= 16) {
134
+ faddr += 8; /* Skip the slot for the FPSCR */
135
+ }
136
+
137
+ pop_ok = pop_ok &&
138
+ v7m_stack_read(cpu, &slo, faddr, mmu_idx) &&
139
+ v7m_stack_read(cpu, &shi, faddr + 4, mmu_idx);
140
+
141
+ if (!pop_ok) {
142
+ break;
143
+ }
144
+
145
+ dn = (uint64_t)shi << 32 | slo;
146
+ *aa32_vfp_dreg(env, i / 2) = dn;
147
+ }
148
+ pop_ok = pop_ok &&
149
+ v7m_stack_read(cpu, &fpscr, frameptr + 0x60, mmu_idx);
150
+ if (pop_ok) {
151
+ vfp_set_fpscr(env, fpscr);
152
+ }
153
+ if (!pop_ok) {
154
+ /*
155
+ * These regs are 0 if security extension present;
156
+ * otherwise merely UNKNOWN. We zero always.
157
+ */
158
+ for (i = 0; i < (restore_s16_s31 ? 32 : 16); i += 2) {
159
+ *aa32_vfp_dreg(env, i / 2) = 0;
160
+ }
161
+ vfp_set_fpscr(env, 0);
162
+ }
163
+ }
164
+ }
165
+ env->v7m.control[M_REG_S] = FIELD_DP32(env->v7m.control[M_REG_S],
166
+ V7M_CONTROL, FPCA, !ftype);
167
+
168
/* Commit to consuming the stack frame */
169
frameptr += 0x20;
170
+ if (!ftype) {
171
+ frameptr += 0x48;
172
+ if (restore_s16_s31) {
173
+ frameptr += 0x40;
174
+ }
175
+ }
176
/* Undo stack alignment (the SPREALIGN bit indicates that the original
177
* pre-exception SP was not 8-aligned and we added a padding word to
178
* align it, so we undo this by ORing in the bit that increases it
179
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
180
*frame_sp_p = frameptr;
31
}
181
}
32
case 0xd04: /* Interrupt Control State (ICSR) */
182
/* This xpsr_write() will invalidate frame_sp_p as it may switch stack */
33
- if (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
183
- xpsr_write(env, xpsr, ~XPSR_SPREALIGN);
34
+ if (attrs.secure || cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
184
+ xpsr_write(env, xpsr, ~(XPSR_SPREALIGN | XPSR_SFPA));
35
if (value & (1 << 31)) {
185
+
36
armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI, false);
186
+ if (env->v7m.secure) {
37
} else if (value & (1 << 30) &&
187
+ bool sfpa = xpsr & XPSR_SFPA;
188
+
189
+ env->v7m.control[M_REG_S] = FIELD_DP32(env->v7m.control[M_REG_S],
190
+ V7M_CONTROL, SFPA, sfpa);
191
+ }
192
193
/* The restored xPSR exception field will be zero if we're
194
* resuming in Thread mode. If that doesn't match what the
38
--
195
--
39
2.16.1
196
2.20.1
40
197
41
198
diff view generated by jsdifflib
New patch
1
Move the NS TBFLAG down from bit 19 to bit 6, which has not
2
been used since commit c1e3781090b9d36c60 in 2015, when we
3
started passing the entire MMU index in the TB flags rather
4
than just a 'privilege level' bit.
1
5
6
This rearrangement is not strictly necessary, but means that
7
we can put M-profile-only bits next to each other rather
8
than scattered across the flag word.
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20190416125744.27770-17-peter.maydell@linaro.org
13
---
14
target/arm/cpu.h | 11 ++++++-----
15
1 file changed, 6 insertions(+), 5 deletions(-)
16
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
25
+/*
26
+ * Indicates whether cp register reads and writes by guest code should access
27
+ * the secure or nonsecure bank of banked registers; note that this is not
28
+ * the same thing as the current security state of the processor!
29
+ */
30
+FIELD(TBFLAG_A32, NS, 6, 1)
31
FIELD(TBFLAG_A32, VFPEN, 7, 1)
32
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
33
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
34
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
35
* checks on the other bits at runtime
36
*/
37
FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
38
-/* Indicates whether cp register reads and writes by guest code should access
39
- * the secure or nonsecure bank of banked registers; note that this is not
40
- * the same thing as the current security state of the processor!
41
- */
42
-FIELD(TBFLAG_A32, NS, 19, 1)
43
/* For M profile only, Handler (ie not Thread) mode */
44
FIELD(TBFLAG_A32, HANDLER, 21, 1)
45
/* For M profile only, whether we should generate stack-limit checks */
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
New patch
1
We are close to running out of TB flags for AArch32; we could
2
start using the cs_base word, but before we do that we can
3
economise on our usage by sharing the same bits for the VFP
4
VECSTRIDE field and the XScale XSCALE_CPAR field. This
5
works because no XScale CPU ever had VFP.
1
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-18-peter.maydell@linaro.org
10
---
11
target/arm/cpu.h | 10 ++++++----
12
target/arm/cpu.c | 7 +++++++
13
target/arm/helper.c | 6 +++++-
14
target/arm/translate.c | 9 +++++++--
15
4 files changed, 25 insertions(+), 7 deletions(-)
16
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
25
+/*
26
+ * We store the bottom two bits of the CPAR as TB flags and handle
27
+ * checks on the other bits at runtime. This shares the same bits as
28
+ * VECSTRIDE, which is OK as no XScale CPU has VFP.
29
+ */
30
+FIELD(TBFLAG_A32, XSCALE_CPAR, 4, 2)
31
/*
32
* Indicates whether cp register reads and writes by guest code should access
33
* the secure or nonsecure bank of banked registers; note that this is not
34
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
35
FIELD(TBFLAG_A32, VFPEN, 7, 1)
36
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
37
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
38
-/* We store the bottom two bits of the CPAR as TB flags and handle
39
- * checks on the other bits at runtime
40
- */
41
-FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
42
/* For M profile only, Handler (ie not Thread) mode */
43
FIELD(TBFLAG_A32, HANDLER, 21, 1)
44
/* For M profile only, whether we should generate stack-limit checks */
45
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/cpu.c
48
+++ b/target/arm/cpu.c
49
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
50
set_feature(env, ARM_FEATURE_THUMB_DSP);
51
}
52
53
+ /*
54
+ * We rely on no XScale CPU having VFP so we can use the same bits in the
55
+ * TB flags field for VECSTRIDE and XSCALE_CPAR.
56
+ */
57
+ assert(!(arm_feature(env, ARM_FEATURE_VFP) &&
58
+ arm_feature(env, ARM_FEATURE_XSCALE)));
59
+
60
if (arm_feature(env, ARM_FEATURE_V7) &&
61
!arm_feature(env, ARM_FEATURE_M) &&
62
!arm_feature(env, ARM_FEATURE_PMSA)) {
63
diff --git a/target/arm/helper.c b/target/arm/helper.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/helper.c
66
+++ b/target/arm/helper.c
67
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
68
|| arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
69
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
70
}
71
- flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
72
+ /* Note that XSCALE_CPAR shares bits with VECSTRIDE */
73
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
74
+ flags = FIELD_DP32(flags, TBFLAG_A32,
75
+ XSCALE_CPAR, env->cp15.c15_cpar);
76
+ }
77
}
78
79
flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
80
diff --git a/target/arm/translate.c b/target/arm/translate.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/translate.c
83
+++ b/target/arm/translate.c
84
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
85
dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
86
dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
87
dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
88
- dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
89
- dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
90
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
91
+ dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
92
+ dc->vec_stride = 0;
93
+ } else {
94
+ dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
95
+ dc->c15_cpar = 0;
96
+ }
97
dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
98
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
99
regime_is_secure(env, dc->mmu_idx);
100
--
101
2.20.1
102
103
diff view generated by jsdifflib
New patch
1
The M-profile FPCCR.S bit indicates the security status of
2
the floating point context. In the pseudocode ExecuteFPCheck()
3
function it is unconditionally set to match the current
4
security state whenever a floating point instruction is
5
executed.
1
6
7
Implement this by adding a new TB flag which tracks whether
8
FPCCR.S is different from the current security state, so
9
that we only need to emit the code to update it in the
10
less-common case when it is not already set correctly.
11
12
Note that we will add the handling for the other work done
13
by ExecuteFPCheck() in later commits.
14
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20190416125744.27770-19-peter.maydell@linaro.org
18
---
19
target/arm/cpu.h | 2 ++
20
target/arm/translate.h | 1 +
21
target/arm/helper.c | 5 +++++
22
target/arm/translate.c | 20 ++++++++++++++++++++
23
4 files changed, 28 insertions(+)
24
25
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/cpu.h
28
+++ b/target/arm/cpu.h
29
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
30
FIELD(TBFLAG_A32, VFPEN, 7, 1)
31
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
32
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
33
+/* For M profile only, set if FPCCR.S does not match current security state */
34
+FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
35
/* For M profile only, Handler (ie not Thread) mode */
36
FIELD(TBFLAG_A32, HANDLER, 21, 1)
37
/* For M profile only, whether we should generate stack-limit checks */
38
diff --git a/target/arm/translate.h b/target/arm/translate.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/translate.h
41
+++ b/target/arm/translate.h
42
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
43
bool v7m_handler_mode;
44
bool v8m_secure; /* true if v8M and we're in Secure mode */
45
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
46
+ bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
47
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
48
* so that top level loop can generate correct syndrome information.
49
*/
50
diff --git a/target/arm/helper.c b/target/arm/helper.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/helper.c
53
+++ b/target/arm/helper.c
54
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
55
flags = FIELD_DP32(flags, TBFLAG_A32, STACKCHECK, 1);
56
}
57
58
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
59
+ FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S) != env->v7m.secure) {
60
+ flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
61
+ }
62
+
63
*pflags = flags;
64
*cs_base = 0;
65
}
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate.c
69
+++ b/target/arm/translate.c
70
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
71
}
72
}
73
74
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
75
+ /* Handle M-profile lazy FP state mechanics */
76
+
77
+ /* Update ownership of FP context: set FPCCR.S to match current state */
78
+ if (s->v8m_fpccr_s_wrong) {
79
+ TCGv_i32 tmp;
80
+
81
+ tmp = load_cpu_field(v7m.fpccr[M_REG_S]);
82
+ if (s->v8m_secure) {
83
+ tcg_gen_ori_i32(tmp, tmp, R_V7M_FPCCR_S_MASK);
84
+ } else {
85
+ tcg_gen_andi_i32(tmp, tmp, ~R_V7M_FPCCR_S_MASK);
86
+ }
87
+ store_cpu_field(tmp, v7m.fpccr[M_REG_S]);
88
+ /* Don't need to do this for any further FP insns in this TB */
89
+ s->v8m_fpccr_s_wrong = false;
90
+ }
91
+ }
92
+
93
if (extract32(insn, 28, 4) == 0xf) {
94
/*
95
* Encodings with T=1 (Thumb) or unconditional (ARM):
96
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
97
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
98
regime_is_secure(env, dc->mmu_idx);
99
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
100
+ dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
101
dc->cp_regs = cpu->cp_regs;
102
dc->features = env->features;
103
104
--
105
2.20.1
106
107
diff view generated by jsdifflib
1
The v8M architecture includes hardware support for enforcing
1
The M-profile FPCCR.ASPEN bit indicates that automatic floating-point
2
stack pointer limits. We don't implement this behaviour yet,
2
context preservation is enabled. Before executing any floating-point
3
but provide the MSPLIM and PSPLIM stack pointer limit registers
3
instruction, if FPCCR.ASPEN is set and the CONTROL FPCA/SFPA bits
4
as reads-as-written, so that when we do implement the checks
4
indicate that there is no active floating point context then we
5
in future this won't break guest migration.
5
must create a new context (by initializing FPSCR and setting
6
FPCA/SFPA to indicate that the context is now active). In the
7
pseudocode this is handled by ExecuteFPCheck().
8
9
Implement this with a new TB flag which tracks whether we
10
need to create a new FP context.
6
11
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180209165810.6668-12-peter.maydell@linaro.org
14
Message-id: 20190416125744.27770-20-peter.maydell@linaro.org
10
---
15
---
11
target/arm/cpu.h | 2 ++
16
target/arm/cpu.h | 2 ++
12
target/arm/helper.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
17
target/arm/translate.h | 1 +
13
target/arm/machine.c | 21 +++++++++++++++++++++
18
target/arm/helper.c | 13 +++++++++++++
14
3 files changed, 69 insertions(+)
19
target/arm/translate.c | 29 +++++++++++++++++++++++++++++
20
4 files changed, 45 insertions(+)
15
21
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
24
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
25
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
26
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
21
uint32_t secure; /* Is CPU in Secure state? (not guest visible) */
27
FIELD(TBFLAG_A32, VFPEN, 7, 1)
22
uint32_t csselr[M_REG_NUM_BANKS];
28
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
23
uint32_t scr[M_REG_NUM_BANKS];
29
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
24
+ uint32_t msplim[M_REG_NUM_BANKS];
30
+/* For M profile only, set if we must create a new FP context */
25
+ uint32_t psplim[M_REG_NUM_BANKS];
31
+FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
26
} v7m;
32
/* For M profile only, set if FPCCR.S does not match current security state */
27
33
FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
28
/* Information associated with an exception about to be taken:
34
/* For M profile only, Handler (ie not Thread) mode */
35
diff --git a/target/arm/translate.h b/target/arm/translate.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/translate.h
38
+++ b/target/arm/translate.h
39
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
40
bool v8m_secure; /* true if v8M and we're in Secure mode */
41
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
42
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
43
+ bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
44
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
45
* so that top level loop can generate correct syndrome information.
46
*/
29
diff --git a/target/arm/helper.c b/target/arm/helper.c
47
diff --git a/target/arm/helper.c b/target/arm/helper.c
30
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/helper.c
49
--- a/target/arm/helper.c
32
+++ b/target/arm/helper.c
50
+++ b/target/arm/helper.c
33
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
51
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
34
return 0;
52
flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
35
}
53
}
36
return env->v7m.other_ss_psp;
54
37
+ case 0x8a: /* MSPLIM_NS */
55
+ if (arm_feature(env, ARM_FEATURE_M) &&
38
+ if (!env->v7m.secure) {
56
+ (env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) &&
39
+ return 0;
57
+ (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) ||
58
+ (env->v7m.secure &&
59
+ !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)))) {
60
+ /*
61
+ * ASPEN is set, but FPCA/SFPA indicate that there is no active
62
+ * FP context; we must create a new FP context before executing
63
+ * any FP insn.
64
+ */
65
+ flags = FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED, 1);
66
+ }
67
+
68
*pflags = flags;
69
*cs_base = 0;
70
}
71
diff --git a/target/arm/translate.c b/target/arm/translate.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/translate.c
74
+++ b/target/arm/translate.c
75
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
76
/* Don't need to do this for any further FP insns in this TB */
77
s->v8m_fpccr_s_wrong = false;
78
}
79
+
80
+ if (s->v7m_new_fp_ctxt_needed) {
81
+ /*
82
+ * Create new FP context by updating CONTROL.FPCA, CONTROL.SFPA
83
+ * and the FPSCR.
84
+ */
85
+ TCGv_i32 control, fpscr;
86
+ uint32_t bits = R_V7M_CONTROL_FPCA_MASK;
87
+
88
+ fpscr = load_cpu_field(v7m.fpdscr[s->v8m_secure]);
89
+ gen_helper_vfp_set_fpscr(cpu_env, fpscr);
90
+ tcg_temp_free_i32(fpscr);
91
+ /*
92
+ * We don't need to arrange to end the TB, because the only
93
+ * parts of FPSCR which we cache in the TB flags are the VECLEN
94
+ * and VECSTRIDE, and those don't exist for M-profile.
95
+ */
96
+
97
+ if (s->v8m_secure) {
98
+ bits |= R_V7M_CONTROL_SFPA_MASK;
40
+ }
99
+ }
41
+ return env->v7m.msplim[M_REG_NS];
100
+ control = load_cpu_field(v7m.control[M_REG_S]);
42
+ case 0x8b: /* PSPLIM_NS */
101
+ tcg_gen_ori_i32(control, control, bits);
43
+ if (!env->v7m.secure) {
102
+ store_cpu_field(control, v7m.control[M_REG_S]);
44
+ return 0;
103
+ /* Don't need to do this for any further FP insns in this TB */
45
+ }
104
+ s->v7m_new_fp_ctxt_needed = false;
46
+ return env->v7m.psplim[M_REG_NS];
47
case 0x90: /* PRIMASK_NS */
48
if (!env->v7m.secure) {
49
return 0;
50
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
51
return v7m_using_psp(env) ? env->v7m.other_sp : env->regs[13];
52
case 9: /* PSP */
53
return v7m_using_psp(env) ? env->regs[13] : env->v7m.other_sp;
54
+ case 10: /* MSPLIM */
55
+ if (!arm_feature(env, ARM_FEATURE_V8)) {
56
+ goto bad_reg;
57
+ }
105
+ }
58
+ return env->v7m.msplim[env->v7m.secure];
59
+ case 11: /* PSPLIM */
60
+ if (!arm_feature(env, ARM_FEATURE_V8)) {
61
+ goto bad_reg;
62
+ }
63
+ return env->v7m.psplim[env->v7m.secure];
64
case 16: /* PRIMASK */
65
return env->v7m.primask[env->v7m.secure];
66
case 17: /* BASEPRI */
67
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
68
case 19: /* FAULTMASK */
69
return env->v7m.faultmask[env->v7m.secure];
70
default:
71
+ bad_reg:
72
qemu_log_mask(LOG_GUEST_ERROR, "Attempt to read unknown special"
73
" register %d\n", reg);
74
return 0;
75
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
76
}
77
env->v7m.other_ss_psp = val;
78
return;
79
+ case 0x8a: /* MSPLIM_NS */
80
+ if (!env->v7m.secure) {
81
+ return;
82
+ }
83
+ env->v7m.msplim[M_REG_NS] = val & ~7;
84
+ return;
85
+ case 0x8b: /* PSPLIM_NS */
86
+ if (!env->v7m.secure) {
87
+ return;
88
+ }
89
+ env->v7m.psplim[M_REG_NS] = val & ~7;
90
+ return;
91
case 0x90: /* PRIMASK_NS */
92
if (!env->v7m.secure) {
93
return;
94
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
95
env->v7m.other_sp = val;
96
}
97
break;
98
+ case 10: /* MSPLIM */
99
+ if (!arm_feature(env, ARM_FEATURE_V8)) {
100
+ goto bad_reg;
101
+ }
102
+ env->v7m.msplim[env->v7m.secure] = val & ~7;
103
+ break;
104
+ case 11: /* PSPLIM */
105
+ if (!arm_feature(env, ARM_FEATURE_V8)) {
106
+ goto bad_reg;
107
+ }
108
+ env->v7m.psplim[env->v7m.secure] = val & ~7;
109
+ break;
110
case 16: /* PRIMASK */
111
env->v7m.primask[env->v7m.secure] = val & 1;
112
break;
113
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
114
env->v7m.control[env->v7m.secure] |= val & R_V7M_CONTROL_NPRIV_MASK;
115
break;
116
default:
117
+ bad_reg:
118
qemu_log_mask(LOG_GUEST_ERROR, "Attempt to write unknown special"
119
" register %d\n", reg);
120
return;
121
diff --git a/target/arm/machine.c b/target/arm/machine.c
122
index XXXXXXX..XXXXXXX 100644
123
--- a/target/arm/machine.c
124
+++ b/target/arm/machine.c
125
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_other_sp = {
126
}
106
}
127
};
107
128
108
if (extract32(insn, 28, 4) == 0xf) {
129
+static bool m_v8m_needed(void *opaque)
109
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
130
+{
110
regime_is_secure(env, dc->mmu_idx);
131
+ ARMCPU *cpu = opaque;
111
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
132
+ CPUARMState *env = &cpu->env;
112
dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
133
+
113
+ dc->v7m_new_fp_ctxt_needed =
134
+ return arm_feature(env, ARM_FEATURE_M) && arm_feature(env, ARM_FEATURE_V8);
114
+ FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
135
+}
115
dc->cp_regs = cpu->cp_regs;
136
+
116
dc->features = env->features;
137
+static const VMStateDescription vmstate_m_v8m = {
117
138
+ .name = "cpu/m/v8m",
139
+ .version_id = 1,
140
+ .minimum_version_id = 1,
141
+ .needed = m_v8m_needed,
142
+ .fields = (VMStateField[]) {
143
+ VMSTATE_UINT32_ARRAY(env.v7m.msplim, ARMCPU, M_REG_NUM_BANKS),
144
+ VMSTATE_UINT32_ARRAY(env.v7m.psplim, ARMCPU, M_REG_NUM_BANKS),
145
+ VMSTATE_END_OF_LIST()
146
+ }
147
+};
148
+
149
static const VMStateDescription vmstate_m = {
150
.name = "cpu/m",
151
.version_id = 4,
152
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
153
&vmstate_m_csselr,
154
&vmstate_m_scr,
155
&vmstate_m_other_sp,
156
+ &vmstate_m_v8m,
157
NULL
158
}
159
};
160
--
118
--
161
2.16.1
119
2.20.1
162
120
163
121
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Add a new helper function which returns the MMU index to use
2
for v7M, where the caller specifies all of the security
3
state, privilege level and whether the execution priority
4
is negative, and reimplement the existing
5
arm_v7m_mmu_idx_for_secstate_and_priv() in terms of it.
2
6
3
This also makes sure that we get the correct ordering of
7
We are going to need this for the lazy-FP-stacking code.
4
SVE vs FP exceptions.
5
8
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180211205848.4568-5-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20190416125744.27770-21-peter.maydell@linaro.org
10
---
12
---
11
target/arm/cpu.h | 3 ++-
13
target/arm/cpu.h | 7 +++++++
12
target/arm/internals.h | 6 ++++++
14
target/arm/helper.c | 14 +++++++++++---
13
target/arm/helper.c | 22 ++++------------------
15
2 files changed, 18 insertions(+), 3 deletions(-)
14
target/arm/translate-a64.c | 16 ++++++++++++++++
15
4 files changed, 28 insertions(+), 19 deletions(-)
16
16
17
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
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
19
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
21
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
22
#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | 0x0500)
22
}
23
#define ARM_LAST_SPECIAL ARM_CP_DC_ZVA
24
#define ARM_CP_FPU 0x1000
25
+#define ARM_CP_SVE 0x2000
26
/* Used only as a terminator for ARMCPRegInfo lists */
27
#define ARM_CP_SENTINEL 0xffff
28
/* Mask of only the flag bits in a type field */
29
-#define ARM_CP_FLAG_MASK 0x10ff
30
+#define ARM_CP_FLAG_MASK 0x30ff
31
32
/* Valid values for ARMCPRegInfo state field, indicating which of
33
* the AArch32 and AArch64 execution states this register is visible in.
34
diff --git a/target/arm/internals.h b/target/arm/internals.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/internals.h
37
+++ b/target/arm/internals.h
38
@@ -XXX,XX +XXX,XX @@ enum arm_exception_class {
39
EC_AA64_HVC = 0x16,
40
EC_AA64_SMC = 0x17,
41
EC_SYSTEMREGISTERTRAP = 0x18,
42
+ EC_SVEACCESSTRAP = 0x19,
43
EC_INSNABORT = 0x20,
44
EC_INSNABORT_SAME_EL = 0x21,
45
EC_PCALIGNMENT = 0x22,
46
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_fp_access_trap(int cv, int cond, bool is_16bit)
47
| (cv << 24) | (cond << 20);
48
}
23
}
49
24
50
+static inline uint32_t syn_sve_access_trap(void)
25
+/*
51
+{
26
+ * Return the MMU index for a v7M CPU with all relevant information
52
+ return EC_SVEACCESSTRAP << ARM_EL_EC_SHIFT;
27
+ * manually specified.
53
+}
28
+ */
29
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
30
+ bool secstate, bool priv, bool negpri);
54
+
31
+
55
static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
32
/* Return the MMU index for a v7M CPU in the specified security and
56
{
33
* privilege state.
57
return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
34
*/
58
diff --git a/target/arm/helper.c b/target/arm/helper.c
35
diff --git a/target/arm/helper.c b/target/arm/helper.c
59
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/helper.c
37
--- a/target/arm/helper.c
61
+++ b/target/arm/helper.c
38
+++ b/target/arm/helper.c
62
@@ -XXX,XX +XXX,XX @@ static int sve_exception_el(CPUARMState *env)
39
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
63
return 0;
40
return 0;
64
}
41
}
65
42
66
-static CPAccessResult zcr_access(CPUARMState *env, const ARMCPRegInfo *ri,
43
-ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
67
- bool isread)
44
- bool secstate, bool priv)
68
-{
45
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
69
- switch (sve_exception_el(env)) {
46
+ bool secstate, bool priv, bool negpri)
70
- case 3:
71
- return CP_ACCESS_TRAP_EL3;
72
- case 2:
73
- return CP_ACCESS_TRAP_EL2;
74
- case 1:
75
- return CP_ACCESS_TRAP;
76
- }
77
- return CP_ACCESS_OK;
78
-}
79
-
80
static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
81
uint64_t value)
82
{
47
{
83
@@ -XXX,XX +XXX,XX @@ static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
48
ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
84
static const ARMCPRegInfo zcr_el1_reginfo = {
49
85
.name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
50
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
86
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
51
mmu_idx |= ARM_MMU_IDX_M_PRIV;
87
- .access = PL1_RW, .accessfn = zcr_access,
52
}
88
+ .access = PL1_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
53
89
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
54
- if (armv7m_nvic_neg_prio_requested(env->nvic, secstate)) {
90
.writefn = zcr_write, .raw_writefn = raw_write
55
+ if (negpri) {
91
};
56
mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
92
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo zcr_el1_reginfo = {
57
}
93
static const ARMCPRegInfo zcr_el2_reginfo = {
58
94
.name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
59
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
95
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
60
return mmu_idx;
96
- .access = PL2_RW, .accessfn = zcr_access,
97
+ .access = PL2_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
98
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
99
.writefn = zcr_write, .raw_writefn = raw_write
100
};
101
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo zcr_el2_reginfo = {
102
static const ARMCPRegInfo zcr_no_el2_reginfo = {
103
.name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
104
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
105
- .access = PL2_RW,
106
+ .access = PL2_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
107
.readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore
108
};
109
110
static const ARMCPRegInfo zcr_el3_reginfo = {
111
.name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
112
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
113
- .access = PL3_RW, .accessfn = zcr_access,
114
+ .access = PL3_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
115
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
116
.writefn = zcr_write, .raw_writefn = raw_write
117
};
118
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
119
index XXXXXXX..XXXXXXX 100644
120
--- a/target/arm/translate-a64.c
121
+++ b/target/arm/translate-a64.c
122
@@ -XXX,XX +XXX,XX @@ static inline bool fp_access_check(DisasContext *s)
123
return false;
124
}
61
}
125
62
126
+/* Check that SVE access is enabled. If it is, return true.
63
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
127
+ * If not, emit code to generate an appropriate exception and return false.
64
+ bool secstate, bool priv)
128
+ */
129
+static inline bool sve_access_check(DisasContext *s)
130
+{
65
+{
131
+ if (s->sve_excp_el) {
66
+ bool negpri = armv7m_nvic_neg_prio_requested(env->nvic, secstate);
132
+ gen_exception_insn(s, 4, EXCP_UDEF, syn_sve_access_trap(),
67
+
133
+ s->sve_excp_el);
68
+ return arm_v7m_mmu_idx_all(env, secstate, priv, negpri);
134
+ return false;
135
+ }
136
+ return true;
137
+}
69
+}
138
+
70
+
139
/*
71
/* Return the MMU index for a v7M CPU in the specified security state */
140
* This utility function is for doing register extension with an
72
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
141
* optional shift. You will likely want to pass a temporary for the
73
{
142
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
143
default:
144
break;
145
}
146
+ if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
147
+ return;
148
+ }
149
if ((ri->type & ARM_CP_FPU) && !fp_access_check(s)) {
150
return;
151
}
152
--
74
--
153
2.16.1
75
2.20.1
154
76
155
77
diff view generated by jsdifflib
1
We were previously making the system control register (SCR)
1
In the v7M architecture, if an exception is generated in the process
2
just RAZ/WI. Although we don't implement the functionality
2
of doing the lazy stacking of FP registers, the handling of
3
this register controls, we should at least provide the state,
3
possible escalation to HardFault is treated differently to the normal
4
including the banked state for v8M.
4
approach: it works based on the saved information about exception
5
readiness that was stored in the FPCCR when the stack frame was
6
created. Provide a new function armv7m_nvic_set_pending_lazyfp()
7
which pends exceptions during lazy stacking, and implements
8
this logic.
9
10
This corresponds to the pseudocode TakePreserveFPException().
5
11
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180209165810.6668-7-peter.maydell@linaro.org
14
Message-id: 20190416125744.27770-22-peter.maydell@linaro.org
9
---
15
---
10
target/arm/cpu.h | 7 +++++++
16
target/arm/cpu.h | 12 ++++++
11
hw/intc/armv7m_nvic.c | 12 ++++++++----
17
hw/intc/armv7m_nvic.c | 96 +++++++++++++++++++++++++++++++++++++++++++
12
target/arm/machine.c | 12 ++++++++++++
18
2 files changed, 108 insertions(+)
13
3 files changed, 27 insertions(+), 4 deletions(-)
14
19
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
22
--- a/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
23
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
24
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
20
uint32_t aircr; /* only holds r/w state if security extn implemented */
25
* a different exception).
21
uint32_t secure; /* Is CPU in Secure state? (not guest visible) */
26
*/
22
uint32_t csselr[M_REG_NUM_BANKS];
27
void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
23
+ uint32_t scr[M_REG_NUM_BANKS];
28
+/**
24
} v7m;
29
+ * armv7m_nvic_set_pending_lazyfp: mark this lazy FP exception as pending
25
30
+ * @opaque: the NVIC
26
/* Information associated with an exception about to be taken:
31
+ * @irq: the exception number to mark pending
27
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_CCR, STKALIGN, 9, 1)
32
+ * @secure: false for non-banked exceptions or for the nonsecure
28
FIELD(V7M_CCR, DC, 16, 1)
33
+ * version of a banked exception, true for the secure version of a banked
29
FIELD(V7M_CCR, IC, 17, 1)
34
+ * exception.
30
35
+ *
31
+/* V7M SCR bits */
36
+ * Similar to armv7m_nvic_set_pending(), but specifically for exceptions
32
+FIELD(V7M_SCR, SLEEPONEXIT, 1, 1)
37
+ * generated in the course of lazy stacking of FP registers.
33
+FIELD(V7M_SCR, SLEEPDEEP, 2, 1)
38
+ */
34
+FIELD(V7M_SCR, SLEEPDEEPS, 3, 1)
39
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure);
35
+FIELD(V7M_SCR, SEVONPEND, 4, 1)
40
/**
36
+
41
* armv7m_nvic_get_pending_irq_info: return highest priority pending
37
/* V7M AIRCR bits */
42
* exception, and whether it targets Secure state
38
FIELD(V7M_AIRCR, VECTRESET, 0, 1)
39
FIELD(V7M_AIRCR, VECTCLRACTIVE, 1, 1)
40
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
43
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
41
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/intc/armv7m_nvic.c
45
--- a/hw/intc/armv7m_nvic.c
43
+++ b/hw/intc/armv7m_nvic.c
46
+++ b/hw/intc/armv7m_nvic.c
44
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
47
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
45
}
48
do_armv7m_nvic_set_pending(opaque, irq, secure, true);
46
return val;
49
}
47
case 0xd10: /* System Control. */
50
48
- /* TODO: Implement SLEEPONEXIT. */
51
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
49
- return 0;
52
+{
50
+ return cpu->env.v7m.scr[attrs.secure];
53
+ /*
51
case 0xd14: /* Configuration Control. */
54
+ * Pend an exception during lazy FP stacking. This differs
52
/* The BFHFNMIGN bit is the only non-banked bit; we
55
+ * from the usual exception pending because the logic for
53
* keep it in the non-secure copy of the register.
56
+ * whether we should escalate depends on the saved context
54
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
57
+ * in the FPCCR register, not on the current state of the CPU/NVIC.
55
}
58
+ */
56
break;
59
+ NVICState *s = (NVICState *)opaque;
57
case 0xd10: /* System Control. */
60
+ bool banked = exc_is_banked(irq);
58
- /* TODO: Implement control registers. */
61
+ VecInfo *vec;
59
- qemu_log_mask(LOG_UNIMP, "NVIC: SCR unimplemented\n");
62
+ bool targets_secure;
60
+ /* We don't implement deep-sleep so these bits are RAZ/WI.
63
+ bool escalate = false;
61
+ * The other bits in the register are banked.
64
+ /*
62
+ * QEMU's implementation ignores SEVONPEND and SLEEPONEXIT, which
65
+ * We will only look at bits in fpccr if this is a banked exception
63
+ * is architecturally permitted.
66
+ * (in which case 'secure' tells us whether it is the S or NS version).
67
+ * All the bits for the non-banked exceptions are in fpccr_s.
68
+ */
69
+ uint32_t fpccr_s = s->cpu->env.v7m.fpccr[M_REG_S];
70
+ uint32_t fpccr = s->cpu->env.v7m.fpccr[secure];
71
+
72
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
73
+ assert(!secure || banked);
74
+
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
76
+
77
+ targets_secure = banked ? secure : exc_targets_secure(s, irq);
78
+
79
+ switch (irq) {
80
+ case ARMV7M_EXCP_DEBUG:
81
+ if (!(fpccr_s & R_V7M_FPCCR_MONRDY_MASK)) {
82
+ /* Ignore DebugMonitor exception */
83
+ return;
84
+ }
85
+ break;
86
+ case ARMV7M_EXCP_MEM:
87
+ escalate = !(fpccr & R_V7M_FPCCR_MMRDY_MASK);
88
+ break;
89
+ case ARMV7M_EXCP_USAGE:
90
+ escalate = !(fpccr & R_V7M_FPCCR_UFRDY_MASK);
91
+ break;
92
+ case ARMV7M_EXCP_BUS:
93
+ escalate = !(fpccr_s & R_V7M_FPCCR_BFRDY_MASK);
94
+ break;
95
+ case ARMV7M_EXCP_SECURE:
96
+ escalate = !(fpccr_s & R_V7M_FPCCR_SFRDY_MASK);
97
+ break;
98
+ default:
99
+ g_assert_not_reached();
100
+ }
101
+
102
+ if (escalate) {
103
+ /*
104
+ * Escalate to HardFault: faults that initially targeted Secure
105
+ * continue to do so, even if HF normally targets NonSecure.
64
+ */
106
+ */
65
+ value &= ~(R_V7M_SCR_SLEEPDEEP_MASK | R_V7M_SCR_SLEEPDEEPS_MASK);
107
+ irq = ARMV7M_EXCP_HARD;
66
+ cpu->env.v7m.scr[attrs.secure] = value;
108
+ if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY) &&
67
break;
109
+ (targets_secure ||
68
case 0xd14: /* Configuration Control. */
110
+ !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK))) {
69
/* Enforce RAZ/WI on reserved and must-RAZ/WI bits */
111
+ vec = &s->sec_vectors[irq];
70
diff --git a/target/arm/machine.c b/target/arm/machine.c
112
+ } else {
71
index XXXXXXX..XXXXXXX 100644
113
+ vec = &s->vectors[irq];
72
--- a/target/arm/machine.c
114
+ }
73
+++ b/target/arm/machine.c
74
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_csselr = {
75
}
76
};
77
78
+static const VMStateDescription vmstate_m_scr = {
79
+ .name = "cpu/m/scr",
80
+ .version_id = 1,
81
+ .minimum_version_id = 1,
82
+ .fields = (VMStateField[]) {
83
+ VMSTATE_UINT32(env.v7m.scr[M_REG_NS], ARMCPU),
84
+ VMSTATE_END_OF_LIST()
85
+ }
115
+ }
86
+};
87
+
116
+
88
static const VMStateDescription vmstate_m = {
117
+ if (!vec->enabled ||
89
.name = "cpu/m",
118
+ nvic_exec_prio(s) <= exc_group_prio(s, vec->prio, secure)) {
90
.version_id = 4,
119
+ if (!(fpccr_s & R_V7M_FPCCR_HFRDY_MASK)) {
91
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
120
+ /*
92
.subsections = (const VMStateDescription*[]) {
121
+ * We want to escalate to HardFault but the context the
93
&vmstate_m_faultmask_primask,
122
+ * FP state belongs to prevents the exception pre-empting.
94
&vmstate_m_csselr,
123
+ */
95
+ &vmstate_m_scr,
124
+ cpu_abort(&s->cpu->parent_obj,
96
NULL
125
+ "Lockup: can't escalate to HardFault during "
97
}
126
+ "lazy FP register stacking\n");
98
};
127
+ }
99
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_security = {
128
+ }
100
VMSTATE_UINT32(env.sau.rnr, ARMCPU),
129
+
101
VMSTATE_VALIDATE("SAU_RNR is valid", sau_rnr_vmstate_validate),
130
+ if (escalate) {
102
VMSTATE_UINT32(env.sau.ctrl, ARMCPU),
131
+ s->cpu->env.v7m.hfsr |= R_V7M_HFSR_FORCED_MASK;
103
+ VMSTATE_UINT32(env.v7m.scr[M_REG_S], ARMCPU),
132
+ }
104
VMSTATE_END_OF_LIST()
133
+ if (!vec->pending) {
105
}
134
+ vec->pending = 1;
106
};
135
+ /*
136
+ * We do not call nvic_irq_update(), because we know our caller
137
+ * is going to handle causing us to take the exception by
138
+ * raising EXCP_LAZYFP, so raising the IRQ line would be
139
+ * pointless extra work. We just need to recompute the
140
+ * priorities so that armv7m_nvic_can_take_pending_exception()
141
+ * returns the right answer.
142
+ */
143
+ nvic_recompute_state(s);
144
+ }
145
+}
146
+
147
/* Make pending IRQ active. */
148
void armv7m_nvic_acknowledge_irq(void *opaque)
149
{
107
--
150
--
108
2.16.1
151
2.20.1
109
152
110
153
diff view generated by jsdifflib
New patch
1
1
Pushing registers to the stack for v7M needs to handle three cases:
2
* the "normal" case where we pend exceptions
3
* an "ignore faults" case where we set FSR bits but
4
do not pend exceptions (this is used when we are
5
handling some kinds of derived exception on exception entry)
6
* a "lazy FP stacking" case, where different FSR bits
7
are set and the exception is pended differently
8
9
Implement this by changing the existing flag argument that
10
tells us whether to ignore faults or not into an enum that
11
specifies which of the 3 modes we should handle.
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20190416125744.27770-23-peter.maydell@linaro.org
16
---
17
target/arm/helper.c | 118 +++++++++++++++++++++++++++++---------------
18
1 file changed, 79 insertions(+), 39 deletions(-)
19
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
23
+++ b/target/arm/helper.c
24
@@ -XXX,XX +XXX,XX @@ static bool v7m_cpacr_pass(CPUARMState *env, bool is_secure, bool is_priv)
25
}
26
}
27
28
+/*
29
+ * What kind of stack write are we doing? This affects how exceptions
30
+ * generated during the stacking are treated.
31
+ */
32
+typedef enum StackingMode {
33
+ STACK_NORMAL,
34
+ STACK_IGNFAULTS,
35
+ STACK_LAZYFP,
36
+} StackingMode;
37
+
38
static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
39
- ARMMMUIdx mmu_idx, bool ignfault)
40
+ ARMMMUIdx mmu_idx, StackingMode mode)
41
{
42
CPUState *cs = CPU(cpu);
43
CPUARMState *env = &cpu->env;
44
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
45
&attrs, &prot, &page_size, &fi, NULL)) {
46
/* MPU/SAU lookup failed */
47
if (fi.type == ARMFault_QEMU_SFault) {
48
- qemu_log_mask(CPU_LOG_INT,
49
- "...SecureFault with SFSR.AUVIOL during stacking\n");
50
- env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK | R_V7M_SFSR_SFARVALID_MASK;
51
+ if (mode == STACK_LAZYFP) {
52
+ qemu_log_mask(CPU_LOG_INT,
53
+ "...SecureFault with SFSR.LSPERR "
54
+ "during lazy stacking\n");
55
+ env->v7m.sfsr |= R_V7M_SFSR_LSPERR_MASK;
56
+ } else {
57
+ qemu_log_mask(CPU_LOG_INT,
58
+ "...SecureFault with SFSR.AUVIOL "
59
+ "during stacking\n");
60
+ env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK;
61
+ }
62
+ env->v7m.sfsr |= R_V7M_SFSR_SFARVALID_MASK;
63
env->v7m.sfar = addr;
64
exc = ARMV7M_EXCP_SECURE;
65
exc_secure = false;
66
} else {
67
- qemu_log_mask(CPU_LOG_INT, "...MemManageFault with CFSR.MSTKERR\n");
68
- env->v7m.cfsr[secure] |= R_V7M_CFSR_MSTKERR_MASK;
69
+ if (mode == STACK_LAZYFP) {
70
+ qemu_log_mask(CPU_LOG_INT,
71
+ "...MemManageFault with CFSR.MLSPERR\n");
72
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MLSPERR_MASK;
73
+ } else {
74
+ qemu_log_mask(CPU_LOG_INT,
75
+ "...MemManageFault with CFSR.MSTKERR\n");
76
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MSTKERR_MASK;
77
+ }
78
exc = ARMV7M_EXCP_MEM;
79
exc_secure = secure;
80
}
81
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
82
attrs, &txres);
83
if (txres != MEMTX_OK) {
84
/* BusFault trying to write the data */
85
- qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.STKERR\n");
86
- env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_STKERR_MASK;
87
+ if (mode == STACK_LAZYFP) {
88
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.LSPERR\n");
89
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_LSPERR_MASK;
90
+ } else {
91
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.STKERR\n");
92
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_STKERR_MASK;
93
+ }
94
exc = ARMV7M_EXCP_BUS;
95
exc_secure = false;
96
goto pend_fault;
97
@@ -XXX,XX +XXX,XX @@ pend_fault:
98
* later if we have two derived exceptions.
99
* The only case when we must not pend the exception but instead
100
* throw it away is if we are doing the push of the callee registers
101
- * and we've already generated a derived exception. Even in this
102
- * case we will still update the fault status registers.
103
+ * and we've already generated a derived exception (this is indicated
104
+ * by the caller passing STACK_IGNFAULTS). Even in this case we will
105
+ * still update the fault status registers.
106
*/
107
- if (!ignfault) {
108
+ switch (mode) {
109
+ case STACK_NORMAL:
110
armv7m_nvic_set_pending_derived(env->nvic, exc, exc_secure);
111
+ break;
112
+ case STACK_LAZYFP:
113
+ armv7m_nvic_set_pending_lazyfp(env->nvic, exc, exc_secure);
114
+ break;
115
+ case STACK_IGNFAULTS:
116
+ break;
117
}
118
return false;
119
}
120
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
121
uint32_t limit;
122
bool want_psp;
123
uint32_t sig;
124
+ StackingMode smode = ignore_faults ? STACK_IGNFAULTS : STACK_NORMAL;
125
126
if (dotailchain) {
127
bool mode = lr & R_V7M_EXCRET_MODE_MASK;
128
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
129
*/
130
sig = v7m_integrity_sig(env, lr);
131
stacked_ok =
132
- v7m_stack_write(cpu, frameptr, sig, mmu_idx, ignore_faults) &&
133
- v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
134
- ignore_faults) &&
135
- v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
136
- ignore_faults) &&
137
- v7m_stack_write(cpu, frameptr + 0x10, env->regs[6], mmu_idx,
138
- ignore_faults) &&
139
- v7m_stack_write(cpu, frameptr + 0x14, env->regs[7], mmu_idx,
140
- ignore_faults) &&
141
- v7m_stack_write(cpu, frameptr + 0x18, env->regs[8], mmu_idx,
142
- ignore_faults) &&
143
- v7m_stack_write(cpu, frameptr + 0x1c, env->regs[9], mmu_idx,
144
- ignore_faults) &&
145
- v7m_stack_write(cpu, frameptr + 0x20, env->regs[10], mmu_idx,
146
- ignore_faults) &&
147
- v7m_stack_write(cpu, frameptr + 0x24, env->regs[11], mmu_idx,
148
- ignore_faults);
149
+ v7m_stack_write(cpu, frameptr, sig, mmu_idx, smode) &&
150
+ v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx, smode) &&
151
+ v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx, smode) &&
152
+ v7m_stack_write(cpu, frameptr + 0x10, env->regs[6], mmu_idx, smode) &&
153
+ v7m_stack_write(cpu, frameptr + 0x14, env->regs[7], mmu_idx, smode) &&
154
+ v7m_stack_write(cpu, frameptr + 0x18, env->regs[8], mmu_idx, smode) &&
155
+ v7m_stack_write(cpu, frameptr + 0x1c, env->regs[9], mmu_idx, smode) &&
156
+ v7m_stack_write(cpu, frameptr + 0x20, env->regs[10], mmu_idx, smode) &&
157
+ v7m_stack_write(cpu, frameptr + 0x24, env->regs[11], mmu_idx, smode);
158
159
/* Update SP regardless of whether any of the stack accesses failed. */
160
*frame_sp_p = frameptr;
161
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
162
* if it has higher priority).
163
*/
164
stacked_ok = stacked_ok &&
165
- v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, false) &&
166
- v7m_stack_write(cpu, frameptr + 4, env->regs[1], mmu_idx, false) &&
167
- v7m_stack_write(cpu, frameptr + 8, env->regs[2], mmu_idx, false) &&
168
- v7m_stack_write(cpu, frameptr + 12, env->regs[3], mmu_idx, false) &&
169
- v7m_stack_write(cpu, frameptr + 16, env->regs[12], mmu_idx, false) &&
170
- v7m_stack_write(cpu, frameptr + 20, env->regs[14], mmu_idx, false) &&
171
- v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
172
- v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
173
+ v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, STACK_NORMAL) &&
174
+ v7m_stack_write(cpu, frameptr + 4, env->regs[1],
175
+ mmu_idx, STACK_NORMAL) &&
176
+ v7m_stack_write(cpu, frameptr + 8, env->regs[2],
177
+ mmu_idx, STACK_NORMAL) &&
178
+ v7m_stack_write(cpu, frameptr + 12, env->regs[3],
179
+ mmu_idx, STACK_NORMAL) &&
180
+ v7m_stack_write(cpu, frameptr + 16, env->regs[12],
181
+ mmu_idx, STACK_NORMAL) &&
182
+ v7m_stack_write(cpu, frameptr + 20, env->regs[14],
183
+ mmu_idx, STACK_NORMAL) &&
184
+ v7m_stack_write(cpu, frameptr + 24, env->regs[15],
185
+ mmu_idx, STACK_NORMAL) &&
186
+ v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, STACK_NORMAL);
187
188
if (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) {
189
/* FPU is active, try to save its registers */
190
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
191
faddr += 8; /* skip the slot for the FPSCR */
192
}
193
stacked_ok = stacked_ok &&
194
- v7m_stack_write(cpu, faddr, slo, mmu_idx, false) &&
195
- v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, false);
196
+ v7m_stack_write(cpu, faddr, slo,
197
+ mmu_idx, STACK_NORMAL) &&
198
+ v7m_stack_write(cpu, faddr + 4, shi,
199
+ mmu_idx, STACK_NORMAL);
200
}
201
stacked_ok = stacked_ok &&
202
v7m_stack_write(cpu, frameptr + 0x60,
203
- vfp_get_fpscr(env), mmu_idx, false);
204
+ vfp_get_fpscr(env), mmu_idx, STACK_NORMAL);
205
if (cpacr_pass) {
206
for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
207
*aa32_vfp_dreg(env, i / 2) = 0;
208
--
209
2.20.1
210
211
diff view generated by jsdifflib
New patch
1
1
The M-profile architecture floating point system supports
2
lazy FP state preservation, where FP registers are not
3
pushed to the stack when an exception occurs but are instead
4
only saved if and when the first FP instruction in the exception
5
handler is executed. Implement this in QEMU, corresponding
6
to the check of LSPACT in the pseudocode ExecuteFPCheck().
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20190416125744.27770-24-peter.maydell@linaro.org
11
---
12
target/arm/cpu.h | 3 ++
13
target/arm/helper.h | 2 +
14
target/arm/translate.h | 1 +
15
target/arm/helper.c | 112 +++++++++++++++++++++++++++++++++++++++++
16
target/arm/translate.c | 22 ++++++++
17
5 files changed, 140 insertions(+)
18
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@
24
#define EXCP_NOCP 17 /* v7M NOCP UsageFault */
25
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
26
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
27
+#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
28
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
29
30
#define ARMV7M_EXCP_RESET 1
31
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
32
FIELD(TBFLAG_A32, VFPEN, 7, 1)
33
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
34
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
35
+/* For M profile only, set if FPCCR.LSPACT is set */
36
+FIELD(TBFLAG_A32, LSPACT, 18, 1)
37
/* For M profile only, set if we must create a new FP context */
38
FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
39
/* For M profile only, set if FPCCR.S does not match current security state */
40
diff --git a/target/arm/helper.h b/target/arm/helper.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/helper.h
43
+++ b/target/arm/helper.h
44
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(v7m_blxns, void, env, i32)
45
46
DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
47
48
+DEF_HELPER_1(v7m_preserve_fp_state, void, env)
49
+
50
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
51
52
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
53
diff --git a/target/arm/translate.h b/target/arm/translate.h
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/translate.h
56
+++ b/target/arm/translate.h
57
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
58
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
59
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
60
bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
61
+ bool v7m_lspact; /* FPCCR.LSPACT set */
62
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
63
* so that top level loop can generate correct syndrome information.
64
*/
65
diff --git a/target/arm/helper.c b/target/arm/helper.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/helper.c
68
+++ b/target/arm/helper.c
69
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
70
g_assert_not_reached();
71
}
72
73
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
74
+{
75
+ /* translate.c should never generate calls here in user-only mode */
76
+ g_assert_not_reached();
77
+}
78
+
79
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
80
{
81
/* The TT instructions can be used by unprivileged code, but in
82
@@ -XXX,XX +XXX,XX @@ pend_fault:
83
return false;
84
}
85
86
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
87
+{
88
+ /*
89
+ * Preserve FP state (because LSPACT was set and we are about
90
+ * to execute an FP instruction). This corresponds to the
91
+ * PreserveFPState() pseudocode.
92
+ * We may throw an exception if the stacking fails.
93
+ */
94
+ ARMCPU *cpu = arm_env_get_cpu(env);
95
+ bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
96
+ bool negpri = !(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_HFRDY_MASK);
97
+ bool is_priv = !(env->v7m.fpccr[is_secure] & R_V7M_FPCCR_USER_MASK);
98
+ bool splimviol = env->v7m.fpccr[is_secure] & R_V7M_FPCCR_SPLIMVIOL_MASK;
99
+ uint32_t fpcar = env->v7m.fpcar[is_secure];
100
+ bool stacked_ok = true;
101
+ bool ts = is_secure && (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
102
+ bool take_exception;
103
+
104
+ /* Take the iothread lock as we are going to touch the NVIC */
105
+ qemu_mutex_lock_iothread();
106
+
107
+ /* Check the background context had access to the FPU */
108
+ if (!v7m_cpacr_pass(env, is_secure, is_priv)) {
109
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, is_secure);
110
+ env->v7m.cfsr[is_secure] |= R_V7M_CFSR_NOCP_MASK;
111
+ stacked_ok = false;
112
+ } else if (!is_secure && !extract32(env->v7m.nsacr, 10, 1)) {
113
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
114
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
115
+ stacked_ok = false;
116
+ }
117
+
118
+ if (!splimviol && stacked_ok) {
119
+ /* We only stack if the stack limit wasn't violated */
120
+ int i;
121
+ ARMMMUIdx mmu_idx;
122
+
123
+ mmu_idx = arm_v7m_mmu_idx_all(env, is_secure, is_priv, negpri);
124
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
125
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
126
+ uint32_t faddr = fpcar + 4 * i;
127
+ uint32_t slo = extract64(dn, 0, 32);
128
+ uint32_t shi = extract64(dn, 32, 32);
129
+
130
+ if (i >= 16) {
131
+ faddr += 8; /* skip the slot for the FPSCR */
132
+ }
133
+ stacked_ok = stacked_ok &&
134
+ v7m_stack_write(cpu, faddr, slo, mmu_idx, STACK_LAZYFP) &&
135
+ v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, STACK_LAZYFP);
136
+ }
137
+
138
+ stacked_ok = stacked_ok &&
139
+ v7m_stack_write(cpu, fpcar + 0x40,
140
+ vfp_get_fpscr(env), mmu_idx, STACK_LAZYFP);
141
+ }
142
+
143
+ /*
144
+ * We definitely pended an exception, but it's possible that it
145
+ * might not be able to be taken now. If its priority permits us
146
+ * to take it now, then we must not update the LSPACT or FP regs,
147
+ * but instead jump out to take the exception immediately.
148
+ * If it's just pending and won't be taken until the current
149
+ * handler exits, then we do update LSPACT and the FP regs.
150
+ */
151
+ take_exception = !stacked_ok &&
152
+ armv7m_nvic_can_take_pending_exception(env->nvic);
153
+
154
+ qemu_mutex_unlock_iothread();
155
+
156
+ if (take_exception) {
157
+ raise_exception_ra(env, EXCP_LAZYFP, 0, 1, GETPC());
158
+ }
159
+
160
+ env->v7m.fpccr[is_secure] &= ~R_V7M_FPCCR_LSPACT_MASK;
161
+
162
+ if (ts) {
163
+ /* Clear s0 to s31 and the FPSCR */
164
+ int i;
165
+
166
+ for (i = 0; i < 32; i += 2) {
167
+ *aa32_vfp_dreg(env, i / 2) = 0;
168
+ }
169
+ vfp_set_fpscr(env, 0);
170
+ }
171
+ /*
172
+ * Otherwise s0 to s15 and FPSCR are UNKNOWN; we choose to leave them
173
+ * unchanged.
174
+ */
175
+}
176
+
177
/* Write to v7M CONTROL.SPSEL bit for the specified security bank.
178
* This may change the current stack pointer between Main and Process
179
* stack pointers if it is done for the CONTROL register for the current
180
@@ -XXX,XX +XXX,XX @@ static void arm_log_exception(int idx)
181
[EXCP_NOCP] = "v7M NOCP UsageFault",
182
[EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
183
[EXCP_STKOF] = "v8M STKOF UsageFault",
184
+ [EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
185
};
186
187
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
188
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
189
return;
190
}
191
break;
192
+ case EXCP_LAZYFP:
193
+ /*
194
+ * We already pended the specific exception in the NVIC in the
195
+ * v7m_preserve_fp_state() helper function.
196
+ */
197
+ break;
198
default:
199
cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
200
return; /* Never happens. Keep compiler happy. */
201
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
202
flags = FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED, 1);
203
}
204
205
+ if (arm_feature(env, ARM_FEATURE_M)) {
206
+ bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
207
+
208
+ if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) {
209
+ flags = FIELD_DP32(flags, TBFLAG_A32, LSPACT, 1);
210
+ }
211
+ }
212
+
213
*pflags = flags;
214
*cs_base = 0;
215
}
216
diff --git a/target/arm/translate.c b/target/arm/translate.c
217
index XXXXXXX..XXXXXXX 100644
218
--- a/target/arm/translate.c
219
+++ b/target/arm/translate.c
220
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
221
if (arm_dc_feature(s, ARM_FEATURE_M)) {
222
/* Handle M-profile lazy FP state mechanics */
223
224
+ /* Trigger lazy-state preservation if necessary */
225
+ if (s->v7m_lspact) {
226
+ /*
227
+ * Lazy state saving affects external memory and also the NVIC,
228
+ * so we must mark it as an IO operation for icount.
229
+ */
230
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
231
+ gen_io_start();
232
+ }
233
+ gen_helper_v7m_preserve_fp_state(cpu_env);
234
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
235
+ gen_io_end();
236
+ }
237
+ /*
238
+ * If the preserve_fp_state helper doesn't throw an exception
239
+ * then it will clear LSPACT; we don't need to repeat this for
240
+ * any further FP insns in this TB.
241
+ */
242
+ s->v7m_lspact = false;
243
+ }
244
+
245
/* Update ownership of FP context: set FPCCR.S to match current state */
246
if (s->v8m_fpccr_s_wrong) {
247
TCGv_i32 tmp;
248
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
249
dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
250
dc->v7m_new_fp_ctxt_needed =
251
FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
252
+ dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_A32, LSPACT);
253
dc->cp_regs = cpu->cp_regs;
254
dc->features = env->features;
255
256
--
257
2.20.1
258
259
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the VLSTM instruction for v7M for the FPU present case.
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20180211205848.4568-3-richard.henderson@linaro.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-25-peter.maydell@linaro.org
7
---
6
---
8
target/arm/cpu.h | 35 ++++++++++++++++++-----------------
7
target/arm/cpu.h | 2 +
9
target/arm/helper.c | 6 ++++--
8
target/arm/helper.h | 2 +
10
target/arm/translate-a64.c | 3 +++
9
target/arm/helper.c | 84 ++++++++++++++++++++++++++++++++++++++++++
11
3 files changed, 25 insertions(+), 19 deletions(-)
10
target/arm/translate.c | 15 +++++++-
11
4 files changed, 102 insertions(+), 1 deletion(-)
12
12
13
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
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
15
--- a/target/arm/cpu.h
16
+++ b/target/arm/cpu.h
16
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
17
@@ -XXX,XX +XXX,XX @@
18
}
18
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
19
19
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
20
/* ARMCPRegInfo type field bits. If the SPECIAL bit is set this is a
20
#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
21
- * special-behaviour cp reg and bits [15..8] indicate what behaviour
21
+#define EXCP_LSERR 21 /* v8M LSERR SecureFault */
22
+ * special-behaviour cp reg and bits [11..8] indicate what behaviour
22
+#define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */
23
* it has. Otherwise it is a simple cp reg, where CONST indicates that
23
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
24
* TCG can assume the value to be constant (ie load at translate time)
24
25
* and 64BIT indicates a 64 bit wide coprocessor register. SUPPRESS_TB_END
25
#define ARMV7M_EXCP_RESET 1
26
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
26
diff --git a/target/arm/helper.h b/target/arm/helper.h
27
* need to be surrounded by gen_io_start()/gen_io_end(). In particular,
27
index XXXXXXX..XXXXXXX 100644
28
* registers which implement clocks or timers require this.
28
--- a/target/arm/helper.h
29
*/
29
+++ b/target/arm/helper.h
30
-#define ARM_CP_SPECIAL 1
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
31
-#define ARM_CP_CONST 2
31
32
-#define ARM_CP_64BIT 4
32
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
33
-#define ARM_CP_SUPPRESS_TB_END 8
33
34
-#define ARM_CP_OVERRIDE 16
34
+DEF_HELPER_2(v7m_vlstm, void, env, i32)
35
-#define ARM_CP_ALIAS 32
35
+
36
-#define ARM_CP_IO 64
36
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
37
-#define ARM_CP_NO_RAW 128
37
38
-#define ARM_CP_NOP (ARM_CP_SPECIAL | (1 << 8))
38
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
39
-#define ARM_CP_WFI (ARM_CP_SPECIAL | (2 << 8))
40
-#define ARM_CP_NZCV (ARM_CP_SPECIAL | (3 << 8))
41
-#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | (4 << 8))
42
-#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | (5 << 8))
43
-#define ARM_LAST_SPECIAL ARM_CP_DC_ZVA
44
+#define ARM_CP_SPECIAL 0x0001
45
+#define ARM_CP_CONST 0x0002
46
+#define ARM_CP_64BIT 0x0004
47
+#define ARM_CP_SUPPRESS_TB_END 0x0008
48
+#define ARM_CP_OVERRIDE 0x0010
49
+#define ARM_CP_ALIAS 0x0020
50
+#define ARM_CP_IO 0x0040
51
+#define ARM_CP_NO_RAW 0x0080
52
+#define ARM_CP_NOP (ARM_CP_SPECIAL | 0x0100)
53
+#define ARM_CP_WFI (ARM_CP_SPECIAL | 0x0200)
54
+#define ARM_CP_NZCV (ARM_CP_SPECIAL | 0x0300)
55
+#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | 0x0400)
56
+#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | 0x0500)
57
+#define ARM_LAST_SPECIAL ARM_CP_DC_ZVA
58
+#define ARM_CP_FPU 0x1000
59
/* Used only as a terminator for ARMCPRegInfo lists */
60
-#define ARM_CP_SENTINEL 0xffff
61
+#define ARM_CP_SENTINEL 0xffff
62
/* Mask of only the flag bits in a type field */
63
-#define ARM_CP_FLAG_MASK 0xff
64
+#define ARM_CP_FLAG_MASK 0x10ff
65
66
/* Valid values for ARMCPRegInfo state field, indicating which of
67
* the AArch32 and AArch64 execution states this register is visible in.
68
diff --git a/target/arm/helper.c b/target/arm/helper.c
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
69
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/helper.c
41
--- a/target/arm/helper.c
71
+++ b/target/arm/helper.c
42
+++ b/target/arm/helper.c
72
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
43
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
73
.writefn = aa64_daif_write, .resetfn = arm_cp_reset_ignore },
44
g_assert_not_reached();
74
{ .name = "FPCR", .state = ARM_CP_STATE_AA64,
45
}
75
.opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 4,
46
76
- .access = PL0_RW, .readfn = aa64_fpcr_read, .writefn = aa64_fpcr_write },
47
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
77
+ .access = PL0_RW, .type = ARM_CP_FPU,
48
+{
78
+ .readfn = aa64_fpcr_read, .writefn = aa64_fpcr_write },
49
+ /* translate.c should never generate calls here in user-only mode */
79
{ .name = "FPSR", .state = ARM_CP_STATE_AA64,
50
+ g_assert_not_reached();
80
.opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 4,
51
+}
81
- .access = PL0_RW, .readfn = aa64_fpsr_read, .writefn = aa64_fpsr_write },
52
+
82
+ .access = PL0_RW, .type = ARM_CP_FPU,
53
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
83
+ .readfn = aa64_fpsr_read, .writefn = aa64_fpsr_write },
54
{
84
{ .name = "DCZID_EL0", .state = ARM_CP_STATE_AA64,
55
/* The TT instructions can be used by unprivileged code, but in
85
.opc0 = 3, .opc1 = 3, .opc2 = 7, .crn = 0, .crm = 0,
56
@@ -XXX,XX +XXX,XX @@ static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
86
.access = PL0_R, .type = ARM_CP_NO_RAW,
87
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/target/arm/translate-a64.c
90
+++ b/target/arm/translate-a64.c
91
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
92
default:
93
break;
94
}
57
}
95
+ if ((ri->type & ARM_CP_FPU) && !fp_access_check(s)) {
58
}
59
60
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
61
+{
62
+ /* fptr is the value of Rn, the frame pointer we store the FP regs to */
63
+ bool s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
64
+ bool lspact = env->v7m.fpccr[s] & R_V7M_FPCCR_LSPACT_MASK;
65
+
66
+ assert(env->v7m.secure);
67
+
68
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
96
+ return;
69
+ return;
97
+ }
70
+ }
98
71
+
99
if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
72
+ /* Check access to the coprocessor is permitted */
100
gen_io_start();
73
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
74
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
75
+ }
76
+
77
+ if (lspact) {
78
+ /* LSPACT should not be active when there is active FP state */
79
+ raise_exception_ra(env, EXCP_LSERR, 0, 1, GETPC());
80
+ }
81
+
82
+ if (fptr & 7) {
83
+ raise_exception_ra(env, EXCP_UNALIGNED, 0, 1, GETPC());
84
+ }
85
+
86
+ /*
87
+ * Note that we do not use v7m_stack_write() here, because the
88
+ * accesses should not set the FSR bits for stacking errors if they
89
+ * fail. (In pseudocode terms, they are AccType_NORMAL, not AccType_STACK
90
+ * or AccType_LAZYFP). Faults in cpu_stl_data() will throw exceptions
91
+ * and longjmp out.
92
+ */
93
+ if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) {
94
+ bool ts = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK;
95
+ int i;
96
+
97
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
98
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
99
+ uint32_t faddr = fptr + 4 * i;
100
+ uint32_t slo = extract64(dn, 0, 32);
101
+ uint32_t shi = extract64(dn, 32, 32);
102
+
103
+ if (i >= 16) {
104
+ faddr += 8; /* skip the slot for the FPSCR */
105
+ }
106
+ cpu_stl_data(env, faddr, slo);
107
+ cpu_stl_data(env, faddr + 4, shi);
108
+ }
109
+ cpu_stl_data(env, fptr + 0x40, vfp_get_fpscr(env));
110
+
111
+ /*
112
+ * If TS is 0 then s0 to s15 and FPSCR are UNKNOWN; we choose to
113
+ * leave them unchanged, matching our choice in v7m_preserve_fp_state.
114
+ */
115
+ if (ts) {
116
+ for (i = 0; i < 32; i += 2) {
117
+ *aa32_vfp_dreg(env, i / 2) = 0;
118
+ }
119
+ vfp_set_fpscr(env, 0);
120
+ }
121
+ } else {
122
+ v7m_update_fpccr(env, fptr, false);
123
+ }
124
+
125
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
126
+}
127
+
128
static bool v7m_push_stack(ARMCPU *cpu)
129
{
130
/* Do the "set up stack frame" part of exception entry,
131
@@ -XXX,XX +XXX,XX @@ static void arm_log_exception(int idx)
132
[EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
133
[EXCP_STKOF] = "v8M STKOF UsageFault",
134
[EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
135
+ [EXCP_LSERR] = "v8M LSERR UsageFault",
136
+ [EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
137
};
138
139
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
140
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
141
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
142
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_STKOF_MASK;
143
break;
144
+ case EXCP_LSERR:
145
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
146
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
147
+ break;
148
+ case EXCP_UNALIGNED:
149
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
150
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNALIGNED_MASK;
151
+ break;
152
case EXCP_SWI:
153
/* The PC already points to the next instruction. */
154
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC, env->v7m.secure);
155
diff --git a/target/arm/translate.c b/target/arm/translate.c
156
index XXXXXXX..XXXXXXX 100644
157
--- a/target/arm/translate.c
158
+++ b/target/arm/translate.c
159
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
160
if (!s->v8m_secure || (insn & 0x0040f0ff)) {
161
goto illegal_op;
162
}
163
- /* Just NOP since FP support is not implemented */
164
+
165
+ if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
166
+ TCGv_i32 fptr = load_reg(s, rn);
167
+
168
+ if (extract32(insn, 20, 1)) {
169
+ /* VLLDM */
170
+ } else {
171
+ gen_helper_v7m_vlstm(cpu_env, fptr);
172
+ }
173
+ tcg_temp_free_i32(fptr);
174
+
175
+ /* End the TB, because we have updated FP control bits */
176
+ s->base.is_jmp = DISAS_UPDATE;
177
+ }
178
break;
179
}
180
if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
101
--
181
--
102
2.16.1
182
2.20.1
103
183
104
184
diff view generated by jsdifflib
New patch
1
Implement the VLLDM instruction for v7M for the FPU present cas.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-26-peter.maydell@linaro.org
6
---
7
target/arm/helper.h | 1 +
8
target/arm/helper.c | 54 ++++++++++++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 2 +-
10
3 files changed, 56 insertions(+), 1 deletion(-)
11
12
diff --git a/target/arm/helper.h b/target/arm/helper.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.h
15
+++ b/target/arm/helper.h
16
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
17
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
18
19
DEF_HELPER_2(v7m_vlstm, void, env, i32)
20
+DEF_HELPER_2(v7m_vlldm, void, env, i32)
21
22
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
23
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.c
27
+++ b/target/arm/helper.c
28
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
29
g_assert_not_reached();
30
}
31
32
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
33
+{
34
+ /* translate.c should never generate calls here in user-only mode */
35
+ g_assert_not_reached();
36
+}
37
+
38
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
39
{
40
/* The TT instructions can be used by unprivileged code, but in
41
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
42
env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
43
}
44
45
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
46
+{
47
+ /* fptr is the value of Rn, the frame pointer we load the FP regs from */
48
+ assert(env->v7m.secure);
49
+
50
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
51
+ return;
52
+ }
53
+
54
+ /* Check access to the coprocessor is permitted */
55
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
56
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
57
+ }
58
+
59
+ if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
60
+ /* State in FP is still valid */
61
+ env->v7m.fpccr[M_REG_S] &= ~R_V7M_FPCCR_LSPACT_MASK;
62
+ } else {
63
+ bool ts = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK;
64
+ int i;
65
+ uint32_t fpscr;
66
+
67
+ if (fptr & 7) {
68
+ raise_exception_ra(env, EXCP_UNALIGNED, 0, 1, GETPC());
69
+ }
70
+
71
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
72
+ uint32_t slo, shi;
73
+ uint64_t dn;
74
+ uint32_t faddr = fptr + 4 * i;
75
+
76
+ if (i >= 16) {
77
+ faddr += 8; /* skip the slot for the FPSCR */
78
+ }
79
+
80
+ slo = cpu_ldl_data(env, faddr);
81
+ shi = cpu_ldl_data(env, faddr + 4);
82
+
83
+ dn = (uint64_t) shi << 32 | slo;
84
+ *aa32_vfp_dreg(env, i / 2) = dn;
85
+ }
86
+ fpscr = cpu_ldl_data(env, fptr + 0x40);
87
+ vfp_set_fpscr(env, fpscr);
88
+ }
89
+
90
+ env->v7m.control[M_REG_S] |= R_V7M_CONTROL_FPCA_MASK;
91
+}
92
+
93
static bool v7m_push_stack(ARMCPU *cpu)
94
{
95
/* Do the "set up stack frame" part of exception entry,
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate.c
99
+++ b/target/arm/translate.c
100
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
101
TCGv_i32 fptr = load_reg(s, rn);
102
103
if (extract32(insn, 20, 1)) {
104
- /* VLLDM */
105
+ gen_helper_v7m_vlldm(cpu_env, fptr);
106
} else {
107
gen_helper_v7m_vlstm(cpu_env, fptr);
108
}
109
--
110
2.20.1
111
112
diff view generated by jsdifflib
1
Instead of hardcoding the values of M profile ID registers in the
1
Enable the FPU by default for the Cortex-M4 and Cortex-M33.
2
NVIC, use the fields in the CPU struct. This will allow us to
3
give different M profile CPU types different ID register values.
4
5
This commit includes the addition of the missing ID_ISAR5,
6
which exists as RES0 in both v7M and v8M.
7
8
(The values of the ID registers might be wrong for the M4 --
9
this commit leaves the behaviour there unchanged.)
10
2
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20180209165810.6668-2-peter.maydell@linaro.org
5
Message-id: 20190416125744.27770-27-peter.maydell@linaro.org
15
---
6
---
16
hw/intc/armv7m_nvic.c | 30 ++++++++++++++++--------------
7
target/arm/cpu.c | 8 ++++++++
17
target/arm/cpu.c | 28 ++++++++++++++++++++++++++++
8
1 file changed, 8 insertions(+)
18
2 files changed, 44 insertions(+), 14 deletions(-)
19
9
20
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/intc/armv7m_nvic.c
23
+++ b/hw/intc/armv7m_nvic.c
24
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
25
"Aux Fault status registers unimplemented\n");
26
return 0;
27
case 0xd40: /* PFR0. */
28
- return 0x00000030;
29
- case 0xd44: /* PRF1. */
30
- return 0x00000200;
31
+ return cpu->id_pfr0;
32
+ case 0xd44: /* PFR1. */
33
+ return cpu->id_pfr1;
34
case 0xd48: /* DFR0. */
35
- return 0x00100000;
36
+ return cpu->id_dfr0;
37
case 0xd4c: /* AFR0. */
38
- return 0x00000000;
39
+ return cpu->id_afr0;
40
case 0xd50: /* MMFR0. */
41
- return 0x00000030;
42
+ return cpu->id_mmfr0;
43
case 0xd54: /* MMFR1. */
44
- return 0x00000000;
45
+ return cpu->id_mmfr1;
46
case 0xd58: /* MMFR2. */
47
- return 0x00000000;
48
+ return cpu->id_mmfr2;
49
case 0xd5c: /* MMFR3. */
50
- return 0x00000000;
51
+ return cpu->id_mmfr3;
52
case 0xd60: /* ISAR0. */
53
- return 0x01141110;
54
+ return cpu->id_isar0;
55
case 0xd64: /* ISAR1. */
56
- return 0x02111000;
57
+ return cpu->id_isar1;
58
case 0xd68: /* ISAR2. */
59
- return 0x21112231;
60
+ return cpu->id_isar2;
61
case 0xd6c: /* ISAR3. */
62
- return 0x01111110;
63
+ return cpu->id_isar3;
64
case 0xd70: /* ISAR4. */
65
- return 0x01310102;
66
+ return cpu->id_isar4;
67
+ case 0xd74: /* ISAR5. */
68
+ return cpu->id_isar5;
69
/* TODO: Implement debug registers. */
70
case 0xd90: /* MPU_TYPE */
71
/* Unified MPU; if the MPU is not present this value is zero */
72
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
10
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
73
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/cpu.c
12
--- a/target/arm/cpu.c
75
+++ b/target/arm/cpu.c
13
+++ b/target/arm/cpu.c
76
@@ -XXX,XX +XXX,XX @@ static void cortex_m3_initfn(Object *obj)
14
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
77
set_feature(&cpu->env, ARM_FEATURE_M);
15
set_feature(&cpu->env, ARM_FEATURE_M);
78
cpu->midr = 0x410fc231;
16
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
79
cpu->pmsav7_dregion = 8;
80
+ cpu->id_pfr0 = 0x00000030;
81
+ cpu->id_pfr1 = 0x00000200;
82
+ cpu->id_dfr0 = 0x00100000;
83
+ cpu->id_afr0 = 0x00000000;
84
+ cpu->id_mmfr0 = 0x00000030;
85
+ cpu->id_mmfr1 = 0x00000000;
86
+ cpu->id_mmfr2 = 0x00000000;
87
+ cpu->id_mmfr3 = 0x00000000;
88
+ cpu->id_isar0 = 0x01141110;
89
+ cpu->id_isar1 = 0x02111000;
90
+ cpu->id_isar2 = 0x21112231;
91
+ cpu->id_isar3 = 0x01111110;
92
+ cpu->id_isar4 = 0x01310102;
93
+ cpu->id_isar5 = 0x00000000;
94
}
95
96
static void cortex_m4_initfn(Object *obj)
97
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
98
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
17
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
18
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
99
cpu->midr = 0x410fc240; /* r0p0 */
19
cpu->midr = 0x410fc240; /* r0p0 */
100
cpu->pmsav7_dregion = 8;
20
cpu->pmsav7_dregion = 8;
101
+ cpu->id_pfr0 = 0x00000030;
21
+ cpu->isar.mvfr0 = 0x10110021;
102
+ cpu->id_pfr1 = 0x00000200;
22
+ cpu->isar.mvfr1 = 0x11000011;
103
+ cpu->id_dfr0 = 0x00100000;
23
+ cpu->isar.mvfr2 = 0x00000000;
104
+ cpu->id_afr0 = 0x00000000;
24
cpu->id_pfr0 = 0x00000030;
105
+ cpu->id_mmfr0 = 0x00000030;
25
cpu->id_pfr1 = 0x00000200;
106
+ cpu->id_mmfr1 = 0x00000000;
26
cpu->id_dfr0 = 0x00100000;
107
+ cpu->id_mmfr2 = 0x00000000;
27
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
108
+ cpu->id_mmfr3 = 0x00000000;
28
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
109
+ cpu->id_isar0 = 0x01141110;
29
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
110
+ cpu->id_isar1 = 0x02111000;
30
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
111
+ cpu->id_isar2 = 0x21112231;
31
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
112
+ cpu->id_isar3 = 0x01111110;
32
cpu->midr = 0x410fd213; /* r0p3 */
113
+ cpu->id_isar4 = 0x01310102;
33
cpu->pmsav7_dregion = 16;
114
+ cpu->id_isar5 = 0x00000000;
34
cpu->sau_sregion = 8;
115
}
35
+ cpu->isar.mvfr0 = 0x10110021;
116
36
+ cpu->isar.mvfr1 = 0x11000011;
117
static void arm_v7m_class_init(ObjectClass *oc, void *data)
37
+ cpu->isar.mvfr2 = 0x00000040;
38
cpu->id_pfr0 = 0x00000030;
39
cpu->id_pfr1 = 0x00000210;
40
cpu->id_dfr0 = 0x00200000;
118
--
41
--
119
2.16.1
42
2.20.1
120
43
121
44
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
2
3
This device is used by both ARM (BCM2836, for raspi2) and AArch64
4
(BCM2837, for raspi3) targets, and is not CPU-specific.
5
Move it to common object, so we build it once for all targets.
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190427133028.12874-1-philmd@redhat.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/dma/Makefile.objs | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/hw/dma/Makefile.objs b/hw/dma/Makefile.objs
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/dma/Makefile.objs
18
+++ b/hw/dma/Makefile.objs
19
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zdma.o
20
21
obj-$(CONFIG_OMAP) += omap_dma.o soc_dma.o
22
obj-$(CONFIG_PXA2XX) += pxa2xx_dma.o
23
-obj-$(CONFIG_RASPI) += bcm2835_dma.o
24
+common-obj-$(CONFIG_RASPI) += bcm2835_dma.o
25
--
26
2.20.1
27
28
diff view generated by jsdifflib
1
From: Pekka Enberg <penberg@iki.fi>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
This patch adds a "cpu-type" property to BCM2836 SoC in preparation for
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
reusing the code for the Raspberry Pi 3, which has a different processor
4
Reviewed-by: Cédric Le Goater <clg@kaod.org>
5
model.
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
6
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Signed-off-by: Pekka Enberg <penberg@iki.fi>
7
Message-id: 20190412165416.7977-2-philmd@redhat.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
include/hw/arm/bcm2836.h | 1 +
10
hw/arm/aspeed.c | 13 +++++++++----
12
hw/arm/bcm2836.c | 17 +++++++++--------
11
1 file changed, 9 insertions(+), 4 deletions(-)
13
hw/arm/raspi.c | 3 +++
14
3 files changed, 13 insertions(+), 8 deletions(-)
15
12
16
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
13
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/bcm2836.h
15
--- a/hw/arm/aspeed.c
19
+++ b/include/hw/arm/bcm2836.h
16
+++ b/hw/arm/aspeed.c
20
@@ -XXX,XX +XXX,XX @@ typedef struct BCM2836State {
21
DeviceState parent_obj;
22
/*< public >*/
23
24
+ char *cpu_type;
25
uint32_t enabled_cpus;
26
27
ARMCPU cpus[BCM2836_NCPUS];
28
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/bcm2836.c
31
+++ b/hw/arm/bcm2836.c
32
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@
33
static void bcm2836_init(Object *obj)
18
#include "hw/arm/aspeed_soc.h"
34
{
19
#include "hw/boards.h"
35
BCM2836State *s = BCM2836(obj);
20
#include "hw/i2c/smbus_eeprom.h"
36
- int n;
21
+#include "hw/misc/pca9552.h"
37
-
22
+#include "hw/misc/tmp105.h"
38
- for (n = 0; n < BCM2836_NCPUS; n++) {
23
#include "qemu/log.h"
39
- object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
24
#include "sysemu/block-backend.h"
40
- "cortex-a15-" TYPE_ARM_CPU);
25
#include "hw/loader.h"
41
- object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
26
@@ -XXX,XX +XXX,XX @@ static void ast2500_evb_i2c_init(AspeedBoardState *bmc)
42
- &error_abort);
27
eeprom_buf);
43
- }
28
44
29
/* The AST2500 EVB expects a LM75 but a TMP105 is compatible */
45
object_initialize(&s->control, sizeof(s->control), TYPE_BCM2836_CONTROL);
30
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7), "tmp105", 0x4d);
46
object_property_add_child(obj, "control", OBJECT(&s->control), NULL);
31
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7),
47
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
32
+ TYPE_TMP105, 0x4d);
48
33
49
/* common peripherals from bcm2835 */
34
/* The AST2500 EVB does not have an RTC. Let's pretend that one is
50
35
* plugged on the I2C bus header */
51
+ obj = OBJECT(dev);
36
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
52
+ for (n = 0; n < BCM2836_NCPUS; n++) {
37
AspeedSoCState *soc = &bmc->soc;
53
+ object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
38
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
54
+ s->cpu_type);
39
55
+ object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
40
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), "pca9552", 0x60);
56
+ &error_abort);
41
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), TYPE_PCA9552,
57
+ }
42
+ 0x60);
58
+
43
59
obj = object_property_get_link(OBJECT(dev), "ram", &err);
44
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), "tmp423", 0x4c);
60
if (obj == NULL) {
45
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 5), "tmp423", 0x4c);
61
error_setg(errp, "%s: required ram link not found: %s",
46
62
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
47
/* The Witherspoon expects a TMP275 but a TMP105 is compatible */
48
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), "tmp105", 0x4a);
49
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), TYPE_TMP105,
50
+ 0x4a);
51
52
/* The witherspoon board expects Epson RX8900 I2C RTC but a ds1338 is
53
* good enough */
54
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
55
56
smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), 0x51,
57
eeprom_buf);
58
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "pca9552",
59
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), TYPE_PCA9552,
60
0x60);
63
}
61
}
64
62
65
static Property bcm2836_props[] = {
66
+ DEFINE_PROP_STRING("cpu-type", BCM2836State, cpu_type),
67
DEFINE_PROP_UINT32("enabled-cpus", BCM2836State, enabled_cpus, BCM2836_NCPUS),
68
DEFINE_PROP_END_OF_LIST()
69
};
70
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/hw/arm/raspi.c
73
+++ b/hw/arm/raspi.c
74
@@ -XXX,XX +XXX,XX @@ static void raspi2_init(MachineState *machine)
75
/* Setup the SOC */
76
object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(&s->ram),
77
&error_abort);
78
+ object_property_set_str(OBJECT(&s->soc), machine->cpu_type, "cpu-type",
79
+ &error_abort);
80
object_property_set_int(OBJECT(&s->soc), smp_cpus, "enabled-cpus",
81
&error_abort);
82
object_property_set_int(OBJECT(&s->soc), 0xa21041, "board-rev",
83
@@ -XXX,XX +XXX,XX @@ static void raspi2_machine_init(MachineClass *mc)
84
mc->no_parallel = 1;
85
mc->no_floppy = 1;
86
mc->no_cdrom = 1;
87
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
88
mc->max_cpus = BCM2836_NCPUS;
89
mc->min_cpus = BCM2836_NCPUS;
90
mc->default_cpus = BCM2836_NCPUS;
91
--
63
--
92
2.16.1
64
2.20.1
93
65
94
66
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
(qemu) info mtree
3
Suggested-by: Markus Armbruster <armbru@redhat.com>
4
address-space: cpu-memory-0
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
0000000000000000-ffffffffffffffff (prio 0, i/o): system
5
Message-id: 20190412165416.7977-3-philmd@redhat.com
6
0000000000000000-0000000007ffffff (prio 0, rom): aspeed.boot_rom
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
000000001e600000-000000001e7fffff (prio -1, i/o): aspeed_soc.io
8
- 000000001e784000-000000001e78401f (prio 0, i/o): serial
9
000000001e620000-000000001e6200ff (prio 0, i/o): aspeed.smc.ast2500-fmc
10
000000001e630000-000000001e6300ff (prio 0, i/o): aspeed.smc.ast2500-spi1
11
[...]
12
000000001e720000-000000001e728fff (prio 0, ram): aspeed.sram
13
000000001e782000-000000001e782fff (prio 0, i/o): aspeed.timer
14
+ 000000001e784000-000000001e78401f (prio 0, i/o): serial
15
000000001e785000-000000001e78501f (prio 0, i/o): aspeed.wdt
16
000000001e785020-000000001e78503f (prio 0, i/o): aspeed.wdt
17
18
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Reviewed-by: Cédric Le Goater <clg@kaod.org>
20
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
21
Message-id: 20180209085755.30414-2-f4bug@amsat.org
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
---
8
---
24
hw/arm/aspeed_soc.c | 3 ++-
9
hw/arm/nseries.c | 3 ++-
25
1 file changed, 2 insertions(+), 1 deletion(-)
10
1 file changed, 2 insertions(+), 1 deletion(-)
26
11
27
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
12
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
28
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/aspeed_soc.c
14
--- a/hw/arm/nseries.c
30
+++ b/hw/arm/aspeed_soc.c
15
+++ b/hw/arm/nseries.c
31
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
16
@@ -XXX,XX +XXX,XX @@
32
/* UART - attach an 8250 to the IO space as our UART5 */
17
#include "hw/boards.h"
33
if (serial_hds[0]) {
18
#include "hw/i2c/i2c.h"
34
qemu_irq uart5 = qdev_get_gpio_in(DEVICE(&s->vic), uart_irqs[4]);
19
#include "hw/devices.h"
35
- serial_mm_init(&s->iomem, ASPEED_SOC_UART_5_BASE, 2,
20
+#include "hw/misc/tmp105.h"
36
+ serial_mm_init(get_system_memory(),
21
#include "hw/block/flash.h"
37
+ ASPEED_SOC_IOMEM_BASE + ASPEED_SOC_UART_5_BASE, 2,
22
#include "hw/hw.h"
38
uart5, 38400, serial_hds[0], DEVICE_LITTLE_ENDIAN);
23
#include "hw/bt.h"
39
}
24
@@ -XXX,XX +XXX,XX @@ static void n8x0_i2c_setup(struct n800_s *s)
25
qemu_register_powerdown_notifier(&n8x0_system_powerdown_notifier);
26
27
/* Attach a TMP105 PM chip (A0 wired to ground) */
28
- dev = i2c_create_slave(i2c, "tmp105", N8X0_TMP105_ADDR);
29
+ dev = i2c_create_slave(i2c, TYPE_TMP105, N8X0_TMP105_ADDR);
30
qdev_connect_gpio_out(dev, 0, tmp_irq);
31
}
40
32
41
--
33
--
42
2.16.1
34
2.20.1
43
35
44
36
diff view generated by jsdifflib
1
From: Pekka Enberg <penberg@iki.fi>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
This patch adds Raspberry Pi 3 support to hw/arm/raspi.c. The
3
No code used the tc6393xb_gpio_in_get() and tc6393xb_gpio_out_set()
4
differences to Pi 2 are:
4
functions since their introduction in commit 88d2c950b002. Time to
5
remove them.
5
6
6
- Firmware address
7
Suggested-by: Markus Armbruster <armbru@redhat.com>
7
- Board ID
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
- Board revision
9
Message-id: 20190412165416.7977-4-philmd@redhat.com
9
10
The CPU is different too, but that's going to be configured as part of
11
the machine default CPU when we introduce a new machine type.
12
13
The patch was written from scratch by me but the logic is similar to
14
Zoltán Baldaszti's previous work, which I used as a reference (with
15
permission from the author):
16
17
https://github.com/bztsrc/qemu-raspi3
18
19
Signed-off-by: Pekka Enberg <penberg@iki.fi>
20
[PMM: fixed trailing whitespace on one line]
21
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
---
12
---
24
hw/arm/raspi.c | 31 +++++++++++++++++++++----------
13
include/hw/devices.h | 3 ---
25
1 file changed, 21 insertions(+), 10 deletions(-)
14
hw/display/tc6393xb.c | 16 ----------------
15
2 files changed, 19 deletions(-)
26
16
27
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
28
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/raspi.c
19
--- a/include/hw/devices.h
30
+++ b/hw/arm/raspi.c
20
+++ b/include/hw/devices.h
31
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ void retu_key_event(void *retu, int state);
32
* Rasperry Pi 2 emulation Copyright (c) 2015, Microsoft
22
typedef struct TC6393xbState TC6393xbState;
33
* Written by Andrew Baumann
23
TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
34
*
24
uint32_t base, qemu_irq irq);
35
+ * Raspberry Pi 3 emulation Copyright (c) 2018 Zoltán Baldaszti
25
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
36
+ * Upstream code cleanup (c) 2018 Pekka Enberg
26
- qemu_irq handler);
37
+ *
27
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s);
38
* This code is licensed under the GNU GPLv2 and later.
28
qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
39
*/
29
40
30
#endif
41
@@ -XXX,XX +XXX,XX @@
31
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
42
#define SMPBOOT_ADDR 0x300 /* this should leave enough space for ATAGS */
32
index XXXXXXX..XXXXXXX 100644
43
#define MVBAR_ADDR 0x400 /* secure vectors */
33
--- a/hw/display/tc6393xb.c
44
#define BOARDSETUP_ADDR (MVBAR_ADDR + 0x20) /* board setup code */
34
+++ b/hw/display/tc6393xb.c
45
-#define FIRMWARE_ADDR 0x8000 /* Pi loads kernel.img here by default */
35
@@ -XXX,XX +XXX,XX @@ struct TC6393xbState {
46
+#define FIRMWARE_ADDR_2 0x8000 /* Pi 2 loads kernel.img here by default */
36
blanked : 1;
47
+#define FIRMWARE_ADDR_3 0x80000 /* Pi 3 loads kernel.img here by default */
37
};
48
38
49
/* Table of Linux board IDs for different Pi versions */
39
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s)
50
-static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43};
40
-{
51
+static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44};
41
- return s->gpio_in;
52
42
-}
53
typedef struct RasPiState {
43
-
54
BCM2836State soc;
44
static void tc6393xb_gpio_set(void *opaque, int line, int level)
55
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
45
{
56
binfo.secure_board_setup = true;
46
// TC6393xbState *s = opaque;
57
binfo.secure_boot = true;
47
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_gpio_set(void *opaque, int line, int level)
58
48
// FIXME: how does the chip reflect the GPIO input level change?
59
- /* Pi2 requires SMP setup */
60
- if (version == 2) {
61
+ /* Pi2 and Pi3 requires SMP setup */
62
+ if (version >= 2) {
63
binfo.smp_loader_start = SMPBOOT_ADDR;
64
binfo.write_secondary_boot = write_smpboot;
65
binfo.secondary_cpu_reset_hook = reset_secondary;
66
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
67
* the normal Linux boot process
68
*/
69
if (machine->firmware) {
70
+ hwaddr firmware_addr = version == 3 ? FIRMWARE_ADDR_3 : FIRMWARE_ADDR_2;
71
/* load the firmware image (typically kernel.img) */
72
- r = load_image_targphys(machine->firmware, FIRMWARE_ADDR,
73
- ram_size - FIRMWARE_ADDR);
74
+ r = load_image_targphys(machine->firmware, firmware_addr,
75
+ ram_size - firmware_addr);
76
if (r < 0) {
77
error_report("Failed to load firmware from %s", machine->firmware);
78
exit(1);
79
}
80
81
- binfo.entry = FIRMWARE_ADDR;
82
+ binfo.entry = firmware_addr;
83
binfo.firmware_loaded = true;
84
} else {
85
binfo.kernel_filename = machine->kernel_filename;
86
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
87
arm_load_kernel(ARM_CPU(first_cpu), &binfo);
88
}
49
}
89
50
90
-static void raspi2_init(MachineState *machine)
51
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
91
+static void raspi_init(MachineState *machine, int version)
52
- qemu_irq handler)
53
-{
54
- if (line >= TC6393XB_GPIOS) {
55
- fprintf(stderr, "TC6393xb: no GPIO pin %d\n", line);
56
- return;
57
- }
58
-
59
- s->handler[line] = handler;
60
-}
61
-
62
static void tc6393xb_gpio_handler_update(TC6393xbState *s)
92
{
63
{
93
RasPiState *s = g_new0(RasPiState, 1);
64
uint32_t level, diff;
94
uint32_t vcram_size;
95
@@ -XXX,XX +XXX,XX @@ static void raspi2_init(MachineState *machine)
96
&error_abort);
97
object_property_set_int(OBJECT(&s->soc), smp_cpus, "enabled-cpus",
98
&error_abort);
99
- object_property_set_int(OBJECT(&s->soc), 0xa21041, "board-rev",
100
+ int board_rev = version == 3 ? 0xa02082 : 0xa21041;
101
+ object_property_set_int(OBJECT(&s->soc), board_rev, "board-rev",
102
&error_abort);
103
object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_abort);
104
105
@@ -XXX,XX +XXX,XX @@ static void raspi2_init(MachineState *machine)
106
107
vcram_size = object_property_get_uint(OBJECT(&s->soc), "vcram-size",
108
&error_abort);
109
- setup_boot(machine, 2, machine->ram_size - vcram_size);
110
+ setup_boot(machine, version, machine->ram_size - vcram_size);
111
+}
112
+
113
+static void raspi2_init(MachineState *machine)
114
+{
115
+ raspi_init(machine, 2);
116
}
117
118
static void raspi2_machine_init(MachineClass *mc)
119
--
65
--
120
2.16.1
66
2.20.1
121
67
122
68
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20190412165416.7977-5-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
include/hw/devices.h | 6 ------
9
include/hw/display/tc6393xb.h | 24 ++++++++++++++++++++++++
10
hw/arm/tosa.c | 2 +-
11
hw/display/tc6393xb.c | 2 +-
12
MAINTAINERS | 1 +
13
5 files changed, 27 insertions(+), 8 deletions(-)
14
create mode 100644 include/hw/display/tc6393xb.h
15
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/devices.h
19
+++ b/include/hw/devices.h
20
@@ -XXX,XX +XXX,XX @@ void *tahvo_init(qemu_irq irq, int betty);
21
22
void retu_key_event(void *retu, int state);
23
24
-/* tc6393xb.c */
25
-typedef struct TC6393xbState TC6393xbState;
26
-TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
27
- uint32_t base, qemu_irq irq);
28
-qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
29
-
30
#endif
31
diff --git a/include/hw/display/tc6393xb.h b/include/hw/display/tc6393xb.h
32
new file mode 100644
33
index XXXXXXX..XXXXXXX
34
--- /dev/null
35
+++ b/include/hw/display/tc6393xb.h
36
@@ -XXX,XX +XXX,XX @@
37
+/*
38
+ * Toshiba TC6393XB I/O Controller.
39
+ * Found in Sharp Zaurus SL-6000 (tosa) or some
40
+ * Toshiba e-Series PDAs.
41
+ *
42
+ * Copyright (c) 2007 Hervé Poussineau
43
+ *
44
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
45
+ * See the COPYING file in the top-level directory.
46
+ */
47
+
48
+#ifndef HW_DISPLAY_TC6393XB_H
49
+#define HW_DISPLAY_TC6393XB_H
50
+
51
+#include "exec/memory.h"
52
+#include "hw/irq.h"
53
+
54
+typedef struct TC6393xbState TC6393xbState;
55
+
56
+TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
57
+ uint32_t base, qemu_irq irq);
58
+qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
59
+
60
+#endif
61
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/tosa.c
64
+++ b/hw/arm/tosa.c
65
@@ -XXX,XX +XXX,XX @@
66
#include "hw/hw.h"
67
#include "hw/arm/pxa.h"
68
#include "hw/arm/arm.h"
69
-#include "hw/devices.h"
70
#include "hw/arm/sharpsl.h"
71
#include "hw/pcmcia.h"
72
#include "hw/boards.h"
73
+#include "hw/display/tc6393xb.h"
74
#include "hw/i2c/i2c.h"
75
#include "hw/ssi/ssi.h"
76
#include "hw/sysbus.h"
77
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/display/tc6393xb.c
80
+++ b/hw/display/tc6393xb.c
81
@@ -XXX,XX +XXX,XX @@
82
#include "qapi/error.h"
83
#include "qemu/host-utils.h"
84
#include "hw/hw.h"
85
-#include "hw/devices.h"
86
+#include "hw/display/tc6393xb.h"
87
#include "hw/block/flash.h"
88
#include "ui/console.h"
89
#include "ui/pixel_ops.h"
90
diff --git a/MAINTAINERS b/MAINTAINERS
91
index XXXXXXX..XXXXXXX 100644
92
--- a/MAINTAINERS
93
+++ b/MAINTAINERS
94
@@ -XXX,XX +XXX,XX @@ F: hw/misc/mst_fpga.c
95
F: hw/misc/max111x.c
96
F: include/hw/arm/pxa.h
97
F: include/hw/arm/sharpsl.h
98
+F: include/hw/display/tc6393xb.h
99
100
SABRELITE / i.MX6
101
M: Peter Maydell <peter.maydell@linaro.org>
102
--
103
2.20.1
104
105
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
2
3
Add an entries the Blizzard device in MAINTAINERS.
4
5
Reviewed-by: Thomas Huth <thuth@redhat.com>
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190412165416.7977-6-philmd@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/devices.h | 7 -------
12
include/hw/display/blizzard.h | 22 ++++++++++++++++++++++
13
hw/arm/nseries.c | 1 +
14
hw/display/blizzard.c | 2 +-
15
MAINTAINERS | 2 ++
16
5 files changed, 26 insertions(+), 8 deletions(-)
17
create mode 100644 include/hw/display/blizzard.h
18
19
diff --git a/include/hw/devices.h b/include/hw/devices.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/devices.h
22
+++ b/include/hw/devices.h
23
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
24
/* stellaris_input.c */
25
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
26
27
-/* blizzard.c */
28
-void *s1d13745_init(qemu_irq gpio_int);
29
-void s1d13745_write(void *opaque, int dc, uint16_t value);
30
-void s1d13745_write_block(void *opaque, int dc,
31
- void *buf, size_t len, int pitch);
32
-uint16_t s1d13745_read(void *opaque, int dc);
33
-
34
/* cbus.c */
35
typedef struct {
36
qemu_irq clk;
37
diff --git a/include/hw/display/blizzard.h b/include/hw/display/blizzard.h
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/include/hw/display/blizzard.h
42
@@ -XXX,XX +XXX,XX @@
43
+/*
44
+ * Epson S1D13744/S1D13745 (Blizzard/Hailstorm/Tornado) LCD/TV controller.
45
+ *
46
+ * Copyright (C) 2008 Nokia Corporation
47
+ * Written by Andrzej Zaborowski
48
+ *
49
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
50
+ * See the COPYING file in the top-level directory.
51
+ */
52
+
53
+#ifndef HW_DISPLAY_BLIZZARD_H
54
+#define HW_DISPLAY_BLIZZARD_H
55
+
56
+#include "hw/irq.h"
57
+
58
+void *s1d13745_init(qemu_irq gpio_int);
59
+void s1d13745_write(void *opaque, int dc, uint16_t value);
60
+void s1d13745_write_block(void *opaque, int dc,
61
+ void *buf, size_t len, int pitch);
62
+uint16_t s1d13745_read(void *opaque, int dc);
63
+
64
+#endif
65
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/arm/nseries.c
68
+++ b/hw/arm/nseries.c
69
@@ -XXX,XX +XXX,XX @@
70
#include "hw/boards.h"
71
#include "hw/i2c/i2c.h"
72
#include "hw/devices.h"
73
+#include "hw/display/blizzard.h"
74
#include "hw/misc/tmp105.h"
75
#include "hw/block/flash.h"
76
#include "hw/hw.h"
77
diff --git a/hw/display/blizzard.c b/hw/display/blizzard.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/display/blizzard.c
80
+++ b/hw/display/blizzard.c
81
@@ -XXX,XX +XXX,XX @@
82
#include "qemu/osdep.h"
83
#include "qemu-common.h"
84
#include "ui/console.h"
85
-#include "hw/devices.h"
86
+#include "hw/display/blizzard.h"
87
#include "ui/pixel_ops.h"
88
89
typedef void (*blizzard_fn_t)(uint8_t *, const uint8_t *, unsigned int);
90
diff --git a/MAINTAINERS b/MAINTAINERS
91
index XXXXXXX..XXXXXXX 100644
92
--- a/MAINTAINERS
93
+++ b/MAINTAINERS
94
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
95
L: qemu-arm@nongnu.org
96
S: Odd Fixes
97
F: hw/arm/nseries.c
98
+F: hw/display/blizzard.c
99
F: hw/input/lm832x.c
100
F: hw/input/tsc2005.c
101
F: hw/misc/cbus.c
102
F: hw/timer/twl92230.c
103
+F: include/hw/display/blizzard.h
104
105
Palm
106
M: Andrzej Zaborowski <balrogg@gmail.com>
107
--
108
2.20.1
109
110
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
2
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190412165416.7977-7-philmd@redhat.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
include/hw/devices.h | 14 --------------
10
include/hw/misc/cbus.h | 32 ++++++++++++++++++++++++++++++++
11
hw/arm/nseries.c | 1 +
12
hw/misc/cbus.c | 2 +-
13
MAINTAINERS | 1 +
14
5 files changed, 35 insertions(+), 15 deletions(-)
15
create mode 100644 include/hw/misc/cbus.h
16
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/devices.h
20
+++ b/include/hw/devices.h
21
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
22
/* stellaris_input.c */
23
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
24
25
-/* cbus.c */
26
-typedef struct {
27
- qemu_irq clk;
28
- qemu_irq dat;
29
- qemu_irq sel;
30
-} CBus;
31
-CBus *cbus_init(qemu_irq dat_out);
32
-void cbus_attach(CBus *bus, void *slave_opaque);
33
-
34
-void *retu_init(qemu_irq irq, int vilma);
35
-void *tahvo_init(qemu_irq irq, int betty);
36
-
37
-void retu_key_event(void *retu, int state);
38
-
39
#endif
40
diff --git a/include/hw/misc/cbus.h b/include/hw/misc/cbus.h
41
new file mode 100644
42
index XXXXXXX..XXXXXXX
43
--- /dev/null
44
+++ b/include/hw/misc/cbus.h
45
@@ -XXX,XX +XXX,XX @@
46
+/*
47
+ * CBUS three-pin bus and the Retu / Betty / Tahvo / Vilma / Avilma /
48
+ * Hinku / Vinku / Ahne / Pihi chips used in various Nokia platforms.
49
+ * Based on reverse-engineering of a linux driver.
50
+ *
51
+ * Copyright (C) 2008 Nokia Corporation
52
+ * Written by Andrzej Zaborowski
53
+ *
54
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
55
+ * See the COPYING file in the top-level directory.
56
+ */
57
+
58
+#ifndef HW_MISC_CBUS_H
59
+#define HW_MISC_CBUS_H
60
+
61
+#include "hw/irq.h"
62
+
63
+typedef struct {
64
+ qemu_irq clk;
65
+ qemu_irq dat;
66
+ qemu_irq sel;
67
+} CBus;
68
+
69
+CBus *cbus_init(qemu_irq dat_out);
70
+void cbus_attach(CBus *bus, void *slave_opaque);
71
+
72
+void *retu_init(qemu_irq irq, int vilma);
73
+void *tahvo_init(qemu_irq irq, int betty);
74
+
75
+void retu_key_event(void *retu, int state);
76
+
77
+#endif
78
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/hw/arm/nseries.c
81
+++ b/hw/arm/nseries.c
82
@@ -XXX,XX +XXX,XX @@
83
#include "hw/i2c/i2c.h"
84
#include "hw/devices.h"
85
#include "hw/display/blizzard.h"
86
+#include "hw/misc/cbus.h"
87
#include "hw/misc/tmp105.h"
88
#include "hw/block/flash.h"
89
#include "hw/hw.h"
90
diff --git a/hw/misc/cbus.c b/hw/misc/cbus.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/hw/misc/cbus.c
93
+++ b/hw/misc/cbus.c
94
@@ -XXX,XX +XXX,XX @@
95
#include "qemu/osdep.h"
96
#include "hw/hw.h"
97
#include "hw/irq.h"
98
-#include "hw/devices.h"
99
+#include "hw/misc/cbus.h"
100
#include "sysemu/sysemu.h"
101
102
//#define DEBUG
103
diff --git a/MAINTAINERS b/MAINTAINERS
104
index XXXXXXX..XXXXXXX 100644
105
--- a/MAINTAINERS
106
+++ b/MAINTAINERS
107
@@ -XXX,XX +XXX,XX @@ F: hw/input/tsc2005.c
108
F: hw/misc/cbus.c
109
F: hw/timer/twl92230.c
110
F: include/hw/display/blizzard.h
111
+F: include/hw/misc/cbus.h
112
113
Palm
114
M: Andrzej Zaborowski <balrogg@gmail.com>
115
--
116
2.20.1
117
118
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20190412165416.7977-8-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
include/hw/devices.h | 3 ---
9
include/hw/input/gamepad.h | 19 +++++++++++++++++++
10
hw/arm/stellaris.c | 2 +-
11
hw/input/stellaris_input.c | 2 +-
12
MAINTAINERS | 1 +
13
5 files changed, 22 insertions(+), 5 deletions(-)
14
create mode 100644 include/hw/input/gamepad.h
15
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/devices.h
19
+++ b/include/hw/devices.h
20
@@ -XXX,XX +XXX,XX @@ void *tsc2005_init(qemu_irq pintdav);
21
uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
22
void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
23
24
-/* stellaris_input.c */
25
-void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
26
-
27
#endif
28
diff --git a/include/hw/input/gamepad.h b/include/hw/input/gamepad.h
29
new file mode 100644
30
index XXXXXXX..XXXXXXX
31
--- /dev/null
32
+++ b/include/hw/input/gamepad.h
33
@@ -XXX,XX +XXX,XX @@
34
+/*
35
+ * Gamepad style buttons connected to IRQ/GPIO lines
36
+ *
37
+ * Copyright (c) 2007 CodeSourcery.
38
+ * Written by Paul Brook
39
+ *
40
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
41
+ * See the COPYING file in the top-level directory.
42
+ */
43
+
44
+#ifndef HW_INPUT_GAMEPAD_H
45
+#define HW_INPUT_GAMEPAD_H
46
+
47
+#include "hw/irq.h"
48
+
49
+/* stellaris_input.c */
50
+void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
51
+
52
+#endif
53
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/arm/stellaris.c
56
+++ b/hw/arm/stellaris.c
57
@@ -XXX,XX +XXX,XX @@
58
#include "hw/sysbus.h"
59
#include "hw/ssi/ssi.h"
60
#include "hw/arm/arm.h"
61
-#include "hw/devices.h"
62
#include "qemu/timer.h"
63
#include "hw/i2c/i2c.h"
64
#include "net/net.h"
65
@@ -XXX,XX +XXX,XX @@
66
#include "sysemu/sysemu.h"
67
#include "hw/arm/armv7m.h"
68
#include "hw/char/pl011.h"
69
+#include "hw/input/gamepad.h"
70
#include "hw/watchdog/cmsdk-apb-watchdog.h"
71
#include "hw/misc/unimp.h"
72
#include "cpu.h"
73
diff --git a/hw/input/stellaris_input.c b/hw/input/stellaris_input.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/input/stellaris_input.c
76
+++ b/hw/input/stellaris_input.c
77
@@ -XXX,XX +XXX,XX @@
78
*/
79
#include "qemu/osdep.h"
80
#include "hw/hw.h"
81
-#include "hw/devices.h"
82
+#include "hw/input/gamepad.h"
83
#include "ui/console.h"
84
85
typedef struct {
86
diff --git a/MAINTAINERS b/MAINTAINERS
87
index XXXXXXX..XXXXXXX 100644
88
--- a/MAINTAINERS
89
+++ b/MAINTAINERS
90
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
91
L: qemu-arm@nongnu.org
92
S: Maintained
93
F: hw/*/stellaris*
94
+F: include/hw/input/gamepad.h
95
96
Versatile Express
97
M: Peter Maydell <peter.maydell@linaro.org>
98
--
99
2.20.1
100
101
diff view generated by jsdifflib
New patch
1
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
3
Since uWireSlave is only used in this new header, there is no
4
need to expose it via "qemu/typedefs.h".
5
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190412165416.7977-9-philmd@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/omap.h | 6 +-----
12
include/hw/devices.h | 15 ---------------
13
include/hw/input/tsc2xxx.h | 36 ++++++++++++++++++++++++++++++++++++
14
include/qemu/typedefs.h | 1 -
15
hw/arm/nseries.c | 2 +-
16
hw/arm/palm.c | 2 +-
17
hw/input/tsc2005.c | 2 +-
18
hw/input/tsc210x.c | 4 ++--
19
MAINTAINERS | 2 ++
20
9 files changed, 44 insertions(+), 26 deletions(-)
21
create mode 100644 include/hw/input/tsc2xxx.h
22
23
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/omap.h
26
+++ b/include/hw/arm/omap.h
27
@@ -XXX,XX +XXX,XX @@
28
#include "exec/memory.h"
29
# define hw_omap_h        "omap.h"
30
#include "hw/irq.h"
31
+#include "hw/input/tsc2xxx.h"
32
#include "target/arm/cpu-qom.h"
33
#include "qemu/log.h"
34
35
@@ -XXX,XX +XXX,XX @@ qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s);
36
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler);
37
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down);
38
39
-struct uWireSlave {
40
- uint16_t (*receive)(void *opaque);
41
- void (*send)(void *opaque, uint16_t data);
42
- void *opaque;
43
-};
44
struct omap_uwire_s;
45
void omap_uwire_attach(struct omap_uwire_s *s,
46
uWireSlave *slave, int chipselect);
47
diff --git a/include/hw/devices.h b/include/hw/devices.h
48
index XXXXXXX..XXXXXXX 100644
49
--- a/include/hw/devices.h
50
+++ b/include/hw/devices.h
51
@@ -XXX,XX +XXX,XX @@
52
/* Devices that have nowhere better to go. */
53
54
#include "hw/hw.h"
55
-#include "ui/console.h"
56
57
/* smc91c111.c */
58
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
59
@@ -XXX,XX +XXX,XX @@ void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
60
/* lan9118.c */
61
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
62
63
-/* tsc210x.c */
64
-uWireSlave *tsc2102_init(qemu_irq pint);
65
-uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
66
-I2SCodec *tsc210x_codec(uWireSlave *chip);
67
-uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
68
-void tsc210x_set_transform(uWireSlave *chip,
69
- MouseTransformInfo *info);
70
-void tsc210x_key_event(uWireSlave *chip, int key, int down);
71
-
72
-/* tsc2005.c */
73
-void *tsc2005_init(qemu_irq pintdav);
74
-uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
75
-void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
76
-
77
#endif
78
diff --git a/include/hw/input/tsc2xxx.h b/include/hw/input/tsc2xxx.h
79
new file mode 100644
80
index XXXXXXX..XXXXXXX
81
--- /dev/null
82
+++ b/include/hw/input/tsc2xxx.h
83
@@ -XXX,XX +XXX,XX @@
84
+/*
85
+ * TI touchscreen controller
86
+ *
87
+ * Copyright (c) 2006 Andrzej Zaborowski
88
+ * Copyright (C) 2008 Nokia Corporation
89
+ *
90
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
91
+ * See the COPYING file in the top-level directory.
92
+ */
93
+
94
+#ifndef HW_INPUT_TSC2XXX_H
95
+#define HW_INPUT_TSC2XXX_H
96
+
97
+#include "hw/irq.h"
98
+#include "ui/console.h"
99
+
100
+typedef struct uWireSlave {
101
+ uint16_t (*receive)(void *opaque);
102
+ void (*send)(void *opaque, uint16_t data);
103
+ void *opaque;
104
+} uWireSlave;
105
+
106
+/* tsc210x.c */
107
+uWireSlave *tsc2102_init(qemu_irq pint);
108
+uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
109
+I2SCodec *tsc210x_codec(uWireSlave *chip);
110
+uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
111
+void tsc210x_set_transform(uWireSlave *chip, MouseTransformInfo *info);
112
+void tsc210x_key_event(uWireSlave *chip, int key, int down);
113
+
114
+/* tsc2005.c */
115
+void *tsc2005_init(qemu_irq pintdav);
116
+uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
117
+void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
118
+
119
+#endif
120
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
121
index XXXXXXX..XXXXXXX 100644
122
--- a/include/qemu/typedefs.h
123
+++ b/include/qemu/typedefs.h
124
@@ -XXX,XX +XXX,XX @@ typedef struct RAMBlock RAMBlock;
125
typedef struct Range Range;
126
typedef struct SHPCDevice SHPCDevice;
127
typedef struct SSIBus SSIBus;
128
-typedef struct uWireSlave uWireSlave;
129
typedef struct VirtIODevice VirtIODevice;
130
typedef struct Visitor Visitor;
131
typedef void SaveStateHandler(QEMUFile *f, void *opaque);
132
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/hw/arm/nseries.c
135
+++ b/hw/arm/nseries.c
136
@@ -XXX,XX +XXX,XX @@
137
#include "ui/console.h"
138
#include "hw/boards.h"
139
#include "hw/i2c/i2c.h"
140
-#include "hw/devices.h"
141
#include "hw/display/blizzard.h"
142
+#include "hw/input/tsc2xxx.h"
143
#include "hw/misc/cbus.h"
144
#include "hw/misc/tmp105.h"
145
#include "hw/block/flash.h"
146
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
147
index XXXXXXX..XXXXXXX 100644
148
--- a/hw/arm/palm.c
149
+++ b/hw/arm/palm.c
150
@@ -XXX,XX +XXX,XX @@
151
#include "hw/arm/omap.h"
152
#include "hw/boards.h"
153
#include "hw/arm/arm.h"
154
-#include "hw/devices.h"
155
+#include "hw/input/tsc2xxx.h"
156
#include "hw/loader.h"
157
#include "exec/address-spaces.h"
158
#include "cpu.h"
159
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/hw/input/tsc2005.c
162
+++ b/hw/input/tsc2005.c
163
@@ -XXX,XX +XXX,XX @@
164
#include "hw/hw.h"
165
#include "qemu/timer.h"
166
#include "ui/console.h"
167
-#include "hw/devices.h"
168
+#include "hw/input/tsc2xxx.h"
169
#include "trace.h"
170
171
#define TSC_CUT_RESOLUTION(value, p)    ((value) >> (16 - (p ? 12 : 10)))
172
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
173
index XXXXXXX..XXXXXXX 100644
174
--- a/hw/input/tsc210x.c
175
+++ b/hw/input/tsc210x.c
176
@@ -XXX,XX +XXX,XX @@
177
#include "audio/audio.h"
178
#include "qemu/timer.h"
179
#include "ui/console.h"
180
-#include "hw/arm/omap.h"    /* For I2SCodec and uWireSlave */
181
-#include "hw/devices.h"
182
+#include "hw/arm/omap.h" /* For I2SCodec */
183
+#include "hw/input/tsc2xxx.h"
184
185
#define TSC_DATA_REGISTERS_PAGE        0x0
186
#define TSC_CONTROL_REGISTERS_PAGE    0x1
187
diff --git a/MAINTAINERS b/MAINTAINERS
188
index XXXXXXX..XXXXXXX 100644
189
--- a/MAINTAINERS
190
+++ b/MAINTAINERS
191
@@ -XXX,XX +XXX,XX @@ F: hw/input/tsc2005.c
192
F: hw/misc/cbus.c
193
F: hw/timer/twl92230.c
194
F: include/hw/display/blizzard.h
195
+F: include/hw/input/tsc2xxx.h
196
F: include/hw/misc/cbus.h
197
198
Palm
199
@@ -XXX,XX +XXX,XX @@ L: qemu-arm@nongnu.org
200
S: Odd Fixes
201
F: hw/arm/palm.c
202
F: hw/input/tsc210x.c
203
+F: include/hw/input/tsc2xxx.h
204
205
Raspberry Pi
206
M: Peter Maydell <peter.maydell@linaro.org>
207
--
208
2.20.1
209
210
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20190412165416.7977-10-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
include/hw/devices.h | 3 ---
9
include/hw/net/lan9118.h | 19 +++++++++++++++++++
10
hw/arm/kzm.c | 2 +-
11
hw/arm/mps2.c | 2 +-
12
hw/arm/realview.c | 1 +
13
hw/arm/vexpress.c | 2 +-
14
hw/net/lan9118.c | 2 +-
15
7 files changed, 24 insertions(+), 7 deletions(-)
16
create mode 100644 include/hw/net/lan9118.h
17
18
diff --git a/include/hw/devices.h b/include/hw/devices.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/devices.h
21
+++ b/include/hw/devices.h
22
@@ -XXX,XX +XXX,XX @@
23
/* smc91c111.c */
24
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
25
26
-/* lan9118.c */
27
-void lan9118_init(NICInfo *, uint32_t, qemu_irq);
28
-
29
#endif
30
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
31
new file mode 100644
32
index XXXXXXX..XXXXXXX
33
--- /dev/null
34
+++ b/include/hw/net/lan9118.h
35
@@ -XXX,XX +XXX,XX @@
36
+/*
37
+ * SMSC LAN9118 Ethernet interface emulation
38
+ *
39
+ * Copyright (c) 2009 CodeSourcery, LLC.
40
+ * Written by Paul Brook
41
+ *
42
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
43
+ * See the COPYING file in the top-level directory.
44
+ */
45
+
46
+#ifndef HW_NET_LAN9118_H
47
+#define HW_NET_LAN9118_H
48
+
49
+#include "hw/irq.h"
50
+#include "net/net.h"
51
+
52
+void lan9118_init(NICInfo *, uint32_t, qemu_irq);
53
+
54
+#endif
55
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/kzm.c
58
+++ b/hw/arm/kzm.c
59
@@ -XXX,XX +XXX,XX @@
60
#include "qemu/error-report.h"
61
#include "exec/address-spaces.h"
62
#include "net/net.h"
63
-#include "hw/devices.h"
64
+#include "hw/net/lan9118.h"
65
#include "hw/char/serial.h"
66
#include "sysemu/qtest.h"
67
68
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/arm/mps2.c
71
+++ b/hw/arm/mps2.c
72
@@ -XXX,XX +XXX,XX @@
73
#include "hw/timer/cmsdk-apb-timer.h"
74
#include "hw/timer/cmsdk-apb-dualtimer.h"
75
#include "hw/misc/mps2-scc.h"
76
-#include "hw/devices.h"
77
+#include "hw/net/lan9118.h"
78
#include "net/net.h"
79
80
typedef enum MPS2FPGAType {
81
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/hw/arm/realview.c
84
+++ b/hw/arm/realview.c
85
@@ -XXX,XX +XXX,XX @@
86
#include "hw/arm/arm.h"
87
#include "hw/arm/primecell.h"
88
#include "hw/devices.h"
89
+#include "hw/net/lan9118.h"
90
#include "hw/pci/pci.h"
91
#include "net/net.h"
92
#include "sysemu/sysemu.h"
93
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/hw/arm/vexpress.c
96
+++ b/hw/arm/vexpress.c
97
@@ -XXX,XX +XXX,XX @@
98
#include "hw/sysbus.h"
99
#include "hw/arm/arm.h"
100
#include "hw/arm/primecell.h"
101
-#include "hw/devices.h"
102
+#include "hw/net/lan9118.h"
103
#include "hw/i2c/i2c.h"
104
#include "net/net.h"
105
#include "sysemu/sysemu.h"
106
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/hw/net/lan9118.c
109
+++ b/hw/net/lan9118.c
110
@@ -XXX,XX +XXX,XX @@
111
#include "hw/sysbus.h"
112
#include "net/net.h"
113
#include "net/eth.h"
114
-#include "hw/devices.h"
115
+#include "hw/net/lan9118.h"
116
#include "sysemu/sysemu.h"
117
#include "hw/ptimer.h"
118
#include "qemu/log.h"
119
--
120
2.20.1
121
122
diff view generated by jsdifflib
1
From: Pekka Enberg <penberg@iki.fi>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
This patch adds a "raspi3" machine type, which can now be selected as
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
the machine to run on by users via the "-M" command line option to QEMU.
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
The machine type does *not* ignore memory transaction failures so we
6
Message-id: 20190412165416.7977-11-philmd@redhat.com
7
likely need to add some dummy devices later when people run something
8
more complicated than what I'm using for testing.
9
10
Signed-off-by: Pekka Enberg <penberg@iki.fi>
11
[PMM: added #ifdef TARGET_AARCH64 so we don't provide the 64-bit
12
board in the 32-bit only arm-softmmu build.]
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
8
---
17
hw/arm/raspi.c | 23 +++++++++++++++++++++++
9
include/hw/net/ne2000-isa.h | 6 ++++++
18
1 file changed, 23 insertions(+)
10
1 file changed, 6 insertions(+)
19
11
20
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
12
diff --git a/include/hw/net/ne2000-isa.h b/include/hw/net/ne2000-isa.h
21
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/raspi.c
14
--- a/include/hw/net/ne2000-isa.h
23
+++ b/hw/arm/raspi.c
15
+++ b/include/hw/net/ne2000-isa.h
24
@@ -XXX,XX +XXX,XX @@ static void raspi2_machine_init(MachineClass *mc)
16
@@ -XXX,XX +XXX,XX @@
25
mc->ignore_memory_transaction_failures = true;
17
* This work is licensed under the terms of the GNU GPL, version 2 or later.
26
};
18
* See the COPYING file in the top-level directory.
27
DEFINE_MACHINE("raspi2", raspi2_machine_init)
19
*/
28
+
20
+
29
+#ifdef TARGET_AARCH64
21
+#ifndef HW_NET_NE2K_ISA_H
30
+static void raspi3_init(MachineState *machine)
22
+#define HW_NET_NE2K_ISA_H
31
+{
32
+ raspi_init(machine, 3);
33
+}
34
+
23
+
35
+static void raspi3_machine_init(MachineClass *mc)
24
#include "hw/hw.h"
36
+{
25
#include "hw/qdev.h"
37
+ mc->desc = "Raspberry Pi 3";
26
#include "hw/isa/isa.h"
38
+ mc->init = raspi3_init;
27
@@ -XXX,XX +XXX,XX @@ static inline ISADevice *isa_ne2000_init(ISABus *bus, int base, int irq,
39
+ mc->block_default_type = IF_SD;
28
}
40
+ mc->no_parallel = 1;
29
return d;
41
+ mc->no_floppy = 1;
30
}
42
+ mc->no_cdrom = 1;
31
+
43
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a53");
44
+ mc->max_cpus = BCM2836_NCPUS;
45
+ mc->min_cpus = BCM2836_NCPUS;
46
+ mc->default_cpus = BCM2836_NCPUS;
47
+ mc->default_ram_size = 1024 * 1024 * 1024;
48
+}
49
+DEFINE_MACHINE("raspi3", raspi3_machine_init)
50
+#endif
32
+#endif
51
--
33
--
52
2.16.1
34
2.20.1
53
35
54
36
diff view generated by jsdifflib
1
In commit abc24d86cc0364f we accidentally broke migration of
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
the stack pointer value for the mode (process, handler) the CPU
3
is not currently running as. (The commit correctly removed the
4
no-longer-used v7m.current_sp flag from the VMState but also
5
deleted the still very much in use v7m.other_sp SP value field.)
6
2
7
Add a subsection to migrate it again. (We don't need to care
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
8
about trying to retain compatibility with pre-abc24d86cc0364f
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
versions of QEMU, because that commit bumped the version_id
5
Message-id: 20190412165416.7977-12-philmd@redhat.com
10
and we've since bumped it again a couple of times.)
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
include/hw/net/lan9118.h | 2 ++
9
hw/arm/exynos4_boards.c | 3 ++-
10
hw/arm/mps2-tz.c | 3 ++-
11
hw/net/lan9118.c | 1 -
12
4 files changed, 6 insertions(+), 3 deletions(-)
11
13
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20180209165810.6668-11-peter.maydell@linaro.org
15
---
16
target/arm/machine.c | 11 +++++++++++
17
1 file changed, 11 insertions(+)
18
19
diff --git a/target/arm/machine.c b/target/arm/machine.c
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/machine.c
16
--- a/include/hw/net/lan9118.h
22
+++ b/target/arm/machine.c
17
+++ b/include/hw/net/lan9118.h
23
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_scr = {
18
@@ -XXX,XX +XXX,XX @@
19
#include "hw/irq.h"
20
#include "net/net.h"
21
22
+#define TYPE_LAN9118 "lan9118"
23
+
24
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
25
26
#endif
27
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/exynos4_boards.c
30
+++ b/hw/arm/exynos4_boards.c
31
@@ -XXX,XX +XXX,XX @@
32
#include "hw/arm/arm.h"
33
#include "exec/address-spaces.h"
34
#include "hw/arm/exynos4210.h"
35
+#include "hw/net/lan9118.h"
36
#include "hw/boards.h"
37
38
#undef DEBUG
39
@@ -XXX,XX +XXX,XX @@ static void lan9215_init(uint32_t base, qemu_irq irq)
40
/* This should be a 9215 but the 9118 is close enough */
41
if (nd_table[0].used) {
42
qemu_check_nic_model(&nd_table[0], "lan9118");
43
- dev = qdev_create(NULL, "lan9118");
44
+ dev = qdev_create(NULL, TYPE_LAN9118);
45
qdev_set_nic_properties(dev, &nd_table[0]);
46
qdev_prop_set_uint32(dev, "mode_16bit", 1);
47
qdev_init_nofail(dev);
48
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/arm/mps2-tz.c
51
+++ b/hw/arm/mps2-tz.c
52
@@ -XXX,XX +XXX,XX @@
53
#include "hw/arm/armsse.h"
54
#include "hw/dma/pl080.h"
55
#include "hw/ssi/pl022.h"
56
+#include "hw/net/lan9118.h"
57
#include "net/net.h"
58
#include "hw/core/split-irq.h"
59
60
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
61
* except that it doesn't support the checksum-offload feature.
62
*/
63
qemu_check_nic_model(nd, "lan9118");
64
- mms->lan9118 = qdev_create(NULL, "lan9118");
65
+ mms->lan9118 = qdev_create(NULL, TYPE_LAN9118);
66
qdev_set_nic_properties(mms->lan9118, nd);
67
qdev_init_nofail(mms->lan9118);
68
69
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/hw/net/lan9118.c
72
+++ b/hw/net/lan9118.c
73
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118_packet = {
24
}
74
}
25
};
75
};
26
76
27
+static const VMStateDescription vmstate_m_other_sp = {
77
-#define TYPE_LAN9118 "lan9118"
28
+ .name = "cpu/m/other-sp",
78
#define LAN9118(obj) OBJECT_CHECK(lan9118_state, (obj), TYPE_LAN9118)
29
+ .version_id = 1,
79
30
+ .minimum_version_id = 1,
80
typedef struct {
31
+ .fields = (VMStateField[]) {
32
+ VMSTATE_UINT32(env.v7m.other_sp, ARMCPU),
33
+ VMSTATE_END_OF_LIST()
34
+ }
35
+};
36
+
37
static const VMStateDescription vmstate_m = {
38
.name = "cpu/m",
39
.version_id = 4,
40
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
41
&vmstate_m_faultmask_primask,
42
&vmstate_m_csselr,
43
&vmstate_m_scr,
44
+ &vmstate_m_other_sp,
45
NULL
46
}
47
};
48
--
81
--
49
2.16.1
82
2.20.1
50
83
51
84
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
(qemu) info mtree
3
This commit finally deletes "hw/devices.h".
4
address-space: cpu-memory-0
5
0000000000000000-ffffffffffffffff (prio 0, i/o): system
6
0000000000000000-0000000007ffffff (prio 0, rom): aspeed.boot_rom
7
- 000000001e600000-000000001e7fffff (prio -1, i/o): aspeed_soc.io
8
+ 000000001e600000-000000001e7fffff (prio -1000, i/o): aspeed_soc.io
9
000000001e620000-000000001e6200ff (prio 0, i/o): aspeed.smc.ast2500-fmc
10
000000001e630000-000000001e6300ff (prio 0, i/o): aspeed.smc.ast2500-spi1
11
000000001e631000-000000001e6310ff (prio 0, i/o): aspeed.smc.ast2500-spi2
12
4
13
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
14
Reviewed-by: Cédric Le Goater <clg@kaod.org>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
7
Message-id: 20190412165416.7977-13-philmd@redhat.com
16
Message-id: 20180209085755.30414-3-f4bug@amsat.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
9
---
19
include/hw/arm/aspeed_soc.h | 1 -
10
include/hw/devices.h | 11 -----------
20
hw/arm/aspeed_soc.c | 32 +++-----------------------------
11
include/hw/net/smc91c111.h | 19 +++++++++++++++++++
21
2 files changed, 3 insertions(+), 30 deletions(-)
12
hw/arm/gumstix.c | 2 +-
13
hw/arm/integratorcp.c | 2 +-
14
hw/arm/mainstone.c | 2 +-
15
hw/arm/realview.c | 2 +-
16
hw/arm/versatilepb.c | 2 +-
17
hw/net/smc91c111.c | 2 +-
18
8 files changed, 25 insertions(+), 17 deletions(-)
19
delete mode 100644 include/hw/devices.h
20
create mode 100644 include/hw/net/smc91c111.h
22
21
23
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
22
diff --git a/include/hw/devices.h b/include/hw/devices.h
23
deleted file mode 100644
24
index XXXXXXX..XXXXXXX
25
--- a/include/hw/devices.h
26
+++ /dev/null
27
@@ -XXX,XX +XXX,XX @@
28
-#ifndef QEMU_DEVICES_H
29
-#define QEMU_DEVICES_H
30
-
31
-/* Devices that have nowhere better to go. */
32
-
33
-#include "hw/hw.h"
34
-
35
-/* smc91c111.c */
36
-void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
37
-
38
-#endif
39
diff --git a/include/hw/net/smc91c111.h b/include/hw/net/smc91c111.h
40
new file mode 100644
41
index XXXXXXX..XXXXXXX
42
--- /dev/null
43
+++ b/include/hw/net/smc91c111.h
44
@@ -XXX,XX +XXX,XX @@
45
+/*
46
+ * SMSC 91C111 Ethernet interface emulation
47
+ *
48
+ * Copyright (c) 2005 CodeSourcery, LLC.
49
+ * Written by Paul Brook
50
+ *
51
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
52
+ * See the COPYING file in the top-level directory.
53
+ */
54
+
55
+#ifndef HW_NET_SMC91C111_H
56
+#define HW_NET_SMC91C111_H
57
+
58
+#include "hw/irq.h"
59
+#include "net/net.h"
60
+
61
+void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
62
+
63
+#endif
64
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
24
index XXXXXXX..XXXXXXX 100644
65
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/aspeed_soc.h
66
--- a/hw/arm/gumstix.c
26
+++ b/include/hw/arm/aspeed_soc.h
67
+++ b/hw/arm/gumstix.c
27
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCState {
68
@@ -XXX,XX +XXX,XX @@
28
69
#include "hw/arm/pxa.h"
29
/*< public >*/
70
#include "net/net.h"
30
ARMCPU cpu;
71
#include "hw/block/flash.h"
31
- MemoryRegion iomem;
72
-#include "hw/devices.h"
32
MemoryRegion sram;
73
+#include "hw/net/smc91c111.h"
33
AspeedVICState vic;
74
#include "hw/boards.h"
34
AspeedTimerCtrlState timerctrl;
75
#include "exec/address-spaces.h"
35
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
76
#include "sysemu/qtest.h"
77
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
36
index XXXXXXX..XXXXXXX 100644
78
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/arm/aspeed_soc.c
79
--- a/hw/arm/integratorcp.c
38
+++ b/hw/arm/aspeed_soc.c
80
+++ b/hw/arm/integratorcp.c
39
@@ -XXX,XX +XXX,XX @@
81
@@ -XXX,XX +XXX,XX @@
40
#include "qemu-common.h"
82
#include "qemu-common.h"
41
#include "cpu.h"
83
#include "cpu.h"
84
#include "hw/sysbus.h"
85
-#include "hw/devices.h"
86
#include "hw/boards.h"
87
#include "hw/arm/arm.h"
88
#include "hw/misc/arm_integrator_debug.h"
89
+#include "hw/net/smc91c111.h"
90
#include "net/net.h"
42
#include "exec/address-spaces.h"
91
#include "exec/address-spaces.h"
43
+#include "hw/misc/unimp.h"
92
#include "sysemu/sysemu.h"
44
#include "hw/arm/aspeed_soc.h"
93
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
45
#include "hw/char/serial.h"
94
index XXXXXXX..XXXXXXX 100644
95
--- a/hw/arm/mainstone.c
96
+++ b/hw/arm/mainstone.c
97
@@ -XXX,XX +XXX,XX @@
98
#include "hw/arm/pxa.h"
99
#include "hw/arm/arm.h"
100
#include "net/net.h"
101
-#include "hw/devices.h"
102
+#include "hw/net/smc91c111.h"
103
#include "hw/boards.h"
104
#include "hw/block/flash.h"
105
#include "hw/sysbus.h"
106
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/hw/arm/realview.c
109
+++ b/hw/arm/realview.c
110
@@ -XXX,XX +XXX,XX @@
111
#include "hw/sysbus.h"
112
#include "hw/arm/arm.h"
113
#include "hw/arm/primecell.h"
114
-#include "hw/devices.h"
115
#include "hw/net/lan9118.h"
116
+#include "hw/net/smc91c111.h"
117
#include "hw/pci/pci.h"
118
#include "net/net.h"
119
#include "sysemu/sysemu.h"
120
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
121
index XXXXXXX..XXXXXXX 100644
122
--- a/hw/arm/versatilepb.c
123
+++ b/hw/arm/versatilepb.c
124
@@ -XXX,XX +XXX,XX @@
125
#include "cpu.h"
126
#include "hw/sysbus.h"
127
#include "hw/arm/arm.h"
128
-#include "hw/devices.h"
129
+#include "hw/net/smc91c111.h"
130
#include "net/net.h"
131
#include "sysemu/sysemu.h"
132
#include "hw/pci/pci.h"
133
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/hw/net/smc91c111.c
136
+++ b/hw/net/smc91c111.c
137
@@ -XXX,XX +XXX,XX @@
138
#include "qemu/osdep.h"
139
#include "hw/sysbus.h"
140
#include "net/net.h"
141
-#include "hw/devices.h"
142
+#include "hw/net/smc91c111.h"
46
#include "qemu/log.h"
143
#include "qemu/log.h"
47
@@ -XXX,XX +XXX,XX @@ static const AspeedSoCInfo aspeed_socs[] = {
144
/* For crc32 */
48
},
145
#include <zlib.h>
49
};
50
51
-/*
52
- * IO handlers: simply catch any reads/writes to IO addresses that aren't
53
- * handled by a device mapping.
54
- */
55
-
56
-static uint64_t aspeed_soc_io_read(void *p, hwaddr offset, unsigned size)
57
-{
58
- qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n",
59
- __func__, offset, size);
60
- return 0;
61
-}
62
-
63
-static void aspeed_soc_io_write(void *opaque, hwaddr offset, uint64_t value,
64
- unsigned size)
65
-{
66
- qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " <- 0x%" PRIx64 " [%u]\n",
67
- __func__, offset, value, size);
68
-}
69
-
70
-static const MemoryRegionOps aspeed_soc_io_ops = {
71
- .read = aspeed_soc_io_read,
72
- .write = aspeed_soc_io_write,
73
- .endianness = DEVICE_LITTLE_ENDIAN,
74
-};
75
-
76
static void aspeed_soc_init(Object *obj)
77
{
78
AspeedSoCState *s = ASPEED_SOC(obj);
79
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
80
Error *err = NULL, *local_err = NULL;
81
82
/* IO space */
83
- memory_region_init_io(&s->iomem, NULL, &aspeed_soc_io_ops, NULL,
84
- "aspeed_soc.io", ASPEED_SOC_IOMEM_SIZE);
85
- memory_region_add_subregion_overlap(get_system_memory(),
86
- ASPEED_SOC_IOMEM_BASE, &s->iomem, -1);
87
+ create_unimplemented_device("aspeed_soc.io",
88
+ ASPEED_SOC_IOMEM_BASE, ASPEED_SOC_IOMEM_SIZE);
89
90
/* CPU */
91
object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);
92
--
146
--
93
2.16.1
147
2.20.1
94
148
95
149
diff view generated by jsdifflib