1
First pullreq for arm of the 4.1 series, since I'm back from
1
First arm pullreq for 6.1 cycle. The big stuff here is RTH's alignment series.
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...
6
2
7
thanks
3
thanks
8
-- PMM
4
-- PMM
9
5
10
The following changes since commit 413a99a92c13ec408dcf2adaa87918dc81e890c8:
6
The following changes since commit ccdf06c1db192152ac70a1dd974c624f566cb7d4:
11
7
12
Add Nios II semihosting support. (2019-04-29 16:09:51 +0100)
8
Open 6.1 development tree (2021-04-30 11:15:40 +0100)
13
9
14
are available in the Git repository at:
10
are available in the Git repository at:
15
11
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190429
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210430
17
13
18
for you to fetch changes up to 437cc27ddfded3bbab6afd5ac1761e0e195edba7:
14
for you to fetch changes up to a6091108aa44e9017af4ca13c43f55a629e3744c:
19
15
20
hw/devices: Move SMSC 91C111 declaration into a new header (2019-04-29 17:57:21 +0100)
16
hw/pci-host/gpex: Don't fault for unmapped parts of MMIO and PIO windows (2021-04-30 11:16:52 +0100)
21
17
22
----------------------------------------------------------------
18
----------------------------------------------------------------
23
target-arm queue:
19
target-arm queue:
24
* remove "bag of random stuff" hw/devices.h header
20
* hw/pci-host/gpex: Don't fault for unmapped parts of MMIO and PIO windows
25
* implement FPU for Cortex-M and enable it for Cortex-M4 and -M33
21
* hw: add compat machines for 6.1
26
* hw/dma: Compile the bcm2835_dma device as common object
22
* Fault misaligned accesses where the architecture requires it
27
* configure: Remove --source-path option
23
* Fix some corner cases of MTE faults (notably with misaligned accesses)
28
* hw/ssi/xilinx_spips: Avoid variable length array
24
* Make Thumb store insns UNDEF for Rn==1111
29
* hw/arm/smmuv3: Remove SMMUNotifierNode
25
* hw/arm/smmuv3: Support 16K translation granule
30
26
31
----------------------------------------------------------------
27
----------------------------------------------------------------
32
Eric Auger (1):
28
Cornelia Huck (1):
33
hw/arm/smmuv3: Remove SMMUNotifierNode
29
hw: add compat machines for 6.1
34
30
35
Peter Maydell (28):
31
Kunkun Jiang (1):
36
hw/ssi/xilinx_spips: Avoid variable length array
32
hw/arm/smmuv3: Support 16K translation granule
37
configure: Remove --source-path option
38
target/arm: Make sure M-profile FPSCR RES0 bits are not settable
39
hw/intc/armv7m_nvic: Allow reading of M-profile MVFR* registers
40
target/arm: Implement dummy versions of M-profile FP-related registers
41
target/arm: Disable most VFP sysregs for M-profile
42
target/arm: Honour M-profile FP enable bits
43
target/arm: Decode FP instructions for M profile
44
target/arm: Clear CONTROL_S.SFPA in SG insn if FPU present
45
target/arm: Handle SFPA and FPCA bits in reads and writes of CONTROL
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
64
33
65
Philippe Mathieu-Daudé (13):
34
Peter Maydell (2):
66
hw/dma: Compile the bcm2835_dma device as common object
35
target/arm: Make Thumb store insns UNDEF for Rn==1111
67
hw/arm/aspeed: Use TYPE_TMP105/TYPE_PCA9552 instead of hardcoded string
36
hw/pci-host/gpex: Don't fault for unmapped parts of MMIO and PIO windows
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
79
37
80
configure | 10 +-
38
Richard Henderson (39):
81
hw/dma/Makefile.objs | 2 +-
39
target/arm: Fix mte_checkN
82
include/hw/arm/omap.h | 6 +-
40
target/arm: Split out mte_probe_int
83
include/hw/arm/smmu-common.h | 8 +-
41
target/arm: Fix unaligned checks for mte_check1, mte_probe1
84
include/hw/devices.h | 62 ---
42
test/tcg/aarch64: Add mte-5
85
include/hw/display/blizzard.h | 22 ++
43
target/arm: Replace MTEDESC ESIZE+TSIZE with SIZEM1
86
include/hw/display/tc6393xb.h | 24 ++
44
target/arm: Merge mte_check1, mte_checkN
87
include/hw/input/gamepad.h | 19 +
45
target/arm: Rename mte_probe1 to mte_probe
88
include/hw/input/tsc2xxx.h | 36 ++
46
target/arm: Simplify sve mte checking
89
include/hw/misc/cbus.h | 32 ++
47
target/arm: Remove log2_esize parameter to gen_mte_checkN
90
include/hw/net/lan9118.h | 21 +
48
target/arm: Fix decode of align in VLDST_single
91
include/hw/net/ne2000-isa.h | 6 +
49
target/arm: Rename TBFLAG_A32, SCTLR_B
92
include/hw/net/smc91c111.h | 19 +
50
target/arm: Rename TBFLAG_ANY, PSTATE_SS
93
include/qemu/typedefs.h | 1 -
51
target/arm: Add wrapper macros for accessing tbflags
94
target/arm/cpu.h | 95 ++++-
52
target/arm: Introduce CPUARMTBFlags
95
target/arm/helper.h | 5 +
53
target/arm: Move mode specific TB flags to tb->cs_base
96
target/arm/translate.h | 3 +
54
target/arm: Move TBFLAG_AM32 bits to the top
97
hw/arm/aspeed.c | 13 +-
55
target/arm: Move TBFLAG_ANY bits to the bottom
98
hw/arm/exynos4_boards.c | 3 +-
56
target/arm: Add ALIGN_MEM to TBFLAG_ANY
99
hw/arm/gumstix.c | 2 +-
57
target/arm: Adjust gen_aa32_{ld, st}_i32 for align+endianness
100
hw/arm/integratorcp.c | 2 +-
58
target/arm: Merge gen_aa32_frob64 into gen_aa32_ld_i64
101
hw/arm/kzm.c | 2 +-
59
target/arm: Fix SCTLR_B test for TCGv_i64 load/store
102
hw/arm/mainstone.c | 2 +-
60
target/arm: Adjust gen_aa32_{ld, st}_i64 for align+endianness
103
hw/arm/mps2-tz.c | 3 +-
61
target/arm: Enforce word alignment for LDRD/STRD
104
hw/arm/mps2.c | 2 +-
62
target/arm: Enforce alignment for LDA/LDAH/STL/STLH
105
hw/arm/nseries.c | 7 +-
63
target/arm: Enforce alignment for LDM/STM
106
hw/arm/palm.c | 2 +-
64
target/arm: Enforce alignment for RFE
107
hw/arm/realview.c | 3 +-
65
target/arm: Enforce alignment for SRS
108
hw/arm/smmu-common.c | 6 +-
66
target/arm: Enforce alignment for VLDM/VSTM
109
hw/arm/smmuv3.c | 28 +-
67
target/arm: Enforce alignment for VLDR/VSTR
110
hw/arm/stellaris.c | 2 +-
68
target/arm: Enforce alignment for VLDn (all lanes)
111
hw/arm/tosa.c | 2 +-
69
target/arm: Enforce alignment for VLDn/VSTn (multiple)
112
hw/arm/versatilepb.c | 2 +-
70
target/arm: Enforce alignment for VLDn/VSTn (single)
113
hw/arm/vexpress.c | 2 +-
71
target/arm: Use finalize_memop for aa64 gpr load/store
114
hw/display/blizzard.c | 2 +-
72
target/arm: Use finalize_memop for aa64 fpr load/store
115
hw/display/tc6393xb.c | 18 +-
73
target/arm: Enforce alignment for aa64 load-acq/store-rel
116
hw/input/stellaris_input.c | 2 +-
74
target/arm: Use MemOp for size + endian in aa64 vector ld/st
117
hw/input/tsc2005.c | 2 +-
75
target/arm: Enforce alignment for aa64 vector LDn/STn (multiple)
118
hw/input/tsc210x.c | 4 +-
76
target/arm: Enforce alignment for aa64 vector LDn/STn (single)
119
hw/intc/armv7m_nvic.c | 261 +++++++++++++
77
target/arm: Enforce alignment for sve LD1R
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
139
78
79
include/hw/boards.h | 3 +
80
include/hw/i386/pc.h | 3 +
81
include/hw/pci-host/gpex.h | 4 +
82
target/arm/cpu.h | 105 ++++++++++-----
83
target/arm/helper-a64.h | 3 +-
84
target/arm/internals.h | 11 +-
85
target/arm/translate-a64.h | 2 +-
86
target/arm/translate.h | 38 ++++++
87
target/arm/neon-ls.decode | 4 +-
88
hw/arm/smmuv3.c | 6 +-
89
hw/arm/virt.c | 7 +-
90
hw/core/machine.c | 5 +
91
hw/i386/pc.c | 3 +
92
hw/i386/pc_piix.c | 14 +-
93
hw/i386/pc_q35.c | 13 +-
94
hw/pci-host/gpex.c | 56 +++++++-
95
hw/ppc/spapr.c | 17 ++-
96
hw/s390x/s390-virtio-ccw.c | 14 +-
97
target/arm/helper-a64.c | 2 +-
98
target/arm/helper.c | 162 ++++++++++++----------
99
target/arm/mte_helper.c | 185 ++++++++++---------------
100
target/arm/sve_helper.c | 100 +++++---------
101
target/arm/translate-a64.c | 236 ++++++++++++++++----------------
102
target/arm/translate-sve.c | 11 +-
103
target/arm/translate.c | 274 ++++++++++++++++++++++----------------
104
tests/tcg/aarch64/mte-5.c | 44 ++++++
105
target/arm/translate-neon.c.inc | 117 ++++++++++++----
106
target/arm/translate-vfp.c.inc | 20 +--
107
tests/tcg/aarch64/Makefile.target | 2 +-
108
29 files changed, 878 insertions(+), 583 deletions(-)
109
create mode 100644 tests/tcg/aarch64/mte-5.c
110
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Kunkun Jiang <jiangkunkun@huawei.com>
2
2
3
The SMMUNotifierNode struct is not necessary and brings extra
3
The driver can query some bits in SMMUv3 IDR5 to learn which
4
complexity so let's remove it. We now directly track the SMMUDevices
4
translation granules are supported. Arm recommends that SMMUv3
5
which have registered IOMMU MR notifiers.
5
implementations support at least 4K and 64K granules. But in
6
the vSMMUv3, there seems to be no reason not to support 16K
7
translation granule. In addition, if 16K is not supported,
8
vSVA will failed to be enabled in the future for 16K guest
9
kernel. So it'd better to support it.
6
10
7
This is inspired from the same transformation on intel-iommu
11
Signed-off-by: Kunkun Jiang <jiangkunkun@huawei.com>
8
done in commit b4a4ba0d68f50f218ee3957b6638dbee32a5eeef
12
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
("intel-iommu: remove IntelIOMMUNotifierNode")
13
Tested-by: Eric Auger <eric.auger@redhat.com>
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
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
15
---
16
include/hw/arm/smmu-common.h | 8 ++------
16
hw/arm/smmuv3.c | 6 ++++--
17
hw/arm/smmu-common.c | 6 +++---
17
1 file changed, 4 insertions(+), 2 deletions(-)
18
hw/arm/smmuv3.c | 28 +++++++---------------------
19
3 files changed, 12 insertions(+), 30 deletions(-)
20
18
21
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/smmu-common.h
24
+++ b/include/hw/arm/smmu-common.h
25
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUDevice {
26
AddressSpace as;
27
uint32_t cfg_cache_hits;
28
uint32_t cfg_cache_misses;
29
+ QLIST_ENTRY(SMMUDevice) next;
30
} SMMUDevice;
31
32
-typedef struct SMMUNotifierNode {
33
- SMMUDevice *sdev;
34
- QLIST_ENTRY(SMMUNotifierNode) next;
35
-} SMMUNotifierNode;
36
-
37
typedef struct SMMUPciBus {
38
PCIBus *bus;
39
SMMUDevice *pbdev[0]; /* Parent array is sparse, so dynamically alloc */
40
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUState {
41
GHashTable *iotlb;
42
SMMUPciBus *smmu_pcibus_by_bus_num[SMMU_PCI_BUS_MAX];
43
PCIBus *pci_bus;
44
- QLIST_HEAD(, SMMUNotifierNode) notifiers_list;
45
+ QLIST_HEAD(, SMMUDevice) devices_with_notifiers;
46
uint8_t bus_num;
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)
56
{
57
- SMMUNotifierNode *node;
58
+ SMMUDevice *sdev;
59
60
- QLIST_FOREACH(node, &s->notifiers_list, next) {
61
- smmu_inv_notifiers_mr(&node->sdev->iommu);
62
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
63
+ smmu_inv_notifiers_mr(&sdev->iommu);
64
}
65
}
66
67
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
19
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
68
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
69
--- a/hw/arm/smmuv3.c
21
--- a/hw/arm/smmuv3.c
70
+++ b/hw/arm/smmuv3.c
22
+++ b/hw/arm/smmuv3.c
71
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
23
@@ -XXX,XX +XXX,XX @@ static void smmuv3_init_regs(SMMUv3State *s)
72
/* invalidate an asid/iova tuple in all mr's */
24
s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, 1);
73
static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova)
25
s->idr[3] = FIELD_DP32(s->idr[3], IDR3, HAD, 1);
74
{
26
75
- SMMUNotifierNode *node;
27
- /* 4K and 64K granule support */
76
+ SMMUDevice *sdev;
28
+ /* 4K, 16K and 64K granule support */
77
29
s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN4K, 1);
78
- QLIST_FOREACH(node, &s->notifiers_list, next) {
30
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN16K, 1);
79
- IOMMUMemoryRegion *mr = &node->sdev->iommu;
31
s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN64K, 1);
80
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
32
s->idr[5] = FIELD_DP32(s->idr[5], IDR5, OAS, SMMU_IDR5_OAS); /* 44 bits */
81
+ IOMMUMemoryRegion *mr = &sdev->iommu;
33
82
IOMMUNotifier *n;
34
@@ -XXX,XX +XXX,XX @@ static int decode_cd(SMMUTransCfg *cfg, CD *cd, SMMUEventInfo *event)
83
35
84
trace_smmuv3_inv_notifiers_iova(mr->parent_obj.name, asid, iova);
36
tg = CD_TG(cd, i);
85
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
37
tt->granule_sz = tg2granule(tg, i);
86
SMMUDevice *sdev = container_of(iommu, SMMUDevice, iommu);
38
- if ((tt->granule_sz != 12 && tt->granule_sz != 16) || CD_ENDI(cd)) {
87
SMMUv3State *s3 = sdev->smmu;
39
+ if ((tt->granule_sz != 12 && tt->granule_sz != 14 &&
88
SMMUState *s = &(s3->smmu_state);
40
+ tt->granule_sz != 16) || CD_ENDI(cd)) {
89
- SMMUNotifierNode *node = NULL;
41
goto bad_cd;
90
- SMMUNotifierNode *next_node = NULL;
42
}
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
- }
103
-
104
- /* update notifier node with new flags */
105
- QLIST_FOREACH_SAFE(node, &s->notifiers_list, next, next_node) {
106
- if (node->sdev == sdev) {
107
- if (new == IOMMU_NOTIFIER_NONE) {
108
- trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
109
- QLIST_REMOVE(node, next);
110
- g_free(node);
111
- }
112
- return;
113
- }
114
+ QLIST_INSERT_HEAD(&s->devices_with_notifiers, sdev, next);
115
+ } else if (new == IOMMU_NOTIFIER_NONE) {
116
+ trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
117
+ QLIST_REMOVE(sdev, next);
118
}
119
}
120
43
121
--
44
--
122
2.20.1
45
2.20.1
123
46
124
47
diff view generated by jsdifflib
1
Handle floating point registers in exception return.
1
The Arm ARM specifies that for Thumb encodings of the various plain
2
This corresponds to pseudocode functions ValidateExceptionReturn(),
2
store insns, if the Rn field is 1111 then we must UNDEF. This is
3
ExceptionReturn(), PopStack() and ConsumeExcStackFrame().
3
different from the Arm encodings, where this case is either
4
UNPREDICTABLE or has well-defined behaviour. The exclusive stores,
5
store-release and STRD do not have this UNDEF case for any encoding.
4
6
7
Enforce the UNDEF for this case in the Thumb plain store insns.
8
9
Fixes: https://bugs.launchpad.net/qemu/+bug/1922887
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190416125744.27770-16-peter.maydell@linaro.org
12
Message-id: 20210408162402.5822-1-peter.maydell@linaro.org
8
---
13
---
9
target/arm/helper.c | 142 +++++++++++++++++++++++++++++++++++++++++++-
14
target/arm/translate.c | 16 ++++++++++++++++
10
1 file changed, 141 insertions(+), 1 deletion(-)
15
1 file changed, 16 insertions(+)
11
16
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
diff --git a/target/arm/translate.c b/target/arm/translate.c
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
19
--- a/target/arm/translate.c
15
+++ b/target/arm/helper.c
20
+++ b/target/arm/translate.c
16
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
21
@@ -XXX,XX +XXX,XX @@ static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
17
bool rettobase = false;
22
ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
18
bool exc_secure = false;
23
TCGv_i32 addr, tmp;
19
bool return_to_secure;
24
20
+ bool ftype;
25
+ /*
21
+ bool restore_s16_s31;
26
+ * In Thumb encodings of stores Rn=1111 is UNDEF; for Arm it
22
27
+ * is either UNPREDICTABLE or has defined behaviour
23
/* If we're not in Handler mode then jumps to magic exception-exit
28
+ */
24
* addresses don't have magic behaviour. However for the v8M
29
+ if (s->thumb && a->rn == 15) {
25
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
30
+ return false;
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
+ }
31
+ }
38
+
32
+
39
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
33
addr = op_addr_rr_pre(s, a);
40
/* EXC_RETURN.ES validation check (R_SMFL). We must do this before
34
41
* we pick which FAULTMASK to clear.
35
tmp = load_reg(s, a->rt);
42
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
36
@@ -XXX,XX +XXX,XX @@ static bool op_store_ri(DisasContext *s, arg_ldst_ri *a,
43
*/
37
ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
44
write_v7m_control_spsel_for_secstate(env, return_to_sp_process, exc_secure);
38
TCGv_i32 addr, tmp;
45
39
46
+ /*
40
+ /*
47
+ * Clear scratch FP values left in caller saved registers; this
41
+ * In Thumb encodings of stores Rn=1111 is UNDEF; for Arm it
48
+ * must happen before any kind of tail chaining.
42
+ * is either UNPREDICTABLE or has defined behaviour
49
+ */
43
+ */
50
+ if ((env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_CLRONRET_MASK) &&
44
+ if (s->thumb && a->rn == 15) {
51
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
45
+ return false;
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
+ }
46
+ }
69
+
47
+
70
if (sfault) {
48
addr = op_addr_ri_pre(s, a);
71
env->v7m.sfsr |= R_V7M_SFSR_INVER_MASK;
49
72
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
50
tmp = load_reg(s, a->rt);
73
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
74
}
75
}
76
77
+ if (!ftype) {
78
+ /* FP present and we need to handle it */
79
+ if (!return_to_secure &&
80
+ (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK)) {
81
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
82
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
83
+ qemu_log_mask(CPU_LOG_INT,
84
+ "...taking SecureFault on existing stackframe: "
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;
181
}
182
/* This xpsr_write() will invalidate frame_sp_p as it may switch stack */
183
- xpsr_write(env, xpsr, ~XPSR_SPREALIGN);
184
+ xpsr_write(env, xpsr, ~(XPSR_SPREALIGN | XPSR_SFPA));
185
+
186
+ if (env->v7m.secure) {
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
195
--
51
--
196
2.20.1
52
2.20.1
197
53
198
54
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
We were incorrectly assuming that only the first byte of an MTE access
4
is checked against the tags. But per the ARM, unaligned accesses are
5
pre-decomposed into single-byte accesses. So by the time we reach the
6
actual MTE check in the ARM pseudocode, all accesses are aligned.
7
8
Therefore, the first failure is always either the first byte of the
9
access, or the first byte of the granule.
10
11
In addition, some of the arithmetic is off for last-first -> count.
12
This does not become directly visible until a later patch that passes
13
single bytes into this function, so ptr == ptr_last.
14
15
Buglink: https://bugs.launchpad.net/bugs/1921948
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20210416183106.1516563-2-richard.henderson@linaro.org
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
[PMM: tweaked a comment]
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
22
target/arm/mte_helper.c | 40 ++++++++++++++++++----------------------
23
1 file changed, 18 insertions(+), 22 deletions(-)
24
25
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/mte_helper.c
28
+++ b/target/arm/mte_helper.c
29
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
30
uint64_t ptr, uintptr_t ra)
31
{
32
int mmu_idx, ptr_tag, bit55;
33
- uint64_t ptr_last, ptr_end, prev_page, next_page;
34
- uint64_t tag_first, tag_end;
35
- uint64_t tag_byte_first, tag_byte_end;
36
- uint32_t esize, total, tag_count, tag_size, n, c;
37
+ uint64_t ptr_last, prev_page, next_page;
38
+ uint64_t tag_first, tag_last;
39
+ uint64_t tag_byte_first, tag_byte_last;
40
+ uint32_t total, tag_count, tag_size, n, c;
41
uint8_t *mem1, *mem2;
42
MMUAccessType type;
43
44
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
45
46
mmu_idx = FIELD_EX32(desc, MTEDESC, MIDX);
47
type = FIELD_EX32(desc, MTEDESC, WRITE) ? MMU_DATA_STORE : MMU_DATA_LOAD;
48
- esize = FIELD_EX32(desc, MTEDESC, ESIZE);
49
total = FIELD_EX32(desc, MTEDESC, TSIZE);
50
51
- /* Find the addr of the end of the access, and of the last element. */
52
- ptr_end = ptr + total;
53
- ptr_last = ptr_end - esize;
54
+ /* Find the addr of the end of the access */
55
+ ptr_last = ptr + total - 1;
56
57
/* Round the bounds to the tag granule, and compute the number of tags. */
58
tag_first = QEMU_ALIGN_DOWN(ptr, TAG_GRANULE);
59
- tag_end = QEMU_ALIGN_UP(ptr_last, TAG_GRANULE);
60
- tag_count = (tag_end - tag_first) / TAG_GRANULE;
61
+ tag_last = QEMU_ALIGN_DOWN(ptr_last, TAG_GRANULE);
62
+ tag_count = ((tag_last - tag_first) / TAG_GRANULE) + 1;
63
64
/* Round the bounds to twice the tag granule, and compute the bytes. */
65
tag_byte_first = QEMU_ALIGN_DOWN(ptr, 2 * TAG_GRANULE);
66
- tag_byte_end = QEMU_ALIGN_UP(ptr_last, 2 * TAG_GRANULE);
67
+ tag_byte_last = QEMU_ALIGN_DOWN(ptr_last, 2 * TAG_GRANULE);
68
69
/* Locate the page boundaries. */
70
prev_page = ptr & TARGET_PAGE_MASK;
71
next_page = prev_page + TARGET_PAGE_SIZE;
72
73
- if (likely(tag_end - prev_page <= TARGET_PAGE_SIZE)) {
74
+ if (likely(tag_last - prev_page <= TARGET_PAGE_SIZE)) {
75
/* Memory access stays on one page. */
76
- tag_size = (tag_byte_end - tag_byte_first) / (2 * TAG_GRANULE);
77
+ tag_size = ((tag_byte_last - tag_byte_first) / (2 * TAG_GRANULE)) + 1;
78
mem1 = allocation_tag_mem(env, mmu_idx, ptr, type, total,
79
MMU_DATA_LOAD, tag_size, ra);
80
if (!mem1) {
81
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
82
mem1 = allocation_tag_mem(env, mmu_idx, ptr, type, next_page - ptr,
83
MMU_DATA_LOAD, tag_size, ra);
84
85
- tag_size = (tag_byte_end - next_page) / (2 * TAG_GRANULE);
86
+ tag_size = ((tag_byte_last - next_page) / (2 * TAG_GRANULE)) + 1;
87
mem2 = allocation_tag_mem(env, mmu_idx, next_page, type,
88
- ptr_end - next_page,
89
+ ptr_last - next_page + 1,
90
MMU_DATA_LOAD, tag_size, ra);
91
92
/*
93
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
94
}
95
96
/*
97
- * If we failed, we know which granule. Compute the element that
98
- * is first in that granule, and signal failure on that element.
99
+ * If we failed, we know which granule. For the first granule, the
100
+ * failure address is @ptr, the first byte accessed. Otherwise the
101
+ * failure address is the first byte of the nth granule.
102
*/
103
if (unlikely(n < tag_count)) {
104
- uint64_t fail_ofs;
105
-
106
- fail_ofs = tag_first + n * TAG_GRANULE - ptr;
107
- fail_ofs = ROUND_UP(fail_ofs, esize);
108
- mte_check_fail(env, desc, ptr + fail_ofs, ra);
109
+ uint64_t fault = (n == 0 ? ptr : tag_first + n * TAG_GRANULE);
110
+ mte_check_fail(env, desc, fault, ra);
111
}
112
113
done:
114
--
115
2.20.1
116
117
diff view generated by jsdifflib
1
Handle floating point registers in exception entry.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
This corresponds to the FP-specific parts of the pseudocode
3
functions ActivateException() and PushStack().
4
2
5
We defer the code corresponding to UpdateFPCCR() to a later patch.
3
Split out a helper function from mte_checkN to perform
4
all of the checking and address manpulation. So far,
5
just use this in mte_checkN itself.
6
6
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210416183106.1516563-3-richard.henderson@linaro.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-11-peter.maydell@linaro.org
10
---
12
---
11
target/arm/helper.c | 98 +++++++++++++++++++++++++++++++++++++++++++--
13
target/arm/mte_helper.c | 52 +++++++++++++++++++++++++++++++----------
12
1 file changed, 95 insertions(+), 3 deletions(-)
14
1 file changed, 40 insertions(+), 12 deletions(-)
13
15
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
18
--- a/target/arm/mte_helper.c
17
+++ b/target/arm/helper.c
19
+++ b/target/arm/mte_helper.c
18
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
20
@@ -XXX,XX +XXX,XX @@ static int checkN(uint8_t *mem, int odd, int cmp, int count)
19
switch_v7m_security_state(env, targets_secure);
21
return n;
20
write_v7m_control_spsel(env, 0);
22
}
21
arm_clear_exclusive(env);
23
22
+ /* Clear SFPA and FPCA (has no effect if no FPU) */
24
-uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
23
+ env->v7m.control[M_REG_S] &=
25
- uint64_t ptr, uintptr_t ra)
24
+ ~(R_V7M_CONTROL_FPCA_MASK | R_V7M_CONTROL_SFPA_MASK);
26
+/**
25
/* Clear IT bits */
27
+ * mte_probe_int() - helper for mte_probe and mte_check
26
env->condexec_bits = 0;
28
+ * @env: CPU environment
27
env->regs[14] = lr;
29
+ * @desc: MTEDESC descriptor
28
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
30
+ * @ptr: virtual address of the base of the access
29
uint32_t xpsr = xpsr_read(env);
31
+ * @fault: return virtual address of the first check failure
30
uint32_t frameptr = env->regs[13];
32
+ *
31
ARMMMUIdx mmu_idx = arm_mmu_idx(env);
33
+ * Internal routine for both mte_probe and mte_check.
32
+ uint32_t framesize;
34
+ * Return zero on failure, filling in *fault.
33
+ bool nsacr_cp10 = extract32(env->v7m.nsacr, 10, 1);
35
+ * Return negative on trivial success for tbi disabled.
34
+
36
+ * Return positive on success with tbi enabled.
35
+ if ((env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) &&
37
+ */
36
+ (env->v7m.secure || nsacr_cp10)) {
38
+static int mte_probe_int(CPUARMState *env, uint32_t desc, uint64_t ptr,
37
+ if (env->v7m.secure &&
39
+ uintptr_t ra, uint32_t total, uint64_t *fault)
38
+ env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK) {
40
{
39
+ framesize = 0xa8;
41
int mmu_idx, ptr_tag, bit55;
40
+ } else {
42
uint64_t ptr_last, prev_page, next_page;
41
+ framesize = 0x68;
43
uint64_t tag_first, tag_last;
42
+ }
44
uint64_t tag_byte_first, tag_byte_last;
43
+ } else {
45
- uint32_t total, tag_count, tag_size, n, c;
44
+ framesize = 0x20;
46
+ uint32_t tag_count, tag_size, n, c;
45
+ }
47
uint8_t *mem1, *mem2;
46
48
MMUAccessType type;
47
/* Align stack pointer if the guest wants that */
49
48
if ((frameptr & 4) &&
50
bit55 = extract64(ptr, 55, 1);
49
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
51
+ *fault = ptr;
50
xpsr |= XPSR_SPREALIGN;
52
53
/* If TBI is disabled, the access is unchecked, and ptr is not dirty. */
54
if (unlikely(!tbi_check(desc, bit55))) {
55
- return ptr;
56
+ return -1;
51
}
57
}
52
58
53
- frameptr -= 0x20;
59
ptr_tag = allocation_tag_from_addr(ptr);
54
+ xpsr &= ~XPSR_SFPA;
60
55
+ if (env->v7m.secure &&
61
if (tcma_check(desc, bit55, ptr_tag)) {
56
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
62
- goto done;
57
+ xpsr |= XPSR_SFPA;
63
+ return 1;
58
+ }
64
}
59
+
65
60
+ frameptr -= framesize;
66
mmu_idx = FIELD_EX32(desc, MTEDESC, MIDX);
61
67
type = FIELD_EX32(desc, MTEDESC, WRITE) ? MMU_DATA_STORE : MMU_DATA_LOAD;
62
if (arm_feature(env, ARM_FEATURE_V8)) {
68
- total = FIELD_EX32(desc, MTEDESC, TSIZE);
63
uint32_t limit = v7m_sp_limit(env);
69
64
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
70
/* Find the addr of the end of the access */
65
v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
71
ptr_last = ptr + total - 1;
66
v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
72
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
67
73
mem1 = allocation_tag_mem(env, mmu_idx, ptr, type, total,
68
+ if (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) {
74
MMU_DATA_LOAD, tag_size, ra);
69
+ /* FPU is active, try to save its registers */
75
if (!mem1) {
70
+ bool fpccr_s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
76
- goto done;
71
+ bool lspact = env->v7m.fpccr[fpccr_s] & R_V7M_FPCCR_LSPACT_MASK;
77
+ return 1;
72
+
78
}
73
+ if (lspact && arm_feature(env, ARM_FEATURE_M_SECURITY)) {
79
/* Perform all of the comparisons. */
74
+ qemu_log_mask(CPU_LOG_INT,
80
n = checkN(mem1, ptr & TAG_GRANULE, ptr_tag, tag_count);
75
+ "...SecureFault because LSPACT and FPCA both set\n");
81
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
76
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
82
}
77
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
83
if (n == c) {
78
+ } else if (!env->v7m.secure && !nsacr_cp10) {
84
if (!mem2) {
79
+ qemu_log_mask(CPU_LOG_INT,
85
- goto done;
80
+ "...Secure UsageFault with CFSR.NOCP because "
86
+ return 1;
81
+ "NSACR.CP10 prevents stacking FP regs\n");
87
}
82
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
88
n += checkN(mem2, 0, ptr_tag, tag_count - c);
83
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
89
}
84
+ } else {
90
}
85
+ if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) {
91
86
+ /* Lazy stacking disabled, save registers now */
92
+ if (likely(n == tag_count)) {
87
+ int i;
93
+ return 1;
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
+ }
94
+ }
134
+
95
+
135
/*
96
/*
136
* If we broke a stack limit then SP was already updated earlier;
97
* If we failed, we know which granule. For the first granule, the
137
* otherwise we update SP regardless of whether any of the stack
98
* failure address is @ptr, the first byte accessed. Otherwise the
138
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
99
* failure address is the first byte of the nth granule.
139
100
*/
140
if (arm_feature(env, ARM_FEATURE_V8)) {
101
- if (unlikely(n < tag_count)) {
141
lr = R_V7M_EXCRET_RES1_MASK |
102
- uint64_t fault = (n == 0 ? ptr : tag_first + n * TAG_GRANULE);
142
- R_V7M_EXCRET_DCRS_MASK |
103
- mte_check_fail(env, desc, fault, ra);
143
- R_V7M_EXCRET_FTYPE_MASK;
104
+ if (n > 0) {
144
+ R_V7M_EXCRET_DCRS_MASK;
105
+ *fault = tag_first + n * TAG_GRANULE;
145
/* The S bit indicates whether we should return to Secure
106
}
146
* or NonSecure (ie our current state).
107
+ return 0;
147
* The ES bit indicates whether we're taking this exception
108
+}
148
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
109
149
if (env->v7m.secure) {
110
- done:
150
lr |= R_V7M_EXCRET_S_MASK;
111
+uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
151
}
112
+ uint64_t ptr, uintptr_t ra)
152
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
113
+{
153
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
114
+ uint64_t fault;
154
+ }
115
+ uint32_t total = FIELD_EX32(desc, MTEDESC, TSIZE);
155
} else {
116
+ int ret = mte_probe_int(env, desc, ptr, ra, total, &fault);
156
lr = R_V7M_EXCRET_RES1_MASK |
117
+
157
R_V7M_EXCRET_S_MASK |
118
+ if (unlikely(ret == 0)) {
119
+ mte_check_fail(env, desc, fault, ra);
120
+ } else if (ret < 0) {
121
+ return ptr;
122
+ }
123
return useronly_clean_ptr(ptr);
124
}
125
158
--
126
--
159
2.20.1
127
2.20.1
160
128
161
129
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
No code used the tc6393xb_gpio_in_get() and tc6393xb_gpio_out_set()
3
We were incorrectly assuming that only the first byte of an MTE access
4
functions since their introduction in commit 88d2c950b002. Time to
4
is checked against the tags. But per the ARM, unaligned accesses are
5
remove them.
5
pre-decomposed into single-byte accesses. So by the time we reach the
6
actual MTE check in the ARM pseudocode, all accesses are aligned.
6
7
7
Suggested-by: Markus Armbruster <armbru@redhat.com>
8
We cannot tell a priori whether or not a given scalar access is aligned,
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
therefore we must at least check. Use mte_probe_int, which is already
9
Message-id: 20190412165416.7977-4-philmd@redhat.com
10
set up for checking multiple granules.
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
12
Buglink: https://bugs.launchpad.net/bugs/1921948
13
Tested-by: Alex Bennée <alex.bennee@linaro.org>
14
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20210416183106.1516563-4-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
18
---
13
include/hw/devices.h | 3 ---
19
target/arm/mte_helper.c | 109 +++++++++++++---------------------------
14
hw/display/tc6393xb.c | 16 ----------------
20
1 file changed, 35 insertions(+), 74 deletions(-)
15
2 files changed, 19 deletions(-)
16
21
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
22
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
18
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/devices.h
24
--- a/target/arm/mte_helper.c
20
+++ b/include/hw/devices.h
25
+++ b/target/arm/mte_helper.c
21
@@ -XXX,XX +XXX,XX @@ void retu_key_event(void *retu, int state);
26
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
22
typedef struct TC6393xbState TC6393xbState;
27
}
23
TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
28
}
24
uint32_t base, qemu_irq irq);
29
25
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
30
-/*
26
- qemu_irq handler);
31
- * Perform an MTE checked access for a single logical or atomic access.
27
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s);
32
- */
28
qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
33
-static bool mte_probe1_int(CPUARMState *env, uint32_t desc, uint64_t ptr,
29
34
- uintptr_t ra, int bit55)
30
#endif
31
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/display/tc6393xb.c
34
+++ b/hw/display/tc6393xb.c
35
@@ -XXX,XX +XXX,XX @@ struct TC6393xbState {
36
blanked : 1;
37
};
38
39
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s)
40
-{
35
-{
41
- return s->gpio_in;
36
- int mem_tag, mmu_idx, ptr_tag, size;
37
- MMUAccessType type;
38
- uint8_t *mem;
39
-
40
- ptr_tag = allocation_tag_from_addr(ptr);
41
-
42
- if (tcma_check(desc, bit55, ptr_tag)) {
43
- return true;
44
- }
45
-
46
- mmu_idx = FIELD_EX32(desc, MTEDESC, MIDX);
47
- type = FIELD_EX32(desc, MTEDESC, WRITE) ? MMU_DATA_STORE : MMU_DATA_LOAD;
48
- size = FIELD_EX32(desc, MTEDESC, ESIZE);
49
-
50
- mem = allocation_tag_mem(env, mmu_idx, ptr, type, size,
51
- MMU_DATA_LOAD, 1, ra);
52
- if (!mem) {
53
- return true;
54
- }
55
-
56
- mem_tag = load_tag1(ptr, mem);
57
- return ptr_tag == mem_tag;
42
-}
58
-}
43
-
59
-
44
static void tc6393xb_gpio_set(void *opaque, int line, int level)
60
-/*
45
{
61
- * No-fault version of mte_check1, to be used by SVE for MemSingleNF.
46
// TC6393xbState *s = opaque;
62
- * Returns false if the access is Checked and the check failed. This
47
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_gpio_set(void *opaque, int line, int level)
63
- * is only intended to probe the tag -- the validity of the page must
48
// FIXME: how does the chip reflect the GPIO input level change?
64
- * be checked beforehand.
49
}
65
- */
50
66
-bool mte_probe1(CPUARMState *env, uint32_t desc, uint64_t ptr)
51
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
52
- qemu_irq handler)
53
-{
67
-{
54
- if (line >= TC6393XB_GPIOS) {
68
- int bit55 = extract64(ptr, 55, 1);
55
- fprintf(stderr, "TC6393xb: no GPIO pin %d\n", line);
69
-
56
- return;
70
- /* If TBI is disabled, the access is unchecked. */
71
- if (unlikely(!tbi_check(desc, bit55))) {
72
- return true;
57
- }
73
- }
58
-
74
-
59
- s->handler[line] = handler;
75
- return mte_probe1_int(env, desc, ptr, 0, bit55);
60
-}
76
-}
61
-
77
-
62
static void tc6393xb_gpio_handler_update(TC6393xbState *s)
78
-uint64_t mte_check1(CPUARMState *env, uint32_t desc,
63
{
79
- uint64_t ptr, uintptr_t ra)
64
uint32_t level, diff;
80
-{
81
- int bit55 = extract64(ptr, 55, 1);
82
-
83
- /* If TBI is disabled, the access is unchecked, and ptr is not dirty. */
84
- if (unlikely(!tbi_check(desc, bit55))) {
85
- return ptr;
86
- }
87
-
88
- if (unlikely(!mte_probe1_int(env, desc, ptr, ra, bit55))) {
89
- mte_check_fail(env, desc, ptr, ra);
90
- }
91
-
92
- return useronly_clean_ptr(ptr);
93
-}
94
-
95
-uint64_t HELPER(mte_check1)(CPUARMState *env, uint32_t desc, uint64_t ptr)
96
-{
97
- return mte_check1(env, desc, ptr, GETPC());
98
-}
99
-
100
-/*
101
- * Perform an MTE checked access for multiple logical accesses.
102
- */
103
-
104
/**
105
* checkN:
106
* @tag: tag memory to test
107
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mte_checkN)(CPUARMState *env, uint32_t desc, uint64_t ptr)
108
return mte_checkN(env, desc, ptr, GETPC());
109
}
110
111
+uint64_t mte_check1(CPUARMState *env, uint32_t desc,
112
+ uint64_t ptr, uintptr_t ra)
113
+{
114
+ uint64_t fault;
115
+ uint32_t total = FIELD_EX32(desc, MTEDESC, ESIZE);
116
+ int ret = mte_probe_int(env, desc, ptr, ra, total, &fault);
117
+
118
+ if (unlikely(ret == 0)) {
119
+ mte_check_fail(env, desc, fault, ra);
120
+ } else if (ret < 0) {
121
+ return ptr;
122
+ }
123
+ return useronly_clean_ptr(ptr);
124
+}
125
+
126
+uint64_t HELPER(mte_check1)(CPUARMState *env, uint32_t desc, uint64_t ptr)
127
+{
128
+ return mte_check1(env, desc, ptr, GETPC());
129
+}
130
+
131
+/*
132
+ * No-fault version of mte_check1, to be used by SVE for MemSingleNF.
133
+ * Returns false if the access is Checked and the check failed. This
134
+ * is only intended to probe the tag -- the validity of the page must
135
+ * be checked beforehand.
136
+ */
137
+bool mte_probe1(CPUARMState *env, uint32_t desc, uint64_t ptr)
138
+{
139
+ uint64_t fault;
140
+ uint32_t total = FIELD_EX32(desc, MTEDESC, ESIZE);
141
+ int ret = mte_probe_int(env, desc, ptr, 0, total, &fault);
142
+
143
+ return ret != 0;
144
+}
145
+
146
/*
147
* Perform an MTE checked access for DC_ZVA.
148
*/
65
--
149
--
66
2.20.1
150
2.20.1
67
151
68
152
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This commit finally deletes "hw/devices.h".
3
Buglink: https://bugs.launchpad.net/bugs/1921948
4
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20210416183106.1516563-5-richard.henderson@linaro.org
7
Message-id: 20190412165416.7977-13-philmd@redhat.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
8
---
10
include/hw/devices.h | 11 -----------
9
tests/tcg/aarch64/mte-5.c | 44 +++++++++++++++++++++++++++++++
11
include/hw/net/smc91c111.h | 19 +++++++++++++++++++
10
tests/tcg/aarch64/Makefile.target | 2 +-
12
hw/arm/gumstix.c | 2 +-
11
2 files changed, 45 insertions(+), 1 deletion(-)
13
hw/arm/integratorcp.c | 2 +-
12
create mode 100644 tests/tcg/aarch64/mte-5.c
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
21
13
22
diff --git a/include/hw/devices.h b/include/hw/devices.h
14
diff --git a/tests/tcg/aarch64/mte-5.c b/tests/tcg/aarch64/mte-5.c
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
15
new file mode 100644
41
index XXXXXXX..XXXXXXX
16
index XXXXXXX..XXXXXXX
42
--- /dev/null
17
--- /dev/null
43
+++ b/include/hw/net/smc91c111.h
18
+++ b/tests/tcg/aarch64/mte-5.c
44
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
45
+/*
20
+/*
46
+ * SMSC 91C111 Ethernet interface emulation
21
+ * Memory tagging, faulting unaligned access.
47
+ *
22
+ *
48
+ * Copyright (c) 2005 CodeSourcery, LLC.
23
+ * Copyright (c) 2021 Linaro Ltd
49
+ * Written by Paul Brook
24
+ * SPDX-License-Identifier: GPL-2.0-or-later
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
+ */
25
+ */
54
+
26
+
55
+#ifndef HW_NET_SMC91C111_H
27
+#include "mte.h"
56
+#define HW_NET_SMC91C111_H
57
+
28
+
58
+#include "hw/irq.h"
29
+void pass(int sig, siginfo_t *info, void *uc)
59
+#include "net/net.h"
30
+{
31
+ assert(info->si_code == SEGV_MTESERR);
32
+ exit(0);
33
+}
60
+
34
+
61
+void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
35
+int main(int ac, char **av)
36
+{
37
+ struct sigaction sa;
38
+ void *p0, *p1, *p2;
39
+ long excl = 1;
62
+
40
+
63
+#endif
41
+ enable_mte(PR_MTE_TCF_SYNC);
64
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
42
+ p0 = alloc_mte_mem(sizeof(*p0));
43
+
44
+ /* Create two differently tagged pointers. */
45
+ asm("irg %0,%1,%2" : "=r"(p1) : "r"(p0), "r"(excl));
46
+ asm("gmi %0,%1,%0" : "+r"(excl) : "r" (p1));
47
+ assert(excl != 1);
48
+ asm("irg %0,%1,%2" : "=r"(p2) : "r"(p0), "r"(excl));
49
+ assert(p1 != p2);
50
+
51
+ memset(&sa, 0, sizeof(sa));
52
+ sa.sa_sigaction = pass;
53
+ sa.sa_flags = SA_SIGINFO;
54
+ sigaction(SIGSEGV, &sa, NULL);
55
+
56
+ /* Store store two different tags in sequential granules. */
57
+ asm("stg %0, [%0]" : : "r"(p1));
58
+ asm("stg %0, [%0]" : : "r"(p2 + 16));
59
+
60
+ /* Perform an unaligned load crossing the granules. */
61
+ asm volatile("ldr %0, [%1]" : "=r"(p0) : "r"(p1 + 12));
62
+ abort();
63
+}
64
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
65
index XXXXXXX..XXXXXXX 100644
65
index XXXXXXX..XXXXXXX 100644
66
--- a/hw/arm/gumstix.c
66
--- a/tests/tcg/aarch64/Makefile.target
67
+++ b/hw/arm/gumstix.c
67
+++ b/tests/tcg/aarch64/Makefile.target
68
@@ -XXX,XX +XXX,XX @@
68
@@ -XXX,XX +XXX,XX @@ AARCH64_TESTS += bti-2
69
#include "hw/arm/pxa.h"
69
70
#include "net/net.h"
70
# MTE Tests
71
#include "hw/block/flash.h"
71
ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_ARMV8_MTE),)
72
-#include "hw/devices.h"
72
-AARCH64_TESTS += mte-1 mte-2 mte-3 mte-4 mte-6
73
+#include "hw/net/smc91c111.h"
73
+AARCH64_TESTS += mte-1 mte-2 mte-3 mte-4 mte-5 mte-6
74
#include "hw/boards.h"
74
mte-%: CFLAGS += -march=armv8.5-a+memtag
75
#include "exec/address-spaces.h"
75
endif
76
#include "sysemu/qtest.h"
76
77
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/arm/integratorcp.c
80
+++ b/hw/arm/integratorcp.c
81
@@ -XXX,XX +XXX,XX @@
82
#include "qemu-common.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"
91
#include "exec/address-spaces.h"
92
#include "sysemu/sysemu.h"
93
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
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"
143
#include "qemu/log.h"
144
/* For crc32 */
145
#include <zlib.h>
146
--
77
--
147
2.20.1
78
2.20.1
148
79
149
80
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
After recent changes, mte_checkN does not use ESIZE,
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
and mte_check1 never used TSIZE. We can combine the
5
Message-id: 20190412165416.7977-12-philmd@redhat.com
5
two into a single field: SIZEM1.
6
7
Choose to pass size - 1 because size == 0 is never used,
8
our immediate need in mte_probe_int is for the address
9
of the last byte (ptr + size - 1), and since almost all
10
operations are powers of 2, this makes the immediate
11
constant one bit smaller.
12
13
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20210416183106.1516563-6-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
17
---
8
include/hw/net/lan9118.h | 2 ++
18
target/arm/internals.h | 4 ++--
9
hw/arm/exynos4_boards.c | 3 ++-
19
target/arm/mte_helper.c | 18 ++++++++----------
10
hw/arm/mps2-tz.c | 3 ++-
20
target/arm/translate-a64.c | 5 ++---
11
hw/net/lan9118.c | 1 -
21
target/arm/translate-sve.c | 5 ++---
12
4 files changed, 6 insertions(+), 3 deletions(-)
22
4 files changed, 14 insertions(+), 18 deletions(-)
13
23
14
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
24
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/net/lan9118.h
26
--- a/target/arm/internals.h
17
+++ b/include/hw/net/lan9118.h
27
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@
19
#include "hw/irq.h"
29
#define TARGET_ARM_INTERNALS_H
20
#include "net/net.h"
30
21
31
#include "hw/registerfields.h"
22
+#define TYPE_LAN9118 "lan9118"
32
+#include "tcg/tcg-gvec-desc.h"
23
+
33
#include "syndrome.h"
24
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
34
25
35
/* register banks for CPU modes */
26
#endif
36
@@ -XXX,XX +XXX,XX @@ FIELD(MTEDESC, MIDX, 0, 4)
27
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
37
FIELD(MTEDESC, TBI, 4, 2)
38
FIELD(MTEDESC, TCMA, 6, 2)
39
FIELD(MTEDESC, WRITE, 8, 1)
40
-FIELD(MTEDESC, ESIZE, 9, 5)
41
-FIELD(MTEDESC, TSIZE, 14, 10) /* mte_checkN only */
42
+FIELD(MTEDESC, SIZEM1, 9, SIMD_DATA_BITS - 9) /* size - 1 */
43
44
bool mte_probe1(CPUARMState *env, uint32_t desc, uint64_t ptr);
45
uint64_t mte_check1(CPUARMState *env, uint32_t desc,
46
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
28
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/exynos4_boards.c
48
--- a/target/arm/mte_helper.c
30
+++ b/hw/arm/exynos4_boards.c
49
+++ b/target/arm/mte_helper.c
31
@@ -XXX,XX +XXX,XX @@
50
@@ -XXX,XX +XXX,XX @@ static int checkN(uint8_t *mem, int odd, int cmp, int count)
32
#include "hw/arm/arm.h"
51
* Return positive on success with tbi enabled.
33
#include "exec/address-spaces.h"
52
*/
34
#include "hw/arm/exynos4210.h"
53
static int mte_probe_int(CPUARMState *env, uint32_t desc, uint64_t ptr,
35
+#include "hw/net/lan9118.h"
54
- uintptr_t ra, uint32_t total, uint64_t *fault)
36
#include "hw/boards.h"
55
+ uintptr_t ra, uint64_t *fault)
37
56
{
38
#undef DEBUG
57
int mmu_idx, ptr_tag, bit55;
39
@@ -XXX,XX +XXX,XX @@ static void lan9215_init(uint32_t base, qemu_irq irq)
58
uint64_t ptr_last, prev_page, next_page;
40
/* This should be a 9215 but the 9118 is close enough */
59
uint64_t tag_first, tag_last;
41
if (nd_table[0].used) {
60
uint64_t tag_byte_first, tag_byte_last;
42
qemu_check_nic_model(&nd_table[0], "lan9118");
61
- uint32_t tag_count, tag_size, n, c;
43
- dev = qdev_create(NULL, "lan9118");
62
+ uint32_t sizem1, tag_count, tag_size, n, c;
44
+ dev = qdev_create(NULL, TYPE_LAN9118);
63
uint8_t *mem1, *mem2;
45
qdev_set_nic_properties(dev, &nd_table[0]);
64
MMUAccessType type;
46
qdev_prop_set_uint32(dev, "mode_16bit", 1);
65
47
qdev_init_nofail(dev);
66
@@ -XXX,XX +XXX,XX @@ static int mte_probe_int(CPUARMState *env, uint32_t desc, uint64_t ptr,
48
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
67
68
mmu_idx = FIELD_EX32(desc, MTEDESC, MIDX);
69
type = FIELD_EX32(desc, MTEDESC, WRITE) ? MMU_DATA_STORE : MMU_DATA_LOAD;
70
+ sizem1 = FIELD_EX32(desc, MTEDESC, SIZEM1);
71
72
/* Find the addr of the end of the access */
73
- ptr_last = ptr + total - 1;
74
+ ptr_last = ptr + sizem1;
75
76
/* Round the bounds to the tag granule, and compute the number of tags. */
77
tag_first = QEMU_ALIGN_DOWN(ptr, TAG_GRANULE);
78
@@ -XXX,XX +XXX,XX @@ static int mte_probe_int(CPUARMState *env, uint32_t desc, uint64_t ptr,
79
if (likely(tag_last - prev_page <= TARGET_PAGE_SIZE)) {
80
/* Memory access stays on one page. */
81
tag_size = ((tag_byte_last - tag_byte_first) / (2 * TAG_GRANULE)) + 1;
82
- mem1 = allocation_tag_mem(env, mmu_idx, ptr, type, total,
83
+ mem1 = allocation_tag_mem(env, mmu_idx, ptr, type, sizem1 + 1,
84
MMU_DATA_LOAD, tag_size, ra);
85
if (!mem1) {
86
return 1;
87
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
88
uint64_t ptr, uintptr_t ra)
89
{
90
uint64_t fault;
91
- uint32_t total = FIELD_EX32(desc, MTEDESC, TSIZE);
92
- int ret = mte_probe_int(env, desc, ptr, ra, total, &fault);
93
+ int ret = mte_probe_int(env, desc, ptr, ra, &fault);
94
95
if (unlikely(ret == 0)) {
96
mte_check_fail(env, desc, fault, ra);
97
@@ -XXX,XX +XXX,XX @@ uint64_t mte_check1(CPUARMState *env, uint32_t desc,
98
uint64_t ptr, uintptr_t ra)
99
{
100
uint64_t fault;
101
- uint32_t total = FIELD_EX32(desc, MTEDESC, ESIZE);
102
- int ret = mte_probe_int(env, desc, ptr, ra, total, &fault);
103
+ int ret = mte_probe_int(env, desc, ptr, ra, &fault);
104
105
if (unlikely(ret == 0)) {
106
mte_check_fail(env, desc, fault, ra);
107
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mte_check1)(CPUARMState *env, uint32_t desc, uint64_t ptr)
108
bool mte_probe1(CPUARMState *env, uint32_t desc, uint64_t ptr)
109
{
110
uint64_t fault;
111
- uint32_t total = FIELD_EX32(desc, MTEDESC, ESIZE);
112
- int ret = mte_probe_int(env, desc, ptr, 0, total, &fault);
113
+ int ret = mte_probe_int(env, desc, ptr, 0, &fault);
114
115
return ret != 0;
116
}
117
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
49
index XXXXXXX..XXXXXXX 100644
118
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/arm/mps2-tz.c
119
--- a/target/arm/translate-a64.c
51
+++ b/hw/arm/mps2-tz.c
120
+++ b/target/arm/translate-a64.c
52
@@ -XXX,XX +XXX,XX @@
121
@@ -XXX,XX +XXX,XX @@ static TCGv_i64 gen_mte_check1_mmuidx(DisasContext *s, TCGv_i64 addr,
53
#include "hw/arm/armsse.h"
122
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
54
#include "hw/dma/pl080.h"
123
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
55
#include "hw/ssi/pl022.h"
124
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
56
+#include "hw/net/lan9118.h"
125
- desc = FIELD_DP32(desc, MTEDESC, ESIZE, 1 << log2_size);
57
#include "net/net.h"
126
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << log2_size) - 1);
58
#include "hw/core/split-irq.h"
127
tcg_desc = tcg_const_i32(desc);
59
128
60
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
129
ret = new_tmp_a64(s);
61
* except that it doesn't support the checksum-offload feature.
130
@@ -XXX,XX +XXX,XX @@ TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
62
*/
131
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
63
qemu_check_nic_model(nd, "lan9118");
132
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
64
- mms->lan9118 = qdev_create(NULL, "lan9118");
133
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
65
+ mms->lan9118 = qdev_create(NULL, TYPE_LAN9118);
134
- desc = FIELD_DP32(desc, MTEDESC, ESIZE, 1 << log2_esize);
66
qdev_set_nic_properties(mms->lan9118, nd);
135
- desc = FIELD_DP32(desc, MTEDESC, TSIZE, total_size);
67
qdev_init_nofail(mms->lan9118);
136
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, total_size - 1);
68
137
tcg_desc = tcg_const_i32(desc);
69
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
138
139
ret = new_tmp_a64(s);
140
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
70
index XXXXXXX..XXXXXXX 100644
141
index XXXXXXX..XXXXXXX 100644
71
--- a/hw/net/lan9118.c
142
--- a/target/arm/translate-sve.c
72
+++ b/hw/net/lan9118.c
143
+++ b/target/arm/translate-sve.c
73
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118_packet = {
144
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
145
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
146
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
147
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
148
- desc = FIELD_DP32(desc, MTEDESC, ESIZE, 1 << msz);
149
- desc = FIELD_DP32(desc, MTEDESC, TSIZE, mte_n << msz);
150
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (mte_n << msz) - 1);
151
desc <<= SVE_MTEDESC_SHIFT;
152
} else {
153
addr = clean_data_tbi(s, addr);
154
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpz(DisasContext *s, int zt, int pg, int zm,
155
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
156
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
157
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
158
- desc = FIELD_DP32(desc, MTEDESC, ESIZE, 1 << msz);
159
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << msz) - 1);
160
desc <<= SVE_MTEDESC_SHIFT;
74
}
161
}
75
};
162
desc = simd_desc(vsz, vsz, desc | scale);
76
77
-#define TYPE_LAN9118 "lan9118"
78
#define LAN9118(obj) OBJECT_CHECK(lan9118_state, (obj), TYPE_LAN9118)
79
80
typedef struct {
81
--
163
--
82
2.20.1
164
2.20.1
83
165
84
166
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
The mte_check1 and mte_checkN functions are now identical.
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Drop mte_check1 and rename mte_checkN to mte_check.
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
6
Message-id: 20190412165416.7977-11-philmd@redhat.com
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210416183106.1516563-7-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
10
---
9
include/hw/net/ne2000-isa.h | 6 ++++++
11
target/arm/helper-a64.h | 3 +--
10
1 file changed, 6 insertions(+)
12
target/arm/internals.h | 5 +----
13
target/arm/mte_helper.c | 26 +++-----------------------
14
target/arm/sve_helper.c | 14 +++++++-------
15
target/arm/translate-a64.c | 4 ++--
16
5 files changed, 14 insertions(+), 38 deletions(-)
11
17
12
diff --git a/include/hw/net/ne2000-isa.h b/include/hw/net/ne2000-isa.h
18
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
13
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/net/ne2000-isa.h
20
--- a/target/arm/helper-a64.h
15
+++ b/include/hw/net/ne2000-isa.h
21
+++ b/target/arm/helper-a64.h
16
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(autdb, TCG_CALL_NO_WG, i64, env, i64, i64)
17
* This work is licensed under the terms of the GNU GPL, version 2 or later.
23
DEF_HELPER_FLAGS_2(xpaci, TCG_CALL_NO_RWG_SE, i64, env, i64)
18
* See the COPYING file in the top-level directory.
24
DEF_HELPER_FLAGS_2(xpacd, TCG_CALL_NO_RWG_SE, i64, env, i64)
19
*/
25
20
+
26
-DEF_HELPER_FLAGS_3(mte_check1, TCG_CALL_NO_WG, i64, env, i32, i64)
21
+#ifndef HW_NET_NE2K_ISA_H
27
-DEF_HELPER_FLAGS_3(mte_checkN, TCG_CALL_NO_WG, i64, env, i32, i64)
22
+#define HW_NET_NE2K_ISA_H
28
+DEF_HELPER_FLAGS_3(mte_check, TCG_CALL_NO_WG, i64, env, i32, i64)
23
+
29
DEF_HELPER_FLAGS_3(mte_check_zva, TCG_CALL_NO_WG, i64, env, i32, i64)
24
#include "hw/hw.h"
30
DEF_HELPER_FLAGS_3(irg, TCG_CALL_NO_RWG, i64, env, i64, i64)
25
#include "hw/qdev.h"
31
DEF_HELPER_FLAGS_4(addsubg, TCG_CALL_NO_RWG_SE, i64, env, i64, s32, i32)
26
#include "hw/isa/isa.h"
32
diff --git a/target/arm/internals.h b/target/arm/internals.h
27
@@ -XXX,XX +XXX,XX @@ static inline ISADevice *isa_ne2000_init(ISABus *bus, int base, int irq,
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/internals.h
35
+++ b/target/arm/internals.h
36
@@ -XXX,XX +XXX,XX @@ FIELD(MTEDESC, WRITE, 8, 1)
37
FIELD(MTEDESC, SIZEM1, 9, SIMD_DATA_BITS - 9) /* size - 1 */
38
39
bool mte_probe1(CPUARMState *env, uint32_t desc, uint64_t ptr);
40
-uint64_t mte_check1(CPUARMState *env, uint32_t desc,
41
- uint64_t ptr, uintptr_t ra);
42
-uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
43
- uint64_t ptr, uintptr_t ra);
44
+uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra);
45
46
static inline int allocation_tag_from_addr(uint64_t ptr)
47
{
48
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/mte_helper.c
51
+++ b/target/arm/mte_helper.c
52
@@ -XXX,XX +XXX,XX @@ static int mte_probe_int(CPUARMState *env, uint32_t desc, uint64_t ptr,
53
return 0;
54
}
55
56
-uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
57
- uint64_t ptr, uintptr_t ra)
58
+uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra)
59
{
60
uint64_t fault;
61
int ret = mte_probe_int(env, desc, ptr, ra, &fault);
62
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
63
return useronly_clean_ptr(ptr);
64
}
65
66
-uint64_t HELPER(mte_checkN)(CPUARMState *env, uint32_t desc, uint64_t ptr)
67
+uint64_t HELPER(mte_check)(CPUARMState *env, uint32_t desc, uint64_t ptr)
68
{
69
- return mte_checkN(env, desc, ptr, GETPC());
70
-}
71
-
72
-uint64_t mte_check1(CPUARMState *env, uint32_t desc,
73
- uint64_t ptr, uintptr_t ra)
74
-{
75
- uint64_t fault;
76
- int ret = mte_probe_int(env, desc, ptr, ra, &fault);
77
-
78
- if (unlikely(ret == 0)) {
79
- mte_check_fail(env, desc, fault, ra);
80
- } else if (ret < 0) {
81
- return ptr;
82
- }
83
- return useronly_clean_ptr(ptr);
84
-}
85
-
86
-uint64_t HELPER(mte_check1)(CPUARMState *env, uint32_t desc, uint64_t ptr)
87
-{
88
- return mte_check1(env, desc, ptr, GETPC());
89
+ return mte_check(env, desc, ptr, GETPC());
90
}
91
92
/*
93
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/target/arm/sve_helper.c
96
+++ b/target/arm/sve_helper.c
97
@@ -XXX,XX +XXX,XX @@ static void sve_cont_ldst_mte_check1(SVEContLdSt *info, CPUARMState *env,
98
uintptr_t ra)
99
{
100
sve_cont_ldst_mte_check_int(info, env, vg, addr, esize, msize,
101
- mtedesc, ra, mte_check1);
102
+ mtedesc, ra, mte_check);
103
}
104
105
static void sve_cont_ldst_mte_checkN(SVEContLdSt *info, CPUARMState *env,
106
@@ -XXX,XX +XXX,XX @@ static void sve_cont_ldst_mte_checkN(SVEContLdSt *info, CPUARMState *env,
107
uintptr_t ra)
108
{
109
sve_cont_ldst_mte_check_int(info, env, vg, addr, esize, msize,
110
- mtedesc, ra, mte_checkN);
111
+ mtedesc, ra, mte_check);
112
}
113
114
115
@@ -XXX,XX +XXX,XX @@ void sve_ldnfff1_r(CPUARMState *env, void *vg, const target_ulong addr,
116
if (fault == FAULT_FIRST) {
117
/* Trapping mte check for the first-fault element. */
118
if (mtedesc) {
119
- mte_check1(env, mtedesc, addr + mem_off, retaddr);
120
+ mte_check(env, mtedesc, addr + mem_off, retaddr);
121
}
122
123
/*
124
@@ -XXX,XX +XXX,XX @@ void sve_ld1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
125
info.attrs, BP_MEM_READ, retaddr);
126
}
127
if (mtedesc && arm_tlb_mte_tagged(&info.attrs)) {
128
- mte_check1(env, mtedesc, addr, retaddr);
129
+ mte_check(env, mtedesc, addr, retaddr);
130
}
131
host_fn(&scratch, reg_off, info.host);
132
} else {
133
@@ -XXX,XX +XXX,XX @@ void sve_ld1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
134
BP_MEM_READ, retaddr);
135
}
136
if (mtedesc && arm_tlb_mte_tagged(&info.attrs)) {
137
- mte_check1(env, mtedesc, addr, retaddr);
138
+ mte_check(env, mtedesc, addr, retaddr);
139
}
140
tlb_fn(env, &scratch, reg_off, addr, retaddr);
141
}
142
@@ -XXX,XX +XXX,XX @@ void sve_ldff1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
143
*/
144
addr = base + (off_fn(vm, reg_off) << scale);
145
if (mtedesc) {
146
- mte_check1(env, mtedesc, addr, retaddr);
147
+ mte_check(env, mtedesc, addr, retaddr);
28
}
148
}
29
return d;
149
tlb_fn(env, vd, reg_off, addr, retaddr);
30
}
150
31
+
151
@@ -XXX,XX +XXX,XX @@ void sve_st1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
32
+#endif
152
}
153
154
if (mtedesc && arm_tlb_mte_tagged(&info.attrs)) {
155
- mte_check1(env, mtedesc, addr, retaddr);
156
+ mte_check(env, mtedesc, addr, retaddr);
157
}
158
}
159
i += 1;
160
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
161
index XXXXXXX..XXXXXXX 100644
162
--- a/target/arm/translate-a64.c
163
+++ b/target/arm/translate-a64.c
164
@@ -XXX,XX +XXX,XX @@ static TCGv_i64 gen_mte_check1_mmuidx(DisasContext *s, TCGv_i64 addr,
165
tcg_desc = tcg_const_i32(desc);
166
167
ret = new_tmp_a64(s);
168
- gen_helper_mte_check1(ret, cpu_env, tcg_desc, addr);
169
+ gen_helper_mte_check(ret, cpu_env, tcg_desc, addr);
170
tcg_temp_free_i32(tcg_desc);
171
172
return ret;
173
@@ -XXX,XX +XXX,XX @@ TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
174
tcg_desc = tcg_const_i32(desc);
175
176
ret = new_tmp_a64(s);
177
- gen_helper_mte_checkN(ret, cpu_env, tcg_desc, addr);
178
+ gen_helper_mte_check(ret, cpu_env, tcg_desc, addr);
179
tcg_temp_free_i32(tcg_desc);
180
181
return ret;
33
--
182
--
34
2.20.1
183
2.20.1
35
184
36
185
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
For consistency with the mte_check1 + mte_checkN merge
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
to mte_check, rename the probe function as well.
5
Message-id: 20190412165416.7977-10-philmd@redhat.com
5
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210416183106.1516563-8-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
include/hw/devices.h | 3 ---
11
target/arm/internals.h | 2 +-
9
include/hw/net/lan9118.h | 19 +++++++++++++++++++
12
target/arm/mte_helper.c | 6 +++---
10
hw/arm/kzm.c | 2 +-
13
target/arm/sve_helper.c | 6 +++---
11
hw/arm/mps2.c | 2 +-
14
3 files changed, 7 insertions(+), 7 deletions(-)
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
15
18
diff --git a/include/hw/devices.h b/include/hw/devices.h
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/devices.h
18
--- a/target/arm/internals.h
21
+++ b/include/hw/devices.h
19
+++ b/target/arm/internals.h
22
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ FIELD(MTEDESC, TCMA, 6, 2)
23
/* smc91c111.c */
21
FIELD(MTEDESC, WRITE, 8, 1)
24
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
22
FIELD(MTEDESC, SIZEM1, 9, SIMD_DATA_BITS - 9) /* size - 1 */
25
23
26
-/* lan9118.c */
24
-bool mte_probe1(CPUARMState *env, uint32_t desc, uint64_t ptr);
27
-void lan9118_init(NICInfo *, uint32_t, qemu_irq);
25
+bool mte_probe(CPUARMState *env, uint32_t desc, uint64_t ptr);
28
-
26
uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra);
29
#endif
27
30
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
28
static inline int allocation_tag_from_addr(uint64_t ptr)
31
new file mode 100644
29
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
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
30
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/kzm.c
31
--- a/target/arm/mte_helper.c
58
+++ b/hw/arm/kzm.c
32
+++ b/target/arm/mte_helper.c
59
@@ -XXX,XX +XXX,XX @@
33
@@ -XXX,XX +XXX,XX @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx,
60
#include "qemu/error-report.h"
34
* exception for inaccessible pages, and resolves the virtual address
61
#include "exec/address-spaces.h"
35
* into the softmmu tlb.
62
#include "net/net.h"
36
*
63
-#include "hw/devices.h"
37
- * When RA == 0, this is for mte_probe1. The page is expected to be
64
+#include "hw/net/lan9118.h"
38
+ * When RA == 0, this is for mte_probe. The page is expected to be
65
#include "hw/char/serial.h"
39
* valid. Indicate to probe_access_flags no-fault, then assert that
66
#include "sysemu/qtest.h"
40
* we received a valid page.
67
41
*/
68
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
42
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mte_check)(CPUARMState *env, uint32_t desc, uint64_t ptr)
43
}
44
45
/*
46
- * No-fault version of mte_check1, to be used by SVE for MemSingleNF.
47
+ * No-fault version of mte_check, to be used by SVE for MemSingleNF.
48
* Returns false if the access is Checked and the check failed. This
49
* is only intended to probe the tag -- the validity of the page must
50
* be checked beforehand.
51
*/
52
-bool mte_probe1(CPUARMState *env, uint32_t desc, uint64_t ptr)
53
+bool mte_probe(CPUARMState *env, uint32_t desc, uint64_t ptr)
54
{
55
uint64_t fault;
56
int ret = mte_probe_int(env, desc, ptr, 0, &fault);
57
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
69
index XXXXXXX..XXXXXXX 100644
58
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/arm/mps2.c
59
--- a/target/arm/sve_helper.c
71
+++ b/hw/arm/mps2.c
60
+++ b/target/arm/sve_helper.c
72
@@ -XXX,XX +XXX,XX @@
61
@@ -XXX,XX +XXX,XX @@ void sve_ldnfff1_r(CPUARMState *env, void *vg, const target_ulong addr,
73
#include "hw/timer/cmsdk-apb-timer.h"
62
/* Watchpoint hit, see below. */
74
#include "hw/timer/cmsdk-apb-dualtimer.h"
63
goto do_fault;
75
#include "hw/misc/mps2-scc.h"
64
}
76
-#include "hw/devices.h"
65
- if (mtedesc && !mte_probe1(env, mtedesc, addr + mem_off)) {
77
+#include "hw/net/lan9118.h"
66
+ if (mtedesc && !mte_probe(env, mtedesc, addr + mem_off)) {
78
#include "net/net.h"
67
goto do_fault;
79
68
}
80
typedef enum MPS2FPGAType {
69
/*
81
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
70
@@ -XXX,XX +XXX,XX @@ void sve_ldnfff1_r(CPUARMState *env, void *vg, const target_ulong addr,
82
index XXXXXXX..XXXXXXX 100644
71
& BP_MEM_READ)) {
83
--- a/hw/arm/realview.c
72
goto do_fault;
84
+++ b/hw/arm/realview.c
73
}
85
@@ -XXX,XX +XXX,XX @@
74
- if (mtedesc && !mte_probe1(env, mtedesc, addr + mem_off)) {
86
#include "hw/arm/arm.h"
75
+ if (mtedesc && !mte_probe(env, mtedesc, addr + mem_off)) {
87
#include "hw/arm/primecell.h"
76
goto do_fault;
88
#include "hw/devices.h"
77
}
89
+#include "hw/net/lan9118.h"
78
host_fn(vd, reg_off, host + mem_off);
90
#include "hw/pci/pci.h"
79
@@ -XXX,XX +XXX,XX @@ void sve_ldff1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
91
#include "net/net.h"
80
}
92
#include "sysemu/sysemu.h"
81
if (mtedesc &&
93
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
82
arm_tlb_mte_tagged(&info.attrs) &&
94
index XXXXXXX..XXXXXXX 100644
83
- !mte_probe1(env, mtedesc, addr)) {
95
--- a/hw/arm/vexpress.c
84
+ !mte_probe(env, mtedesc, addr)) {
96
+++ b/hw/arm/vexpress.c
85
goto fault;
97
@@ -XXX,XX +XXX,XX @@
86
}
98
#include "hw/sysbus.h"
87
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
--
88
--
120
2.20.1
89
2.20.1
121
90
122
91
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Since uWireSlave is only used in this new header, there is no
3
Now that mte_check1 and mte_checkN have been merged, we can
4
need to expose it via "qemu/typedefs.h".
4
merge sve_cont_ldst_mte_check1 and sve_cont_ldst_mte_checkN.
5
5
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
6
Which means that we can eliminate the function pointer into
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
sve_ldN_r and sve_stN_r, calling sve_cont_ldst_mte_check directly.
8
Message-id: 20190412165416.7977-9-philmd@redhat.com
8
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20210416183106.1516563-9-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
include/hw/arm/omap.h | 6 +-----
14
target/arm/sve_helper.c | 84 +++++++++++++----------------------------
12
include/hw/devices.h | 15 ---------------
15
1 file changed, 26 insertions(+), 58 deletions(-)
13
include/hw/input/tsc2xxx.h | 36 ++++++++++++++++++++++++++++++++++++
16
14
include/qemu/typedefs.h | 1 -
17
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
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
18
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/omap.h
19
--- a/target/arm/sve_helper.c
26
+++ b/include/hw/arm/omap.h
20
+++ b/target/arm/sve_helper.c
27
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static void sve_cont_ldst_watchpoints(SVEContLdSt *info, CPUARMState *env,
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
22
#endif
78
diff --git a/include/hw/input/tsc2xxx.h b/include/hw/input/tsc2xxx.h
23
}
79
new file mode 100644
24
80
index XXXXXXX..XXXXXXX
25
-typedef uint64_t mte_check_fn(CPUARMState *, uint32_t, uint64_t, uintptr_t);
81
--- /dev/null
26
-
82
+++ b/include/hw/input/tsc2xxx.h
27
-static inline QEMU_ALWAYS_INLINE
83
@@ -XXX,XX +XXX,XX @@
28
-void sve_cont_ldst_mte_check_int(SVEContLdSt *info, CPUARMState *env,
84
+/*
29
- uint64_t *vg, target_ulong addr, int esize,
85
+ * TI touchscreen controller
30
- int msize, uint32_t mtedesc, uintptr_t ra,
86
+ *
31
- mte_check_fn *check)
87
+ * Copyright (c) 2006 Andrzej Zaborowski
32
+static void sve_cont_ldst_mte_check(SVEContLdSt *info, CPUARMState *env,
88
+ * Copyright (C) 2008 Nokia Corporation
33
+ uint64_t *vg, target_ulong addr, int esize,
89
+ *
34
+ int msize, uint32_t mtedesc, uintptr_t ra)
90
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
35
{
91
+ * See the COPYING file in the top-level directory.
36
intptr_t mem_off, reg_off, reg_last;
92
+ */
37
93
+
38
@@ -XXX,XX +XXX,XX @@ void sve_cont_ldst_mte_check_int(SVEContLdSt *info, CPUARMState *env,
94
+#ifndef HW_INPUT_TSC2XXX_H
39
uint64_t pg = vg[reg_off >> 6];
95
+#define HW_INPUT_TSC2XXX_H
40
do {
96
+
41
if ((pg >> (reg_off & 63)) & 1) {
97
+#include "hw/irq.h"
42
- check(env, mtedesc, addr, ra);
98
+#include "ui/console.h"
43
+ mte_check(env, mtedesc, addr, ra);
99
+
44
}
100
+typedef struct uWireSlave {
45
reg_off += esize;
101
+ uint16_t (*receive)(void *opaque);
46
mem_off += msize;
102
+ void (*send)(void *opaque, uint16_t data);
47
@@ -XXX,XX +XXX,XX @@ void sve_cont_ldst_mte_check_int(SVEContLdSt *info, CPUARMState *env,
103
+ void *opaque;
48
uint64_t pg = vg[reg_off >> 6];
104
+} uWireSlave;
49
do {
105
+
50
if ((pg >> (reg_off & 63)) & 1) {
106
+/* tsc210x.c */
51
- check(env, mtedesc, addr, ra);
107
+uWireSlave *tsc2102_init(qemu_irq pint);
52
+ mte_check(env, mtedesc, addr, ra);
108
+uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
53
}
109
+I2SCodec *tsc210x_codec(uWireSlave *chip);
54
reg_off += esize;
110
+uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
55
mem_off += msize;
111
+void tsc210x_set_transform(uWireSlave *chip, MouseTransformInfo *info);
56
@@ -XXX,XX +XXX,XX @@ void sve_cont_ldst_mte_check_int(SVEContLdSt *info, CPUARMState *env,
112
+void tsc210x_key_event(uWireSlave *chip, int key, int down);
57
}
113
+
58
}
114
+/* tsc2005.c */
59
115
+void *tsc2005_init(qemu_irq pintdav);
60
-typedef void sve_cont_ldst_mte_check_fn(SVEContLdSt *info, CPUARMState *env,
116
+uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
61
- uint64_t *vg, target_ulong addr,
117
+void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
62
- int esize, int msize, uint32_t mtedesc,
118
+
63
- uintptr_t ra);
119
+#endif
64
-
120
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
65
-static void sve_cont_ldst_mte_check1(SVEContLdSt *info, CPUARMState *env,
121
index XXXXXXX..XXXXXXX 100644
66
- uint64_t *vg, target_ulong addr,
122
--- a/include/qemu/typedefs.h
67
- int esize, int msize, uint32_t mtedesc,
123
+++ b/include/qemu/typedefs.h
68
- uintptr_t ra)
124
@@ -XXX,XX +XXX,XX @@ typedef struct RAMBlock RAMBlock;
69
-{
125
typedef struct Range Range;
70
- sve_cont_ldst_mte_check_int(info, env, vg, addr, esize, msize,
126
typedef struct SHPCDevice SHPCDevice;
71
- mtedesc, ra, mte_check);
127
typedef struct SSIBus SSIBus;
72
-}
128
-typedef struct uWireSlave uWireSlave;
73
-
129
typedef struct VirtIODevice VirtIODevice;
74
-static void sve_cont_ldst_mte_checkN(SVEContLdSt *info, CPUARMState *env,
130
typedef struct Visitor Visitor;
75
- uint64_t *vg, target_ulong addr,
131
typedef void SaveStateHandler(QEMUFile *f, void *opaque);
76
- int esize, int msize, uint32_t mtedesc,
132
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
77
- uintptr_t ra)
133
index XXXXXXX..XXXXXXX 100644
78
-{
134
--- a/hw/arm/nseries.c
79
- sve_cont_ldst_mte_check_int(info, env, vg, addr, esize, msize,
135
+++ b/hw/arm/nseries.c
80
- mtedesc, ra, mte_check);
136
@@ -XXX,XX +XXX,XX @@
81
-}
137
#include "ui/console.h"
82
-
138
#include "hw/boards.h"
83
-
139
#include "hw/i2c/i2c.h"
84
/*
140
-#include "hw/devices.h"
85
* Common helper for all contiguous 1,2,3,4-register predicated stores.
141
#include "hw/display/blizzard.h"
86
*/
142
+#include "hw/input/tsc2xxx.h"
87
@@ -XXX,XX +XXX,XX @@ void sve_ldN_r(CPUARMState *env, uint64_t *vg, const target_ulong addr,
143
#include "hw/misc/cbus.h"
88
uint32_t desc, const uintptr_t retaddr,
144
#include "hw/misc/tmp105.h"
89
const int esz, const int msz, const int N, uint32_t mtedesc,
145
#include "hw/block/flash.h"
90
sve_ldst1_host_fn *host_fn,
146
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
91
- sve_ldst1_tlb_fn *tlb_fn,
147
index XXXXXXX..XXXXXXX 100644
92
- sve_cont_ldst_mte_check_fn *mte_check_fn)
148
--- a/hw/arm/palm.c
93
+ sve_ldst1_tlb_fn *tlb_fn)
149
+++ b/hw/arm/palm.c
94
{
150
@@ -XXX,XX +XXX,XX @@
95
const unsigned rd = simd_data(desc);
151
#include "hw/arm/omap.h"
96
const intptr_t reg_max = simd_oprsz(desc);
152
#include "hw/boards.h"
97
@@ -XXX,XX +XXX,XX @@ void sve_ldN_r(CPUARMState *env, uint64_t *vg, const target_ulong addr,
153
#include "hw/arm/arm.h"
98
* Handle mte checks for all active elements.
154
-#include "hw/devices.h"
99
* Since TBI must be set for MTE, !mtedesc => !mte_active.
155
+#include "hw/input/tsc2xxx.h"
100
*/
156
#include "hw/loader.h"
101
- if (mte_check_fn && mtedesc) {
157
#include "exec/address-spaces.h"
102
- mte_check_fn(&info, env, vg, addr, 1 << esz, N << msz,
158
#include "cpu.h"
103
- mtedesc, retaddr);
159
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
104
+ if (mtedesc) {
160
index XXXXXXX..XXXXXXX 100644
105
+ sve_cont_ldst_mte_check(&info, env, vg, addr, 1 << esz, N << msz,
161
--- a/hw/input/tsc2005.c
106
+ mtedesc, retaddr);
162
+++ b/hw/input/tsc2005.c
107
}
163
@@ -XXX,XX +XXX,XX @@
108
164
#include "hw/hw.h"
109
flags = info.page[0].flags | info.page[1].flags;
165
#include "qemu/timer.h"
110
@@ -XXX,XX +XXX,XX @@ void sve_ldN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
166
#include "ui/console.h"
111
mtedesc = 0;
167
-#include "hw/devices.h"
112
}
168
+#include "hw/input/tsc2xxx.h"
113
169
#include "trace.h"
114
- sve_ldN_r(env, vg, addr, desc, ra, esz, msz, N, mtedesc, host_fn, tlb_fn,
170
115
- N == 1 ? sve_cont_ldst_mte_check1 : sve_cont_ldst_mte_checkN);
171
#define TSC_CUT_RESOLUTION(value, p)    ((value) >> (16 - (p ? 12 : 10)))
116
+ sve_ldN_r(env, vg, addr, desc, ra, esz, msz, N, mtedesc, host_fn, tlb_fn);
172
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
117
}
173
index XXXXXXX..XXXXXXX 100644
118
174
--- a/hw/input/tsc210x.c
119
#define DO_LD1_1(NAME, ESZ) \
175
+++ b/hw/input/tsc210x.c
120
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_##NAME##_r)(CPUARMState *env, void *vg, \
176
@@ -XXX,XX +XXX,XX @@
121
target_ulong addr, uint32_t desc) \
177
#include "audio/audio.h"
122
{ \
178
#include "qemu/timer.h"
123
sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, MO_8, 1, 0, \
179
#include "ui/console.h"
124
- sve_##NAME##_host, sve_##NAME##_tlb, NULL); \
180
-#include "hw/arm/omap.h"    /* For I2SCodec and uWireSlave */
125
+ sve_##NAME##_host, sve_##NAME##_tlb); \
181
-#include "hw/devices.h"
126
} \
182
+#include "hw/arm/omap.h" /* For I2SCodec */
127
void HELPER(sve_##NAME##_r_mte)(CPUARMState *env, void *vg, \
183
+#include "hw/input/tsc2xxx.h"
128
target_ulong addr, uint32_t desc) \
184
129
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_##NAME##_le_r)(CPUARMState *env, void *vg, \
185
#define TSC_DATA_REGISTERS_PAGE        0x0
130
target_ulong addr, uint32_t desc) \
186
#define TSC_CONTROL_REGISTERS_PAGE    0x1
131
{ \
187
diff --git a/MAINTAINERS b/MAINTAINERS
132
sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, MSZ, 1, 0, \
188
index XXXXXXX..XXXXXXX 100644
133
- sve_##NAME##_le_host, sve_##NAME##_le_tlb, NULL); \
189
--- a/MAINTAINERS
134
+ sve_##NAME##_le_host, sve_##NAME##_le_tlb); \
190
+++ b/MAINTAINERS
135
} \
191
@@ -XXX,XX +XXX,XX @@ F: hw/input/tsc2005.c
136
void HELPER(sve_##NAME##_be_r)(CPUARMState *env, void *vg, \
192
F: hw/misc/cbus.c
137
target_ulong addr, uint32_t desc) \
193
F: hw/timer/twl92230.c
138
{ \
194
F: include/hw/display/blizzard.h
139
sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, MSZ, 1, 0, \
195
+F: include/hw/input/tsc2xxx.h
140
- sve_##NAME##_be_host, sve_##NAME##_be_tlb, NULL); \
196
F: include/hw/misc/cbus.h
141
+ sve_##NAME##_be_host, sve_##NAME##_be_tlb); \
197
142
} \
198
Palm
143
void HELPER(sve_##NAME##_le_r_mte)(CPUARMState *env, void *vg, \
199
@@ -XXX,XX +XXX,XX @@ L: qemu-arm@nongnu.org
144
- target_ulong addr, uint32_t desc) \
200
S: Odd Fixes
145
+ target_ulong addr, uint32_t desc) \
201
F: hw/arm/palm.c
146
{ \
202
F: hw/input/tsc210x.c
147
sve_ldN_r_mte(env, vg, addr, desc, GETPC(), ESZ, MSZ, 1, \
203
+F: include/hw/input/tsc2xxx.h
148
sve_##NAME##_le_host, sve_##NAME##_le_tlb); \
204
149
} \
205
Raspberry Pi
150
void HELPER(sve_##NAME##_be_r_mte)(CPUARMState *env, void *vg, \
206
M: Peter Maydell <peter.maydell@linaro.org>
151
- target_ulong addr, uint32_t desc) \
152
+ target_ulong addr, uint32_t desc) \
153
{ \
154
sve_ldN_r_mte(env, vg, addr, desc, GETPC(), ESZ, MSZ, 1, \
155
sve_##NAME##_be_host, sve_##NAME##_be_tlb); \
156
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_ld##N##bb_r)(CPUARMState *env, void *vg, \
157
target_ulong addr, uint32_t desc) \
158
{ \
159
sve_ldN_r(env, vg, addr, desc, GETPC(), MO_8, MO_8, N, 0, \
160
- sve_ld1bb_host, sve_ld1bb_tlb, NULL); \
161
+ sve_ld1bb_host, sve_ld1bb_tlb); \
162
} \
163
void HELPER(sve_ld##N##bb_r_mte)(CPUARMState *env, void *vg, \
164
target_ulong addr, uint32_t desc) \
165
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_ld##N##SUFF##_le_r)(CPUARMState *env, void *vg, \
166
target_ulong addr, uint32_t desc) \
167
{ \
168
sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, ESZ, N, 0, \
169
- sve_ld1##SUFF##_le_host, sve_ld1##SUFF##_le_tlb, NULL); \
170
+ sve_ld1##SUFF##_le_host, sve_ld1##SUFF##_le_tlb); \
171
} \
172
void HELPER(sve_ld##N##SUFF##_be_r)(CPUARMState *env, void *vg, \
173
target_ulong addr, uint32_t desc) \
174
{ \
175
sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, ESZ, N, 0, \
176
- sve_ld1##SUFF##_be_host, sve_ld1##SUFF##_be_tlb, NULL); \
177
+ sve_ld1##SUFF##_be_host, sve_ld1##SUFF##_be_tlb); \
178
} \
179
void HELPER(sve_ld##N##SUFF##_le_r_mte)(CPUARMState *env, void *vg, \
180
target_ulong addr, uint32_t desc) \
181
@@ -XXX,XX +XXX,XX @@ void sve_stN_r(CPUARMState *env, uint64_t *vg, target_ulong addr,
182
uint32_t desc, const uintptr_t retaddr,
183
const int esz, const int msz, const int N, uint32_t mtedesc,
184
sve_ldst1_host_fn *host_fn,
185
- sve_ldst1_tlb_fn *tlb_fn,
186
- sve_cont_ldst_mte_check_fn *mte_check_fn)
187
+ sve_ldst1_tlb_fn *tlb_fn)
188
{
189
const unsigned rd = simd_data(desc);
190
const intptr_t reg_max = simd_oprsz(desc);
191
@@ -XXX,XX +XXX,XX @@ void sve_stN_r(CPUARMState *env, uint64_t *vg, target_ulong addr,
192
* Handle mte checks for all active elements.
193
* Since TBI must be set for MTE, !mtedesc => !mte_active.
194
*/
195
- if (mte_check_fn && mtedesc) {
196
- mte_check_fn(&info, env, vg, addr, 1 << esz, N << msz,
197
- mtedesc, retaddr);
198
+ if (mtedesc) {
199
+ sve_cont_ldst_mte_check(&info, env, vg, addr, 1 << esz, N << msz,
200
+ mtedesc, retaddr);
201
}
202
203
flags = info.page[0].flags | info.page[1].flags;
204
@@ -XXX,XX +XXX,XX @@ void sve_stN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
205
mtedesc = 0;
206
}
207
208
- sve_stN_r(env, vg, addr, desc, ra, esz, msz, N, mtedesc, host_fn, tlb_fn,
209
- N == 1 ? sve_cont_ldst_mte_check1 : sve_cont_ldst_mte_checkN);
210
+ sve_stN_r(env, vg, addr, desc, ra, esz, msz, N, mtedesc, host_fn, tlb_fn);
211
}
212
213
#define DO_STN_1(N, NAME, ESZ) \
214
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_st##N##NAME##_r)(CPUARMState *env, void *vg, \
215
target_ulong addr, uint32_t desc) \
216
{ \
217
sve_stN_r(env, vg, addr, desc, GETPC(), ESZ, MO_8, N, 0, \
218
- sve_st1##NAME##_host, sve_st1##NAME##_tlb, NULL); \
219
+ sve_st1##NAME##_host, sve_st1##NAME##_tlb); \
220
} \
221
void HELPER(sve_st##N##NAME##_r_mte)(CPUARMState *env, void *vg, \
222
target_ulong addr, uint32_t desc) \
223
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_st##N##NAME##_le_r)(CPUARMState *env, void *vg, \
224
target_ulong addr, uint32_t desc) \
225
{ \
226
sve_stN_r(env, vg, addr, desc, GETPC(), ESZ, MSZ, N, 0, \
227
- sve_st1##NAME##_le_host, sve_st1##NAME##_le_tlb, NULL); \
228
+ sve_st1##NAME##_le_host, sve_st1##NAME##_le_tlb); \
229
} \
230
void HELPER(sve_st##N##NAME##_be_r)(CPUARMState *env, void *vg, \
231
target_ulong addr, uint32_t desc) \
232
{ \
233
sve_stN_r(env, vg, addr, desc, GETPC(), ESZ, MSZ, N, 0, \
234
- sve_st1##NAME##_be_host, sve_st1##NAME##_be_tlb, NULL); \
235
+ sve_st1##NAME##_be_host, sve_st1##NAME##_be_tlb); \
236
} \
237
void HELPER(sve_st##N##NAME##_le_r_mte)(CPUARMState *env, void *vg, \
238
target_ulong addr, uint32_t desc) \
207
--
239
--
208
2.20.1
240
2.20.1
209
241
210
242
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
The log2_esize parameter is not used except trivially.
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
Drop the parameter and the deferral to gen_mte_check1.
5
Message-id: 20190412165416.7977-8-philmd@redhat.com
5
6
This fixes a bug in that the parameters as documented
7
in the header file were the reverse from those in the
8
implementation. Which meant that translate-sve.c was
9
passing the parameters in the wrong order.
10
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20210416183106.1516563-10-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
15
---
8
include/hw/devices.h | 3 ---
16
target/arm/translate-a64.h | 2 +-
9
include/hw/input/gamepad.h | 19 +++++++++++++++++++
17
target/arm/translate-a64.c | 15 +++++++--------
10
hw/arm/stellaris.c | 2 +-
18
target/arm/translate-sve.c | 4 ++--
11
hw/input/stellaris_input.c | 2 +-
19
3 files changed, 10 insertions(+), 11 deletions(-)
12
MAINTAINERS | 1 +
13
5 files changed, 22 insertions(+), 5 deletions(-)
14
create mode 100644 include/hw/input/gamepad.h
15
20
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
21
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
17
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/devices.h
23
--- a/target/arm/translate-a64.h
19
+++ b/include/hw/devices.h
24
+++ b/target/arm/translate-a64.h
20
@@ -XXX,XX +XXX,XX @@ void *tsc2005_init(qemu_irq pintdav);
25
@@ -XXX,XX +XXX,XX @@ TCGv_i64 clean_data_tbi(DisasContext *s, TCGv_i64 addr);
21
uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
26
TCGv_i64 gen_mte_check1(DisasContext *s, TCGv_i64 addr, bool is_write,
22
void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
27
bool tag_checked, int log2_size);
23
28
TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
24
-/* stellaris_input.c */
29
- bool tag_checked, int count, int log2_esize);
25
-void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
30
+ bool tag_checked, int size);
26
-
31
27
#endif
32
/* We should have at some point before trying to access an FP register
28
diff --git a/include/hw/input/gamepad.h b/include/hw/input/gamepad.h
33
* done the necessary access check, so assert that
29
new file mode 100644
34
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
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
35
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/arm/stellaris.c
36
--- a/target/arm/translate-a64.c
56
+++ b/hw/arm/stellaris.c
37
+++ b/target/arm/translate-a64.c
57
@@ -XXX,XX +XXX,XX @@
38
@@ -XXX,XX +XXX,XX @@ TCGv_i64 gen_mte_check1(DisasContext *s, TCGv_i64 addr, bool is_write,
58
#include "hw/sysbus.h"
39
* For MTE, check multiple logical sequential accesses.
59
#include "hw/ssi/ssi.h"
40
*/
60
#include "hw/arm/arm.h"
41
TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
61
-#include "hw/devices.h"
42
- bool tag_checked, int log2_esize, int total_size)
62
#include "qemu/timer.h"
43
+ bool tag_checked, int size)
63
#include "hw/i2c/i2c.h"
44
{
64
#include "net/net.h"
45
- if (tag_checked && s->mte_active[0] && total_size != (1 << log2_esize)) {
65
@@ -XXX,XX +XXX,XX @@
46
+ if (tag_checked && s->mte_active[0]) {
66
#include "sysemu/sysemu.h"
47
TCGv_i32 tcg_desc;
67
#include "hw/arm/armv7m.h"
48
TCGv_i64 ret;
68
#include "hw/char/pl011.h"
49
int desc = 0;
69
+#include "hw/input/gamepad.h"
50
@@ -XXX,XX +XXX,XX @@ TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
70
#include "hw/watchdog/cmsdk-apb-watchdog.h"
51
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
71
#include "hw/misc/unimp.h"
52
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
72
#include "cpu.h"
53
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
73
diff --git a/hw/input/stellaris_input.c b/hw/input/stellaris_input.c
54
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, total_size - 1);
55
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, size - 1);
56
tcg_desc = tcg_const_i32(desc);
57
58
ret = new_tmp_a64(s);
59
@@ -XXX,XX +XXX,XX @@ TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
60
61
return ret;
62
}
63
- return gen_mte_check1(s, addr, is_write, tag_checked, log2_esize);
64
+ return clean_data_tbi(s, addr);
65
}
66
67
typedef struct DisasCompare64 {
68
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn)
69
}
70
71
clean_addr = gen_mte_checkN(s, dirty_addr, !is_load,
72
- (wback || rn != 31) && !set_tag,
73
- size, 2 << size);
74
+ (wback || rn != 31) && !set_tag, 2 << size);
75
76
if (is_vector) {
77
if (is_load) {
78
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
79
* promote consecutive little-endian elements below.
80
*/
81
clean_addr = gen_mte_checkN(s, tcg_rn, is_store, is_postidx || rn != 31,
82
- size, total);
83
+ total);
84
85
/*
86
* Consecutive little-endian elements from a single register
87
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
88
tcg_rn = cpu_reg_sp(s, rn);
89
90
clean_addr = gen_mte_checkN(s, tcg_rn, !is_load, is_postidx || rn != 31,
91
- scale, total);
92
+ total);
93
94
tcg_ebytes = tcg_const_i64(1 << scale);
95
for (xs = 0; xs < selem; xs++) {
96
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
74
index XXXXXXX..XXXXXXX 100644
97
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/input/stellaris_input.c
98
--- a/target/arm/translate-sve.c
76
+++ b/hw/input/stellaris_input.c
99
+++ b/target/arm/translate-sve.c
77
@@ -XXX,XX +XXX,XX @@
100
@@ -XXX,XX +XXX,XX @@ static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
78
*/
101
79
#include "qemu/osdep.h"
102
dirty_addr = tcg_temp_new_i64();
80
#include "hw/hw.h"
103
tcg_gen_addi_i64(dirty_addr, cpu_reg_sp(s, rn), imm);
81
-#include "hw/devices.h"
104
- clean_addr = gen_mte_checkN(s, dirty_addr, false, rn != 31, len, MO_8);
82
+#include "hw/input/gamepad.h"
105
+ clean_addr = gen_mte_checkN(s, dirty_addr, false, rn != 31, len);
83
#include "ui/console.h"
106
tcg_temp_free_i64(dirty_addr);
84
107
85
typedef struct {
108
/*
86
diff --git a/MAINTAINERS b/MAINTAINERS
109
@@ -XXX,XX +XXX,XX @@ static void do_str(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
87
index XXXXXXX..XXXXXXX 100644
110
88
--- a/MAINTAINERS
111
dirty_addr = tcg_temp_new_i64();
89
+++ b/MAINTAINERS
112
tcg_gen_addi_i64(dirty_addr, cpu_reg_sp(s, rn), imm);
90
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
113
- clean_addr = gen_mte_checkN(s, dirty_addr, false, rn != 31, len, MO_8);
91
L: qemu-arm@nongnu.org
114
+ clean_addr = gen_mte_checkN(s, dirty_addr, false, rn != 31, len);
92
S: Maintained
115
tcg_temp_free_i64(dirty_addr);
93
F: hw/*/stellaris*
116
94
+F: include/hw/input/gamepad.h
117
/* Note that unpredicated load/store of vector/predicate registers
95
96
Versatile Express
97
M: Peter Maydell <peter.maydell@linaro.org>
98
--
118
--
99
2.20.1
119
2.20.1
100
120
101
121
diff view generated by jsdifflib
1
The M-profile floating point support has three associated config
1
From: Richard Henderson <richard.henderson@linaro.org>
2
registers: FPCAR, FPCCR and FPDSCR. It also makes the registers
3
CPACR and NSACR have behaviour other than reads-as-zero.
4
Add support for all of these as simple reads-as-written registers.
5
We will hook up actual functionality later.
6
2
7
The main complexity here is handling the FPCCR register, which
3
The encoding of size = 2 and size = 3 had the incorrect decode
8
has a mix of banked and unbanked bits.
4
for align, overlapping the stride field. This error was hidden
5
by what should have been unnecessary masking in translate.
9
6
10
Note that we don't share storage with the A-profile
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
cpu->cp15.nsacr and cpu->cp15.cpacr_el1, though the behaviour
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
is quite similar, for two reasons:
9
Message-id: 20210419202257.161730-2-richard.henderson@linaro.org
13
* the M profile CPACR is banked between security states
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
* it preserves the invariant that M profile uses no state
11
---
15
inside the cp15 substruct
12
target/arm/neon-ls.decode | 4 ++--
13
target/arm/translate-neon.c.inc | 4 ++--
14
2 files changed, 4 insertions(+), 4 deletions(-)
16
15
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20190416125744.27770-4-peter.maydell@linaro.org
20
---
21
target/arm/cpu.h | 34 ++++++++++++
22
hw/intc/armv7m_nvic.c | 125 ++++++++++++++++++++++++++++++++++++++++++
23
target/arm/cpu.c | 5 ++
24
target/arm/machine.c | 16 ++++++
25
4 files changed, 180 insertions(+)
26
27
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
28
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/cpu.h
18
--- a/target/arm/neon-ls.decode
30
+++ b/target/arm/cpu.h
19
+++ b/target/arm/neon-ls.decode
31
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
20
@@ -XXX,XX +XXX,XX @@ VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
32
uint32_t scr[M_REG_NUM_BANKS];
21
33
uint32_t msplim[M_REG_NUM_BANKS];
22
VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 00 n:2 reg_idx:3 align:1 rm:4 \
34
uint32_t psplim[M_REG_NUM_BANKS];
23
vd=%vd_dp size=0 stride=1
35
+ uint32_t fpcar[M_REG_NUM_BANKS];
24
-VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 01 n:2 reg_idx:2 align:2 rm:4 \
36
+ uint32_t fpccr[M_REG_NUM_BANKS];
25
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 01 n:2 reg_idx:2 . align:1 rm:4 \
37
+ uint32_t fpdscr[M_REG_NUM_BANKS];
26
vd=%vd_dp size=1 stride=%imm1_5_p1
38
+ uint32_t cpacr[M_REG_NUM_BANKS];
27
-VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 10 n:2 reg_idx:1 align:3 rm:4 \
39
+ uint32_t nsacr;
28
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 10 n:2 reg_idx:1 . align:2 rm:4 \
40
} v7m;
29
vd=%vd_dp size=2 stride=%imm1_6_p1
41
30
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
42
/* Information associated with an exception about to be taken:
43
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_CSSELR, LEVEL, 1, 3)
44
*/
45
FIELD(V7M_CSSELR, INDEX, 0, 4)
46
47
+/* v7M FPCCR bits */
48
+FIELD(V7M_FPCCR, LSPACT, 0, 1)
49
+FIELD(V7M_FPCCR, USER, 1, 1)
50
+FIELD(V7M_FPCCR, S, 2, 1)
51
+FIELD(V7M_FPCCR, THREAD, 3, 1)
52
+FIELD(V7M_FPCCR, HFRDY, 4, 1)
53
+FIELD(V7M_FPCCR, MMRDY, 5, 1)
54
+FIELD(V7M_FPCCR, BFRDY, 6, 1)
55
+FIELD(V7M_FPCCR, SFRDY, 7, 1)
56
+FIELD(V7M_FPCCR, MONRDY, 8, 1)
57
+FIELD(V7M_FPCCR, SPLIMVIOL, 9, 1)
58
+FIELD(V7M_FPCCR, UFRDY, 10, 1)
59
+FIELD(V7M_FPCCR, RES0, 11, 15)
60
+FIELD(V7M_FPCCR, TS, 26, 1)
61
+FIELD(V7M_FPCCR, CLRONRETS, 27, 1)
62
+FIELD(V7M_FPCCR, CLRONRET, 28, 1)
63
+FIELD(V7M_FPCCR, LSPENS, 29, 1)
64
+FIELD(V7M_FPCCR, LSPEN, 30, 1)
65
+FIELD(V7M_FPCCR, ASPEN, 31, 1)
66
+/* These bits are banked. Others are non-banked and live in the M_REG_S bank */
67
+#define R_V7M_FPCCR_BANKED_MASK \
68
+ (R_V7M_FPCCR_LSPACT_MASK | \
69
+ R_V7M_FPCCR_USER_MASK | \
70
+ R_V7M_FPCCR_THREAD_MASK | \
71
+ R_V7M_FPCCR_MMRDY_MASK | \
72
+ R_V7M_FPCCR_SPLIMVIOL_MASK | \
73
+ R_V7M_FPCCR_UFRDY_MASK | \
74
+ R_V7M_FPCCR_ASPEN_MASK)
75
+
76
/*
77
* System register ID fields.
78
*/
79
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
80
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
81
--- a/hw/intc/armv7m_nvic.c
32
--- a/target/arm/translate-neon.c.inc
82
+++ b/hw/intc/armv7m_nvic.c
33
+++ b/target/arm/translate-neon.c.inc
83
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
34
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
84
}
35
switch (nregs) {
85
case 0xd84: /* CSSELR */
36
case 1:
86
return cpu->env.v7m.csselr[attrs.secure];
37
if (((a->align & (1 << a->size)) != 0) ||
87
+ case 0xd88: /* CPACR */
38
- (a->size == 2 && ((a->align & 3) == 1 || (a->align & 3) == 2))) {
88
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
39
+ (a->size == 2 && (a->align == 1 || a->align == 2))) {
89
+ return 0;
40
return false;
90
+ }
91
+ return cpu->env.v7m.cpacr[attrs.secure];
92
+ case 0xd8c: /* NSACR */
93
+ if (!attrs.secure || !arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
94
+ return 0;
95
+ }
96
+ return cpu->env.v7m.nsacr;
97
/* TODO: Implement debug registers. */
98
case 0xd90: /* MPU_TYPE */
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 */
144
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
145
cpu->env.v7m.csselr[attrs.secure] = value & R_V7M_CSSELR_INDEX_MASK;
146
}
41
}
147
break;
42
break;
148
+ case 0xd88: /* CPACR */
43
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
149
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
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);
158
+ }
159
+ break;
160
case 0xd90: /* MPU_TYPE */
161
return; /* RO */
162
case 0xd94: /* MPU_CTRL */
163
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
164
}
44
}
165
break;
45
break;
166
}
46
case 4:
167
+ case 0xf34: /* FPCCR */
47
- if ((a->size == 2) && ((a->align & 3) == 3)) {
168
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
48
+ if (a->size == 2 && a->align == 3) {
169
+ /* Not all bits here are banked. */
49
return false;
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
}
50
}
243
51
break;
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
252
diff --git a/target/arm/machine.c b/target/arm/machine.c
253
index XXXXXXX..XXXXXXX 100644
254
--- a/target/arm/machine.c
255
+++ b/target/arm/machine.c
256
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_v8m = {
257
}
258
};
259
260
+static const VMStateDescription vmstate_m_fp = {
261
+ .name = "cpu/m/fp",
262
+ .version_id = 1,
263
+ .minimum_version_id = 1,
264
+ .needed = vfp_needed,
265
+ .fields = (VMStateField[]) {
266
+ VMSTATE_UINT32_ARRAY(env.v7m.fpcar, ARMCPU, M_REG_NUM_BANKS),
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),
271
+ VMSTATE_END_OF_LIST()
272
+ }
273
+};
274
+
275
static const VMStateDescription vmstate_m = {
276
.name = "cpu/m",
277
.version_id = 4,
278
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
279
&vmstate_m_scr,
280
&vmstate_m_other_sp,
281
&vmstate_m_v8m,
282
+ &vmstate_m_fp,
283
NULL
284
}
285
};
286
--
52
--
287
2.20.1
53
2.20.1
288
54
289
55
diff view generated by jsdifflib
1
Implement the VLSTM instruction for v7M for the FPU present case.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
We're about to rearrange the macro expansion surrounding tbflags,
4
and this field name will be expanded using the bit definition of
5
the same name, resulting in a token pasting error.
6
7
So SCTLR_B -> SCTLR__B in the 3 uses, and document it.
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20210419202257.161730-3-richard.henderson@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
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
6
---
13
---
7
target/arm/cpu.h | 2 +
14
target/arm/cpu.h | 2 +-
8
target/arm/helper.h | 2 +
15
target/arm/helper.c | 2 +-
9
target/arm/helper.c | 84 ++++++++++++++++++++++++++++++++++++++++++
16
target/arm/translate.c | 2 +-
10
target/arm/translate.c | 15 +++++++-
17
3 files changed, 3 insertions(+), 3 deletions(-)
11
4 files changed, 102 insertions(+), 1 deletion(-)
12
18
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
21
--- a/target/arm/cpu.h
16
+++ b/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, VECSTRIDE, 12, 2) /* Not cached. */
18
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
24
*/
19
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
25
FIELD(TBFLAG_A32, XSCALE_CPAR, 12, 2)
20
#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
26
FIELD(TBFLAG_A32, VFPEN, 14, 1) /* Partially cached, minus FPEXC. */
21
+#define EXCP_LSERR 21 /* v8M LSERR SecureFault */
27
-FIELD(TBFLAG_A32, SCTLR_B, 15, 1)
22
+#define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */
28
+FIELD(TBFLAG_A32, SCTLR__B, 15, 1) /* Cannot overlap with SCTLR_B */
23
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
29
FIELD(TBFLAG_A32, HSTR_ACTIVE, 16, 1)
24
30
/*
25
#define ARMV7M_EXCP_RESET 1
31
* Indicates whether cp register reads and writes by guest code should access
26
diff --git a/target/arm/helper.h b/target/arm/helper.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/helper.h
29
+++ b/target/arm/helper.h
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
31
32
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
33
34
+DEF_HELPER_2(v7m_vlstm, void, env, i32)
35
+
36
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
37
38
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
40
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/helper.c
34
--- a/target/arm/helper.c
42
+++ b/target/arm/helper.c
35
+++ b/target/arm/helper.c
43
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
36
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_common_32(CPUARMState *env, int fp_el,
44
g_assert_not_reached();
37
bool sctlr_b = arm_sctlr_b(env);
45
}
38
46
39
if (sctlr_b) {
47
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
40
- flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, 1);
48
+{
41
+ flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR__B, 1);
49
+ /* translate.c should never generate calls here in user-only mode */
50
+ g_assert_not_reached();
51
+}
52
+
53
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
54
{
55
/* The TT instructions can be used by unprivileged code, but in
56
@@ -XXX,XX +XXX,XX @@ static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
57
}
42
}
58
}
43
if (arm_cpu_data_is_big_endian_a32(env, sctlr_b)) {
59
44
flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
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)) {
69
+ return;
70
+ }
71
+
72
+ /* Check access to the coprocessor is permitted */
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
45
diff --git a/target/arm/translate.c b/target/arm/translate.c
156
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
157
--- a/target/arm/translate.c
47
--- a/target/arm/translate.c
158
+++ b/target/arm/translate.c
48
+++ b/target/arm/translate.c
159
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
49
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
160
if (!s->v8m_secure || (insn & 0x0040f0ff)) {
50
FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
161
goto illegal_op;
51
dc->debug_target_el =
162
}
52
FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
163
- /* Just NOP since FP support is not implemented */
53
- dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
164
+
54
+ dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR__B);
165
+ if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
55
dc->hstr_active = FIELD_EX32(tb_flags, TBFLAG_A32, HSTR_ACTIVE);
166
+ TCGv_i32 fptr = load_reg(s, rn);
56
dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
167
+
57
dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
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) &&
181
--
58
--
182
2.20.1
59
2.20.1
183
60
184
61
diff view generated by jsdifflib
1
We are close to running out of TB flags for AArch32; we could
1
From: Richard Henderson <richard.henderson@linaro.org>
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.
6
2
3
We're about to rearrange the macro expansion surrounding tbflags,
4
and this field name will be expanded using the bit definition of
5
the same name, resulting in a token pasting error.
6
7
So PSTATE_SS -> PSTATE__SS in the uses, and document it.
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20210419202257.161730-4-richard.henderson@linaro.org
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>
9
Message-id: 20190416125744.27770-18-peter.maydell@linaro.org
10
---
13
---
11
target/arm/cpu.h | 10 ++++++----
14
target/arm/cpu.h | 2 +-
12
target/arm/cpu.c | 7 +++++++
15
target/arm/helper.c | 4 ++--
13
target/arm/helper.c | 6 +++++-
16
target/arm/translate-a64.c | 2 +-
14
target/arm/translate.c | 9 +++++++--
17
target/arm/translate.c | 2 +-
15
4 files changed, 25 insertions(+), 7 deletions(-)
18
4 files changed, 5 insertions(+), 5 deletions(-)
16
19
17
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
18
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
22
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
23
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
24
@@ -XXX,XX +XXX,XX @@ typedef ARMCPU ArchCPU;
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
25
*/
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
26
FIELD(TBFLAG_ANY, AARCH64_STATE, 31, 1)
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
27
FIELD(TBFLAG_ANY, SS_ACTIVE, 30, 1)
25
+/*
28
-FIELD(TBFLAG_ANY, PSTATE_SS, 29, 1) /* Not cached. */
26
+ * We store the bottom two bits of the CPAR as TB flags and handle
29
+FIELD(TBFLAG_ANY, PSTATE__SS, 29, 1) /* Not cached. */
27
+ * checks on the other bits at runtime. This shares the same bits as
30
FIELD(TBFLAG_ANY, BE_DATA, 28, 1)
28
+ * VECSTRIDE, which is OK as no XScale CPU has VFP.
31
FIELD(TBFLAG_ANY, MMUIDX, 24, 4)
29
+ */
32
/* Target EL if we take a floating-point-disabled exception */
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
33
diff --git a/target/arm/helper.c b/target/arm/helper.c
64
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/helper.c
35
--- a/target/arm/helper.c
66
+++ b/target/arm/helper.c
36
+++ b/target/arm/helper.c
67
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
37
@@ -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)) {
38
* 0 x Inactive (the TB flag for SS is always 0)
69
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
39
* 1 0 Active-pending
70
}
40
* 1 1 Active-not-pending
71
- flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
41
- * SS_ACTIVE is set in hflags; PSTATE_SS is computed every TB.
72
+ /* Note that XSCALE_CPAR shares bits with VECSTRIDE */
42
+ * SS_ACTIVE is set in hflags; PSTATE__SS is computed every TB.
73
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
43
*/
74
+ flags = FIELD_DP32(flags, TBFLAG_A32,
44
if (FIELD_EX32(flags, TBFLAG_ANY, SS_ACTIVE) &&
75
+ XSCALE_CPAR, env->cp15.c15_cpar);
45
(env->pstate & PSTATE_SS)) {
76
+ }
46
- flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1);
47
+ flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE__SS, 1);
77
}
48
}
78
49
79
flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
50
*pflags = flags;
51
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/translate-a64.c
54
+++ b/target/arm/translate-a64.c
55
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
56
* end the TB
57
*/
58
dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
59
- dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
60
+ dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE__SS);
61
dc->is_ldex = false;
62
dc->debug_target_el = FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
63
80
diff --git a/target/arm/translate.c b/target/arm/translate.c
64
diff --git a/target/arm/translate.c b/target/arm/translate.c
81
index XXXXXXX..XXXXXXX 100644
65
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/translate.c
66
--- a/target/arm/translate.c
83
+++ b/target/arm/translate.c
67
+++ b/target/arm/translate.c
84
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
68
@@ -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);
69
* end the TB
86
dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
70
*/
87
dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
71
dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
88
- dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
72
- dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
89
- dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
73
+ dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE__SS);
90
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
74
dc->is_ldex = false;
91
+ dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
75
92
+ dc->vec_stride = 0;
76
dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
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
--
77
--
101
2.20.1
78
2.20.1
102
79
103
80
diff view generated by jsdifflib
1
Add a new helper function which returns the MMU index to use
1
From: Richard Henderson <richard.henderson@linaro.org>
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.
6
2
7
We are going to need this for the lazy-FP-stacking code.
3
We're about to split tbflags into two parts. These macros
4
will ensure that the correct part is used with the correct
5
set of bits.
8
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210419202257.161730-5-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20190416125744.27770-21-peter.maydell@linaro.org
12
---
11
---
13
target/arm/cpu.h | 7 +++++++
12
target/arm/cpu.h | 22 +++++++++-
14
target/arm/helper.c | 14 +++++++++++---
13
target/arm/helper-a64.c | 2 +-
15
2 files changed, 18 insertions(+), 3 deletions(-)
14
target/arm/helper.c | 85 +++++++++++++++++---------------------
15
target/arm/translate-a64.c | 36 ++++++++--------
16
target/arm/translate.c | 48 ++++++++++-----------
17
5 files changed, 101 insertions(+), 92 deletions(-)
16
18
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
21
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
23
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, TCMA, 16, 2)
22
}
24
FIELD(TBFLAG_A64, MTE_ACTIVE, 18, 1)
25
FIELD(TBFLAG_A64, MTE0_ACTIVE, 19, 1)
26
27
+/*
28
+ * Helpers for using the above.
29
+ */
30
+#define DP_TBFLAG_ANY(DST, WHICH, VAL) \
31
+ (DST = FIELD_DP32(DST, TBFLAG_ANY, WHICH, VAL))
32
+#define DP_TBFLAG_A64(DST, WHICH, VAL) \
33
+ (DST = FIELD_DP32(DST, TBFLAG_A64, WHICH, VAL))
34
+#define DP_TBFLAG_A32(DST, WHICH, VAL) \
35
+ (DST = FIELD_DP32(DST, TBFLAG_A32, WHICH, VAL))
36
+#define DP_TBFLAG_M32(DST, WHICH, VAL) \
37
+ (DST = FIELD_DP32(DST, TBFLAG_M32, WHICH, VAL))
38
+#define DP_TBFLAG_AM32(DST, WHICH, VAL) \
39
+ (DST = FIELD_DP32(DST, TBFLAG_AM32, WHICH, VAL))
40
+
41
+#define EX_TBFLAG_ANY(IN, WHICH) FIELD_EX32(IN, TBFLAG_ANY, WHICH)
42
+#define EX_TBFLAG_A64(IN, WHICH) FIELD_EX32(IN, TBFLAG_A64, WHICH)
43
+#define EX_TBFLAG_A32(IN, WHICH) FIELD_EX32(IN, TBFLAG_A32, WHICH)
44
+#define EX_TBFLAG_M32(IN, WHICH) FIELD_EX32(IN, TBFLAG_M32, WHICH)
45
+#define EX_TBFLAG_AM32(IN, WHICH) FIELD_EX32(IN, TBFLAG_AM32, WHICH)
46
+
47
/**
48
* cpu_mmu_index:
49
* @env: The cpu environment
50
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, MTE0_ACTIVE, 19, 1)
51
*/
52
static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
53
{
54
- return FIELD_EX32(env->hflags, TBFLAG_ANY, MMUIDX);
55
+ return EX_TBFLAG_ANY(env->hflags, MMUIDX);
23
}
56
}
24
57
25
+/*
58
static inline bool bswap_code(bool sctlr_b)
26
+ * Return the MMU index for a v7M CPU with all relevant information
59
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
27
+ * manually specified.
60
index XXXXXXX..XXXXXXX 100644
28
+ */
61
--- a/target/arm/helper-a64.c
29
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
62
+++ b/target/arm/helper-a64.c
30
+ bool secstate, bool priv, bool negpri);
63
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
31
+
64
* the hflags rebuild, since we can pull the composite TBII field
32
/* Return the MMU index for a v7M CPU in the specified security and
65
* from there.
33
* privilege state.
66
*/
34
*/
67
- tbii = FIELD_EX32(env->hflags, TBFLAG_A64, TBII);
68
+ tbii = EX_TBFLAG_A64(env->hflags, TBII);
69
if ((tbii >> extract64(new_pc, 55, 1)) & 1) {
70
/* TBI is enabled. */
71
int core_mmu_idx = cpu_mmu_index(env, false);
35
diff --git a/target/arm/helper.c b/target/arm/helper.c
72
diff --git a/target/arm/helper.c b/target/arm/helper.c
36
index XXXXXXX..XXXXXXX 100644
73
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper.c
74
--- a/target/arm/helper.c
38
+++ b/target/arm/helper.c
75
+++ b/target/arm/helper.c
39
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
76
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
40
return 0;
77
static uint32_t rebuild_hflags_common(CPUARMState *env, int fp_el,
78
ARMMMUIdx mmu_idx, uint32_t flags)
79
{
80
- flags = FIELD_DP32(flags, TBFLAG_ANY, FPEXC_EL, fp_el);
81
- flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX,
82
- arm_to_core_mmu_idx(mmu_idx));
83
+ DP_TBFLAG_ANY(flags, FPEXC_EL, fp_el);
84
+ DP_TBFLAG_ANY(flags, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
85
86
if (arm_singlestep_active(env)) {
87
- flags = FIELD_DP32(flags, TBFLAG_ANY, SS_ACTIVE, 1);
88
+ DP_TBFLAG_ANY(flags, SS_ACTIVE, 1);
89
}
90
return flags;
41
}
91
}
42
92
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_common_32(CPUARMState *env, int fp_el,
43
-ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
93
bool sctlr_b = arm_sctlr_b(env);
44
- bool secstate, bool priv)
94
45
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
95
if (sctlr_b) {
46
+ bool secstate, bool priv, bool negpri)
96
- flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR__B, 1);
97
+ DP_TBFLAG_A32(flags, SCTLR__B, 1);
98
}
99
if (arm_cpu_data_is_big_endian_a32(env, sctlr_b)) {
100
- flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
101
+ DP_TBFLAG_ANY(flags, BE_DATA, 1);
102
}
103
- flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
104
+ DP_TBFLAG_A32(flags, NS, !access_secure_reg(env));
105
106
return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
107
}
108
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_m32(CPUARMState *env, int fp_el,
109
uint32_t flags = 0;
110
111
if (arm_v7m_is_handler_mode(env)) {
112
- flags = FIELD_DP32(flags, TBFLAG_M32, HANDLER, 1);
113
+ DP_TBFLAG_M32(flags, HANDLER, 1);
114
}
115
116
/*
117
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_m32(CPUARMState *env, int fp_el,
118
if (arm_feature(env, ARM_FEATURE_V8) &&
119
!((mmu_idx & ARM_MMU_IDX_M_NEGPRI) &&
120
(env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_STKOFHFNMIGN_MASK))) {
121
- flags = FIELD_DP32(flags, TBFLAG_M32, STACKCHECK, 1);
122
+ DP_TBFLAG_M32(flags, STACKCHECK, 1);
123
}
124
125
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
126
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_aprofile(CPUARMState *env)
47
{
127
{
48
ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
128
int flags = 0;
49
129
50
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
130
- flags = FIELD_DP32(flags, TBFLAG_ANY, DEBUG_TARGET_EL,
51
mmu_idx |= ARM_MMU_IDX_M_PRIV;
131
- arm_debug_target_el(env));
52
}
132
+ DP_TBFLAG_ANY(flags, DEBUG_TARGET_EL, arm_debug_target_el(env));
53
133
return flags;
54
- if (armv7m_nvic_neg_prio_requested(env->nvic, secstate)) {
55
+ if (negpri) {
56
mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
57
}
58
59
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
60
return mmu_idx;
61
}
134
}
62
135
63
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
136
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
64
+ bool secstate, bool priv)
137
uint32_t flags = rebuild_hflags_aprofile(env);
65
+{
138
66
+ bool negpri = armv7m_nvic_neg_prio_requested(env->nvic, secstate);
139
if (arm_el_is_aa64(env, 1)) {
67
+
140
- flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
68
+ return arm_v7m_mmu_idx_all(env, secstate, priv, negpri);
141
+ DP_TBFLAG_A32(flags, VFPEN, 1);
69
+}
142
}
70
+
143
71
/* Return the MMU index for a v7M CPU in the specified security state */
144
if (arm_current_el(env) < 2 && env->cp15.hstr_el2 &&
72
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
145
(arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
73
{
146
- flags = FIELD_DP32(flags, TBFLAG_A32, HSTR_ACTIVE, 1);
147
+ DP_TBFLAG_A32(flags, HSTR_ACTIVE, 1);
148
}
149
150
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
151
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
152
uint64_t sctlr;
153
int tbii, tbid;
154
155
- flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
156
+ DP_TBFLAG_ANY(flags, AARCH64_STATE, 1);
157
158
/* Get control bits for tagged addresses. */
159
tbid = aa64_va_parameter_tbi(tcr, mmu_idx);
160
tbii = tbid & ~aa64_va_parameter_tbid(tcr, mmu_idx);
161
162
- flags = FIELD_DP32(flags, TBFLAG_A64, TBII, tbii);
163
- flags = FIELD_DP32(flags, TBFLAG_A64, TBID, tbid);
164
+ DP_TBFLAG_A64(flags, TBII, tbii);
165
+ DP_TBFLAG_A64(flags, TBID, tbid);
166
167
if (cpu_isar_feature(aa64_sve, env_archcpu(env))) {
168
int sve_el = sve_exception_el(env, el);
169
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
170
} else {
171
zcr_len = sve_zcr_len_for_el(env, el);
172
}
173
- flags = FIELD_DP32(flags, TBFLAG_A64, SVEEXC_EL, sve_el);
174
- flags = FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len);
175
+ DP_TBFLAG_A64(flags, SVEEXC_EL, sve_el);
176
+ DP_TBFLAG_A64(flags, ZCR_LEN, zcr_len);
177
}
178
179
sctlr = regime_sctlr(env, stage1);
180
181
if (arm_cpu_data_is_big_endian_a64(el, sctlr)) {
182
- flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
183
+ DP_TBFLAG_ANY(flags, BE_DATA, 1);
184
}
185
186
if (cpu_isar_feature(aa64_pauth, env_archcpu(env))) {
187
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
188
* The decision of which action to take is left to a helper.
189
*/
190
if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) {
191
- flags = FIELD_DP32(flags, TBFLAG_A64, PAUTH_ACTIVE, 1);
192
+ DP_TBFLAG_A64(flags, PAUTH_ACTIVE, 1);
193
}
194
}
195
196
if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
197
/* Note that SCTLR_EL[23].BT == SCTLR_BT1. */
198
if (sctlr & (el == 0 ? SCTLR_BT0 : SCTLR_BT1)) {
199
- flags = FIELD_DP32(flags, TBFLAG_A64, BT, 1);
200
+ DP_TBFLAG_A64(flags, BT, 1);
201
}
202
}
203
204
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
205
case ARMMMUIdx_SE10_1:
206
case ARMMMUIdx_SE10_1_PAN:
207
/* TODO: ARMv8.3-NV */
208
- flags = FIELD_DP32(flags, TBFLAG_A64, UNPRIV, 1);
209
+ DP_TBFLAG_A64(flags, UNPRIV, 1);
210
break;
211
case ARMMMUIdx_E20_2:
212
case ARMMMUIdx_E20_2_PAN:
213
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
214
* gated by HCR_EL2.<E2H,TGE> == '11', and so is LDTR.
215
*/
216
if (env->cp15.hcr_el2 & HCR_TGE) {
217
- flags = FIELD_DP32(flags, TBFLAG_A64, UNPRIV, 1);
218
+ DP_TBFLAG_A64(flags, UNPRIV, 1);
219
}
220
break;
221
default:
222
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
223
* 4) If no Allocation Tag Access, then all accesses are Unchecked.
224
*/
225
if (allocation_tag_access_enabled(env, el, sctlr)) {
226
- flags = FIELD_DP32(flags, TBFLAG_A64, ATA, 1);
227
+ DP_TBFLAG_A64(flags, ATA, 1);
228
if (tbid
229
&& !(env->pstate & PSTATE_TCO)
230
&& (sctlr & (el == 0 ? SCTLR_TCF0 : SCTLR_TCF))) {
231
- flags = FIELD_DP32(flags, TBFLAG_A64, MTE_ACTIVE, 1);
232
+ DP_TBFLAG_A64(flags, MTE_ACTIVE, 1);
233
}
234
}
235
/* And again for unprivileged accesses, if required. */
236
- if (FIELD_EX32(flags, TBFLAG_A64, UNPRIV)
237
+ if (EX_TBFLAG_A64(flags, UNPRIV)
238
&& tbid
239
&& !(env->pstate & PSTATE_TCO)
240
&& (sctlr & SCTLR_TCF0)
241
&& allocation_tag_access_enabled(env, 0, sctlr)) {
242
- flags = FIELD_DP32(flags, TBFLAG_A64, MTE0_ACTIVE, 1);
243
+ DP_TBFLAG_A64(flags, MTE0_ACTIVE, 1);
244
}
245
/* Cache TCMA as well as TBI. */
246
- flags = FIELD_DP32(flags, TBFLAG_A64, TCMA,
247
- aa64_va_parameter_tcma(tcr, mmu_idx));
248
+ DP_TBFLAG_A64(flags, TCMA, aa64_va_parameter_tcma(tcr, mmu_idx));
249
}
250
251
return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
252
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
253
*cs_base = 0;
254
assert_hflags_rebuild_correctly(env);
255
256
- if (FIELD_EX32(flags, TBFLAG_ANY, AARCH64_STATE)) {
257
+ if (EX_TBFLAG_ANY(flags, AARCH64_STATE)) {
258
*pc = env->pc;
259
if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
260
- flags = FIELD_DP32(flags, TBFLAG_A64, BTYPE, env->btype);
261
+ DP_TBFLAG_A64(flags, BTYPE, env->btype);
262
}
263
} else {
264
*pc = env->regs[15];
265
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
266
if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
267
FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S)
268
!= env->v7m.secure) {
269
- flags = FIELD_DP32(flags, TBFLAG_M32, FPCCR_S_WRONG, 1);
270
+ DP_TBFLAG_M32(flags, FPCCR_S_WRONG, 1);
271
}
272
273
if ((env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) &&
274
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
275
* active FP context; we must create a new FP context before
276
* executing any FP insn.
277
*/
278
- flags = FIELD_DP32(flags, TBFLAG_M32, NEW_FP_CTXT_NEEDED, 1);
279
+ DP_TBFLAG_M32(flags, NEW_FP_CTXT_NEEDED, 1);
280
}
281
282
bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
283
if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) {
284
- flags = FIELD_DP32(flags, TBFLAG_M32, LSPACT, 1);
285
+ DP_TBFLAG_M32(flags, LSPACT, 1);
286
}
287
} else {
288
/*
289
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
290
* Note that VECLEN+VECSTRIDE are RES0 for M-profile.
291
*/
292
if (arm_feature(env, ARM_FEATURE_XSCALE)) {
293
- flags = FIELD_DP32(flags, TBFLAG_A32,
294
- XSCALE_CPAR, env->cp15.c15_cpar);
295
+ DP_TBFLAG_A32(flags, XSCALE_CPAR, env->cp15.c15_cpar);
296
} else {
297
- flags = FIELD_DP32(flags, TBFLAG_A32, VECLEN,
298
- env->vfp.vec_len);
299
- flags = FIELD_DP32(flags, TBFLAG_A32, VECSTRIDE,
300
- env->vfp.vec_stride);
301
+ DP_TBFLAG_A32(flags, VECLEN, env->vfp.vec_len);
302
+ DP_TBFLAG_A32(flags, VECSTRIDE, env->vfp.vec_stride);
303
}
304
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) {
305
- flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
306
+ DP_TBFLAG_A32(flags, VFPEN, 1);
307
}
308
}
309
310
- flags = FIELD_DP32(flags, TBFLAG_AM32, THUMB, env->thumb);
311
- flags = FIELD_DP32(flags, TBFLAG_AM32, CONDEXEC, env->condexec_bits);
312
+ DP_TBFLAG_AM32(flags, THUMB, env->thumb);
313
+ DP_TBFLAG_AM32(flags, CONDEXEC, env->condexec_bits);
314
}
315
316
/*
317
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
318
* 1 1 Active-not-pending
319
* SS_ACTIVE is set in hflags; PSTATE__SS is computed every TB.
320
*/
321
- if (FIELD_EX32(flags, TBFLAG_ANY, SS_ACTIVE) &&
322
- (env->pstate & PSTATE_SS)) {
323
- flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE__SS, 1);
324
+ if (EX_TBFLAG_ANY(flags, SS_ACTIVE) && (env->pstate & PSTATE_SS)) {
325
+ DP_TBFLAG_ANY(flags, PSTATE__SS, 1);
326
}
327
328
*pflags = flags;
329
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
330
index XXXXXXX..XXXXXXX 100644
331
--- a/target/arm/translate-a64.c
332
+++ b/target/arm/translate-a64.c
333
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
334
!arm_el_is_aa64(env, 3);
335
dc->thumb = 0;
336
dc->sctlr_b = 0;
337
- dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
338
+ dc->be_data = EX_TBFLAG_ANY(tb_flags, BE_DATA) ? MO_BE : MO_LE;
339
dc->condexec_mask = 0;
340
dc->condexec_cond = 0;
341
- core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
342
+ core_mmu_idx = EX_TBFLAG_ANY(tb_flags, MMUIDX);
343
dc->mmu_idx = core_to_aa64_mmu_idx(core_mmu_idx);
344
- dc->tbii = FIELD_EX32(tb_flags, TBFLAG_A64, TBII);
345
- dc->tbid = FIELD_EX32(tb_flags, TBFLAG_A64, TBID);
346
- dc->tcma = FIELD_EX32(tb_flags, TBFLAG_A64, TCMA);
347
+ dc->tbii = EX_TBFLAG_A64(tb_flags, TBII);
348
+ dc->tbid = EX_TBFLAG_A64(tb_flags, TBID);
349
+ dc->tcma = EX_TBFLAG_A64(tb_flags, TCMA);
350
dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
351
#if !defined(CONFIG_USER_ONLY)
352
dc->user = (dc->current_el == 0);
353
#endif
354
- dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
355
- dc->sve_excp_el = FIELD_EX32(tb_flags, TBFLAG_A64, SVEEXC_EL);
356
- dc->sve_len = (FIELD_EX32(tb_flags, TBFLAG_A64, ZCR_LEN) + 1) * 16;
357
- dc->pauth_active = FIELD_EX32(tb_flags, TBFLAG_A64, PAUTH_ACTIVE);
358
- dc->bt = FIELD_EX32(tb_flags, TBFLAG_A64, BT);
359
- dc->btype = FIELD_EX32(tb_flags, TBFLAG_A64, BTYPE);
360
- dc->unpriv = FIELD_EX32(tb_flags, TBFLAG_A64, UNPRIV);
361
- dc->ata = FIELD_EX32(tb_flags, TBFLAG_A64, ATA);
362
- dc->mte_active[0] = FIELD_EX32(tb_flags, TBFLAG_A64, MTE_ACTIVE);
363
- dc->mte_active[1] = FIELD_EX32(tb_flags, TBFLAG_A64, MTE0_ACTIVE);
364
+ dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
365
+ dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
366
+ dc->sve_len = (EX_TBFLAG_A64(tb_flags, ZCR_LEN) + 1) * 16;
367
+ dc->pauth_active = EX_TBFLAG_A64(tb_flags, PAUTH_ACTIVE);
368
+ dc->bt = EX_TBFLAG_A64(tb_flags, BT);
369
+ dc->btype = EX_TBFLAG_A64(tb_flags, BTYPE);
370
+ dc->unpriv = EX_TBFLAG_A64(tb_flags, UNPRIV);
371
+ dc->ata = EX_TBFLAG_A64(tb_flags, ATA);
372
+ dc->mte_active[0] = EX_TBFLAG_A64(tb_flags, MTE_ACTIVE);
373
+ dc->mte_active[1] = EX_TBFLAG_A64(tb_flags, MTE0_ACTIVE);
374
dc->vec_len = 0;
375
dc->vec_stride = 0;
376
dc->cp_regs = arm_cpu->cp_regs;
377
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
378
* emit code to generate a software step exception
379
* end the TB
380
*/
381
- dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
382
- dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE__SS);
383
+ dc->ss_active = EX_TBFLAG_ANY(tb_flags, SS_ACTIVE);
384
+ dc->pstate_ss = EX_TBFLAG_ANY(tb_flags, PSTATE__SS);
385
dc->is_ldex = false;
386
- dc->debug_target_el = FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
387
+ dc->debug_target_el = EX_TBFLAG_ANY(tb_flags, DEBUG_TARGET_EL);
388
389
/* Bound the number of insns to execute to those left on the page. */
390
bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
391
diff --git a/target/arm/translate.c b/target/arm/translate.c
392
index XXXXXXX..XXXXXXX 100644
393
--- a/target/arm/translate.c
394
+++ b/target/arm/translate.c
395
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
396
*/
397
dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
398
!arm_el_is_aa64(env, 3);
399
- dc->thumb = FIELD_EX32(tb_flags, TBFLAG_AM32, THUMB);
400
- dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
401
- condexec = FIELD_EX32(tb_flags, TBFLAG_AM32, CONDEXEC);
402
+ dc->thumb = EX_TBFLAG_AM32(tb_flags, THUMB);
403
+ dc->be_data = EX_TBFLAG_ANY(tb_flags, BE_DATA) ? MO_BE : MO_LE;
404
+ condexec = EX_TBFLAG_AM32(tb_flags, CONDEXEC);
405
dc->condexec_mask = (condexec & 0xf) << 1;
406
dc->condexec_cond = condexec >> 4;
407
408
- core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
409
+ core_mmu_idx = EX_TBFLAG_ANY(tb_flags, MMUIDX);
410
dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
411
dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
412
#if !defined(CONFIG_USER_ONLY)
413
dc->user = (dc->current_el == 0);
414
#endif
415
- dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
416
+ dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
417
418
if (arm_feature(env, ARM_FEATURE_M)) {
419
dc->vfp_enabled = 1;
420
dc->be_data = MO_TE;
421
- dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_M32, HANDLER);
422
+ dc->v7m_handler_mode = EX_TBFLAG_M32(tb_flags, HANDLER);
423
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
424
regime_is_secure(env, dc->mmu_idx);
425
- dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_M32, STACKCHECK);
426
- dc->v8m_fpccr_s_wrong =
427
- FIELD_EX32(tb_flags, TBFLAG_M32, FPCCR_S_WRONG);
428
+ dc->v8m_stackcheck = EX_TBFLAG_M32(tb_flags, STACKCHECK);
429
+ dc->v8m_fpccr_s_wrong = EX_TBFLAG_M32(tb_flags, FPCCR_S_WRONG);
430
dc->v7m_new_fp_ctxt_needed =
431
- FIELD_EX32(tb_flags, TBFLAG_M32, NEW_FP_CTXT_NEEDED);
432
- dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_M32, LSPACT);
433
+ EX_TBFLAG_M32(tb_flags, NEW_FP_CTXT_NEEDED);
434
+ dc->v7m_lspact = EX_TBFLAG_M32(tb_flags, LSPACT);
435
} else {
436
- dc->be_data =
437
- FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
438
- dc->debug_target_el =
439
- FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
440
- dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR__B);
441
- dc->hstr_active = FIELD_EX32(tb_flags, TBFLAG_A32, HSTR_ACTIVE);
442
- dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
443
- dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
444
+ dc->debug_target_el = EX_TBFLAG_ANY(tb_flags, DEBUG_TARGET_EL);
445
+ dc->sctlr_b = EX_TBFLAG_A32(tb_flags, SCTLR__B);
446
+ dc->hstr_active = EX_TBFLAG_A32(tb_flags, HSTR_ACTIVE);
447
+ dc->ns = EX_TBFLAG_A32(tb_flags, NS);
448
+ dc->vfp_enabled = EX_TBFLAG_A32(tb_flags, VFPEN);
449
if (arm_feature(env, ARM_FEATURE_XSCALE)) {
450
- dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
451
+ dc->c15_cpar = EX_TBFLAG_A32(tb_flags, XSCALE_CPAR);
452
} else {
453
- dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
454
- dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
455
+ dc->vec_len = EX_TBFLAG_A32(tb_flags, VECLEN);
456
+ dc->vec_stride = EX_TBFLAG_A32(tb_flags, VECSTRIDE);
457
}
458
}
459
dc->cp_regs = cpu->cp_regs;
460
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
461
* emit code to generate a software step exception
462
* end the TB
463
*/
464
- dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
465
- dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE__SS);
466
+ dc->ss_active = EX_TBFLAG_ANY(tb_flags, SS_ACTIVE);
467
+ dc->pstate_ss = EX_TBFLAG_ANY(tb_flags, PSTATE__SS);
468
dc->is_ldex = false;
469
470
dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
471
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
472
DisasContext dc = { };
473
const TranslatorOps *ops = &arm_translator_ops;
474
475
- if (FIELD_EX32(tb->flags, TBFLAG_AM32, THUMB)) {
476
+ if (EX_TBFLAG_AM32(tb->flags, THUMB)) {
477
ops = &thumb_translator_ops;
478
}
479
#ifdef TARGET_AARCH64
480
- if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
481
+ if (EX_TBFLAG_ANY(tb->flags, AARCH64_STATE)) {
482
ops = &aarch64_translator_ops;
483
}
484
#endif
74
--
485
--
75
2.20.1
486
2.20.1
76
487
77
488
diff view generated by jsdifflib
1
The M-profile architecture floating point system supports
1
From: Richard Henderson <richard.henderson@linaro.org>
2
lazy FP state preservation, where FP registers are not
2
3
pushed to the stack when an exception occurs but are instead
3
In preparation for splitting tb->flags across multiple
4
only saved if and when the first FP instruction in the exception
4
fields, introduce a structure to hold the value(s).
5
handler is executed. Implement this in QEMU, corresponding
5
So far this only migrates the one uint32_t and fixes
6
to the check of LSPACT in the pseudocode ExecuteFPCheck().
6
all of the places that require adjustment to match.
7
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210419202257.161730-6-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
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
---
12
target/arm/cpu.h | 3 ++
13
target/arm/cpu.h | 26 ++++++++++++---------
13
target/arm/helper.h | 2 +
14
target/arm/translate.h | 11 +++++++++
14
target/arm/translate.h | 1 +
15
target/arm/helper.c | 48 +++++++++++++++++++++-----------------
15
target/arm/helper.c | 112 +++++++++++++++++++++++++++++++++++++++++
16
target/arm/translate-a64.c | 2 +-
16
target/arm/translate.c | 22 ++++++++
17
target/arm/translate.c | 7 +++---
17
5 files changed, 140 insertions(+)
18
5 files changed, 57 insertions(+), 37 deletions(-)
18
19
19
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
20
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
22
--- a/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
23
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ typedef struct ARMPACKey {
24
#define EXCP_NOCP 17 /* v7M NOCP UsageFault */
25
} ARMPACKey;
25
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
26
#endif
26
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
27
27
+#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
28
+/* See the commentary above the TBFLAG field definitions. */
28
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
29
+typedef struct CPUARMTBFlags {
29
30
+ uint32_t flags;
30
#define ARMV7M_EXCP_RESET 1
31
+} CPUARMTBFlags;
31
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
32
32
FIELD(TBFLAG_A32, VFPEN, 7, 1)
33
typedef struct CPUARMState {
33
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
34
/* Regs for current mode. */
34
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
35
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
35
+/* For M profile only, set if FPCCR.LSPACT is set */
36
uint32_t aarch64; /* 1 if CPU is in aarch64 state; inverse of PSTATE.nRW */
36
+FIELD(TBFLAG_A32, LSPACT, 18, 1)
37
37
/* For M profile only, set if we must create a new FP context */
38
/* Cached TBFLAGS state. See below for which bits are included. */
38
FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
39
- uint32_t hflags;
39
/* For M profile only, set if FPCCR.S does not match current security state */
40
+ CPUARMTBFlags hflags;
40
diff --git a/target/arm/helper.h b/target/arm/helper.h
41
41
index XXXXXXX..XXXXXXX 100644
42
/* Frequently accessed CPSR bits are stored separately for efficiency.
42
--- a/target/arm/helper.h
43
This contains all the other bits. Use cpsr_{read,write} to access
43
+++ b/target/arm/helper.h
44
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, MTE0_ACTIVE, 19, 1)
44
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(v7m_blxns, void, env, i32)
45
* Helpers for using the above.
45
46
*/
46
DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
47
#define DP_TBFLAG_ANY(DST, WHICH, VAL) \
47
48
- (DST = FIELD_DP32(DST, TBFLAG_ANY, WHICH, VAL))
48
+DEF_HELPER_1(v7m_preserve_fp_state, void, env)
49
+ (DST.flags = FIELD_DP32(DST.flags, TBFLAG_ANY, WHICH, VAL))
49
+
50
#define DP_TBFLAG_A64(DST, WHICH, VAL) \
50
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
51
- (DST = FIELD_DP32(DST, TBFLAG_A64, WHICH, VAL))
51
52
+ (DST.flags = FIELD_DP32(DST.flags, TBFLAG_A64, WHICH, VAL))
52
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
53
#define DP_TBFLAG_A32(DST, WHICH, VAL) \
54
- (DST = FIELD_DP32(DST, TBFLAG_A32, WHICH, VAL))
55
+ (DST.flags = FIELD_DP32(DST.flags, TBFLAG_A32, WHICH, VAL))
56
#define DP_TBFLAG_M32(DST, WHICH, VAL) \
57
- (DST = FIELD_DP32(DST, TBFLAG_M32, WHICH, VAL))
58
+ (DST.flags = FIELD_DP32(DST.flags, TBFLAG_M32, WHICH, VAL))
59
#define DP_TBFLAG_AM32(DST, WHICH, VAL) \
60
- (DST = FIELD_DP32(DST, TBFLAG_AM32, WHICH, VAL))
61
+ (DST.flags = FIELD_DP32(DST.flags, TBFLAG_AM32, WHICH, VAL))
62
63
-#define EX_TBFLAG_ANY(IN, WHICH) FIELD_EX32(IN, TBFLAG_ANY, WHICH)
64
-#define EX_TBFLAG_A64(IN, WHICH) FIELD_EX32(IN, TBFLAG_A64, WHICH)
65
-#define EX_TBFLAG_A32(IN, WHICH) FIELD_EX32(IN, TBFLAG_A32, WHICH)
66
-#define EX_TBFLAG_M32(IN, WHICH) FIELD_EX32(IN, TBFLAG_M32, WHICH)
67
-#define EX_TBFLAG_AM32(IN, WHICH) FIELD_EX32(IN, TBFLAG_AM32, WHICH)
68
+#define EX_TBFLAG_ANY(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_ANY, WHICH)
69
+#define EX_TBFLAG_A64(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_A64, WHICH)
70
+#define EX_TBFLAG_A32(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_A32, WHICH)
71
+#define EX_TBFLAG_M32(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_M32, WHICH)
72
+#define EX_TBFLAG_AM32(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_AM32, WHICH)
73
74
/**
75
* cpu_mmu_index:
53
diff --git a/target/arm/translate.h b/target/arm/translate.h
76
diff --git a/target/arm/translate.h b/target/arm/translate.h
54
index XXXXXXX..XXXXXXX 100644
77
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/translate.h
78
--- a/target/arm/translate.h
56
+++ b/target/arm/translate.h
79
+++ b/target/arm/translate.h
57
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
80
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
58
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
81
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
59
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
82
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
60
bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
83
61
+ bool v7m_lspact; /* FPCCR.LSPACT set */
84
+/**
62
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
85
+ * arm_tbflags_from_tb:
63
* so that top level loop can generate correct syndrome information.
86
+ * @tb: the TranslationBlock
64
*/
87
+ *
88
+ * Extract the flag values from @tb.
89
+ */
90
+static inline CPUARMTBFlags arm_tbflags_from_tb(const TranslationBlock *tb)
91
+{
92
+ return (CPUARMTBFlags){ tb->flags };
93
+}
94
+
95
/*
96
* Enum for argument to fpstatus_ptr().
97
*/
65
diff --git a/target/arm/helper.c b/target/arm/helper.c
98
diff --git a/target/arm/helper.c b/target/arm/helper.c
66
index XXXXXXX..XXXXXXX 100644
99
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/helper.c
100
--- a/target/arm/helper.c
68
+++ b/target/arm/helper.c
101
+++ b/target/arm/helper.c
69
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
102
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
70
g_assert_not_reached();
103
}
71
}
104
#endif
72
105
73
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
106
-static uint32_t rebuild_hflags_common(CPUARMState *env, int fp_el,
74
+{
107
- ARMMMUIdx mmu_idx, uint32_t flags)
75
+ /* translate.c should never generate calls here in user-only mode */
108
+static CPUARMTBFlags rebuild_hflags_common(CPUARMState *env, int fp_el,
76
+ g_assert_not_reached();
109
+ ARMMMUIdx mmu_idx,
77
+}
110
+ CPUARMTBFlags flags)
111
{
112
DP_TBFLAG_ANY(flags, FPEXC_EL, fp_el);
113
DP_TBFLAG_ANY(flags, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
114
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_common(CPUARMState *env, int fp_el,
115
return flags;
116
}
117
118
-static uint32_t rebuild_hflags_common_32(CPUARMState *env, int fp_el,
119
- ARMMMUIdx mmu_idx, uint32_t flags)
120
+static CPUARMTBFlags rebuild_hflags_common_32(CPUARMState *env, int fp_el,
121
+ ARMMMUIdx mmu_idx,
122
+ CPUARMTBFlags flags)
123
{
124
bool sctlr_b = arm_sctlr_b(env);
125
126
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_common_32(CPUARMState *env, int fp_el,
127
return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
128
}
129
130
-static uint32_t rebuild_hflags_m32(CPUARMState *env, int fp_el,
131
- ARMMMUIdx mmu_idx)
132
+static CPUARMTBFlags rebuild_hflags_m32(CPUARMState *env, int fp_el,
133
+ ARMMMUIdx mmu_idx)
134
{
135
- uint32_t flags = 0;
136
+ CPUARMTBFlags flags = {};
137
138
if (arm_v7m_is_handler_mode(env)) {
139
DP_TBFLAG_M32(flags, HANDLER, 1);
140
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_m32(CPUARMState *env, int fp_el,
141
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
142
}
143
144
-static uint32_t rebuild_hflags_aprofile(CPUARMState *env)
145
+static CPUARMTBFlags rebuild_hflags_aprofile(CPUARMState *env)
146
{
147
- int flags = 0;
148
+ CPUARMTBFlags flags = {};
149
150
DP_TBFLAG_ANY(flags, DEBUG_TARGET_EL, arm_debug_target_el(env));
151
return flags;
152
}
153
154
-static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
155
- ARMMMUIdx mmu_idx)
156
+static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el,
157
+ ARMMMUIdx mmu_idx)
158
{
159
- uint32_t flags = rebuild_hflags_aprofile(env);
160
+ CPUARMTBFlags flags = rebuild_hflags_aprofile(env);
161
162
if (arm_el_is_aa64(env, 1)) {
163
DP_TBFLAG_A32(flags, VFPEN, 1);
164
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
165
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
166
}
167
168
-static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
169
- ARMMMUIdx mmu_idx)
170
+static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
171
+ ARMMMUIdx mmu_idx)
172
{
173
- uint32_t flags = rebuild_hflags_aprofile(env);
174
+ CPUARMTBFlags flags = rebuild_hflags_aprofile(env);
175
ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
176
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
177
uint64_t sctlr;
178
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
179
return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
180
}
181
182
-static uint32_t rebuild_hflags_internal(CPUARMState *env)
183
+static CPUARMTBFlags rebuild_hflags_internal(CPUARMState *env)
184
{
185
int el = arm_current_el(env);
186
int fp_el = fp_exception_el(env, el);
187
@@ -XXX,XX +XXX,XX @@ void HELPER(rebuild_hflags_m32_newel)(CPUARMState *env)
188
int el = arm_current_el(env);
189
int fp_el = fp_exception_el(env, el);
190
ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
78
+
191
+
79
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
192
env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
80
{
193
}
81
/* The TT instructions can be used by unprivileged code, but in
194
82
@@ -XXX,XX +XXX,XX @@ pend_fault:
195
@@ -XXX,XX +XXX,XX @@ void HELPER(rebuild_hflags_a64)(CPUARMState *env, int el)
83
return false;
196
static inline void assert_hflags_rebuild_correctly(CPUARMState *env)
84
}
197
{
85
198
#ifdef CONFIG_DEBUG_TCG
86
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
199
- uint32_t env_flags_current = env->hflags;
87
+{
200
- uint32_t env_flags_rebuilt = rebuild_hflags_internal(env);
88
+ /*
201
+ CPUARMTBFlags c = env->hflags;
89
+ * Preserve FP state (because LSPACT was set and we are about
202
+ CPUARMTBFlags r = rebuild_hflags_internal(env);
90
+ * to execute an FP instruction). This corresponds to the
203
91
+ * PreserveFPState() pseudocode.
204
- if (unlikely(env_flags_current != env_flags_rebuilt)) {
92
+ * We may throw an exception if the stacking fails.
205
+ if (unlikely(c.flags != r.flags)) {
93
+ */
206
fprintf(stderr, "TCG hflags mismatch (current:0x%08x rebuilt:0x%08x)\n",
94
+ ARMCPU *cpu = arm_env_get_cpu(env);
207
- env_flags_current, env_flags_rebuilt);
95
+ bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
208
+ c.flags, r.flags);
96
+ bool negpri = !(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_HFRDY_MASK);
209
abort();
97
+ bool is_priv = !(env->v7m.fpccr[is_secure] & R_V7M_FPCCR_USER_MASK);
210
}
98
+ bool splimviol = env->v7m.fpccr[is_secure] & R_V7M_FPCCR_SPLIMVIOL_MASK;
211
#endif
99
+ uint32_t fpcar = env->v7m.fpcar[is_secure];
212
@@ -XXX,XX +XXX,XX @@ static inline void assert_hflags_rebuild_correctly(CPUARMState *env)
100
+ bool stacked_ok = true;
213
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
101
+ bool ts = is_secure && (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
214
target_ulong *cs_base, uint32_t *pflags)
102
+ bool take_exception;
215
{
103
+
216
- uint32_t flags = env->hflags;
104
+ /* Take the iothread lock as we are going to touch the NVIC */
217
+ CPUARMTBFlags flags;
105
+ qemu_mutex_lock_iothread();
218
106
+
219
*cs_base = 0;
107
+ /* Check the background context had access to the FPU */
220
assert_hflags_rebuild_correctly(env);
108
+ if (!v7m_cpacr_pass(env, is_secure, is_priv)) {
221
+ flags = env->hflags;
109
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, is_secure);
222
110
+ env->v7m.cfsr[is_secure] |= R_V7M_CFSR_NOCP_MASK;
223
if (EX_TBFLAG_ANY(flags, AARCH64_STATE)) {
111
+ stacked_ok = false;
224
*pc = env->pc;
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,
225
@@ -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);
226
DP_TBFLAG_ANY(flags, PSTATE__SS, 1);
203
}
227
}
204
228
205
+ if (arm_feature(env, ARM_FEATURE_M)) {
229
- *pflags = flags;
206
+ bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
230
+ *pflags = flags.flags;
207
+
231
}
208
+ if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) {
232
209
+ flags = FIELD_DP32(flags, TBFLAG_A32, LSPACT, 1);
233
#ifdef TARGET_AARCH64
210
+ }
234
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
211
+ }
235
index XXXXXXX..XXXXXXX 100644
212
+
236
--- a/target/arm/translate-a64.c
213
*pflags = flags;
237
+++ b/target/arm/translate-a64.c
214
*cs_base = 0;
238
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
215
}
239
DisasContext *dc = container_of(dcbase, DisasContext, base);
240
CPUARMState *env = cpu->env_ptr;
241
ARMCPU *arm_cpu = env_archcpu(env);
242
- uint32_t tb_flags = dc->base.tb->flags;
243
+ CPUARMTBFlags tb_flags = arm_tbflags_from_tb(dc->base.tb);
244
int bound, core_mmu_idx;
245
246
dc->isar = &arm_cpu->isar;
216
diff --git a/target/arm/translate.c b/target/arm/translate.c
247
diff --git a/target/arm/translate.c b/target/arm/translate.c
217
index XXXXXXX..XXXXXXX 100644
248
index XXXXXXX..XXXXXXX 100644
218
--- a/target/arm/translate.c
249
--- a/target/arm/translate.c
219
+++ b/target/arm/translate.c
250
+++ 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)
251
@@ -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);
252
DisasContext *dc = container_of(dcbase, DisasContext, base);
250
dc->v7m_new_fp_ctxt_needed =
253
CPUARMState *env = cs->env_ptr;
251
FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
254
ARMCPU *cpu = env_archcpu(env);
252
+ dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_A32, LSPACT);
255
- uint32_t tb_flags = dc->base.tb->flags;
253
dc->cp_regs = cpu->cp_regs;
256
+ CPUARMTBFlags tb_flags = arm_tbflags_from_tb(dc->base.tb);
254
dc->features = env->features;
257
uint32_t condexec, core_mmu_idx;
255
258
259
dc->isar = &cpu->isar;
260
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
261
{
262
DisasContext dc = { };
263
const TranslatorOps *ops = &arm_translator_ops;
264
+ CPUARMTBFlags tb_flags = arm_tbflags_from_tb(tb);
265
266
- if (EX_TBFLAG_AM32(tb->flags, THUMB)) {
267
+ if (EX_TBFLAG_AM32(tb_flags, THUMB)) {
268
ops = &thumb_translator_ops;
269
}
270
#ifdef TARGET_AARCH64
271
- if (EX_TBFLAG_ANY(tb->flags, AARCH64_STATE)) {
272
+ if (EX_TBFLAG_ANY(tb_flags, AARCH64_STATE)) {
273
ops = &aarch64_translator_ops;
274
}
275
#endif
256
--
276
--
257
2.20.1
277
2.20.1
258
278
259
279
diff view generated by jsdifflib
1
Implement the code which updates the FPCCR register on an
1
From: Richard Henderson <richard.henderson@linaro.org>
2
exception entry where we are going to use lazy FP stacking.
3
We have to defer to the NVIC to determine whether the
4
various exceptions are currently ready or not.
5
2
3
Now that we have all of the proper macros defined, expanding
4
the CPUARMTBFlags structure and populating the two TB fields
5
is relatively simple.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210419202257.161730-7-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20190416125744.27770-12-peter.maydell@linaro.org
8
---
11
---
9
target/arm/cpu.h | 14 +++++++++
12
target/arm/cpu.h | 49 ++++++++++++++++++++++++------------------
10
hw/intc/armv7m_nvic.c | 34 ++++++++++++++++++++++
13
target/arm/translate.h | 2 +-
11
target/arm/helper.c | 67 ++++++++++++++++++++++++++++++++++++++++++-
14
target/arm/helper.c | 10 +++++----
12
3 files changed, 114 insertions(+), 1 deletion(-)
15
3 files changed, 35 insertions(+), 26 deletions(-)
13
16
14
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
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
19
--- a/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_acknowledge_irq(void *opaque);
21
@@ -XXX,XX +XXX,XX @@ typedef struct ARMPACKey {
19
* (Ignoring -1, this is the same as the RETTOBASE value before completion.)
22
/* See the commentary above the TBFLAG field definitions. */
23
typedef struct CPUARMTBFlags {
24
uint32_t flags;
25
+ target_ulong flags2;
26
} CPUARMTBFlags;
27
28
typedef struct CPUARMState {
29
@@ -XXX,XX +XXX,XX @@ typedef ARMCPU ArchCPU;
30
#include "exec/cpu-all.h"
31
32
/*
33
- * Bit usage in the TB flags field: bit 31 indicates whether we are
34
- * in 32 or 64 bit mode. The meaning of the other bits depends on that.
35
- * We put flags which are shared between 32 and 64 bit mode at the top
36
- * of the word, and flags which apply to only one mode at the bottom.
37
+ * We have more than 32-bits worth of state per TB, so we split the data
38
+ * between tb->flags and tb->cs_base, which is otherwise unused for ARM.
39
+ * We collect these two parts in CPUARMTBFlags where they are named
40
+ * flags and flags2 respectively.
41
*
42
- * 31 20 18 14 9 0
43
- * +--------------+-----+-----+----------+--------------+
44
- * | | | TBFLAG_A32 | |
45
- * | | +-----+----------+ TBFLAG_AM32 |
46
- * | TBFLAG_ANY | |TBFLAG_M32| |
47
- * | +-----------+----------+--------------|
48
- * | | TBFLAG_A64 |
49
- * +--------------+-------------------------------------+
50
- * 31 20 0
51
+ * The flags that are shared between all execution modes, TBFLAG_ANY,
52
+ * are stored in flags. The flags that are specific to a given mode
53
+ * are stores in flags2. Since cs_base is sized on the configured
54
+ * address size, flags2 always has 64-bits for A64, and a minimum of
55
+ * 32-bits for A32 and M32.
56
+ *
57
+ * The bits for 32-bit A-profile and M-profile partially overlap:
58
+ *
59
+ * 18 9 0
60
+ * +----------------+--------------+
61
+ * | TBFLAG_A32 | |
62
+ * +-----+----------+ TBFLAG_AM32 |
63
+ * | |TBFLAG_M32| |
64
+ * +-----+----------+--------------+
65
+ * 14 9 0
66
*
67
* Unless otherwise noted, these bits are cached in env->hflags.
20
*/
68
*/
21
int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure);
69
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, MTE0_ACTIVE, 19, 1)
22
+/**
70
#define DP_TBFLAG_ANY(DST, WHICH, VAL) \
23
+ * armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
71
(DST.flags = FIELD_DP32(DST.flags, TBFLAG_ANY, WHICH, VAL))
24
+ * @opaque: the NVIC
72
#define DP_TBFLAG_A64(DST, WHICH, VAL) \
25
+ * @irq: the exception number to mark pending
73
- (DST.flags = FIELD_DP32(DST.flags, TBFLAG_A64, WHICH, VAL))
26
+ * @secure: false for non-banked exceptions or for the nonsecure
74
+ (DST.flags2 = FIELD_DP32(DST.flags2, TBFLAG_A64, WHICH, VAL))
27
+ * version of a banked exception, true for the secure version of a banked
75
#define DP_TBFLAG_A32(DST, WHICH, VAL) \
28
+ * exception.
76
- (DST.flags = FIELD_DP32(DST.flags, TBFLAG_A32, WHICH, VAL))
29
+ *
77
+ (DST.flags2 = FIELD_DP32(DST.flags2, TBFLAG_A32, WHICH, VAL))
30
+ * Return whether an exception is "ready", i.e. whether the exception is
78
#define DP_TBFLAG_M32(DST, WHICH, VAL) \
31
+ * enabled and is configured at a priority which would allow it to
79
- (DST.flags = FIELD_DP32(DST.flags, TBFLAG_M32, WHICH, VAL))
32
+ * interrupt the current execution priority. This controls whether the
80
+ (DST.flags2 = FIELD_DP32(DST.flags2, TBFLAG_M32, WHICH, VAL))
33
+ * RDY bit for it in the FPCCR is set.
81
#define DP_TBFLAG_AM32(DST, WHICH, VAL) \
34
+ */
82
- (DST.flags = FIELD_DP32(DST.flags, TBFLAG_AM32, WHICH, VAL))
35
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure);
83
+ (DST.flags2 = FIELD_DP32(DST.flags2, TBFLAG_AM32, WHICH, VAL))
84
85
#define EX_TBFLAG_ANY(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_ANY, WHICH)
86
-#define EX_TBFLAG_A64(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_A64, WHICH)
87
-#define EX_TBFLAG_A32(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_A32, WHICH)
88
-#define EX_TBFLAG_M32(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_M32, WHICH)
89
-#define EX_TBFLAG_AM32(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_AM32, WHICH)
90
+#define EX_TBFLAG_A64(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_A64, WHICH)
91
+#define EX_TBFLAG_A32(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_A32, WHICH)
92
+#define EX_TBFLAG_M32(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_M32, WHICH)
93
+#define EX_TBFLAG_AM32(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_AM32, WHICH)
94
36
/**
95
/**
37
* armv7m_nvic_raw_execution_priority: return the raw execution priority
96
* cpu_mmu_index:
38
* @opaque: the NVIC
97
diff --git a/target/arm/translate.h b/target/arm/translate.h
39
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
40
index XXXXXXX..XXXXXXX 100644
98
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/intc/armv7m_nvic.c
99
--- a/target/arm/translate.h
42
+++ b/hw/intc/armv7m_nvic.c
100
+++ b/target/arm/translate.h
43
@@ -XXX,XX +XXX,XX @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
101
@@ -XXX,XX +XXX,XX @@ typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
44
return ret;
102
*/
103
static inline CPUARMTBFlags arm_tbflags_from_tb(const TranslationBlock *tb)
104
{
105
- return (CPUARMTBFlags){ tb->flags };
106
+ return (CPUARMTBFlags){ tb->flags, tb->cs_base };
45
}
107
}
46
108
47
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
109
/*
48
+{
49
+ /*
50
+ * Return whether an exception is "ready", i.e. it is enabled and is
51
+ * configured at a priority which would allow it to interrupt the
52
+ * current execution priority.
53
+ *
54
+ * irq and secure have the same semantics as for armv7m_nvic_set_pending():
55
+ * for non-banked exceptions secure is always false; for banked exceptions
56
+ * it indicates which of the exceptions is required.
57
+ */
58
+ NVICState *s = (NVICState *)opaque;
59
+ bool banked = exc_is_banked(irq);
60
+ VecInfo *vec;
61
+ int running = nvic_exec_prio(s);
62
+
63
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
64
+ assert(!secure || banked);
65
+
66
+ /*
67
+ * HardFault is an odd special case: we always check against -1,
68
+ * even if we're secure and HardFault has priority -3; we never
69
+ * need to check for enabled state.
70
+ */
71
+ if (irq == ARMV7M_EXCP_HARD) {
72
+ return running > -1;
73
+ }
74
+
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
76
+
77
+ return vec->enabled &&
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
110
diff --git a/target/arm/helper.c b/target/arm/helper.c
85
index XXXXXXX..XXXXXXX 100644
111
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/helper.c
112
--- a/target/arm/helper.c
87
+++ b/target/arm/helper.c
113
+++ b/target/arm/helper.c
88
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
114
@@ -XXX,XX +XXX,XX @@ static inline void assert_hflags_rebuild_correctly(CPUARMState *env)
89
env->thumb = addr & 1;
115
CPUARMTBFlags c = env->hflags;
116
CPUARMTBFlags r = rebuild_hflags_internal(env);
117
118
- if (unlikely(c.flags != r.flags)) {
119
- fprintf(stderr, "TCG hflags mismatch (current:0x%08x rebuilt:0x%08x)\n",
120
- c.flags, r.flags);
121
+ if (unlikely(c.flags != r.flags || c.flags2 != r.flags2)) {
122
+ fprintf(stderr, "TCG hflags mismatch "
123
+ "(current:(0x%08x,0x" TARGET_FMT_lx ")"
124
+ " rebuilt:(0x%08x,0x" TARGET_FMT_lx ")\n",
125
+ c.flags, c.flags2, r.flags, r.flags2);
126
abort();
127
}
128
#endif
129
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
130
{
131
CPUARMTBFlags flags;
132
133
- *cs_base = 0;
134
assert_hflags_rebuild_correctly(env);
135
flags = env->hflags;
136
137
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
138
}
139
140
*pflags = flags.flags;
141
+ *cs_base = flags.flags2;
90
}
142
}
91
143
92
+static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
144
#ifdef TARGET_AARCH64
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
}
169
--
145
--
170
2.20.1
146
2.20.1
171
147
172
148
diff view generated by jsdifflib
1
In the v7M architecture, if an exception is generated in the process
1
From: Richard Henderson <richard.henderson@linaro.org>
2
of doing the lazy stacking of FP registers, the handling of
3
possible escalation to HardFault is treated differently to the normal
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
2
10
This corresponds to the pseudocode TakePreserveFPException().
3
Now that these bits have been moved out of tb->flags,
4
where TBFLAG_ANY was filling from the top, move AM32
5
to fill from the top, and A32 and M32 to fill from the
6
bottom. This means fewer changes when adding new bits.
11
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210419202257.161730-9-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190416125744.27770-22-peter.maydell@linaro.org
15
---
12
---
16
target/arm/cpu.h | 12 ++++++
13
target/arm/cpu.h | 42 +++++++++++++++++++++---------------------
17
hw/intc/armv7m_nvic.c | 96 +++++++++++++++++++++++++++++++++++++++++++
14
1 file changed, 21 insertions(+), 21 deletions(-)
18
2 files changed, 108 insertions(+)
19
15
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
18
--- a/target/arm/cpu.h
23
+++ b/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
24
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
20
@@ -XXX,XX +XXX,XX @@ typedef ARMCPU ArchCPU;
25
* a different exception).
21
*
22
* The bits for 32-bit A-profile and M-profile partially overlap:
23
*
24
- * 18 9 0
25
- * +----------------+--------------+
26
- * | TBFLAG_A32 | |
27
- * +-----+----------+ TBFLAG_AM32 |
28
- * | |TBFLAG_M32| |
29
- * +-----+----------+--------------+
30
- * 14 9 0
31
+ * 31 23 11 10 0
32
+ * +-------------+----------+----------------+
33
+ * | | | TBFLAG_A32 |
34
+ * | TBFLAG_AM32 | +-----+----------+
35
+ * | | |TBFLAG_M32|
36
+ * +-------------+----------------+----------+
37
+ * 31 23 5 4 0
38
*
39
* Unless otherwise noted, these bits are cached in env->hflags.
26
*/
40
*/
27
void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
41
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, DEBUG_TARGET_EL, 20, 2)
28
+/**
42
/*
29
+ * armv7m_nvic_set_pending_lazyfp: mark this lazy FP exception as pending
43
* Bit usage when in AArch32 state, both A- and M-profile.
30
+ * @opaque: the NVIC
44
*/
31
+ * @irq: the exception number to mark pending
45
-FIELD(TBFLAG_AM32, CONDEXEC, 0, 8) /* Not cached. */
32
+ * @secure: false for non-banked exceptions or for the nonsecure
46
-FIELD(TBFLAG_AM32, THUMB, 8, 1) /* Not cached. */
33
+ * version of a banked exception, true for the secure version of a banked
47
+FIELD(TBFLAG_AM32, CONDEXEC, 24, 8) /* Not cached. */
34
+ * exception.
48
+FIELD(TBFLAG_AM32, THUMB, 23, 1) /* Not cached. */
35
+ *
49
36
+ * Similar to armv7m_nvic_set_pending(), but specifically for exceptions
50
/*
37
+ * generated in the course of lazy stacking of FP registers.
51
* Bit usage when in AArch32 state, for A-profile only.
38
+ */
52
*/
39
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure);
53
-FIELD(TBFLAG_A32, VECLEN, 9, 3) /* Not cached. */
40
/**
54
-FIELD(TBFLAG_A32, VECSTRIDE, 12, 2) /* Not cached. */
41
* armv7m_nvic_get_pending_irq_info: return highest priority pending
55
+FIELD(TBFLAG_A32, VECLEN, 0, 3) /* Not cached. */
42
* exception, and whether it targets Secure state
56
+FIELD(TBFLAG_A32, VECSTRIDE, 3, 2) /* Not cached. */
43
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
57
/*
44
index XXXXXXX..XXXXXXX 100644
58
* We store the bottom two bits of the CPAR as TB flags and handle
45
--- a/hw/intc/armv7m_nvic.c
59
* checks on the other bits at runtime. This shares the same bits as
46
+++ b/hw/intc/armv7m_nvic.c
60
* VECSTRIDE, which is OK as no XScale CPU has VFP.
47
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
61
* Not cached, because VECLEN+VECSTRIDE are not cached.
48
do_armv7m_nvic_set_pending(opaque, irq, secure, true);
62
*/
49
}
63
-FIELD(TBFLAG_A32, XSCALE_CPAR, 12, 2)
50
64
-FIELD(TBFLAG_A32, VFPEN, 14, 1) /* Partially cached, minus FPEXC. */
51
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
65
-FIELD(TBFLAG_A32, SCTLR__B, 15, 1) /* Cannot overlap with SCTLR_B */
52
+{
66
-FIELD(TBFLAG_A32, HSTR_ACTIVE, 16, 1)
53
+ /*
67
+FIELD(TBFLAG_A32, XSCALE_CPAR, 5, 2)
54
+ * Pend an exception during lazy FP stacking. This differs
68
+FIELD(TBFLAG_A32, VFPEN, 7, 1) /* Partially cached, minus FPEXC. */
55
+ * from the usual exception pending because the logic for
69
+FIELD(TBFLAG_A32, SCTLR__B, 8, 1) /* Cannot overlap with SCTLR_B */
56
+ * whether we should escalate depends on the saved context
70
+FIELD(TBFLAG_A32, HSTR_ACTIVE, 9, 1)
57
+ * in the FPCCR register, not on the current state of the CPU/NVIC.
71
/*
58
+ */
72
* Indicates whether cp register reads and writes by guest code should access
59
+ NVICState *s = (NVICState *)opaque;
73
* the secure or nonsecure bank of banked registers; note that this is not
60
+ bool banked = exc_is_banked(irq);
74
* the same thing as the current security state of the processor!
61
+ VecInfo *vec;
75
*/
62
+ bool targets_secure;
76
-FIELD(TBFLAG_A32, NS, 17, 1)
63
+ bool escalate = false;
77
+FIELD(TBFLAG_A32, NS, 10, 1)
64
+ /*
78
65
+ * We will only look at bits in fpccr if this is a banked exception
79
/*
66
+ * (in which case 'secure' tells us whether it is the S or NS version).
80
* Bit usage when in AArch32 state, for M-profile only.
67
+ * All the bits for the non-banked exceptions are in fpccr_s.
81
*/
68
+ */
82
/* Handler (ie not Thread) mode */
69
+ uint32_t fpccr_s = s->cpu->env.v7m.fpccr[M_REG_S];
83
-FIELD(TBFLAG_M32, HANDLER, 9, 1)
70
+ uint32_t fpccr = s->cpu->env.v7m.fpccr[secure];
84
+FIELD(TBFLAG_M32, HANDLER, 0, 1)
71
+
85
/* Whether we should generate stack-limit checks */
72
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
86
-FIELD(TBFLAG_M32, STACKCHECK, 10, 1)
73
+ assert(!secure || banked);
87
+FIELD(TBFLAG_M32, STACKCHECK, 1, 1)
74
+
88
/* Set if FPCCR.LSPACT is set */
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
89
-FIELD(TBFLAG_M32, LSPACT, 11, 1) /* Not cached. */
76
+
90
+FIELD(TBFLAG_M32, LSPACT, 2, 1) /* Not cached. */
77
+ targets_secure = banked ? secure : exc_targets_secure(s, irq);
91
/* Set if we must create a new FP context */
78
+
92
-FIELD(TBFLAG_M32, NEW_FP_CTXT_NEEDED, 12, 1) /* Not cached. */
79
+ switch (irq) {
93
+FIELD(TBFLAG_M32, NEW_FP_CTXT_NEEDED, 3, 1) /* Not cached. */
80
+ case ARMV7M_EXCP_DEBUG:
94
/* Set if FPCCR.S does not match current security state */
81
+ if (!(fpccr_s & R_V7M_FPCCR_MONRDY_MASK)) {
95
-FIELD(TBFLAG_M32, FPCCR_S_WRONG, 13, 1) /* Not cached. */
82
+ /* Ignore DebugMonitor exception */
96
+FIELD(TBFLAG_M32, FPCCR_S_WRONG, 4, 1) /* Not cached. */
83
+ return;
97
84
+ }
98
/*
85
+ break;
99
* Bit usage when in AArch64 state
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.
106
+ */
107
+ irq = ARMV7M_EXCP_HARD;
108
+ if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY) &&
109
+ (targets_secure ||
110
+ !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK))) {
111
+ vec = &s->sec_vectors[irq];
112
+ } else {
113
+ vec = &s->vectors[irq];
114
+ }
115
+ }
116
+
117
+ if (!vec->enabled ||
118
+ nvic_exec_prio(s) <= exc_group_prio(s, vec->prio, secure)) {
119
+ if (!(fpccr_s & R_V7M_FPCCR_HFRDY_MASK)) {
120
+ /*
121
+ * We want to escalate to HardFault but the context the
122
+ * FP state belongs to prevents the exception pre-empting.
123
+ */
124
+ cpu_abort(&s->cpu->parent_obj,
125
+ "Lockup: can't escalate to HardFault during "
126
+ "lazy FP register stacking\n");
127
+ }
128
+ }
129
+
130
+ if (escalate) {
131
+ s->cpu->env.v7m.hfsr |= R_V7M_HFSR_FORCED_MASK;
132
+ }
133
+ if (!vec->pending) {
134
+ vec->pending = 1;
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
{
150
--
100
--
151
2.20.1
101
2.20.1
152
102
153
103
diff view generated by jsdifflib
1
Move the NS TBFLAG down from bit 19 to bit 6, which has not
1
From: Richard Henderson <richard.henderson@linaro.org>
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.
5
2
6
This rearrangement is not strictly necessary, but means that
3
Now that other bits have been moved out of tb->flags,
7
we can put M-profile-only bits next to each other rather
4
there's no point in filling from the top.
8
than scattered across the flag word.
9
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210419202257.161730-10-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
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
---
10
---
14
target/arm/cpu.h | 11 ++++++-----
11
target/arm/cpu.h | 14 +++++++-------
15
1 file changed, 6 insertions(+), 5 deletions(-)
12
1 file changed, 7 insertions(+), 7 deletions(-)
16
13
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
16
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
18
@@ -XXX,XX +XXX,XX @@ typedef ARMCPU ArchCPU;
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
19
*
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
20
* Unless otherwise noted, these bits are cached in env->hflags.
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
*/
21
*/
37
FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
22
-FIELD(TBFLAG_ANY, AARCH64_STATE, 31, 1)
38
-/* Indicates whether cp register reads and writes by guest code should access
23
-FIELD(TBFLAG_ANY, SS_ACTIVE, 30, 1)
39
- * the secure or nonsecure bank of banked registers; note that this is not
24
-FIELD(TBFLAG_ANY, PSTATE__SS, 29, 1) /* Not cached. */
40
- * the same thing as the current security state of the processor!
25
-FIELD(TBFLAG_ANY, BE_DATA, 28, 1)
41
- */
26
-FIELD(TBFLAG_ANY, MMUIDX, 24, 4)
42
-FIELD(TBFLAG_A32, NS, 19, 1)
27
+FIELD(TBFLAG_ANY, AARCH64_STATE, 0, 1)
43
/* For M profile only, Handler (ie not Thread) mode */
28
+FIELD(TBFLAG_ANY, SS_ACTIVE, 1, 1)
44
FIELD(TBFLAG_A32, HANDLER, 21, 1)
29
+FIELD(TBFLAG_ANY, PSTATE__SS, 2, 1) /* Not cached. */
45
/* For M profile only, whether we should generate stack-limit checks */
30
+FIELD(TBFLAG_ANY, BE_DATA, 3, 1)
31
+FIELD(TBFLAG_ANY, MMUIDX, 4, 4)
32
/* Target EL if we take a floating-point-disabled exception */
33
-FIELD(TBFLAG_ANY, FPEXC_EL, 22, 2)
34
+FIELD(TBFLAG_ANY, FPEXC_EL, 8, 2)
35
/* For A-profile only, target EL for debug exceptions. */
36
-FIELD(TBFLAG_ANY, DEBUG_TARGET_EL, 20, 2)
37
+FIELD(TBFLAG_ANY, DEBUG_TARGET_EL, 10, 2)
38
39
/*
40
* Bit usage when in AArch32 state, both A- and M-profile.
46
--
41
--
47
2.20.1
42
2.20.1
48
43
49
44
diff view generated by jsdifflib
1
The M-profile FPCCR.S bit indicates the security status of
1
From: Richard Henderson <richard.henderson@linaro.org>
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.
6
2
7
Implement this by adding a new TB flag which tracks whether
3
Use this to signal when memory access alignment is required.
8
FPCCR.S is different from the current security state, so
4
This value comes from the CCR register for M-profile, and
9
that we only need to emit the code to update it in the
5
from the SCTLR register for A-profile.
10
less-common case when it is not already set correctly.
11
6
12
Note that we will add the handling for the other work done
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
by ExecuteFPCheck() in later commits.
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
9
Message-id: 20210419202257.161730-11-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
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
---
11
---
19
target/arm/cpu.h | 2 ++
12
target/arm/cpu.h | 2 ++
20
target/arm/translate.h | 1 +
13
target/arm/translate.h | 2 ++
21
target/arm/helper.c | 5 +++++
14
target/arm/helper.c | 19 +++++++++++++++++--
22
target/arm/translate.c | 20 ++++++++++++++++++++
15
target/arm/translate-a64.c | 1 +
23
4 files changed, 28 insertions(+)
16
target/arm/translate.c | 7 +++----
17
5 files changed, 25 insertions(+), 6 deletions(-)
24
18
25
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
26
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/cpu.h
21
--- a/target/arm/cpu.h
28
+++ b/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
29
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
23
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, MMUIDX, 4, 4)
30
FIELD(TBFLAG_A32, VFPEN, 7, 1)
24
FIELD(TBFLAG_ANY, FPEXC_EL, 8, 2)
31
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
25
/* For A-profile only, target EL for debug exceptions. */
32
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
26
FIELD(TBFLAG_ANY, DEBUG_TARGET_EL, 10, 2)
33
+/* For M profile only, set if FPCCR.S does not match current security state */
27
+/* Memory operations require alignment: SCTLR_ELx.A or CCR.UNALIGN_TRP */
34
+FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
28
+FIELD(TBFLAG_ANY, ALIGN_MEM, 12, 1)
35
/* For M profile only, Handler (ie not Thread) mode */
29
36
FIELD(TBFLAG_A32, HANDLER, 21, 1)
30
/*
37
/* For M profile only, whether we should generate stack-limit checks */
31
* Bit usage when in AArch32 state, both A- and M-profile.
38
diff --git a/target/arm/translate.h b/target/arm/translate.h
32
diff --git a/target/arm/translate.h b/target/arm/translate.h
39
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/translate.h
34
--- a/target/arm/translate.h
41
+++ b/target/arm/translate.h
35
+++ b/target/arm/translate.h
42
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
36
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
43
bool v7m_handler_mode;
37
bool bt;
44
bool v8m_secure; /* true if v8M and we're in Secure mode */
38
/* True if any CP15 access is trapped by HSTR_EL2 */
45
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
39
bool hstr_active;
46
+ bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
40
+ /* True if memory operations require alignment */
47
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
41
+ bool align_mem;
48
* so that top level loop can generate correct syndrome information.
42
/*
49
*/
43
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
44
* < 0, set by the current instruction.
50
diff --git a/target/arm/helper.c b/target/arm/helper.c
45
diff --git a/target/arm/helper.c b/target/arm/helper.c
51
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/helper.c
47
--- a/target/arm/helper.c
53
+++ b/target/arm/helper.c
48
+++ b/target/arm/helper.c
54
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
49
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_m32(CPUARMState *env, int fp_el,
55
flags = FIELD_DP32(flags, TBFLAG_A32, STACKCHECK, 1);
50
ARMMMUIdx mmu_idx)
51
{
52
CPUARMTBFlags flags = {};
53
+ uint32_t ccr = env->v7m.ccr[env->v7m.secure];
54
+
55
+ /* Without HaveMainExt, CCR.UNALIGN_TRP is RES1. */
56
+ if (ccr & R_V7M_CCR_UNALIGN_TRP_MASK) {
57
+ DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
58
+ }
59
60
if (arm_v7m_is_handler_mode(env)) {
61
DP_TBFLAG_M32(flags, HANDLER, 1);
62
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_m32(CPUARMState *env, int fp_el,
63
*/
64
if (arm_feature(env, ARM_FEATURE_V8) &&
65
!((mmu_idx & ARM_MMU_IDX_M_NEGPRI) &&
66
- (env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_STKOFHFNMIGN_MASK))) {
67
+ (ccr & R_V7M_CCR_STKOFHFNMIGN_MASK))) {
68
DP_TBFLAG_M32(flags, STACKCHECK, 1);
56
}
69
}
57
70
58
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
71
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el,
59
+ FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S) != env->v7m.secure) {
72
ARMMMUIdx mmu_idx)
60
+ flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
73
{
74
CPUARMTBFlags flags = rebuild_hflags_aprofile(env);
75
+ int el = arm_current_el(env);
76
+
77
+ if (arm_sctlr(env, el) & SCTLR_A) {
78
+ DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
79
+ }
80
81
if (arm_el_is_aa64(env, 1)) {
82
DP_TBFLAG_A32(flags, VFPEN, 1);
83
}
84
85
- if (arm_current_el(env) < 2 && env->cp15.hstr_el2 &&
86
+ if (el < 2 && env->cp15.hstr_el2 &&
87
(arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
88
DP_TBFLAG_A32(flags, HSTR_ACTIVE, 1);
89
}
90
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
91
92
sctlr = regime_sctlr(env, stage1);
93
94
+ if (sctlr & SCTLR_A) {
95
+ DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
61
+ }
96
+ }
62
+
97
+
63
*pflags = flags;
98
if (arm_cpu_data_is_big_endian_a64(el, sctlr)) {
64
*cs_base = 0;
99
DP_TBFLAG_ANY(flags, BE_DATA, 1);
65
}
100
}
101
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
102
index XXXXXXX..XXXXXXX 100644
103
--- a/target/arm/translate-a64.c
104
+++ b/target/arm/translate-a64.c
105
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
106
dc->user = (dc->current_el == 0);
107
#endif
108
dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
109
+ dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
110
dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
111
dc->sve_len = (EX_TBFLAG_A64(tb_flags, ZCR_LEN) + 1) * 16;
112
dc->pauth_active = EX_TBFLAG_A64(tb_flags, PAUTH_ACTIVE);
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
113
diff --git a/target/arm/translate.c b/target/arm/translate.c
67
index XXXXXXX..XXXXXXX 100644
114
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate.c
115
--- a/target/arm/translate.c
69
+++ b/target/arm/translate.c
116
+++ b/target/arm/translate.c
70
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
117
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
71
}
118
{
119
TCGv addr;
120
121
- if (arm_dc_feature(s, ARM_FEATURE_M) &&
122
- !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
123
+ if (s->align_mem) {
124
opc |= MO_ALIGN;
72
}
125
}
73
126
74
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
127
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
75
+ /* Handle M-profile lazy FP state mechanics */
128
{
76
+
129
TCGv addr;
77
+ /* Update ownership of FP context: set FPCCR.S to match current state */
130
78
+ if (s->v8m_fpccr_s_wrong) {
131
- if (arm_dc_feature(s, ARM_FEATURE_M) &&
79
+ TCGv_i32 tmp;
132
- !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
80
+
133
+ if (s->align_mem) {
81
+ tmp = load_cpu_field(v7m.fpccr[M_REG_S]);
134
opc |= MO_ALIGN;
82
+ if (s->v8m_secure) {
135
}
83
+ tcg_gen_ori_i32(tmp, tmp, R_V7M_FPCCR_S_MASK);
136
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)
137
@@ -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) &&
138
dc->user = (dc->current_el == 0);
98
regime_is_secure(env, dc->mmu_idx);
139
#endif
99
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
140
dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
100
+ dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
141
+ dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
101
dc->cp_regs = cpu->cp_regs;
142
102
dc->features = env->features;
143
if (arm_feature(env, ARM_FEATURE_M)) {
103
144
dc->vfp_enabled = 1;
104
--
145
--
105
2.20.1
146
2.20.1
106
147
107
148
diff view generated by jsdifflib
1
Implement the VLLDM instruction for v7M for the FPU present cas.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Create a finalize_memop function that computes alignment and
4
endianness and returns the final MemOp for the operation.
5
6
Split out gen_aa32_{ld,st}_internal_i32 which bypasses any special
7
handling of endianness or alignment. Adjust gen_aa32_{ld,st}_i32
8
so that s->be_data is not added by the callers.
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210419202257.161730-12-richard.henderson@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
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
---
14
---
7
target/arm/helper.h | 1 +
15
target/arm/translate.h | 24 ++++++++
8
target/arm/helper.c | 54 ++++++++++++++++++++++++++++++++++++++++++
16
target/arm/translate.c | 100 +++++++++++++++++---------------
9
target/arm/translate.c | 2 +-
17
target/arm/translate-neon.c.inc | 9 +--
10
3 files changed, 56 insertions(+), 1 deletion(-)
18
3 files changed, 79 insertions(+), 54 deletions(-)
11
19
12
diff --git a/target/arm/helper.h b/target/arm/helper.h
20
diff --git a/target/arm/translate.h b/target/arm/translate.h
13
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.h
22
--- a/target/arm/translate.h
15
+++ b/target/arm/helper.h
23
+++ b/target/arm/translate.h
16
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
24
@@ -XXX,XX +XXX,XX @@ static inline TCGv_ptr fpstatus_ptr(ARMFPStatusFlavour flavour)
17
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
25
return statusptr;
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
}
26
}
31
27
32
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
28
+/**
29
+ * finalize_memop:
30
+ * @s: DisasContext
31
+ * @opc: size+sign+align of the memory operation
32
+ *
33
+ * Build the complete MemOp for a memory operation, including alignment
34
+ * and endianness.
35
+ *
36
+ * If (op & MO_AMASK) then the operation already contains the required
37
+ * alignment, e.g. for AccType_ATOMIC. Otherwise, this an optionally
38
+ * unaligned operation, e.g. for AccType_NORMAL.
39
+ *
40
+ * In the latter case, there are configuration bits that require alignment,
41
+ * and this is applied here. Note that there is no way to indicate that
42
+ * no alignment should ever be enforced; this must be handled manually.
43
+ */
44
+static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
33
+{
45
+{
34
+ /* translate.c should never generate calls here in user-only mode */
46
+ if (s->align_mem && !(opc & MO_AMASK)) {
35
+ g_assert_not_reached();
47
+ opc |= MO_ALIGN;
48
+ }
49
+ return opc | s->be_data;
36
+}
50
+}
37
+
51
+
38
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
52
#endif /* TARGET_ARM_TRANSLATE_H */
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
53
diff --git a/target/arm/translate.c b/target/arm/translate.c
97
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate.c
55
--- a/target/arm/translate.c
99
+++ b/target/arm/translate.c
56
+++ b/target/arm/translate.c
100
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
57
@@ -XXX,XX +XXX,XX @@ static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
101
TCGv_i32 fptr = load_reg(s, rn);
58
#define IS_USER_ONLY 0
102
59
#endif
103
if (extract32(insn, 20, 1)) {
60
104
- /* VLLDM */
61
-/* Abstractions of "generate code to do a guest load/store for
105
+ gen_helper_v7m_vlldm(cpu_env, fptr);
62
+/*
106
} else {
63
+ * Abstractions of "generate code to do a guest load/store for
107
gen_helper_v7m_vlstm(cpu_env, fptr);
64
* AArch32", where a vaddr is always 32 bits (and is zero
108
}
65
* extended if we're a 64 bit core) and data is also
66
* 32 bits unless specifically doing a 64 bit access.
67
@@ -XXX,XX +XXX,XX @@ static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
68
* that the address argument is TCGv_i32 rather than TCGv.
69
*/
70
71
-static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, MemOp op)
72
+static TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, MemOp op)
73
{
74
TCGv addr = tcg_temp_new();
75
tcg_gen_extu_i32_tl(addr, a32);
76
@@ -XXX,XX +XXX,XX @@ static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, MemOp op)
77
return addr;
78
}
79
80
+/*
81
+ * Internal routines are used for NEON cases where the endianness
82
+ * and/or alignment has already been taken into account and manipulated.
83
+ */
84
+static void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
85
+ TCGv_i32 a32, int index, MemOp opc)
86
+{
87
+ TCGv addr = gen_aa32_addr(s, a32, opc);
88
+ tcg_gen_qemu_ld_i32(val, addr, index, opc);
89
+ tcg_temp_free(addr);
90
+}
91
+
92
+static void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
93
+ TCGv_i32 a32, int index, MemOp opc)
94
+{
95
+ TCGv addr = gen_aa32_addr(s, a32, opc);
96
+ tcg_gen_qemu_st_i32(val, addr, index, opc);
97
+ tcg_temp_free(addr);
98
+}
99
+
100
static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
101
int index, MemOp opc)
102
{
103
- TCGv addr;
104
-
105
- if (s->align_mem) {
106
- opc |= MO_ALIGN;
107
- }
108
-
109
- addr = gen_aa32_addr(s, a32, opc);
110
- tcg_gen_qemu_ld_i32(val, addr, index, opc);
111
- tcg_temp_free(addr);
112
+ gen_aa32_ld_internal_i32(s, val, a32, index, finalize_memop(s, opc));
113
}
114
115
static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
116
int index, MemOp opc)
117
{
118
- TCGv addr;
119
+ gen_aa32_st_internal_i32(s, val, a32, index, finalize_memop(s, opc));
120
+}
121
122
- if (s->align_mem) {
123
- opc |= MO_ALIGN;
124
+#define DO_GEN_LD(SUFF, OPC) \
125
+ static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
126
+ TCGv_i32 a32, int index) \
127
+ { \
128
+ gen_aa32_ld_i32(s, val, a32, index, OPC); \
129
}
130
131
- addr = gen_aa32_addr(s, a32, opc);
132
- tcg_gen_qemu_st_i32(val, addr, index, opc);
133
- tcg_temp_free(addr);
134
-}
135
-
136
-#define DO_GEN_LD(SUFF, OPC) \
137
-static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
138
- TCGv_i32 a32, int index) \
139
-{ \
140
- gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
141
-}
142
-
143
-#define DO_GEN_ST(SUFF, OPC) \
144
-static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
145
- TCGv_i32 a32, int index) \
146
-{ \
147
- gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
148
-}
149
+#define DO_GEN_ST(SUFF, OPC) \
150
+ static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
151
+ TCGv_i32 a32, int index) \
152
+ { \
153
+ gen_aa32_st_i32(s, val, a32, index, OPC); \
154
+ }
155
156
static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
157
{
158
@@ -XXX,XX +XXX,XX @@ static bool op_load_rr(DisasContext *s, arg_ldst_rr *a,
159
addr = op_addr_rr_pre(s, a);
160
161
tmp = tcg_temp_new_i32();
162
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop | s->be_data);
163
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop);
164
disas_set_da_iss(s, mop, issinfo);
165
166
/*
167
@@ -XXX,XX +XXX,XX @@ static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
168
addr = op_addr_rr_pre(s, a);
169
170
tmp = load_reg(s, a->rt);
171
- gen_aa32_st_i32(s, tmp, addr, mem_idx, mop | s->be_data);
172
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, mop);
173
disas_set_da_iss(s, mop, issinfo);
174
tcg_temp_free_i32(tmp);
175
176
@@ -XXX,XX +XXX,XX @@ static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
177
addr = op_addr_rr_pre(s, a);
178
179
tmp = tcg_temp_new_i32();
180
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
181
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
182
store_reg(s, a->rt, tmp);
183
184
tcg_gen_addi_i32(addr, addr, 4);
185
186
tmp = tcg_temp_new_i32();
187
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
188
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
189
store_reg(s, a->rt + 1, tmp);
190
191
/* LDRD w/ base writeback is undefined if the registers overlap. */
192
@@ -XXX,XX +XXX,XX @@ static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
193
addr = op_addr_rr_pre(s, a);
194
195
tmp = load_reg(s, a->rt);
196
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
197
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
198
tcg_temp_free_i32(tmp);
199
200
tcg_gen_addi_i32(addr, addr, 4);
201
202
tmp = load_reg(s, a->rt + 1);
203
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
204
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
205
tcg_temp_free_i32(tmp);
206
207
op_addr_rr_post(s, a, addr, -4);
208
@@ -XXX,XX +XXX,XX @@ static bool op_load_ri(DisasContext *s, arg_ldst_ri *a,
209
addr = op_addr_ri_pre(s, a);
210
211
tmp = tcg_temp_new_i32();
212
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop | s->be_data);
213
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop);
214
disas_set_da_iss(s, mop, issinfo);
215
216
/*
217
@@ -XXX,XX +XXX,XX @@ static bool op_store_ri(DisasContext *s, arg_ldst_ri *a,
218
addr = op_addr_ri_pre(s, a);
219
220
tmp = load_reg(s, a->rt);
221
- gen_aa32_st_i32(s, tmp, addr, mem_idx, mop | s->be_data);
222
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, mop);
223
disas_set_da_iss(s, mop, issinfo);
224
tcg_temp_free_i32(tmp);
225
226
@@ -XXX,XX +XXX,XX @@ static bool op_ldrd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
227
addr = op_addr_ri_pre(s, a);
228
229
tmp = tcg_temp_new_i32();
230
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
231
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
232
store_reg(s, a->rt, tmp);
233
234
tcg_gen_addi_i32(addr, addr, 4);
235
236
tmp = tcg_temp_new_i32();
237
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
238
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
239
store_reg(s, rt2, tmp);
240
241
/* LDRD w/ base writeback is undefined if the registers overlap. */
242
@@ -XXX,XX +XXX,XX @@ static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
243
addr = op_addr_ri_pre(s, a);
244
245
tmp = load_reg(s, a->rt);
246
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
247
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
248
tcg_temp_free_i32(tmp);
249
250
tcg_gen_addi_i32(addr, addr, 4);
251
252
tmp = load_reg(s, rt2);
253
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
254
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
255
tcg_temp_free_i32(tmp);
256
257
op_addr_ri_post(s, a, addr, -4);
258
@@ -XXX,XX +XXX,XX @@ static bool op_stl(DisasContext *s, arg_STL *a, MemOp mop)
259
addr = load_reg(s, a->rn);
260
tmp = load_reg(s, a->rt);
261
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
262
- gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop | s->be_data);
263
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop);
264
disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel | ISSIsWrite);
265
266
tcg_temp_free_i32(tmp);
267
@@ -XXX,XX +XXX,XX @@ static bool op_lda(DisasContext *s, arg_LDA *a, MemOp mop)
268
269
addr = load_reg(s, a->rn);
270
tmp = tcg_temp_new_i32();
271
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop | s->be_data);
272
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop);
273
disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel);
274
tcg_temp_free_i32(addr);
275
276
@@ -XXX,XX +XXX,XX @@ static bool op_tbranch(DisasContext *s, arg_tbranch *a, bool half)
277
addr = load_reg(s, a->rn);
278
tcg_gen_add_i32(addr, addr, tmp);
279
280
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
281
- half ? MO_UW | s->be_data : MO_UB);
282
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), half ? MO_UW : MO_UB);
283
tcg_temp_free_i32(addr);
284
285
tcg_gen_add_i32(tmp, tmp, tmp);
286
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
287
index XXXXXXX..XXXXXXX 100644
288
--- a/target/arm/translate-neon.c.inc
289
+++ b/target/arm/translate-neon.c.inc
290
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
291
addr = tcg_temp_new_i32();
292
load_reg_var(s, addr, a->rn);
293
for (reg = 0; reg < nregs; reg++) {
294
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
295
- s->be_data | size);
296
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), size);
297
if ((vd & 1) && vec_size == 16) {
298
/*
299
* We cannot write 16 bytes at once because the
300
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
301
*/
302
for (reg = 0; reg < nregs; reg++) {
303
if (a->l) {
304
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
305
- s->be_data | a->size);
306
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), a->size);
307
neon_store_element(vd, a->reg_idx, a->size, tmp);
308
} else { /* Store */
309
neon_load_element(tmp, vd, a->reg_idx, a->size);
310
- gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
311
- s->be_data | a->size);
312
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), a->size);
313
}
314
vd += a->stride;
315
tcg_gen_addi_i32(addr, addr, 1 << a->size);
109
--
316
--
110
2.20.1
317
2.20.1
111
318
112
319
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
This is the only caller. Adjust some commentary to talk
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
about SCTLR_B instead of the vanishing function.
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
6
Message-id: 20190412165416.7977-7-philmd@redhat.com
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210419202257.161730-13-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
10
---
9
include/hw/devices.h | 14 --------------
11
target/arm/translate.c | 37 ++++++++++++++++---------------------
10
include/hw/misc/cbus.h | 32 ++++++++++++++++++++++++++++++++
12
1 file changed, 16 insertions(+), 21 deletions(-)
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
13
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/devices.h
16
--- a/target/arm/translate.c
20
+++ b/include/hw/devices.h
17
+++ b/target/arm/translate.c
21
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
18
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
22
/* stellaris_input.c */
19
gen_aa32_st_i32(s, val, a32, index, OPC); \
23
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
20
}
24
21
25
-/* cbus.c */
22
-static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
26
-typedef struct {
23
-{
27
- qemu_irq clk;
24
- /* Not needed for user-mode BE32, where we use MO_BE instead. */
28
- qemu_irq dat;
25
- if (!IS_USER_ONLY && s->sctlr_b) {
29
- qemu_irq sel;
26
- tcg_gen_rotri_i64(val, val, 32);
30
-} CBus;
27
- }
31
-CBus *cbus_init(qemu_irq dat_out);
28
-}
32
-void cbus_attach(CBus *bus, void *slave_opaque);
33
-
29
-
34
-void *retu_init(qemu_irq irq, int vilma);
30
static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
35
-void *tahvo_init(qemu_irq irq, int betty);
31
int index, MemOp opc)
36
-
32
{
37
-void retu_key_event(void *retu, int state);
33
TCGv addr = gen_aa32_addr(s, a32, opc);
38
-
34
tcg_gen_qemu_ld_i64(val, addr, index, opc);
39
#endif
35
- gen_aa32_frob64(s, val);
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
+
36
+
58
+#ifndef HW_MISC_CBUS_H
37
+ /* Not needed for user-mode BE32, where we use MO_BE instead. */
59
+#define HW_MISC_CBUS_H
38
+ if (!IS_USER_ONLY && s->sctlr_b) {
39
+ tcg_gen_rotri_i64(val, val, 32);
40
+ }
60
+
41
+
61
+#include "hw/irq.h"
42
tcg_temp_free(addr);
43
}
44
45
@@ -XXX,XX +XXX,XX @@ static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
46
TCGv_i32 tmp2 = tcg_temp_new_i32();
47
TCGv_i64 t64 = tcg_temp_new_i64();
48
49
- /* For AArch32, architecturally the 32-bit word at the lowest
50
+ /*
51
+ * For AArch32, architecturally the 32-bit word at the lowest
52
* address is always Rt and the one at addr+4 is Rt2, even if
53
* the CPU is big-endian. That means we don't want to do a
54
- * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
55
- * for an architecturally 64-bit access, but instead do a
56
- * 64-bit access using MO_BE if appropriate and then split
57
- * the two halves.
58
- * This only makes a difference for BE32 user-mode, where
59
- * frob64() must not flip the two halves of the 64-bit data
60
- * but this code must treat BE32 user-mode like BE32 system.
61
+ * gen_aa32_ld_i64(), which checks SCTLR_B as if for an
62
+ * architecturally 64-bit access, but instead do a 64-bit access
63
+ * using MO_BE if appropriate and then split the two halves.
64
*/
65
TCGv taddr = gen_aa32_addr(s, addr, opc);
66
67
@@ -XXX,XX +XXX,XX @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
68
TCGv_i64 n64 = tcg_temp_new_i64();
69
70
t2 = load_reg(s, rt2);
71
- /* For AArch32, architecturally the 32-bit word at the lowest
62
+
72
+
63
+typedef struct {
73
+ /*
64
+ qemu_irq clk;
74
+ * For AArch32, architecturally the 32-bit word at the lowest
65
+ qemu_irq dat;
75
* address is always Rt and the one at addr+4 is Rt2, even if
66
+ qemu_irq sel;
76
* the CPU is big-endian. Since we're going to treat this as a
67
+} CBus;
77
* single 64-bit BE store, we need to put the two halves in the
68
+
78
* opposite order for BE to LE, so that they end up in the right
69
+CBus *cbus_init(qemu_irq dat_out);
79
- * places.
70
+void cbus_attach(CBus *bus, void *slave_opaque);
80
- * We don't want gen_aa32_frob64() because that does the wrong
71
+
81
- * thing for BE32 usermode.
72
+void *retu_init(qemu_irq irq, int vilma);
82
+ * places. We don't want gen_aa32_st_i64, because that checks
73
+void *tahvo_init(qemu_irq irq, int betty);
83
+ * SCTLR_B as if for an architectural 64-bit access.
74
+
84
*/
75
+void retu_key_event(void *retu, int state);
85
if (s->be_data == MO_BE) {
76
+
86
tcg_gen_concat_i32_i64(n64, t2, t1);
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
--
87
--
116
2.20.1
88
2.20.1
117
89
118
90
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add an entries the Blizzard device in MAINTAINERS.
3
Just because operating on a TCGv_i64 temporary does not
4
mean that we're performing a 64-bit operation. Restrict
5
the frobbing to actual 64-bit operations.
4
6
5
Reviewed-by: Thomas Huth <thuth@redhat.com>
7
This bug is not currently visible because all current
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
8
users of these two functions always pass MO_64.
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
8
Message-id: 20190412165416.7977-6-philmd@redhat.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210419202257.161730-14-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
14
---
11
include/hw/devices.h | 7 -------
15
target/arm/translate.c | 4 ++--
12
include/hw/display/blizzard.h | 22 ++++++++++++++++++++++
16
1 file changed, 2 insertions(+), 2 deletions(-)
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
17
19
diff --git a/include/hw/devices.h b/include/hw/devices.h
18
diff --git a/target/arm/translate.c b/target/arm/translate.c
20
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/devices.h
20
--- a/target/arm/translate.c
22
+++ b/include/hw/devices.h
21
+++ b/target/arm/translate.c
23
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
22
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
24
/* stellaris_input.c */
23
tcg_gen_qemu_ld_i64(val, addr, index, opc);
25
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
24
26
25
/* Not needed for user-mode BE32, where we use MO_BE instead. */
27
-/* blizzard.c */
26
- if (!IS_USER_ONLY && s->sctlr_b) {
28
-void *s1d13745_init(qemu_irq gpio_int);
27
+ if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
29
-void s1d13745_write(void *opaque, int dc, uint16_t value);
28
tcg_gen_rotri_i64(val, val, 32);
30
-void s1d13745_write_block(void *opaque, int dc,
29
}
31
- void *buf, size_t len, int pitch);
30
32
-uint16_t s1d13745_read(void *opaque, int dc);
31
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
33
-
32
TCGv addr = gen_aa32_addr(s, a32, opc);
34
/* cbus.c */
33
35
typedef struct {
34
/* Not needed for user-mode BE32, where we use MO_BE instead. */
36
qemu_irq clk;
35
- if (!IS_USER_ONLY && s->sctlr_b) {
37
diff --git a/include/hw/display/blizzard.h b/include/hw/display/blizzard.h
36
+ if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
38
new file mode 100644
37
TCGv_i64 tmp = tcg_temp_new_i64();
39
index XXXXXXX..XXXXXXX
38
tcg_gen_rotri_i64(tmp, val, 32);
40
--- /dev/null
39
tcg_gen_qemu_st_i64(tmp, addr, index, opc);
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
--
40
--
108
2.20.1
41
2.20.1
109
42
110
43
diff view generated by jsdifflib
1
The magic value pushed onto the callee stack as an integrity
1
From: Richard Henderson <richard.henderson@linaro.org>
2
check is different if floating point is present.
3
2
3
Adjust the interface to match what has been done to the
4
TCGv_i32 load/store functions.
5
6
This is less obvious, because at present the only user of
7
these functions, trans_VLDST_multiple, also wants to manipulate
8
the endianness to speed up loading multiple bytes. Thus we
9
retain an "internal" interface which is identical to the
10
current gen_aa32_{ld,st}_i64 interface.
11
12
The "new" interface will gain users as we remove the legacy
13
interfaces, gen_aa32_ld64 and gen_aa32_st64.
14
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20210419202257.161730-15-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
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
7
---
19
---
8
target/arm/helper.c | 22 +++++++++++++++++++---
20
target/arm/translate.c | 78 +++++++++++++++++++--------------
9
1 file changed, 19 insertions(+), 3 deletions(-)
21
target/arm/translate-neon.c.inc | 6 ++-
22
2 files changed, 49 insertions(+), 35 deletions(-)
10
23
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
24
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
26
--- a/target/arm/translate.c
14
+++ b/target/arm/helper.c
27
+++ b/target/arm/translate.c
15
@@ -XXX,XX +XXX,XX @@ load_fail:
28
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
16
return false;
29
tcg_temp_free(addr);
17
}
30
}
18
31
19
+static uint32_t v7m_integrity_sig(CPUARMState *env, uint32_t lr)
32
+static void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
33
+ TCGv_i32 a32, int index, MemOp opc)
20
+{
34
+{
21
+ /*
35
+ TCGv addr = gen_aa32_addr(s, a32, opc);
22
+ * Return the integrity signature value for the callee-saves
23
+ * stack frame section. @lr is the exception return payload/LR value
24
+ * whose FType bit forms bit 0 of the signature if FP is present.
25
+ */
26
+ uint32_t sig = 0xfefa125a;
27
+
36
+
28
+ if (!arm_feature(env, ARM_FEATURE_VFP) || (lr & R_V7M_EXCRET_FTYPE_MASK)) {
37
+ tcg_gen_qemu_ld_i64(val, addr, index, opc);
29
+ sig |= 1;
38
+
39
+ /* Not needed for user-mode BE32, where we use MO_BE instead. */
40
+ if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
41
+ tcg_gen_rotri_i64(val, val, 32);
30
+ }
42
+ }
31
+ return sig;
43
+ tcg_temp_free(addr);
32
+}
44
+}
33
+
45
+
34
static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
46
+static void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
35
bool ignore_faults)
47
+ TCGv_i32 a32, int index, MemOp opc)
48
+{
49
+ TCGv addr = gen_aa32_addr(s, a32, opc);
50
+
51
+ /* Not needed for user-mode BE32, where we use MO_BE instead. */
52
+ if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
53
+ TCGv_i64 tmp = tcg_temp_new_i64();
54
+ tcg_gen_rotri_i64(tmp, val, 32);
55
+ tcg_gen_qemu_st_i64(tmp, addr, index, opc);
56
+ tcg_temp_free_i64(tmp);
57
+ } else {
58
+ tcg_gen_qemu_st_i64(val, addr, index, opc);
59
+ }
60
+ tcg_temp_free(addr);
61
+}
62
+
63
static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
64
int index, MemOp opc)
36
{
65
{
37
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
66
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
38
bool stacked_ok;
67
gen_aa32_st_internal_i32(s, val, a32, index, finalize_memop(s, opc));
39
uint32_t limit;
68
}
40
bool want_psp;
69
41
+ uint32_t sig;
70
+static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
42
71
+ int index, MemOp opc)
43
if (dotailchain) {
72
+{
44
bool mode = lr & R_V7M_EXCRET_MODE_MASK;
73
+ gen_aa32_ld_internal_i64(s, val, a32, index, finalize_memop(s, opc));
45
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
74
+}
46
/* Write as much of the stack frame as we can. A write failure may
75
+
47
* cause us to pend a derived exception.
76
+static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
48
*/
77
+ int index, MemOp opc)
49
+ sig = v7m_integrity_sig(env, lr);
78
+{
50
stacked_ok =
79
+ gen_aa32_st_internal_i64(s, val, a32, index, finalize_memop(s, opc));
51
- v7m_stack_write(cpu, frameptr, 0xfefa125b, mmu_idx, ignore_faults) &&
80
+}
52
+ v7m_stack_write(cpu, frameptr, sig, mmu_idx, ignore_faults) &&
81
+
53
v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
82
#define DO_GEN_LD(SUFF, OPC) \
54
ignore_faults) &&
83
static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
55
v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
84
TCGv_i32 a32, int index) \
56
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
85
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
57
if (return_to_secure &&
86
gen_aa32_st_i32(s, val, a32, index, OPC); \
58
((excret & R_V7M_EXCRET_ES_MASK) == 0 ||
87
}
59
(excret & R_V7M_EXCRET_DCRS_MASK) == 0)) {
88
60
- uint32_t expected_sig = 0xfefa125b;
89
-static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
61
uint32_t actual_sig;
90
- int index, MemOp opc)
62
91
-{
63
pop_ok = v7m_stack_read(cpu, &actual_sig, frameptr, mmu_idx);
92
- TCGv addr = gen_aa32_addr(s, a32, opc);
64
93
- tcg_gen_qemu_ld_i64(val, addr, index, opc);
65
- if (pop_ok && expected_sig != actual_sig) {
94
-
66
+ if (pop_ok && v7m_integrity_sig(env, excret) != actual_sig) {
95
- /* Not needed for user-mode BE32, where we use MO_BE instead. */
67
/* Take a SecureFault on the current stack */
96
- if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
68
env->v7m.sfsr |= R_V7M_SFSR_INVIS_MASK;
97
- tcg_gen_rotri_i64(val, val, 32);
69
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
98
- }
99
-
100
- tcg_temp_free(addr);
101
-}
102
-
103
static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
104
TCGv_i32 a32, int index)
105
{
106
- gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
107
-}
108
-
109
-static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
110
- int index, MemOp opc)
111
-{
112
- TCGv addr = gen_aa32_addr(s, a32, opc);
113
-
114
- /* Not needed for user-mode BE32, where we use MO_BE instead. */
115
- if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
116
- TCGv_i64 tmp = tcg_temp_new_i64();
117
- tcg_gen_rotri_i64(tmp, val, 32);
118
- tcg_gen_qemu_st_i64(tmp, addr, index, opc);
119
- tcg_temp_free_i64(tmp);
120
- } else {
121
- tcg_gen_qemu_st_i64(val, addr, index, opc);
122
- }
123
- tcg_temp_free(addr);
124
+ gen_aa32_ld_i64(s, val, a32, index, MO_Q);
125
}
126
127
static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
128
TCGv_i32 a32, int index)
129
{
130
- gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
131
+ gen_aa32_st_i64(s, val, a32, index, MO_Q);
132
}
133
134
DO_GEN_LD(8u, MO_UB)
135
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
136
index XXXXXXX..XXXXXXX 100644
137
--- a/target/arm/translate-neon.c.inc
138
+++ b/target/arm/translate-neon.c.inc
139
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
140
int tt = a->vd + reg + spacing * xs;
141
142
if (a->l) {
143
- gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
144
+ gen_aa32_ld_internal_i64(s, tmp64, addr, mmu_idx,
145
+ endian | size);
146
neon_store_element64(tt, n, size, tmp64);
147
} else {
148
neon_load_element64(tmp64, tt, n, size);
149
- gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
150
+ gen_aa32_st_internal_i64(s, tmp64, addr, mmu_idx,
151
+ endian | size);
152
}
153
tcg_gen_add_i32(addr, addr, tmp);
154
}
70
--
155
--
71
2.20.1
156
2.20.1
72
157
73
158
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
Buglink: https://bugs.launchpad.net/qemu/+bug/1905356
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20190412165416.7977-5-philmd@redhat.com
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210419202257.161730-16-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
---
8
include/hw/devices.h | 6 ------
9
target/arm/translate.c | 16 ++++++++--------
9
include/hw/display/tc6393xb.h | 24 ++++++++++++++++++++++++
10
1 file changed, 8 insertions(+), 8 deletions(-)
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
11
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
12
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/devices.h
14
--- a/target/arm/translate.c
19
+++ b/include/hw/devices.h
15
+++ b/target/arm/translate.c
20
@@ -XXX,XX +XXX,XX @@ void *tahvo_init(qemu_irq irq, int betty);
16
@@ -XXX,XX +XXX,XX @@ static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
21
17
addr = op_addr_rr_pre(s, a);
22
void retu_key_event(void *retu, int state);
18
23
19
tmp = tcg_temp_new_i32();
24
-/* tc6393xb.c */
20
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
25
-typedef struct TC6393xbState TC6393xbState;
21
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
26
-TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
22
store_reg(s, a->rt, tmp);
27
- uint32_t base, qemu_irq irq);
23
28
-qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
24
tcg_gen_addi_i32(addr, addr, 4);
29
-
25
30
#endif
26
tmp = tcg_temp_new_i32();
31
diff --git a/include/hw/display/tc6393xb.h b/include/hw/display/tc6393xb.h
27
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
32
new file mode 100644
28
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
33
index XXXXXXX..XXXXXXX
29
store_reg(s, a->rt + 1, tmp);
34
--- /dev/null
30
35
+++ b/include/hw/display/tc6393xb.h
31
/* LDRD w/ base writeback is undefined if the registers overlap. */
36
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@ static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
37
+/*
33
addr = op_addr_rr_pre(s, a);
38
+ * Toshiba TC6393XB I/O Controller.
34
39
+ * Found in Sharp Zaurus SL-6000 (tosa) or some
35
tmp = load_reg(s, a->rt);
40
+ * Toshiba e-Series PDAs.
36
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
41
+ *
37
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
42
+ * Copyright (c) 2007 Hervé Poussineau
38
tcg_temp_free_i32(tmp);
43
+ *
39
44
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
40
tcg_gen_addi_i32(addr, addr, 4);
45
+ * See the COPYING file in the top-level directory.
41
46
+ */
42
tmp = load_reg(s, a->rt + 1);
47
+
43
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
48
+#ifndef HW_DISPLAY_TC6393XB_H
44
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
49
+#define HW_DISPLAY_TC6393XB_H
45
tcg_temp_free_i32(tmp);
50
+
46
51
+#include "exec/memory.h"
47
op_addr_rr_post(s, a, addr, -4);
52
+#include "hw/irq.h"
48
@@ -XXX,XX +XXX,XX @@ static bool op_ldrd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
53
+
49
addr = op_addr_ri_pre(s, a);
54
+typedef struct TC6393xbState TC6393xbState;
50
55
+
51
tmp = tcg_temp_new_i32();
56
+TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
52
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
57
+ uint32_t base, qemu_irq irq);
53
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
58
+qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
54
store_reg(s, a->rt, tmp);
59
+
55
60
+#endif
56
tcg_gen_addi_i32(addr, addr, 4);
61
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
57
62
index XXXXXXX..XXXXXXX 100644
58
tmp = tcg_temp_new_i32();
63
--- a/hw/arm/tosa.c
59
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
64
+++ b/hw/arm/tosa.c
60
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
65
@@ -XXX,XX +XXX,XX @@
61
store_reg(s, rt2, tmp);
66
#include "hw/hw.h"
62
67
#include "hw/arm/pxa.h"
63
/* LDRD w/ base writeback is undefined if the registers overlap. */
68
#include "hw/arm/arm.h"
64
@@ -XXX,XX +XXX,XX @@ static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
69
-#include "hw/devices.h"
65
addr = op_addr_ri_pre(s, a);
70
#include "hw/arm/sharpsl.h"
66
71
#include "hw/pcmcia.h"
67
tmp = load_reg(s, a->rt);
72
#include "hw/boards.h"
68
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
73
+#include "hw/display/tc6393xb.h"
69
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
74
#include "hw/i2c/i2c.h"
70
tcg_temp_free_i32(tmp);
75
#include "hw/ssi/ssi.h"
71
76
#include "hw/sysbus.h"
72
tcg_gen_addi_i32(addr, addr, 4);
77
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
73
78
index XXXXXXX..XXXXXXX 100644
74
tmp = load_reg(s, rt2);
79
--- a/hw/display/tc6393xb.c
75
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
80
+++ b/hw/display/tc6393xb.c
76
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
81
@@ -XXX,XX +XXX,XX @@
77
tcg_temp_free_i32(tmp);
82
#include "qapi/error.h"
78
83
#include "qemu/host-utils.h"
79
op_addr_ri_post(s, a, addr, -4);
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
--
80
--
103
2.20.1
81
2.20.1
104
82
105
83
diff view generated by jsdifflib
1
Like AArch64, M-profile floating point has no FPEXC enable
1
From: Richard Henderson <richard.henderson@linaro.org>
2
bit to gate floating point; so always set the VFPEN TB flag.
3
2
4
M-profile also has CPACR and NSACR similar to A-profile;
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
they behave slightly differently:
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
* the CPACR is banked between Secure and Non-Secure
5
Message-id: 20210419202257.161730-17-richard.henderson@linaro.org
7
* if the NSACR forces a trap then this is taken to
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
the Secure state, not the Non-Secure state
7
---
8
target/arm/translate.c | 4 ++--
9
1 file changed, 2 insertions(+), 2 deletions(-)
9
10
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
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
113
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/translate.c
13
--- a/target/arm/translate.c
115
+++ b/target/arm/translate.c
14
+++ b/target/arm/translate.c
116
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
15
@@ -XXX,XX +XXX,XX @@ static bool op_stl(DisasContext *s, arg_STL *a, MemOp mop)
117
* for attempts to execute invalid vfp/neon encodings with FP disabled.
16
addr = load_reg(s, a->rn);
118
*/
17
tmp = load_reg(s, a->rt);
119
if (s->fp_excp_el) {
18
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
120
- gen_exception_insn(s, 4, EXCP_UDEF,
19
- gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop);
121
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
20
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop | MO_ALIGN);
122
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
21
disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel | ISSIsWrite);
123
+ gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
22
124
+ s->fp_excp_el);
23
tcg_temp_free_i32(tmp);
125
+ } else {
24
@@ -XXX,XX +XXX,XX @@ static bool op_lda(DisasContext *s, arg_LDA *a, MemOp mop)
126
+ gen_exception_insn(s, 4, EXCP_UDEF,
25
127
+ syn_fp_access_trap(1, 0xe, false),
26
addr = load_reg(s, a->rn);
128
+ s->fp_excp_el);
27
tmp = tcg_temp_new_i32();
129
+ }
28
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop);
130
return 0;
29
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop | MO_ALIGN);
131
}
30
disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel);
31
tcg_temp_free_i32(addr);
132
32
133
--
33
--
134
2.20.1
34
2.20.1
135
35
136
36
diff view generated by jsdifflib
1
Enable the FPU by default for the Cortex-M4 and Cortex-M33.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-18-richard.henderson@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-27-peter.maydell@linaro.org
6
---
7
---
7
target/arm/cpu.c | 8 ++++++++
8
target/arm/translate.c | 4 ++--
8
1 file changed, 8 insertions(+)
9
1 file changed, 2 insertions(+), 2 deletions(-)
9
10
10
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
11
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
12
--- a/target/arm/cpu.c
13
--- a/target/arm/translate.c
13
+++ b/target/arm/cpu.c
14
+++ b/target/arm/translate.c
14
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
15
@@ -XXX,XX +XXX,XX @@ static bool op_stm(DisasContext *s, arg_ldst_block *a, int min_n)
15
set_feature(&cpu->env, ARM_FEATURE_M);
16
} else {
16
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
17
tmp = load_reg(s, i);
17
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
18
}
18
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
19
- gen_aa32_st32(s, tmp, addr, mem_idx);
19
cpu->midr = 0x410fc240; /* r0p0 */
20
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
20
cpu->pmsav7_dregion = 8;
21
tcg_temp_free_i32(tmp);
21
+ cpu->isar.mvfr0 = 0x10110021;
22
22
+ cpu->isar.mvfr1 = 0x11000011;
23
/* No need to add after the last transfer. */
23
+ cpu->isar.mvfr2 = 0x00000000;
24
@@ -XXX,XX +XXX,XX @@ static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n)
24
cpu->id_pfr0 = 0x00000030;
25
}
25
cpu->id_pfr1 = 0x00000200;
26
26
cpu->id_dfr0 = 0x00100000;
27
tmp = tcg_temp_new_i32();
27
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
28
- gen_aa32_ld32u(s, tmp, addr, mem_idx);
28
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
29
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
29
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
30
if (user) {
30
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
31
tmp2 = tcg_const_i32(i);
31
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
32
gen_helper_set_user_reg(cpu_env, tmp2, tmp);
32
cpu->midr = 0x410fd213; /* r0p3 */
33
cpu->pmsav7_dregion = 16;
34
cpu->sau_sregion = 8;
35
+ cpu->isar.mvfr0 = 0x10110021;
36
+ cpu->isar.mvfr1 = 0x11000011;
37
+ cpu->isar.mvfr2 = 0x00000040;
38
cpu->id_pfr0 = 0x00000030;
39
cpu->id_pfr1 = 0x00000210;
40
cpu->id_dfr0 = 0x00200000;
41
--
33
--
42
2.20.1
34
2.20.1
43
35
44
36
diff view generated by jsdifflib
1
Correct the decode of the M-profile "coprocessor and
1
From: Richard Henderson <richard.henderson@linaro.org>
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()
6
2
7
For the moment we leave VLLDM and VLSTM as NOPs; in
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
a later commit we will fill in the proper implementation
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
for the case where an FPU is present.
5
Message-id: 20210419202257.161730-19-richard.henderson@linaro.org
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
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
---
7
---
15
target/arm/translate.c | 26 ++++++++++++++++++++++----
8
target/arm/translate.c | 4 ++--
16
1 file changed, 22 insertions(+), 4 deletions(-)
9
1 file changed, 2 insertions(+), 2 deletions(-)
17
10
18
diff --git a/target/arm/translate.c b/target/arm/translate.c
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
19
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate.c
13
--- a/target/arm/translate.c
21
+++ b/target/arm/translate.c
14
+++ b/target/arm/translate.c
22
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
15
@@ -XXX,XX +XXX,XX @@ static bool trans_RFE(DisasContext *s, arg_RFE *a)
23
case 6: case 7: case 14: case 15:
16
24
/* Coprocessor. */
17
/* Load PC into tmp and CPSR into tmp2. */
25
if (arm_dc_feature(s, ARM_FEATURE_M)) {
18
t1 = tcg_temp_new_i32();
26
- /* We don't currently implement M profile FP support,
19
- gen_aa32_ld32u(s, t1, addr, get_mem_index(s));
27
- * so this entire space should give a NOCP fault, with
20
+ gen_aa32_ld_i32(s, t1, addr, get_mem_index(s), MO_UL | MO_ALIGN);
28
- * the exception of the v8M VLLDM and VLSTM insns, which
21
tcg_gen_addi_i32(addr, addr, 4);
29
- * must be NOPs in Secure state and UNDEF in Nonsecure state.
22
t2 = tcg_temp_new_i32();
30
+ /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
23
- gen_aa32_ld32u(s, t2, addr, get_mem_index(s));
31
+ if (extract32(insn, 24, 2) == 3) {
24
+ gen_aa32_ld_i32(s, t2, addr, get_mem_index(s), MO_UL | MO_ALIGN);
32
+ goto illegal_op; /* op0 = 0b11 : unallocated */
25
33
+ }
26
if (a->w) {
34
+
27
/* Base writeback. */
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
--
28
--
63
2.20.1
29
2.20.1
64
30
65
31
diff view generated by jsdifflib
1
The only "system register" that M-profile floating point exposes
1
From: Richard Henderson <richard.henderson@linaro.org>
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.
5
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-20-richard.henderson@linaro.org
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>
8
Message-id: 20190416125744.27770-5-peter.maydell@linaro.org
9
---
7
---
10
target/arm/translate.c | 19 +++++++++++++++++--
8
target/arm/translate.c | 4 ++--
11
1 file changed, 17 insertions(+), 2 deletions(-)
9
1 file changed, 2 insertions(+), 2 deletions(-)
12
10
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
13
--- a/target/arm/translate.c
16
+++ b/target/arm/translate.c
14
+++ b/target/arm/translate.c
17
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
15
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
18
}
16
}
19
}
17
tcg_gen_addi_i32(addr, addr, offset);
20
} else { /* !dp */
18
tmp = load_reg(s, 14);
21
+ bool is_sysreg;
19
- gen_aa32_st32(s, tmp, addr, get_mem_index(s));
22
+
20
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
23
if ((insn & 0x6f) != 0x00)
21
tcg_temp_free_i32(tmp);
24
return 1;
22
tmp = load_cpu_field(spsr);
25
rn = VFP_SREG_N(insn);
23
tcg_gen_addi_i32(addr, addr, 4);
26
+
24
- gen_aa32_st32(s, tmp, addr, get_mem_index(s));
27
+ is_sysreg = extract32(insn, 21, 1);
25
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
28
+
26
tcg_temp_free_i32(tmp);
29
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
27
if (writeback) {
30
+ /*
28
switch (amode) {
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
--
29
--
56
2.20.1
30
2.20.1
57
31
58
32
diff view generated by jsdifflib
1
For v8M floating point support, transitions from Secure
1
From: Richard Henderson <richard.henderson@linaro.org>
2
to Non-secure state via BLNS and BLXNS must clear the
3
CONTROL.SFPA bit. (This corresponds to the pseudocode
4
BranchToNS() function.)
5
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-21-richard.henderson@linaro.org
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>
8
Message-id: 20190416125744.27770-13-peter.maydell@linaro.org
9
---
7
---
10
target/arm/helper.c | 4 ++++
8
target/arm/translate-vfp.c.inc | 8 ++++----
11
1 file changed, 4 insertions(+)
9
1 file changed, 4 insertions(+), 4 deletions(-)
12
10
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
11
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
14
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
13
--- a/target/arm/translate-vfp.c.inc
16
+++ b/target/arm/helper.c
14
+++ b/target/arm/translate-vfp.c.inc
17
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest)
15
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_sp(DisasContext *s, arg_VLDM_VSTM_sp *a)
18
/* translate.c should have made BXNS UNDEF unless we're secure */
16
for (i = 0; i < n; i++) {
19
assert(env->v7m.secure);
17
if (a->l) {
20
18
/* load */
21
+ if (!(dest & 1)) {
19
- gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
20
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
23
+ }
21
vfp_store_reg32(tmp, a->vd + i);
24
switch_v7m_security_state(env, dest & 1);
22
} else {
25
env->thumb = 1;
23
/* store */
26
env->regs[15] = dest & ~1;
24
vfp_load_reg32(tmp, a->vd + i);
27
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
25
- gen_aa32_st32(s, tmp, addr, get_mem_index(s));
28
*/
26
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
29
write_v7m_exception(env, 1);
27
}
28
tcg_gen_addi_i32(addr, addr, offset);
30
}
29
}
31
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
30
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a)
32
switch_v7m_security_state(env, 0);
31
for (i = 0; i < n; i++) {
33
env->thumb = 1;
32
if (a->l) {
34
env->regs[15] = dest;
33
/* load */
34
- gen_aa32_ld64(s, tmp, addr, get_mem_index(s));
35
+ gen_aa32_ld_i64(s, tmp, addr, get_mem_index(s), MO_Q | MO_ALIGN_4);
36
vfp_store_reg64(tmp, a->vd + i);
37
} else {
38
/* store */
39
vfp_load_reg64(tmp, a->vd + i);
40
- gen_aa32_st64(s, tmp, addr, get_mem_index(s));
41
+ gen_aa32_st_i64(s, tmp, addr, get_mem_index(s), MO_Q | MO_ALIGN_4);
42
}
43
tcg_gen_addi_i32(addr, addr, offset);
44
}
35
--
45
--
36
2.20.1
46
2.20.1
37
47
38
48
diff view generated by jsdifflib
1
If the floating point extension is present, then the SG instruction
1
From: Richard Henderson <richard.henderson@linaro.org>
2
must clear the CONTROL_S.SFPA bit. Implement this.
3
2
4
(On a no-FPU system the bit will always be zero, so we don't need
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
to make the clearing of the bit conditional on ARM_FEATURE_VFP.)
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-22-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate-vfp.c.inc | 12 ++++++------
9
1 file changed, 6 insertions(+), 6 deletions(-)
6
10
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
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
12
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
13
--- a/target/arm/translate-vfp.c.inc
17
+++ b/target/arm/helper.c
14
+++ b/target/arm/translate-vfp.c.inc
18
@@ -XXX,XX +XXX,XX @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
15
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_hp(DisasContext *s, arg_VLDR_VSTR_sp *a)
19
qemu_log_mask(CPU_LOG_INT, "...really an SG instruction at 0x%08" PRIx32
16
addr = add_reg_for_lit(s, a->rn, offset);
20
", executing it\n", env->regs[15]);
17
tmp = tcg_temp_new_i32();
21
env->regs[14] &= ~1;
18
if (a->l) {
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
19
- gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
23
switch_v7m_security_state(env, true);
20
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), MO_UW | MO_ALIGN);
24
xpsr_write(env, 0, XPSR_IT);
21
vfp_store_reg32(tmp, a->vd);
25
env->regs[15] += 4;
22
} else {
23
vfp_load_reg32(tmp, a->vd);
24
- gen_aa32_st16(s, tmp, addr, get_mem_index(s));
25
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), MO_UW | MO_ALIGN);
26
}
27
tcg_temp_free_i32(tmp);
28
tcg_temp_free_i32(addr);
29
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
30
addr = add_reg_for_lit(s, a->rn, offset);
31
tmp = tcg_temp_new_i32();
32
if (a->l) {
33
- gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
34
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
35
vfp_store_reg32(tmp, a->vd);
36
} else {
37
vfp_load_reg32(tmp, a->vd);
38
- gen_aa32_st32(s, tmp, addr, get_mem_index(s));
39
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
40
}
41
tcg_temp_free_i32(tmp);
42
tcg_temp_free_i32(addr);
43
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
44
addr = add_reg_for_lit(s, a->rn, offset);
45
tmp = tcg_temp_new_i64();
46
if (a->l) {
47
- gen_aa32_ld64(s, tmp, addr, get_mem_index(s));
48
+ gen_aa32_ld_i64(s, tmp, addr, get_mem_index(s), MO_Q | MO_ALIGN_4);
49
vfp_store_reg64(tmp, a->vd);
50
} else {
51
vfp_load_reg64(tmp, a->vd);
52
- gen_aa32_st64(s, tmp, addr, get_mem_index(s));
53
+ gen_aa32_st_i64(s, tmp, addr, get_mem_index(s), MO_Q | MO_ALIGN_4);
54
}
55
tcg_temp_free_i64(tmp);
56
tcg_temp_free_i32(addr);
26
--
57
--
27
2.20.1
58
2.20.1
28
59
29
60
diff view generated by jsdifflib
1
The M-profile FPCCR.ASPEN bit indicates that automatic floating-point
1
From: Richard Henderson <richard.henderson@linaro.org>
2
context preservation is enabled. Before executing any floating-point
3
instruction, if FPCCR.ASPEN is set and the CONTROL FPCA/SFPA bits
4
indicate that there is no active floating point context then we
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
2
9
Implement this with a new TB flag which tracks whether we
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
need to create a new FP context.
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-23-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate.h | 1 +
9
target/arm/translate.c | 15 +++++++++++++
10
target/arm/translate-neon.c.inc | 37 +++++++++++++++++++++++++--------
11
3 files changed, 44 insertions(+), 9 deletions(-)
11
12
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190416125744.27770-20-peter.maydell@linaro.org
15
---
16
target/arm/cpu.h | 2 ++
17
target/arm/translate.h | 1 +
18
target/arm/helper.c | 13 +++++++++++++
19
target/arm/translate.c | 29 +++++++++++++++++++++++++++++
20
4 files changed, 45 insertions(+)
21
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
25
+++ b/target/arm/cpu.h
26
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
27
FIELD(TBFLAG_A32, VFPEN, 7, 1)
28
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
29
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
30
+/* For M profile only, set if we must create a new FP context */
31
+FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
32
/* For M profile only, set if FPCCR.S does not match current security state */
33
FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
34
/* For M profile only, Handler (ie not Thread) mode */
35
diff --git a/target/arm/translate.h b/target/arm/translate.h
13
diff --git a/target/arm/translate.h b/target/arm/translate.h
36
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/translate.h
15
--- a/target/arm/translate.h
38
+++ b/target/arm/translate.h
16
+++ b/target/arm/translate.h
39
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
17
@@ -XXX,XX +XXX,XX @@ void arm_test_cc(DisasCompare *cmp, int cc);
40
bool v8m_secure; /* true if v8M and we're in Secure mode */
18
void arm_free_cc(DisasCompare *cmp);
41
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
19
void arm_jump_cc(DisasCompare *cmp, TCGLabel *label);
42
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
20
void arm_gen_test_cc(int cc, TCGLabel *label);
43
+ bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
21
+MemOp pow2_align(unsigned i);
44
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
22
45
* so that top level loop can generate correct syndrome information.
23
/* Return state of Alternate Half-precision flag, caller frees result */
46
*/
24
static inline TCGv_i32 get_ahp_flag(void)
47
diff --git a/target/arm/helper.c b/target/arm/helper.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/helper.c
50
+++ b/target/arm/helper.c
51
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
52
flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
53
}
54
55
+ if (arm_feature(env, ARM_FEATURE_M) &&
56
+ (env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) &&
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
25
diff --git a/target/arm/translate.c b/target/arm/translate.c
72
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/translate.c
27
--- a/target/arm/translate.c
74
+++ b/target/arm/translate.c
28
+++ b/target/arm/translate.c
75
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
29
@@ -XXX,XX +XXX,XX @@ static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
76
/* Don't need to do this for any further FP insns in this TB */
30
#define IS_USER_ONLY 0
77
s->v8m_fpccr_s_wrong = false;
31
#endif
32
33
+MemOp pow2_align(unsigned i)
34
+{
35
+ static const MemOp mop_align[] = {
36
+ 0, MO_ALIGN_2, MO_ALIGN_4, MO_ALIGN_8, MO_ALIGN_16,
37
+ /*
38
+ * FIXME: TARGET_PAGE_BITS_MIN affects TLB_FLAGS_MASK such
39
+ * that 256-bit alignment (MO_ALIGN_32) cannot be supported:
40
+ * see get_alignment_bits(). Enforce only 128-bit alignment for now.
41
+ */
42
+ MO_ALIGN_16
43
+ };
44
+ g_assert(i < ARRAY_SIZE(mop_align));
45
+ return mop_align[i];
46
+}
47
+
48
/*
49
* Abstractions of "generate code to do a guest load/store for
50
* AArch32", where a vaddr is always 32 bits (and is zero
51
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/translate-neon.c.inc
54
+++ b/target/arm/translate-neon.c.inc
55
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
56
int size = a->size;
57
int nregs = a->n + 1;
58
TCGv_i32 addr, tmp;
59
+ MemOp mop, align;
60
61
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
62
return false;
63
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
64
return false;
65
}
66
67
+ align = 0;
68
if (size == 3) {
69
if (nregs != 4 || a->a == 0) {
70
return false;
78
}
71
}
79
+
72
/* For VLD4 size == 3 a == 1 means 32 bits at 16 byte alignment */
80
+ if (s->v7m_new_fp_ctxt_needed) {
73
- size = 2;
81
+ /*
74
- }
82
+ * Create new FP context by updating CONTROL.FPCA, CONTROL.SFPA
75
- if (nregs == 1 && a->a == 1 && size == 0) {
83
+ * and the FPSCR.
76
- return false;
84
+ */
77
- }
85
+ TCGv_i32 control, fpscr;
78
- if (nregs == 3 && a->a == 1) {
86
+ uint32_t bits = R_V7M_CONTROL_FPCA_MASK;
79
- return false;
87
+
80
+ size = MO_32;
88
+ fpscr = load_cpu_field(v7m.fpdscr[s->v8m_secure]);
81
+ align = MO_ALIGN_16;
89
+ gen_helper_vfp_set_fpscr(cpu_env, fpscr);
82
+ } else if (a->a) {
90
+ tcg_temp_free_i32(fpscr);
83
+ switch (nregs) {
91
+ /*
84
+ case 1:
92
+ * We don't need to arrange to end the TB, because the only
85
+ if (size == 0) {
93
+ * parts of FPSCR which we cache in the TB flags are the VECLEN
86
+ return false;
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;
99
+ }
87
+ }
100
+ control = load_cpu_field(v7m.control[M_REG_S]);
88
+ align = MO_ALIGN;
101
+ tcg_gen_ori_i32(control, control, bits);
89
+ break;
102
+ store_cpu_field(control, v7m.control[M_REG_S]);
90
+ case 2:
103
+ /* Don't need to do this for any further FP insns in this TB */
91
+ align = pow2_align(size + 1);
104
+ s->v7m_new_fp_ctxt_needed = false;
92
+ break;
93
+ case 3:
94
+ return false;
95
+ case 4:
96
+ align = pow2_align(size + 2);
97
+ break;
98
+ default:
99
+ g_assert_not_reached();
105
+ }
100
+ }
106
}
101
}
107
102
108
if (extract32(insn, 28, 4) == 0xf) {
103
if (!vfp_access_check(s)) {
109
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
104
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
110
regime_is_secure(env, dc->mmu_idx);
105
*/
111
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
106
stride = a->t ? 2 : 1;
112
dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
107
vec_size = nregs == 1 ? stride * 8 : 8;
113
+ dc->v7m_new_fp_ctxt_needed =
108
-
114
+ FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
109
+ mop = size | align;
115
dc->cp_regs = cpu->cp_regs;
110
tmp = tcg_temp_new_i32();
116
dc->features = env->features;
111
addr = tcg_temp_new_i32();
117
112
load_reg_var(s, addr, a->rn);
113
for (reg = 0; reg < nregs; reg++) {
114
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), size);
115
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop);
116
if ((vd & 1) && vec_size == 16) {
117
/*
118
* We cannot write 16 bytes at once because the
119
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
120
}
121
tcg_gen_addi_i32(addr, addr, 1 << size);
122
vd += stride;
123
+
124
+ /* Subsequent memory operations inherit alignment */
125
+ mop &= ~MO_AMASK;
126
}
127
tcg_temp_free_i32(tmp);
128
tcg_temp_free_i32(addr);
118
--
129
--
119
2.20.1
130
2.20.1
120
131
121
132
diff view generated by jsdifflib
1
Enforce that for M-profile various FPSCR bits which are RES0 there
1
From: Richard Henderson <richard.henderson@linaro.org>
2
but have defined meanings on A-profile are never settable. This
3
ensures that M-profile code can't enable the A-profile behaviour
4
(notably vector length/stride handling) by accident.
5
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-24-richard.henderson@linaro.org
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>
8
Message-id: 20190416125744.27770-2-peter.maydell@linaro.org
9
---
7
---
10
target/arm/vfp_helper.c | 8 ++++++++
8
target/arm/translate-neon.c.inc | 27 ++++++++++++++++++++++-----
11
1 file changed, 8 insertions(+)
9
1 file changed, 22 insertions(+), 5 deletions(-)
12
10
13
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
11
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
14
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/vfp_helper.c
13
--- a/target/arm/translate-neon.c.inc
16
+++ b/target/arm/vfp_helper.c
14
+++ b/target/arm/translate-neon.c.inc
17
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
15
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
18
val &= ~FPCR_FZ16;
16
{
17
/* Neon load/store multiple structures */
18
int nregs, interleave, spacing, reg, n;
19
- MemOp endian = s->be_data;
20
+ MemOp mop, align, endian;
21
int mmu_idx = get_mem_index(s);
22
int size = a->size;
23
TCGv_i64 tmp64;
24
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
19
}
25
}
20
26
21
+ if (arm_feature(env, ARM_FEATURE_M)) {
27
/* For our purposes, bytes are always little-endian. */
22
+ /*
28
+ endian = s->be_data;
23
+ * M profile FPSCR is RES0 for the QC, STRIDE, FZ16, LEN bits
29
if (size == 0) {
24
+ * and also for the trapped-exception-handling bits IxE.
30
endian = MO_LE;
25
+ */
31
}
26
+ val &= 0xf7c0009f;
32
+
33
+ /* Enforce alignment requested by the instruction */
34
+ if (a->align) {
35
+ align = pow2_align(a->align + 2); /* 4 ** a->align */
36
+ } else {
37
+ align = s->align_mem ? MO_ALIGN : 0;
27
+ }
38
+ }
28
+
39
+
29
/*
40
/*
30
* We don't implement trapped exception handling, so the
41
* Consecutive little-endian elements from a single register
31
* trap enable bits, IDE|IXE|UFE|OFE|DZE|IOE are all RAZ/WI (not RES0!)
42
* can be promoted to a larger little-endian operation.
43
*/
44
if (interleave == 1 && endian == MO_LE) {
45
+ /* Retain any natural alignment. */
46
+ if (align == MO_ALIGN) {
47
+ align = pow2_align(size);
48
+ }
49
size = 3;
50
}
51
+
52
tmp64 = tcg_temp_new_i64();
53
addr = tcg_temp_new_i32();
54
tmp = tcg_const_i32(1 << size);
55
load_reg_var(s, addr, a->rn);
56
+
57
+ mop = endian | size | align;
58
for (reg = 0; reg < nregs; reg++) {
59
for (n = 0; n < 8 >> size; n++) {
60
int xs;
61
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
62
int tt = a->vd + reg + spacing * xs;
63
64
if (a->l) {
65
- gen_aa32_ld_internal_i64(s, tmp64, addr, mmu_idx,
66
- endian | size);
67
+ gen_aa32_ld_internal_i64(s, tmp64, addr, mmu_idx, mop);
68
neon_store_element64(tt, n, size, tmp64);
69
} else {
70
neon_load_element64(tmp64, tt, n, size);
71
- gen_aa32_st_internal_i64(s, tmp64, addr, mmu_idx,
72
- endian | size);
73
+ gen_aa32_st_internal_i64(s, tmp64, addr, mmu_idx, mop);
74
}
75
tcg_gen_add_i32(addr, addr, tmp);
76
+
77
+ /* Subsequent memory operations inherit alignment */
78
+ mop &= ~MO_AMASK;
79
}
80
}
81
}
32
--
82
--
33
2.20.1
83
2.20.1
34
84
35
85
diff view generated by jsdifflib
1
In the stripe8() function we use a variable length array; however
1
From: Richard Henderson <richard.henderson@linaro.org>
2
we know that the maximum length required is MAX_NUM_BUSSES. Use
3
a fixed-length array and an assert instead.
4
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-25-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
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
---
7
---
12
hw/ssi/xilinx_spips.c | 6 ++++--
8
target/arm/translate-neon.c.inc | 48 ++++++++++++++++++++++++++++-----
13
1 file changed, 4 insertions(+), 2 deletions(-)
9
1 file changed, 42 insertions(+), 6 deletions(-)
14
10
15
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
11
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/ssi/xilinx_spips.c
13
--- a/target/arm/translate-neon.c.inc
18
+++ b/hw/ssi/xilinx_spips.c
14
+++ b/target/arm/translate-neon.c.inc
19
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_reset(DeviceState *d)
15
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
20
16
int nregs = a->n + 1;
21
static inline void stripe8(uint8_t *x, int num, bool dir)
17
int vd = a->vd;
22
{
18
TCGv_i32 addr, tmp;
23
- uint8_t r[num];
19
+ MemOp mop;
24
- memset(r, 0, sizeof(uint8_t) * num);
20
25
+ uint8_t r[MAX_NUM_BUSSES];
21
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
26
int idx[2] = {0, 0};
22
return false;
27
int bit[2] = {0, 7};
23
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
28
int d = dir;
24
return true;
29
25
}
30
+ assert(num <= MAX_NUM_BUSSES);
26
31
+ memset(r, 0, sizeof(uint8_t) * num);
27
+ /* Pick up SCTLR settings */
28
+ mop = finalize_memop(s, a->size);
32
+
29
+
33
for (idx[0] = 0; idx[0] < num; ++idx[0]) {
30
+ if (a->align) {
34
for (bit[0] = 7; bit[0] >= 0; bit[0]--) {
31
+ MemOp align_op;
35
r[idx[!d]] |= x[idx[d]] & 1 << bit[d] ? 1 << bit[!d] : 0;
32
+
33
+ switch (nregs) {
34
+ case 1:
35
+ /* For VLD1, use natural alignment. */
36
+ align_op = MO_ALIGN;
37
+ break;
38
+ case 2:
39
+ /* For VLD2, use double alignment. */
40
+ align_op = pow2_align(a->size + 1);
41
+ break;
42
+ case 4:
43
+ if (a->size == MO_32) {
44
+ /*
45
+ * For VLD4.32, align = 1 is double alignment, align = 2 is
46
+ * quad alignment; align = 3 is rejected above.
47
+ */
48
+ align_op = pow2_align(a->size + a->align);
49
+ } else {
50
+ /* For VLD4.8 and VLD.16, we want quad alignment. */
51
+ align_op = pow2_align(a->size + 2);
52
+ }
53
+ break;
54
+ default:
55
+ /* For VLD3, the alignment field is zero and rejected above. */
56
+ g_assert_not_reached();
57
+ }
58
+
59
+ mop = (mop & ~MO_AMASK) | align_op;
60
+ }
61
+
62
tmp = tcg_temp_new_i32();
63
addr = tcg_temp_new_i32();
64
load_reg_var(s, addr, a->rn);
65
- /*
66
- * TODO: if we implemented alignment exceptions, we should check
67
- * addr against the alignment encoded in a->align here.
68
- */
69
+
70
for (reg = 0; reg < nregs; reg++) {
71
if (a->l) {
72
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), a->size);
73
+ gen_aa32_ld_internal_i32(s, tmp, addr, get_mem_index(s), mop);
74
neon_store_element(vd, a->reg_idx, a->size, tmp);
75
} else { /* Store */
76
neon_load_element(tmp, vd, a->reg_idx, a->size);
77
- gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), a->size);
78
+ gen_aa32_st_internal_i32(s, tmp, addr, get_mem_index(s), mop);
79
}
80
vd += a->stride;
81
tcg_gen_addi_i32(addr, addr, 1 << a->size);
82
+
83
+ /* Subsequent memory operations inherit alignment */
84
+ mop &= ~MO_AMASK;
85
}
86
tcg_temp_free_i32(addr);
87
tcg_temp_free_i32(tmp);
36
--
88
--
37
2.20.1
89
2.20.1
38
90
39
91
diff view generated by jsdifflib
1
Currently the code in v7m_push_stack() which detects a violation
1
From: Richard Henderson <richard.henderson@linaro.org>
2
of the v8M stack limit simply returns early if it does so. This
2
3
is OK for the current integer-only code, but won't work for the
3
In the case of gpr load, merge the size and is_signed arguments;
4
floating point handling we're about to add. We need to continue
4
otherwise, simply convert size to memop.
5
executing the rest of the function so that we check for other
5
6
exceptions like not having permission to use the FPU and so
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
that we correctly set the FPCCR state if we are doing lazy
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
stacking. Refactor to avoid the early return.
8
Message-id: 20210419202257.161730-26-richard.henderson@linaro.org
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
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
---
10
---
14
target/arm/helper.c | 23 ++++++++++++++++++-----
11
target/arm/translate-a64.c | 78 ++++++++++++++++----------------------
15
1 file changed, 18 insertions(+), 5 deletions(-)
12
1 file changed, 33 insertions(+), 45 deletions(-)
16
13
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
16
--- a/target/arm/translate-a64.c
20
+++ b/target/arm/helper.c
17
+++ b/target/arm/translate-a64.c
21
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
18
@@ -XXX,XX +XXX,XX @@ static void gen_adc_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
22
* should ignore further stack faults trying to process
19
* Store from GPR register to memory.
23
* that derived exception.)
20
*/
24
*/
21
static void do_gpr_st_memidx(DisasContext *s, TCGv_i64 source,
25
- bool stacked_ok;
22
- TCGv_i64 tcg_addr, int size, int memidx,
26
+ bool stacked_ok = true, limitviol = false;
23
+ TCGv_i64 tcg_addr, MemOp memop, int memidx,
27
CPUARMState *env = &cpu->env;
24
bool iss_valid,
28
uint32_t xpsr = xpsr_read(env);
25
unsigned int iss_srt,
29
uint32_t frameptr = env->regs[13];
26
bool iss_sf, bool iss_ar)
30
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
27
{
31
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
28
- g_assert(size <= 3);
32
env->v7m.secure);
29
- tcg_gen_qemu_st_i64(source, tcg_addr, memidx, s->be_data + size);
33
env->regs[13] = limit;
30
+ memop = finalize_memop(s, memop);
34
- return true;
31
+ tcg_gen_qemu_st_i64(source, tcg_addr, memidx, memop);
35
+ /*
32
36
+ * We won't try to perform any further memory accesses but
33
if (iss_valid) {
37
+ * we must continue through the following code to check for
34
uint32_t syn;
38
+ * permission faults during FPU state preservation, and we
35
39
+ * must update FPCCR if lazy stacking is enabled.
36
syn = syn_data_abort_with_iss(0,
40
+ */
37
- size,
41
+ limitviol = true;
38
+ (memop & MO_SIZE),
42
+ stacked_ok = false;
39
false,
43
}
40
iss_srt,
44
}
41
iss_sf,
45
42
@@ -XXX,XX +XXX,XX @@ static void do_gpr_st_memidx(DisasContext *s, TCGv_i64 source,
46
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
43
}
47
* (which may be taken in preference to the one we started with
44
48
* if it has higher priority).
45
static void do_gpr_st(DisasContext *s, TCGv_i64 source,
49
*/
46
- TCGv_i64 tcg_addr, int size,
50
- stacked_ok =
47
+ TCGv_i64 tcg_addr, MemOp memop,
51
+ stacked_ok = stacked_ok &&
48
bool iss_valid,
52
v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, false) &&
49
unsigned int iss_srt,
53
v7m_stack_write(cpu, frameptr + 4, env->regs[1], mmu_idx, false) &&
50
bool iss_sf, bool iss_ar)
54
v7m_stack_write(cpu, frameptr + 8, env->regs[2], mmu_idx, false) &&
51
{
55
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
52
- do_gpr_st_memidx(s, source, tcg_addr, size, get_mem_index(s),
56
v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
53
+ do_gpr_st_memidx(s, source, tcg_addr, memop, get_mem_index(s),
57
v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
54
iss_valid, iss_srt, iss_sf, iss_ar);
58
55
}
59
- /* Update SP regardless of whether any of the stack accesses failed. */
56
60
- env->regs[13] = frameptr;
57
/*
61
+ /*
58
* Load from memory to GPR register
62
+ * If we broke a stack limit then SP was already updated earlier;
59
*/
63
+ * otherwise we update SP regardless of whether any of the stack
60
-static void do_gpr_ld_memidx(DisasContext *s,
64
+ * accesses failed or we took some other kind of fault.
61
- TCGv_i64 dest, TCGv_i64 tcg_addr,
65
+ */
62
- int size, bool is_signed,
66
+ if (!limitviol) {
63
- bool extend, int memidx,
67
+ env->regs[13] = frameptr;
64
+static void do_gpr_ld_memidx(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
68
+ }
65
+ MemOp memop, bool extend, int memidx,
69
66
bool iss_valid, unsigned int iss_srt,
70
return !stacked_ok;
67
bool iss_sf, bool iss_ar)
68
{
69
- MemOp memop = s->be_data + size;
70
-
71
- g_assert(size <= 3);
72
-
73
- if (is_signed) {
74
- memop += MO_SIGN;
75
- }
76
-
77
+ memop = finalize_memop(s, memop);
78
tcg_gen_qemu_ld_i64(dest, tcg_addr, memidx, memop);
79
80
- if (extend && is_signed) {
81
- g_assert(size < 3);
82
+ if (extend && (memop & MO_SIGN)) {
83
+ g_assert((memop & MO_SIZE) <= MO_32);
84
tcg_gen_ext32u_i64(dest, dest);
85
}
86
87
@@ -XXX,XX +XXX,XX @@ static void do_gpr_ld_memidx(DisasContext *s,
88
uint32_t syn;
89
90
syn = syn_data_abort_with_iss(0,
91
- size,
92
- is_signed,
93
+ (memop & MO_SIZE),
94
+ (memop & MO_SIGN) != 0,
95
iss_srt,
96
iss_sf,
97
iss_ar,
98
@@ -XXX,XX +XXX,XX @@ static void do_gpr_ld_memidx(DisasContext *s,
99
}
100
}
101
102
-static void do_gpr_ld(DisasContext *s,
103
- TCGv_i64 dest, TCGv_i64 tcg_addr,
104
- int size, bool is_signed, bool extend,
105
+static void do_gpr_ld(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
106
+ MemOp memop, bool extend,
107
bool iss_valid, unsigned int iss_srt,
108
bool iss_sf, bool iss_ar)
109
{
110
- do_gpr_ld_memidx(s, dest, tcg_addr, size, is_signed, extend,
111
- get_mem_index(s),
112
+ do_gpr_ld_memidx(s, dest, tcg_addr, memop, extend, get_mem_index(s),
113
iss_valid, iss_srt, iss_sf, iss_ar);
114
}
115
116
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
117
}
118
clean_addr = gen_mte_check1(s, cpu_reg_sp(s, rn),
119
false, rn != 31, size);
120
- do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, false, false, true, rt,
121
+ do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, false, true, rt,
122
disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
123
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
124
return;
125
@@ -XXX,XX +XXX,XX @@ static void disas_ld_lit(DisasContext *s, uint32_t insn)
126
/* Only unsigned 32bit loads target 32bit registers. */
127
bool iss_sf = opc != 0;
128
129
- do_gpr_ld(s, tcg_rt, clean_addr, size, is_signed, false,
130
- true, rt, iss_sf, false);
131
+ do_gpr_ld(s, tcg_rt, clean_addr, size + is_signed * MO_SIGN,
132
+ false, true, rt, iss_sf, false);
133
}
134
tcg_temp_free_i64(clean_addr);
135
}
136
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn)
137
/* Do not modify tcg_rt before recognizing any exception
138
* from the second load.
139
*/
140
- do_gpr_ld(s, tmp, clean_addr, size, is_signed, false,
141
- false, 0, false, false);
142
+ do_gpr_ld(s, tmp, clean_addr, size + is_signed * MO_SIGN,
143
+ false, false, 0, false, false);
144
tcg_gen_addi_i64(clean_addr, clean_addr, 1 << size);
145
- do_gpr_ld(s, tcg_rt2, clean_addr, size, is_signed, false,
146
- false, 0, false, false);
147
+ do_gpr_ld(s, tcg_rt2, clean_addr, size + is_signed * MO_SIGN,
148
+ false, false, 0, false, false);
149
150
tcg_gen_mov_i64(tcg_rt, tmp);
151
tcg_temp_free_i64(tmp);
152
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn,
153
do_gpr_st_memidx(s, tcg_rt, clean_addr, size, memidx,
154
iss_valid, rt, iss_sf, false);
155
} else {
156
- do_gpr_ld_memidx(s, tcg_rt, clean_addr, size,
157
- is_signed, is_extended, memidx,
158
+ do_gpr_ld_memidx(s, tcg_rt, clean_addr, size + is_signed * MO_SIGN,
159
+ is_extended, memidx,
160
iss_valid, rt, iss_sf, false);
161
}
162
}
163
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_roffset(DisasContext *s, uint32_t insn,
164
do_gpr_st(s, tcg_rt, clean_addr, size,
165
true, rt, iss_sf, false);
166
} else {
167
- do_gpr_ld(s, tcg_rt, clean_addr, size,
168
- is_signed, is_extended,
169
- true, rt, iss_sf, false);
170
+ do_gpr_ld(s, tcg_rt, clean_addr, size + is_signed * MO_SIGN,
171
+ is_extended, true, rt, iss_sf, false);
172
}
173
}
174
}
175
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn,
176
do_gpr_st(s, tcg_rt, clean_addr, size,
177
true, rt, iss_sf, false);
178
} else {
179
- do_gpr_ld(s, tcg_rt, clean_addr, size, is_signed, is_extended,
180
- true, rt, iss_sf, false);
181
+ do_gpr_ld(s, tcg_rt, clean_addr, size + is_signed * MO_SIGN,
182
+ is_extended, true, rt, iss_sf, false);
183
}
184
}
185
}
186
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
187
* full load-acquire (we only need "load-acquire processor consistent"),
188
* but we choose to implement them as full LDAQ.
189
*/
190
- do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, false, false,
191
+ do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, false,
192
true, rt, disas_ldst_compute_iss_sf(size, false, 0), true);
193
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
194
return;
195
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_pac(DisasContext *s, uint32_t insn,
196
is_wback || rn != 31, size);
197
198
tcg_rt = cpu_reg(s, rt);
199
- do_gpr_ld(s, tcg_rt, clean_addr, size, /* is_signed */ false,
200
+ do_gpr_ld(s, tcg_rt, clean_addr, size,
201
/* extend */ false, /* iss_valid */ !is_wback,
202
/* iss_srt */ rt, /* iss_sf */ true, /* iss_ar */ false);
203
204
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_ldapr_stlr(DisasContext *s, uint32_t insn)
205
* Load-AcquirePC semantics; we implement as the slightly more
206
* restrictive Load-Acquire.
207
*/
208
- do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, is_signed, extend,
209
- true, rt, iss_sf, true);
210
+ do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size + is_signed * MO_SIGN,
211
+ extend, true, rt, iss_sf, true);
212
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
213
}
71
}
214
}
72
--
215
--
73
2.20.1
216
2.20.1
74
217
75
218
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
For 128-bit load/store, use 16-byte alignment. This
4
Reviewed-by: Cédric Le Goater <clg@kaod.org>
4
requires that we perform the two operations in the
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
correct order so that we generate the alignment fault
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
before modifying memory.
7
Message-id: 20190412165416.7977-2-philmd@redhat.com
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210419202257.161730-27-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
12
---
10
hw/arm/aspeed.c | 13 +++++++++----
13
target/arm/translate-a64.c | 42 +++++++++++++++++++++++---------------
11
1 file changed, 9 insertions(+), 4 deletions(-)
14
1 file changed, 26 insertions(+), 16 deletions(-)
12
15
13
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
16
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/aspeed.c
18
--- a/target/arm/translate-a64.c
16
+++ b/hw/arm/aspeed.c
19
+++ b/target/arm/translate-a64.c
17
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static void do_gpr_ld(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
18
#include "hw/arm/aspeed_soc.h"
21
static void do_fp_st(DisasContext *s, int srcidx, TCGv_i64 tcg_addr, int size)
19
#include "hw/boards.h"
22
{
20
#include "hw/i2c/smbus_eeprom.h"
23
/* This writes the bottom N bits of a 128 bit wide vector to memory */
21
+#include "hw/misc/pca9552.h"
24
- TCGv_i64 tmp = tcg_temp_new_i64();
22
+#include "hw/misc/tmp105.h"
25
- tcg_gen_ld_i64(tmp, cpu_env, fp_reg_offset(s, srcidx, MO_64));
23
#include "qemu/log.h"
26
+ TCGv_i64 tmplo = tcg_temp_new_i64();
24
#include "sysemu/block-backend.h"
27
+ MemOp mop;
25
#include "hw/loader.h"
28
+
26
@@ -XXX,XX +XXX,XX @@ static void ast2500_evb_i2c_init(AspeedBoardState *bmc)
29
+ tcg_gen_ld_i64(tmplo, cpu_env, fp_reg_offset(s, srcidx, MO_64));
27
eeprom_buf);
30
+
28
31
if (size < 4) {
29
/* The AST2500 EVB expects a LM75 but a TMP105 is compatible */
32
- tcg_gen_qemu_st_i64(tmp, tcg_addr, get_mem_index(s),
30
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7), "tmp105", 0x4d);
33
- s->be_data + size);
31
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7),
34
+ mop = finalize_memop(s, size);
32
+ TYPE_TMP105, 0x4d);
35
+ tcg_gen_qemu_st_i64(tmplo, tcg_addr, get_mem_index(s), mop);
33
36
} else {
34
/* The AST2500 EVB does not have an RTC. Let's pretend that one is
37
bool be = s->be_data == MO_BE;
35
* plugged on the I2C bus header */
38
TCGv_i64 tcg_hiaddr = tcg_temp_new_i64();
36
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
39
+ TCGv_i64 tmphi = tcg_temp_new_i64();
37
AspeedSoCState *soc = &bmc->soc;
40
38
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
41
+ tcg_gen_ld_i64(tmphi, cpu_env, fp_reg_hi_offset(s, srcidx));
39
42
+
40
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), "pca9552", 0x60);
43
+ mop = s->be_data | MO_Q;
41
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), TYPE_PCA9552,
44
+ tcg_gen_qemu_st_i64(be ? tmphi : tmplo, tcg_addr, get_mem_index(s),
42
+ 0x60);
45
+ mop | (s->align_mem ? MO_ALIGN_16 : 0));
43
46
tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8);
44
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), "tmp423", 0x4c);
47
- tcg_gen_qemu_st_i64(tmp, be ? tcg_hiaddr : tcg_addr, get_mem_index(s),
45
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 5), "tmp423", 0x4c);
48
- s->be_data | MO_Q);
46
49
- tcg_gen_ld_i64(tmp, cpu_env, fp_reg_hi_offset(s, srcidx));
47
/* The Witherspoon expects a TMP275 but a TMP105 is compatible */
50
- tcg_gen_qemu_st_i64(tmp, be ? tcg_addr : tcg_hiaddr, get_mem_index(s),
48
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), "tmp105", 0x4a);
51
- s->be_data | MO_Q);
49
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), TYPE_TMP105,
52
+ tcg_gen_qemu_st_i64(be ? tmplo : tmphi, tcg_hiaddr,
50
+ 0x4a);
53
+ get_mem_index(s), mop);
51
54
+
52
/* The witherspoon board expects Epson RX8900 I2C RTC but a ds1338 is
55
tcg_temp_free_i64(tcg_hiaddr);
53
* good enough */
56
+ tcg_temp_free_i64(tmphi);
54
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
57
}
55
58
56
smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), 0x51,
59
- tcg_temp_free_i64(tmp);
57
eeprom_buf);
60
+ tcg_temp_free_i64(tmplo);
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);
61
}
61
}
62
63
/*
64
@@ -XXX,XX +XXX,XX @@ static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size)
65
/* This always zero-extends and writes to a full 128 bit wide vector */
66
TCGv_i64 tmplo = tcg_temp_new_i64();
67
TCGv_i64 tmphi = NULL;
68
+ MemOp mop;
69
70
if (size < 4) {
71
- MemOp memop = s->be_data + size;
72
- tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), memop);
73
+ mop = finalize_memop(s, size);
74
+ tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), mop);
75
} else {
76
bool be = s->be_data == MO_BE;
77
TCGv_i64 tcg_hiaddr;
78
@@ -XXX,XX +XXX,XX @@ static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size)
79
tmphi = tcg_temp_new_i64();
80
tcg_hiaddr = tcg_temp_new_i64();
81
82
+ mop = s->be_data | MO_Q;
83
+ tcg_gen_qemu_ld_i64(be ? tmphi : tmplo, tcg_addr, get_mem_index(s),
84
+ mop | (s->align_mem ? MO_ALIGN_16 : 0));
85
tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8);
86
- tcg_gen_qemu_ld_i64(tmplo, be ? tcg_hiaddr : tcg_addr, get_mem_index(s),
87
- s->be_data | MO_Q);
88
- tcg_gen_qemu_ld_i64(tmphi, be ? tcg_addr : tcg_hiaddr, get_mem_index(s),
89
- s->be_data | MO_Q);
90
+ tcg_gen_qemu_ld_i64(be ? tmplo : tmphi, tcg_hiaddr,
91
+ get_mem_index(s), mop);
92
tcg_temp_free_i64(tcg_hiaddr);
93
}
62
94
63
--
95
--
64
2.20.1
96
2.20.1
65
97
66
98
diff view generated by jsdifflib
1
The M-profile CONTROL register has two bits -- SFPA and FPCA --
1
From: Richard Henderson <richard.henderson@linaro.org>
2
which relate to floating-point support, and should be RES0 otherwise.
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.
6
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-28-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-9-peter.maydell@linaro.org
10
---
7
---
11
target/arm/helper.c | 57 ++++++++++++++++++++++++++++++++++++++-------
8
target/arm/translate-a64.c | 23 ++++++++++++++---------
12
1 file changed, 49 insertions(+), 8 deletions(-)
9
1 file changed, 14 insertions(+), 9 deletions(-)
13
10
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
13
--- a/target/arm/translate-a64.c
17
+++ b/target/arm/helper.c
14
+++ b/target/arm/translate-a64.c
18
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
15
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
19
return xpsr_read(env) & mask;
16
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
20
break;
17
clean_addr = gen_mte_check1(s, cpu_reg_sp(s, rn),
21
case 20: /* CONTROL */
18
true, rn != 31, size);
22
- return env->v7m.control[env->v7m.secure];
19
- do_gpr_st(s, cpu_reg(s, rt), clean_addr, size, true, rt,
23
+ {
20
+ /* TODO: ARMv8.4-LSE SCTLR.nAA */
24
+ uint32_t value = env->v7m.control[env->v7m.secure];
21
+ do_gpr_st(s, cpu_reg(s, rt), clean_addr, size | MO_ALIGN, true, rt,
25
+ if (!env->v7m.secure) {
22
disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
26
+ /* SFPA is RAZ/WI from NS; FPCA is stored in the M_REG_S bank */
23
return;
27
+ value |= env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK;
24
28
+ }
25
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
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
}
26
}
38
- return env->v7m.control[M_REG_NS];
27
clean_addr = gen_mte_check1(s, cpu_reg_sp(s, rn),
39
+ return env->v7m.control[M_REG_NS] |
28
false, rn != 31, size);
40
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK);
29
- do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, false, true, rt,
41
}
30
- disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
42
31
+ /* TODO: ARMv8.4-LSE SCTLR.nAA */
43
if (el == 0) {
32
+ do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size | MO_ALIGN, false, true,
44
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
33
+ rt, disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
45
*/
34
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
46
uint32_t mask = extract32(maskreg, 8, 4);
35
return;
47
uint32_t reg = extract32(maskreg, 0, 8);
36
48
+ int cur_el = arm_current_el(env);
37
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_ldapr_stlr(DisasContext *s, uint32_t insn)
49
38
int size = extract32(insn, 30, 2);
50
- if (arm_current_el(env) == 0 && reg > 7) {
39
TCGv_i64 clean_addr, dirty_addr;
51
- /* only xPSR sub-fields may be written by unprivileged */
40
bool is_store = false;
52
+ if (cur_el == 0 && reg > 7 && reg != 20) {
41
- bool is_signed = false;
53
+ /*
42
bool extend = false;
54
+ * only xPSR sub-fields and CONTROL.SFPA may be written by
43
bool iss_sf;
55
+ * unprivileged code
44
+ MemOp mop;
56
+ */
45
46
if (!dc_isar_feature(aa64_rcpc_8_4, s)) {
47
unallocated_encoding(s);
57
return;
48
return;
58
}
49
}
59
50
60
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
51
+ /* TODO: ARMv8.4-LSE SCTLR.nAA */
61
env->v7m.control[M_REG_NS] &= ~R_V7M_CONTROL_NPRIV_MASK;
52
+ mop = size | MO_ALIGN;
62
env->v7m.control[M_REG_NS] |= val & R_V7M_CONTROL_NPRIV_MASK;
53
+
63
}
54
switch (opc) {
64
+ /*
55
case 0: /* STLURB */
65
+ * SFPA is RAZ/WI from NS. FPCA is RO if NSACR.CP10 == 0,
56
is_store = true;
66
+ * RES0 if the FPU is not present, and is stored in the S bank
57
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_ldapr_stlr(DisasContext *s, uint32_t insn)
67
+ */
58
unallocated_encoding(s);
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
+ }
73
return;
59
return;
74
case 0x98: /* SP_NS */
60
}
75
{
61
- is_signed = true;
76
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
62
+ mop |= MO_SIGN;
77
env->v7m.faultmask[env->v7m.secure] = val & 1;
78
break;
63
break;
79
case 20: /* CONTROL */
64
case 3: /* LDAPURS* 32-bit variant */
80
- /* Writing to the SPSEL bit only has an effect if we are in
65
if (size > 1) {
81
+ /*
66
unallocated_encoding(s);
82
+ * Writing to the SPSEL bit only has an effect if we are in
67
return;
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
}
68
}
97
- if (arm_feature(env, ARM_FEATURE_M_MAIN)) {
69
- is_signed = true;
98
+ if (cur_el > 0 && arm_feature(env, ARM_FEATURE_M_MAIN)) {
70
+ mop |= MO_SIGN;
99
env->v7m.control[env->v7m.secure] &= ~R_V7M_CONTROL_NPRIV_MASK;
71
extend = true; /* zero-extend 32->64 after signed load */
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;
72
break;
120
default:
73
default:
121
bad_reg:
74
g_assert_not_reached();
75
}
76
77
- iss_sf = disas_ldst_compute_iss_sf(size, is_signed, opc);
78
+ iss_sf = disas_ldst_compute_iss_sf(size, (mop & MO_SIGN) != 0, opc);
79
80
if (rn == 31) {
81
gen_check_sp_alignment(s);
82
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_ldapr_stlr(DisasContext *s, uint32_t insn)
83
if (is_store) {
84
/* Store-Release semantics */
85
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
86
- do_gpr_st(s, cpu_reg(s, rt), clean_addr, size, true, rt, iss_sf, true);
87
+ do_gpr_st(s, cpu_reg(s, rt), clean_addr, mop, true, rt, iss_sf, true);
88
} else {
89
/*
90
* Load-AcquirePC semantics; we implement as the slightly more
91
* restrictive Load-Acquire.
92
*/
93
- do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size + is_signed * MO_SIGN,
94
+ do_gpr_ld(s, cpu_reg(s, rt), clean_addr, mop,
95
extend, true, rt, iss_sf, true);
96
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
97
}
122
--
98
--
123
2.20.1
99
2.20.1
124
100
125
101
diff view generated by jsdifflib
1
Pushing registers to the stack for v7M needs to handle three cases:
1
From: Richard Henderson <richard.henderson@linaro.org>
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
2
9
Implement this by changing the existing flag argument that
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
tells us whether to ignore faults or not into an enum that
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
specifies which of the 3 modes we should handle.
5
Message-id: 20210419202257.161730-29-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate-a64.c | 20 ++++++++++----------
9
1 file changed, 10 insertions(+), 10 deletions(-)
12
10
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
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
12
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
13
--- a/target/arm/translate-a64.c
23
+++ b/target/arm/helper.c
14
+++ b/target/arm/translate-a64.c
24
@@ -XXX,XX +XXX,XX @@ static bool v7m_cpacr_pass(CPUARMState *env, bool is_secure, bool is_priv)
15
@@ -XXX,XX +XXX,XX @@ static void write_vec_element_i32(DisasContext *s, TCGv_i32 tcg_src,
25
}
16
17
/* Store from vector register to memory */
18
static void do_vec_st(DisasContext *s, int srcidx, int element,
19
- TCGv_i64 tcg_addr, int size, MemOp endian)
20
+ TCGv_i64 tcg_addr, MemOp mop)
21
{
22
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
23
24
- read_vec_element(s, tcg_tmp, srcidx, element, size);
25
- tcg_gen_qemu_st_i64(tcg_tmp, tcg_addr, get_mem_index(s), endian | size);
26
+ read_vec_element(s, tcg_tmp, srcidx, element, mop & MO_SIZE);
27
+ tcg_gen_qemu_st_i64(tcg_tmp, tcg_addr, get_mem_index(s), mop);
28
29
tcg_temp_free_i64(tcg_tmp);
26
}
30
}
27
31
28
+/*
32
/* Load from memory to vector register */
29
+ * What kind of stack write are we doing? This affects how exceptions
33
static void do_vec_ld(DisasContext *s, int destidx, int element,
30
+ * generated during the stacking are treated.
34
- TCGv_i64 tcg_addr, int size, MemOp endian)
31
+ */
35
+ TCGv_i64 tcg_addr, MemOp mop)
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
{
36
{
42
CPUState *cs = CPU(cpu);
37
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
43
CPUARMState *env = &cpu->env;
38
44
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
39
- tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr, get_mem_index(s), endian | size);
45
&attrs, &prot, &page_size, &fi, NULL)) {
40
- write_vec_element(s, tcg_tmp, destidx, element, size);
46
/* MPU/SAU lookup failed */
41
+ tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr, get_mem_index(s), mop);
47
if (fi.type == ARMFault_QEMU_SFault) {
42
+ write_vec_element(s, tcg_tmp, destidx, element, mop & MO_SIZE);
48
- qemu_log_mask(CPU_LOG_INT,
43
49
- "...SecureFault with SFSR.AUVIOL during stacking\n");
44
tcg_temp_free_i64(tcg_tmp);
50
- env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK | R_V7M_SFSR_SFARVALID_MASK;
45
}
51
+ if (mode == STACK_LAZYFP) {
46
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
52
+ qemu_log_mask(CPU_LOG_INT,
47
for (xs = 0; xs < selem; xs++) {
53
+ "...SecureFault with SFSR.LSPERR "
48
int tt = (rt + r + xs) % 32;
54
+ "during lazy stacking\n");
49
if (is_store) {
55
+ env->v7m.sfsr |= R_V7M_SFSR_LSPERR_MASK;
50
- do_vec_st(s, tt, e, clean_addr, size, endian);
56
+ } else {
51
+ do_vec_st(s, tt, e, clean_addr, size | endian);
57
+ qemu_log_mask(CPU_LOG_INT,
52
} else {
58
+ "...SecureFault with SFSR.AUVIOL "
53
- do_vec_ld(s, tt, e, clean_addr, size, endian);
59
+ "during stacking\n");
54
+ do_vec_ld(s, tt, e, clean_addr, size | endian);
60
+ env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK;
55
}
61
+ }
56
tcg_gen_add_i64(clean_addr, clean_addr, tcg_ebytes);
62
+ env->v7m.sfsr |= R_V7M_SFSR_SFARVALID_MASK;
57
}
63
env->v7m.sfar = addr;
58
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
64
exc = ARMV7M_EXCP_SECURE;
65
exc_secure = false;
66
} else {
59
} else {
67
- qemu_log_mask(CPU_LOG_INT, "...MemManageFault with CFSR.MSTKERR\n");
60
/* Load/store one element per register */
68
- env->v7m.cfsr[secure] |= R_V7M_CFSR_MSTKERR_MASK;
61
if (is_load) {
69
+ if (mode == STACK_LAZYFP) {
62
- do_vec_ld(s, rt, index, clean_addr, scale, s->be_data);
70
+ qemu_log_mask(CPU_LOG_INT,
63
+ do_vec_ld(s, rt, index, clean_addr, scale | s->be_data);
71
+ "...MemManageFault with CFSR.MLSPERR\n");
64
} else {
72
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MLSPERR_MASK;
65
- do_vec_st(s, rt, index, clean_addr, scale, s->be_data);
73
+ } else {
66
+ do_vec_st(s, rt, index, clean_addr, scale | s->be_data);
74
+ qemu_log_mask(CPU_LOG_INT,
67
}
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
}
68
}
81
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
69
tcg_gen_add_i64(clean_addr, clean_addr, tcg_ebytes);
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
--
70
--
209
2.20.1
71
2.20.1
210
72
211
73
diff view generated by jsdifflib
1
For M-profile the MVFR* ID registers are memory mapped, in the
1
From: Richard Henderson <richard.henderson@linaro.org>
2
range we implement via the NVIC. Allow them to be read.
3
(If the CPU has no FPU, these registers are defined to be RAZ.)
4
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-30-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190416125744.27770-3-peter.maydell@linaro.org
8
---
7
---
9
hw/intc/armv7m_nvic.c | 6 ++++++
8
target/arm/translate-a64.c | 15 +++++++++++----
10
1 file changed, 6 insertions(+)
9
1 file changed, 11 insertions(+), 4 deletions(-)
11
10
12
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
13
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/intc/armv7m_nvic.c
13
--- a/target/arm/translate-a64.c
15
+++ b/hw/intc/armv7m_nvic.c
14
+++ b/target/arm/translate-a64.c
16
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
15
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
17
return 0;
16
bool is_postidx = extract32(insn, 23, 1);
18
}
17
bool is_q = extract32(insn, 30, 1);
19
return cpu->env.v7m.sfar;
18
TCGv_i64 clean_addr, tcg_rn, tcg_ebytes;
20
+ case 0xf40: /* MVFR0 */
19
- MemOp endian = s->be_data;
21
+ return cpu->isar.mvfr0;
20
+ MemOp endian, align, mop;
22
+ case 0xf44: /* MVFR1 */
21
23
+ return cpu->isar.mvfr1;
22
int total; /* total bytes */
24
+ case 0xf48: /* MVFR2 */
23
int elements; /* elements per vector */
25
+ return cpu->isar.mvfr2;
24
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
26
default:
25
}
27
bad_offset:
26
28
qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
27
/* For our purposes, bytes are always little-endian. */
28
+ endian = s->be_data;
29
if (size == 0) {
30
endian = MO_LE;
31
}
32
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
33
* Consecutive little-endian elements from a single register
34
* can be promoted to a larger little-endian operation.
35
*/
36
+ align = MO_ALIGN;
37
if (selem == 1 && endian == MO_LE) {
38
+ align = pow2_align(size);
39
size = 3;
40
}
41
- elements = (is_q ? 16 : 8) >> size;
42
+ if (!s->align_mem) {
43
+ align = 0;
44
+ }
45
+ mop = endian | size | align;
46
47
+ elements = (is_q ? 16 : 8) >> size;
48
tcg_ebytes = tcg_const_i64(1 << size);
49
for (r = 0; r < rpt; r++) {
50
int e;
51
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
52
for (xs = 0; xs < selem; xs++) {
53
int tt = (rt + r + xs) % 32;
54
if (is_store) {
55
- do_vec_st(s, tt, e, clean_addr, size | endian);
56
+ do_vec_st(s, tt, e, clean_addr, mop);
57
} else {
58
- do_vec_ld(s, tt, e, clean_addr, size | endian);
59
+ do_vec_ld(s, tt, e, clean_addr, mop);
60
}
61
tcg_gen_add_i64(clean_addr, clean_addr, tcg_ebytes);
62
}
29
--
63
--
30
2.20.1
64
2.20.1
31
65
32
66
diff view generated by jsdifflib
1
Normally configure identifies the source path by looking
1
From: Richard Henderson <richard.henderson@linaro.org>
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.
5
2
6
There isn't really an obvious use case for the --source-path
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
option, and in commit 927128222b0a91f56c13a in 2017 we
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
accidentally added some logic that looks at $source_path
5
Message-id: 20210419202257.161730-31-richard.henderson@linaro.org
9
before the command line option that overrides it has been
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
processed.
7
---
8
target/arm/translate-a64.c | 9 +++++----
9
1 file changed, 5 insertions(+), 4 deletions(-)
11
10
12
The fact that nobody complained suggests that there isn't
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
13
any use of this option and we aren't testing it either;
12
index XXXXXXX..XXXXXXX 100644
14
remove it. This allows us to move the "make $source_path
13
--- a/target/arm/translate-a64.c
15
absolute" logic up so that there is no window in the script
14
+++ b/target/arm/translate-a64.c
16
where $source_path is set but not yet absolute.
15
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
17
16
int index = is_q << 3 | S << 2 | size;
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
int xs, total;
19
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
18
TCGv_i64 clean_addr, tcg_rn, tcg_ebytes;
20
Message-id: 20190318134019.23729-1-peter.maydell@linaro.org
19
+ MemOp mop;
21
---
20
22
configure | 10 ++--------
21
if (extract32(insn, 31, 1)) {
23
1 file changed, 2 insertions(+), 8 deletions(-)
22
unallocated_encoding(s);
24
23
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
25
diff --git a/configure b/configure
24
26
index XXXXXXX..XXXXXXX 100755
25
clean_addr = gen_mte_checkN(s, tcg_rn, !is_load, is_postidx || rn != 31,
27
--- a/configure
26
total);
28
+++ b/configure
27
+ mop = finalize_memop(s, scale);
29
@@ -XXX,XX +XXX,XX @@ ld_has() {
28
30
29
tcg_ebytes = tcg_const_i64(1 << scale);
31
# default parameters
30
for (xs = 0; xs < selem; xs++) {
32
source_path=$(dirname "$0")
31
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
33
+# make source path absolute
32
/* Load and replicate to all elements */
34
+source_path=$(cd "$source_path"; pwd)
33
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
35
cpu=""
34
36
iasl="iasl"
35
- tcg_gen_qemu_ld_i64(tcg_tmp, clean_addr,
37
interp_prefix="/usr/gnemul/qemu-%M"
36
- get_mem_index(s), s->be_data + scale);
38
@@ -XXX,XX +XXX,XX @@ for opt do
37
+ tcg_gen_qemu_ld_i64(tcg_tmp, clean_addr, get_mem_index(s), mop);
39
;;
38
tcg_gen_gvec_dup_i64(scale, vec_full_reg_offset(s, rt),
40
--cxx=*) CXX="$optarg"
39
(is_q + 1) * 8, vec_full_reg_size(s),
41
;;
40
tcg_tmp);
42
- --source-path=*) source_path="$optarg"
41
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
43
- ;;
42
} else {
44
--cpu=*) cpu="$optarg"
43
/* Load/store one element per register */
45
;;
44
if (is_load) {
46
--extra-cflags=*) QEMU_CFLAGS="$QEMU_CFLAGS $optarg"
45
- do_vec_ld(s, rt, index, clean_addr, scale | s->be_data);
47
@@ -XXX,XX +XXX,XX @@ if test "$debug_info" = "yes"; then
46
+ do_vec_ld(s, rt, index, clean_addr, mop);
48
LDFLAGS="-g $LDFLAGS"
47
} else {
49
fi
48
- do_vec_st(s, rt, index, clean_addr, scale | s->be_data);
50
49
+ do_vec_st(s, rt, index, clean_addr, mop);
51
-# make source path absolute
50
}
52
-source_path=$(cd "$source_path"; pwd)
51
}
53
-
52
tcg_gen_add_i64(clean_addr, clean_addr, tcg_ebytes);
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
--
53
--
75
2.20.1
54
2.20.1
76
55
77
56
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
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>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-32-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
7
---
12
hw/dma/Makefile.objs | 2 +-
8
target/arm/translate-sve.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
9
1 file changed, 1 insertion(+), 1 deletion(-)
14
10
15
diff --git a/hw/dma/Makefile.objs b/hw/dma/Makefile.objs
11
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/dma/Makefile.objs
13
--- a/target/arm/translate-sve.c
18
+++ b/hw/dma/Makefile.objs
14
+++ b/target/arm/translate-sve.c
19
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zdma.o
15
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1R_zpri(DisasContext *s, arg_rpri_load *a)
20
16
clean_addr = gen_mte_check1(s, temp, false, true, msz);
21
obj-$(CONFIG_OMAP) += omap_dma.o soc_dma.o
17
22
obj-$(CONFIG_PXA2XX) += pxa2xx_dma.o
18
tcg_gen_qemu_ld_i64(temp, clean_addr, get_mem_index(s),
23
-obj-$(CONFIG_RASPI) += bcm2835_dma.o
19
- s->be_data | dtype_mop[a->dtype]);
24
+common-obj-$(CONFIG_RASPI) += bcm2835_dma.o
20
+ finalize_memop(s, dtype_mop[a->dtype]));
21
22
/* Broadcast to *all* elements. */
23
tcg_gen_gvec_dup_i64(esz, vec_full_reg_offset(s, a->rd),
25
--
24
--
26
2.20.1
25
2.20.1
27
26
28
27
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Cornelia Huck <cohuck@redhat.com>
2
2
3
Suggested-by: Markus Armbruster <armbru@redhat.com>
3
Add 6.1 machine types for arm/i440fx/q35/s390x/spapr.
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
5
Message-id: 20190412165416.7977-3-philmd@redhat.com
5
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
6
Acked-by: Greg Kurz <groug@kaod.org>
7
Message-id: 20210331111900.118274-1-cohuck@redhat.com
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
10
---
9
hw/arm/nseries.c | 3 ++-
11
include/hw/boards.h | 3 +++
10
1 file changed, 2 insertions(+), 1 deletion(-)
12
include/hw/i386/pc.h | 3 +++
11
13
hw/arm/virt.c | 7 ++++++-
12
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
14
hw/core/machine.c | 3 +++
13
index XXXXXXX..XXXXXXX 100644
15
hw/i386/pc.c | 3 +++
14
--- a/hw/arm/nseries.c
16
hw/i386/pc_piix.c | 14 +++++++++++++-
15
+++ b/hw/arm/nseries.c
17
hw/i386/pc_q35.c | 13 ++++++++++++-
18
hw/ppc/spapr.c | 17 ++++++++++++++---
19
hw/s390x/s390-virtio-ccw.c | 14 +++++++++++++-
20
9 files changed, 70 insertions(+), 7 deletions(-)
21
22
diff --git a/include/hw/boards.h b/include/hw/boards.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/boards.h
25
+++ b/include/hw/boards.h
26
@@ -XXX,XX +XXX,XX @@ struct MachineState {
27
} \
28
type_init(machine_initfn##_register_types)
29
30
+extern GlobalProperty hw_compat_6_0[];
31
+extern const size_t hw_compat_6_0_len;
32
+
33
extern GlobalProperty hw_compat_5_2[];
34
extern const size_t hw_compat_5_2_len;
35
36
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/include/hw/i386/pc.h
39
+++ b/include/hw/i386/pc.h
40
@@ -XXX,XX +XXX,XX @@ bool pc_system_ovmf_table_find(const char *entry, uint8_t **data,
41
void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
42
const CPUArchIdList *apic_ids, GArray *entry);
43
44
+extern GlobalProperty pc_compat_6_0[];
45
+extern const size_t pc_compat_6_0_len;
46
+
47
extern GlobalProperty pc_compat_5_2[];
48
extern const size_t pc_compat_5_2_len;
49
50
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/arm/virt.c
53
+++ b/hw/arm/virt.c
54
@@ -XXX,XX +XXX,XX @@ static void machvirt_machine_init(void)
55
}
56
type_init(machvirt_machine_init);
57
58
+static void virt_machine_6_1_options(MachineClass *mc)
59
+{
60
+}
61
+DEFINE_VIRT_MACHINE_AS_LATEST(6, 1)
62
+
63
static void virt_machine_6_0_options(MachineClass *mc)
64
{
65
}
66
-DEFINE_VIRT_MACHINE_AS_LATEST(6, 0)
67
+DEFINE_VIRT_MACHINE(6, 0)
68
69
static void virt_machine_5_2_options(MachineClass *mc)
70
{
71
diff --git a/hw/core/machine.c b/hw/core/machine.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/hw/core/machine.c
74
+++ b/hw/core/machine.c
16
@@ -XXX,XX +XXX,XX @@
75
@@ -XXX,XX +XXX,XX @@
17
#include "hw/boards.h"
76
#include "hw/virtio/virtio.h"
18
#include "hw/i2c/i2c.h"
77
#include "hw/virtio/virtio-pci.h"
19
#include "hw/devices.h"
78
20
+#include "hw/misc/tmp105.h"
79
+GlobalProperty hw_compat_6_0[] = {};
21
#include "hw/block/flash.h"
80
+const size_t hw_compat_6_0_len = G_N_ELEMENTS(hw_compat_6_0);
22
#include "hw/hw.h"
81
+
23
#include "hw/bt.h"
82
GlobalProperty hw_compat_5_2[] = {
24
@@ -XXX,XX +XXX,XX @@ static void n8x0_i2c_setup(struct n800_s *s)
83
{ "ICH9-LPC", "smm-compat", "on"},
25
qemu_register_powerdown_notifier(&n8x0_system_powerdown_notifier);
84
{ "PIIX4_PM", "smm-compat", "on"},
26
85
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
27
/* Attach a TMP105 PM chip (A0 wired to ground) */
86
index XXXXXXX..XXXXXXX 100644
28
- dev = i2c_create_slave(i2c, "tmp105", N8X0_TMP105_ADDR);
87
--- a/hw/i386/pc.c
29
+ dev = i2c_create_slave(i2c, TYPE_TMP105, N8X0_TMP105_ADDR);
88
+++ b/hw/i386/pc.c
30
qdev_connect_gpio_out(dev, 0, tmp_irq);
89
@@ -XXX,XX +XXX,XX @@
31
}
90
#include "trace.h"
32
91
#include CONFIG_DEVICES
92
93
+GlobalProperty pc_compat_6_0[] = {};
94
+const size_t pc_compat_6_0_len = G_N_ELEMENTS(pc_compat_6_0);
95
+
96
GlobalProperty pc_compat_5_2[] = {
97
{ "ICH9-LPC", "x-smi-cpu-hotunplug", "off" },
98
};
99
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/hw/i386/pc_piix.c
102
+++ b/hw/i386/pc_piix.c
103
@@ -XXX,XX +XXX,XX @@ static void pc_i440fx_machine_options(MachineClass *m)
104
machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE);
105
}
106
107
-static void pc_i440fx_6_0_machine_options(MachineClass *m)
108
+static void pc_i440fx_6_1_machine_options(MachineClass *m)
109
{
110
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
111
pc_i440fx_machine_options(m);
112
@@ -XXX,XX +XXX,XX @@ static void pc_i440fx_6_0_machine_options(MachineClass *m)
113
pcmc->default_cpu_version = 1;
114
}
115
116
+DEFINE_I440FX_MACHINE(v6_1, "pc-i440fx-6.1", NULL,
117
+ pc_i440fx_6_1_machine_options);
118
+
119
+static void pc_i440fx_6_0_machine_options(MachineClass *m)
120
+{
121
+ pc_i440fx_6_1_machine_options(m);
122
+ m->alias = NULL;
123
+ m->is_default = false;
124
+ compat_props_add(m->compat_props, hw_compat_6_0, hw_compat_6_0_len);
125
+ compat_props_add(m->compat_props, pc_compat_6_0, pc_compat_6_0_len);
126
+}
127
+
128
DEFINE_I440FX_MACHINE(v6_0, "pc-i440fx-6.0", NULL,
129
pc_i440fx_6_0_machine_options);
130
131
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/hw/i386/pc_q35.c
134
+++ b/hw/i386/pc_q35.c
135
@@ -XXX,XX +XXX,XX @@ static void pc_q35_machine_options(MachineClass *m)
136
m->max_cpus = 288;
137
}
138
139
-static void pc_q35_6_0_machine_options(MachineClass *m)
140
+static void pc_q35_6_1_machine_options(MachineClass *m)
141
{
142
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
143
pc_q35_machine_options(m);
144
@@ -XXX,XX +XXX,XX @@ static void pc_q35_6_0_machine_options(MachineClass *m)
145
pcmc->default_cpu_version = 1;
146
}
147
148
+DEFINE_Q35_MACHINE(v6_1, "pc-q35-6.1", NULL,
149
+ pc_q35_6_1_machine_options);
150
+
151
+static void pc_q35_6_0_machine_options(MachineClass *m)
152
+{
153
+ pc_q35_6_1_machine_options(m);
154
+ m->alias = NULL;
155
+ compat_props_add(m->compat_props, hw_compat_6_0, hw_compat_6_0_len);
156
+ compat_props_add(m->compat_props, pc_compat_6_0, pc_compat_6_0_len);
157
+}
158
+
159
DEFINE_Q35_MACHINE(v6_0, "pc-q35-6.0", NULL,
160
pc_q35_6_0_machine_options);
161
162
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
163
index XXXXXXX..XXXXXXX 100644
164
--- a/hw/ppc/spapr.c
165
+++ b/hw/ppc/spapr.c
166
@@ -XXX,XX +XXX,XX @@ static void spapr_machine_latest_class_options(MachineClass *mc)
167
type_init(spapr_machine_register_##suffix)
168
169
/*
170
- * pseries-6.0
171
+ * pseries-6.1
172
*/
173
-static void spapr_machine_6_0_class_options(MachineClass *mc)
174
+static void spapr_machine_6_1_class_options(MachineClass *mc)
175
{
176
/* Defaults for the latest behaviour inherited from the base class */
177
}
178
179
-DEFINE_SPAPR_MACHINE(6_0, "6.0", true);
180
+DEFINE_SPAPR_MACHINE(6_1, "6.1", true);
181
+
182
+/*
183
+ * pseries-6.0
184
+ */
185
+static void spapr_machine_6_0_class_options(MachineClass *mc)
186
+{
187
+ spapr_machine_6_1_class_options(mc);
188
+ compat_props_add(mc->compat_props, hw_compat_6_0, hw_compat_6_0_len);
189
+}
190
+
191
+DEFINE_SPAPR_MACHINE(6_0, "6.0", false);
192
193
/*
194
* pseries-5.2
195
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
196
index XXXXXXX..XXXXXXX 100644
197
--- a/hw/s390x/s390-virtio-ccw.c
198
+++ b/hw/s390x/s390-virtio-ccw.c
199
@@ -XXX,XX +XXX,XX @@ bool css_migration_enabled(void)
200
} \
201
type_init(ccw_machine_register_##suffix)
202
203
+static void ccw_machine_6_1_instance_options(MachineState *machine)
204
+{
205
+}
206
+
207
+static void ccw_machine_6_1_class_options(MachineClass *mc)
208
+{
209
+}
210
+DEFINE_CCW_MACHINE(6_1, "6.1", true);
211
+
212
static void ccw_machine_6_0_instance_options(MachineState *machine)
213
{
214
+ ccw_machine_6_1_instance_options(machine);
215
}
216
217
static void ccw_machine_6_0_class_options(MachineClass *mc)
218
{
219
+ ccw_machine_6_1_class_options(mc);
220
+ compat_props_add(mc->compat_props, hw_compat_6_0, hw_compat_6_0_len);
221
}
222
-DEFINE_CCW_MACHINE(6_0, "6.0", true);
223
+DEFINE_CCW_MACHINE(6_0, "6.0", false);
224
225
static void ccw_machine_5_2_instance_options(MachineState *machine)
226
{
33
--
227
--
34
2.20.1
228
2.20.1
35
229
36
230
diff view generated by jsdifflib
1
The TailChain() pseudocode specifies that a tail chaining
1
Currently the gpex PCI controller implements no special behaviour for
2
exception should sanitize the excReturn all-ones bits and
2
guest accesses to areas of the PIO and MMIO where it has not mapped
3
(if there is no FPU) the excReturn FType bits; we weren't
3
any PCI devices, which means that for Arm you end up with a CPU
4
doing this.
4
exception due to a data abort.
5
5
6
Most host OSes expect "like an x86 PC" behaviour, where bad accesses
7
like this return -1 for reads and ignore writes. In the interests of
8
not being surprising, make host CPU accesses to these windows behave
9
as -1/discard where there's no mapped PCI device.
10
11
The old behaviour generally didn't cause any problems, because
12
almost always the guest OS will map the PCI devices and then only
13
access where it has mapped them. One corner case where you will see
14
this kind of access is if Linux attempts to probe legacy ISA
15
devices via a PIO window access. So far the only case where we've
16
seen this has been via the syzkaller fuzzer.
17
18
Reported-by: Dmitry Vyukov <dvyukov@google.com>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-14-peter.maydell@linaro.org
21
Acked-by: Michael S. Tsirkin <mst@redhat.com>
22
Message-id: 20210325163315.27724-1-peter.maydell@linaro.org
23
Fixes: https://bugs.launchpad.net/qemu/+bug/1918917
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
25
---
10
target/arm/helper.c | 8 ++++++++
26
include/hw/pci-host/gpex.h | 4 +++
11
1 file changed, 8 insertions(+)
27
hw/core/machine.c | 4 ++-
28
hw/pci-host/gpex.c | 56 ++++++++++++++++++++++++++++++++++++--
29
3 files changed, 60 insertions(+), 4 deletions(-)
12
30
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
31
diff --git a/include/hw/pci-host/gpex.h b/include/hw/pci-host/gpex.h
14
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
33
--- a/include/hw/pci-host/gpex.h
16
+++ b/target/arm/helper.c
34
+++ b/include/hw/pci-host/gpex.h
17
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
35
@@ -XXX,XX +XXX,XX @@ struct GPEXHost {
18
qemu_log_mask(CPU_LOG_INT, "...taking pending %s exception %d\n",
36
19
targets_secure ? "secure" : "nonsecure", exc);
37
MemoryRegion io_ioport;
20
38
MemoryRegion io_mmio;
21
+ if (dotailchain) {
39
+ MemoryRegion io_ioport_window;
22
+ /* Sanitize LR FType and PREFIX bits */
40
+ MemoryRegion io_mmio_window;
23
+ if (!arm_feature(env, ARM_FEATURE_VFP)) {
41
qemu_irq irq[GPEX_NUM_IRQS];
24
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
42
int irq_num[GPEX_NUM_IRQS];
25
+ }
43
+
26
+ lr = deposit32(lr, 24, 8, 0xff);
44
+ bool allow_unmapped_accesses;
45
};
46
47
struct GPEXConfig {
48
diff --git a/hw/core/machine.c b/hw/core/machine.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/core/machine.c
51
+++ b/hw/core/machine.c
52
@@ -XXX,XX +XXX,XX @@
53
#include "hw/virtio/virtio.h"
54
#include "hw/virtio/virtio-pci.h"
55
56
-GlobalProperty hw_compat_6_0[] = {};
57
+GlobalProperty hw_compat_6_0[] = {
58
+ { "gpex-pcihost", "allow-unmapped-accesses", "false" },
59
+};
60
const size_t hw_compat_6_0_len = G_N_ELEMENTS(hw_compat_6_0);
61
62
GlobalProperty hw_compat_5_2[] = {
63
diff --git a/hw/pci-host/gpex.c b/hw/pci-host/gpex.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/pci-host/gpex.c
66
+++ b/hw/pci-host/gpex.c
67
@@ -XXX,XX +XXX,XX @@ static void gpex_host_realize(DeviceState *dev, Error **errp)
68
int i;
69
70
pcie_host_mmcfg_init(pex, PCIE_MMCFG_SIZE_MAX);
71
+ sysbus_init_mmio(sbd, &pex->mmio);
72
+
73
+ /*
74
+ * Note that the MemoryRegions io_mmio and io_ioport that we pass
75
+ * to pci_register_root_bus() are not the same as the
76
+ * MemoryRegions io_mmio_window and io_ioport_window that we
77
+ * expose as SysBus MRs. The difference is in the behaviour of
78
+ * accesses to addresses where no PCI device has been mapped.
79
+ *
80
+ * io_mmio and io_ioport are the underlying PCI view of the PCI
81
+ * address space, and when a PCI device does a bus master access
82
+ * to a bad address this is reported back to it as a transaction
83
+ * failure.
84
+ *
85
+ * io_mmio_window and io_ioport_window implement "unmapped
86
+ * addresses read as -1 and ignore writes"; this is traditional
87
+ * x86 PC behaviour, which is not mandated by the PCI spec proper
88
+ * but expected by much PCI-using guest software, including Linux.
89
+ *
90
+ * In the interests of not being unnecessarily surprising, we
91
+ * implement it in the gpex PCI host controller, by providing the
92
+ * _window MRs, which are containers with io ops that implement
93
+ * the 'background' behaviour and which hold the real PCI MRs as
94
+ * subregions.
95
+ */
96
memory_region_init(&s->io_mmio, OBJECT(s), "gpex_mmio", UINT64_MAX);
97
memory_region_init(&s->io_ioport, OBJECT(s), "gpex_ioport", 64 * 1024);
98
99
- sysbus_init_mmio(sbd, &pex->mmio);
100
- sysbus_init_mmio(sbd, &s->io_mmio);
101
- sysbus_init_mmio(sbd, &s->io_ioport);
102
+ if (s->allow_unmapped_accesses) {
103
+ memory_region_init_io(&s->io_mmio_window, OBJECT(s),
104
+ &unassigned_io_ops, OBJECT(s),
105
+ "gpex_mmio_window", UINT64_MAX);
106
+ memory_region_init_io(&s->io_ioport_window, OBJECT(s),
107
+ &unassigned_io_ops, OBJECT(s),
108
+ "gpex_ioport_window", 64 * 1024);
109
+
110
+ memory_region_add_subregion(&s->io_mmio_window, 0, &s->io_mmio);
111
+ memory_region_add_subregion(&s->io_ioport_window, 0, &s->io_ioport);
112
+ sysbus_init_mmio(sbd, &s->io_mmio_window);
113
+ sysbus_init_mmio(sbd, &s->io_ioport_window);
114
+ } else {
115
+ sysbus_init_mmio(sbd, &s->io_mmio);
116
+ sysbus_init_mmio(sbd, &s->io_ioport);
27
+ }
117
+ }
28
+
118
+
29
if (arm_feature(env, ARM_FEATURE_V8)) {
119
for (i = 0; i < GPEX_NUM_IRQS; i++) {
30
if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
120
sysbus_init_irq(sbd, &s->irq[i]);
31
(lr & R_V7M_EXCRET_S_MASK)) {
121
s->irq_num[i] = -1;
122
@@ -XXX,XX +XXX,XX @@ static const char *gpex_host_root_bus_path(PCIHostState *host_bridge,
123
return "0000:00";
124
}
125
126
+static Property gpex_host_properties[] = {
127
+ /*
128
+ * Permit CPU accesses to unmapped areas of the PIO and MMIO windows
129
+ * (discarding writes and returning -1 for reads) rather than aborting.
130
+ */
131
+ DEFINE_PROP_BOOL("allow-unmapped-accesses", GPEXHost,
132
+ allow_unmapped_accesses, true),
133
+ DEFINE_PROP_END_OF_LIST(),
134
+};
135
+
136
static void gpex_host_class_init(ObjectClass *klass, void *data)
137
{
138
DeviceClass *dc = DEVICE_CLASS(klass);
139
@@ -XXX,XX +XXX,XX @@ static void gpex_host_class_init(ObjectClass *klass, void *data)
140
dc->realize = gpex_host_realize;
141
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
142
dc->fw_name = "pci";
143
+ device_class_set_props(dc, gpex_host_properties);
144
}
145
146
static void gpex_host_initfn(Object *obj)
32
--
147
--
33
2.20.1
148
2.20.1
34
149
35
150
diff view generated by jsdifflib