1
target-arm queue; this one has a fair scattering of more
1
First pullreq for arm of the 4.1 series, since I'm back from
2
miscellaneous things in it which I've sent out this week.
2
holiday now. This is mostly my M-profile FPU series and Philippe's
3
I've shoved those in as well as it seemed the least-effort
3
devices.h cleanup. I have a pile of other patchsets to work through
4
way of getting them into master; a few of them are dependencies
4
in my to-review folder, but 42 patches is definitely quite
5
on arm-related patches I have brewing.
5
big enough to send now...
6
6
7
thanks
7
thanks
8
-- PMM
8
-- PMM
9
9
10
The following changes since commit 413a99a92c13ec408dcf2adaa87918dc81e890c8:
10
11
11
The following changes since commit 2702c2d3eb74e3908c0c5dbf3a71c8987595a86e:
12
Add Nios II semihosting support. (2019-04-29 16:09:51 +0100)
12
13
Merge remote-tracking branch 'remotes/stsquad/tags/pull-travis-updates-140618-1' into staging (2018-06-15 12:49:36 +0100)
14
13
15
are available in the Git repository at:
14
are available in the Git repository at:
16
15
17
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180615
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190429
18
17
19
for you to fetch changes up to 14120108f87b3f9e1beacdf0a6096e464e62bb65:
18
for you to fetch changes up to 437cc27ddfded3bbab6afd5ac1761e0e195edba7:
20
19
21
target/arm: Allow ARMv6-M Thumb2 instructions (2018-06-15 15:23:34 +0100)
20
hw/devices: Move SMSC 91C111 declaration into a new header (2019-04-29 17:57:21 +0100)
22
21
23
----------------------------------------------------------------
22
----------------------------------------------------------------
24
target-arm and miscellaneous queue:
23
target-arm queue:
25
* fix KVM state save/restore for GICv3 priority registers for high IRQ numbers
24
* remove "bag of random stuff" hw/devices.h header
26
* hw/arm/mps2-tz: Put ethernet controller behind PPC
25
* implement FPU for Cortex-M and enable it for Cortex-M4 and -M33
27
* hw/sh/sh7750: Convert away from old_mmio
26
* hw/dma: Compile the bcm2835_dma device as common object
28
* hw/m68k/mcf5206: Convert away from old_mmio
27
* configure: Remove --source-path option
29
* hw/block/pflash_cfi02: Convert away from old_mmio
28
* hw/ssi/xilinx_spips: Avoid variable length array
30
* hw/watchdog/wdt_i6300esb: Convert away from old_mmio
29
* hw/arm/smmuv3: Remove SMMUNotifierNode
31
* hw/input/pckbd: Convert away from old_mmio
32
* hw/char/parallel: Convert away from old_mmio
33
* armv7m: refactor to get rid of armv7m_init() function
34
* arm: Don't crash if user tries to use a Cortex-M CPU without an NVIC
35
* hw/core/or-irq: Support more than 16 inputs to an OR gate
36
* cpu-defs.h: Document CPUIOTLBEntry 'addr' field
37
* cputlb: Pass cpu_transaction_failed() the correct physaddr
38
* CODING_STYLE: Define our preferred form for multiline comments
39
* Add and use new stn_*_p() and ldn_*_p() memory access functions
40
* target/arm: More parts of the upcoming SVE support
41
* aspeed_scu: Implement RNG register
42
* m25p80: add support for two bytes WRSR for Macronix chips
43
* exec.c: Handle IOMMUs being in the path of TCG CPU memory accesses
44
* target/arm: Allow ARMv6-M Thumb2 instructions
45
30
46
----------------------------------------------------------------
31
----------------------------------------------------------------
47
Cédric Le Goater (1):
32
Eric Auger (1):
48
m25p80: add support for two bytes WRSR for Macronix chips
33
hw/arm/smmuv3: Remove SMMUNotifierNode
49
34
50
Joel Stanley (1):
35
Peter Maydell (28):
51
aspeed_scu: Implement RNG register
36
hw/ssi/xilinx_spips: Avoid variable length array
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
52
64
53
Julia Suvorova (1):
65
Philippe Mathieu-Daudé (13):
54
target/arm: Allow ARMv6-M Thumb2 instructions
66
hw/dma: Compile the bcm2835_dma device as common object
67
hw/arm/aspeed: Use TYPE_TMP105/TYPE_PCA9552 instead of hardcoded string
68
hw/arm/nseries: Use TYPE_TMP105 instead of hardcoded string
69
hw/display/tc6393xb: Remove unused functions
70
hw/devices: Move TC6393XB declarations into a new header
71
hw/devices: Move Blizzard declarations into a new header
72
hw/devices: Move CBus declarations into a new header
73
hw/devices: Move Gamepad declarations into a new header
74
hw/devices: Move TI touchscreen declarations into a new header
75
hw/devices: Move LAN9118 declarations into a new header
76
hw/net/ne2000-isa: Add guards to the header
77
hw/net/lan9118: Export TYPE_LAN9118 and use it instead of hardcoded string
78
hw/devices: Move SMSC 91C111 declaration into a new header
55
79
56
Peter Maydell (21):
80
configure | 10 +-
57
hw/arm/mps2-tz: Put ethernet controller behind PPC
81
hw/dma/Makefile.objs | 2 +-
58
hw/sh/sh7750: Convert away from old_mmio
82
include/hw/arm/omap.h | 6 +-
59
hw/m68k/mcf5206: Convert away from old_mmio
83
include/hw/arm/smmu-common.h | 8 +-
60
hw/block/pflash_cfi02: Convert away from old_mmio
84
include/hw/devices.h | 62 ---
61
hw/watchdog/wdt_i6300esb: Convert away from old_mmio
85
include/hw/display/blizzard.h | 22 ++
62
hw/input/pckbd: Convert away from old_mmio
86
include/hw/display/tc6393xb.h | 24 ++
63
hw/char/parallel: Convert away from old_mmio
87
include/hw/input/gamepad.h | 19 +
64
stellaris: Stop using armv7m_init()
88
include/hw/input/tsc2xxx.h | 36 ++
65
hw/arm/armv7m: Remove unused armv7m_init() function
89
include/hw/misc/cbus.h | 32 ++
66
arm: Don't crash if user tries to use a Cortex-M CPU without an NVIC
90
include/hw/net/lan9118.h | 21 +
67
hw/core/or-irq: Support more than 16 inputs to an OR gate
91
include/hw/net/ne2000-isa.h | 6 +
68
cpu-defs.h: Document CPUIOTLBEntry 'addr' field
92
include/hw/net/smc91c111.h | 19 +
69
cputlb: Pass cpu_transaction_failed() the correct physaddr
93
include/qemu/typedefs.h | 1 -
70
CODING_STYLE: Define our preferred form for multiline comments
94
target/arm/cpu.h | 95 ++++-
71
bswap: Add new stn_*_p() and ldn_*_p() memory access functions
95
target/arm/helper.h | 5 +
72
exec.c: Don't accidentally sign-extend 4-byte loads in subpage_read()
96
target/arm/translate.h | 3 +
73
exec.c: Use stn_p() and ldn_p() instead of explicit switches
97
hw/arm/aspeed.c | 13 +-
74
iommu: Add IOMMU index concept to IOMMU API
98
hw/arm/exynos4_boards.c | 3 +-
75
iommu: Add IOMMU index argument to notifier APIs
99
hw/arm/gumstix.c | 2 +-
76
iommu: Add IOMMU index argument to translate method
100
hw/arm/integratorcp.c | 2 +-
77
exec.c: Handle IOMMUs in address_space_translate_for_iotlb()
101
hw/arm/kzm.c | 2 +-
102
hw/arm/mainstone.c | 2 +-
103
hw/arm/mps2-tz.c | 3 +-
104
hw/arm/mps2.c | 2 +-
105
hw/arm/nseries.c | 7 +-
106
hw/arm/palm.c | 2 +-
107
hw/arm/realview.c | 3 +-
108
hw/arm/smmu-common.c | 6 +-
109
hw/arm/smmuv3.c | 28 +-
110
hw/arm/stellaris.c | 2 +-
111
hw/arm/tosa.c | 2 +-
112
hw/arm/versatilepb.c | 2 +-
113
hw/arm/vexpress.c | 2 +-
114
hw/display/blizzard.c | 2 +-
115
hw/display/tc6393xb.c | 18 +-
116
hw/input/stellaris_input.c | 2 +-
117
hw/input/tsc2005.c | 2 +-
118
hw/input/tsc210x.c | 4 +-
119
hw/intc/armv7m_nvic.c | 261 +++++++++++++
120
hw/misc/cbus.c | 2 +-
121
hw/net/lan9118.c | 3 +-
122
hw/net/smc91c111.c | 2 +-
123
hw/ssi/xilinx_spips.c | 6 +-
124
target/arm/cpu.c | 20 +
125
target/arm/helper.c | 873 +++++++++++++++++++++++++++++++++++++++---
126
target/arm/machine.c | 16 +
127
target/arm/translate.c | 150 +++++++-
128
target/arm/vfp_helper.c | 8 +
129
MAINTAINERS | 7 +
130
50 files changed, 1595 insertions(+), 235 deletions(-)
131
delete mode 100644 include/hw/devices.h
132
create mode 100644 include/hw/display/blizzard.h
133
create mode 100644 include/hw/display/tc6393xb.h
134
create mode 100644 include/hw/input/gamepad.h
135
create mode 100644 include/hw/input/tsc2xxx.h
136
create mode 100644 include/hw/misc/cbus.h
137
create mode 100644 include/hw/net/lan9118.h
138
create mode 100644 include/hw/net/smc91c111.h
78
139
79
Richard Henderson (18):
80
target/arm: Extend vec_reg_offset to larger sizes
81
target/arm: Implement SVE Permute - Unpredicated Group
82
target/arm: Implement SVE Permute - Predicates Group
83
target/arm: Implement SVE Permute - Interleaving Group
84
target/arm: Implement SVE compress active elements
85
target/arm: Implement SVE conditionally broadcast/extract element
86
target/arm: Implement SVE copy to vector (predicated)
87
target/arm: Implement SVE reverse within elements
88
target/arm: Implement SVE vector splice (predicated)
89
target/arm: Implement SVE Select Vectors Group
90
target/arm: Implement SVE Integer Compare - Vectors Group
91
target/arm: Implement SVE Integer Compare - Immediate Group
92
target/arm: Implement SVE Partition Break Group
93
target/arm: Implement SVE Predicate Count Group
94
target/arm: Implement SVE Integer Compare - Scalars Group
95
target/arm: Implement FDUP/DUP
96
target/arm: Implement SVE Integer Wide Immediate - Unpredicated Group
97
target/arm: Implement SVE Floating Point Arithmetic - Unpredicated Group
98
99
Shannon Zhao (1):
100
arm_gicv3_kvm: kvm_dist_get/put_priority: skip the registers banked by GICR_IPRIORITYR
101
102
include/exec/cpu-all.h | 4 +
103
include/exec/cpu-defs.h | 9 +
104
include/exec/exec-all.h | 16 +-
105
include/exec/memory.h | 65 +-
106
include/hw/arm/arm.h | 8 +-
107
include/hw/or-irq.h | 5 +-
108
include/qemu/bswap.h | 52 ++
109
include/qom/cpu.h | 3 +
110
target/arm/helper-sve.h | 294 +++++++++
111
target/arm/helper.h | 19 +
112
target/arm/translate-a64.h | 26 +-
113
accel/tcg/cputlb.c | 59 +-
114
exec.c | 263 ++++----
115
hw/alpha/typhoon.c | 3 +-
116
hw/arm/armv7m.c | 28 +-
117
hw/arm/mps2-tz.c | 32 +-
118
hw/arm/smmuv3.c | 2 +-
119
hw/arm/stellaris.c | 12 +-
120
hw/block/m25p80.c | 1 +
121
hw/block/pflash_cfi02.c | 97 +--
122
hw/char/parallel.c | 50 +-
123
hw/core/or-irq.c | 39 +-
124
hw/dma/rc4030.c | 2 +-
125
hw/i386/amd_iommu.c | 2 +-
126
hw/i386/intel_iommu.c | 8 +-
127
hw/input/pckbd.c | 14 +-
128
hw/intc/arm_gicv3_kvm.c | 18 +-
129
hw/intc/armv7m_nvic.c | 6 +-
130
hw/m68k/mcf5206.c | 48 +-
131
hw/misc/aspeed_scu.c | 20 +
132
hw/ppc/spapr_iommu.c | 5 +-
133
hw/s390x/s390-pci-bus.c | 2 +-
134
hw/s390x/s390-pci-inst.c | 4 +-
135
hw/sh4/sh7750.c | 44 +-
136
hw/sparc/sun4m_iommu.c | 3 +-
137
hw/sparc64/sun4u_iommu.c | 2 +-
138
hw/vfio/common.c | 6 +-
139
hw/virtio/vhost.c | 7 +-
140
hw/watchdog/wdt_i6300esb.c | 48 +-
141
memory.c | 33 +-
142
target/arm/cpu.c | 18 +
143
target/arm/sve_helper.c | 1250 +++++++++++++++++++++++++++++++++++++
144
target/arm/translate-sve.c | 1458 +++++++++++++++++++++++++++++++++++++++++++
145
target/arm/translate.c | 43 +-
146
target/arm/vec_helper.c | 69 ++
147
CODING_STYLE | 17 +
148
docs/devel/loads-stores.rst | 15 +
149
target/arm/sve.decode | 248 ++++++++
150
48 files changed, 4114 insertions(+), 363 deletions(-)
151
diff view generated by jsdifflib
Deleted patch
1
From: Shannon Zhao <zhaoshenglong@huawei.com>
2
1
3
While for_each_dist_irq_reg loop starts from GIC_INTERNAL, it forgot to
4
offset the date array and index. This will overlap the GICR registers
5
value and leave the last GIC_INTERNAL irq's registers out of update.
6
7
Fixes: 367b9f527becdd20ddf116e17a3c0c2bbc486920
8
Cc: qemu-stable@nongnu.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/intc/arm_gicv3_kvm.c | 18 ++++++++++++++++--
15
1 file changed, 16 insertions(+), 2 deletions(-)
16
17
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/intc/arm_gicv3_kvm.c
20
+++ b/hw/intc/arm_gicv3_kvm.c
21
@@ -XXX,XX +XXX,XX @@ static void kvm_dist_get_priority(GICv3State *s, uint32_t offset, uint8_t *bmp)
22
uint32_t reg, *field;
23
int irq;
24
25
- field = (uint32_t *)bmp;
26
+ /* For the KVM GICv3, affinity routing is always enabled, and the first 8
27
+ * GICD_IPRIORITYR<n> registers are always RAZ/WI. The corresponding
28
+ * functionality is replaced by GICR_IPRIORITYR<n>. It doesn't need to
29
+ * sync them. So it needs to skip the field of GIC_INTERNAL irqs in bmp and
30
+ * offset.
31
+ */
32
+ field = (uint32_t *)(bmp + GIC_INTERNAL);
33
+ offset += (GIC_INTERNAL * 8) / 8;
34
for_each_dist_irq_reg(irq, s->num_irq, 8) {
35
kvm_gicd_access(s, offset, &reg, false);
36
*field = reg;
37
@@ -XXX,XX +XXX,XX @@ static void kvm_dist_put_priority(GICv3State *s, uint32_t offset, uint8_t *bmp)
38
uint32_t reg, *field;
39
int irq;
40
41
- field = (uint32_t *)bmp;
42
+ /* For the KVM GICv3, affinity routing is always enabled, and the first 8
43
+ * GICD_IPRIORITYR<n> registers are always RAZ/WI. The corresponding
44
+ * functionality is replaced by GICR_IPRIORITYR<n>. It doesn't need to
45
+ * sync them. So it needs to skip the field of GIC_INTERNAL irqs in bmp and
46
+ * offset.
47
+ */
48
+ field = (uint32_t *)(bmp + GIC_INTERNAL);
49
+ offset += (GIC_INTERNAL * 8) / 8;
50
for_each_dist_irq_reg(irq, s->num_irq, 8) {
51
reg = *field;
52
kvm_gicd_access(s, offset, &reg, true);
53
--
54
2.17.1
55
56
diff view generated by jsdifflib
1
Add an IOMMU index argument to the translate method of
1
From: Eric Auger <eric.auger@redhat.com>
2
IOMMUs. Since all of our current IOMMU implementations
3
support only a single IOMMU index, this has no effect
4
on the behaviour.
5
2
3
The SMMUNotifierNode struct is not necessary and brings extra
4
complexity so let's remove it. We now directly track the SMMUDevices
5
which have registered IOMMU MR notifiers.
6
7
This is inspired from the same transformation on intel-iommu
8
done in commit b4a4ba0d68f50f218ee3957b6638dbee32a5eeef
9
("intel-iommu: remove IntelIOMMUNotifierNode")
10
11
Signed-off-by: Eric Auger <eric.auger@redhat.com>
12
Reviewed-by: Peter Xu <peterx@redhat.com>
13
Message-id: 20190409160219.19026-1-eric.auger@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20180604152941.20374-4-peter.maydell@linaro.org
10
---
15
---
11
include/exec/memory.h | 3 ++-
16
include/hw/arm/smmu-common.h | 8 ++------
12
exec.c | 11 +++++++++--
17
hw/arm/smmu-common.c | 6 +++---
13
hw/alpha/typhoon.c | 3 ++-
18
hw/arm/smmuv3.c | 28 +++++++---------------------
14
hw/arm/smmuv3.c | 2 +-
19
3 files changed, 12 insertions(+), 30 deletions(-)
15
hw/dma/rc4030.c | 2 +-
16
hw/i386/amd_iommu.c | 2 +-
17
hw/i386/intel_iommu.c | 2 +-
18
hw/ppc/spapr_iommu.c | 3 ++-
19
hw/s390x/s390-pci-bus.c | 2 +-
20
hw/sparc/sun4m_iommu.c | 3 ++-
21
hw/sparc64/sun4u_iommu.c | 2 +-
22
memory.c | 2 +-
23
12 files changed, 24 insertions(+), 13 deletions(-)
24
20
25
diff --git a/include/exec/memory.h b/include/exec/memory.h
21
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
26
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
27
--- a/include/exec/memory.h
23
--- a/include/hw/arm/smmu-common.h
28
+++ b/include/exec/memory.h
24
+++ b/include/hw/arm/smmu-common.h
29
@@ -XXX,XX +XXX,XX @@ typedef struct IOMMUMemoryRegionClass {
25
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUDevice {
30
* @iommu: the IOMMUMemoryRegion
26
AddressSpace as;
31
* @hwaddr: address to be translated within the memory region
27
uint32_t cfg_cache_hits;
32
* @flag: requested access permissions
28
uint32_t cfg_cache_misses;
33
+ * @iommu_idx: IOMMU index for the translation
29
+ QLIST_ENTRY(SMMUDevice) next;
34
*/
30
} SMMUDevice;
35
IOMMUTLBEntry (*translate)(IOMMUMemoryRegion *iommu, hwaddr addr,
31
36
- IOMMUAccessFlags flag);
32
-typedef struct SMMUNotifierNode {
37
+ IOMMUAccessFlags flag, int iommu_idx);
33
- SMMUDevice *sdev;
38
/* Returns minimum supported page size in bytes.
34
- QLIST_ENTRY(SMMUNotifierNode) next;
39
* If this method is not provided then the minimum is assumed to
35
-} SMMUNotifierNode;
40
* be TARGET_PAGE_SIZE.
36
-
41
diff --git a/exec.c b/exec.c
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
42
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
43
--- a/exec.c
51
--- a/hw/arm/smmu-common.c
44
+++ b/exec.c
52
+++ b/hw/arm/smmu-common.c
45
@@ -XXX,XX +XXX,XX @@ static MemoryRegionSection address_space_translate_iommu(IOMMUMemoryRegion *iomm
53
@@ -XXX,XX +XXX,XX @@ inline void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
46
do {
54
/* Unmap all notifiers of all mr's */
47
hwaddr addr = *xlat;
55
void smmu_inv_notifiers_all(SMMUState *s)
48
IOMMUMemoryRegionClass *imrc = memory_region_get_iommu_class_nocheck(iommu_mr);
49
- IOMMUTLBEntry iotlb = imrc->translate(iommu_mr, addr, is_write ?
50
- IOMMU_WO : IOMMU_RO);
51
+ int iommu_idx = 0;
52
+ IOMMUTLBEntry iotlb;
53
+
54
+ if (imrc->attrs_to_index) {
55
+ iommu_idx = imrc->attrs_to_index(iommu_mr, attrs);
56
+ }
57
+
58
+ iotlb = imrc->translate(iommu_mr, addr, is_write ?
59
+ IOMMU_WO : IOMMU_RO, iommu_idx);
60
61
if (!(iotlb.perm & (1 << is_write))) {
62
goto unassigned;
63
diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/alpha/typhoon.c
66
+++ b/hw/alpha/typhoon.c
67
@@ -XXX,XX +XXX,XX @@ static bool window_translate(TyphoonWindow *win, hwaddr addr,
68
Pchip and generate a machine check interrupt. */
69
static IOMMUTLBEntry typhoon_translate_iommu(IOMMUMemoryRegion *iommu,
70
hwaddr addr,
71
- IOMMUAccessFlags flag)
72
+ IOMMUAccessFlags flag,
73
+ int iommu_idx)
74
{
56
{
75
TyphoonPchip *pchip = container_of(iommu, TyphoonPchip, iommu);
57
- SMMUNotifierNode *node;
76
IOMMUTLBEntry ret;
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
77
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
67
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
78
index XXXXXXX..XXXXXXX 100644
68
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/arm/smmuv3.c
69
--- a/hw/arm/smmuv3.c
80
+++ b/hw/arm/smmuv3.c
70
+++ b/hw/arm/smmuv3.c
81
@@ -XXX,XX +XXX,XX @@ static int smmuv3_decode_config(IOMMUMemoryRegion *mr, SMMUTransCfg *cfg,
71
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
72
/* invalidate an asid/iova tuple in all mr's */
73
static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova)
74
{
75
- SMMUNotifierNode *node;
76
+ SMMUDevice *sdev;
77
78
- QLIST_FOREACH(node, &s->notifiers_list, next) {
79
- IOMMUMemoryRegion *mr = &node->sdev->iommu;
80
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
81
+ IOMMUMemoryRegion *mr = &sdev->iommu;
82
IOMMUNotifier *n;
83
84
trace_smmuv3_inv_notifiers_iova(mr->parent_obj.name, asid, iova);
85
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
86
SMMUDevice *sdev = container_of(iommu, SMMUDevice, iommu);
87
SMMUv3State *s3 = sdev->smmu;
88
SMMUState *s = &(s3->smmu_state);
89
- SMMUNotifierNode *node = NULL;
90
- SMMUNotifierNode *next_node = NULL;
91
92
if (new & IOMMU_NOTIFIER_MAP) {
93
int bus_num = pci_bus_num(sdev->bus);
94
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
95
96
if (old == IOMMU_NOTIFIER_NONE) {
97
trace_smmuv3_notify_flag_add(iommu->parent_obj.name);
98
- node = g_malloc0(sizeof(*node));
99
- node->sdev = sdev;
100
- QLIST_INSERT_HEAD(&s->notifiers_list, node, next);
101
- return;
102
- }
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
}
82
}
119
}
83
120
84
static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
85
- IOMMUAccessFlags flag)
86
+ IOMMUAccessFlags flag, int iommu_idx)
87
{
88
SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu);
89
SMMUv3State *s = sdev->smmu;
90
diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/hw/dma/rc4030.c
93
+++ b/hw/dma/rc4030.c
94
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps jazzio_ops = {
95
};
96
97
static IOMMUTLBEntry rc4030_dma_translate(IOMMUMemoryRegion *iommu, hwaddr addr,
98
- IOMMUAccessFlags flag)
99
+ IOMMUAccessFlags flag, int iommu_idx)
100
{
101
rc4030State *s = container_of(iommu, rc4030State, dma_mr);
102
IOMMUTLBEntry ret = {
103
diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/hw/i386/amd_iommu.c
106
+++ b/hw/i386/amd_iommu.c
107
@@ -XXX,XX +XXX,XX @@ static inline bool amdvi_is_interrupt_addr(hwaddr addr)
108
}
109
110
static IOMMUTLBEntry amdvi_translate(IOMMUMemoryRegion *iommu, hwaddr addr,
111
- IOMMUAccessFlags flag)
112
+ IOMMUAccessFlags flag, int iommu_idx)
113
{
114
AMDVIAddressSpace *as = container_of(iommu, AMDVIAddressSpace, iommu);
115
AMDVIState *s = as->iommu_state;
116
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/hw/i386/intel_iommu.c
119
+++ b/hw/i386/intel_iommu.c
120
@@ -XXX,XX +XXX,XX @@ static void vtd_mem_write(void *opaque, hwaddr addr,
121
}
122
123
static IOMMUTLBEntry vtd_iommu_translate(IOMMUMemoryRegion *iommu, hwaddr addr,
124
- IOMMUAccessFlags flag)
125
+ IOMMUAccessFlags flag, int iommu_idx)
126
{
127
VTDAddressSpace *vtd_as = container_of(iommu, VTDAddressSpace, iommu);
128
IntelIOMMUState *s = vtd_as->iommu_state;
129
diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
130
index XXXXXXX..XXXXXXX 100644
131
--- a/hw/ppc/spapr_iommu.c
132
+++ b/hw/ppc/spapr_iommu.c
133
@@ -XXX,XX +XXX,XX @@ static void spapr_tce_free_table(uint64_t *table, int fd, uint32_t nb_table)
134
/* Called from RCU critical section */
135
static IOMMUTLBEntry spapr_tce_translate_iommu(IOMMUMemoryRegion *iommu,
136
hwaddr addr,
137
- IOMMUAccessFlags flag)
138
+ IOMMUAccessFlags flag,
139
+ int iommu_idx)
140
{
141
sPAPRTCETable *tcet = container_of(iommu, sPAPRTCETable, iommu);
142
uint64_t tce;
143
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
144
index XXXXXXX..XXXXXXX 100644
145
--- a/hw/s390x/s390-pci-bus.c
146
+++ b/hw/s390x/s390-pci-bus.c
147
@@ -XXX,XX +XXX,XX @@ uint16_t s390_guest_io_table_walk(uint64_t g_iota, hwaddr addr,
148
}
149
150
static IOMMUTLBEntry s390_translate_iommu(IOMMUMemoryRegion *mr, hwaddr addr,
151
- IOMMUAccessFlags flag)
152
+ IOMMUAccessFlags flag, int iommu_idx)
153
{
154
S390PCIIOMMU *iommu = container_of(mr, S390PCIIOMMU, iommu_mr);
155
S390IOTLBEntry *entry;
156
diff --git a/hw/sparc/sun4m_iommu.c b/hw/sparc/sun4m_iommu.c
157
index XXXXXXX..XXXXXXX 100644
158
--- a/hw/sparc/sun4m_iommu.c
159
+++ b/hw/sparc/sun4m_iommu.c
160
@@ -XXX,XX +XXX,XX @@ static void iommu_bad_addr(IOMMUState *s, hwaddr addr,
161
/* Called from RCU critical section */
162
static IOMMUTLBEntry sun4m_translate_iommu(IOMMUMemoryRegion *iommu,
163
hwaddr addr,
164
- IOMMUAccessFlags flags)
165
+ IOMMUAccessFlags flags,
166
+ int iommu_idx)
167
{
168
IOMMUState *is = container_of(iommu, IOMMUState, iommu);
169
hwaddr page, pa;
170
diff --git a/hw/sparc64/sun4u_iommu.c b/hw/sparc64/sun4u_iommu.c
171
index XXXXXXX..XXXXXXX 100644
172
--- a/hw/sparc64/sun4u_iommu.c
173
+++ b/hw/sparc64/sun4u_iommu.c
174
@@ -XXX,XX +XXX,XX @@
175
/* Called from RCU critical section */
176
static IOMMUTLBEntry sun4u_translate_iommu(IOMMUMemoryRegion *iommu,
177
hwaddr addr,
178
- IOMMUAccessFlags flag)
179
+ IOMMUAccessFlags flag, int iommu_idx)
180
{
181
IOMMUState *is = container_of(iommu, IOMMUState, iommu);
182
hwaddr baseaddr, offset;
183
diff --git a/memory.c b/memory.c
184
index XXXXXXX..XXXXXXX 100644
185
--- a/memory.c
186
+++ b/memory.c
187
@@ -XXX,XX +XXX,XX @@ void memory_region_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n)
188
granularity = memory_region_iommu_get_min_page_size(iommu_mr);
189
190
for (addr = 0; addr < memory_region_size(mr); addr += granularity) {
191
- iotlb = imrc->translate(iommu_mr, addr, IOMMU_NONE);
192
+ iotlb = imrc->translate(iommu_mr, addr, IOMMU_NONE, n->iommu_idx);
193
if (iotlb.perm != IOMMU_NONE) {
194
n->notify(n, &iotlb);
195
}
196
--
121
--
197
2.17.1
122
2.20.1
198
123
199
124
diff view generated by jsdifflib
1
Now we have stn_p() and ldn_p() we can use them in various
1
In the stripe8() function we use a variable length array; however
2
functions in exec.c that used to have their own switch-on-size code.
2
we know that the maximum length required is MAX_NUM_BUSSES. Use
3
a fixed-length array and an assert instead.
3
4
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
7
Message-id: 20180611171007.4165-4-peter.maydell@linaro.org
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
8
---
11
---
9
exec.c | 112 +++++----------------------------------------------------
12
hw/ssi/xilinx_spips.c | 6 ++++--
10
1 file changed, 8 insertions(+), 104 deletions(-)
13
1 file changed, 4 insertions(+), 2 deletions(-)
11
14
12
diff --git a/exec.c b/exec.c
15
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/exec.c
17
--- a/hw/ssi/xilinx_spips.c
15
+++ b/exec.c
18
+++ b/hw/ssi/xilinx_spips.c
16
@@ -XXX,XX +XXX,XX @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
19
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_reset(DeviceState *d)
17
memory_notdirty_write_prepare(&ndi, current_cpu, current_cpu->mem_io_vaddr,
20
18
ram_addr, size);
21
static inline void stripe8(uint8_t *x, int num, bool dir)
19
22
{
20
- switch (size) {
23
- uint8_t r[num];
21
- case 1:
24
- memset(r, 0, sizeof(uint8_t) * num);
22
- stb_p(qemu_map_ram_ptr(NULL, ram_addr), val);
25
+ uint8_t r[MAX_NUM_BUSSES];
23
- break;
26
int idx[2] = {0, 0};
24
- case 2:
27
int bit[2] = {0, 7};
25
- stw_p(qemu_map_ram_ptr(NULL, ram_addr), val);
28
int d = dir;
26
- break;
29
27
- case 4:
30
+ assert(num <= MAX_NUM_BUSSES);
28
- stl_p(qemu_map_ram_ptr(NULL, ram_addr), val);
31
+ memset(r, 0, sizeof(uint8_t) * num);
29
- break;
32
+
30
- case 8:
33
for (idx[0] = 0; idx[0] < num; ++idx[0]) {
31
- stq_p(qemu_map_ram_ptr(NULL, ram_addr), val);
34
for (bit[0] = 7; bit[0] >= 0; bit[0]--) {
32
- break;
35
r[idx[!d]] |= x[idx[d]] & 1 << bit[d] ? 1 << bit[!d] : 0;
33
- default:
34
- abort();
35
- }
36
+ stn_p(qemu_map_ram_ptr(NULL, ram_addr), size, val);
37
memory_notdirty_write_complete(&ndi);
38
}
39
40
@@ -XXX,XX +XXX,XX @@ static MemTxResult subpage_read(void *opaque, hwaddr addr, uint64_t *data,
41
if (res) {
42
return res;
43
}
44
- switch (len) {
45
- case 1:
46
- *data = ldub_p(buf);
47
- return MEMTX_OK;
48
- case 2:
49
- *data = lduw_p(buf);
50
- return MEMTX_OK;
51
- case 4:
52
- *data = (uint32_t)ldl_p(buf);
53
- return MEMTX_OK;
54
- case 8:
55
- *data = ldq_p(buf);
56
- return MEMTX_OK;
57
- default:
58
- abort();
59
- }
60
+ *data = ldn_p(buf, len);
61
+ return MEMTX_OK;
62
}
63
64
static MemTxResult subpage_write(void *opaque, hwaddr addr,
65
@@ -XXX,XX +XXX,XX @@ static MemTxResult subpage_write(void *opaque, hwaddr addr,
66
" value %"PRIx64"\n",
67
__func__, subpage, len, addr, value);
68
#endif
69
- switch (len) {
70
- case 1:
71
- stb_p(buf, value);
72
- break;
73
- case 2:
74
- stw_p(buf, value);
75
- break;
76
- case 4:
77
- stl_p(buf, value);
78
- break;
79
- case 8:
80
- stq_p(buf, value);
81
- break;
82
- default:
83
- abort();
84
- }
85
+ stn_p(buf, len, value);
86
return flatview_write(subpage->fv, addr + subpage->base, attrs, buf, len);
87
}
88
89
@@ -XXX,XX +XXX,XX @@ static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr,
90
l = memory_access_size(mr, l, addr1);
91
/* XXX: could force current_cpu to NULL to avoid
92
potential bugs */
93
- switch (l) {
94
- case 8:
95
- /* 64 bit write access */
96
- val = ldq_p(buf);
97
- result |= memory_region_dispatch_write(mr, addr1, val, 8,
98
- attrs);
99
- break;
100
- case 4:
101
- /* 32 bit write access */
102
- val = (uint32_t)ldl_p(buf);
103
- result |= memory_region_dispatch_write(mr, addr1, val, 4,
104
- attrs);
105
- break;
106
- case 2:
107
- /* 16 bit write access */
108
- val = lduw_p(buf);
109
- result |= memory_region_dispatch_write(mr, addr1, val, 2,
110
- attrs);
111
- break;
112
- case 1:
113
- /* 8 bit write access */
114
- val = ldub_p(buf);
115
- result |= memory_region_dispatch_write(mr, addr1, val, 1,
116
- attrs);
117
- break;
118
- default:
119
- abort();
120
- }
121
+ val = ldn_p(buf, l);
122
+ result |= memory_region_dispatch_write(mr, addr1, val, l, attrs);
123
} else {
124
/* RAM case */
125
ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l, false);
126
@@ -XXX,XX +XXX,XX @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
127
/* I/O case */
128
release_lock |= prepare_mmio_access(mr);
129
l = memory_access_size(mr, l, addr1);
130
- switch (l) {
131
- case 8:
132
- /* 64 bit read access */
133
- result |= memory_region_dispatch_read(mr, addr1, &val, 8,
134
- attrs);
135
- stq_p(buf, val);
136
- break;
137
- case 4:
138
- /* 32 bit read access */
139
- result |= memory_region_dispatch_read(mr, addr1, &val, 4,
140
- attrs);
141
- stl_p(buf, val);
142
- break;
143
- case 2:
144
- /* 16 bit read access */
145
- result |= memory_region_dispatch_read(mr, addr1, &val, 2,
146
- attrs);
147
- stw_p(buf, val);
148
- break;
149
- case 1:
150
- /* 8 bit read access */
151
- result |= memory_region_dispatch_read(mr, addr1, &val, 1,
152
- attrs);
153
- stb_p(buf, val);
154
- break;
155
- default:
156
- abort();
157
- }
158
+ result |= memory_region_dispatch_read(mr, addr1, &val, l, attrs);
159
+ stn_p(buf, l, val);
160
} else {
161
/* RAM case */
162
ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l, false);
163
--
36
--
164
2.17.1
37
2.20.1
165
38
166
39
diff view generated by jsdifflib
1
The codebase has a bit of a mix of different multiline
1
Normally configure identifies the source path by looking
2
comment styles. State a preference for the Linux kernel
2
at the location where the configure script itself exists.
3
style:
3
We also provide a --source-path option which lets the user
4
/*
4
manually override this.
5
* Star on the left for each line.
5
6
* Leading slash-star and trailing star-slash
6
There isn't really an obvious use case for the --source-path
7
* each go on a line of their own.
7
option, and in commit 927128222b0a91f56c13a in 2017 we
8
*/
8
accidentally added some logic that looks at $source_path
9
before the command line option that overrides it has been
10
processed.
11
12
The fact that nobody complained suggests that there isn't
13
any use of this option and we aren't testing it either;
14
remove it. This allows us to move the "make $source_path
15
absolute" logic up so that there is no window in the script
16
where $source_path is set but not yet absolute.
9
17
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
19
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
12
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
20
Message-id: 20190318134019.23729-1-peter.maydell@linaro.org
13
Reviewed-by: Markus Armbruster <armbru@redhat.com>
14
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
15
Reviewed-by: Thomas Huth <thuth@redhat.com>
16
Reviewed-by: John Snow <jsnow@redhat.com>
17
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
18
Message-id: 20180611141716.3813-1-peter.maydell@linaro.org
19
---
21
---
20
CODING_STYLE | 17 +++++++++++++++++
22
configure | 10 ++--------
21
1 file changed, 17 insertions(+)
23
1 file changed, 2 insertions(+), 8 deletions(-)
22
24
23
diff --git a/CODING_STYLE b/CODING_STYLE
25
diff --git a/configure b/configure
24
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100755
25
--- a/CODING_STYLE
27
--- a/configure
26
+++ b/CODING_STYLE
28
+++ b/configure
27
@@ -XXX,XX +XXX,XX @@ We use traditional C-style /* */ comments and avoid // comments.
29
@@ -XXX,XX +XXX,XX @@ ld_has() {
28
Rationale: The // form is valid in C99, so this is purely a matter of
30
29
consistency of style. The checkpatch script will warn you about this.
31
# default parameters
30
32
source_path=$(dirname "$0")
31
+Multiline comment blocks should have a row of stars on the left,
33
+# make source path absolute
32
+and the initial /* and terminating */ both on their own lines:
34
+source_path=$(cd "$source_path"; pwd)
33
+ /*
35
cpu=""
34
+ * like
36
iasl="iasl"
35
+ * this
37
interp_prefix="/usr/gnemul/qemu-%M"
36
+ */
38
@@ -XXX,XX +XXX,XX @@ for opt do
37
+This is the same format required by the Linux kernel coding style.
39
;;
38
+
40
--cxx=*) CXX="$optarg"
39
+(Some of the existing comments in the codebase use the GNU Coding
41
;;
40
+Standards form which does not have stars on the left, or other
42
- --source-path=*) source_path="$optarg"
41
+variations; avoid these when writing new comments, but don't worry
43
- ;;
42
+about converting to the preferred form unless you're editing that
44
--cpu=*) cpu="$optarg"
43
+comment anyway.)
45
;;
44
+
46
--extra-cflags=*) QEMU_CFLAGS="$QEMU_CFLAGS $optarg"
45
+Rationale: Consistency, and ease of visually picking out a multiline
47
@@ -XXX,XX +XXX,XX @@ if test "$debug_info" = "yes"; then
46
+comment from the surrounding code.
48
LDFLAGS="-g $LDFLAGS"
47
+
49
fi
48
8. trace-events style
50
49
51
-# make source path absolute
50
8.1 0x prefix
52
-source_path=$(cd "$source_path"; pwd)
53
-
54
# running configure in the source tree?
55
# we know that's the case if configure is there.
56
if test -f "./configure"; then
57
@@ -XXX,XX +XXX,XX @@ for opt do
58
;;
59
--interp-prefix=*) interp_prefix="$optarg"
60
;;
61
- --source-path=*)
62
- ;;
63
--cross-prefix=*)
64
;;
65
--cc=*)
66
@@ -XXX,XX +XXX,XX @@ $(echo Available targets: $default_target_list | \
67
--target-list-exclude=LIST exclude a set of targets from the default target-list
68
69
Advanced options (experts only):
70
- --source-path=PATH path of source code [$source_path]
71
--cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]
72
--cc=CC use C compiler CC [$cc]
73
--iasl=IASL use ACPI compiler IASL [$iasl]
51
--
74
--
52
2.17.1
75
2.20.1
53
76
54
77
diff view generated by jsdifflib
1
There's a common pattern in QEMU where a function needs to perform
1
Enforce that for M-profile various FPSCR bits which are RES0 there
2
a data load or store of an N byte integer in a particular endianness.
2
but have defined meanings on A-profile are never settable. This
3
At the moment this is handled by doing a switch() on the size and
3
ensures that M-profile code can't enable the A-profile behaviour
4
calling the appropriate ld*_p or st*_p function for each size.
4
(notably vector length/stride handling) by accident.
5
6
Provide a new family of functions ldn_*_p() and stn_*_p() which
7
take the size as an argument and do the switch() themselves.
8
5
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20180611171007.4165-2-peter.maydell@linaro.org
8
Message-id: 20190416125744.27770-2-peter.maydell@linaro.org
13
---
9
---
14
include/exec/cpu-all.h | 4 +++
10
target/arm/vfp_helper.c | 8 ++++++++
15
include/qemu/bswap.h | 52 +++++++++++++++++++++++++++++++++++++
11
1 file changed, 8 insertions(+)
16
docs/devel/loads-stores.rst | 15 +++++++++++
17
3 files changed, 71 insertions(+)
18
12
19
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
13
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
20
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
21
--- a/include/exec/cpu-all.h
15
--- a/target/arm/vfp_helper.c
22
+++ b/include/exec/cpu-all.h
16
+++ b/target/arm/vfp_helper.c
23
@@ -XXX,XX +XXX,XX @@ static inline void tswap64s(uint64_t *s)
17
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
24
#define stq_p(p, v) stq_be_p(p, v)
18
val &= ~FPCR_FZ16;
25
#define stfl_p(p, v) stfl_be_p(p, v)
19
}
26
#define stfq_p(p, v) stfq_be_p(p, v)
20
27
+#define ldn_p(p, sz) ldn_be_p(p, sz)
21
+ if (arm_feature(env, ARM_FEATURE_M)) {
28
+#define stn_p(p, sz, v) stn_be_p(p, sz, v)
22
+ /*
29
#else
23
+ * M profile FPSCR is RES0 for the QC, STRIDE, FZ16, LEN bits
30
#define lduw_p(p) lduw_le_p(p)
24
+ * and also for the trapped-exception-handling bits IxE.
31
#define ldsw_p(p) ldsw_le_p(p)
25
+ */
32
@@ -XXX,XX +XXX,XX @@ static inline void tswap64s(uint64_t *s)
26
+ val &= 0xf7c0009f;
33
#define stq_p(p, v) stq_le_p(p, v)
34
#define stfl_p(p, v) stfl_le_p(p, v)
35
#define stfq_p(p, v) stfq_le_p(p, v)
36
+#define ldn_p(p, sz) ldn_le_p(p, sz)
37
+#define stn_p(p, sz, v) stn_le_p(p, sz, v)
38
#endif
39
40
/* MMU memory access macros */
41
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
42
index XXXXXXX..XXXXXXX 100644
43
--- a/include/qemu/bswap.h
44
+++ b/include/qemu/bswap.h
45
@@ -XXX,XX +XXX,XX @@ typedef union {
46
* For accessors that take a guest address rather than a
47
* host address, see the cpu_{ld,st}_* accessors defined in
48
* cpu_ldst.h.
49
+ *
50
+ * For cases where the size to be used is not fixed at compile time,
51
+ * there are
52
+ * stn{endian}_p(ptr, sz, val)
53
+ * which stores @val to @ptr as an @endian-order number @sz bytes in size
54
+ * and
55
+ * ldn{endian}_p(ptr, sz)
56
+ * which loads @sz bytes from @ptr as an unsigned @endian-order number
57
+ * and returns it in a uint64_t.
58
*/
59
60
static inline int ldub_p(const void *ptr)
61
@@ -XXX,XX +XXX,XX @@ static inline unsigned long leul_to_cpu(unsigned long v)
62
#endif
63
}
64
65
+/* Store v to p as a sz byte value in host order */
66
+#define DO_STN_LDN_P(END) \
67
+ static inline void stn_## END ## _p(void *ptr, int sz, uint64_t v) \
68
+ { \
69
+ switch (sz) { \
70
+ case 1: \
71
+ stb_p(ptr, v); \
72
+ break; \
73
+ case 2: \
74
+ stw_ ## END ## _p(ptr, v); \
75
+ break; \
76
+ case 4: \
77
+ stl_ ## END ## _p(ptr, v); \
78
+ break; \
79
+ case 8: \
80
+ stq_ ## END ## _p(ptr, v); \
81
+ break; \
82
+ default: \
83
+ g_assert_not_reached(); \
84
+ } \
85
+ } \
86
+ static inline uint64_t ldn_## END ## _p(const void *ptr, int sz) \
87
+ { \
88
+ switch (sz) { \
89
+ case 1: \
90
+ return ldub_p(ptr); \
91
+ case 2: \
92
+ return lduw_ ## END ## _p(ptr); \
93
+ case 4: \
94
+ return (uint32_t)ldl_ ## END ## _p(ptr); \
95
+ case 8: \
96
+ return ldq_ ## END ## _p(ptr); \
97
+ default: \
98
+ g_assert_not_reached(); \
99
+ } \
100
+ }
27
+ }
101
+
28
+
102
+DO_STN_LDN_P(he)
29
/*
103
+DO_STN_LDN_P(le)
30
* We don't implement trapped exception handling, so the
104
+DO_STN_LDN_P(be)
31
* trap enable bits, IDE|IXE|UFE|OFE|DZE|IOE are all RAZ/WI (not RES0!)
105
+
106
+#undef DO_STN_LDN_P
107
+
108
#undef le_bswap
109
#undef be_bswap
110
#undef le_bswaps
111
diff --git a/docs/devel/loads-stores.rst b/docs/devel/loads-stores.rst
112
index XXXXXXX..XXXXXXX 100644
113
--- a/docs/devel/loads-stores.rst
114
+++ b/docs/devel/loads-stores.rst
115
@@ -XXX,XX +XXX,XX @@ The ``_{endian}`` infix is omitted for target-endian accesses.
116
The target endian accessors are only available to source
117
files which are built per-target.
118
119
+There are also functions which take the size as an argument:
120
+
121
+load: ``ldn{endian}_p(ptr, sz)``
122
+
123
+which performs an unsigned load of ``sz`` bytes from ``ptr``
124
+as an ``{endian}`` order value and returns it in a uint64_t.
125
+
126
+store: ``stn{endian}_p(ptr, sz, val)``
127
+
128
+which stores ``val`` to ``ptr`` as an ``{endian}`` order value
129
+of size ``sz`` bytes.
130
+
131
+
132
Regexes for git grep
133
- ``\<ldf\?[us]\?[bwlq]\(_[hbl]e\)\?_p\>``
134
- ``\<stf\?[bwlq]\(_[hbl]e\)\?_p\>``
135
+ - ``\<ldn_\([hbl]e\)?_p\>``
136
+ - ``\<stn_\([hbl]e\)?_p\>``
137
138
``cpu_{ld,st}_*``
139
~~~~~~~~~~~~~~~~~
140
--
32
--
141
2.17.1
33
2.20.1
142
34
143
35
diff view generated by jsdifflib
1
The 'addr' field in the CPUIOTLBEntry struct has a rather non-obvious
1
For M-profile the MVFR* ID registers are memory mapped, in the
2
use; add a comment documenting it (reverse-engineered from what
2
range we implement via the NVIC. Allow them to be read.
3
the code that sets it is doing).
3
(If the CPU has no FPU, these registers are defined to be RAZ.)
4
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180611125633.32755-2-peter.maydell@linaro.org
7
Message-id: 20190416125744.27770-3-peter.maydell@linaro.org
9
---
8
---
10
include/exec/cpu-defs.h | 9 +++++++++
9
hw/intc/armv7m_nvic.c | 6 ++++++
11
accel/tcg/cputlb.c | 12 ++++++++++++
10
1 file changed, 6 insertions(+)
12
2 files changed, 21 insertions(+)
13
11
14
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
12
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
15
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
16
--- a/include/exec/cpu-defs.h
14
--- a/hw/intc/armv7m_nvic.c
17
+++ b/include/exec/cpu-defs.h
15
+++ b/hw/intc/armv7m_nvic.c
18
@@ -XXX,XX +XXX,XX @@ QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS));
16
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
19
* structs into one.)
17
return 0;
20
*/
18
}
21
typedef struct CPUIOTLBEntry {
19
return cpu->env.v7m.sfar;
22
+ /*
20
+ case 0xf40: /* MVFR0 */
23
+ * @addr contains:
21
+ return cpu->isar.mvfr0;
24
+ * - in the lower TARGET_PAGE_BITS, a physical section number
22
+ case 0xf44: /* MVFR1 */
25
+ * - with the lower TARGET_PAGE_BITS masked off, an offset which
23
+ return cpu->isar.mvfr1;
26
+ * must be added to the virtual address to obtain:
24
+ case 0xf48: /* MVFR2 */
27
+ * + the ram_addr_t of the target RAM (if the physical section
25
+ return cpu->isar.mvfr2;
28
+ * number is PHYS_SECTION_NOTDIRTY or PHYS_SECTION_ROM)
26
default:
29
+ * + the offset within the target MemoryRegion (otherwise)
27
bad_offset:
30
+ */
28
qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
31
hwaddr addr;
32
MemTxAttrs attrs;
33
} CPUIOTLBEntry;
34
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/accel/tcg/cputlb.c
37
+++ b/accel/tcg/cputlb.c
38
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
39
env->iotlb_v[mmu_idx][vidx] = env->iotlb[mmu_idx][index];
40
41
/* refill the tlb */
42
+ /*
43
+ * At this point iotlb contains a physical section number in the lower
44
+ * TARGET_PAGE_BITS, and either
45
+ * + the ram_addr_t of the page base of the target RAM (if NOTDIRTY or ROM)
46
+ * + the offset within section->mr of the page base (otherwise)
47
+ * We subtract the vaddr (which is page aligned and thus won't
48
+ * disturb the low bits) to give an offset which can be added to the
49
+ * (non-page-aligned) vaddr of the eventual memory access to get
50
+ * the MemoryRegion offset for the access. Note that the vaddr we
51
+ * subtract here is that of the page base, and not the same as the
52
+ * vaddr we add back in io_readx()/io_writex()/get_page_addr_code().
53
+ */
54
env->iotlb[mmu_idx][index].addr = iotlb - vaddr;
55
env->iotlb[mmu_idx][index].attrs = attrs;
56
57
--
29
--
58
2.17.1
30
2.20.1
59
31
60
32
diff view generated by jsdifflib
1
For the IoTKit MPC support, we need to wire together the
1
The M-profile floating point support has three associated config
2
interrupt outputs of 17 MPCs; this exceeds the current
2
registers: FPCAR, FPCCR and FPDSCR. It also makes the registers
3
value of MAX_OR_LINES. Increase MAX_OR_LINES to 32 (which
3
CPACR and NSACR have behaviour other than reads-as-zero.
4
should be enough for anyone).
4
Add support for all of these as simple reads-as-written registers.
5
5
We will hook up actual functionality later.
6
The tricky part is retaining the migration compatibility for
6
7
existing OR gates; we add a subsection which is only used
7
The main complexity here is handling the FPCCR register, which
8
for larger OR gates, and define it such that we can freely
8
has a mix of banked and unbanked bits.
9
increase MAX_OR_LINES in future (or even move to a dynamically
9
10
allocated levels[] array without an upper size limit) without
10
Note that we don't share storage with the A-profile
11
breaking compatibility.
11
cpu->cp15.nsacr and cpu->cp15.cpacr_el1, though the behaviour
12
is quite similar, for two reasons:
13
* the M profile CPACR is banked between security states
14
* it preserves the invariant that M profile uses no state
15
inside the cp15 substruct
12
16
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20180604152941.20374-10-peter.maydell@linaro.org
19
Message-id: 20190416125744.27770-4-peter.maydell@linaro.org
16
---
20
---
17
include/hw/or-irq.h | 5 ++++-
21
target/arm/cpu.h | 34 ++++++++++++
18
hw/core/or-irq.c | 39 +++++++++++++++++++++++++++++++++++++--
22
hw/intc/armv7m_nvic.c | 125 ++++++++++++++++++++++++++++++++++++++++++
19
2 files changed, 41 insertions(+), 3 deletions(-)
23
target/arm/cpu.c | 5 ++
20
24
target/arm/machine.c | 16 ++++++
21
diff --git a/include/hw/or-irq.h b/include/hw/or-irq.h
25
4 files changed, 180 insertions(+)
22
index XXXXXXX..XXXXXXX 100644
26
23
--- a/include/hw/or-irq.h
27
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
24
+++ b/include/hw/or-irq.h
28
index XXXXXXX..XXXXXXX 100644
25
@@ -XXX,XX +XXX,XX @@
29
--- a/target/arm/cpu.h
26
30
+++ b/target/arm/cpu.h
27
#define TYPE_OR_IRQ "or-irq"
31
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
28
32
uint32_t scr[M_REG_NUM_BANKS];
29
-#define MAX_OR_LINES 16
33
uint32_t msplim[M_REG_NUM_BANKS];
30
+/* This can safely be increased if necessary without breaking
34
uint32_t psplim[M_REG_NUM_BANKS];
31
+ * migration compatibility (as long as it remains greater than 15).
35
+ uint32_t fpcar[M_REG_NUM_BANKS];
32
+ */
36
+ uint32_t fpccr[M_REG_NUM_BANKS];
33
+#define MAX_OR_LINES 32
37
+ uint32_t fpdscr[M_REG_NUM_BANKS];
34
38
+ uint32_t cpacr[M_REG_NUM_BANKS];
35
typedef struct OrIRQState qemu_or_irq;
39
+ uint32_t nsacr;
36
40
} v7m;
37
diff --git a/hw/core/or-irq.c b/hw/core/or-irq.c
41
38
index XXXXXXX..XXXXXXX 100644
42
/* Information associated with an exception about to be taken:
39
--- a/hw/core/or-irq.c
43
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_CSSELR, LEVEL, 1, 3)
40
+++ b/hw/core/or-irq.c
44
*/
41
@@ -XXX,XX +XXX,XX @@ static void or_irq_init(Object *obj)
45
FIELD(V7M_CSSELR, INDEX, 0, 4)
42
qdev_init_gpio_out(DEVICE(obj), &s->out_irq, 1);
46
43
}
47
+/* v7M FPCCR bits */
44
48
+FIELD(V7M_FPCCR, LSPACT, 0, 1)
45
+/* The original version of this device had a fixed 16 entries in its
49
+FIELD(V7M_FPCCR, USER, 1, 1)
46
+ * VMState array; devices with more inputs than this need to
50
+FIELD(V7M_FPCCR, S, 2, 1)
47
+ * migrate the extra lines via a subsection.
51
+FIELD(V7M_FPCCR, THREAD, 3, 1)
48
+ * The subsection migrates as much of the levels[] array as is needed
52
+FIELD(V7M_FPCCR, HFRDY, 4, 1)
49
+ * (including repeating the first 16 elements), to avoid the awkwardness
53
+FIELD(V7M_FPCCR, MMRDY, 5, 1)
50
+ * of splitting it in two to meet the requirements of VMSTATE_VARRAY_UINT16.
54
+FIELD(V7M_FPCCR, BFRDY, 6, 1)
51
+ */
55
+FIELD(V7M_FPCCR, SFRDY, 7, 1)
52
+#define OLD_MAX_OR_LINES 16
56
+FIELD(V7M_FPCCR, MONRDY, 8, 1)
53
+#if MAX_OR_LINES < OLD_MAX_OR_LINES
57
+FIELD(V7M_FPCCR, SPLIMVIOL, 9, 1)
54
+#error MAX_OR_LINES must be at least 16 for migration compatibility
58
+FIELD(V7M_FPCCR, UFRDY, 10, 1)
55
+#endif
59
+FIELD(V7M_FPCCR, RES0, 11, 15)
56
+
60
+FIELD(V7M_FPCCR, TS, 26, 1)
57
+static bool vmstate_extras_needed(void *opaque)
61
+FIELD(V7M_FPCCR, CLRONRETS, 27, 1)
58
+{
62
+FIELD(V7M_FPCCR, CLRONRET, 28, 1)
59
+ qemu_or_irq *s = OR_IRQ(opaque);
63
+FIELD(V7M_FPCCR, LSPENS, 29, 1)
60
+
64
+FIELD(V7M_FPCCR, LSPEN, 30, 1)
61
+ return s->num_lines >= OLD_MAX_OR_LINES;
65
+FIELD(V7M_FPCCR, ASPEN, 31, 1)
62
+}
66
+/* These bits are banked. Others are non-banked and live in the M_REG_S bank */
63
+
67
+#define R_V7M_FPCCR_BANKED_MASK \
64
+static const VMStateDescription vmstate_or_irq_extras = {
68
+ (R_V7M_FPCCR_LSPACT_MASK | \
65
+ .name = "or-irq-extras",
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
81
--- a/hw/intc/armv7m_nvic.c
82
+++ b/hw/intc/armv7m_nvic.c
83
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
84
}
85
case 0xd84: /* CSSELR */
86
return cpu->env.v7m.csselr[attrs.secure];
87
+ case 0xd88: /* CPACR */
88
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
89
+ return 0;
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
}
147
break;
148
+ case 0xd88: /* CPACR */
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
}
165
break;
166
}
167
+ case 0xf34: /* FPCCR */
168
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
169
+ /* Not all bits here are banked. */
170
+ uint32_t fpccr_s;
171
+
172
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
173
+ /* Don't allow setting of bits not present in v7M */
174
+ value &= (R_V7M_FPCCR_LSPACT_MASK |
175
+ R_V7M_FPCCR_USER_MASK |
176
+ R_V7M_FPCCR_THREAD_MASK |
177
+ R_V7M_FPCCR_HFRDY_MASK |
178
+ R_V7M_FPCCR_MMRDY_MASK |
179
+ R_V7M_FPCCR_BFRDY_MASK |
180
+ R_V7M_FPCCR_MONRDY_MASK |
181
+ R_V7M_FPCCR_LSPEN_MASK |
182
+ R_V7M_FPCCR_ASPEN_MASK);
183
+ }
184
+ value &= ~R_V7M_FPCCR_RES0_MASK;
185
+
186
+ if (!attrs.secure) {
187
+ /* Some non-banked bits are configurably writable by NS */
188
+ fpccr_s = cpu->env.v7m.fpccr[M_REG_S];
189
+ if (!(fpccr_s & R_V7M_FPCCR_LSPENS_MASK)) {
190
+ uint32_t lspen = FIELD_EX32(value, V7M_FPCCR, LSPEN);
191
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, LSPEN, lspen);
192
+ }
193
+ if (!(fpccr_s & R_V7M_FPCCR_CLRONRETS_MASK)) {
194
+ uint32_t cor = FIELD_EX32(value, V7M_FPCCR, CLRONRET);
195
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, CLRONRET, cor);
196
+ }
197
+ if ((s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
198
+ uint32_t hfrdy = FIELD_EX32(value, V7M_FPCCR, HFRDY);
199
+ uint32_t bfrdy = FIELD_EX32(value, V7M_FPCCR, BFRDY);
200
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, HFRDY, hfrdy);
201
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, BFRDY, bfrdy);
202
+ }
203
+ /* TODO MONRDY should RAZ/WI if DEMCR.SDME is set */
204
+ {
205
+ uint32_t monrdy = FIELD_EX32(value, V7M_FPCCR, MONRDY);
206
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, MONRDY, monrdy);
207
+ }
208
+
209
+ /*
210
+ * All other non-banked bits are RAZ/WI from NS; write
211
+ * just the banked bits to fpccr[M_REG_NS].
212
+ */
213
+ value &= R_V7M_FPCCR_BANKED_MASK;
214
+ cpu->env.v7m.fpccr[M_REG_NS] = value;
215
+ } else {
216
+ fpccr_s = value;
217
+ }
218
+ cpu->env.v7m.fpccr[M_REG_S] = fpccr_s;
219
+ }
220
+ break;
221
+ case 0xf38: /* FPCAR */
222
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
223
+ value &= ~7;
224
+ cpu->env.v7m.fpcar[attrs.secure] = value;
225
+ }
226
+ break;
227
+ case 0xf3c: /* FPDSCR */
228
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
229
+ value &= 0x07c00000;
230
+ cpu->env.v7m.fpdscr[attrs.secure] = value;
231
+ }
232
+ break;
233
case 0xf50: /* ICIALLU */
234
case 0xf58: /* ICIMVAU */
235
case 0xf5c: /* DCIMVAC */
236
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
237
index XXXXXXX..XXXXXXX 100644
238
--- a/target/arm/cpu.c
239
+++ b/target/arm/cpu.c
240
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
241
env->v7m.ccr[M_REG_S] |= R_V7M_CCR_UNALIGN_TRP_MASK;
242
}
243
244
+ if (arm_feature(env, ARM_FEATURE_VFP)) {
245
+ env->v7m.fpccr[M_REG_NS] = R_V7M_FPCCR_ASPEN_MASK;
246
+ env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK |
247
+ R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK;
248
+ }
249
/* Unlike A/R profile, M profile defines the reset LR value */
250
env->regs[14] = 0xffffffff;
251
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",
66
+ .version_id = 1,
262
+ .version_id = 1,
67
+ .minimum_version_id = 1,
263
+ .minimum_version_id = 1,
68
+ .needed = vmstate_extras_needed,
264
+ .needed = vfp_needed,
69
+ .fields = (VMStateField[]) {
265
+ .fields = (VMStateField[]) {
70
+ VMSTATE_VARRAY_UINT16_UNSAFE(levels, qemu_or_irq, num_lines, 0,
266
+ VMSTATE_UINT32_ARRAY(env.v7m.fpcar, ARMCPU, M_REG_NUM_BANKS),
71
+ vmstate_info_bool, bool),
267
+ VMSTATE_UINT32_ARRAY(env.v7m.fpccr, ARMCPU, M_REG_NUM_BANKS),
72
+ VMSTATE_END_OF_LIST(),
268
+ VMSTATE_UINT32_ARRAY(env.v7m.fpdscr, ARMCPU, M_REG_NUM_BANKS),
73
+ },
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
+ }
74
+};
273
+};
75
+
274
+
76
static const VMStateDescription vmstate_or_irq = {
275
static const VMStateDescription vmstate_m = {
77
.name = TYPE_OR_IRQ,
276
.name = "cpu/m",
78
.version_id = 1,
277
.version_id = 4,
79
.minimum_version_id = 1,
278
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
80
.fields = (VMStateField[]) {
279
&vmstate_m_scr,
81
- VMSTATE_BOOL_ARRAY(levels, qemu_or_irq, MAX_OR_LINES),
280
&vmstate_m_other_sp,
82
+ VMSTATE_BOOL_SUB_ARRAY(levels, qemu_or_irq, 0, OLD_MAX_OR_LINES),
281
&vmstate_m_v8m,
83
VMSTATE_END_OF_LIST(),
282
+ &vmstate_m_fp,
84
- }
283
NULL
85
+ },
284
}
86
+ .subsections = (const VMStateDescription*[]) {
87
+ &vmstate_or_irq_extras,
88
+ NULL
89
+ },
90
};
285
};
91
92
static Property or_irq_properties[] = {
93
--
286
--
94
2.17.1
287
2.20.1
95
288
96
289
diff view generated by jsdifflib
1
Remove the now-unused armv7m_init() function. This was a legacy from
1
The only "system register" that M-profile floating point exposes
2
before we properly QOMified ARMv7M, and it has some flaws:
2
via the VMRS/VMRS instructions is FPSCR, and it does not have
3
3
the odd special case for rd==15. Add a check to ensure we only
4
* it combines work that needs to be done by an SoC object (creating
4
expose FPSCR.
5
and initializing the TYPE_ARMV7M object) with work that needs to
6
be done by the board model (setting the system up to load the ELF
7
file specified with -kernel)
8
* TYPE_ARMV7M creation failure is fatal, but an SoC object wants to
9
arrange to propagate the failure outward
10
* it uses allocate-and-create via qdev_create() whereas the current
11
preferred style for SoC objects is to do creation in-place
12
13
Board and SoC models can instead do the two jobs this function
14
was doing themselves, in the right places and with whatever their
15
preferred style/error handling is.
16
5
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Message-id: 20190416125744.27770-5-peter.maydell@linaro.org
20
Message-id: 20180601144328.23817-3-peter.maydell@linaro.org
21
---
9
---
22
include/hw/arm/arm.h | 8 ++------
10
target/arm/translate.c | 19 +++++++++++++++++--
23
hw/arm/armv7m.c | 21 ---------------------
11
1 file changed, 17 insertions(+), 2 deletions(-)
24
2 files changed, 2 insertions(+), 27 deletions(-)
25
12
26
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
27
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/arm/arm.h
15
--- a/target/arm/translate.c
29
+++ b/include/hw/arm/arm.h
16
+++ b/target/arm/translate.c
30
@@ -XXX,XX +XXX,XX @@ typedef enum {
17
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
31
ARM_ENDIANNESS_BE32,
18
}
32
} arm_endianness;
19
}
33
20
} else { /* !dp */
34
-/* armv7m.c */
21
+ bool is_sysreg;
35
-DeviceState *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
22
+
36
- const char *kernel_filename, const char *cpu_type);
23
if ((insn & 0x6f) != 0x00)
37
/**
24
return 1;
38
* armv7m_load_kernel:
25
rn = VFP_SREG_N(insn);
39
* @cpu: CPU
26
+
40
@@ -XXX,XX +XXX,XX @@ DeviceState *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
27
+ is_sysreg = extract32(insn, 21, 1);
41
* @mem_size: mem_size: maximum image size to load
28
+
42
*
29
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
43
* Load the guest image for an ARMv7M system. This must be called by
30
+ /*
44
- * any ARMv7M board, either directly or via armv7m_init(). (This is
31
+ * The only M-profile VFP vmrs/vmsr sysreg is FPSCR.
45
- * necessary to ensure that the CPU resets correctly on system reset,
32
+ * Writes to R15 are UNPREDICTABLE; we choose to undef.
46
- * as well as for kernel loading.)
33
+ */
47
+ * any ARMv7M board. (This is necessary to ensure that the CPU resets
34
+ if (is_sysreg && (rd == 15 || (rn >> 1) != ARM_VFP_FPSCR)) {
48
+ * correctly on system reset, as well as for kernel loading.)
35
+ return 1;
49
*/
36
+ }
50
void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size);
37
+ }
51
38
+
52
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
39
if (insn & ARM_CP_RW_BIT) {
53
index XXXXXXX..XXXXXXX 100644
40
/* vfp->arm */
54
--- a/hw/arm/armv7m.c
41
- if (insn & (1 << 21)) {
55
+++ b/hw/arm/armv7m.c
42
+ if (is_sysreg) {
56
@@ -XXX,XX +XXX,XX @@ static void armv7m_reset(void *opaque)
43
/* system register */
57
cpu_reset(CPU(cpu));
44
rn >>= 1;
58
}
45
59
46
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
60
-/* Init CPU and memory for a v7-M based board.
47
}
61
- mem_size is in bytes.
48
} else {
62
- Returns the ARMv7M device. */
49
/* arm->vfp */
63
-
50
- if (insn & (1 << 21)) {
64
-DeviceState *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
51
+ if (is_sysreg) {
65
- const char *kernel_filename, const char *cpu_type)
52
rn >>= 1;
66
-{
53
/* system register */
67
- DeviceState *armv7m;
54
switch (rn) {
68
-
69
- armv7m = qdev_create(NULL, TYPE_ARMV7M);
70
- qdev_prop_set_uint32(armv7m, "num-irq", num_irq);
71
- qdev_prop_set_string(armv7m, "cpu-type", cpu_type);
72
- object_property_set_link(OBJECT(armv7m), OBJECT(get_system_memory()),
73
- "memory", &error_abort);
74
- /* This will exit with an error if the user passed us a bad cpu_type */
75
- qdev_init_nofail(armv7m);
76
-
77
- armv7m_load_kernel(ARM_CPU(first_cpu), kernel_filename, mem_size);
78
- return armv7m;
79
-}
80
-
81
void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size)
82
{
83
int image_size;
84
--
55
--
85
2.17.1
56
2.20.1
86
57
87
58
diff view generated by jsdifflib
1
Convert the wdt_i6300esb device away from using the old_mmio field
1
Like AArch64, M-profile floating point has no FPEXC enable
2
of MemoryRegionOps.
2
bit to gate floating point; so always set the VFPEN TB flag.
3
4
M-profile also has CPACR and NSACR similar to A-profile;
5
they behave slightly differently:
6
* the CPACR is banked between Secure and Non-Secure
7
* if the NSACR forces a trap then this is taken to
8
the Secure state, not the Non-Secure state
9
10
Honour the CPACR and NSACR settings. The NSACR handling
11
requires us to borrow the exception.target_el field
12
(usually meaningless for M profile) to distinguish the
13
NOCP UsageFault taken to Secure state from the more
14
usual fault taken to the current security state.
3
15
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20180601141223.26630-5-peter.maydell@linaro.org
18
Message-id: 20190416125744.27770-6-peter.maydell@linaro.org
7
---
19
---
8
hw/watchdog/wdt_i6300esb.c | 48 ++++++++++++++++++++++++++++----------
20
target/arm/helper.c | 55 +++++++++++++++++++++++++++++++++++++++---
9
1 file changed, 36 insertions(+), 12 deletions(-)
21
target/arm/translate.c | 10 ++++++--
22
2 files changed, 60 insertions(+), 5 deletions(-)
10
23
11
diff --git a/hw/watchdog/wdt_i6300esb.c b/hw/watchdog/wdt_i6300esb.c
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/watchdog/wdt_i6300esb.c
26
--- a/target/arm/helper.c
14
+++ b/hw/watchdog/wdt_i6300esb.c
27
+++ b/target/arm/helper.c
15
@@ -XXX,XX +XXX,XX @@ static void i6300esb_mem_writel(void *vp, hwaddr addr, uint32_t val)
28
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
16
}
29
return target_el;
17
}
30
}
18
31
19
+static uint64_t i6300esb_mem_readfn(void *opaque, hwaddr addr, unsigned size)
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)
20
+{
37
+{
21
+ switch (size) {
38
+ switch (extract32(env->v7m.cpacr[is_secure], 20, 2)) {
39
+ case 0:
40
+ case 2: /* UNPREDICTABLE: we treat like 0 */
41
+ return false;
22
+ case 1:
42
+ case 1:
23
+ return i6300esb_mem_readb(opaque, addr);
43
+ return is_priv;
24
+ case 2:
44
+ case 3:
25
+ return i6300esb_mem_readw(opaque, addr);
45
+ return true;
26
+ case 4:
27
+ return i6300esb_mem_readl(opaque, addr);
28
+ default:
46
+ default:
29
+ g_assert_not_reached();
47
+ g_assert_not_reached();
30
+ }
48
+ }
31
+}
49
+}
32
+
50
+
33
+static void i6300esb_mem_writefn(void *opaque, hwaddr addr,
51
static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
34
+ uint64_t value, unsigned size)
52
ARMMMUIdx mmu_idx, bool ignfault)
35
+{
53
{
36
+ switch (size) {
54
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
37
+ case 1:
55
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNDEFINSTR_MASK;
38
+ i6300esb_mem_writeb(opaque, addr, value);
56
break;
39
+ break;
57
case EXCP_NOCP:
40
+ case 2:
58
- armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
41
+ i6300esb_mem_writew(opaque, addr, value);
59
- env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_NOCP_MASK;
42
+ break;
60
+ {
43
+ case 4:
61
+ /*
44
+ i6300esb_mem_writel(opaque, addr, value);
62
+ * NOCP might be directed to something other than the current
45
+ break;
63
+ * security state if this fault is because of NSACR; we indicate
46
+ default:
64
+ * the target security state using exception.target_el.
47
+ g_assert_not_reached();
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;
48
+ }
76
+ }
49
+}
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
+ }
50
+
89
+
51
static const MemoryRegionOps i6300esb_ops = {
90
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) && !env->v7m.secure) {
52
- .old_mmio = {
91
+ if (!extract32(env->v7m.nsacr, 10, 1)) {
53
- .read = {
92
+ /* FP insns cause a NOCP UsageFault taken to Secure */
54
- i6300esb_mem_readb,
93
+ return 3;
55
- i6300esb_mem_readw,
94
+ }
56
- i6300esb_mem_readl,
95
+ }
57
- },
96
+
58
- .write = {
97
+ return 0;
59
- i6300esb_mem_writeb,
98
+ }
60
- i6300esb_mem_writew,
99
+
61
- i6300esb_mem_writel,
100
/* The CPACR controls traps to EL1, or PL1 if we're 32 bit:
62
- },
101
* 0, 2 : trap EL0 and EL1/PL1 accesses
63
- },
102
* 1 : trap only EL0 accesses
64
+ .read = i6300esb_mem_readfn,
103
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
65
+ .write = i6300esb_mem_writefn,
104
flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, arm_sctlr_b(env));
66
+ .valid.min_access_size = 1,
105
flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
67
+ .valid.max_access_size = 4,
106
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
68
.endianness = DEVICE_LITTLE_ENDIAN,
107
- || arm_el_is_aa64(env, 1)) {
69
};
108
+ || arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
109
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
110
}
111
flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
112
diff --git a/target/arm/translate.c b/target/arm/translate.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/translate.c
115
+++ b/target/arm/translate.c
116
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
117
* for attempts to execute invalid vfp/neon encodings with FP disabled.
118
*/
119
if (s->fp_excp_el) {
120
- gen_exception_insn(s, 4, EXCP_UDEF,
121
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
122
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
123
+ gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
124
+ s->fp_excp_el);
125
+ } else {
126
+ gen_exception_insn(s, 4, EXCP_UDEF,
127
+ syn_fp_access_trap(1, 0xe, false),
128
+ s->fp_excp_el);
129
+ }
130
return 0;
131
}
70
132
71
--
133
--
72
2.17.1
134
2.20.1
73
135
74
136
diff view generated by jsdifflib
1
From: Julia Suvorova <jusual@mail.ru>
1
Correct the decode of the M-profile "coprocessor and
2
floating-point instructions" space:
3
* op0 == 0b11 is always unallocated
4
* if the CPU has an FPU then all insns with op1 == 0b101
5
are floating point and go to disas_vfp_insn()
2
6
3
ARMv6-M supports 6 Thumb2 instructions. This patch checks for these
7
For the moment we leave VLLDM and VLSTM as NOPs; in
4
instructions and allows their execution.
8
a later commit we will fill in the proper implementation
5
Like Thumb2 cores, ARMv6-M always interprets BL instruction as 32-bit.
9
for the case where an FPU is present.
6
10
7
This patch is required for future Cortex-M0 support.
8
9
Signed-off-by: Julia Suvorova <jusual@mail.ru>
10
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Message-id: 20180612204632.28780-1-jusual@mail.ru
12
[PMM: move armv6m_insn[] and armv6m_mask[] closer to
13
point of use, and mark 'const'. Check for M-and-not-v7
14
rather than M-and-6.]
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20190416125744.27770-7-peter.maydell@linaro.org
17
---
14
---
18
target/arm/translate.c | 43 +++++++++++++++++++++++++++++++++++++-----
15
target/arm/translate.c | 26 ++++++++++++++++++++++----
19
1 file changed, 38 insertions(+), 5 deletions(-)
16
1 file changed, 22 insertions(+), 4 deletions(-)
20
17
21
diff --git a/target/arm/translate.c b/target/arm/translate.c
18
diff --git a/target/arm/translate.c b/target/arm/translate.c
22
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/translate.c
20
--- a/target/arm/translate.c
24
+++ b/target/arm/translate.c
21
+++ b/target/arm/translate.c
25
@@ -XXX,XX +XXX,XX @@ static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
26
* end up actually treating this as two 16-bit insns, though,
27
* if it's half of a bl/blx pair that might span a page boundary.
28
*/
29
- if (arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
30
+ if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
31
+ arm_dc_feature(s, ARM_FEATURE_M)) {
32
/* Thumb2 cores (including all M profile ones) always treat
33
* 32-bit insns as 32-bit.
34
*/
35
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
22
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
36
int conds;
23
case 6: case 7: case 14: case 15:
37
int logic_cc;
24
/* Coprocessor. */
38
25
if (arm_dc_feature(s, ARM_FEATURE_M)) {
39
- /* The only 32 bit insn that's allowed for Thumb1 is the combined
26
- /* We don't currently implement M profile FP support,
40
- * BL/BLX prefix and suffix.
27
- * so this entire space should give a NOCP fault, with
41
+ /*
28
- * the exception of the v8M VLLDM and VLSTM insns, which
42
+ * ARMv6-M supports a limited subset of Thumb2 instructions.
29
- * must be NOPs in Secure state and UNDEF in Nonsecure state.
43
+ * Other Thumb1 architectures allow only 32-bit
30
+ /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
44
+ * combined BL/BLX prefix and suffix.
31
+ if (extract32(insn, 24, 2) == 3) {
45
*/
32
+ goto illegal_op; /* op0 = 0b11 : unallocated */
46
- if ((insn & 0xf800e800) != 0xf000e800) {
33
+ }
47
+ if (arm_dc_feature(s, ARM_FEATURE_M) &&
48
+ !arm_dc_feature(s, ARM_FEATURE_V7)) {
49
+ int i;
50
+ bool found = false;
51
+ const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
52
+ 0xf3b08040 /* dsb */,
53
+ 0xf3b08050 /* dmb */,
54
+ 0xf3b08060 /* isb */,
55
+ 0xf3e08000 /* mrs */,
56
+ 0xf000d000 /* bl */};
57
+ const uint32_t armv6m_mask[] = {0xffe0d000,
58
+ 0xfff0d0f0,
59
+ 0xfff0d0f0,
60
+ 0xfff0d0f0,
61
+ 0xffe0d000,
62
+ 0xf800d000};
63
+
34
+
64
+ for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
35
+ /*
65
+ if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
36
+ * Decode VLLDM and VLSTM first: these are nonstandard because:
66
+ found = true;
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
+ }
67
+ break;
56
+ break;
68
+ }
57
+ }
69
+ }
58
+
70
+ if (!found) {
59
/* All other insns: NOCP */
71
+ goto illegal_op;
60
gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
72
+ }
61
default_exception_el(s));
73
+ } else if ((insn & 0xf800e800) != 0xf000e800) {
74
ARCH(6T2);
75
}
76
77
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
78
}
79
break;
80
case 3: /* Special control operations. */
81
- ARCH(7);
82
+ if (!arm_dc_feature(s, ARM_FEATURE_V7) &&
83
+ !(arm_dc_feature(s, ARM_FEATURE_V6) &&
84
+ arm_dc_feature(s, ARM_FEATURE_M))) {
85
+ goto illegal_op;
86
+ }
87
op = (insn >> 4) & 0xf;
88
switch (op) {
89
case 2: /* clrex */
90
--
62
--
91
2.17.1
63
2.20.1
92
64
93
65
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
If the floating point extension is present, then the SG instruction
2
must clear the CONTROL_S.SFPA bit. Implement this.
2
3
3
On Macronix chips, two bytes can written to the WRSR. First byte will
4
(On a no-FPU system the bit will always be zero, so we don't need
4
configure the status register and the second the configuration
5
to make the clearing of the bit conditional on ARM_FEATURE_VFP.)
5
register. It is important to save the configuration value as it
6
contains the dummy cycle setting when using dual or quad IO mode.
7
6
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-8-peter.maydell@linaro.org
11
---
10
---
12
hw/block/m25p80.c | 1 +
11
target/arm/helper.c | 1 +
13
1 file changed, 1 insertion(+)
12
1 file changed, 1 insertion(+)
14
13
15
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/block/m25p80.c
16
--- a/target/arm/helper.c
18
+++ b/hw/block/m25p80.c
17
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ static void complete_collecting_data(Flash *s)
18
@@ -XXX,XX +XXX,XX @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
20
case MAN_MACRONIX:
19
qemu_log_mask(CPU_LOG_INT, "...really an SG instruction at 0x%08" PRIx32
21
s->quad_enable = extract32(s->data[0], 6, 1);
20
", executing it\n", env->regs[15]);
22
if (s->len > 1) {
21
env->regs[14] &= ~1;
23
+ s->volatile_cfg = s->data[1];
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
24
s->four_bytes_address_mode = extract32(s->data[1], 5, 1);
23
switch_v7m_security_state(env, true);
25
}
24
xpsr_write(env, 0, XPSR_IT);
26
break;
25
env->regs[15] += 4;
27
--
26
--
28
2.17.1
27
2.20.1
29
28
30
29
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
The M-profile CONTROL register has two bits -- SFPA and FPCA --
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.
2
6
3
The ASPEED SoCs contain a single register that returns random data when
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
read. This models that register so that guests can use it.
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-9-peter.maydell@linaro.org
10
---
11
target/arm/helper.c | 57 ++++++++++++++++++++++++++++++++++++++-------
12
1 file changed, 49 insertions(+), 8 deletions(-)
5
13
6
The random number data register has a corresponding control register,
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
7
however it returns data regardless of the state of the enabled bit, so
8
the model follows this behaviour.
9
10
When the qcrypto call fails we exit as the guest uses the random number
11
device to feed it's entropy pool, which is used for cryptographic
12
purposes.
13
14
Reviewed-by: Cédric Le Goater <clg@kaod.org>
15
Signed-off-by: Joel Stanley <joel@jms.id.au>
16
Message-id: 20180613114836.9265-1-joel@jms.id.au
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
hw/misc/aspeed_scu.c | 20 ++++++++++++++++++++
20
1 file changed, 20 insertions(+)
21
22
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
23
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/misc/aspeed_scu.c
16
--- a/target/arm/helper.c
25
+++ b/hw/misc/aspeed_scu.c
17
+++ b/target/arm/helper.c
26
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
27
#include "qapi/visitor.h"
19
return xpsr_read(env) & mask;
28
#include "qemu/bitops.h"
20
break;
29
#include "qemu/log.h"
21
case 20: /* CONTROL */
30
+#include "crypto/random.h"
22
- return env->v7m.control[env->v7m.secure];
31
#include "trace.h"
23
+ {
32
24
+ uint32_t value = env->v7m.control[env->v7m.secure];
33
#define TO_REG(offset) ((offset) >> 2)
25
+ if (!env->v7m.secure) {
34
@@ -XXX,XX +XXX,XX @@ static const uint32_t ast2500_a1_resets[ASPEED_SCU_NR_REGS] = {
26
+ /* SFPA is RAZ/WI from NS; FPCA is stored in the M_REG_S bank */
35
[BMC_DEV_ID] = 0x00002402U
27
+ value |= env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK;
36
};
28
+ }
37
29
+ return value;
38
+static uint32_t aspeed_scu_get_random(void)
39
+{
40
+ Error *err = NULL;
41
+ uint32_t num;
42
+
43
+ if (qcrypto_random_bytes((uint8_t *)&num, sizeof(num), &err)) {
44
+ error_report_err(err);
45
+ exit(1);
46
+ }
30
+ }
47
+
31
case 0x94: /* CONTROL_NS */
48
+ return num;
32
/* We have to handle this here because unprivileged Secure code
49
+}
33
* can read the NS CONTROL register.
50
+
34
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
51
static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
35
if (!env->v7m.secure) {
52
{
36
return 0;
53
AspeedSCUState *s = ASPEED_SCU(opaque);
37
}
54
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
38
- return env->v7m.control[M_REG_NS];
39
+ return env->v7m.control[M_REG_NS] |
40
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK);
55
}
41
}
56
42
57
switch (reg) {
43
if (el == 0) {
58
+ case RNG_DATA:
44
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
59
+ /* On hardware, RNG_DATA works regardless of
45
*/
60
+ * the state of the enable bit in RNG_CTRL
46
uint32_t mask = extract32(maskreg, 8, 4);
47
uint32_t reg = extract32(maskreg, 0, 8);
48
+ int cur_el = arm_current_el(env);
49
50
- if (arm_current_el(env) == 0 && reg > 7) {
51
- /* only xPSR sub-fields may be written by unprivileged */
52
+ if (cur_el == 0 && reg > 7 && reg != 20) {
53
+ /*
54
+ * only xPSR sub-fields and CONTROL.SFPA may be written by
55
+ * unprivileged code
61
+ */
56
+ */
62
+ s->regs[RNG_DATA] = aspeed_scu_get_random();
57
return;
63
+ break;
58
}
64
case WAKEUP_EN:
59
65
qemu_log_mask(LOG_GUEST_ERROR,
60
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
66
"%s: Read of write-only offset 0x%" HWADDR_PRIx "\n",
61
env->v7m.control[M_REG_NS] &= ~R_V7M_CONTROL_NPRIV_MASK;
62
env->v7m.control[M_REG_NS] |= val & R_V7M_CONTROL_NPRIV_MASK;
63
}
64
+ /*
65
+ * SFPA is RAZ/WI from NS. FPCA is RO if NSACR.CP10 == 0,
66
+ * RES0 if the FPU is not present, and is stored in the S bank
67
+ */
68
+ if (arm_feature(env, ARM_FEATURE_VFP) &&
69
+ extract32(env->v7m.nsacr, 10, 1)) {
70
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
71
+ env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK;
72
+ }
73
return;
74
case 0x98: /* SP_NS */
75
{
76
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
77
env->v7m.faultmask[env->v7m.secure] = val & 1;
78
break;
79
case 20: /* CONTROL */
80
- /* Writing to the SPSEL bit only has an effect if we are in
81
+ /*
82
+ * Writing to the SPSEL bit only has an effect if we are in
83
* thread mode; other bits can be updated by any privileged code.
84
* write_v7m_control_spsel() deals with updating the SPSEL bit in
85
* env->v7m.control, so we only need update the others.
86
* For v7M, we must just ignore explicit writes to SPSEL in handler
87
* mode; for v8M the write is permitted but will have no effect.
88
+ * All these bits are writes-ignored from non-privileged code,
89
+ * except for SFPA.
90
*/
91
- if (arm_feature(env, ARM_FEATURE_V8) ||
92
- !arm_v7m_is_handler_mode(env)) {
93
+ if (cur_el > 0 && (arm_feature(env, ARM_FEATURE_V8) ||
94
+ !arm_v7m_is_handler_mode(env))) {
95
write_v7m_control_spsel(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 0);
96
}
97
- if (arm_feature(env, ARM_FEATURE_M_MAIN)) {
98
+ if (cur_el > 0 && arm_feature(env, ARM_FEATURE_M_MAIN)) {
99
env->v7m.control[env->v7m.secure] &= ~R_V7M_CONTROL_NPRIV_MASK;
100
env->v7m.control[env->v7m.secure] |= val & R_V7M_CONTROL_NPRIV_MASK;
101
}
102
+ if (arm_feature(env, ARM_FEATURE_VFP)) {
103
+ /*
104
+ * SFPA is RAZ/WI from NS or if no FPU.
105
+ * FPCA is RO if NSACR.CP10 == 0, RES0 if the FPU is not present.
106
+ * Both are stored in the S bank.
107
+ */
108
+ if (env->v7m.secure) {
109
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
110
+ env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_SFPA_MASK;
111
+ }
112
+ if (cur_el > 0 &&
113
+ (env->v7m.secure || !arm_feature(env, ARM_FEATURE_M_SECURITY) ||
114
+ extract32(env->v7m.nsacr, 10, 1))) {
115
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
116
+ env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK;
117
+ }
118
+ }
119
break;
120
default:
121
bad_reg:
67
--
122
--
68
2.17.1
123
2.20.1
69
124
70
125
diff view generated by jsdifflib
1
The API for cpu_transaction_failed() says that it takes the physical
1
Currently the code in v7m_push_stack() which detects a violation
2
address for the failed transaction. However we were actually passing
2
of the v8M stack limit simply returns early if it does so. This
3
it the offset within the target MemoryRegion. We don't currently
3
is OK for the current integer-only code, but won't work for the
4
have any target CPU implementations of this hook that require the
4
floating point handling we're about to add. We need to continue
5
physical address; fix this bug so we don't get confused if we ever
5
executing the rest of the function so that we check for other
6
do add one.
6
exceptions like not having permission to use the FPU and so
7
that we correctly set the FPCCR state if we are doing lazy
8
stacking. Refactor to avoid the early return.
7
9
8
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20180611125633.32755-3-peter.maydell@linaro.org
12
Message-id: 20190416125744.27770-10-peter.maydell@linaro.org
13
---
13
---
14
include/exec/exec-all.h | 13 ++++++++++--
14
target/arm/helper.c | 23 ++++++++++++++++++-----
15
accel/tcg/cputlb.c | 44 +++++++++++++++++++++++++++++------------
15
1 file changed, 18 insertions(+), 5 deletions(-)
16
exec.c | 5 +++--
17
3 files changed, 45 insertions(+), 17 deletions(-)
18
16
19
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/include/exec/exec-all.h
19
--- a/target/arm/helper.c
22
+++ b/include/exec/exec-all.h
20
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@ void tb_lock_reset(void);
21
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
24
22
* should ignore further stack faults trying to process
25
#if !defined(CONFIG_USER_ONLY)
23
* that derived exception.)
26
24
*/
27
-struct MemoryRegion *iotlb_to_region(CPUState *cpu,
25
- bool stacked_ok;
28
- hwaddr index, MemTxAttrs attrs);
26
+ bool stacked_ok = true, limitviol = false;
29
+/**
27
CPUARMState *env = &cpu->env;
30
+ * iotlb_to_section:
28
uint32_t xpsr = xpsr_read(env);
31
+ * @cpu: CPU performing the access
29
uint32_t frameptr = env->regs[13];
32
+ * @index: TCG CPU IOTLB entry
30
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
33
+ *
31
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
34
+ * Given a TCG CPU IOTLB entry, return the MemoryRegionSection that
32
env->v7m.secure);
35
+ * it refers to. @index will have been initially created and returned
33
env->regs[13] = limit;
36
+ * by memory_region_section_get_iotlb().
34
- return true;
37
+ */
35
+ /*
38
+struct MemoryRegionSection *iotlb_to_section(CPUState *cpu,
36
+ * We won't try to perform any further memory accesses but
39
+ hwaddr index, MemTxAttrs attrs);
37
+ * we must continue through the following code to check for
40
38
+ * permission faults during FPU state preservation, and we
41
void tlb_fill(CPUState *cpu, target_ulong addr, int size,
39
+ * must update FPCCR if lazy stacking is enabled.
42
MMUAccessType access_type, int mmu_idx, uintptr_t retaddr);
40
+ */
43
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
41
+ limitviol = true;
44
index XXXXXXX..XXXXXXX 100644
42
+ stacked_ok = false;
45
--- a/accel/tcg/cputlb.c
46
+++ b/accel/tcg/cputlb.c
47
@@ -XXX,XX +XXX,XX @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
48
target_ulong addr, uintptr_t retaddr, int size)
49
{
50
CPUState *cpu = ENV_GET_CPU(env);
51
- hwaddr physaddr = iotlbentry->addr;
52
- MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs);
53
+ hwaddr mr_offset;
54
+ MemoryRegionSection *section;
55
+ MemoryRegion *mr;
56
uint64_t val;
57
bool locked = false;
58
MemTxResult r;
59
60
- physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
61
+ section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
62
+ mr = section->mr;
63
+ mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
64
cpu->mem_io_pc = retaddr;
65
if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu->can_do_io) {
66
cpu_io_recompile(cpu, retaddr);
67
@@ -XXX,XX +XXX,XX @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
68
qemu_mutex_lock_iothread();
69
locked = true;
70
}
71
- r = memory_region_dispatch_read(mr, physaddr,
72
+ r = memory_region_dispatch_read(mr, mr_offset,
73
&val, size, iotlbentry->attrs);
74
if (r != MEMTX_OK) {
75
+ hwaddr physaddr = mr_offset +
76
+ section->offset_within_address_space -
77
+ section->offset_within_region;
78
+
79
cpu_transaction_failed(cpu, physaddr, addr, size, MMU_DATA_LOAD,
80
mmu_idx, iotlbentry->attrs, r, retaddr);
81
}
82
@@ -XXX,XX +XXX,XX @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
83
uintptr_t retaddr, int size)
84
{
85
CPUState *cpu = ENV_GET_CPU(env);
86
- hwaddr physaddr = iotlbentry->addr;
87
- MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs);
88
+ hwaddr mr_offset;
89
+ MemoryRegionSection *section;
90
+ MemoryRegion *mr;
91
bool locked = false;
92
MemTxResult r;
93
94
- physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
95
+ section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
96
+ mr = section->mr;
97
+ mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
98
if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu->can_do_io) {
99
cpu_io_recompile(cpu, retaddr);
100
}
101
@@ -XXX,XX +XXX,XX @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
102
qemu_mutex_lock_iothread();
103
locked = true;
104
}
105
- r = memory_region_dispatch_write(mr, physaddr,
106
+ r = memory_region_dispatch_write(mr, mr_offset,
107
val, size, iotlbentry->attrs);
108
if (r != MEMTX_OK) {
109
+ hwaddr physaddr = mr_offset +
110
+ section->offset_within_address_space -
111
+ section->offset_within_region;
112
+
113
cpu_transaction_failed(cpu, physaddr, addr, size, MMU_DATA_STORE,
114
mmu_idx, iotlbentry->attrs, r, retaddr);
115
}
116
@@ -XXX,XX +XXX,XX @@ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
117
*/
118
tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
119
{
120
- int mmu_idx, index, pd;
121
+ int mmu_idx, index;
122
void *p;
123
MemoryRegion *mr;
124
+ MemoryRegionSection *section;
125
CPUState *cpu = ENV_GET_CPU(env);
126
CPUIOTLBEntry *iotlbentry;
127
- hwaddr physaddr;
128
+ hwaddr physaddr, mr_offset;
129
130
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
131
mmu_idx = cpu_mmu_index(env, true);
132
@@ -XXX,XX +XXX,XX @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
133
}
43
}
134
}
44
}
135
iotlbentry = &env->iotlb[mmu_idx][index];
45
136
- pd = iotlbentry->addr & ~TARGET_PAGE_MASK;
46
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
137
- mr = iotlb_to_region(cpu, pd, iotlbentry->attrs);
47
* (which may be taken in preference to the one we started with
138
+ section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
48
* if it has higher priority).
139
+ mr = section->mr;
49
*/
140
if (memory_region_is_unassigned(mr)) {
50
- stacked_ok =
141
qemu_mutex_lock_iothread();
51
+ stacked_ok = stacked_ok &&
142
if (memory_region_request_mmio_ptr(mr, addr)) {
52
v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, false) &&
143
@@ -XXX,XX +XXX,XX @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
53
v7m_stack_write(cpu, frameptr + 4, env->regs[1], mmu_idx, false) &&
144
* and use the MemTXResult it produced). However it is the
54
v7m_stack_write(cpu, frameptr + 8, env->regs[2], mmu_idx, false) &&
145
* simplest place we have currently available for the check.
55
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
146
*/
56
v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
147
- physaddr = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
57
v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
148
+ mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
58
149
+ physaddr = mr_offset +
59
- /* Update SP regardless of whether any of the stack accesses failed. */
150
+ section->offset_within_address_space -
60
- env->regs[13] = frameptr;
151
+ section->offset_within_region;
61
+ /*
152
cpu_transaction_failed(cpu, physaddr, addr, 0, MMU_INST_FETCH, mmu_idx,
62
+ * If we broke a stack limit then SP was already updated earlier;
153
iotlbentry->attrs, MEMTX_DECODE_ERROR, 0);
63
+ * otherwise we update SP regardless of whether any of the stack
154
64
+ * accesses failed or we took some other kind of fault.
155
diff --git a/exec.c b/exec.c
65
+ */
156
index XXXXXXX..XXXXXXX 100644
66
+ if (!limitviol) {
157
--- a/exec.c
67
+ env->regs[13] = frameptr;
158
+++ b/exec.c
68
+ }
159
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps readonly_mem_ops = {
69
160
},
70
return !stacked_ok;
161
};
162
163
-MemoryRegion *iotlb_to_region(CPUState *cpu, hwaddr index, MemTxAttrs attrs)
164
+MemoryRegionSection *iotlb_to_section(CPUState *cpu,
165
+ hwaddr index, MemTxAttrs attrs)
166
{
167
int asidx = cpu_asidx_from_attrs(cpu, attrs);
168
CPUAddressSpace *cpuas = &cpu->cpu_ases[asidx];
169
AddressSpaceDispatch *d = atomic_rcu_read(&cpuas->memory_dispatch);
170
MemoryRegionSection *sections = d->map.sections;
171
172
- return sections[index & ~TARGET_PAGE_MASK].mr;
173
+ return &sections[index & ~TARGET_PAGE_MASK];
174
}
71
}
175
176
static void io_mem_init(void)
177
--
72
--
178
2.17.1
73
2.20.1
179
74
180
75
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Handle floating point registers in exception entry.
2
This corresponds to the FP-specific parts of the pseudocode
3
functions ActivateException() and PushStack().
2
4
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
We defer the code corresponding to UpdateFPCCR() to a later patch.
4
Message-id: 20180613015641.5667-16-richard.henderson@linaro.org
6
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-11-peter.maydell@linaro.org
7
---
10
---
8
target/arm/helper-sve.h | 2 +
11
target/arm/helper.c | 98 +++++++++++++++++++++++++++++++++++++++++++--
9
target/arm/sve_helper.c | 31 ++++++++++++
12
1 file changed, 95 insertions(+), 3 deletions(-)
10
target/arm/translate-sve.c | 99 ++++++++++++++++++++++++++++++++++++++
11
target/arm/sve.decode | 8 +++
12
4 files changed, 140 insertions(+)
13
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper-sve.h
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_brkn, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
18
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
19
DEF_HELPER_FLAGS_4(sve_brkns, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
19
switch_v7m_security_state(env, targets_secure);
20
20
write_v7m_control_spsel(env, 0);
21
DEF_HELPER_FLAGS_3(sve_cntp, TCG_CALL_NO_RWG, i64, ptr, ptr, i32)
21
arm_clear_exclusive(env);
22
+ /* Clear SFPA and FPCA (has no effect if no FPU) */
23
+ env->v7m.control[M_REG_S] &=
24
+ ~(R_V7M_CONTROL_FPCA_MASK | R_V7M_CONTROL_SFPA_MASK);
25
/* Clear IT bits */
26
env->condexec_bits = 0;
27
env->regs[14] = lr;
28
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
29
uint32_t xpsr = xpsr_read(env);
30
uint32_t frameptr = env->regs[13];
31
ARMMMUIdx mmu_idx = arm_mmu_idx(env);
32
+ uint32_t framesize;
33
+ bool nsacr_cp10 = extract32(env->v7m.nsacr, 10, 1);
22
+
34
+
23
+DEF_HELPER_FLAGS_3(sve_while, TCG_CALL_NO_RWG, i32, ptr, i32, i32)
35
+ if ((env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) &&
24
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
36
+ (env->v7m.secure || nsacr_cp10)) {
25
index XXXXXXX..XXXXXXX 100644
37
+ if (env->v7m.secure &&
26
--- a/target/arm/sve_helper.c
38
+ env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK) {
27
+++ b/target/arm/sve_helper.c
39
+ framesize = 0xa8;
28
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(sve_cntp)(void *vn, void *vg, uint32_t pred_desc)
40
+ } else {
41
+ framesize = 0x68;
42
+ }
43
+ } else {
44
+ framesize = 0x20;
45
+ }
46
47
/* Align stack pointer if the guest wants that */
48
if ((frameptr & 4) &&
49
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
50
xpsr |= XPSR_SPREALIGN;
29
}
51
}
30
return sum;
52
31
}
53
- frameptr -= 0x20;
32
+
54
+ xpsr &= ~XPSR_SFPA;
33
+uint32_t HELPER(sve_while)(void *vd, uint32_t count, uint32_t pred_desc)
55
+ if (env->v7m.secure &&
34
+{
56
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
35
+ uintptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
57
+ xpsr |= XPSR_SFPA;
36
+ intptr_t esz = extract32(pred_desc, SIMD_DATA_SHIFT, 2);
37
+ uint64_t esz_mask = pred_esz_masks[esz];
38
+ ARMPredicateReg *d = vd;
39
+ uint32_t flags;
40
+ intptr_t i;
41
+
42
+ /* Begin with a zero predicate register. */
43
+ flags = do_zero(d, oprsz);
44
+ if (count == 0) {
45
+ return flags;
46
+ }
58
+ }
47
+
59
+
48
+ /* Scale from predicate element count to bits. */
60
+ frameptr -= framesize;
49
+ count <<= esz;
61
50
+ /* Bound to the bits in the predicate. */
62
if (arm_feature(env, ARM_FEATURE_V8)) {
51
+ count = MIN(count, oprsz * 8);
63
uint32_t limit = v7m_sp_limit(env);
64
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
65
v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
66
v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
67
68
+ if (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) {
69
+ /* FPU is active, try to save its registers */
70
+ bool fpccr_s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
71
+ bool lspact = env->v7m.fpccr[fpccr_s] & R_V7M_FPCCR_LSPACT_MASK;
52
+
72
+
53
+ /* Set all of the requested bits. */
73
+ if (lspact && arm_feature(env, ARM_FEATURE_M_SECURITY)) {
54
+ for (i = 0; i < count / 64; ++i) {
74
+ qemu_log_mask(CPU_LOG_INT,
55
+ d->p[i] = esz_mask;
75
+ "...SecureFault because LSPACT and FPCA both set\n");
56
+ }
76
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
57
+ if (count & 63) {
77
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
58
+ d->p[i] = MAKE_64BIT_MASK(0, count & 63) & esz_mask;
78
+ } else if (!env->v7m.secure && !nsacr_cp10) {
59
+ }
79
+ qemu_log_mask(CPU_LOG_INT,
80
+ "...Secure UsageFault with CFSR.NOCP because "
81
+ "NSACR.CP10 prevents stacking FP regs\n");
82
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
83
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
84
+ } else {
85
+ if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) {
86
+ /* Lazy stacking disabled, save registers now */
87
+ int i;
88
+ bool cpacr_pass = v7m_cpacr_pass(env, env->v7m.secure,
89
+ arm_current_el(env) != 0);
60
+
90
+
61
+ return predtest_ones(d, oprsz, esz_mask);
91
+ if (stacked_ok && !cpacr_pass) {
62
+}
92
+ /*
63
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
93
+ * Take UsageFault if CPACR forbids access. The pseudocode
64
index XXXXXXX..XXXXXXX 100644
94
+ * here does a full CheckCPEnabled() but we know the NSACR
65
--- a/target/arm/translate-sve.c
95
+ * check can never fail as we have already handled that.
66
+++ b/target/arm/translate-sve.c
96
+ */
67
@@ -XXX,XX +XXX,XX @@ static bool trans_SINCDECP_z(DisasContext *s, arg_incdec2_pred *a,
97
+ qemu_log_mask(CPU_LOG_INT,
68
return true;
98
+ "...UsageFault with CFSR.NOCP because "
69
}
99
+ "CPACR.CP10 prevents stacking FP regs\n");
70
100
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
71
+/*
101
+ env->v7m.secure);
72
+ *** SVE Integer Compare Scalars Group
102
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_NOCP_MASK;
73
+ */
103
+ stacked_ok = false;
104
+ }
74
+
105
+
75
+static bool trans_CTERM(DisasContext *s, arg_CTERM *a, uint32_t insn)
106
+ for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
76
+{
107
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
77
+ if (!sve_access_check(s)) {
108
+ uint32_t faddr = frameptr + 0x20 + 4 * i;
78
+ return true;
109
+ uint32_t slo = extract64(dn, 0, 32);
79
+ }
110
+ uint32_t shi = extract64(dn, 32, 32);
80
+
111
+
81
+ TCGCond cond = (a->ne ? TCG_COND_NE : TCG_COND_EQ);
112
+ if (i >= 16) {
82
+ TCGv_i64 rn = read_cpu_reg(s, a->rn, a->sf);
113
+ faddr += 8; /* skip the slot for the FPSCR */
83
+ TCGv_i64 rm = read_cpu_reg(s, a->rm, a->sf);
114
+ }
84
+ TCGv_i64 cmp = tcg_temp_new_i64();
115
+ stacked_ok = stacked_ok &&
85
+
116
+ v7m_stack_write(cpu, faddr, slo, mmu_idx, false) &&
86
+ tcg_gen_setcond_i64(cond, cmp, rn, rm);
117
+ v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, false);
87
+ tcg_gen_extrl_i64_i32(cpu_NF, cmp);
118
+ }
88
+ tcg_temp_free_i64(cmp);
119
+ stacked_ok = stacked_ok &&
89
+
120
+ v7m_stack_write(cpu, frameptr + 0x60,
90
+ /* VF = !NF & !CF. */
121
+ vfp_get_fpscr(env), mmu_idx, false);
91
+ tcg_gen_xori_i32(cpu_VF, cpu_NF, 1);
122
+ if (cpacr_pass) {
92
+ tcg_gen_andc_i32(cpu_VF, cpu_VF, cpu_CF);
123
+ for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
93
+
124
+ *aa32_vfp_dreg(env, i / 2) = 0;
94
+ /* Both NF and VF actually look at bit 31. */
125
+ }
95
+ tcg_gen_neg_i32(cpu_NF, cpu_NF);
126
+ vfp_set_fpscr(env, 0);
96
+ tcg_gen_neg_i32(cpu_VF, cpu_VF);
127
+ }
97
+ return true;
128
+ } else {
98
+}
129
+ /* Lazy stacking enabled, save necessary info to stack later */
99
+
130
+ /* TODO : equivalent of UpdateFPCCR() pseudocode */
100
+static bool trans_WHILE(DisasContext *s, arg_WHILE *a, uint32_t insn)
131
+ }
101
+{
102
+ if (!sve_access_check(s)) {
103
+ return true;
104
+ }
105
+
106
+ TCGv_i64 op0 = read_cpu_reg(s, a->rn, 1);
107
+ TCGv_i64 op1 = read_cpu_reg(s, a->rm, 1);
108
+ TCGv_i64 t0 = tcg_temp_new_i64();
109
+ TCGv_i64 t1 = tcg_temp_new_i64();
110
+ TCGv_i32 t2, t3;
111
+ TCGv_ptr ptr;
112
+ unsigned desc, vsz = vec_full_reg_size(s);
113
+ TCGCond cond;
114
+
115
+ if (!a->sf) {
116
+ if (a->u) {
117
+ tcg_gen_ext32u_i64(op0, op0);
118
+ tcg_gen_ext32u_i64(op1, op1);
119
+ } else {
120
+ tcg_gen_ext32s_i64(op0, op0);
121
+ tcg_gen_ext32s_i64(op1, op1);
122
+ }
132
+ }
123
+ }
133
+ }
124
+
134
+
125
+ /* For the helper, compress the different conditions into a computation
135
/*
126
+ * of how many iterations for which the condition is true.
136
* If we broke a stack limit then SP was already updated earlier;
127
+ *
137
* otherwise we update SP regardless of whether any of the stack
128
+ * This is slightly complicated by 0 <= UINT64_MAX, which is nominally
138
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
129
+ * 2**64 iterations, overflowing to 0. Of course, predicate registers
139
130
+ * aren't that large, so any value >= predicate size is sufficient.
140
if (arm_feature(env, ARM_FEATURE_V8)) {
131
+ */
141
lr = R_V7M_EXCRET_RES1_MASK |
132
+ tcg_gen_sub_i64(t0, op1, op0);
142
- R_V7M_EXCRET_DCRS_MASK |
133
+
143
- R_V7M_EXCRET_FTYPE_MASK;
134
+ /* t0 = MIN(op1 - op0, vsz). */
144
+ R_V7M_EXCRET_DCRS_MASK;
135
+ tcg_gen_movi_i64(t1, vsz);
145
/* The S bit indicates whether we should return to Secure
136
+ tcg_gen_umin_i64(t0, t0, t1);
146
* or NonSecure (ie our current state).
137
+ if (a->eq) {
147
* The ES bit indicates whether we're taking this exception
138
+ /* Equality means one more iteration. */
148
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
139
+ tcg_gen_addi_i64(t0, t0, 1);
149
if (env->v7m.secure) {
140
+ }
150
lr |= R_V7M_EXCRET_S_MASK;
141
+
151
}
142
+ /* t0 = (condition true ? t0 : 0). */
152
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
143
+ cond = (a->u
153
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
144
+ ? (a->eq ? TCG_COND_LEU : TCG_COND_LTU)
154
+ }
145
+ : (a->eq ? TCG_COND_LE : TCG_COND_LT));
155
} else {
146
+ tcg_gen_movi_i64(t1, 0);
156
lr = R_V7M_EXCRET_RES1_MASK |
147
+ tcg_gen_movcond_i64(cond, t0, op0, op1, t0, t1);
157
R_V7M_EXCRET_S_MASK |
148
+
149
+ t2 = tcg_temp_new_i32();
150
+ tcg_gen_extrl_i64_i32(t2, t0);
151
+ tcg_temp_free_i64(t0);
152
+ tcg_temp_free_i64(t1);
153
+
154
+ desc = (vsz / 8) - 2;
155
+ desc = deposit32(desc, SIMD_DATA_SHIFT, 2, a->esz);
156
+ t3 = tcg_const_i32(desc);
157
+
158
+ ptr = tcg_temp_new_ptr();
159
+ tcg_gen_addi_ptr(ptr, cpu_env, pred_full_reg_offset(s, a->rd));
160
+
161
+ gen_helper_sve_while(t2, ptr, t2, t3);
162
+ do_pred_flags(t2);
163
+
164
+ tcg_temp_free_ptr(ptr);
165
+ tcg_temp_free_i32(t2);
166
+ tcg_temp_free_i32(t3);
167
+ return true;
168
+}
169
+
170
/*
171
*** SVE Memory - 32-bit Gather and Unsized Contiguous Group
172
*/
173
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
174
index XXXXXXX..XXXXXXX 100644
175
--- a/target/arm/sve.decode
176
+++ b/target/arm/sve.decode
177
@@ -XXX,XX +XXX,XX @@ SINCDECP_r_64 00100101 .. 1010 d:1 u:1 10001 10 .... ..... @incdec_pred
178
# SVE saturating inc/dec vector by predicate count
179
SINCDECP_z 00100101 .. 1010 d:1 u:1 10000 00 .... ..... @incdec2_pred
180
181
+### SVE Integer Compare - Scalars Group
182
+
183
+# SVE conditionally terminate scalars
184
+CTERM 00100101 1 sf:1 1 rm:5 001000 rn:5 ne:1 0000
185
+
186
+# SVE integer compare scalar count and limit
187
+WHILE 00100101 esz:2 1 rm:5 000 sf:1 u:1 1 rn:5 eq:1 rd:4
188
+
189
### SVE Memory - 32-bit Gather and Unsized Contiguous Group
190
191
# SVE load predicate register
192
--
158
--
193
2.17.1
159
2.20.1
194
160
195
161
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the code which updates the FPCCR register on an
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.
2
5
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180613015641.5667-14-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
Message-id: 20190416125744.27770-12-peter.maydell@linaro.org
7
---
8
---
8
target/arm/helper-sve.h | 18 +++
9
target/arm/cpu.h | 14 +++++++++
9
target/arm/sve_helper.c | 248 +++++++++++++++++++++++++++++++++++++
10
hw/intc/armv7m_nvic.c | 34 ++++++++++++++++++++++
10
target/arm/translate-sve.c | 106 ++++++++++++++++
11
target/arm/helper.c | 67 ++++++++++++++++++++++++++++++++++++++++++-
11
target/arm/sve.decode | 19 +++
12
3 files changed, 114 insertions(+), 1 deletion(-)
12
4 files changed, 391 insertions(+)
13
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
16
--- a/target/arm/cpu.h
17
+++ b/target/arm/helper-sve.h
17
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_orn_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
18
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_acknowledge_irq(void *opaque);
19
DEF_HELPER_FLAGS_5(sve_nor_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
19
* (Ignoring -1, this is the same as the RETTOBASE value before completion.)
20
DEF_HELPER_FLAGS_5(sve_nand_pppp, TCG_CALL_NO_RWG,
20
*/
21
void, ptr, ptr, ptr, ptr, i32)
21
int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure);
22
+/**
23
+ * armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
24
+ * @opaque: the NVIC
25
+ * @irq: the exception number to mark pending
26
+ * @secure: false for non-banked exceptions or for the nonsecure
27
+ * version of a banked exception, true for the secure version of a banked
28
+ * exception.
29
+ *
30
+ * Return whether an exception is "ready", i.e. whether the exception is
31
+ * enabled and is configured at a priority which would allow it to
32
+ * interrupt the current execution priority. This controls whether the
33
+ * RDY bit for it in the FPCCR is set.
34
+ */
35
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure);
36
/**
37
* armv7m_nvic_raw_execution_priority: return the raw execution priority
38
* @opaque: the NVIC
39
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/intc/armv7m_nvic.c
42
+++ b/hw/intc/armv7m_nvic.c
43
@@ -XXX,XX +XXX,XX @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
44
return ret;
45
}
46
47
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
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);
22
+
62
+
23
+DEF_HELPER_FLAGS_5(sve_brkpa, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
63
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
24
+DEF_HELPER_FLAGS_5(sve_brkpb, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
64
+ assert(!secure || banked);
25
+DEF_HELPER_FLAGS_5(sve_brkpas, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_5(sve_brkpbs, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, ptr, i32)
27
+
65
+
28
+DEF_HELPER_FLAGS_4(sve_brka_z, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
66
+ /*
29
+DEF_HELPER_FLAGS_4(sve_brkb_z, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
67
+ * HardFault is an odd special case: we always check against -1,
30
+DEF_HELPER_FLAGS_4(sve_brka_m, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
68
+ * even if we're secure and HardFault has priority -3; we never
31
+DEF_HELPER_FLAGS_4(sve_brkb_m, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
69
+ * need to check for enabled state.
70
+ */
71
+ if (irq == ARMV7M_EXCP_HARD) {
72
+ return running > -1;
73
+ }
32
+
74
+
33
+DEF_HELPER_FLAGS_4(sve_brkas_z, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
34
+DEF_HELPER_FLAGS_4(sve_brkbs_z, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_4(sve_brkas_m, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_4(sve_brkbs_m, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
37
+
76
+
38
+DEF_HELPER_FLAGS_4(sve_brkn, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
77
+ return vec->enabled &&
39
+DEF_HELPER_FLAGS_4(sve_brkns, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
78
+ exc_group_prio(s, vec->prio, secure) < running;
40
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/sve_helper.c
43
+++ b/target/arm/sve_helper.c
44
@@ -XXX,XX +XXX,XX @@ DO_CMP_PPZI_D(sve_cmpls_ppzi_d, uint64_t, <=)
45
#undef DO_CMP_PPZI_S
46
#undef DO_CMP_PPZI_D
47
#undef DO_CMP_PPZI
48
+
49
+/* Similar to the ARM LastActive pseudocode function. */
50
+static bool last_active_pred(void *vd, void *vg, intptr_t oprsz)
51
+{
52
+ intptr_t i;
53
+
54
+ for (i = QEMU_ALIGN_UP(oprsz, 8) - 8; i >= 0; i -= 8) {
55
+ uint64_t pg = *(uint64_t *)(vg + i);
56
+ if (pg) {
57
+ return (pow2floor(pg) & *(uint64_t *)(vd + i)) != 0;
58
+ }
59
+ }
60
+ return 0;
61
+}
79
+}
62
+
80
+
63
+/* Compute a mask into RETB that is true for all G, up to and including
81
/* callback when external interrupt line is changed */
64
+ * (if after) or excluding (if !after) the first G & N.
82
static void set_irq_level(void *opaque, int n, int level)
65
+ * Return true if BRK found.
83
{
66
+ */
84
diff --git a/target/arm/helper.c b/target/arm/helper.c
67
+static bool compute_brk(uint64_t *retb, uint64_t n, uint64_t g,
85
index XXXXXXX..XXXXXXX 100644
68
+ bool brk, bool after)
86
--- a/target/arm/helper.c
87
+++ b/target/arm/helper.c
88
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
89
env->thumb = addr & 1;
90
}
91
92
+static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
93
+ bool apply_splim)
69
+{
94
+{
70
+ uint64_t b;
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;
71
+
111
+
72
+ if (brk) {
112
+ env->v7m.fpcar[is_secure] = frameptr & ~0x7;
73
+ b = 0;
113
+
74
+ } else if ((g & n) == 0) {
114
+ if (apply_splim && arm_feature(env, ARM_FEATURE_V8)) {
75
+ /* For all G, no N are set; break not found. */
115
+ bool splimviol;
76
+ b = g;
116
+ uint32_t splim = v7m_sp_limit(env);
77
+ } else {
117
+ bool ign = armv7m_nvic_neg_prio_requested(nvic, is_secure) &&
78
+ /* Break somewhere in N. Locate it. */
118
+ (env->v7m.ccr[is_secure] & R_V7M_CCR_STKOFHFNMIGN_MASK);
79
+ b = g & n; /* guard true, pred true */
119
+
80
+ b = b & -b; /* first such */
120
+ splimviol = !ign && frameptr < splim;
81
+ if (after) {
121
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, SPLIMVIOL, splimviol);
82
+ b = b | (b - 1); /* break after same */
83
+ } else {
84
+ b = b - 1; /* break before same */
85
+ }
86
+ brk = true;
87
+ }
122
+ }
88
+
123
+
89
+ *retb = b;
124
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, LSPACT, 1);
90
+ return brk;
91
+}
92
+
125
+
93
+/* Compute a zeroing BRK. */
126
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, S, is_secure);
94
+static void compute_brk_z(uint64_t *d, uint64_t *n, uint64_t *g,
95
+ intptr_t oprsz, bool after)
96
+{
97
+ bool brk = false;
98
+ intptr_t i;
99
+
127
+
100
+ for (i = 0; i < DIV_ROUND_UP(oprsz, 8); ++i) {
128
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, USER, arm_current_el(env) == 0);
101
+ uint64_t this_b, this_g = g[i];
102
+
129
+
103
+ brk = compute_brk(&this_b, n[i], this_g, brk, after);
130
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, THREAD,
104
+ d[i] = this_b & this_g;
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);
105
+ }
154
+ }
106
+}
155
+}
107
+
156
+
108
+/* Likewise, but also compute flags. */
157
static bool v7m_push_stack(ARMCPU *cpu)
109
+static uint32_t compute_brks_z(uint64_t *d, uint64_t *n, uint64_t *g,
158
{
110
+ intptr_t oprsz, bool after)
159
/* Do the "set up stack frame" part of exception entry,
111
+{
160
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
112
+ uint32_t flags = PREDTEST_INIT;
161
}
113
+ bool brk = false;
162
} else {
114
+ intptr_t i;
163
/* Lazy stacking enabled, save necessary info to stack later */
115
+
164
- /* TODO : equivalent of UpdateFPCCR() pseudocode */
116
+ for (i = 0; i < DIV_ROUND_UP(oprsz, 8); ++i) {
165
+ v7m_update_fpccr(env, frameptr + 0x20, true);
117
+ uint64_t this_b, this_d, this_g = g[i];
166
}
118
+
167
}
119
+ brk = compute_brk(&this_b, n[i], this_g, brk, after);
168
}
120
+ d[i] = this_d = this_b & this_g;
121
+ flags = iter_predtest_fwd(this_d, this_g, flags);
122
+ }
123
+ return flags;
124
+}
125
+
126
+/* Compute a merging BRK. */
127
+static void compute_brk_m(uint64_t *d, uint64_t *n, uint64_t *g,
128
+ intptr_t oprsz, bool after)
129
+{
130
+ bool brk = false;
131
+ intptr_t i;
132
+
133
+ for (i = 0; i < DIV_ROUND_UP(oprsz, 8); ++i) {
134
+ uint64_t this_b, this_g = g[i];
135
+
136
+ brk = compute_brk(&this_b, n[i], this_g, brk, after);
137
+ d[i] = (this_b & this_g) | (d[i] & ~this_g);
138
+ }
139
+}
140
+
141
+/* Likewise, but also compute flags. */
142
+static uint32_t compute_brks_m(uint64_t *d, uint64_t *n, uint64_t *g,
143
+ intptr_t oprsz, bool after)
144
+{
145
+ uint32_t flags = PREDTEST_INIT;
146
+ bool brk = false;
147
+ intptr_t i;
148
+
149
+ for (i = 0; i < oprsz / 8; ++i) {
150
+ uint64_t this_b, this_d = d[i], this_g = g[i];
151
+
152
+ brk = compute_brk(&this_b, n[i], this_g, brk, after);
153
+ d[i] = this_d = (this_b & this_g) | (this_d & ~this_g);
154
+ flags = iter_predtest_fwd(this_d, this_g, flags);
155
+ }
156
+ return flags;
157
+}
158
+
159
+static uint32_t do_zero(ARMPredicateReg *d, intptr_t oprsz)
160
+{
161
+ /* It is quicker to zero the whole predicate than loop on OPRSZ.
162
+ * The compiler should turn this into 4 64-bit integer stores.
163
+ */
164
+ memset(d, 0, sizeof(ARMPredicateReg));
165
+ return PREDTEST_INIT;
166
+}
167
+
168
+void HELPER(sve_brkpa)(void *vd, void *vn, void *vm, void *vg,
169
+ uint32_t pred_desc)
170
+{
171
+ intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
172
+ if (last_active_pred(vn, vg, oprsz)) {
173
+ compute_brk_z(vd, vm, vg, oprsz, true);
174
+ } else {
175
+ do_zero(vd, oprsz);
176
+ }
177
+}
178
+
179
+uint32_t HELPER(sve_brkpas)(void *vd, void *vn, void *vm, void *vg,
180
+ uint32_t pred_desc)
181
+{
182
+ intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
183
+ if (last_active_pred(vn, vg, oprsz)) {
184
+ return compute_brks_z(vd, vm, vg, oprsz, true);
185
+ } else {
186
+ return do_zero(vd, oprsz);
187
+ }
188
+}
189
+
190
+void HELPER(sve_brkpb)(void *vd, void *vn, void *vm, void *vg,
191
+ uint32_t pred_desc)
192
+{
193
+ intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
194
+ if (last_active_pred(vn, vg, oprsz)) {
195
+ compute_brk_z(vd, vm, vg, oprsz, false);
196
+ } else {
197
+ do_zero(vd, oprsz);
198
+ }
199
+}
200
+
201
+uint32_t HELPER(sve_brkpbs)(void *vd, void *vn, void *vm, void *vg,
202
+ uint32_t pred_desc)
203
+{
204
+ intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
205
+ if (last_active_pred(vn, vg, oprsz)) {
206
+ return compute_brks_z(vd, vm, vg, oprsz, false);
207
+ } else {
208
+ return do_zero(vd, oprsz);
209
+ }
210
+}
211
+
212
+void HELPER(sve_brka_z)(void *vd, void *vn, void *vg, uint32_t pred_desc)
213
+{
214
+ intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
215
+ compute_brk_z(vd, vn, vg, oprsz, true);
216
+}
217
+
218
+uint32_t HELPER(sve_brkas_z)(void *vd, void *vn, void *vg, uint32_t pred_desc)
219
+{
220
+ intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
221
+ return compute_brks_z(vd, vn, vg, oprsz, true);
222
+}
223
+
224
+void HELPER(sve_brkb_z)(void *vd, void *vn, void *vg, uint32_t pred_desc)
225
+{
226
+ intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
227
+ compute_brk_z(vd, vn, vg, oprsz, false);
228
+}
229
+
230
+uint32_t HELPER(sve_brkbs_z)(void *vd, void *vn, void *vg, uint32_t pred_desc)
231
+{
232
+ intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
233
+ return compute_brks_z(vd, vn, vg, oprsz, false);
234
+}
235
+
236
+void HELPER(sve_brka_m)(void *vd, void *vn, void *vg, uint32_t pred_desc)
237
+{
238
+ intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
239
+ compute_brk_m(vd, vn, vg, oprsz, true);
240
+}
241
+
242
+uint32_t HELPER(sve_brkas_m)(void *vd, void *vn, void *vg, uint32_t pred_desc)
243
+{
244
+ intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
245
+ return compute_brks_m(vd, vn, vg, oprsz, true);
246
+}
247
+
248
+void HELPER(sve_brkb_m)(void *vd, void *vn, void *vg, uint32_t pred_desc)
249
+{
250
+ intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
251
+ compute_brk_m(vd, vn, vg, oprsz, false);
252
+}
253
+
254
+uint32_t HELPER(sve_brkbs_m)(void *vd, void *vn, void *vg, uint32_t pred_desc)
255
+{
256
+ intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
257
+ return compute_brks_m(vd, vn, vg, oprsz, false);
258
+}
259
+
260
+void HELPER(sve_brkn)(void *vd, void *vn, void *vg, uint32_t pred_desc)
261
+{
262
+ intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
263
+
264
+ if (!last_active_pred(vn, vg, oprsz)) {
265
+ do_zero(vd, oprsz);
266
+ }
267
+}
268
+
269
+/* As if PredTest(Ones(PL), D, esz). */
270
+static uint32_t predtest_ones(ARMPredicateReg *d, intptr_t oprsz,
271
+ uint64_t esz_mask)
272
+{
273
+ uint32_t flags = PREDTEST_INIT;
274
+ intptr_t i;
275
+
276
+ for (i = 0; i < oprsz / 8; i++) {
277
+ flags = iter_predtest_fwd(d->p[i], esz_mask, flags);
278
+ }
279
+ if (oprsz & 7) {
280
+ uint64_t mask = ~(-1ULL << (8 * (oprsz & 7)));
281
+ flags = iter_predtest_fwd(d->p[i], esz_mask & mask, flags);
282
+ }
283
+ return flags;
284
+}
285
+
286
+uint32_t HELPER(sve_brkns)(void *vd, void *vn, void *vg, uint32_t pred_desc)
287
+{
288
+ intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
289
+
290
+ if (last_active_pred(vn, vg, oprsz)) {
291
+ return predtest_ones(vd, oprsz, -1);
292
+ } else {
293
+ return do_zero(vd, oprsz);
294
+ }
295
+}
296
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
297
index XXXXXXX..XXXXXXX 100644
298
--- a/target/arm/translate-sve.c
299
+++ b/target/arm/translate-sve.c
300
@@ -XXX,XX +XXX,XX @@ DO_PPZI(CMPLS, cmpls)
301
302
#undef DO_PPZI
303
304
+/*
305
+ *** SVE Partition Break Group
306
+ */
307
+
308
+static bool do_brk3(DisasContext *s, arg_rprr_s *a,
309
+ gen_helper_gvec_4 *fn, gen_helper_gvec_flags_4 *fn_s)
310
+{
311
+ if (!sve_access_check(s)) {
312
+ return true;
313
+ }
314
+
315
+ unsigned vsz = pred_full_reg_size(s);
316
+
317
+ /* Predicate sizes may be smaller and cannot use simd_desc. */
318
+ TCGv_ptr d = tcg_temp_new_ptr();
319
+ TCGv_ptr n = tcg_temp_new_ptr();
320
+ TCGv_ptr m = tcg_temp_new_ptr();
321
+ TCGv_ptr g = tcg_temp_new_ptr();
322
+ TCGv_i32 t = tcg_const_i32(vsz - 2);
323
+
324
+ tcg_gen_addi_ptr(d, cpu_env, pred_full_reg_offset(s, a->rd));
325
+ tcg_gen_addi_ptr(n, cpu_env, pred_full_reg_offset(s, a->rn));
326
+ tcg_gen_addi_ptr(m, cpu_env, pred_full_reg_offset(s, a->rm));
327
+ tcg_gen_addi_ptr(g, cpu_env, pred_full_reg_offset(s, a->pg));
328
+
329
+ if (a->s) {
330
+ fn_s(t, d, n, m, g, t);
331
+ do_pred_flags(t);
332
+ } else {
333
+ fn(d, n, m, g, t);
334
+ }
335
+ tcg_temp_free_ptr(d);
336
+ tcg_temp_free_ptr(n);
337
+ tcg_temp_free_ptr(m);
338
+ tcg_temp_free_ptr(g);
339
+ tcg_temp_free_i32(t);
340
+ return true;
341
+}
342
+
343
+static bool do_brk2(DisasContext *s, arg_rpr_s *a,
344
+ gen_helper_gvec_3 *fn, gen_helper_gvec_flags_3 *fn_s)
345
+{
346
+ if (!sve_access_check(s)) {
347
+ return true;
348
+ }
349
+
350
+ unsigned vsz = pred_full_reg_size(s);
351
+
352
+ /* Predicate sizes may be smaller and cannot use simd_desc. */
353
+ TCGv_ptr d = tcg_temp_new_ptr();
354
+ TCGv_ptr n = tcg_temp_new_ptr();
355
+ TCGv_ptr g = tcg_temp_new_ptr();
356
+ TCGv_i32 t = tcg_const_i32(vsz - 2);
357
+
358
+ tcg_gen_addi_ptr(d, cpu_env, pred_full_reg_offset(s, a->rd));
359
+ tcg_gen_addi_ptr(n, cpu_env, pred_full_reg_offset(s, a->rn));
360
+ tcg_gen_addi_ptr(g, cpu_env, pred_full_reg_offset(s, a->pg));
361
+
362
+ if (a->s) {
363
+ fn_s(t, d, n, g, t);
364
+ do_pred_flags(t);
365
+ } else {
366
+ fn(d, n, g, t);
367
+ }
368
+ tcg_temp_free_ptr(d);
369
+ tcg_temp_free_ptr(n);
370
+ tcg_temp_free_ptr(g);
371
+ tcg_temp_free_i32(t);
372
+ return true;
373
+}
374
+
375
+static bool trans_BRKPA(DisasContext *s, arg_rprr_s *a, uint32_t insn)
376
+{
377
+ return do_brk3(s, a, gen_helper_sve_brkpa, gen_helper_sve_brkpas);
378
+}
379
+
380
+static bool trans_BRKPB(DisasContext *s, arg_rprr_s *a, uint32_t insn)
381
+{
382
+ return do_brk3(s, a, gen_helper_sve_brkpb, gen_helper_sve_brkpbs);
383
+}
384
+
385
+static bool trans_BRKA_m(DisasContext *s, arg_rpr_s *a, uint32_t insn)
386
+{
387
+ return do_brk2(s, a, gen_helper_sve_brka_m, gen_helper_sve_brkas_m);
388
+}
389
+
390
+static bool trans_BRKB_m(DisasContext *s, arg_rpr_s *a, uint32_t insn)
391
+{
392
+ return do_brk2(s, a, gen_helper_sve_brkb_m, gen_helper_sve_brkbs_m);
393
+}
394
+
395
+static bool trans_BRKA_z(DisasContext *s, arg_rpr_s *a, uint32_t insn)
396
+{
397
+ return do_brk2(s, a, gen_helper_sve_brka_z, gen_helper_sve_brkas_z);
398
+}
399
+
400
+static bool trans_BRKB_z(DisasContext *s, arg_rpr_s *a, uint32_t insn)
401
+{
402
+ return do_brk2(s, a, gen_helper_sve_brkb_z, gen_helper_sve_brkbs_z);
403
+}
404
+
405
+static bool trans_BRKN(DisasContext *s, arg_rpr_s *a, uint32_t insn)
406
+{
407
+ return do_brk2(s, a, gen_helper_sve_brkn, gen_helper_sve_brkns);
408
+}
409
+
410
/*
411
*** SVE Memory - 32-bit Gather and Unsized Contiguous Group
412
*/
413
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
414
index XXXXXXX..XXXXXXX 100644
415
--- a/target/arm/sve.decode
416
+++ b/target/arm/sve.decode
417
@@ -XXX,XX +XXX,XX @@
418
&rri_esz rd rn imm esz
419
&rrr_esz rd rn rm esz
420
&rpr_esz rd pg rn esz
421
+&rpr_s rd pg rn s
422
&rprr_s rd pg rn rm s
423
&rprr_esz rd pg rn rm esz
424
&rprrr_esz rd pg rn rm ra esz
425
@@ -XXX,XX +XXX,XX @@
426
@pd_pn ........ esz:2 .. .... ....... rn:4 . rd:4 &rr_esz
427
@rd_rn ........ esz:2 ...... ...... rn:5 rd:5 &rr_esz
428
429
+# Two operand with governing predicate, flags setting
430
+@pd_pg_pn_s ........ . s:1 ...... .. pg:4 . rn:4 . rd:4 &rpr_s
431
+
432
# Three operand with unused vector element size
433
@rd_rn_rm_e0 ........ ... rm:5 ... ... rn:5 rd:5 &rrr_esz esz=0
434
435
@@ -XXX,XX +XXX,XX @@ PFIRST 00100101 01 011 000 11000 00 .... 0 .... @pd_pn_e0
436
# SVE predicate next active
437
PNEXT 00100101 .. 011 001 11000 10 .... 0 .... @pd_pn
438
439
+### SVE Partition Break Group
440
+
441
+# SVE propagate break from previous partition
442
+BRKPA 00100101 0. 00 .... 11 .... 0 .... 0 .... @pd_pg_pn_pm_s
443
+BRKPB 00100101 0. 00 .... 11 .... 0 .... 1 .... @pd_pg_pn_pm_s
444
+
445
+# SVE partition break condition
446
+BRKA_z 00100101 0. 01000001 .... 0 .... 0 .... @pd_pg_pn_s
447
+BRKB_z 00100101 1. 01000001 .... 0 .... 0 .... @pd_pg_pn_s
448
+BRKA_m 00100101 0. 01000001 .... 0 .... 1 .... @pd_pg_pn_s
449
+BRKB_m 00100101 1. 01000001 .... 0 .... 1 .... @pd_pg_pn_s
450
+
451
+# SVE propagate break to next partition
452
+BRKN 00100101 0. 01100001 .... 0 .... 0 .... @pd_pg_pn_s
453
+
454
### SVE Memory - 32-bit Gather and Unsized Contiguous Group
455
456
# SVE load predicate register
457
--
169
--
458
2.17.1
170
2.20.1
459
171
460
172
diff view generated by jsdifflib
1
Convert the parallel device away from using the old_mmio field
1
For v8M floating point support, transitions from Secure
2
of MemoryRegionOps. This change only affects the memory-mapped
2
to Non-secure state via BLNS and BLXNS must clear the
3
variant, which is used by the MIPS Jazz boards 'magnum' and 'pica61'.
3
CONTROL.SFPA bit. (This corresponds to the pseudocode
4
BranchToNS() function.)
4
5
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: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180601141223.26630-7-peter.maydell@linaro.org
8
Message-id: 20190416125744.27770-13-peter.maydell@linaro.org
8
---
9
---
9
hw/char/parallel.c | 50 ++++++++++------------------------------------
10
target/arm/helper.c | 4 ++++
10
1 file changed, 11 insertions(+), 39 deletions(-)
11
1 file changed, 4 insertions(+)
11
12
12
diff --git a/hw/char/parallel.c b/hw/char/parallel.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/char/parallel.c
15
--- a/target/arm/helper.c
15
+++ b/hw/char/parallel.c
16
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ static void parallel_isa_realizefn(DeviceState *dev, Error **errp)
17
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest)
17
}
18
/* translate.c should have made BXNS UNDEF unless we're secure */
18
19
assert(env->v7m.secure);
19
/* Memory mapped interface */
20
20
-static uint32_t parallel_mm_readb (void *opaque, hwaddr addr)
21
+ if (!(dest & 1)) {
21
+static uint64_t parallel_mm_readfn(void *opaque, hwaddr addr, unsigned size)
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
22
{
23
+ }
23
ParallelState *s = opaque;
24
switch_v7m_security_state(env, dest & 1);
24
25
env->thumb = 1;
25
- return parallel_ioport_read_sw(s, addr >> s->it_shift) & 0xFF;
26
env->regs[15] = dest & ~1;
26
+ return parallel_ioport_read_sw(s, addr >> s->it_shift) &
27
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
27
+ MAKE_64BIT_MASK(0, size * 8);
28
*/
28
}
29
write_v7m_exception(env, 1);
29
30
}
30
-static void parallel_mm_writeb (void *opaque,
31
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
31
- hwaddr addr, uint32_t value)
32
switch_v7m_security_state(env, 0);
32
+static void parallel_mm_writefn(void *opaque, hwaddr addr,
33
env->thumb = 1;
33
+ uint64_t value, unsigned size)
34
env->regs[15] = dest;
34
{
35
ParallelState *s = opaque;
36
37
- parallel_ioport_write_sw(s, addr >> s->it_shift, value & 0xFF);
38
-}
39
-
40
-static uint32_t parallel_mm_readw (void *opaque, hwaddr addr)
41
-{
42
- ParallelState *s = opaque;
43
-
44
- return parallel_ioport_read_sw(s, addr >> s->it_shift) & 0xFFFF;
45
-}
46
-
47
-static void parallel_mm_writew (void *opaque,
48
- hwaddr addr, uint32_t value)
49
-{
50
- ParallelState *s = opaque;
51
-
52
- parallel_ioport_write_sw(s, addr >> s->it_shift, value & 0xFFFF);
53
-}
54
-
55
-static uint32_t parallel_mm_readl (void *opaque, hwaddr addr)
56
-{
57
- ParallelState *s = opaque;
58
-
59
- return parallel_ioport_read_sw(s, addr >> s->it_shift);
60
-}
61
-
62
-static void parallel_mm_writel (void *opaque,
63
- hwaddr addr, uint32_t value)
64
-{
65
- ParallelState *s = opaque;
66
-
67
- parallel_ioport_write_sw(s, addr >> s->it_shift, value);
68
+ parallel_ioport_write_sw(s, addr >> s->it_shift,
69
+ value & MAKE_64BIT_MASK(0, size * 8));
70
}
71
72
static const MemoryRegionOps parallel_mm_ops = {
73
- .old_mmio = {
74
- .read = { parallel_mm_readb, parallel_mm_readw, parallel_mm_readl },
75
- .write = { parallel_mm_writeb, parallel_mm_writew, parallel_mm_writel },
76
- },
77
+ .read = parallel_mm_readfn,
78
+ .write = parallel_mm_writefn,
79
+ .valid.min_access_size = 1,
80
+ .valid.max_access_size = 4,
81
.endianness = DEVICE_NATIVE_ENDIAN,
82
};
83
84
--
35
--
85
2.17.1
36
2.20.1
86
37
87
38
diff view generated by jsdifflib
1
If an IOMMU supports mappings that care about the memory
1
The TailChain() pseudocode specifies that a tail chaining
2
transaction attributes, then it no longer has a unique
2
exception should sanitize the excReturn all-ones bits and
3
address -> output mapping, but more than one. We can
3
(if there is no FPU) the excReturn FType bits; we weren't
4
represent these using an IOMMU index, analogous to TCG's
4
doing this.
5
mmu indexes.
6
5
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>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20190416125744.27770-14-peter.maydell@linaro.org
10
Message-id: 20180604152941.20374-2-peter.maydell@linaro.org
11
---
9
---
12
include/exec/memory.h | 55 +++++++++++++++++++++++++++++++++++++++++++
10
target/arm/helper.c | 8 ++++++++
13
memory.c | 23 ++++++++++++++++++
11
1 file changed, 8 insertions(+)
14
2 files changed, 78 insertions(+)
15
12
16
diff --git a/include/exec/memory.h b/include/exec/memory.h
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/include/exec/memory.h
15
--- a/target/arm/helper.c
19
+++ b/include/exec/memory.h
16
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ enum IOMMUMemoryRegionAttr {
17
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
21
* to report whenever mappings are changed, by calling
18
qemu_log_mask(CPU_LOG_INT, "...taking pending %s exception %d\n",
22
* memory_region_notify_iommu() (or, if necessary, by calling
19
targets_secure ? "secure" : "nonsecure", exc);
23
* memory_region_notify_one() for each registered notifier).
20
24
+ *
21
+ if (dotailchain) {
25
+ * Conceptually an IOMMU provides a mapping from input address
22
+ /* Sanitize LR FType and PREFIX bits */
26
+ * to an output TLB entry. If the IOMMU is aware of memory transaction
23
+ if (!arm_feature(env, ARM_FEATURE_VFP)) {
27
+ * attributes and the output TLB entry depends on the transaction
24
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
28
+ * attributes, we represent this using IOMMU indexes. Each index
25
+ }
29
+ * selects a particular translation table that the IOMMU has:
26
+ lr = deposit32(lr, 24, 8, 0xff);
30
+ * @attrs_to_index returns the IOMMU index for a set of transaction attributes
31
+ * @translate takes an input address and an IOMMU index
32
+ * and the mapping returned can only depend on the input address and the
33
+ * IOMMU index.
34
+ *
35
+ * Most IOMMUs don't care about the transaction attributes and support
36
+ * only a single IOMMU index. A more complex IOMMU might have one index
37
+ * for secure transactions and one for non-secure transactions.
38
*/
39
typedef struct IOMMUMemoryRegionClass {
40
/* private */
41
@@ -XXX,XX +XXX,XX @@ typedef struct IOMMUMemoryRegionClass {
42
*/
43
int (*get_attr)(IOMMUMemoryRegion *iommu, enum IOMMUMemoryRegionAttr attr,
44
void *data);
45
+
46
+ /* Return the IOMMU index to use for a given set of transaction attributes.
47
+ *
48
+ * Optional method: if an IOMMU only supports a single IOMMU index then
49
+ * the default implementation of memory_region_iommu_attrs_to_index()
50
+ * will return 0.
51
+ *
52
+ * The indexes supported by an IOMMU must be contiguous, starting at 0.
53
+ *
54
+ * @iommu: the IOMMUMemoryRegion
55
+ * @attrs: memory transaction attributes
56
+ */
57
+ int (*attrs_to_index)(IOMMUMemoryRegion *iommu, MemTxAttrs attrs);
58
+
59
+ /* Return the number of IOMMU indexes this IOMMU supports.
60
+ *
61
+ * Optional method: if this method is not provided, then
62
+ * memory_region_iommu_num_indexes() will return 1, indicating that
63
+ * only a single IOMMU index is supported.
64
+ *
65
+ * @iommu: the IOMMUMemoryRegion
66
+ */
67
+ int (*num_indexes)(IOMMUMemoryRegion *iommu);
68
} IOMMUMemoryRegionClass;
69
70
typedef struct CoalescedMemoryRange CoalescedMemoryRange;
71
@@ -XXX,XX +XXX,XX @@ int memory_region_iommu_get_attr(IOMMUMemoryRegion *iommu_mr,
72
enum IOMMUMemoryRegionAttr attr,
73
void *data);
74
75
+/**
76
+ * memory_region_iommu_attrs_to_index: return the IOMMU index to
77
+ * use for translations with the given memory transaction attributes.
78
+ *
79
+ * @iommu_mr: the memory region
80
+ * @attrs: the memory transaction attributes
81
+ */
82
+int memory_region_iommu_attrs_to_index(IOMMUMemoryRegion *iommu_mr,
83
+ MemTxAttrs attrs);
84
+
85
+/**
86
+ * memory_region_iommu_num_indexes: return the total number of IOMMU
87
+ * indexes that this IOMMU supports.
88
+ *
89
+ * @iommu_mr: the memory region
90
+ */
91
+int memory_region_iommu_num_indexes(IOMMUMemoryRegion *iommu_mr);
92
+
93
/**
94
* memory_region_name: get a memory region's name
95
*
96
diff --git a/memory.c b/memory.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/memory.c
99
+++ b/memory.c
100
@@ -XXX,XX +XXX,XX @@ int memory_region_iommu_get_attr(IOMMUMemoryRegion *iommu_mr,
101
return imrc->get_attr(iommu_mr, attr, data);
102
}
103
104
+int memory_region_iommu_attrs_to_index(IOMMUMemoryRegion *iommu_mr,
105
+ MemTxAttrs attrs)
106
+{
107
+ IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_GET_CLASS(iommu_mr);
108
+
109
+ if (!imrc->attrs_to_index) {
110
+ return 0;
111
+ }
27
+ }
112
+
28
+
113
+ return imrc->attrs_to_index(iommu_mr, attrs);
29
if (arm_feature(env, ARM_FEATURE_V8)) {
114
+}
30
if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
115
+
31
(lr & R_V7M_EXCRET_S_MASK)) {
116
+int memory_region_iommu_num_indexes(IOMMUMemoryRegion *iommu_mr)
117
+{
118
+ IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_GET_CLASS(iommu_mr);
119
+
120
+ if (!imrc->num_indexes) {
121
+ return 1;
122
+ }
123
+
124
+ return imrc->num_indexes(iommu_mr);
125
+}
126
+
127
void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client)
128
{
129
uint8_t mask = 1 << client;
130
--
32
--
131
2.17.1
33
2.20.1
132
34
133
35
diff view generated by jsdifflib
1
Convert the mcf5206 device away from using the old_mmio field
1
The magic value pushed onto the callee stack as an integrity
2
of MemoryRegionOps. This device is used by the an5206 board.
2
check is different if floating point is present.
3
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Acked-by: Thomas Huth <huth@tuxfamily.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20180601141223.26630-3-peter.maydell@linaro.org
6
Message-id: 20190416125744.27770-15-peter.maydell@linaro.org
7
---
7
---
8
hw/m68k/mcf5206.c | 48 +++++++++++++++++++++++++++++++++++------------
8
target/arm/helper.c | 22 +++++++++++++++++++---
9
1 file changed, 36 insertions(+), 12 deletions(-)
9
1 file changed, 19 insertions(+), 3 deletions(-)
10
10
11
diff --git a/hw/m68k/mcf5206.c b/hw/m68k/mcf5206.c
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/m68k/mcf5206.c
13
--- a/target/arm/helper.c
14
+++ b/hw/m68k/mcf5206.c
14
+++ b/target/arm/helper.c
15
@@ -XXX,XX +XXX,XX @@ static void m5206_mbar_writel(void *opaque, hwaddr offset,
15
@@ -XXX,XX +XXX,XX @@ load_fail:
16
m5206_mbar_write(s, offset, value, 4);
16
return false;
17
}
17
}
18
18
19
+static uint64_t m5206_mbar_readfn(void *opaque, hwaddr addr, unsigned size)
19
+static uint32_t v7m_integrity_sig(CPUARMState *env, uint32_t lr)
20
+{
20
+{
21
+ switch (size) {
21
+ /*
22
+ case 1:
22
+ * Return the integrity signature value for the callee-saves
23
+ return m5206_mbar_readb(opaque, addr);
23
+ * stack frame section. @lr is the exception return payload/LR value
24
+ case 2:
24
+ * whose FType bit forms bit 0 of the signature if FP is present.
25
+ return m5206_mbar_readw(opaque, addr);
25
+ */
26
+ case 4:
26
+ uint32_t sig = 0xfefa125a;
27
+ return m5206_mbar_readl(opaque, addr);
27
+
28
+ default:
28
+ if (!arm_feature(env, ARM_FEATURE_VFP) || (lr & R_V7M_EXCRET_FTYPE_MASK)) {
29
+ g_assert_not_reached();
29
+ sig |= 1;
30
+ }
30
+ }
31
+ return sig;
31
+}
32
+}
32
+
33
+
33
+static void m5206_mbar_writefn(void *opaque, hwaddr addr,
34
static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
34
+ uint64_t value, unsigned size)
35
bool ignore_faults)
35
+{
36
{
36
+ switch (size) {
37
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
37
+ case 1:
38
bool stacked_ok;
38
+ m5206_mbar_writeb(opaque, addr, value);
39
uint32_t limit;
39
+ break;
40
bool want_psp;
40
+ case 2:
41
+ uint32_t sig;
41
+ m5206_mbar_writew(opaque, addr, value);
42
42
+ break;
43
if (dotailchain) {
43
+ case 4:
44
bool mode = lr & R_V7M_EXCRET_MODE_MASK;
44
+ m5206_mbar_writel(opaque, addr, value);
45
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
45
+ break;
46
/* Write as much of the stack frame as we can. A write failure may
46
+ default:
47
* cause us to pend a derived exception.
47
+ g_assert_not_reached();
48
*/
48
+ }
49
+ sig = v7m_integrity_sig(env, lr);
49
+}
50
stacked_ok =
50
+
51
- v7m_stack_write(cpu, frameptr, 0xfefa125b, mmu_idx, ignore_faults) &&
51
static const MemoryRegionOps m5206_mbar_ops = {
52
+ v7m_stack_write(cpu, frameptr, sig, mmu_idx, ignore_faults) &&
52
- .old_mmio = {
53
v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
53
- .read = {
54
ignore_faults) &&
54
- m5206_mbar_readb,
55
v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
55
- m5206_mbar_readw,
56
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
56
- m5206_mbar_readl,
57
if (return_to_secure &&
57
- },
58
((excret & R_V7M_EXCRET_ES_MASK) == 0 ||
58
- .write = {
59
(excret & R_V7M_EXCRET_DCRS_MASK) == 0)) {
59
- m5206_mbar_writeb,
60
- uint32_t expected_sig = 0xfefa125b;
60
- m5206_mbar_writew,
61
uint32_t actual_sig;
61
- m5206_mbar_writel,
62
62
- },
63
pop_ok = v7m_stack_read(cpu, &actual_sig, frameptr, mmu_idx);
63
- },
64
64
+ .read = m5206_mbar_readfn,
65
- if (pop_ok && expected_sig != actual_sig) {
65
+ .write = m5206_mbar_writefn,
66
+ if (pop_ok && v7m_integrity_sig(env, excret) != actual_sig) {
66
+ .valid.min_access_size = 1,
67
/* Take a SecureFault on the current stack */
67
+ .valid.max_access_size = 4,
68
env->v7m.sfsr |= R_V7M_SFSR_INVIS_MASK;
68
.endianness = DEVICE_NATIVE_ENDIAN,
69
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
69
};
70
71
--
70
--
72
2.17.1
71
2.20.1
73
72
74
73
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Handle floating point registers in exception return.
2
This corresponds to pseudocode functions ValidateExceptionReturn(),
3
ExceptionReturn(), PopStack() and ConsumeExcStackFrame().
2
4
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180613015641.5667-10-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190416125744.27770-16-peter.maydell@linaro.org
7
---
8
---
8
target/arm/helper-sve.h | 2 ++
9
target/arm/helper.c | 142 +++++++++++++++++++++++++++++++++++++++++++-
9
target/arm/sve_helper.c | 37 +++++++++++++++++++++++++++++++++++++
10
1 file changed, 141 insertions(+), 1 deletion(-)
10
target/arm/translate-sve.c | 13 +++++++++++++
11
target/arm/sve.decode | 3 +++
12
4 files changed, 55 insertions(+)
13
11
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
14
--- a/target/arm/helper.c
17
+++ b/target/arm/helper-sve.h
15
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_rbit_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
16
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
19
DEF_HELPER_FLAGS_4(sve_rbit_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
17
bool rettobase = false;
20
DEF_HELPER_FLAGS_4(sve_rbit_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
18
bool exc_secure = false;
21
19
bool return_to_secure;
22
+DEF_HELPER_FLAGS_5(sve_splice, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
20
+ bool ftype;
21
+ bool restore_s16_s31;
22
23
/* If we're not in Handler mode then jumps to magic exception-exit
24
* addresses don't have magic behaviour. However for the v8M
25
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
26
excret);
27
}
28
29
+ ftype = excret & R_V7M_EXCRET_FTYPE_MASK;
23
+
30
+
24
DEF_HELPER_FLAGS_5(sve_and_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
31
+ if (!arm_feature(env, ARM_FEATURE_VFP) && !ftype) {
25
DEF_HELPER_FLAGS_5(sve_bic_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
32
+ qemu_log_mask(LOG_GUEST_ERROR, "M profile: zero FTYPE in exception "
26
DEF_HELPER_FLAGS_5(sve_eor_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
33
+ "exit PC value 0x%" PRIx32 " is UNPREDICTABLE "
27
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
34
+ "if FPU not present\n",
28
index XXXXXXX..XXXXXXX 100644
35
+ excret);
29
--- a/target/arm/sve_helper.c
36
+ ftype = true;
30
+++ b/target/arm/sve_helper.c
37
+ }
31
@@ -XXX,XX +XXX,XX @@ int32_t HELPER(sve_last_active_element)(void *vg, uint32_t pred_desc)
32
33
return last_active_element(vg, DIV_ROUND_UP(oprsz, 8), esz);
34
}
35
+
38
+
36
+void HELPER(sve_splice)(void *vd, void *vn, void *vm, void *vg, uint32_t desc)
39
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
37
+{
40
/* EXC_RETURN.ES validation check (R_SMFL). We must do this before
38
+ intptr_t opr_sz = simd_oprsz(desc) / 8;
41
* we pick which FAULTMASK to clear.
39
+ int esz = simd_data(desc);
42
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
40
+ uint64_t pg, first_g, last_g, len, mask = pred_esz_masks[esz];
43
*/
41
+ intptr_t i, first_i, last_i;
44
write_v7m_control_spsel_for_secstate(env, return_to_sp_process, exc_secure);
42
+ ARMVectorReg tmp;
45
46
+ /*
47
+ * Clear scratch FP values left in caller saved registers; this
48
+ * must happen before any kind of tail chaining.
49
+ */
50
+ if ((env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_CLRONRET_MASK) &&
51
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
52
+ if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
53
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
54
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
55
+ qemu_log_mask(CPU_LOG_INT, "...taking SecureFault on existing "
56
+ "stackframe: error during lazy state deactivation\n");
57
+ v7m_exception_taken(cpu, excret, true, false);
58
+ return;
59
+ } else {
60
+ /* Clear s0..s15 and FPSCR */
61
+ int i;
43
+
62
+
44
+ first_i = last_i = 0;
63
+ for (i = 0; i < 16; i += 2) {
45
+ first_g = last_g = 0;
64
+ *aa32_vfp_dreg(env, i / 2) = 0;
46
+
47
+ /* Find the extent of the active elements within VG. */
48
+ for (i = QEMU_ALIGN_UP(opr_sz, 8) - 8; i >= 0; i -= 8) {
49
+ pg = *(uint64_t *)(vg + i) & mask;
50
+ if (pg) {
51
+ if (last_g == 0) {
52
+ last_g = pg;
53
+ last_i = i;
54
+ }
65
+ }
55
+ first_g = pg;
66
+ vfp_set_fpscr(env, 0);
56
+ first_i = i;
57
+ }
67
+ }
58
+ }
68
+ }
59
+
69
+
60
+ len = 0;
70
if (sfault) {
61
+ if (first_g != 0) {
71
env->v7m.sfsr |= R_V7M_SFSR_INVER_MASK;
62
+ first_i = first_i * 8 + ctz64(first_g);
72
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
63
+ last_i = last_i * 8 + 63 - clz64(last_g);
73
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
64
+ len = last_i - first_i + (1 << esz);
74
}
65
+ if (vd == vm) {
75
}
66
+ vm = memcpy(&tmp, vm, opr_sz * 8);
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
+ }
67
+ }
164
+ }
68
+ swap_memmove(vd, vn + first_i, len);
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);
69
+ }
191
+ }
70
+ swap_memmove(vd + len, vm, opr_sz * 8 - len);
192
71
+}
193
/* The restored xPSR exception field will be zero if we're
72
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
194
* resuming in Thread mode. If that doesn't match what the
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/translate-sve.c
75
+++ b/target/arm/translate-sve.c
76
@@ -XXX,XX +XXX,XX @@ static bool trans_RBIT(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
77
return do_zpz_ool(s, a, fns[a->esz]);
78
}
79
80
+static bool trans_SPLICE(DisasContext *s, arg_rprr_esz *a, uint32_t insn)
81
+{
82
+ if (sve_access_check(s)) {
83
+ unsigned vsz = vec_full_reg_size(s);
84
+ tcg_gen_gvec_4_ool(vec_full_reg_offset(s, a->rd),
85
+ vec_full_reg_offset(s, a->rn),
86
+ vec_full_reg_offset(s, a->rm),
87
+ pred_full_reg_offset(s, a->pg),
88
+ vsz, vsz, a->esz, gen_helper_sve_splice);
89
+ }
90
+ return true;
91
+}
92
+
93
/*
94
*** SVE Memory - 32-bit Gather and Unsized Contiguous Group
95
*/
96
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
97
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/sve.decode
99
+++ b/target/arm/sve.decode
100
@@ -XXX,XX +XXX,XX @@ REVH 00000101 .. 1001 01 100 ... ..... ..... @rd_pg_rn
101
REVW 00000101 .. 1001 10 100 ... ..... ..... @rd_pg_rn
102
RBIT 00000101 .. 1001 11 100 ... ..... ..... @rd_pg_rn
103
104
+# SVE vector splice (predicated)
105
+SPLICE 00000101 .. 101 100 100 ... ..... ..... @rdn_pg_rm
106
+
107
### SVE Predicate Logical Operations Group
108
109
# SVE predicate logical operations
110
--
195
--
111
2.17.1
196
2.20.1
112
197
113
198
diff view generated by jsdifflib
1
In subpage_read() we perform a load of the data into a local buffer
1
Move the NS TBFLAG down from bit 19 to bit 6, which has not
2
which we then access using ldub_p(), lduw_p(), ldl_p() or ldq_p()
2
been used since commit c1e3781090b9d36c60 in 2015, when we
3
depending on its size, storing the result into the uint64_t *data.
3
started passing the entire MMU index in the TB flags rather
4
Since ldl_p() returns an 'int', this means that for the 4-byte
4
than just a 'privilege level' bit.
5
case we will sign-extend the data, whereas for 1 and 2 byte
6
reads we zero-extend it.
7
5
8
This ought not to matter since the caller will likely ignore values in
6
This rearrangement is not strictly necessary, but means that
9
the high bytes of the data, but add a cast so that we're consistent.
7
we can put M-profile-only bits next to each other rather
8
than scattered across the flag word.
10
9
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20180611171007.4165-3-peter.maydell@linaro.org
12
Message-id: 20190416125744.27770-17-peter.maydell@linaro.org
14
---
13
---
15
exec.c | 2 +-
14
target/arm/cpu.h | 11 ++++++-----
16
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 6 insertions(+), 5 deletions(-)
17
16
18
diff --git a/exec.c b/exec.c
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
20
--- a/exec.c
19
--- a/target/arm/cpu.h
21
+++ b/exec.c
20
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ static MemTxResult subpage_read(void *opaque, hwaddr addr, uint64_t *data,
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
23
*data = lduw_p(buf);
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
24
return MEMTX_OK;
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
25
case 4:
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
26
- *data = ldl_p(buf);
25
+/*
27
+ *data = (uint32_t)ldl_p(buf);
26
+ * Indicates whether cp register reads and writes by guest code should access
28
return MEMTX_OK;
27
+ * the secure or nonsecure bank of banked registers; note that this is not
29
case 8:
28
+ * the same thing as the current security state of the processor!
30
*data = ldq_p(buf);
29
+ */
30
+FIELD(TBFLAG_A32, NS, 6, 1)
31
FIELD(TBFLAG_A32, VFPEN, 7, 1)
32
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
33
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
34
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
35
* checks on the other bits at runtime
36
*/
37
FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
38
-/* Indicates whether cp register reads and writes by guest code should access
39
- * the secure or nonsecure bank of banked registers; note that this is not
40
- * the same thing as the current security state of the processor!
41
- */
42
-FIELD(TBFLAG_A32, NS, 19, 1)
43
/* For M profile only, Handler (ie not Thread) mode */
44
FIELD(TBFLAG_A32, HANDLER, 21, 1)
45
/* For M profile only, whether we should generate stack-limit checks */
31
--
46
--
32
2.17.1
47
2.20.1
33
48
34
49
diff view generated by jsdifflib
1
The Cortex-M CPU and its NVIC are two intimately intertwined parts of
1
We are close to running out of TB flags for AArch32; we could
2
the same hardware; it is not possible to use one without the other.
2
start using the cs_base word, but before we do that we can
3
Unfortunately a lot of our board models don't do any sanity checking
3
economise on our usage by sharing the same bits for the VFP
4
on the CPU type the user asks for, so a command line like
4
VECSTRIDE field and the XScale XSCALE_CPAR field. This
5
qemu-system-arm -M versatilepb -cpu cortex-m3
5
works because no XScale CPU ever had VFP.
6
will create an M3 without an NVIC, and coredump immediately.
7
In the other direction, trying a non-M-profile CPU in an M-profile
8
board won't blow up, but doesn't do anything useful either:
9
qemu-system-arm -M lm3s6965evb -cpu arm926
10
6
11
Add some checking in the NVIC and CPU realize functions that the
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
user isn't trying to use an NVIC without an M-profile CPU or
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
an M-profile CPU without an NVIC, so we can produce a helpful
9
Message-id: 20190416125744.27770-18-peter.maydell@linaro.org
14
error message rather than a core dump.
10
---
11
target/arm/cpu.h | 10 ++++++----
12
target/arm/cpu.c | 7 +++++++
13
target/arm/helper.c | 6 +++++-
14
target/arm/translate.c | 9 +++++++--
15
4 files changed, 25 insertions(+), 7 deletions(-)
15
16
16
Fixes: https://bugs.launchpad.net/qemu/+bug/1766896
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Message-id: 20180601160355.15393-1-peter.maydell@linaro.org
20
---
21
hw/arm/armv7m.c | 7 ++++++-
22
hw/intc/armv7m_nvic.c | 6 +++++-
23
target/arm/cpu.c | 18 ++++++++++++++++++
24
3 files changed, 29 insertions(+), 2 deletions(-)
25
26
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
27
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/armv7m.c
19
--- a/target/arm/cpu.h
29
+++ b/hw/arm/armv7m.c
20
+++ b/target/arm/cpu.h
30
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
31
return;
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
32
}
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
33
}
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
34
+
25
+/*
35
+ /* Tell the CPU where the NVIC is; it will fail realize if it doesn't
26
+ * We store the bottom two bits of the CPAR as TB flags and handle
36
+ * have one.
27
+ * checks on the other bits at runtime. This shares the same bits as
37
+ */
28
+ * VECSTRIDE, which is OK as no XScale CPU has VFP.
38
+ s->cpu->env.nvic = &s->nvic;
29
+ */
39
+
30
+FIELD(TBFLAG_A32, XSCALE_CPAR, 4, 2)
40
object_property_set_bool(OBJECT(s->cpu), true, "realized", &err);
31
/*
41
if (err != NULL) {
32
* Indicates whether cp register reads and writes by guest code should access
42
error_propagate(errp, err);
33
* the secure or nonsecure bank of banked registers; note that this is not
43
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
34
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
44
sbd = SYS_BUS_DEVICE(&s->nvic);
35
FIELD(TBFLAG_A32, VFPEN, 7, 1)
45
sysbus_connect_irq(sbd, 0,
36
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
46
qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
37
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
47
- s->cpu->env.nvic = &s->nvic;
38
-/* We store the bottom two bits of the CPAR as TB flags and handle
48
39
- * checks on the other bits at runtime
49
memory_region_add_subregion(&s->container, 0xe000e000,
40
- */
50
sysbus_mmio_get_region(sbd, 0));
41
-FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
51
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
42
/* For M profile only, Handler (ie not Thread) mode */
52
index XXXXXXX..XXXXXXX 100644
43
FIELD(TBFLAG_A32, HANDLER, 21, 1)
53
--- a/hw/intc/armv7m_nvic.c
44
/* For M profile only, whether we should generate stack-limit checks */
54
+++ b/hw/intc/armv7m_nvic.c
55
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
56
int regionlen;
57
58
s->cpu = ARM_CPU(qemu_get_cpu(0));
59
- assert(s->cpu);
60
+
61
+ if (!s->cpu || !arm_feature(&s->cpu->env, ARM_FEATURE_M)) {
62
+ error_setg(errp, "The NVIC can only be used with a Cortex-M CPU");
63
+ return;
64
+ }
65
66
if (s->num_irq > NVIC_MAX_IRQ) {
67
error_setg(errp, "num-irq %d exceeds NVIC maximum", s->num_irq);
68
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
45
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
69
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/cpu.c
47
--- a/target/arm/cpu.c
71
+++ b/target/arm/cpu.c
48
+++ b/target/arm/cpu.c
72
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
49
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
73
return;
50
set_feature(env, ARM_FEATURE_THUMB_DSP);
74
}
51
}
75
52
76
+#ifndef CONFIG_USER_ONLY
53
+ /*
77
+ /* The NVIC and M-profile CPU are two halves of a single piece of
54
+ * We rely on no XScale CPU having VFP so we can use the same bits in the
78
+ * hardware; trying to use one without the other is a command line
55
+ * TB flags field for VECSTRIDE and XSCALE_CPAR.
79
+ * error and will result in segfaults if not caught here.
80
+ */
56
+ */
81
+ if (arm_feature(env, ARM_FEATURE_M)) {
57
+ assert(!(arm_feature(env, ARM_FEATURE_VFP) &&
82
+ if (!env->nvic) {
58
+ arm_feature(env, ARM_FEATURE_XSCALE)));
83
+ error_setg(errp, "This board cannot be used with Cortex-M CPUs");
59
+
84
+ return;
60
if (arm_feature(env, ARM_FEATURE_V7) &&
61
!arm_feature(env, ARM_FEATURE_M) &&
62
!arm_feature(env, ARM_FEATURE_PMSA)) {
63
diff --git a/target/arm/helper.c b/target/arm/helper.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/helper.c
66
+++ b/target/arm/helper.c
67
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
68
|| arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
69
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
70
}
71
- flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
72
+ /* Note that XSCALE_CPAR shares bits with VECSTRIDE */
73
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
74
+ flags = FIELD_DP32(flags, TBFLAG_A32,
75
+ XSCALE_CPAR, env->cp15.c15_cpar);
85
+ }
76
+ }
77
}
78
79
flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
80
diff --git a/target/arm/translate.c b/target/arm/translate.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/translate.c
83
+++ b/target/arm/translate.c
84
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
85
dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
86
dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
87
dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
88
- dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
89
- dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
90
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
91
+ dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
92
+ dc->vec_stride = 0;
86
+ } else {
93
+ } else {
87
+ if (env->nvic) {
94
+ dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
88
+ error_setg(errp, "This board can only be used with Cortex-M CPUs");
95
+ dc->c15_cpar = 0;
89
+ return;
90
+ }
91
+ }
96
+ }
92
+#endif
97
dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
93
+
98
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
94
cpu_exec_realizefn(cs, &local_err);
99
regime_is_secure(env, dc->mmu_idx);
95
if (local_err != NULL) {
96
error_propagate(errp, local_err);
97
--
100
--
98
2.17.1
101
2.20.1
99
102
100
103
diff view generated by jsdifflib
1
Currently we don't support board configurations that put an IOMMU
1
The M-profile FPCCR.S bit indicates the security status of
2
in the path of the CPU's memory transactions, and instead just
2
the floating point context. In the pseudocode ExecuteFPCheck()
3
assert() if the memory region fonud in address_space_translate_for_iotlb()
3
function it is unconditionally set to match the current
4
is an IOMMUMemoryRegion.
4
security state whenever a floating point instruction is
5
executed.
5
6
6
Remove this limitation by having the function handle IOMMUs.
7
Implement this by adding a new TB flag which tracks whether
7
This is mostly straightforward, but we must make sure we have
8
FPCCR.S is different from the current security state, so
8
a notifier registered for every IOMMU that a transaction has
9
that we only need to emit the code to update it in the
9
passed through, so that we can flush the TLB appropriately
10
less-common case when it is not already set correctly.
10
when any of the IOMMUs change their mappings.
11
12
Note that we will add the handling for the other work done
13
by ExecuteFPCheck() in later commits.
11
14
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20180604152941.20374-5-peter.maydell@linaro.org
17
Message-id: 20190416125744.27770-19-peter.maydell@linaro.org
15
---
18
---
16
include/exec/exec-all.h | 3 +-
19
target/arm/cpu.h | 2 ++
17
include/qom/cpu.h | 3 +
20
target/arm/translate.h | 1 +
18
accel/tcg/cputlb.c | 3 +-
21
target/arm/helper.c | 5 +++++
19
exec.c | 135 +++++++++++++++++++++++++++++++++++++++-
22
target/arm/translate.c | 20 ++++++++++++++++++++
20
4 files changed, 140 insertions(+), 4 deletions(-)
23
4 files changed, 28 insertions(+)
21
24
22
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
25
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
24
--- a/include/exec/exec-all.h
27
--- a/target/arm/cpu.h
25
+++ b/include/exec/exec-all.h
28
+++ b/target/arm/cpu.h
26
@@ -XXX,XX +XXX,XX @@ void tb_flush_jmp_cache(CPUState *cpu, target_ulong addr);
29
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
27
30
FIELD(TBFLAG_A32, VFPEN, 7, 1)
28
MemoryRegionSection *
31
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
29
address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr addr,
32
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
30
- hwaddr *xlat, hwaddr *plen);
33
+/* For M profile only, set if FPCCR.S does not match current security state */
31
+ hwaddr *xlat, hwaddr *plen,
34
+FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
32
+ MemTxAttrs attrs, int *prot);
35
/* For M profile only, Handler (ie not Thread) mode */
33
hwaddr memory_region_section_get_iotlb(CPUState *cpu,
36
FIELD(TBFLAG_A32, HANDLER, 21, 1)
34
MemoryRegionSection *section,
37
/* For M profile only, whether we should generate stack-limit checks */
35
target_ulong vaddr,
38
diff --git a/target/arm/translate.h b/target/arm/translate.h
36
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
37
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
38
--- a/include/qom/cpu.h
40
--- a/target/arm/translate.h
39
+++ b/include/qom/cpu.h
41
+++ b/target/arm/translate.h
40
@@ -XXX,XX +XXX,XX @@ struct CPUState {
42
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
41
uint16_t pending_tlb_flush;
43
bool v7m_handler_mode;
42
44
bool v8m_secure; /* true if v8M and we're in Secure mode */
43
int hvf_fd;
45
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
46
+ bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
47
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
48
* so that top level loop can generate correct syndrome information.
49
*/
50
diff --git a/target/arm/helper.c b/target/arm/helper.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/helper.c
53
+++ b/target/arm/helper.c
54
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
55
flags = FIELD_DP32(flags, TBFLAG_A32, STACKCHECK, 1);
56
}
57
58
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
59
+ FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S) != env->v7m.secure) {
60
+ flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
61
+ }
44
+
62
+
45
+ /* track IOMMUs whose translations we've cached in the TCG TLB */
63
*pflags = flags;
46
+ GArray *iommu_notifiers;
64
*cs_base = 0;
47
};
65
}
48
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
49
QTAILQ_HEAD(CPUTailQ, CPUState);
50
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
51
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
52
--- a/accel/tcg/cputlb.c
68
--- a/target/arm/translate.c
53
+++ b/accel/tcg/cputlb.c
69
+++ b/target/arm/translate.c
54
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
70
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
71
}
55
}
72
}
56
73
57
sz = size;
74
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
58
- section = address_space_translate_for_iotlb(cpu, asidx, paddr, &xlat, &sz);
75
+ /* Handle M-profile lazy FP state mechanics */
59
+ section = address_space_translate_for_iotlb(cpu, asidx, paddr, &xlat, &sz,
60
+ attrs, &prot);
61
assert(sz >= TARGET_PAGE_SIZE);
62
63
tlb_debug("vaddr=" TARGET_FMT_lx " paddr=0x" TARGET_FMT_plx
64
diff --git a/exec.c b/exec.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/exec.c
67
+++ b/exec.c
68
@@ -XXX,XX +XXX,XX @@ MemoryRegion *flatview_translate(FlatView *fv, hwaddr addr, hwaddr *xlat,
69
return mr;
70
}
71
72
+typedef struct TCGIOMMUNotifier {
73
+ IOMMUNotifier n;
74
+ MemoryRegion *mr;
75
+ CPUState *cpu;
76
+ int iommu_idx;
77
+ bool active;
78
+} TCGIOMMUNotifier;
79
+
76
+
80
+static void tcg_iommu_unmap_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
77
+ /* Update ownership of FP context: set FPCCR.S to match current state */
81
+{
78
+ if (s->v8m_fpccr_s_wrong) {
82
+ TCGIOMMUNotifier *notifier = container_of(n, TCGIOMMUNotifier, n);
79
+ TCGv_i32 tmp;
83
+
80
+
84
+ if (!notifier->active) {
81
+ tmp = load_cpu_field(v7m.fpccr[M_REG_S]);
85
+ return;
82
+ if (s->v8m_secure) {
86
+ }
83
+ tcg_gen_ori_i32(tmp, tmp, R_V7M_FPCCR_S_MASK);
87
+ tlb_flush(notifier->cpu);
84
+ } else {
88
+ notifier->active = false;
85
+ tcg_gen_andi_i32(tmp, tmp, ~R_V7M_FPCCR_S_MASK);
89
+ /* We leave the notifier struct on the list to avoid reallocating it later.
86
+ }
90
+ * Generally the number of IOMMUs a CPU deals with will be small.
87
+ store_cpu_field(tmp, v7m.fpccr[M_REG_S]);
91
+ * In any case we can't unregister the iommu notifier from a notify
88
+ /* Don't need to do this for any further FP insns in this TB */
92
+ * callback.
89
+ s->v8m_fpccr_s_wrong = false;
93
+ */
94
+}
95
+
96
+static void tcg_register_iommu_notifier(CPUState *cpu,
97
+ IOMMUMemoryRegion *iommu_mr,
98
+ int iommu_idx)
99
+{
100
+ /* Make sure this CPU has an IOMMU notifier registered for this
101
+ * IOMMU/IOMMU index combination, so that we can flush its TLB
102
+ * when the IOMMU tells us the mappings we've cached have changed.
103
+ */
104
+ MemoryRegion *mr = MEMORY_REGION(iommu_mr);
105
+ TCGIOMMUNotifier *notifier;
106
+ int i;
107
+
108
+ for (i = 0; i < cpu->iommu_notifiers->len; i++) {
109
+ notifier = &g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier, i);
110
+ if (notifier->mr == mr && notifier->iommu_idx == iommu_idx) {
111
+ break;
112
+ }
90
+ }
113
+ }
91
+ }
114
+ if (i == cpu->iommu_notifiers->len) {
115
+ /* Not found, add a new entry at the end of the array */
116
+ cpu->iommu_notifiers = g_array_set_size(cpu->iommu_notifiers, i + 1);
117
+ notifier = &g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier, i);
118
+
92
+
119
+ notifier->mr = mr;
93
if (extract32(insn, 28, 4) == 0xf) {
120
+ notifier->iommu_idx = iommu_idx;
94
/*
121
+ notifier->cpu = cpu;
95
* Encodings with T=1 (Thumb) or unconditional (ARM):
122
+ /* Rather than trying to register interest in the specific part
96
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
123
+ * of the iommu's address space that we've accessed and then
97
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
124
+ * expand it later as subsequent accesses touch more of it, we
98
regime_is_secure(env, dc->mmu_idx);
125
+ * just register interest in the whole thing, on the assumption
99
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
126
+ * that iommu reconfiguration will be rare.
100
+ dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
127
+ */
101
dc->cp_regs = cpu->cp_regs;
128
+ iommu_notifier_init(&notifier->n,
102
dc->features = env->features;
129
+ tcg_iommu_unmap_notify,
130
+ IOMMU_NOTIFIER_UNMAP,
131
+ 0,
132
+ HWADDR_MAX,
133
+ iommu_idx);
134
+ memory_region_register_iommu_notifier(notifier->mr, &notifier->n);
135
+ }
136
+
137
+ if (!notifier->active) {
138
+ notifier->active = true;
139
+ }
140
+}
141
+
142
+static void tcg_iommu_free_notifier_list(CPUState *cpu)
143
+{
144
+ /* Destroy the CPU's notifier list */
145
+ int i;
146
+ TCGIOMMUNotifier *notifier;
147
+
148
+ for (i = 0; i < cpu->iommu_notifiers->len; i++) {
149
+ notifier = &g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier, i);
150
+ memory_region_unregister_iommu_notifier(notifier->mr, &notifier->n);
151
+ }
152
+ g_array_free(cpu->iommu_notifiers, true);
153
+}
154
+
155
/* Called from RCU critical section */
156
MemoryRegionSection *
157
address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr addr,
158
- hwaddr *xlat, hwaddr *plen)
159
+ hwaddr *xlat, hwaddr *plen,
160
+ MemTxAttrs attrs, int *prot)
161
{
162
MemoryRegionSection *section;
163
+ IOMMUMemoryRegion *iommu_mr;
164
+ IOMMUMemoryRegionClass *imrc;
165
+ IOMMUTLBEntry iotlb;
166
+ int iommu_idx;
167
AddressSpaceDispatch *d = atomic_rcu_read(&cpu->cpu_ases[asidx].memory_dispatch);
168
169
- section = address_space_translate_internal(d, addr, xlat, plen, false);
170
+ for (;;) {
171
+ section = address_space_translate_internal(d, addr, &addr, plen, false);
172
+
173
+ iommu_mr = memory_region_get_iommu(section->mr);
174
+ if (!iommu_mr) {
175
+ break;
176
+ }
177
+
178
+ imrc = memory_region_get_iommu_class_nocheck(iommu_mr);
179
+
180
+ iommu_idx = imrc->attrs_to_index(iommu_mr, attrs);
181
+ tcg_register_iommu_notifier(cpu, iommu_mr, iommu_idx);
182
+ /* We need all the permissions, so pass IOMMU_NONE so the IOMMU
183
+ * doesn't short-cut its translation table walk.
184
+ */
185
+ iotlb = imrc->translate(iommu_mr, addr, IOMMU_NONE, iommu_idx);
186
+ addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
187
+ | (addr & iotlb.addr_mask));
188
+ /* Update the caller's prot bits to remove permissions the IOMMU
189
+ * is giving us a failure response for. If we get down to no
190
+ * permissions left at all we can give up now.
191
+ */
192
+ if (!(iotlb.perm & IOMMU_RO)) {
193
+ *prot &= ~(PAGE_READ | PAGE_EXEC);
194
+ }
195
+ if (!(iotlb.perm & IOMMU_WO)) {
196
+ *prot &= ~PAGE_WRITE;
197
+ }
198
+
199
+ if (!*prot) {
200
+ goto translate_fail;
201
+ }
202
+
203
+ d = flatview_to_dispatch(address_space_to_flatview(iotlb.target_as));
204
+ }
205
206
assert(!memory_region_is_iommu(section->mr));
207
+ *xlat = addr;
208
return section;
209
+
210
+translate_fail:
211
+ return &d->map.sections[PHYS_SECTION_UNASSIGNED];
212
}
213
#endif
214
215
@@ -XXX,XX +XXX,XX @@ void cpu_exec_unrealizefn(CPUState *cpu)
216
if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
217
vmstate_unregister(NULL, &vmstate_cpu_common, cpu);
218
}
219
+#ifndef CONFIG_USER_ONLY
220
+ tcg_iommu_free_notifier_list(cpu);
221
+#endif
222
}
223
224
Property cpu_common_props[] = {
225
@@ -XXX,XX +XXX,XX @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp)
226
if (cc->vmsd != NULL) {
227
vmstate_register(NULL, cpu->cpu_index, cc->vmsd, cpu);
228
}
229
+
230
+ cpu->iommu_notifiers = g_array_new(false, true, sizeof(TCGIOMMUNotifier));
231
#endif
232
}
233
103
234
--
104
--
235
2.17.1
105
2.20.1
236
106
237
107
diff view generated by jsdifflib
1
Add support for multiple IOMMU indexes to the IOMMU notifier APIs.
1
The M-profile FPCCR.ASPEN bit indicates that automatic floating-point
2
When initializing a notifier with iommu_notifier_init(), the caller
2
context preservation is enabled. Before executing any floating-point
3
must pass the IOMMU index that it is interested in. When a change
3
instruction, if FPCCR.ASPEN is set and the CONTROL FPCA/SFPA bits
4
happens, the IOMMU implementation must pass
4
indicate that there is no active floating point context then we
5
memory_region_notify_iommu() the IOMMU index that has changed and
5
must create a new context (by initializing FPSCR and setting
6
that notifiers must be called for.
6
FPCA/SFPA to indicate that the context is now active). In the
7
pseudocode this is handled by ExecuteFPCheck().
7
8
8
IOMMUs which support only a single index don't need to change.
9
Implement this with a new TB flag which tracks whether we
9
Callers which only really support working with IOMMUs with a single
10
need to create a new FP context.
10
index can use the result of passing MEMTXATTRS_UNSPECIFIED to
11
memory_region_iommu_attrs_to_index().
12
11
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
14
Message-id: 20190416125744.27770-20-peter.maydell@linaro.org
16
Message-id: 20180604152941.20374-3-peter.maydell@linaro.org
17
---
15
---
18
include/exec/memory.h | 7 ++++++-
16
target/arm/cpu.h | 2 ++
19
hw/i386/intel_iommu.c | 6 +++---
17
target/arm/translate.h | 1 +
20
hw/ppc/spapr_iommu.c | 2 +-
18
target/arm/helper.c | 13 +++++++++++++
21
hw/s390x/s390-pci-inst.c | 4 ++--
19
target/arm/translate.c | 29 +++++++++++++++++++++++++++++
22
hw/vfio/common.c | 6 +++++-
20
4 files changed, 45 insertions(+)
23
hw/virtio/vhost.c | 7 ++++++-
24
memory.c | 8 +++++++-
25
7 files changed, 30 insertions(+), 10 deletions(-)
26
21
27
diff --git a/include/exec/memory.h b/include/exec/memory.h
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
28
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
29
--- a/include/exec/memory.h
24
--- a/target/arm/cpu.h
30
+++ b/include/exec/memory.h
25
+++ b/target/arm/cpu.h
31
@@ -XXX,XX +XXX,XX @@ struct IOMMUNotifier {
26
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
32
/* Notify for address space range start <= addr <= end */
27
FIELD(TBFLAG_A32, VFPEN, 7, 1)
33
hwaddr start;
28
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
34
hwaddr end;
29
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
35
+ int iommu_idx;
30
+/* For M profile only, set if we must create a new FP context */
36
QLIST_ENTRY(IOMMUNotifier) node;
31
+FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
37
};
32
/* For M profile only, set if FPCCR.S does not match current security state */
38
typedef struct IOMMUNotifier IOMMUNotifier;
33
FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
39
34
/* For M profile only, Handler (ie not Thread) mode */
40
static inline void iommu_notifier_init(IOMMUNotifier *n, IOMMUNotify fn,
35
diff --git a/target/arm/translate.h b/target/arm/translate.h
41
IOMMUNotifierFlag flags,
36
index XXXXXXX..XXXXXXX 100644
42
- hwaddr start, hwaddr end)
37
--- a/target/arm/translate.h
43
+ hwaddr start, hwaddr end,
38
+++ b/target/arm/translate.h
44
+ int iommu_idx)
39
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
45
{
40
bool v8m_secure; /* true if v8M and we're in Secure mode */
46
n->notify = fn;
41
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
47
n->notifier_flags = flags;
42
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
48
n->start = start;
43
+ bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
49
n->end = end;
44
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
50
+ n->iommu_idx = iommu_idx;
45
* so that top level loop can generate correct syndrome information.
46
*/
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;
51
}
70
}
52
71
diff --git a/target/arm/translate.c b/target/arm/translate.c
53
/*
54
@@ -XXX,XX +XXX,XX @@ uint64_t memory_region_iommu_get_min_page_size(IOMMUMemoryRegion *iommu_mr);
55
* should be notified with an UNMAP followed by a MAP.
56
*
57
* @iommu_mr: the memory region that was changed
58
+ * @iommu_idx: the IOMMU index for the translation table which has changed
59
* @entry: the new entry in the IOMMU translation table. The entry
60
* replaces all old entries for the same virtual I/O address range.
61
* Deleted entries have .@perm == 0.
62
*/
63
void memory_region_notify_iommu(IOMMUMemoryRegion *iommu_mr,
64
+ int iommu_idx,
65
IOMMUTLBEntry entry);
66
67
/**
68
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
69
index XXXXXXX..XXXXXXX 100644
72
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/i386/intel_iommu.c
73
--- a/target/arm/translate.c
71
+++ b/hw/i386/intel_iommu.c
74
+++ b/target/arm/translate.c
72
@@ -XXX,XX +XXX,XX @@ static int vtd_dev_to_context_entry(IntelIOMMUState *s, uint8_t bus_num,
75
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
73
static int vtd_sync_shadow_page_hook(IOMMUTLBEntry *entry,
76
/* Don't need to do this for any further FP insns in this TB */
74
void *private)
77
s->v8m_fpccr_s_wrong = false;
75
{
76
- memory_region_notify_iommu((IOMMUMemoryRegion *)private, *entry);
77
+ memory_region_notify_iommu((IOMMUMemoryRegion *)private, 0, *entry);
78
return 0;
79
}
80
81
@@ -XXX,XX +XXX,XX @@ static void vtd_iotlb_page_invalidate_notify(IntelIOMMUState *s,
82
.addr_mask = size - 1,
83
.perm = IOMMU_NONE,
84
};
85
- memory_region_notify_iommu(&vtd_as->iommu, entry);
86
+ memory_region_notify_iommu(&vtd_as->iommu, 0, entry);
87
}
88
}
78
}
89
}
90
@@ -XXX,XX +XXX,XX @@ static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s,
91
entry.iova = addr;
92
entry.perm = IOMMU_NONE;
93
entry.translated_addr = 0;
94
- memory_region_notify_iommu(&vtd_dev_as->iommu, entry);
95
+ memory_region_notify_iommu(&vtd_dev_as->iommu, 0, entry);
96
97
done:
98
return true;
99
diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/hw/ppc/spapr_iommu.c
102
+++ b/hw/ppc/spapr_iommu.c
103
@@ -XXX,XX +XXX,XX @@ static target_ulong put_tce_emu(sPAPRTCETable *tcet, target_ulong ioba,
104
entry.translated_addr = tce & page_mask;
105
entry.addr_mask = ~page_mask;
106
entry.perm = spapr_tce_iommu_access_flags(tce);
107
- memory_region_notify_iommu(&tcet->iommu, entry);
108
+ memory_region_notify_iommu(&tcet->iommu, 0, entry);
109
110
return H_SUCCESS;
111
}
112
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/hw/s390x/s390-pci-inst.c
115
+++ b/hw/s390x/s390-pci-inst.c
116
@@ -XXX,XX +XXX,XX @@ static void s390_pci_update_iotlb(S390PCIIOMMU *iommu, S390IOTLBEntry *entry)
117
}
118
119
notify.perm = IOMMU_NONE;
120
- memory_region_notify_iommu(&iommu->iommu_mr, notify);
121
+ memory_region_notify_iommu(&iommu->iommu_mr, 0, notify);
122
notify.perm = entry->perm;
123
}
124
125
@@ -XXX,XX +XXX,XX @@ static void s390_pci_update_iotlb(S390PCIIOMMU *iommu, S390IOTLBEntry *entry)
126
g_hash_table_replace(iommu->iotlb, &cache->iova, cache);
127
}
128
129
- memory_region_notify_iommu(&iommu->iommu_mr, notify);
130
+ memory_region_notify_iommu(&iommu->iommu_mr, 0, notify);
131
}
132
133
int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
134
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
135
index XXXXXXX..XXXXXXX 100644
136
--- a/hw/vfio/common.c
137
+++ b/hw/vfio/common.c
138
@@ -XXX,XX +XXX,XX @@ static void vfio_listener_region_add(MemoryListener *listener,
139
if (memory_region_is_iommu(section->mr)) {
140
VFIOGuestIOMMU *giommu;
141
IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr);
142
+ int iommu_idx;
143
144
trace_vfio_listener_region_add_iommu(iova, end);
145
/*
146
@@ -XXX,XX +XXX,XX @@ static void vfio_listener_region_add(MemoryListener *listener,
147
llend = int128_add(int128_make64(section->offset_within_region),
148
section->size);
149
llend = int128_sub(llend, int128_one());
150
+ iommu_idx = memory_region_iommu_attrs_to_index(iommu_mr,
151
+ MEMTXATTRS_UNSPECIFIED);
152
iommu_notifier_init(&giommu->n, vfio_iommu_map_notify,
153
IOMMU_NOTIFIER_ALL,
154
section->offset_within_region,
155
- int128_get64(llend));
156
+ int128_get64(llend),
157
+ iommu_idx);
158
QLIST_INSERT_HEAD(&container->giommu_list, giommu, giommu_next);
159
160
memory_region_register_iommu_notifier(section->mr, &giommu->n);
161
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
162
index XXXXXXX..XXXXXXX 100644
163
--- a/hw/virtio/vhost.c
164
+++ b/hw/virtio/vhost.c
165
@@ -XXX,XX +XXX,XX @@ static void vhost_iommu_region_add(MemoryListener *listener,
166
iommu_listener);
167
struct vhost_iommu *iommu;
168
Int128 end;
169
+ int iommu_idx;
170
+ IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr);
171
172
if (!memory_region_is_iommu(section->mr)) {
173
return;
174
@@ -XXX,XX +XXX,XX @@ static void vhost_iommu_region_add(MemoryListener *listener,
175
end = int128_add(int128_make64(section->offset_within_region),
176
section->size);
177
end = int128_sub(end, int128_one());
178
+ iommu_idx = memory_region_iommu_attrs_to_index(iommu_mr,
179
+ MEMTXATTRS_UNSPECIFIED);
180
iommu_notifier_init(&iommu->n, vhost_iommu_unmap_notify,
181
IOMMU_NOTIFIER_UNMAP,
182
section->offset_within_region,
183
- int128_get64(end));
184
+ int128_get64(end),
185
+ iommu_idx);
186
iommu->mr = section->mr;
187
iommu->iommu_offset = section->offset_within_address_space -
188
section->offset_within_region;
189
diff --git a/memory.c b/memory.c
190
index XXXXXXX..XXXXXXX 100644
191
--- a/memory.c
192
+++ b/memory.c
193
@@ -XXX,XX +XXX,XX @@ void memory_region_register_iommu_notifier(MemoryRegion *mr,
194
iommu_mr = IOMMU_MEMORY_REGION(mr);
195
assert(n->notifier_flags != IOMMU_NOTIFIER_NONE);
196
assert(n->start <= n->end);
197
+ assert(n->iommu_idx >= 0 &&
198
+ n->iommu_idx < memory_region_iommu_num_indexes(iommu_mr));
199
+
79
+
200
QLIST_INSERT_HEAD(&iommu_mr->iommu_notify, n, node);
80
+ if (s->v7m_new_fp_ctxt_needed) {
201
memory_region_update_iommu_notify_flags(iommu_mr);
81
+ /*
202
}
82
+ * Create new FP context by updating CONTROL.FPCA, CONTROL.SFPA
203
@@ -XXX,XX +XXX,XX @@ void memory_region_notify_one(IOMMUNotifier *notifier,
83
+ * and the FPSCR.
204
}
84
+ */
205
85
+ TCGv_i32 control, fpscr;
206
void memory_region_notify_iommu(IOMMUMemoryRegion *iommu_mr,
86
+ uint32_t bits = R_V7M_CONTROL_FPCA_MASK;
207
+ int iommu_idx,
87
+
208
IOMMUTLBEntry entry)
88
+ fpscr = load_cpu_field(v7m.fpdscr[s->v8m_secure]);
209
{
89
+ gen_helper_vfp_set_fpscr(cpu_env, fpscr);
210
IOMMUNotifier *iommu_notifier;
90
+ tcg_temp_free_i32(fpscr);
211
@@ -XXX,XX +XXX,XX @@ void memory_region_notify_iommu(IOMMUMemoryRegion *iommu_mr,
91
+ /*
212
assert(memory_region_is_iommu(MEMORY_REGION(iommu_mr)));
92
+ * We don't need to arrange to end the TB, because the only
213
93
+ * parts of FPSCR which we cache in the TB flags are the VECLEN
214
IOMMU_NOTIFIER_FOREACH(iommu_notifier, iommu_mr) {
94
+ * and VECSTRIDE, and those don't exist for M-profile.
215
- memory_region_notify_one(iommu_notifier, &entry);
95
+ */
216
+ if (iommu_notifier->iommu_idx == iommu_idx) {
96
+
217
+ memory_region_notify_one(iommu_notifier, &entry);
97
+ if (s->v8m_secure) {
98
+ bits |= R_V7M_CONTROL_SFPA_MASK;
99
+ }
100
+ control = load_cpu_field(v7m.control[M_REG_S]);
101
+ tcg_gen_ori_i32(control, control, bits);
102
+ store_cpu_field(control, v7m.control[M_REG_S]);
103
+ /* Don't need to do this for any further FP insns in this TB */
104
+ s->v7m_new_fp_ctxt_needed = false;
218
+ }
105
+ }
219
}
106
}
220
}
107
108
if (extract32(insn, 28, 4) == 0xf) {
109
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
110
regime_is_secure(env, dc->mmu_idx);
111
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
112
dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
113
+ dc->v7m_new_fp_ctxt_needed =
114
+ FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
115
dc->cp_regs = cpu->cp_regs;
116
dc->features = env->features;
221
117
222
--
118
--
223
2.17.1
119
2.20.1
224
120
225
121
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Add a new helper function which returns the MMU index to use
2
for v7M, where the caller specifies all of the security
3
state, privilege level and whether the execution priority
4
is negative, and reimplement the existing
5
arm_v7m_mmu_idx_for_secstate_and_priv() in terms of it.
2
6
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
We are going to need this for the lazy-FP-stacking code.
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
5
Message-id: 20180613015641.5667-17-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20190416125744.27770-21-peter.maydell@linaro.org
7
---
12
---
8
target/arm/translate-sve.c | 37 +++++++++++++++++++++++++++++++++++++
13
target/arm/cpu.h | 7 +++++++
9
target/arm/sve.decode | 8 ++++++++
14
target/arm/helper.c | 14 +++++++++++---
10
2 files changed, 45 insertions(+)
15
2 files changed, 18 insertions(+), 3 deletions(-)
11
16
12
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-sve.c
19
--- a/target/arm/cpu.h
15
+++ b/target/arm/translate-sve.c
20
+++ b/target/arm/cpu.h
16
@@ -XXX,XX +XXX,XX @@ static bool trans_WHILE(DisasContext *s, arg_WHILE *a, uint32_t insn)
21
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
17
return true;
22
}
18
}
23
}
19
24
20
+/*
25
+/*
21
+ *** SVE Integer Wide Immediate - Unpredicated Group
26
+ * Return the MMU index for a v7M CPU with all relevant information
27
+ * manually specified.
22
+ */
28
+ */
29
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
30
+ bool secstate, bool priv, bool negpri);
23
+
31
+
24
+static bool trans_FDUP(DisasContext *s, arg_FDUP *a, uint32_t insn)
32
/* Return the MMU index for a v7M CPU in the specified security and
33
* privilege state.
34
*/
35
diff --git a/target/arm/helper.c b/target/arm/helper.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper.c
38
+++ b/target/arm/helper.c
39
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
40
return 0;
41
}
42
43
-ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
44
- bool secstate, bool priv)
45
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
46
+ bool secstate, bool priv, bool negpri)
47
{
48
ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
49
50
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
51
mmu_idx |= ARM_MMU_IDX_M_PRIV;
52
}
53
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
}
62
63
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
64
+ bool secstate, bool priv)
25
+{
65
+{
26
+ if (a->esz == 0) {
66
+ bool negpri = armv7m_nvic_neg_prio_requested(env->nvic, secstate);
27
+ return false;
28
+ }
29
+ if (sve_access_check(s)) {
30
+ unsigned vsz = vec_full_reg_size(s);
31
+ int dofs = vec_full_reg_offset(s, a->rd);
32
+ uint64_t imm;
33
+
67
+
34
+ /* Decode the VFP immediate. */
68
+ return arm_v7m_mmu_idx_all(env, secstate, priv, negpri);
35
+ imm = vfp_expand_imm(a->esz, a->imm);
36
+ imm = dup_const(a->esz, imm);
37
+
38
+ tcg_gen_gvec_dup64i(dofs, vsz, vsz, imm);
39
+ }
40
+ return true;
41
+}
69
+}
42
+
70
+
43
+static bool trans_DUP_i(DisasContext *s, arg_DUP_i *a, uint32_t insn)
71
/* Return the MMU index for a v7M CPU in the specified security state */
44
+{
72
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
45
+ if (a->esz == 0 && extract32(insn, 13, 1)) {
73
{
46
+ return false;
47
+ }
48
+ if (sve_access_check(s)) {
49
+ unsigned vsz = vec_full_reg_size(s);
50
+ int dofs = vec_full_reg_offset(s, a->rd);
51
+
52
+ tcg_gen_gvec_dup64i(dofs, vsz, vsz, dup_const(a->esz, a->imm));
53
+ }
54
+ return true;
55
+}
56
+
57
/*
58
*** SVE Memory - 32-bit Gather and Unsized Contiguous Group
59
*/
60
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/sve.decode
63
+++ b/target/arm/sve.decode
64
@@ -XXX,XX +XXX,XX @@ CTERM 00100101 1 sf:1 1 rm:5 001000 rn:5 ne:1 0000
65
# SVE integer compare scalar count and limit
66
WHILE 00100101 esz:2 1 rm:5 000 sf:1 u:1 1 rn:5 eq:1 rd:4
67
68
+### SVE Integer Wide Immediate - Unpredicated Group
69
+
70
+# SVE broadcast floating-point immediate (unpredicated)
71
+FDUP 00100101 esz:2 111 00 1110 imm:8 rd:5
72
+
73
+# SVE broadcast integer immediate (unpredicated)
74
+DUP_i 00100101 esz:2 111 00 011 . ........ rd:5 imm=%sh8_i8s
75
+
76
### SVE Memory - 32-bit Gather and Unsized Contiguous Group
77
78
# SVE load predicate register
79
--
74
--
80
2.17.1
75
2.20.1
81
76
82
77
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
In the v7M architecture, if an exception is generated in the process
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.
2
9
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
This corresponds to the pseudocode TakePreserveFPException().
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
5
Message-id: 20180613015641.5667-7-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190416125744.27770-22-peter.maydell@linaro.org
7
---
15
---
8
target/arm/helper-sve.h | 2 +
16
target/arm/cpu.h | 12 ++++++
9
target/arm/sve_helper.c | 12 ++
17
hw/intc/armv7m_nvic.c | 96 +++++++++++++++++++++++++++++++++++++++++++
10
target/arm/translate-sve.c | 328 +++++++++++++++++++++++++++++++++++++
18
2 files changed, 108 insertions(+)
11
target/arm/sve.decode | 20 +++
12
4 files changed, 362 insertions(+)
13
19
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
22
--- a/target/arm/cpu.h
17
+++ b/target/arm/helper-sve.h
23
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_trn_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
24
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
19
DEF_HELPER_FLAGS_4(sve_compact_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
* a different exception).
20
DEF_HELPER_FLAGS_4(sve_compact_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
*/
21
27
void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
22
+DEF_HELPER_FLAGS_2(sve_last_active_element, TCG_CALL_NO_RWG, s32, ptr, i32)
28
+/**
29
+ * armv7m_nvic_set_pending_lazyfp: mark this lazy FP exception as pending
30
+ * @opaque: the NVIC
31
+ * @irq: the exception number to mark pending
32
+ * @secure: false for non-banked exceptions or for the nonsecure
33
+ * version of a banked exception, true for the secure version of a banked
34
+ * exception.
35
+ *
36
+ * Similar to armv7m_nvic_set_pending(), but specifically for exceptions
37
+ * generated in the course of lazy stacking of FP registers.
38
+ */
39
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure);
40
/**
41
* armv7m_nvic_get_pending_irq_info: return highest priority pending
42
* exception, and whether it targets Secure state
43
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/intc/armv7m_nvic.c
46
+++ b/hw/intc/armv7m_nvic.c
47
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
48
do_armv7m_nvic_set_pending(opaque, irq, secure, true);
49
}
50
51
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
52
+{
53
+ /*
54
+ * Pend an exception during lazy FP stacking. This differs
55
+ * from the usual exception pending because the logic for
56
+ * whether we should escalate depends on the saved context
57
+ * in the FPCCR register, not on the current state of the CPU/NVIC.
58
+ */
59
+ NVICState *s = (NVICState *)opaque;
60
+ bool banked = exc_is_banked(irq);
61
+ VecInfo *vec;
62
+ bool targets_secure;
63
+ bool escalate = false;
64
+ /*
65
+ * We will only look at bits in fpccr if this is a banked exception
66
+ * (in which case 'secure' tells us whether it is the S or NS version).
67
+ * All the bits for the non-banked exceptions are in fpccr_s.
68
+ */
69
+ uint32_t fpccr_s = s->cpu->env.v7m.fpccr[M_REG_S];
70
+ uint32_t fpccr = s->cpu->env.v7m.fpccr[secure];
23
+
71
+
24
DEF_HELPER_FLAGS_5(sve_and_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
72
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
25
DEF_HELPER_FLAGS_5(sve_bic_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
73
+ assert(!secure || banked);
26
DEF_HELPER_FLAGS_5(sve_eor_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
27
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/sve_helper.c
30
+++ b/target/arm/sve_helper.c
31
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_compact_d)(void *vd, void *vn, void *vg, uint32_t desc)
32
d[j] = 0;
33
}
34
}
35
+
74
+
36
+/* Similar to the ARM LastActiveElement pseudocode function, except the
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
37
+ * result is multiplied by the element size. This includes the not found
38
+ * indication; e.g. not found for esz=3 is -8.
39
+ */
40
+int32_t HELPER(sve_last_active_element)(void *vg, uint32_t pred_desc)
41
+{
42
+ intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
43
+ intptr_t esz = extract32(pred_desc, SIMD_DATA_SHIFT, 2);
44
+
76
+
45
+ return last_active_element(vg, DIV_ROUND_UP(oprsz, 8), esz);
77
+ targets_secure = banked ? secure : exc_targets_secure(s, irq);
46
+}
47
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/translate-sve.c
50
+++ b/target/arm/translate-sve.c
51
@@ -XXX,XX +XXX,XX @@ static bool trans_COMPACT(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
52
return do_zpz_ool(s, a, fns[a->esz]);
53
}
54
55
+/* Call the helper that computes the ARM LastActiveElement pseudocode
56
+ * function, scaled by the element size. This includes the not found
57
+ * indication; e.g. not found for esz=3 is -8.
58
+ */
59
+static void find_last_active(DisasContext *s, TCGv_i32 ret, int esz, int pg)
60
+{
61
+ /* Predicate sizes may be smaller and cannot use simd_desc. We cannot
62
+ * round up, as we do elsewhere, because we need the exact size.
63
+ */
64
+ TCGv_ptr t_p = tcg_temp_new_ptr();
65
+ TCGv_i32 t_desc;
66
+ unsigned vsz = pred_full_reg_size(s);
67
+ unsigned desc;
68
+
78
+
69
+ desc = vsz - 2;
79
+ switch (irq) {
70
+ desc = deposit32(desc, SIMD_DATA_SHIFT, 2, esz);
80
+ case ARMV7M_EXCP_DEBUG:
71
+
81
+ if (!(fpccr_s & R_V7M_FPCCR_MONRDY_MASK)) {
72
+ tcg_gen_addi_ptr(t_p, cpu_env, pred_full_reg_offset(s, pg));
82
+ /* Ignore DebugMonitor exception */
73
+ t_desc = tcg_const_i32(desc);
83
+ return;
74
+
84
+ }
75
+ gen_helper_sve_last_active_element(ret, t_p, t_desc);
76
+
77
+ tcg_temp_free_i32(t_desc);
78
+ tcg_temp_free_ptr(t_p);
79
+}
80
+
81
+/* Increment LAST to the offset of the next element in the vector,
82
+ * wrapping around to 0.
83
+ */
84
+static void incr_last_active(DisasContext *s, TCGv_i32 last, int esz)
85
+{
86
+ unsigned vsz = vec_full_reg_size(s);
87
+
88
+ tcg_gen_addi_i32(last, last, 1 << esz);
89
+ if (is_power_of_2(vsz)) {
90
+ tcg_gen_andi_i32(last, last, vsz - 1);
91
+ } else {
92
+ TCGv_i32 max = tcg_const_i32(vsz);
93
+ TCGv_i32 zero = tcg_const_i32(0);
94
+ tcg_gen_movcond_i32(TCG_COND_GEU, last, last, max, zero, last);
95
+ tcg_temp_free_i32(max);
96
+ tcg_temp_free_i32(zero);
97
+ }
98
+}
99
+
100
+/* If LAST < 0, set LAST to the offset of the last element in the vector. */
101
+static void wrap_last_active(DisasContext *s, TCGv_i32 last, int esz)
102
+{
103
+ unsigned vsz = vec_full_reg_size(s);
104
+
105
+ if (is_power_of_2(vsz)) {
106
+ tcg_gen_andi_i32(last, last, vsz - 1);
107
+ } else {
108
+ TCGv_i32 max = tcg_const_i32(vsz - (1 << esz));
109
+ TCGv_i32 zero = tcg_const_i32(0);
110
+ tcg_gen_movcond_i32(TCG_COND_LT, last, last, zero, max, last);
111
+ tcg_temp_free_i32(max);
112
+ tcg_temp_free_i32(zero);
113
+ }
114
+}
115
+
116
+/* Load an unsigned element of ESZ from BASE+OFS. */
117
+static TCGv_i64 load_esz(TCGv_ptr base, int ofs, int esz)
118
+{
119
+ TCGv_i64 r = tcg_temp_new_i64();
120
+
121
+ switch (esz) {
122
+ case 0:
123
+ tcg_gen_ld8u_i64(r, base, ofs);
124
+ break;
85
+ break;
125
+ case 1:
86
+ case ARMV7M_EXCP_MEM:
126
+ tcg_gen_ld16u_i64(r, base, ofs);
87
+ escalate = !(fpccr & R_V7M_FPCCR_MMRDY_MASK);
127
+ break;
88
+ break;
128
+ case 2:
89
+ case ARMV7M_EXCP_USAGE:
129
+ tcg_gen_ld32u_i64(r, base, ofs);
90
+ escalate = !(fpccr & R_V7M_FPCCR_UFRDY_MASK);
130
+ break;
91
+ break;
131
+ case 3:
92
+ case ARMV7M_EXCP_BUS:
132
+ tcg_gen_ld_i64(r, base, ofs);
93
+ escalate = !(fpccr_s & R_V7M_FPCCR_BFRDY_MASK);
133
+ break;
94
+ break;
134
+ default:
95
+ case ARMV7M_EXCP_SECURE:
135
+ g_assert_not_reached();
96
+ escalate = !(fpccr_s & R_V7M_FPCCR_SFRDY_MASK);
136
+ }
137
+ return r;
138
+}
139
+
140
+/* Load an unsigned element of ESZ from RM[LAST]. */
141
+static TCGv_i64 load_last_active(DisasContext *s, TCGv_i32 last,
142
+ int rm, int esz)
143
+{
144
+ TCGv_ptr p = tcg_temp_new_ptr();
145
+ TCGv_i64 r;
146
+
147
+ /* Convert offset into vector into offset into ENV.
148
+ * The final adjustment for the vector register base
149
+ * is added via constant offset to the load.
150
+ */
151
+#ifdef HOST_WORDS_BIGENDIAN
152
+ /* Adjust for element ordering. See vec_reg_offset. */
153
+ if (esz < 3) {
154
+ tcg_gen_xori_i32(last, last, 8 - (1 << esz));
155
+ }
156
+#endif
157
+ tcg_gen_ext_i32_ptr(p, last);
158
+ tcg_gen_add_ptr(p, p, cpu_env);
159
+
160
+ r = load_esz(p, vec_full_reg_offset(s, rm), esz);
161
+ tcg_temp_free_ptr(p);
162
+
163
+ return r;
164
+}
165
+
166
+/* Compute CLAST for a Zreg. */
167
+static bool do_clast_vector(DisasContext *s, arg_rprr_esz *a, bool before)
168
+{
169
+ TCGv_i32 last;
170
+ TCGLabel *over;
171
+ TCGv_i64 ele;
172
+ unsigned vsz, esz = a->esz;
173
+
174
+ if (!sve_access_check(s)) {
175
+ return true;
176
+ }
177
+
178
+ last = tcg_temp_local_new_i32();
179
+ over = gen_new_label();
180
+
181
+ find_last_active(s, last, esz, a->pg);
182
+
183
+ /* There is of course no movcond for a 2048-bit vector,
184
+ * so we must branch over the actual store.
185
+ */
186
+ tcg_gen_brcondi_i32(TCG_COND_LT, last, 0, over);
187
+
188
+ if (!before) {
189
+ incr_last_active(s, last, esz);
190
+ }
191
+
192
+ ele = load_last_active(s, last, a->rm, esz);
193
+ tcg_temp_free_i32(last);
194
+
195
+ vsz = vec_full_reg_size(s);
196
+ tcg_gen_gvec_dup_i64(esz, vec_full_reg_offset(s, a->rd), vsz, vsz, ele);
197
+ tcg_temp_free_i64(ele);
198
+
199
+ /* If this insn used MOVPRFX, we may need a second move. */
200
+ if (a->rd != a->rn) {
201
+ TCGLabel *done = gen_new_label();
202
+ tcg_gen_br(done);
203
+
204
+ gen_set_label(over);
205
+ do_mov_z(s, a->rd, a->rn);
206
+
207
+ gen_set_label(done);
208
+ } else {
209
+ gen_set_label(over);
210
+ }
211
+ return true;
212
+}
213
+
214
+static bool trans_CLASTA_z(DisasContext *s, arg_rprr_esz *a, uint32_t insn)
215
+{
216
+ return do_clast_vector(s, a, false);
217
+}
218
+
219
+static bool trans_CLASTB_z(DisasContext *s, arg_rprr_esz *a, uint32_t insn)
220
+{
221
+ return do_clast_vector(s, a, true);
222
+}
223
+
224
+/* Compute CLAST for a scalar. */
225
+static void do_clast_scalar(DisasContext *s, int esz, int pg, int rm,
226
+ bool before, TCGv_i64 reg_val)
227
+{
228
+ TCGv_i32 last = tcg_temp_new_i32();
229
+ TCGv_i64 ele, cmp, zero;
230
+
231
+ find_last_active(s, last, esz, pg);
232
+
233
+ /* Extend the original value of last prior to incrementing. */
234
+ cmp = tcg_temp_new_i64();
235
+ tcg_gen_ext_i32_i64(cmp, last);
236
+
237
+ if (!before) {
238
+ incr_last_active(s, last, esz);
239
+ }
240
+
241
+ /* The conceit here is that while last < 0 indicates not found, after
242
+ * adjusting for cpu_env->vfp.zregs[rm], it is still a valid address
243
+ * from which we can load garbage. We then discard the garbage with
244
+ * a conditional move.
245
+ */
246
+ ele = load_last_active(s, last, rm, esz);
247
+ tcg_temp_free_i32(last);
248
+
249
+ zero = tcg_const_i64(0);
250
+ tcg_gen_movcond_i64(TCG_COND_GE, reg_val, cmp, zero, ele, reg_val);
251
+
252
+ tcg_temp_free_i64(zero);
253
+ tcg_temp_free_i64(cmp);
254
+ tcg_temp_free_i64(ele);
255
+}
256
+
257
+/* Compute CLAST for a Vreg. */
258
+static bool do_clast_fp(DisasContext *s, arg_rpr_esz *a, bool before)
259
+{
260
+ if (sve_access_check(s)) {
261
+ int esz = a->esz;
262
+ int ofs = vec_reg_offset(s, a->rd, 0, esz);
263
+ TCGv_i64 reg = load_esz(cpu_env, ofs, esz);
264
+
265
+ do_clast_scalar(s, esz, a->pg, a->rn, before, reg);
266
+ write_fp_dreg(s, a->rd, reg);
267
+ tcg_temp_free_i64(reg);
268
+ }
269
+ return true;
270
+}
271
+
272
+static bool trans_CLASTA_v(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
273
+{
274
+ return do_clast_fp(s, a, false);
275
+}
276
+
277
+static bool trans_CLASTB_v(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
278
+{
279
+ return do_clast_fp(s, a, true);
280
+}
281
+
282
+/* Compute CLAST for a Xreg. */
283
+static bool do_clast_general(DisasContext *s, arg_rpr_esz *a, bool before)
284
+{
285
+ TCGv_i64 reg;
286
+
287
+ if (!sve_access_check(s)) {
288
+ return true;
289
+ }
290
+
291
+ reg = cpu_reg(s, a->rd);
292
+ switch (a->esz) {
293
+ case 0:
294
+ tcg_gen_ext8u_i64(reg, reg);
295
+ break;
296
+ case 1:
297
+ tcg_gen_ext16u_i64(reg, reg);
298
+ break;
299
+ case 2:
300
+ tcg_gen_ext32u_i64(reg, reg);
301
+ break;
302
+ case 3:
303
+ break;
97
+ break;
304
+ default:
98
+ default:
305
+ g_assert_not_reached();
99
+ g_assert_not_reached();
306
+ }
100
+ }
307
+
101
+
308
+ do_clast_scalar(s, a->esz, a->pg, a->rn, before, reg);
102
+ if (escalate) {
309
+ return true;
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
+ }
310
+}
145
+}
311
+
146
+
312
+static bool trans_CLASTA_r(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
147
/* Make pending IRQ active. */
313
+{
148
void armv7m_nvic_acknowledge_irq(void *opaque)
314
+ return do_clast_general(s, a, false);
149
{
315
+}
316
+
317
+static bool trans_CLASTB_r(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
318
+{
319
+ return do_clast_general(s, a, true);
320
+}
321
+
322
+/* Compute LAST for a scalar. */
323
+static TCGv_i64 do_last_scalar(DisasContext *s, int esz,
324
+ int pg, int rm, bool before)
325
+{
326
+ TCGv_i32 last = tcg_temp_new_i32();
327
+ TCGv_i64 ret;
328
+
329
+ find_last_active(s, last, esz, pg);
330
+ if (before) {
331
+ wrap_last_active(s, last, esz);
332
+ } else {
333
+ incr_last_active(s, last, esz);
334
+ }
335
+
336
+ ret = load_last_active(s, last, rm, esz);
337
+ tcg_temp_free_i32(last);
338
+ return ret;
339
+}
340
+
341
+/* Compute LAST for a Vreg. */
342
+static bool do_last_fp(DisasContext *s, arg_rpr_esz *a, bool before)
343
+{
344
+ if (sve_access_check(s)) {
345
+ TCGv_i64 val = do_last_scalar(s, a->esz, a->pg, a->rn, before);
346
+ write_fp_dreg(s, a->rd, val);
347
+ tcg_temp_free_i64(val);
348
+ }
349
+ return true;
350
+}
351
+
352
+static bool trans_LASTA_v(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
353
+{
354
+ return do_last_fp(s, a, false);
355
+}
356
+
357
+static bool trans_LASTB_v(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
358
+{
359
+ return do_last_fp(s, a, true);
360
+}
361
+
362
+/* Compute LAST for a Xreg. */
363
+static bool do_last_general(DisasContext *s, arg_rpr_esz *a, bool before)
364
+{
365
+ if (sve_access_check(s)) {
366
+ TCGv_i64 val = do_last_scalar(s, a->esz, a->pg, a->rn, before);
367
+ tcg_gen_mov_i64(cpu_reg(s, a->rd), val);
368
+ tcg_temp_free_i64(val);
369
+ }
370
+ return true;
371
+}
372
+
373
+static bool trans_LASTA_r(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
374
+{
375
+ return do_last_general(s, a, false);
376
+}
377
+
378
+static bool trans_LASTB_r(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
379
+{
380
+ return do_last_general(s, a, true);
381
+}
382
+
383
/*
384
*** SVE Memory - 32-bit Gather and Unsized Contiguous Group
385
*/
386
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
387
index XXXXXXX..XXXXXXX 100644
388
--- a/target/arm/sve.decode
389
+++ b/target/arm/sve.decode
390
@@ -XXX,XX +XXX,XX @@ TRN2_z 00000101 .. 1 ..... 011 101 ..... ..... @rd_rn_rm
391
# Note esz >= 2
392
COMPACT 00000101 .. 100001 100 ... ..... ..... @rd_pg_rn
393
394
+# SVE conditionally broadcast element to vector
395
+CLASTA_z 00000101 .. 10100 0 100 ... ..... ..... @rdn_pg_rm
396
+CLASTB_z 00000101 .. 10100 1 100 ... ..... ..... @rdn_pg_rm
397
+
398
+# SVE conditionally copy element to SIMD&FP scalar
399
+CLASTA_v 00000101 .. 10101 0 100 ... ..... ..... @rd_pg_rn
400
+CLASTB_v 00000101 .. 10101 1 100 ... ..... ..... @rd_pg_rn
401
+
402
+# SVE conditionally copy element to general register
403
+CLASTA_r 00000101 .. 11000 0 101 ... ..... ..... @rd_pg_rn
404
+CLASTB_r 00000101 .. 11000 1 101 ... ..... ..... @rd_pg_rn
405
+
406
+# SVE copy element to SIMD&FP scalar register
407
+LASTA_v 00000101 .. 10001 0 100 ... ..... ..... @rd_pg_rn
408
+LASTB_v 00000101 .. 10001 1 100 ... ..... ..... @rd_pg_rn
409
+
410
+# SVE copy element to general register
411
+LASTA_r 00000101 .. 10000 0 101 ... ..... ..... @rd_pg_rn
412
+LASTB_r 00000101 .. 10000 1 101 ... ..... ..... @rd_pg_rn
413
+
414
### SVE Predicate Logical Operations Group
415
416
# SVE predicate logical operations
417
--
150
--
418
2.17.1
151
2.20.1
419
152
420
153
diff view generated by jsdifflib
1
Convert the sh7750 device away from using the old_mmio field
1
Pushing registers to the stack for v7M needs to handle three cases:
2
of MemoryRegionOps. This device is used by the sh4 r2d board.
2
* the "normal" case where we pend exceptions
3
* an "ignore faults" case where we set FSR bits but
4
do not pend exceptions (this is used when we are
5
handling some kinds of derived exception on exception entry)
6
* a "lazy FP stacking" case, where different FSR bits
7
are set and the exception is pended differently
8
9
Implement this by changing the existing flag argument that
10
tells us whether to ignore faults or not into an enum that
11
specifies which of the 3 modes we should handle.
3
12
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20180601141223.26630-2-peter.maydell@linaro.org
15
Message-id: 20190416125744.27770-23-peter.maydell@linaro.org
7
---
16
---
8
hw/sh4/sh7750.c | 44 ++++++++++++++++++++++++++++++++++++--------
17
target/arm/helper.c | 118 +++++++++++++++++++++++++++++---------------
9
1 file changed, 36 insertions(+), 8 deletions(-)
18
1 file changed, 79 insertions(+), 39 deletions(-)
10
19
11
diff --git a/hw/sh4/sh7750.c b/hw/sh4/sh7750.c
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/sh4/sh7750.c
22
--- a/target/arm/helper.c
14
+++ b/hw/sh4/sh7750.c
23
+++ b/target/arm/helper.c
15
@@ -XXX,XX +XXX,XX @@ static void sh7750_mem_writel(void *opaque, hwaddr addr,
24
@@ -XXX,XX +XXX,XX @@ static bool v7m_cpacr_pass(CPUARMState *env, bool is_secure, bool is_priv)
16
}
25
}
17
}
26
}
18
27
19
+static uint64_t sh7750_mem_readfn(void *opaque, hwaddr addr, unsigned size)
28
+/*
20
+{
29
+ * What kind of stack write are we doing? This affects how exceptions
21
+ switch (size) {
30
+ * generated during the stacking are treated.
22
+ case 1:
31
+ */
23
+ return sh7750_mem_readb(opaque, addr);
32
+typedef enum StackingMode {
24
+ case 2:
33
+ STACK_NORMAL,
25
+ return sh7750_mem_readw(opaque, addr);
34
+ STACK_IGNFAULTS,
26
+ case 4:
35
+ STACK_LAZYFP,
27
+ return sh7750_mem_readl(opaque, addr);
36
+} StackingMode;
28
+ default:
29
+ g_assert_not_reached();
30
+ }
31
+}
32
+
37
+
33
+static void sh7750_mem_writefn(void *opaque, hwaddr addr,
38
static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
34
+ uint64_t value, unsigned size)
39
- ARMMMUIdx mmu_idx, bool ignfault)
35
+{
40
+ ARMMMUIdx mmu_idx, StackingMode mode)
36
+ switch (size) {
41
{
37
+ case 1:
42
CPUState *cs = CPU(cpu);
38
+ sh7750_mem_writeb(opaque, addr, value);
43
CPUARMState *env = &cpu->env;
44
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
45
&attrs, &prot, &page_size, &fi, NULL)) {
46
/* MPU/SAU lookup failed */
47
if (fi.type == ARMFault_QEMU_SFault) {
48
- qemu_log_mask(CPU_LOG_INT,
49
- "...SecureFault with SFSR.AUVIOL during stacking\n");
50
- env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK | R_V7M_SFSR_SFARVALID_MASK;
51
+ if (mode == STACK_LAZYFP) {
52
+ qemu_log_mask(CPU_LOG_INT,
53
+ "...SecureFault with SFSR.LSPERR "
54
+ "during lazy stacking\n");
55
+ env->v7m.sfsr |= R_V7M_SFSR_LSPERR_MASK;
56
+ } else {
57
+ qemu_log_mask(CPU_LOG_INT,
58
+ "...SecureFault with SFSR.AUVIOL "
59
+ "during stacking\n");
60
+ env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK;
61
+ }
62
+ env->v7m.sfsr |= R_V7M_SFSR_SFARVALID_MASK;
63
env->v7m.sfar = addr;
64
exc = ARMV7M_EXCP_SECURE;
65
exc_secure = false;
66
} else {
67
- qemu_log_mask(CPU_LOG_INT, "...MemManageFault with CFSR.MSTKERR\n");
68
- env->v7m.cfsr[secure] |= R_V7M_CFSR_MSTKERR_MASK;
69
+ if (mode == STACK_LAZYFP) {
70
+ qemu_log_mask(CPU_LOG_INT,
71
+ "...MemManageFault with CFSR.MLSPERR\n");
72
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MLSPERR_MASK;
73
+ } else {
74
+ qemu_log_mask(CPU_LOG_INT,
75
+ "...MemManageFault with CFSR.MSTKERR\n");
76
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MSTKERR_MASK;
77
+ }
78
exc = ARMV7M_EXCP_MEM;
79
exc_secure = secure;
80
}
81
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
82
attrs, &txres);
83
if (txres != MEMTX_OK) {
84
/* BusFault trying to write the data */
85
- qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.STKERR\n");
86
- env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_STKERR_MASK;
87
+ if (mode == STACK_LAZYFP) {
88
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.LSPERR\n");
89
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_LSPERR_MASK;
90
+ } else {
91
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.STKERR\n");
92
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_STKERR_MASK;
93
+ }
94
exc = ARMV7M_EXCP_BUS;
95
exc_secure = false;
96
goto pend_fault;
97
@@ -XXX,XX +XXX,XX @@ pend_fault:
98
* later if we have two derived exceptions.
99
* The only case when we must not pend the exception but instead
100
* throw it away is if we are doing the push of the callee registers
101
- * and we've already generated a derived exception. Even in this
102
- * case we will still update the fault status registers.
103
+ * and we've already generated a derived exception (this is indicated
104
+ * by the caller passing STACK_IGNFAULTS). Even in this case we will
105
+ * still update the fault status registers.
106
*/
107
- if (!ignfault) {
108
+ switch (mode) {
109
+ case STACK_NORMAL:
110
armv7m_nvic_set_pending_derived(env->nvic, exc, exc_secure);
39
+ break;
111
+ break;
40
+ case 2:
112
+ case STACK_LAZYFP:
41
+ sh7750_mem_writew(opaque, addr, value);
113
+ armv7m_nvic_set_pending_lazyfp(env->nvic, exc, exc_secure);
42
+ break;
114
+ break;
43
+ case 4:
115
+ case STACK_IGNFAULTS:
44
+ sh7750_mem_writel(opaque, addr, value);
45
+ break;
116
+ break;
46
+ default:
117
}
47
+ g_assert_not_reached();
118
return false;
48
+ }
119
}
49
+}
120
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
50
+
121
uint32_t limit;
51
static const MemoryRegionOps sh7750_mem_ops = {
122
bool want_psp;
52
- .old_mmio = {
123
uint32_t sig;
53
- .read = {sh7750_mem_readb,
124
+ StackingMode smode = ignore_faults ? STACK_IGNFAULTS : STACK_NORMAL;
54
- sh7750_mem_readw,
125
55
- sh7750_mem_readl },
126
if (dotailchain) {
56
- .write = {sh7750_mem_writeb,
127
bool mode = lr & R_V7M_EXCRET_MODE_MASK;
57
- sh7750_mem_writew,
128
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
58
- sh7750_mem_writel },
129
*/
59
- },
130
sig = v7m_integrity_sig(env, lr);
60
+ .read = sh7750_mem_readfn,
131
stacked_ok =
61
+ .write = sh7750_mem_writefn,
132
- v7m_stack_write(cpu, frameptr, sig, mmu_idx, ignore_faults) &&
62
+ .valid.min_access_size = 1,
133
- v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
63
+ .valid.max_access_size = 4,
134
- ignore_faults) &&
64
.endianness = DEVICE_NATIVE_ENDIAN,
135
- v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
65
};
136
- ignore_faults) &&
66
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;
67
--
208
--
68
2.17.1
209
2.20.1
69
210
70
211
diff view generated by jsdifflib
1
Convert the pflash_cfi02 device away from using the old_mmio field
1
The M-profile architecture floating point system supports
2
of MemoryRegionOps.
2
lazy FP state preservation, where FP registers are not
3
pushed to the stack when an exception occurs but are instead
4
only saved if and when the first FP instruction in the exception
5
handler is executed. Implement this in QEMU, corresponding
6
to the check of LSPACT in the pseudocode ExecuteFPCheck().
3
7
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Acked-by: Max Reitz <mreitz@redhat.com>
10
Message-id: 20190416125744.27770-24-peter.maydell@linaro.org
7
Message-id: 20180601141223.26630-4-peter.maydell@linaro.org
8
---
11
---
9
hw/block/pflash_cfi02.c | 97 ++++++++---------------------------------
12
target/arm/cpu.h | 3 ++
10
1 file changed, 18 insertions(+), 79 deletions(-)
13
target/arm/helper.h | 2 +
11
14
target/arm/translate.h | 1 +
12
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
15
target/arm/helper.c | 112 +++++++++++++++++++++++++++++++++++++++++
13
index XXXXXXX..XXXXXXX 100644
16
target/arm/translate.c | 22 ++++++++
14
--- a/hw/block/pflash_cfi02.c
17
5 files changed, 140 insertions(+)
15
+++ b/hw/block/pflash_cfi02.c
18
16
@@ -XXX,XX +XXX,XX @@ static void pflash_write (pflash_t *pfl, hwaddr offset,
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
pfl->cmd = 0;
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@
24
#define EXCP_NOCP 17 /* v7M NOCP UsageFault */
25
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
26
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
27
+#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
28
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
29
30
#define ARMV7M_EXCP_RESET 1
31
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
32
FIELD(TBFLAG_A32, VFPEN, 7, 1)
33
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
34
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
35
+/* For M profile only, set if FPCCR.LSPACT is set */
36
+FIELD(TBFLAG_A32, LSPACT, 18, 1)
37
/* For M profile only, set if we must create a new FP context */
38
FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
39
/* For M profile only, set if FPCCR.S does not match current security state */
40
diff --git a/target/arm/helper.h b/target/arm/helper.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/helper.h
43
+++ b/target/arm/helper.h
44
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(v7m_blxns, void, env, i32)
45
46
DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
47
48
+DEF_HELPER_1(v7m_preserve_fp_state, void, env)
49
+
50
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
51
52
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
53
diff --git a/target/arm/translate.h b/target/arm/translate.h
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/translate.h
56
+++ b/target/arm/translate.h
57
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
58
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
59
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
60
bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
61
+ bool v7m_lspact; /* FPCCR.LSPACT set */
62
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
63
* so that top level loop can generate correct syndrome information.
64
*/
65
diff --git a/target/arm/helper.c b/target/arm/helper.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/helper.c
68
+++ b/target/arm/helper.c
69
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
70
g_assert_not_reached();
18
}
71
}
19
72
20
-
73
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
21
-static uint32_t pflash_readb_be(void *opaque, hwaddr addr)
74
+{
22
+static uint64_t pflash_be_readfn(void *opaque, hwaddr addr, unsigned size)
75
+ /* translate.c should never generate calls here in user-only mode */
76
+ g_assert_not_reached();
77
+}
78
+
79
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
23
{
80
{
24
- return pflash_read(opaque, addr, 1, 1);
81
/* The TT instructions can be used by unprivileged code, but in
25
+ return pflash_read(opaque, addr, size, 1);
82
@@ -XXX,XX +XXX,XX @@ pend_fault:
83
return false;
26
}
84
}
27
85
28
-static uint32_t pflash_readb_le(void *opaque, hwaddr addr)
86
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
29
+static void pflash_be_writefn(void *opaque, hwaddr addr,
87
+{
30
+ uint64_t value, unsigned size)
88
+ /*
31
{
89
+ * Preserve FP state (because LSPACT was set and we are about
32
- return pflash_read(opaque, addr, 1, 0);
90
+ * to execute an FP instruction). This corresponds to the
33
+ pflash_write(opaque, addr, value, size, 1);
91
+ * PreserveFPState() pseudocode.
92
+ * We may throw an exception if the stacking fails.
93
+ */
94
+ ARMCPU *cpu = arm_env_get_cpu(env);
95
+ bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
96
+ bool negpri = !(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_HFRDY_MASK);
97
+ bool is_priv = !(env->v7m.fpccr[is_secure] & R_V7M_FPCCR_USER_MASK);
98
+ bool splimviol = env->v7m.fpccr[is_secure] & R_V7M_FPCCR_SPLIMVIOL_MASK;
99
+ uint32_t fpcar = env->v7m.fpcar[is_secure];
100
+ bool stacked_ok = true;
101
+ bool ts = is_secure && (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
102
+ bool take_exception;
103
+
104
+ /* Take the iothread lock as we are going to touch the NVIC */
105
+ qemu_mutex_lock_iothread();
106
+
107
+ /* Check the background context had access to the FPU */
108
+ if (!v7m_cpacr_pass(env, is_secure, is_priv)) {
109
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, is_secure);
110
+ env->v7m.cfsr[is_secure] |= R_V7M_CFSR_NOCP_MASK;
111
+ stacked_ok = false;
112
+ } else if (!is_secure && !extract32(env->v7m.nsacr, 10, 1)) {
113
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
114
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
115
+ stacked_ok = false;
116
+ }
117
+
118
+ if (!splimviol && stacked_ok) {
119
+ /* We only stack if the stack limit wasn't violated */
120
+ int i;
121
+ ARMMMUIdx mmu_idx;
122
+
123
+ mmu_idx = arm_v7m_mmu_idx_all(env, is_secure, is_priv, negpri);
124
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
125
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
126
+ uint32_t faddr = fpcar + 4 * i;
127
+ uint32_t slo = extract64(dn, 0, 32);
128
+ uint32_t shi = extract64(dn, 32, 32);
129
+
130
+ if (i >= 16) {
131
+ faddr += 8; /* skip the slot for the FPSCR */
132
+ }
133
+ stacked_ok = stacked_ok &&
134
+ v7m_stack_write(cpu, faddr, slo, mmu_idx, STACK_LAZYFP) &&
135
+ v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, STACK_LAZYFP);
136
+ }
137
+
138
+ stacked_ok = stacked_ok &&
139
+ v7m_stack_write(cpu, fpcar + 0x40,
140
+ vfp_get_fpscr(env), mmu_idx, STACK_LAZYFP);
141
+ }
142
+
143
+ /*
144
+ * We definitely pended an exception, but it's possible that it
145
+ * might not be able to be taken now. If its priority permits us
146
+ * to take it now, then we must not update the LSPACT or FP regs,
147
+ * but instead jump out to take the exception immediately.
148
+ * If it's just pending and won't be taken until the current
149
+ * handler exits, then we do update LSPACT and the FP regs.
150
+ */
151
+ take_exception = !stacked_ok &&
152
+ armv7m_nvic_can_take_pending_exception(env->nvic);
153
+
154
+ qemu_mutex_unlock_iothread();
155
+
156
+ if (take_exception) {
157
+ raise_exception_ra(env, EXCP_LAZYFP, 0, 1, GETPC());
158
+ }
159
+
160
+ env->v7m.fpccr[is_secure] &= ~R_V7M_FPCCR_LSPACT_MASK;
161
+
162
+ if (ts) {
163
+ /* Clear s0 to s31 and the FPSCR */
164
+ int i;
165
+
166
+ for (i = 0; i < 32; i += 2) {
167
+ *aa32_vfp_dreg(env, i / 2) = 0;
168
+ }
169
+ vfp_set_fpscr(env, 0);
170
+ }
171
+ /*
172
+ * Otherwise s0 to s15 and FPSCR are UNKNOWN; we choose to leave them
173
+ * unchanged.
174
+ */
175
+}
176
+
177
/* Write to v7M CONTROL.SPSEL bit for the specified security bank.
178
* This may change the current stack pointer between Main and Process
179
* stack pointers if it is done for the CONTROL register for the current
180
@@ -XXX,XX +XXX,XX @@ static void arm_log_exception(int idx)
181
[EXCP_NOCP] = "v7M NOCP UsageFault",
182
[EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
183
[EXCP_STKOF] = "v8M STKOF UsageFault",
184
+ [EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
185
};
186
187
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
188
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
189
return;
190
}
191
break;
192
+ case EXCP_LAZYFP:
193
+ /*
194
+ * We already pended the specific exception in the NVIC in the
195
+ * v7m_preserve_fp_state() helper function.
196
+ */
197
+ break;
198
default:
199
cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
200
return; /* Never happens. Keep compiler happy. */
201
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
202
flags = FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED, 1);
203
}
204
205
+ if (arm_feature(env, ARM_FEATURE_M)) {
206
+ bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
207
+
208
+ if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) {
209
+ flags = FIELD_DP32(flags, TBFLAG_A32, LSPACT, 1);
210
+ }
211
+ }
212
+
213
*pflags = flags;
214
*cs_base = 0;
34
}
215
}
35
216
diff --git a/target/arm/translate.c b/target/arm/translate.c
36
-static uint32_t pflash_readw_be(void *opaque, hwaddr addr)
217
index XXXXXXX..XXXXXXX 100644
37
+static uint64_t pflash_le_readfn(void *opaque, hwaddr addr, unsigned size)
218
--- a/target/arm/translate.c
38
{
219
+++ b/target/arm/translate.c
39
- pflash_t *pfl = opaque;
220
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
40
-
221
if (arm_dc_feature(s, ARM_FEATURE_M)) {
41
- return pflash_read(pfl, addr, 2, 1);
222
/* Handle M-profile lazy FP state mechanics */
42
+ return pflash_read(opaque, addr, size, 0);
223
43
}
224
+ /* Trigger lazy-state preservation if necessary */
44
225
+ if (s->v7m_lspact) {
45
-static uint32_t pflash_readw_le(void *opaque, hwaddr addr)
226
+ /*
46
+static void pflash_le_writefn(void *opaque, hwaddr addr,
227
+ * Lazy state saving affects external memory and also the NVIC,
47
+ uint64_t value, unsigned size)
228
+ * so we must mark it as an IO operation for icount.
48
{
229
+ */
49
- pflash_t *pfl = opaque;
230
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
50
-
231
+ gen_io_start();
51
- return pflash_read(pfl, addr, 2, 0);
232
+ }
52
-}
233
+ gen_helper_v7m_preserve_fp_state(cpu_env);
53
-
234
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
54
-static uint32_t pflash_readl_be(void *opaque, hwaddr addr)
235
+ gen_io_end();
55
-{
236
+ }
56
- pflash_t *pfl = opaque;
237
+ /*
57
-
238
+ * If the preserve_fp_state helper doesn't throw an exception
58
- return pflash_read(pfl, addr, 4, 1);
239
+ * then it will clear LSPACT; we don't need to repeat this for
59
-}
240
+ * any further FP insns in this TB.
60
-
241
+ */
61
-static uint32_t pflash_readl_le(void *opaque, hwaddr addr)
242
+ s->v7m_lspact = false;
62
-{
243
+ }
63
- pflash_t *pfl = opaque;
244
+
64
-
245
/* Update ownership of FP context: set FPCCR.S to match current state */
65
- return pflash_read(pfl, addr, 4, 0);
246
if (s->v8m_fpccr_s_wrong) {
66
-}
247
TCGv_i32 tmp;
67
-
248
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
68
-static void pflash_writeb_be(void *opaque, hwaddr addr,
249
dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
69
- uint32_t value)
250
dc->v7m_new_fp_ctxt_needed =
70
-{
251
FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
71
- pflash_write(opaque, addr, value, 1, 1);
252
+ dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_A32, LSPACT);
72
-}
253
dc->cp_regs = cpu->cp_regs;
73
-
254
dc->features = env->features;
74
-static void pflash_writeb_le(void *opaque, hwaddr addr,
75
- uint32_t value)
76
-{
77
- pflash_write(opaque, addr, value, 1, 0);
78
-}
79
-
80
-static void pflash_writew_be(void *opaque, hwaddr addr,
81
- uint32_t value)
82
-{
83
- pflash_t *pfl = opaque;
84
-
85
- pflash_write(pfl, addr, value, 2, 1);
86
-}
87
-
88
-static void pflash_writew_le(void *opaque, hwaddr addr,
89
- uint32_t value)
90
-{
91
- pflash_t *pfl = opaque;
92
-
93
- pflash_write(pfl, addr, value, 2, 0);
94
-}
95
-
96
-static void pflash_writel_be(void *opaque, hwaddr addr,
97
- uint32_t value)
98
-{
99
- pflash_t *pfl = opaque;
100
-
101
- pflash_write(pfl, addr, value, 4, 1);
102
-}
103
-
104
-static void pflash_writel_le(void *opaque, hwaddr addr,
105
- uint32_t value)
106
-{
107
- pflash_t *pfl = opaque;
108
-
109
- pflash_write(pfl, addr, value, 4, 0);
110
+ pflash_write(opaque, addr, value, size, 0);
111
}
112
113
static const MemoryRegionOps pflash_cfi02_ops_be = {
114
- .old_mmio = {
115
- .read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, },
116
- .write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, },
117
- },
118
+ .read = pflash_be_readfn,
119
+ .write = pflash_be_writefn,
120
+ .valid.min_access_size = 1,
121
+ .valid.max_access_size = 4,
122
.endianness = DEVICE_NATIVE_ENDIAN,
123
};
124
125
static const MemoryRegionOps pflash_cfi02_ops_le = {
126
- .old_mmio = {
127
- .read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, },
128
- .write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, },
129
- },
130
+ .read = pflash_le_readfn,
131
+ .write = pflash_le_writefn,
132
+ .valid.min_access_size = 1,
133
+ .valid.max_access_size = 4,
134
.endianness = DEVICE_NATIVE_ENDIAN,
135
};
136
255
137
--
256
--
138
2.17.1
257
2.20.1
139
258
140
259
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the VLSTM instruction for v7M for the FPU present case.
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180613015641.5667-12-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-25-peter.maydell@linaro.org
7
---
6
---
8
target/arm/helper-sve.h | 115 +++++++++++++++++++++++
7
target/arm/cpu.h | 2 +
9
target/arm/sve_helper.c | 187 +++++++++++++++++++++++++++++++++++++
8
target/arm/helper.h | 2 +
10
target/arm/translate-sve.c | 91 ++++++++++++++++++
9
target/arm/helper.c | 84 ++++++++++++++++++++++++++++++++++++++++++
11
target/arm/sve.decode | 24 +++++
10
target/arm/translate.c | 15 +++++++-
12
4 files changed, 417 insertions(+)
11
4 files changed, 102 insertions(+), 1 deletion(-)
13
12
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
15
--- a/target/arm/cpu.h
17
+++ b/target/arm/helper-sve.h
16
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_rbit_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
17
@@ -XXX,XX +XXX,XX @@
19
18
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
20
DEF_HELPER_FLAGS_5(sve_splice, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
19
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
21
20
#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
22
+DEF_HELPER_FLAGS_5(sve_cmpeq_ppzz_b, TCG_CALL_NO_RWG,
21
+#define EXCP_LSERR 21 /* v8M LSERR SecureFault */
23
+ i32, ptr, ptr, ptr, ptr, i32)
22
+#define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */
24
+DEF_HELPER_FLAGS_5(sve_cmpne_ppzz_b, TCG_CALL_NO_RWG,
23
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
25
+ i32, ptr, ptr, ptr, ptr, i32)
24
26
+DEF_HELPER_FLAGS_5(sve_cmpge_ppzz_b, TCG_CALL_NO_RWG,
25
#define ARMV7M_EXCP_RESET 1
27
+ i32, ptr, ptr, ptr, ptr, i32)
26
diff --git a/target/arm/helper.h b/target/arm/helper.h
28
+DEF_HELPER_FLAGS_5(sve_cmpgt_ppzz_b, TCG_CALL_NO_RWG,
27
index XXXXXXX..XXXXXXX 100644
29
+ i32, ptr, ptr, ptr, ptr, i32)
28
--- a/target/arm/helper.h
30
+DEF_HELPER_FLAGS_5(sve_cmphi_ppzz_b, TCG_CALL_NO_RWG,
29
+++ b/target/arm/helper.h
31
+ i32, ptr, ptr, ptr, ptr, i32)
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
32
+DEF_HELPER_FLAGS_5(sve_cmphs_ppzz_b, TCG_CALL_NO_RWG,
31
33
+ i32, ptr, ptr, ptr, ptr, i32)
32
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
33
34
+DEF_HELPER_2(v7m_vlstm, void, env, i32)
34
+
35
+
35
+DEF_HELPER_FLAGS_5(sve_cmpeq_ppzz_h, TCG_CALL_NO_RWG,
36
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
36
+ i32, ptr, ptr, ptr, ptr, i32)
37
37
+DEF_HELPER_FLAGS_5(sve_cmpne_ppzz_h, TCG_CALL_NO_RWG,
38
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
38
+ i32, ptr, ptr, ptr, ptr, i32)
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
39
+DEF_HELPER_FLAGS_5(sve_cmpge_ppzz_h, TCG_CALL_NO_RWG,
40
+ i32, ptr, ptr, ptr, ptr, i32)
41
+DEF_HELPER_FLAGS_5(sve_cmpgt_ppzz_h, TCG_CALL_NO_RWG,
42
+ i32, ptr, ptr, ptr, ptr, i32)
43
+DEF_HELPER_FLAGS_5(sve_cmphi_ppzz_h, TCG_CALL_NO_RWG,
44
+ i32, ptr, ptr, ptr, ptr, i32)
45
+DEF_HELPER_FLAGS_5(sve_cmphs_ppzz_h, TCG_CALL_NO_RWG,
46
+ i32, ptr, ptr, ptr, ptr, i32)
47
+
48
+DEF_HELPER_FLAGS_5(sve_cmpeq_ppzz_s, TCG_CALL_NO_RWG,
49
+ i32, ptr, ptr, ptr, ptr, i32)
50
+DEF_HELPER_FLAGS_5(sve_cmpne_ppzz_s, TCG_CALL_NO_RWG,
51
+ i32, ptr, ptr, ptr, ptr, i32)
52
+DEF_HELPER_FLAGS_5(sve_cmpge_ppzz_s, TCG_CALL_NO_RWG,
53
+ i32, ptr, ptr, ptr, ptr, i32)
54
+DEF_HELPER_FLAGS_5(sve_cmpgt_ppzz_s, TCG_CALL_NO_RWG,
55
+ i32, ptr, ptr, ptr, ptr, i32)
56
+DEF_HELPER_FLAGS_5(sve_cmphi_ppzz_s, TCG_CALL_NO_RWG,
57
+ i32, ptr, ptr, ptr, ptr, i32)
58
+DEF_HELPER_FLAGS_5(sve_cmphs_ppzz_s, TCG_CALL_NO_RWG,
59
+ i32, ptr, ptr, ptr, ptr, i32)
60
+
61
+DEF_HELPER_FLAGS_5(sve_cmpeq_ppzz_d, TCG_CALL_NO_RWG,
62
+ i32, ptr, ptr, ptr, ptr, i32)
63
+DEF_HELPER_FLAGS_5(sve_cmpne_ppzz_d, TCG_CALL_NO_RWG,
64
+ i32, ptr, ptr, ptr, ptr, i32)
65
+DEF_HELPER_FLAGS_5(sve_cmpge_ppzz_d, TCG_CALL_NO_RWG,
66
+ i32, ptr, ptr, ptr, ptr, i32)
67
+DEF_HELPER_FLAGS_5(sve_cmpgt_ppzz_d, TCG_CALL_NO_RWG,
68
+ i32, ptr, ptr, ptr, ptr, i32)
69
+DEF_HELPER_FLAGS_5(sve_cmphi_ppzz_d, TCG_CALL_NO_RWG,
70
+ i32, ptr, ptr, ptr, ptr, i32)
71
+DEF_HELPER_FLAGS_5(sve_cmphs_ppzz_d, TCG_CALL_NO_RWG,
72
+ i32, ptr, ptr, ptr, ptr, i32)
73
+
74
+DEF_HELPER_FLAGS_5(sve_cmpeq_ppzw_b, TCG_CALL_NO_RWG,
75
+ i32, ptr, ptr, ptr, ptr, i32)
76
+DEF_HELPER_FLAGS_5(sve_cmpne_ppzw_b, TCG_CALL_NO_RWG,
77
+ i32, ptr, ptr, ptr, ptr, i32)
78
+DEF_HELPER_FLAGS_5(sve_cmpge_ppzw_b, TCG_CALL_NO_RWG,
79
+ i32, ptr, ptr, ptr, ptr, i32)
80
+DEF_HELPER_FLAGS_5(sve_cmpgt_ppzw_b, TCG_CALL_NO_RWG,
81
+ i32, ptr, ptr, ptr, ptr, i32)
82
+DEF_HELPER_FLAGS_5(sve_cmphi_ppzw_b, TCG_CALL_NO_RWG,
83
+ i32, ptr, ptr, ptr, ptr, i32)
84
+DEF_HELPER_FLAGS_5(sve_cmphs_ppzw_b, TCG_CALL_NO_RWG,
85
+ i32, ptr, ptr, ptr, ptr, i32)
86
+DEF_HELPER_FLAGS_5(sve_cmple_ppzw_b, TCG_CALL_NO_RWG,
87
+ i32, ptr, ptr, ptr, ptr, i32)
88
+DEF_HELPER_FLAGS_5(sve_cmplt_ppzw_b, TCG_CALL_NO_RWG,
89
+ i32, ptr, ptr, ptr, ptr, i32)
90
+DEF_HELPER_FLAGS_5(sve_cmplo_ppzw_b, TCG_CALL_NO_RWG,
91
+ i32, ptr, ptr, ptr, ptr, i32)
92
+DEF_HELPER_FLAGS_5(sve_cmpls_ppzw_b, TCG_CALL_NO_RWG,
93
+ i32, ptr, ptr, ptr, ptr, i32)
94
+
95
+DEF_HELPER_FLAGS_5(sve_cmpeq_ppzw_h, TCG_CALL_NO_RWG,
96
+ i32, ptr, ptr, ptr, ptr, i32)
97
+DEF_HELPER_FLAGS_5(sve_cmpne_ppzw_h, TCG_CALL_NO_RWG,
98
+ i32, ptr, ptr, ptr, ptr, i32)
99
+DEF_HELPER_FLAGS_5(sve_cmpge_ppzw_h, TCG_CALL_NO_RWG,
100
+ i32, ptr, ptr, ptr, ptr, i32)
101
+DEF_HELPER_FLAGS_5(sve_cmpgt_ppzw_h, TCG_CALL_NO_RWG,
102
+ i32, ptr, ptr, ptr, ptr, i32)
103
+DEF_HELPER_FLAGS_5(sve_cmphi_ppzw_h, TCG_CALL_NO_RWG,
104
+ i32, ptr, ptr, ptr, ptr, i32)
105
+DEF_HELPER_FLAGS_5(sve_cmphs_ppzw_h, TCG_CALL_NO_RWG,
106
+ i32, ptr, ptr, ptr, ptr, i32)
107
+DEF_HELPER_FLAGS_5(sve_cmple_ppzw_h, TCG_CALL_NO_RWG,
108
+ i32, ptr, ptr, ptr, ptr, i32)
109
+DEF_HELPER_FLAGS_5(sve_cmplt_ppzw_h, TCG_CALL_NO_RWG,
110
+ i32, ptr, ptr, ptr, ptr, i32)
111
+DEF_HELPER_FLAGS_5(sve_cmplo_ppzw_h, TCG_CALL_NO_RWG,
112
+ i32, ptr, ptr, ptr, ptr, i32)
113
+DEF_HELPER_FLAGS_5(sve_cmpls_ppzw_h, TCG_CALL_NO_RWG,
114
+ i32, ptr, ptr, ptr, ptr, i32)
115
+
116
+DEF_HELPER_FLAGS_5(sve_cmpeq_ppzw_s, TCG_CALL_NO_RWG,
117
+ i32, ptr, ptr, ptr, ptr, i32)
118
+DEF_HELPER_FLAGS_5(sve_cmpne_ppzw_s, TCG_CALL_NO_RWG,
119
+ i32, ptr, ptr, ptr, ptr, i32)
120
+DEF_HELPER_FLAGS_5(sve_cmpge_ppzw_s, TCG_CALL_NO_RWG,
121
+ i32, ptr, ptr, ptr, ptr, i32)
122
+DEF_HELPER_FLAGS_5(sve_cmpgt_ppzw_s, TCG_CALL_NO_RWG,
123
+ i32, ptr, ptr, ptr, ptr, i32)
124
+DEF_HELPER_FLAGS_5(sve_cmphi_ppzw_s, TCG_CALL_NO_RWG,
125
+ i32, ptr, ptr, ptr, ptr, i32)
126
+DEF_HELPER_FLAGS_5(sve_cmphs_ppzw_s, TCG_CALL_NO_RWG,
127
+ i32, ptr, ptr, ptr, ptr, i32)
128
+DEF_HELPER_FLAGS_5(sve_cmple_ppzw_s, TCG_CALL_NO_RWG,
129
+ i32, ptr, ptr, ptr, ptr, i32)
130
+DEF_HELPER_FLAGS_5(sve_cmplt_ppzw_s, TCG_CALL_NO_RWG,
131
+ i32, ptr, ptr, ptr, ptr, i32)
132
+DEF_HELPER_FLAGS_5(sve_cmplo_ppzw_s, TCG_CALL_NO_RWG,
133
+ i32, ptr, ptr, ptr, ptr, i32)
134
+DEF_HELPER_FLAGS_5(sve_cmpls_ppzw_s, TCG_CALL_NO_RWG,
135
+ i32, ptr, ptr, ptr, ptr, i32)
136
+
137
DEF_HELPER_FLAGS_5(sve_and_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
138
DEF_HELPER_FLAGS_5(sve_bic_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
139
DEF_HELPER_FLAGS_5(sve_eor_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
140
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
141
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
142
--- a/target/arm/sve_helper.c
41
--- a/target/arm/helper.c
143
+++ b/target/arm/sve_helper.c
42
+++ b/target/arm/helper.c
144
@@ -XXX,XX +XXX,XX @@ static uint32_t iter_predtest_fwd(uint64_t d, uint64_t g, uint32_t flags)
43
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
145
return flags;
44
g_assert_not_reached();
146
}
45
}
147
46
148
+/* This is an iterative function, called for each Pd and Pg word
47
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
149
+ * moving backward.
150
+ */
151
+static uint32_t iter_predtest_bwd(uint64_t d, uint64_t g, uint32_t flags)
152
+{
48
+{
153
+ if (likely(g)) {
49
+ /* translate.c should never generate calls here in user-only mode */
154
+ /* Compute C from first (i.e last) !(D & G).
50
+ g_assert_not_reached();
155
+ Use bit 2 to signal first G bit seen. */
156
+ if (!(flags & 4)) {
157
+ flags += 4 - 1; /* add bit 2, subtract C from PREDTEST_INIT */
158
+ flags |= (d & pow2floor(g)) == 0;
159
+ }
160
+
161
+ /* Accumulate Z from each D & G. */
162
+ flags |= ((d & g) != 0) << 1;
163
+
164
+ /* Compute N from last (i.e first) D & G. Replace previous. */
165
+ flags = deposit32(flags, 31, 1, (d & (g & -g)) != 0);
166
+ }
167
+ return flags;
168
+}
51
+}
169
+
52
+
170
/* The same for a single word predicate. */
53
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
171
uint32_t HELPER(sve_predtest1)(uint64_t d, uint64_t g)
172
{
54
{
173
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_sel_zpzz_d)(void *vd, void *vn, void *vm,
55
/* The TT instructions can be used by unprivileged code, but in
174
d[i] = (pg[H1(i)] & 1 ? nn : mm);
56
@@ -XXX,XX +XXX,XX @@ static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
175
}
57
}
176
}
58
}
59
60
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
61
+{
62
+ /* fptr is the value of Rn, the frame pointer we store the FP regs to */
63
+ bool s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
64
+ bool lspact = env->v7m.fpccr[s] & R_V7M_FPCCR_LSPACT_MASK;
177
+
65
+
178
+/* Two operand comparison controlled by a predicate.
66
+ assert(env->v7m.secure);
179
+ * ??? It is very tempting to want to be able to expand this inline
67
+
180
+ * with x86 instructions, e.g.
68
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
181
+ *
69
+ return;
182
+ * vcmpeqw zm, zn, %ymm0
70
+ }
183
+ * vpmovmskb %ymm0, %eax
71
+
184
+ * and $0x5555, %eax
72
+ /* Check access to the coprocessor is permitted */
185
+ * and pg, %eax
73
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
186
+ *
74
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
187
+ * or even aarch64, e.g.
75
+ }
188
+ *
76
+
189
+ * // mask = 4000 1000 0400 0100 0040 0010 0004 0001
77
+ if (lspact) {
190
+ * cmeq v0.8h, zn, zm
78
+ /* LSPACT should not be active when there is active FP state */
191
+ * and v0.8h, v0.8h, mask
79
+ raise_exception_ra(env, EXCP_LSERR, 0, 1, GETPC());
192
+ * addv h0, v0.8h
80
+ }
193
+ * and v0.8b, pg
81
+
194
+ *
82
+ if (fptr & 7) {
195
+ * However, coming up with an abstraction that allows vector inputs and
83
+ raise_exception_ra(env, EXCP_UNALIGNED, 0, 1, GETPC());
196
+ * a scalar output, and also handles the byte-ordering of sub-uint64_t
84
+ }
197
+ * scalar outputs, is tricky.
85
+
198
+ */
86
+ /*
199
+#define DO_CMP_PPZZ(NAME, TYPE, OP, H, MASK) \
87
+ * Note that we do not use v7m_stack_write() here, because the
200
+uint32_t HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, uint32_t desc) \
88
+ * accesses should not set the FSR bits for stacking errors if they
201
+{ \
89
+ * fail. (In pseudocode terms, they are AccType_NORMAL, not AccType_STACK
202
+ intptr_t opr_sz = simd_oprsz(desc); \
90
+ * or AccType_LAZYFP). Faults in cpu_stl_data() will throw exceptions
203
+ uint32_t flags = PREDTEST_INIT; \
91
+ * and longjmp out.
204
+ intptr_t i = opr_sz; \
92
+ */
205
+ do { \
93
+ if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) {
206
+ uint64_t out = 0, pg; \
94
+ bool ts = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK;
207
+ do { \
95
+ int i;
208
+ i -= sizeof(TYPE), out <<= sizeof(TYPE); \
96
+
209
+ TYPE nn = *(TYPE *)(vn + H(i)); \
97
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
210
+ TYPE mm = *(TYPE *)(vm + H(i)); \
98
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
211
+ out |= nn OP mm; \
99
+ uint32_t faddr = fptr + 4 * i;
212
+ } while (i & 63); \
100
+ uint32_t slo = extract64(dn, 0, 32);
213
+ pg = *(uint64_t *)(vg + (i >> 3)) & MASK; \
101
+ uint32_t shi = extract64(dn, 32, 32);
214
+ out &= pg; \
102
+
215
+ *(uint64_t *)(vd + (i >> 3)) = out; \
103
+ if (i >= 16) {
216
+ flags = iter_predtest_bwd(out, pg, flags); \
104
+ faddr += 8; /* skip the slot for the FPSCR */
217
+ } while (i > 0); \
105
+ }
218
+ return flags; \
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;
219
+}
126
+}
220
+
127
+
221
+#define DO_CMP_PPZZ_B(NAME, TYPE, OP) \
128
static bool v7m_push_stack(ARMCPU *cpu)
222
+ DO_CMP_PPZZ(NAME, TYPE, OP, H1, 0xffffffffffffffffull)
129
{
223
+#define DO_CMP_PPZZ_H(NAME, TYPE, OP) \
130
/* Do the "set up stack frame" part of exception entry,
224
+ DO_CMP_PPZZ(NAME, TYPE, OP, H1_2, 0x5555555555555555ull)
131
@@ -XXX,XX +XXX,XX @@ static void arm_log_exception(int idx)
225
+#define DO_CMP_PPZZ_S(NAME, TYPE, OP) \
132
[EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
226
+ DO_CMP_PPZZ(NAME, TYPE, OP, H1_4, 0x1111111111111111ull)
133
[EXCP_STKOF] = "v8M STKOF UsageFault",
227
+#define DO_CMP_PPZZ_D(NAME, TYPE, OP) \
134
[EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
228
+ DO_CMP_PPZZ(NAME, TYPE, OP, , 0x0101010101010101ull)
135
+ [EXCP_LSERR] = "v8M LSERR UsageFault",
136
+ [EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
137
};
138
139
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
140
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
141
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
142
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_STKOF_MASK;
143
break;
144
+ case EXCP_LSERR:
145
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
146
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
147
+ break;
148
+ case EXCP_UNALIGNED:
149
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
150
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNALIGNED_MASK;
151
+ break;
152
case EXCP_SWI:
153
/* The PC already points to the next instruction. */
154
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC, env->v7m.secure);
155
diff --git a/target/arm/translate.c b/target/arm/translate.c
156
index XXXXXXX..XXXXXXX 100644
157
--- a/target/arm/translate.c
158
+++ b/target/arm/translate.c
159
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
160
if (!s->v8m_secure || (insn & 0x0040f0ff)) {
161
goto illegal_op;
162
}
163
- /* Just NOP since FP support is not implemented */
229
+
164
+
230
+DO_CMP_PPZZ_B(sve_cmpeq_ppzz_b, uint8_t, ==)
165
+ if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
231
+DO_CMP_PPZZ_H(sve_cmpeq_ppzz_h, uint16_t, ==)
166
+ TCGv_i32 fptr = load_reg(s, rn);
232
+DO_CMP_PPZZ_S(sve_cmpeq_ppzz_s, uint32_t, ==)
233
+DO_CMP_PPZZ_D(sve_cmpeq_ppzz_d, uint64_t, ==)
234
+
167
+
235
+DO_CMP_PPZZ_B(sve_cmpne_ppzz_b, uint8_t, !=)
168
+ if (extract32(insn, 20, 1)) {
236
+DO_CMP_PPZZ_H(sve_cmpne_ppzz_h, uint16_t, !=)
169
+ /* VLLDM */
237
+DO_CMP_PPZZ_S(sve_cmpne_ppzz_s, uint32_t, !=)
170
+ } else {
238
+DO_CMP_PPZZ_D(sve_cmpne_ppzz_d, uint64_t, !=)
171
+ gen_helper_v7m_vlstm(cpu_env, fptr);
172
+ }
173
+ tcg_temp_free_i32(fptr);
239
+
174
+
240
+DO_CMP_PPZZ_B(sve_cmpgt_ppzz_b, int8_t, >)
175
+ /* End the TB, because we have updated FP control bits */
241
+DO_CMP_PPZZ_H(sve_cmpgt_ppzz_h, int16_t, >)
176
+ s->base.is_jmp = DISAS_UPDATE;
242
+DO_CMP_PPZZ_S(sve_cmpgt_ppzz_s, int32_t, >)
177
+ }
243
+DO_CMP_PPZZ_D(sve_cmpgt_ppzz_d, int64_t, >)
178
break;
244
+
179
}
245
+DO_CMP_PPZZ_B(sve_cmpge_ppzz_b, int8_t, >=)
180
if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
246
+DO_CMP_PPZZ_H(sve_cmpge_ppzz_h, int16_t, >=)
247
+DO_CMP_PPZZ_S(sve_cmpge_ppzz_s, int32_t, >=)
248
+DO_CMP_PPZZ_D(sve_cmpge_ppzz_d, int64_t, >=)
249
+
250
+DO_CMP_PPZZ_B(sve_cmphi_ppzz_b, uint8_t, >)
251
+DO_CMP_PPZZ_H(sve_cmphi_ppzz_h, uint16_t, >)
252
+DO_CMP_PPZZ_S(sve_cmphi_ppzz_s, uint32_t, >)
253
+DO_CMP_PPZZ_D(sve_cmphi_ppzz_d, uint64_t, >)
254
+
255
+DO_CMP_PPZZ_B(sve_cmphs_ppzz_b, uint8_t, >=)
256
+DO_CMP_PPZZ_H(sve_cmphs_ppzz_h, uint16_t, >=)
257
+DO_CMP_PPZZ_S(sve_cmphs_ppzz_s, uint32_t, >=)
258
+DO_CMP_PPZZ_D(sve_cmphs_ppzz_d, uint64_t, >=)
259
+
260
+#undef DO_CMP_PPZZ_B
261
+#undef DO_CMP_PPZZ_H
262
+#undef DO_CMP_PPZZ_S
263
+#undef DO_CMP_PPZZ_D
264
+#undef DO_CMP_PPZZ
265
+
266
+/* Similar, but the second source is "wide". */
267
+#define DO_CMP_PPZW(NAME, TYPE, TYPEW, OP, H, MASK) \
268
+uint32_t HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, uint32_t desc) \
269
+{ \
270
+ intptr_t opr_sz = simd_oprsz(desc); \
271
+ uint32_t flags = PREDTEST_INIT; \
272
+ intptr_t i = opr_sz; \
273
+ do { \
274
+ uint64_t out = 0, pg; \
275
+ do { \
276
+ TYPEW mm = *(TYPEW *)(vm + i - 8); \
277
+ do { \
278
+ i -= sizeof(TYPE), out <<= sizeof(TYPE); \
279
+ TYPE nn = *(TYPE *)(vn + H(i)); \
280
+ out |= nn OP mm; \
281
+ } while (i & 7); \
282
+ } while (i & 63); \
283
+ pg = *(uint64_t *)(vg + (i >> 3)) & MASK; \
284
+ out &= pg; \
285
+ *(uint64_t *)(vd + (i >> 3)) = out; \
286
+ flags = iter_predtest_bwd(out, pg, flags); \
287
+ } while (i > 0); \
288
+ return flags; \
289
+}
290
+
291
+#define DO_CMP_PPZW_B(NAME, TYPE, TYPEW, OP) \
292
+ DO_CMP_PPZW(NAME, TYPE, TYPEW, OP, H1, 0xffffffffffffffffull)
293
+#define DO_CMP_PPZW_H(NAME, TYPE, TYPEW, OP) \
294
+ DO_CMP_PPZW(NAME, TYPE, TYPEW, OP, H1_2, 0x5555555555555555ull)
295
+#define DO_CMP_PPZW_S(NAME, TYPE, TYPEW, OP) \
296
+ DO_CMP_PPZW(NAME, TYPE, TYPEW, OP, H1_4, 0x1111111111111111ull)
297
+
298
+DO_CMP_PPZW_B(sve_cmpeq_ppzw_b, uint8_t, uint64_t, ==)
299
+DO_CMP_PPZW_H(sve_cmpeq_ppzw_h, uint16_t, uint64_t, ==)
300
+DO_CMP_PPZW_S(sve_cmpeq_ppzw_s, uint32_t, uint64_t, ==)
301
+
302
+DO_CMP_PPZW_B(sve_cmpne_ppzw_b, uint8_t, uint64_t, !=)
303
+DO_CMP_PPZW_H(sve_cmpne_ppzw_h, uint16_t, uint64_t, !=)
304
+DO_CMP_PPZW_S(sve_cmpne_ppzw_s, uint32_t, uint64_t, !=)
305
+
306
+DO_CMP_PPZW_B(sve_cmpgt_ppzw_b, int8_t, int64_t, >)
307
+DO_CMP_PPZW_H(sve_cmpgt_ppzw_h, int16_t, int64_t, >)
308
+DO_CMP_PPZW_S(sve_cmpgt_ppzw_s, int32_t, int64_t, >)
309
+
310
+DO_CMP_PPZW_B(sve_cmpge_ppzw_b, int8_t, int64_t, >=)
311
+DO_CMP_PPZW_H(sve_cmpge_ppzw_h, int16_t, int64_t, >=)
312
+DO_CMP_PPZW_S(sve_cmpge_ppzw_s, int32_t, int64_t, >=)
313
+
314
+DO_CMP_PPZW_B(sve_cmphi_ppzw_b, uint8_t, uint64_t, >)
315
+DO_CMP_PPZW_H(sve_cmphi_ppzw_h, uint16_t, uint64_t, >)
316
+DO_CMP_PPZW_S(sve_cmphi_ppzw_s, uint32_t, uint64_t, >)
317
+
318
+DO_CMP_PPZW_B(sve_cmphs_ppzw_b, uint8_t, uint64_t, >=)
319
+DO_CMP_PPZW_H(sve_cmphs_ppzw_h, uint16_t, uint64_t, >=)
320
+DO_CMP_PPZW_S(sve_cmphs_ppzw_s, uint32_t, uint64_t, >=)
321
+
322
+DO_CMP_PPZW_B(sve_cmplt_ppzw_b, int8_t, int64_t, <)
323
+DO_CMP_PPZW_H(sve_cmplt_ppzw_h, int16_t, int64_t, <)
324
+DO_CMP_PPZW_S(sve_cmplt_ppzw_s, int32_t, int64_t, <)
325
+
326
+DO_CMP_PPZW_B(sve_cmple_ppzw_b, int8_t, int64_t, <=)
327
+DO_CMP_PPZW_H(sve_cmple_ppzw_h, int16_t, int64_t, <=)
328
+DO_CMP_PPZW_S(sve_cmple_ppzw_s, int32_t, int64_t, <=)
329
+
330
+DO_CMP_PPZW_B(sve_cmplo_ppzw_b, uint8_t, uint64_t, <)
331
+DO_CMP_PPZW_H(sve_cmplo_ppzw_h, uint16_t, uint64_t, <)
332
+DO_CMP_PPZW_S(sve_cmplo_ppzw_s, uint32_t, uint64_t, <)
333
+
334
+DO_CMP_PPZW_B(sve_cmpls_ppzw_b, uint8_t, uint64_t, <=)
335
+DO_CMP_PPZW_H(sve_cmpls_ppzw_h, uint16_t, uint64_t, <=)
336
+DO_CMP_PPZW_S(sve_cmpls_ppzw_s, uint32_t, uint64_t, <=)
337
+
338
+#undef DO_CMP_PPZW_B
339
+#undef DO_CMP_PPZW_H
340
+#undef DO_CMP_PPZW_S
341
+#undef DO_CMP_PPZW
342
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
343
index XXXXXXX..XXXXXXX 100644
344
--- a/target/arm/translate-sve.c
345
+++ b/target/arm/translate-sve.c
346
@@ -XXX,XX +XXX,XX @@
347
#include "trace-tcg.h"
348
#include "translate-a64.h"
349
350
+
351
+typedef void gen_helper_gvec_flags_4(TCGv_i32, TCGv_ptr, TCGv_ptr,
352
+ TCGv_ptr, TCGv_ptr, TCGv_i32);
353
+
354
/*
355
* Helpers for extracting complex instruction fields.
356
*/
357
@@ -XXX,XX +XXX,XX @@ static bool trans_SPLICE(DisasContext *s, arg_rprr_esz *a, uint32_t insn)
358
return true;
359
}
360
361
+/*
362
+ *** SVE Integer Compare - Vectors Group
363
+ */
364
+
365
+static bool do_ppzz_flags(DisasContext *s, arg_rprr_esz *a,
366
+ gen_helper_gvec_flags_4 *gen_fn)
367
+{
368
+ TCGv_ptr pd, zn, zm, pg;
369
+ unsigned vsz;
370
+ TCGv_i32 t;
371
+
372
+ if (gen_fn == NULL) {
373
+ return false;
374
+ }
375
+ if (!sve_access_check(s)) {
376
+ return true;
377
+ }
378
+
379
+ vsz = vec_full_reg_size(s);
380
+ t = tcg_const_i32(simd_desc(vsz, vsz, 0));
381
+ pd = tcg_temp_new_ptr();
382
+ zn = tcg_temp_new_ptr();
383
+ zm = tcg_temp_new_ptr();
384
+ pg = tcg_temp_new_ptr();
385
+
386
+ tcg_gen_addi_ptr(pd, cpu_env, pred_full_reg_offset(s, a->rd));
387
+ tcg_gen_addi_ptr(zn, cpu_env, vec_full_reg_offset(s, a->rn));
388
+ tcg_gen_addi_ptr(zm, cpu_env, vec_full_reg_offset(s, a->rm));
389
+ tcg_gen_addi_ptr(pg, cpu_env, pred_full_reg_offset(s, a->pg));
390
+
391
+ gen_fn(t, pd, zn, zm, pg, t);
392
+
393
+ tcg_temp_free_ptr(pd);
394
+ tcg_temp_free_ptr(zn);
395
+ tcg_temp_free_ptr(zm);
396
+ tcg_temp_free_ptr(pg);
397
+
398
+ do_pred_flags(t);
399
+
400
+ tcg_temp_free_i32(t);
401
+ return true;
402
+}
403
+
404
+#define DO_PPZZ(NAME, name) \
405
+static bool trans_##NAME##_ppzz(DisasContext *s, arg_rprr_esz *a, \
406
+ uint32_t insn) \
407
+{ \
408
+ static gen_helper_gvec_flags_4 * const fns[4] = { \
409
+ gen_helper_sve_##name##_ppzz_b, gen_helper_sve_##name##_ppzz_h, \
410
+ gen_helper_sve_##name##_ppzz_s, gen_helper_sve_##name##_ppzz_d, \
411
+ }; \
412
+ return do_ppzz_flags(s, a, fns[a->esz]); \
413
+}
414
+
415
+DO_PPZZ(CMPEQ, cmpeq)
416
+DO_PPZZ(CMPNE, cmpne)
417
+DO_PPZZ(CMPGT, cmpgt)
418
+DO_PPZZ(CMPGE, cmpge)
419
+DO_PPZZ(CMPHI, cmphi)
420
+DO_PPZZ(CMPHS, cmphs)
421
+
422
+#undef DO_PPZZ
423
+
424
+#define DO_PPZW(NAME, name) \
425
+static bool trans_##NAME##_ppzw(DisasContext *s, arg_rprr_esz *a, \
426
+ uint32_t insn) \
427
+{ \
428
+ static gen_helper_gvec_flags_4 * const fns[4] = { \
429
+ gen_helper_sve_##name##_ppzw_b, gen_helper_sve_##name##_ppzw_h, \
430
+ gen_helper_sve_##name##_ppzw_s, NULL \
431
+ }; \
432
+ return do_ppzz_flags(s, a, fns[a->esz]); \
433
+}
434
+
435
+DO_PPZW(CMPEQ, cmpeq)
436
+DO_PPZW(CMPNE, cmpne)
437
+DO_PPZW(CMPGT, cmpgt)
438
+DO_PPZW(CMPGE, cmpge)
439
+DO_PPZW(CMPHI, cmphi)
440
+DO_PPZW(CMPHS, cmphs)
441
+DO_PPZW(CMPLT, cmplt)
442
+DO_PPZW(CMPLE, cmple)
443
+DO_PPZW(CMPLO, cmplo)
444
+DO_PPZW(CMPLS, cmpls)
445
+
446
+#undef DO_PPZW
447
+
448
/*
449
*** SVE Memory - 32-bit Gather and Unsized Contiguous Group
450
*/
451
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
452
index XXXXXXX..XXXXXXX 100644
453
--- a/target/arm/sve.decode
454
+++ b/target/arm/sve.decode
455
@@ -XXX,XX +XXX,XX @@
456
@rdm_pg_rn ........ esz:2 ... ... ... pg:3 rn:5 rd:5 \
457
&rprr_esz rm=%reg_movprfx
458
@rd_pg4_rn_rm ........ esz:2 . rm:5 .. pg:4 rn:5 rd:5 &rprr_esz
459
+@pd_pg_rn_rm ........ esz:2 . rm:5 ... pg:3 rn:5 . rd:4 &rprr_esz
460
461
# Three register operand, with governing predicate, vector element size
462
@rda_pg_rn_rm ........ esz:2 . rm:5 ... pg:3 rn:5 rd:5 \
463
@@ -XXX,XX +XXX,XX @@ SPLICE 00000101 .. 101 100 100 ... ..... ..... @rdn_pg_rm
464
# SVE select vector elements (predicated)
465
SEL_zpzz 00000101 .. 1 ..... 11 .... ..... ..... @rd_pg4_rn_rm
466
467
+### SVE Integer Compare - Vectors Group
468
+
469
+# SVE integer compare_vectors
470
+CMPHS_ppzz 00100100 .. 0 ..... 000 ... ..... 0 .... @pd_pg_rn_rm
471
+CMPHI_ppzz 00100100 .. 0 ..... 000 ... ..... 1 .... @pd_pg_rn_rm
472
+CMPGE_ppzz 00100100 .. 0 ..... 100 ... ..... 0 .... @pd_pg_rn_rm
473
+CMPGT_ppzz 00100100 .. 0 ..... 100 ... ..... 1 .... @pd_pg_rn_rm
474
+CMPEQ_ppzz 00100100 .. 0 ..... 101 ... ..... 0 .... @pd_pg_rn_rm
475
+CMPNE_ppzz 00100100 .. 0 ..... 101 ... ..... 1 .... @pd_pg_rn_rm
476
+
477
+# SVE integer compare with wide elements
478
+# Note these require esz != 3.
479
+CMPEQ_ppzw 00100100 .. 0 ..... 001 ... ..... 0 .... @pd_pg_rn_rm
480
+CMPNE_ppzw 00100100 .. 0 ..... 001 ... ..... 1 .... @pd_pg_rn_rm
481
+CMPGE_ppzw 00100100 .. 0 ..... 010 ... ..... 0 .... @pd_pg_rn_rm
482
+CMPGT_ppzw 00100100 .. 0 ..... 010 ... ..... 1 .... @pd_pg_rn_rm
483
+CMPLT_ppzw 00100100 .. 0 ..... 011 ... ..... 0 .... @pd_pg_rn_rm
484
+CMPLE_ppzw 00100100 .. 0 ..... 011 ... ..... 1 .... @pd_pg_rn_rm
485
+CMPHS_ppzw 00100100 .. 0 ..... 110 ... ..... 0 .... @pd_pg_rn_rm
486
+CMPHI_ppzw 00100100 .. 0 ..... 110 ... ..... 1 .... @pd_pg_rn_rm
487
+CMPLO_ppzw 00100100 .. 0 ..... 111 ... ..... 0 .... @pd_pg_rn_rm
488
+CMPLS_ppzw 00100100 .. 0 ..... 111 ... ..... 1 .... @pd_pg_rn_rm
489
+
490
### SVE Predicate Logical Operations Group
491
492
# SVE predicate logical operations
493
--
181
--
494
2.17.1
182
2.20.1
495
183
496
184
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the VLLDM instruction for v7M for the FPU present cas.
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180613015641.5667-19-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-26-peter.maydell@linaro.org
7
---
6
---
8
target/arm/helper-sve.h | 14 ++++++++
7
target/arm/helper.h | 1 +
9
target/arm/helper.h | 19 +++++++++++
8
target/arm/helper.c | 54 ++++++++++++++++++++++++++++++++++++++++++
10
target/arm/translate-sve.c | 42 +++++++++++++++++++++++
9
target/arm/translate.c | 2 +-
11
target/arm/vec_helper.c | 69 ++++++++++++++++++++++++++++++++++++++
10
3 files changed, 56 insertions(+), 1 deletion(-)
12
target/arm/sve.decode | 10 ++++++
13
5 files changed, 154 insertions(+)
14
11
15
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-sve.h
18
+++ b/target/arm/helper-sve.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_umini_b, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
20
DEF_HELPER_FLAGS_4(sve_umini_h, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
21
DEF_HELPER_FLAGS_4(sve_umini_s, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
22
DEF_HELPER_FLAGS_4(sve_umini_d, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
23
+
24
+DEF_HELPER_FLAGS_5(gvec_recps_h, TCG_CALL_NO_RWG,
25
+ void, ptr, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_5(gvec_recps_s, TCG_CALL_NO_RWG,
27
+ void, ptr, ptr, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_5(gvec_recps_d, TCG_CALL_NO_RWG,
29
+ void, ptr, ptr, ptr, ptr, i32)
30
+
31
+DEF_HELPER_FLAGS_5(gvec_rsqrts_h, TCG_CALL_NO_RWG,
32
+ void, ptr, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_5(gvec_rsqrts_s, TCG_CALL_NO_RWG,
34
+ void, ptr, ptr, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_5(gvec_rsqrts_d, TCG_CALL_NO_RWG,
36
+ void, ptr, ptr, ptr, ptr, i32)
37
diff --git a/target/arm/helper.h b/target/arm/helper.h
12
diff --git a/target/arm/helper.h b/target/arm/helper.h
38
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/helper.h
14
--- a/target/arm/helper.h
40
+++ b/target/arm/helper.h
15
+++ b/target/arm/helper.h
41
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_fcmlas_idx, TCG_CALL_NO_RWG,
16
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
42
DEF_HELPER_FLAGS_5(gvec_fcmlad, TCG_CALL_NO_RWG,
17
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
43
void, ptr, ptr, ptr, ptr, i32)
18
44
19
DEF_HELPER_2(v7m_vlstm, void, env, i32)
45
+DEF_HELPER_FLAGS_5(gvec_fadd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
20
+DEF_HELPER_2(v7m_vlldm, void, env, i32)
46
+DEF_HELPER_FLAGS_5(gvec_fadd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
21
47
+DEF_HELPER_FLAGS_5(gvec_fadd_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
22
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
48
+
23
49
+DEF_HELPER_FLAGS_5(gvec_fsub_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
50
+DEF_HELPER_FLAGS_5(gvec_fsub_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
51
+DEF_HELPER_FLAGS_5(gvec_fsub_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
52
+
53
+DEF_HELPER_FLAGS_5(gvec_fmul_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
54
+DEF_HELPER_FLAGS_5(gvec_fmul_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
55
+DEF_HELPER_FLAGS_5(gvec_fmul_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
56
+
57
+DEF_HELPER_FLAGS_5(gvec_ftsmul_h, TCG_CALL_NO_RWG,
58
+ void, ptr, ptr, ptr, ptr, i32)
59
+DEF_HELPER_FLAGS_5(gvec_ftsmul_s, TCG_CALL_NO_RWG,
60
+ void, ptr, ptr, ptr, ptr, i32)
61
+DEF_HELPER_FLAGS_5(gvec_ftsmul_d, TCG_CALL_NO_RWG,
62
+ void, ptr, ptr, ptr, ptr, i32)
63
+
64
#ifdef TARGET_AARCH64
65
#include "helper-a64.h"
66
#include "helper-sve.h"
67
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
68
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
69
--- a/target/arm/translate-sve.c
26
--- a/target/arm/helper.c
70
+++ b/target/arm/translate-sve.c
27
+++ b/target/arm/helper.c
71
@@ -XXX,XX +XXX,XX @@ DO_ZZI(UMIN, umin)
28
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
72
29
g_assert_not_reached();
73
#undef DO_ZZI
30
}
74
31
75
+/*
32
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
76
+ *** SVE Floating Point Arithmetic - Unpredicated Group
77
+ */
78
+
79
+static bool do_zzz_fp(DisasContext *s, arg_rrr_esz *a,
80
+ gen_helper_gvec_3_ptr *fn)
81
+{
33
+{
82
+ if (fn == NULL) {
34
+ /* translate.c should never generate calls here in user-only mode */
83
+ return false;
35
+ g_assert_not_reached();
84
+ }
85
+ if (sve_access_check(s)) {
86
+ unsigned vsz = vec_full_reg_size(s);
87
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
88
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
89
+ vec_full_reg_offset(s, a->rn),
90
+ vec_full_reg_offset(s, a->rm),
91
+ status, vsz, vsz, 0, fn);
92
+ tcg_temp_free_ptr(status);
93
+ }
94
+ return true;
95
+}
36
+}
96
+
37
+
38
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
39
{
40
/* The TT instructions can be used by unprivileged code, but in
41
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
42
env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
43
}
44
45
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
46
+{
47
+ /* fptr is the value of Rn, the frame pointer we load the FP regs from */
48
+ assert(env->v7m.secure);
97
+
49
+
98
+#define DO_FP3(NAME, name) \
50
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
99
+static bool trans_##NAME(DisasContext *s, arg_rrr_esz *a, uint32_t insn) \
51
+ return;
100
+{ \
52
+ }
101
+ static gen_helper_gvec_3_ptr * const fns[4] = { \
53
+
102
+ NULL, gen_helper_gvec_##name##_h, \
54
+ /* Check access to the coprocessor is permitted */
103
+ gen_helper_gvec_##name##_s, gen_helper_gvec_##name##_d \
55
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
104
+ }; \
56
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
105
+ return do_zzz_fp(s, a, fns[a->esz]); \
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;
106
+}
91
+}
107
+
92
+
108
+DO_FP3(FADD_zzz, fadd)
93
static bool v7m_push_stack(ARMCPU *cpu)
109
+DO_FP3(FSUB_zzz, fsub)
94
{
110
+DO_FP3(FMUL_zzz, fmul)
95
/* Do the "set up stack frame" part of exception entry,
111
+DO_FP3(FTSMUL, ftsmul)
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
112
+DO_FP3(FRECPS, recps)
113
+DO_FP3(FRSQRTS, rsqrts)
114
+
115
+#undef DO_FP3
116
+
117
/*
118
*** SVE Memory - 32-bit Gather and Unsized Contiguous Group
119
*/
120
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
121
index XXXXXXX..XXXXXXX 100644
97
index XXXXXXX..XXXXXXX 100644
122
--- a/target/arm/vec_helper.c
98
--- a/target/arm/translate.c
123
+++ b/target/arm/vec_helper.c
99
+++ b/target/arm/translate.c
124
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcmlad)(void *vd, void *vn, void *vm,
100
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
125
}
101
TCGv_i32 fptr = load_reg(s, rn);
126
clear_tail(d, opr_sz, simd_maxsz(desc));
102
127
}
103
if (extract32(insn, 20, 1)) {
128
+
104
- /* VLLDM */
129
+/* Floating-point trigonometric starting value.
105
+ gen_helper_v7m_vlldm(cpu_env, fptr);
130
+ * See the ARM ARM pseudocode function FPTrigSMul.
106
} else {
131
+ */
107
gen_helper_v7m_vlstm(cpu_env, fptr);
132
+static float16 float16_ftsmul(float16 op1, uint16_t op2, float_status *stat)
108
}
133
+{
134
+ float16 result = float16_mul(op1, op1, stat);
135
+ if (!float16_is_any_nan(result)) {
136
+ result = float16_set_sign(result, op2 & 1);
137
+ }
138
+ return result;
139
+}
140
+
141
+static float32 float32_ftsmul(float32 op1, uint32_t op2, float_status *stat)
142
+{
143
+ float32 result = float32_mul(op1, op1, stat);
144
+ if (!float32_is_any_nan(result)) {
145
+ result = float32_set_sign(result, op2 & 1);
146
+ }
147
+ return result;
148
+}
149
+
150
+static float64 float64_ftsmul(float64 op1, uint64_t op2, float_status *stat)
151
+{
152
+ float64 result = float64_mul(op1, op1, stat);
153
+ if (!float64_is_any_nan(result)) {
154
+ result = float64_set_sign(result, op2 & 1);
155
+ }
156
+ return result;
157
+}
158
+
159
+#define DO_3OP(NAME, FUNC, TYPE) \
160
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *stat, uint32_t desc) \
161
+{ \
162
+ intptr_t i, oprsz = simd_oprsz(desc); \
163
+ TYPE *d = vd, *n = vn, *m = vm; \
164
+ for (i = 0; i < oprsz / sizeof(TYPE); i++) { \
165
+ d[i] = FUNC(n[i], m[i], stat); \
166
+ } \
167
+}
168
+
169
+DO_3OP(gvec_fadd_h, float16_add, float16)
170
+DO_3OP(gvec_fadd_s, float32_add, float32)
171
+DO_3OP(gvec_fadd_d, float64_add, float64)
172
+
173
+DO_3OP(gvec_fsub_h, float16_sub, float16)
174
+DO_3OP(gvec_fsub_s, float32_sub, float32)
175
+DO_3OP(gvec_fsub_d, float64_sub, float64)
176
+
177
+DO_3OP(gvec_fmul_h, float16_mul, float16)
178
+DO_3OP(gvec_fmul_s, float32_mul, float32)
179
+DO_3OP(gvec_fmul_d, float64_mul, float64)
180
+
181
+DO_3OP(gvec_ftsmul_h, float16_ftsmul, float16)
182
+DO_3OP(gvec_ftsmul_s, float32_ftsmul, float32)
183
+DO_3OP(gvec_ftsmul_d, float64_ftsmul, float64)
184
+
185
+#ifdef TARGET_AARCH64
186
+
187
+DO_3OP(gvec_recps_h, helper_recpsf_f16, float16)
188
+DO_3OP(gvec_recps_s, helper_recpsf_f32, float32)
189
+DO_3OP(gvec_recps_d, helper_recpsf_f64, float64)
190
+
191
+DO_3OP(gvec_rsqrts_h, helper_rsqrtsf_f16, float16)
192
+DO_3OP(gvec_rsqrts_s, helper_rsqrtsf_f32, float32)
193
+DO_3OP(gvec_rsqrts_d, helper_rsqrtsf_f64, float64)
194
+
195
+#endif
196
+#undef DO_3OP
197
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
198
index XXXXXXX..XXXXXXX 100644
199
--- a/target/arm/sve.decode
200
+++ b/target/arm/sve.decode
201
@@ -XXX,XX +XXX,XX @@ UMIN_zzi 00100101 .. 101 011 110 ........ ..... @rdn_i8u
202
# SVE integer multiply immediate (unpredicated)
203
MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
204
205
+### SVE Floating Point Arithmetic - Unpredicated Group
206
+
207
+# SVE floating-point arithmetic (unpredicated)
208
+FADD_zzz 01100101 .. 0 ..... 000 000 ..... ..... @rd_rn_rm
209
+FSUB_zzz 01100101 .. 0 ..... 000 001 ..... ..... @rd_rn_rm
210
+FMUL_zzz 01100101 .. 0 ..... 000 010 ..... ..... @rd_rn_rm
211
+FTSMUL 01100101 .. 0 ..... 000 011 ..... ..... @rd_rn_rm
212
+FRECPS 01100101 .. 0 ..... 000 110 ..... ..... @rd_rn_rm
213
+FRSQRTS 01100101 .. 0 ..... 000 111 ..... ..... @rd_rn_rm
214
+
215
### SVE Memory - 32-bit Gather and Unsized Contiguous Group
216
217
# SVE load predicate register
218
--
109
--
219
2.17.1
110
2.20.1
220
111
221
112
diff view generated by jsdifflib
1
Convert the pckbd device away from using the old_mmio field
1
Enable the FPU by default for the Cortex-M4 and Cortex-M33.
2
of MemoryRegionOps. This change only affects the memory-mapped
3
variant of the i8042, which is used by the Unicore32 'puv3'
4
board and the MIPS Jazz boards 'magnum' and 'pica61'.
5
2
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180601141223.26630-6-peter.maydell@linaro.org
5
Message-id: 20190416125744.27770-27-peter.maydell@linaro.org
9
---
6
---
10
hw/input/pckbd.c | 14 ++++++++------
7
target/arm/cpu.c | 8 ++++++++
11
1 file changed, 8 insertions(+), 6 deletions(-)
8
1 file changed, 8 insertions(+)
12
9
13
diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c
10
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
14
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/input/pckbd.c
12
--- a/target/arm/cpu.c
16
+++ b/hw/input/pckbd.c
13
+++ b/target/arm/cpu.c
17
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_kbd = {
14
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
18
};
15
set_feature(&cpu->env, ARM_FEATURE_M);
19
16
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
20
/* Memory mapped interface */
17
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
21
-static uint32_t kbd_mm_readb (void *opaque, hwaddr addr)
18
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
22
+static uint64_t kbd_mm_readfn(void *opaque, hwaddr addr, unsigned size)
19
cpu->midr = 0x410fc240; /* r0p0 */
23
{
20
cpu->pmsav7_dregion = 8;
24
KBDState *s = opaque;
21
+ cpu->isar.mvfr0 = 0x10110021;
25
22
+ cpu->isar.mvfr1 = 0x11000011;
26
@@ -XXX,XX +XXX,XX @@ static uint32_t kbd_mm_readb (void *opaque, hwaddr addr)
23
+ cpu->isar.mvfr2 = 0x00000000;
27
return kbd_read_data(s, 0, 1) & 0xff;
24
cpu->id_pfr0 = 0x00000030;
28
}
25
cpu->id_pfr1 = 0x00000200;
29
26
cpu->id_dfr0 = 0x00100000;
30
-static void kbd_mm_writeb (void *opaque, hwaddr addr, uint32_t value)
27
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
31
+static void kbd_mm_writefn(void *opaque, hwaddr addr,
28
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
32
+ uint64_t value, unsigned size)
29
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
33
{
30
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
34
KBDState *s = opaque;
31
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
35
32
cpu->midr = 0x410fd213; /* r0p3 */
36
@@ -XXX,XX +XXX,XX @@ static void kbd_mm_writeb (void *opaque, hwaddr addr, uint32_t value)
33
cpu->pmsav7_dregion = 16;
37
kbd_write_data(s, 0, value & 0xff, 1);
34
cpu->sau_sregion = 8;
38
}
35
+ cpu->isar.mvfr0 = 0x10110021;
39
36
+ cpu->isar.mvfr1 = 0x11000011;
40
+
37
+ cpu->isar.mvfr2 = 0x00000040;
41
static const MemoryRegionOps i8042_mmio_ops = {
38
cpu->id_pfr0 = 0x00000030;
42
+ .read = kbd_mm_readfn,
39
cpu->id_pfr1 = 0x00000210;
43
+ .write = kbd_mm_writefn,
40
cpu->id_dfr0 = 0x00200000;
44
+ .valid.min_access_size = 1,
45
+ .valid.max_access_size = 4,
46
.endianness = DEVICE_NATIVE_ENDIAN,
47
- .old_mmio = {
48
- .read = { kbd_mm_readb, kbd_mm_readb, kbd_mm_readb },
49
- .write = { kbd_mm_writeb, kbd_mm_writeb, kbd_mm_writeb },
50
- },
51
};
52
53
void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
54
--
41
--
55
2.17.1
42
2.20.1
56
43
57
44
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Rearrange the arithmetic so that we are agnostic about the total size
3
This device is used by both ARM (BCM2836, for raspi2) and AArch64
4
of the vector and the size of the element. This will allow us to index
4
(BCM2837, for raspi3) targets, and is not CPU-specific.
5
up to the 32nd byte and with 16-byte elements.
5
Move it to common object, so we build it once for all targets.
6
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190427133028.12874-1-philmd@redhat.com
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180613015641.5667-2-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
target/arm/translate-a64.h | 26 +++++++++++++++++---------
12
hw/dma/Makefile.objs | 2 +-
13
1 file changed, 17 insertions(+), 9 deletions(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
14
15
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
15
diff --git a/hw/dma/Makefile.objs b/hw/dma/Makefile.objs
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.h
17
--- a/hw/dma/Makefile.objs
18
+++ b/target/arm/translate-a64.h
18
+++ b/hw/dma/Makefile.objs
19
@@ -XXX,XX +XXX,XX @@ static inline void assert_fp_access_checked(DisasContext *s)
19
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zdma.o
20
static inline int vec_reg_offset(DisasContext *s, int regno,
20
21
int element, TCGMemOp size)
21
obj-$(CONFIG_OMAP) += omap_dma.o soc_dma.o
22
{
22
obj-$(CONFIG_PXA2XX) += pxa2xx_dma.o
23
- int offs = 0;
23
-obj-$(CONFIG_RASPI) += bcm2835_dma.o
24
+ int element_size = 1 << size;
24
+common-obj-$(CONFIG_RASPI) += bcm2835_dma.o
25
+ int offs = element * element_size;
26
#ifdef HOST_WORDS_BIGENDIAN
27
/* This is complicated slightly because vfp.zregs[n].d[0] is
28
- * still the low half and vfp.zregs[n].d[1] the high half
29
- * of the 128 bit vector, even on big endian systems.
30
- * Calculate the offset assuming a fully bigendian 128 bits,
31
- * then XOR to account for the order of the two 64 bit halves.
32
+ * still the lowest and vfp.zregs[n].d[15] the highest of the
33
+ * 256 byte vector, even on big endian systems.
34
+ *
35
+ * Calculate the offset assuming fully little-endian,
36
+ * then XOR to account for the order of the 8-byte units.
37
+ *
38
+ * For 16 byte elements, the two 8 byte halves will not form a
39
+ * host int128 if the host is bigendian, since they're in the
40
+ * wrong order. However the only 16 byte operation we have is
41
+ * a move, so we can ignore this for the moment. More complicated
42
+ * operations will have to special case loading and storing from
43
+ * the zregs array.
44
*/
45
- offs += (16 - ((element + 1) * (1 << size)));
46
- offs ^= 8;
47
-#else
48
- offs += element * (1 << size);
49
+ if (element_size < 8) {
50
+ offs ^= 8 - element_size;
51
+ }
52
#endif
53
offs += offsetof(CPUARMState, vfp.zregs[regno]);
54
assert_fp_access_checked(s);
55
--
25
--
56
2.17.1
26
2.20.1
57
27
58
28
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Cédric Le Goater <clg@kaod.org>
5
Message-id: 20180613015641.5667-18-richard.henderson@linaro.org
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Message-id: 20190412165416.7977-2-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
9
---
8
target/arm/helper-sve.h | 25 +++++++
10
hw/arm/aspeed.c | 13 +++++++++----
9
target/arm/sve_helper.c | 41 +++++++++++
11
1 file changed, 9 insertions(+), 4 deletions(-)
10
target/arm/translate-sve.c | 144 +++++++++++++++++++++++++++++++++++++
11
target/arm/sve.decode | 26 +++++++
12
4 files changed, 236 insertions(+)
13
12
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
13
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
15
--- a/hw/arm/aspeed.c
17
+++ b/target/arm/helper-sve.h
16
+++ b/hw/arm/aspeed.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_brkns, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
17
@@ -XXX,XX +XXX,XX @@
19
DEF_HELPER_FLAGS_3(sve_cntp, TCG_CALL_NO_RWG, i64, ptr, ptr, i32)
18
#include "hw/arm/aspeed_soc.h"
20
19
#include "hw/boards.h"
21
DEF_HELPER_FLAGS_3(sve_while, TCG_CALL_NO_RWG, i32, ptr, i32, i32)
20
#include "hw/i2c/smbus_eeprom.h"
22
+
21
+#include "hw/misc/pca9552.h"
23
+DEF_HELPER_FLAGS_4(sve_subri_b, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
22
+#include "hw/misc/tmp105.h"
24
+DEF_HELPER_FLAGS_4(sve_subri_h, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
23
#include "qemu/log.h"
25
+DEF_HELPER_FLAGS_4(sve_subri_s, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
24
#include "sysemu/block-backend.h"
26
+DEF_HELPER_FLAGS_4(sve_subri_d, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
25
#include "hw/loader.h"
27
+
26
@@ -XXX,XX +XXX,XX @@ static void ast2500_evb_i2c_init(AspeedBoardState *bmc)
28
+DEF_HELPER_FLAGS_4(sve_smaxi_b, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
27
eeprom_buf);
29
+DEF_HELPER_FLAGS_4(sve_smaxi_h, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
28
30
+DEF_HELPER_FLAGS_4(sve_smaxi_s, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
29
/* The AST2500 EVB expects a LM75 but a TMP105 is compatible */
31
+DEF_HELPER_FLAGS_4(sve_smaxi_d, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
30
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7), "tmp105", 0x4d);
32
+
31
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7),
33
+DEF_HELPER_FLAGS_4(sve_smini_b, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
32
+ TYPE_TMP105, 0x4d);
34
+DEF_HELPER_FLAGS_4(sve_smini_h, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
33
35
+DEF_HELPER_FLAGS_4(sve_smini_s, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
34
/* The AST2500 EVB does not have an RTC. Let's pretend that one is
36
+DEF_HELPER_FLAGS_4(sve_smini_d, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
35
* plugged on the I2C bus header */
37
+
36
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
38
+DEF_HELPER_FLAGS_4(sve_umaxi_b, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
37
AspeedSoCState *soc = &bmc->soc;
39
+DEF_HELPER_FLAGS_4(sve_umaxi_h, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
38
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
40
+DEF_HELPER_FLAGS_4(sve_umaxi_s, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
39
41
+DEF_HELPER_FLAGS_4(sve_umaxi_d, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
40
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), "pca9552", 0x60);
42
+
41
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), TYPE_PCA9552,
43
+DEF_HELPER_FLAGS_4(sve_umini_b, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
42
+ 0x60);
44
+DEF_HELPER_FLAGS_4(sve_umini_h, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
43
45
+DEF_HELPER_FLAGS_4(sve_umini_s, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
44
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), "tmp423", 0x4c);
46
+DEF_HELPER_FLAGS_4(sve_umini_d, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
45
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 5), "tmp423", 0x4c);
47
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
46
48
index XXXXXXX..XXXXXXX 100644
47
/* The Witherspoon expects a TMP275 but a TMP105 is compatible */
49
--- a/target/arm/sve_helper.c
48
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), "tmp105", 0x4a);
50
+++ b/target/arm/sve_helper.c
49
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), TYPE_TMP105,
51
@@ -XXX,XX +XXX,XX @@ DO_VPZ_D(sve_uminv_d, uint64_t, uint64_t, -1, DO_MIN)
50
+ 0x4a);
52
#undef DO_VPZ
51
53
#undef DO_VPZ_D
52
/* The witherspoon board expects Epson RX8900 I2C RTC but a ds1338 is
54
53
* good enough */
55
+/* Two vector operand, one scalar operand, unpredicated. */
54
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
56
+#define DO_ZZI(NAME, TYPE, OP) \
55
57
+void HELPER(NAME)(void *vd, void *vn, uint64_t s64, uint32_t desc) \
56
smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), 0x51,
58
+{ \
57
eeprom_buf);
59
+ intptr_t i, opr_sz = simd_oprsz(desc) / sizeof(TYPE); \
58
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "pca9552",
60
+ TYPE s = s64, *d = vd, *n = vn; \
59
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), TYPE_PCA9552,
61
+ for (i = 0; i < opr_sz; ++i) { \
60
0x60);
62
+ d[i] = OP(n[i], s); \
63
+ } \
64
+}
65
+
66
+#define DO_SUBR(X, Y) (Y - X)
67
+
68
+DO_ZZI(sve_subri_b, uint8_t, DO_SUBR)
69
+DO_ZZI(sve_subri_h, uint16_t, DO_SUBR)
70
+DO_ZZI(sve_subri_s, uint32_t, DO_SUBR)
71
+DO_ZZI(sve_subri_d, uint64_t, DO_SUBR)
72
+
73
+DO_ZZI(sve_smaxi_b, int8_t, DO_MAX)
74
+DO_ZZI(sve_smaxi_h, int16_t, DO_MAX)
75
+DO_ZZI(sve_smaxi_s, int32_t, DO_MAX)
76
+DO_ZZI(sve_smaxi_d, int64_t, DO_MAX)
77
+
78
+DO_ZZI(sve_smini_b, int8_t, DO_MIN)
79
+DO_ZZI(sve_smini_h, int16_t, DO_MIN)
80
+DO_ZZI(sve_smini_s, int32_t, DO_MIN)
81
+DO_ZZI(sve_smini_d, int64_t, DO_MIN)
82
+
83
+DO_ZZI(sve_umaxi_b, uint8_t, DO_MAX)
84
+DO_ZZI(sve_umaxi_h, uint16_t, DO_MAX)
85
+DO_ZZI(sve_umaxi_s, uint32_t, DO_MAX)
86
+DO_ZZI(sve_umaxi_d, uint64_t, DO_MAX)
87
+
88
+DO_ZZI(sve_umini_b, uint8_t, DO_MIN)
89
+DO_ZZI(sve_umini_h, uint16_t, DO_MIN)
90
+DO_ZZI(sve_umini_s, uint32_t, DO_MIN)
91
+DO_ZZI(sve_umini_d, uint64_t, DO_MIN)
92
+
93
+#undef DO_ZZI
94
+
95
#undef DO_AND
96
#undef DO_ORR
97
#undef DO_EOR
98
@@ -XXX,XX +XXX,XX @@ DO_VPZ_D(sve_uminv_d, uint64_t, uint64_t, -1, DO_MIN)
99
#undef DO_ASR
100
#undef DO_LSR
101
#undef DO_LSL
102
+#undef DO_SUBR
103
104
/* Similar to the ARM LastActiveElement pseudocode function, except the
105
result is multiplied by the element size. This includes the not found
106
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/translate-sve.c
109
+++ b/target/arm/translate-sve.c
110
@@ -XXX,XX +XXX,XX @@ static inline int expand_imm_sh8s(int x)
111
return (int8_t)x << (x & 0x100 ? 8 : 0);
112
}
61
}
113
62
114
+static inline int expand_imm_sh8u(int x)
115
+{
116
+ return (uint8_t)x << (x & 0x100 ? 8 : 0);
117
+}
118
+
119
/*
120
* Include the generated decoder.
121
*/
122
@@ -XXX,XX +XXX,XX @@ static bool trans_DUP_i(DisasContext *s, arg_DUP_i *a, uint32_t insn)
123
return true;
124
}
125
126
+static bool trans_ADD_zzi(DisasContext *s, arg_rri_esz *a, uint32_t insn)
127
+{
128
+ if (a->esz == 0 && extract32(insn, 13, 1)) {
129
+ return false;
130
+ }
131
+ if (sve_access_check(s)) {
132
+ unsigned vsz = vec_full_reg_size(s);
133
+ tcg_gen_gvec_addi(a->esz, vec_full_reg_offset(s, a->rd),
134
+ vec_full_reg_offset(s, a->rn), a->imm, vsz, vsz);
135
+ }
136
+ return true;
137
+}
138
+
139
+static bool trans_SUB_zzi(DisasContext *s, arg_rri_esz *a, uint32_t insn)
140
+{
141
+ a->imm = -a->imm;
142
+ return trans_ADD_zzi(s, a, insn);
143
+}
144
+
145
+static bool trans_SUBR_zzi(DisasContext *s, arg_rri_esz *a, uint32_t insn)
146
+{
147
+ static const GVecGen2s op[4] = {
148
+ { .fni8 = tcg_gen_vec_sub8_i64,
149
+ .fniv = tcg_gen_sub_vec,
150
+ .fno = gen_helper_sve_subri_b,
151
+ .opc = INDEX_op_sub_vec,
152
+ .vece = MO_8,
153
+ .scalar_first = true },
154
+ { .fni8 = tcg_gen_vec_sub16_i64,
155
+ .fniv = tcg_gen_sub_vec,
156
+ .fno = gen_helper_sve_subri_h,
157
+ .opc = INDEX_op_sub_vec,
158
+ .vece = MO_16,
159
+ .scalar_first = true },
160
+ { .fni4 = tcg_gen_sub_i32,
161
+ .fniv = tcg_gen_sub_vec,
162
+ .fno = gen_helper_sve_subri_s,
163
+ .opc = INDEX_op_sub_vec,
164
+ .vece = MO_32,
165
+ .scalar_first = true },
166
+ { .fni8 = tcg_gen_sub_i64,
167
+ .fniv = tcg_gen_sub_vec,
168
+ .fno = gen_helper_sve_subri_d,
169
+ .opc = INDEX_op_sub_vec,
170
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
171
+ .vece = MO_64,
172
+ .scalar_first = true }
173
+ };
174
+
175
+ if (a->esz == 0 && extract32(insn, 13, 1)) {
176
+ return false;
177
+ }
178
+ if (sve_access_check(s)) {
179
+ unsigned vsz = vec_full_reg_size(s);
180
+ TCGv_i64 c = tcg_const_i64(a->imm);
181
+ tcg_gen_gvec_2s(vec_full_reg_offset(s, a->rd),
182
+ vec_full_reg_offset(s, a->rn),
183
+ vsz, vsz, c, &op[a->esz]);
184
+ tcg_temp_free_i64(c);
185
+ }
186
+ return true;
187
+}
188
+
189
+static bool trans_MUL_zzi(DisasContext *s, arg_rri_esz *a, uint32_t insn)
190
+{
191
+ if (sve_access_check(s)) {
192
+ unsigned vsz = vec_full_reg_size(s);
193
+ tcg_gen_gvec_muli(a->esz, vec_full_reg_offset(s, a->rd),
194
+ vec_full_reg_offset(s, a->rn), a->imm, vsz, vsz);
195
+ }
196
+ return true;
197
+}
198
+
199
+static bool do_zzi_sat(DisasContext *s, arg_rri_esz *a, uint32_t insn,
200
+ bool u, bool d)
201
+{
202
+ if (a->esz == 0 && extract32(insn, 13, 1)) {
203
+ return false;
204
+ }
205
+ if (sve_access_check(s)) {
206
+ TCGv_i64 val = tcg_const_i64(a->imm);
207
+ do_sat_addsub_vec(s, a->esz, a->rd, a->rn, val, u, d);
208
+ tcg_temp_free_i64(val);
209
+ }
210
+ return true;
211
+}
212
+
213
+static bool trans_SQADD_zzi(DisasContext *s, arg_rri_esz *a, uint32_t insn)
214
+{
215
+ return do_zzi_sat(s, a, insn, false, false);
216
+}
217
+
218
+static bool trans_UQADD_zzi(DisasContext *s, arg_rri_esz *a, uint32_t insn)
219
+{
220
+ return do_zzi_sat(s, a, insn, true, false);
221
+}
222
+
223
+static bool trans_SQSUB_zzi(DisasContext *s, arg_rri_esz *a, uint32_t insn)
224
+{
225
+ return do_zzi_sat(s, a, insn, false, true);
226
+}
227
+
228
+static bool trans_UQSUB_zzi(DisasContext *s, arg_rri_esz *a, uint32_t insn)
229
+{
230
+ return do_zzi_sat(s, a, insn, true, true);
231
+}
232
+
233
+static bool do_zzi_ool(DisasContext *s, arg_rri_esz *a, gen_helper_gvec_2i *fn)
234
+{
235
+ if (sve_access_check(s)) {
236
+ unsigned vsz = vec_full_reg_size(s);
237
+ TCGv_i64 c = tcg_const_i64(a->imm);
238
+
239
+ tcg_gen_gvec_2i_ool(vec_full_reg_offset(s, a->rd),
240
+ vec_full_reg_offset(s, a->rn),
241
+ c, vsz, vsz, 0, fn);
242
+ tcg_temp_free_i64(c);
243
+ }
244
+ return true;
245
+}
246
+
247
+#define DO_ZZI(NAME, name) \
248
+static bool trans_##NAME##_zzi(DisasContext *s, arg_rri_esz *a, \
249
+ uint32_t insn) \
250
+{ \
251
+ static gen_helper_gvec_2i * const fns[4] = { \
252
+ gen_helper_sve_##name##i_b, gen_helper_sve_##name##i_h, \
253
+ gen_helper_sve_##name##i_s, gen_helper_sve_##name##i_d, \
254
+ }; \
255
+ return do_zzi_ool(s, a, fns[a->esz]); \
256
+}
257
+
258
+DO_ZZI(SMAX, smax)
259
+DO_ZZI(UMAX, umax)
260
+DO_ZZI(SMIN, smin)
261
+DO_ZZI(UMIN, umin)
262
+
263
+#undef DO_ZZI
264
+
265
/*
266
*** SVE Memory - 32-bit Gather and Unsized Contiguous Group
267
*/
268
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
269
index XXXXXXX..XXXXXXX 100644
270
--- a/target/arm/sve.decode
271
+++ b/target/arm/sve.decode
272
@@ -XXX,XX +XXX,XX @@
273
274
# Signed 8-bit immediate, optionally shifted left by 8.
275
%sh8_i8s 5:9 !function=expand_imm_sh8s
276
+# Unsigned 8-bit immediate, optionally shifted left by 8.
277
+%sh8_i8u 5:9 !function=expand_imm_sh8u
278
279
# Either a copy of rd (at bit 0), or a different source
280
# as propagated via the MOVPRFX instruction.
281
@@ -XXX,XX +XXX,XX @@
282
@pd_pn_pm ........ esz:2 .. rm:4 ....... rn:4 . rd:4 &rrr_esz
283
@rdn_rm ........ esz:2 ...... ...... rm:5 rd:5 \
284
&rrr_esz rn=%reg_movprfx
285
+@rdn_sh_i8u ........ esz:2 ...... ...... ..... rd:5 \
286
+ &rri_esz rn=%reg_movprfx imm=%sh8_i8u
287
+@rdn_i8u ........ esz:2 ...... ... imm:8 rd:5 \
288
+ &rri_esz rn=%reg_movprfx
289
+@rdn_i8s ........ esz:2 ...... ... imm:s8 rd:5 \
290
+ &rri_esz rn=%reg_movprfx
291
292
# Three operand with "memory" size, aka immediate left shift
293
@rd_rn_msz_rm ........ ... rm:5 .... imm:2 rn:5 rd:5 &rrri
294
@@ -XXX,XX +XXX,XX @@ FDUP 00100101 esz:2 111 00 1110 imm:8 rd:5
295
# SVE broadcast integer immediate (unpredicated)
296
DUP_i 00100101 esz:2 111 00 011 . ........ rd:5 imm=%sh8_i8s
297
298
+# SVE integer add/subtract immediate (unpredicated)
299
+ADD_zzi 00100101 .. 100 000 11 . ........ ..... @rdn_sh_i8u
300
+SUB_zzi 00100101 .. 100 001 11 . ........ ..... @rdn_sh_i8u
301
+SUBR_zzi 00100101 .. 100 011 11 . ........ ..... @rdn_sh_i8u
302
+SQADD_zzi 00100101 .. 100 100 11 . ........ ..... @rdn_sh_i8u
303
+UQADD_zzi 00100101 .. 100 101 11 . ........ ..... @rdn_sh_i8u
304
+SQSUB_zzi 00100101 .. 100 110 11 . ........ ..... @rdn_sh_i8u
305
+UQSUB_zzi 00100101 .. 100 111 11 . ........ ..... @rdn_sh_i8u
306
+
307
+# SVE integer min/max immediate (unpredicated)
308
+SMAX_zzi 00100101 .. 101 000 110 ........ ..... @rdn_i8s
309
+UMAX_zzi 00100101 .. 101 001 110 ........ ..... @rdn_i8u
310
+SMIN_zzi 00100101 .. 101 010 110 ........ ..... @rdn_i8s
311
+UMIN_zzi 00100101 .. 101 011 110 ........ ..... @rdn_i8u
312
+
313
+# SVE integer multiply immediate (unpredicated)
314
+MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
315
+
316
### SVE Memory - 32-bit Gather and Unsized Contiguous Group
317
318
# SVE load predicate register
319
--
63
--
320
2.17.1
64
2.20.1
321
65
322
66
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Suggested-by: Markus Armbruster <armbru@redhat.com>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20190412165416.7977-3-philmd@redhat.com
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180613015641.5667-8-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
target/arm/translate-sve.c | 19 +++++++++++++++++++
9
hw/arm/nseries.c | 3 ++-
9
target/arm/sve.decode | 6 ++++++
10
1 file changed, 2 insertions(+), 1 deletion(-)
10
2 files changed, 25 insertions(+)
11
11
12
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
12
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-sve.c
14
--- a/hw/arm/nseries.c
15
+++ b/target/arm/translate-sve.c
15
+++ b/hw/arm/nseries.c
16
@@ -XXX,XX +XXX,XX @@ static bool trans_LASTB_r(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
16
@@ -XXX,XX +XXX,XX @@
17
return do_last_general(s, a, true);
17
#include "hw/boards.h"
18
#include "hw/i2c/i2c.h"
19
#include "hw/devices.h"
20
+#include "hw/misc/tmp105.h"
21
#include "hw/block/flash.h"
22
#include "hw/hw.h"
23
#include "hw/bt.h"
24
@@ -XXX,XX +XXX,XX @@ static void n8x0_i2c_setup(struct n800_s *s)
25
qemu_register_powerdown_notifier(&n8x0_system_powerdown_notifier);
26
27
/* Attach a TMP105 PM chip (A0 wired to ground) */
28
- dev = i2c_create_slave(i2c, "tmp105", N8X0_TMP105_ADDR);
29
+ dev = i2c_create_slave(i2c, TYPE_TMP105, N8X0_TMP105_ADDR);
30
qdev_connect_gpio_out(dev, 0, tmp_irq);
18
}
31
}
19
32
20
+static bool trans_CPY_m_r(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
21
+{
22
+ if (sve_access_check(s)) {
23
+ do_cpy_m(s, a->esz, a->rd, a->rd, a->pg, cpu_reg_sp(s, a->rn));
24
+ }
25
+ return true;
26
+}
27
+
28
+static bool trans_CPY_m_v(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
29
+{
30
+ if (sve_access_check(s)) {
31
+ int ofs = vec_reg_offset(s, a->rn, 0, a->esz);
32
+ TCGv_i64 t = load_esz(cpu_env, ofs, a->esz);
33
+ do_cpy_m(s, a->esz, a->rd, a->rd, a->pg, t);
34
+ tcg_temp_free_i64(t);
35
+ }
36
+ return true;
37
+}
38
+
39
/*
40
*** SVE Memory - 32-bit Gather and Unsized Contiguous Group
41
*/
42
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/sve.decode
45
+++ b/target/arm/sve.decode
46
@@ -XXX,XX +XXX,XX @@ LASTB_v 00000101 .. 10001 1 100 ... ..... ..... @rd_pg_rn
47
LASTA_r 00000101 .. 10000 0 101 ... ..... ..... @rd_pg_rn
48
LASTB_r 00000101 .. 10000 1 101 ... ..... ..... @rd_pg_rn
49
50
+# SVE copy element from SIMD&FP scalar register
51
+CPY_m_v 00000101 .. 100000 100 ... ..... ..... @rd_pg_rn
52
+
53
+# SVE copy element from general register to vector (predicated)
54
+CPY_m_r 00000101 .. 101000 101 ... ..... ..... @rd_pg_rn
55
+
56
### SVE Predicate Logical Operations Group
57
58
# SVE predicate logical operations
59
--
33
--
60
2.17.1
34
2.20.1
61
35
62
36
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
No code used the tc6393xb_gpio_in_get() and tc6393xb_gpio_out_set()
4
functions since their introduction in commit 88d2c950b002. Time to
5
remove them.
6
7
Suggested-by: Markus Armbruster <armbru@redhat.com>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20190412165416.7977-4-philmd@redhat.com
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180613015641.5667-9-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
12
---
8
target/arm/helper-sve.h | 14 +++++++++++++
13
include/hw/devices.h | 3 ---
9
target/arm/sve_helper.c | 41 +++++++++++++++++++++++++++++++-------
14
hw/display/tc6393xb.c | 16 ----------------
10
target/arm/translate-sve.c | 38 +++++++++++++++++++++++++++++++++++
15
2 files changed, 19 deletions(-)
11
target/arm/sve.decode | 7 +++++++
12
4 files changed, 93 insertions(+), 7 deletions(-)
13
16
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
19
--- a/include/hw/devices.h
17
+++ b/target/arm/helper-sve.h
20
+++ b/include/hw/devices.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_compact_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
21
@@ -XXX,XX +XXX,XX @@ void retu_key_event(void *retu, int state);
19
22
typedef struct TC6393xbState TC6393xbState;
20
DEF_HELPER_FLAGS_2(sve_last_active_element, TCG_CALL_NO_RWG, s32, ptr, i32)
23
TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
21
24
uint32_t base, qemu_irq irq);
22
+DEF_HELPER_FLAGS_4(sve_revb_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
23
+DEF_HELPER_FLAGS_4(sve_revb_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
- qemu_irq handler);
24
+DEF_HELPER_FLAGS_4(sve_revb_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
27
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s);
25
+
28
qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
26
+DEF_HELPER_FLAGS_4(sve_revh_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
29
27
+DEF_HELPER_FLAGS_4(sve_revh_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
30
#endif
28
+
31
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
29
+DEF_HELPER_FLAGS_4(sve_revw_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
30
+
31
+DEF_HELPER_FLAGS_4(sve_rbit_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(sve_rbit_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_4(sve_rbit_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
34
+DEF_HELPER_FLAGS_4(sve_rbit_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
35
+
36
DEF_HELPER_FLAGS_5(sve_and_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
37
DEF_HELPER_FLAGS_5(sve_bic_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
38
DEF_HELPER_FLAGS_5(sve_eor_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
39
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
40
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/sve_helper.c
33
--- a/hw/display/tc6393xb.c
42
+++ b/target/arm/sve_helper.c
34
+++ b/hw/display/tc6393xb.c
43
@@ -XXX,XX +XXX,XX @@ static inline uint64_t expand_pred_s(uint8_t byte)
35
@@ -XXX,XX +XXX,XX @@ struct TC6393xbState {
44
return word[byte & 0x11];
36
blanked : 1;
45
}
37
};
46
38
47
+/* Swap 16-bit words within a 32-bit word. */
39
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s)
48
+static inline uint32_t hswap32(uint32_t h)
49
+{
50
+ return rol32(h, 16);
51
+}
52
+
53
+/* Swap 16-bit words within a 64-bit word. */
54
+static inline uint64_t hswap64(uint64_t h)
55
+{
56
+ uint64_t m = 0x0000ffff0000ffffull;
57
+ h = rol64(h, 32);
58
+ return ((h & m) << 16) | ((h >> 16) & m);
59
+}
60
+
61
+/* Swap 32-bit words within a 64-bit word. */
62
+static inline uint64_t wswap64(uint64_t h)
63
+{
64
+ return rol64(h, 32);
65
+}
66
+
67
#define LOGICAL_PPPP(NAME, FUNC) \
68
void HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, uint32_t desc) \
69
{ \
70
@@ -XXX,XX +XXX,XX @@ DO_ZPZ(sve_neg_h, uint16_t, H1_2, DO_NEG)
71
DO_ZPZ(sve_neg_s, uint32_t, H1_4, DO_NEG)
72
DO_ZPZ_D(sve_neg_d, uint64_t, DO_NEG)
73
74
+DO_ZPZ(sve_revb_h, uint16_t, H1_2, bswap16)
75
+DO_ZPZ(sve_revb_s, uint32_t, H1_4, bswap32)
76
+DO_ZPZ_D(sve_revb_d, uint64_t, bswap64)
77
+
78
+DO_ZPZ(sve_revh_s, uint32_t, H1_4, hswap32)
79
+DO_ZPZ_D(sve_revh_d, uint64_t, hswap64)
80
+
81
+DO_ZPZ_D(sve_revw_d, uint64_t, wswap64)
82
+
83
+DO_ZPZ(sve_rbit_b, uint8_t, H1, revbit8)
84
+DO_ZPZ(sve_rbit_h, uint16_t, H1_2, revbit16)
85
+DO_ZPZ(sve_rbit_s, uint32_t, H1_4, revbit32)
86
+DO_ZPZ_D(sve_rbit_d, uint64_t, revbit64)
87
+
88
/* Three-operand expander, unpredicated, in which the third operand is "wide".
89
*/
90
#define DO_ZZW(NAME, TYPE, TYPEW, H, OP) \
91
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_rev_b)(void *vd, void *vn, uint32_t desc)
92
}
93
}
94
95
-static inline uint64_t hswap64(uint64_t h)
96
-{
40
-{
97
- uint64_t m = 0x0000ffff0000ffffull;
41
- return s->gpio_in;
98
- h = rol64(h, 32);
99
- return ((h & m) << 16) | ((h >> 16) & m);
100
-}
42
-}
101
-
43
-
102
void HELPER(sve_rev_h)(void *vd, void *vn, uint32_t desc)
44
static void tc6393xb_gpio_set(void *opaque, int line, int level)
103
{
45
{
104
intptr_t i, j, opr_sz = simd_oprsz(desc);
46
// TC6393xbState *s = opaque;
105
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
47
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_gpio_set(void *opaque, int line, int level)
106
index XXXXXXX..XXXXXXX 100644
48
// FIXME: how does the chip reflect the GPIO input level change?
107
--- a/target/arm/translate-sve.c
108
+++ b/target/arm/translate-sve.c
109
@@ -XXX,XX +XXX,XX @@ static bool trans_CPY_m_v(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
110
return true;
111
}
49
}
112
50
113
+static bool trans_REVB(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
51
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
114
+{
52
- qemu_irq handler)
115
+ static gen_helper_gvec_3 * const fns[4] = {
53
-{
116
+ NULL,
54
- if (line >= TC6393XB_GPIOS) {
117
+ gen_helper_sve_revb_h,
55
- fprintf(stderr, "TC6393xb: no GPIO pin %d\n", line);
118
+ gen_helper_sve_revb_s,
56
- return;
119
+ gen_helper_sve_revb_d,
57
- }
120
+ };
58
-
121
+ return do_zpz_ool(s, a, fns[a->esz]);
59
- s->handler[line] = handler;
122
+}
60
-}
123
+
61
-
124
+static bool trans_REVH(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
62
static void tc6393xb_gpio_handler_update(TC6393xbState *s)
125
+{
63
{
126
+ static gen_helper_gvec_3 * const fns[4] = {
64
uint32_t level, diff;
127
+ NULL,
128
+ NULL,
129
+ gen_helper_sve_revh_s,
130
+ gen_helper_sve_revh_d,
131
+ };
132
+ return do_zpz_ool(s, a, fns[a->esz]);
133
+}
134
+
135
+static bool trans_REVW(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
136
+{
137
+ return do_zpz_ool(s, a, a->esz == 3 ? gen_helper_sve_revw_d : NULL);
138
+}
139
+
140
+static bool trans_RBIT(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
141
+{
142
+ static gen_helper_gvec_3 * const fns[4] = {
143
+ gen_helper_sve_rbit_b,
144
+ gen_helper_sve_rbit_h,
145
+ gen_helper_sve_rbit_s,
146
+ gen_helper_sve_rbit_d,
147
+ };
148
+ return do_zpz_ool(s, a, fns[a->esz]);
149
+}
150
+
151
/*
152
*** SVE Memory - 32-bit Gather and Unsized Contiguous Group
153
*/
154
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
155
index XXXXXXX..XXXXXXX 100644
156
--- a/target/arm/sve.decode
157
+++ b/target/arm/sve.decode
158
@@ -XXX,XX +XXX,XX @@ CPY_m_v 00000101 .. 100000 100 ... ..... ..... @rd_pg_rn
159
# SVE copy element from general register to vector (predicated)
160
CPY_m_r 00000101 .. 101000 101 ... ..... ..... @rd_pg_rn
161
162
+# SVE reverse within elements
163
+# Note esz >= operation size
164
+REVB 00000101 .. 1001 00 100 ... ..... ..... @rd_pg_rn
165
+REVH 00000101 .. 1001 01 100 ... ..... ..... @rd_pg_rn
166
+REVW 00000101 .. 1001 10 100 ... ..... ..... @rd_pg_rn
167
+RBIT 00000101 .. 1001 11 100 ... ..... ..... @rd_pg_rn
168
+
169
### SVE Predicate Logical Operations Group
170
171
# SVE predicate logical operations
172
--
65
--
173
2.17.1
66
2.20.1
174
67
175
68
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20180613015641.5667-15-richard.henderson@linaro.org
5
Message-id: 20190412165416.7977-5-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
target/arm/helper-sve.h | 2 +
8
include/hw/devices.h | 6 ------
9
target/arm/sve_helper.c | 14 ++++
9
include/hw/display/tc6393xb.h | 24 ++++++++++++++++++++++++
10
target/arm/translate-sve.c | 133 +++++++++++++++++++++++++++++++++++++
10
hw/arm/tosa.c | 2 +-
11
target/arm/sve.decode | 27 ++++++++
11
hw/display/tc6393xb.c | 2 +-
12
4 files changed, 176 insertions(+)
12
MAINTAINERS | 1 +
13
5 files changed, 27 insertions(+), 8 deletions(-)
14
create mode 100644 include/hw/display/tc6393xb.h
13
15
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
18
--- a/include/hw/devices.h
17
+++ b/target/arm/helper-sve.h
19
+++ b/include/hw/devices.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_brkbs_m, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
20
@@ -XXX,XX +XXX,XX @@ void *tahvo_init(qemu_irq irq, int betty);
19
21
20
DEF_HELPER_FLAGS_4(sve_brkn, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
22
void retu_key_event(void *retu, int state);
21
DEF_HELPER_FLAGS_4(sve_brkns, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
23
22
+
24
-/* tc6393xb.c */
23
+DEF_HELPER_FLAGS_3(sve_cntp, TCG_CALL_NO_RWG, i64, ptr, ptr, i32)
25
-typedef struct TC6393xbState TC6393xbState;
24
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
26
-TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
25
index XXXXXXX..XXXXXXX 100644
27
- uint32_t base, qemu_irq irq);
26
--- a/target/arm/sve_helper.c
28
-qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
27
+++ b/target/arm/sve_helper.c
29
-
28
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_brkns)(void *vd, void *vn, void *vg, uint32_t pred_desc)
30
#endif
29
return do_zero(vd, oprsz);
31
diff --git a/include/hw/display/tc6393xb.h b/include/hw/display/tc6393xb.h
30
}
32
new file mode 100644
31
}
33
index XXXXXXX..XXXXXXX
32
+
34
--- /dev/null
33
+uint64_t HELPER(sve_cntp)(void *vn, void *vg, uint32_t pred_desc)
35
+++ b/include/hw/display/tc6393xb.h
34
+{
35
+ intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
36
+ intptr_t esz = extract32(pred_desc, SIMD_DATA_SHIFT, 2);
37
+ uint64_t *n = vn, *g = vg, sum = 0, mask = pred_esz_masks[esz];
38
+ intptr_t i;
39
+
40
+ for (i = 0; i < DIV_ROUND_UP(oprsz, 8); ++i) {
41
+ uint64_t t = n[i] & g[i] & mask;
42
+ sum += ctpop64(t);
43
+ }
44
+ return sum;
45
+}
46
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/translate-sve.c
49
+++ b/target/arm/translate-sve.c
50
@@ -XXX,XX +XXX,XX @@
36
@@ -XXX,XX +XXX,XX @@
51
#include "translate-a64.h"
52
53
54
+typedef void GVecGen2sFn(unsigned, uint32_t, uint32_t,
55
+ TCGv_i64, uint32_t, uint32_t);
56
+
57
typedef void gen_helper_gvec_flags_3(TCGv_i32, TCGv_ptr, TCGv_ptr,
58
TCGv_ptr, TCGv_i32);
59
typedef void gen_helper_gvec_flags_4(TCGv_i32, TCGv_ptr, TCGv_ptr,
60
@@ -XXX,XX +XXX,XX @@ static bool trans_BRKN(DisasContext *s, arg_rpr_s *a, uint32_t insn)
61
return do_brk2(s, a, gen_helper_sve_brkn, gen_helper_sve_brkns);
62
}
63
64
+/*
37
+/*
65
+ *** SVE Predicate Count Group
38
+ * Toshiba TC6393XB I/O Controller.
39
+ * Found in Sharp Zaurus SL-6000 (tosa) or some
40
+ * Toshiba e-Series PDAs.
41
+ *
42
+ * Copyright (c) 2007 Hervé Poussineau
43
+ *
44
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
45
+ * See the COPYING file in the top-level directory.
66
+ */
46
+ */
67
+
47
+
68
+static void do_cntp(DisasContext *s, TCGv_i64 val, int esz, int pn, int pg)
48
+#ifndef HW_DISPLAY_TC6393XB_H
69
+{
49
+#define HW_DISPLAY_TC6393XB_H
70
+ unsigned psz = pred_full_reg_size(s);
71
+
50
+
72
+ if (psz <= 8) {
51
+#include "exec/memory.h"
73
+ uint64_t psz_mask;
52
+#include "hw/irq.h"
74
+
53
+
75
+ tcg_gen_ld_i64(val, cpu_env, pred_full_reg_offset(s, pn));
54
+typedef struct TC6393xbState TC6393xbState;
76
+ if (pn != pg) {
77
+ TCGv_i64 g = tcg_temp_new_i64();
78
+ tcg_gen_ld_i64(g, cpu_env, pred_full_reg_offset(s, pg));
79
+ tcg_gen_and_i64(val, val, g);
80
+ tcg_temp_free_i64(g);
81
+ }
82
+
55
+
83
+ /* Reduce the pred_esz_masks value simply to reduce the
56
+TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
84
+ * size of the code generated here.
57
+ uint32_t base, qemu_irq irq);
85
+ */
58
+qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
86
+ psz_mask = MAKE_64BIT_MASK(0, psz * 8);
87
+ tcg_gen_andi_i64(val, val, pred_esz_masks[esz] & psz_mask);
88
+
59
+
89
+ tcg_gen_ctpop_i64(val, val);
60
+#endif
90
+ } else {
61
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
91
+ TCGv_ptr t_pn = tcg_temp_new_ptr();
92
+ TCGv_ptr t_pg = tcg_temp_new_ptr();
93
+ unsigned desc;
94
+ TCGv_i32 t_desc;
95
+
96
+ desc = psz - 2;
97
+ desc = deposit32(desc, SIMD_DATA_SHIFT, 2, esz);
98
+
99
+ tcg_gen_addi_ptr(t_pn, cpu_env, pred_full_reg_offset(s, pn));
100
+ tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, pg));
101
+ t_desc = tcg_const_i32(desc);
102
+
103
+ gen_helper_sve_cntp(val, t_pn, t_pg, t_desc);
104
+ tcg_temp_free_ptr(t_pn);
105
+ tcg_temp_free_ptr(t_pg);
106
+ tcg_temp_free_i32(t_desc);
107
+ }
108
+}
109
+
110
+static bool trans_CNTP(DisasContext *s, arg_CNTP *a, uint32_t insn)
111
+{
112
+ if (sve_access_check(s)) {
113
+ do_cntp(s, cpu_reg(s, a->rd), a->esz, a->rn, a->pg);
114
+ }
115
+ return true;
116
+}
117
+
118
+static bool trans_INCDECP_r(DisasContext *s, arg_incdec_pred *a,
119
+ uint32_t insn)
120
+{
121
+ if (sve_access_check(s)) {
122
+ TCGv_i64 reg = cpu_reg(s, a->rd);
123
+ TCGv_i64 val = tcg_temp_new_i64();
124
+
125
+ do_cntp(s, val, a->esz, a->pg, a->pg);
126
+ if (a->d) {
127
+ tcg_gen_sub_i64(reg, reg, val);
128
+ } else {
129
+ tcg_gen_add_i64(reg, reg, val);
130
+ }
131
+ tcg_temp_free_i64(val);
132
+ }
133
+ return true;
134
+}
135
+
136
+static bool trans_INCDECP_z(DisasContext *s, arg_incdec2_pred *a,
137
+ uint32_t insn)
138
+{
139
+ if (a->esz == 0) {
140
+ return false;
141
+ }
142
+ if (sve_access_check(s)) {
143
+ unsigned vsz = vec_full_reg_size(s);
144
+ TCGv_i64 val = tcg_temp_new_i64();
145
+ GVecGen2sFn *gvec_fn = a->d ? tcg_gen_gvec_subs : tcg_gen_gvec_adds;
146
+
147
+ do_cntp(s, val, a->esz, a->pg, a->pg);
148
+ gvec_fn(a->esz, vec_full_reg_offset(s, a->rd),
149
+ vec_full_reg_offset(s, a->rn), val, vsz, vsz);
150
+ }
151
+ return true;
152
+}
153
+
154
+static bool trans_SINCDECP_r_32(DisasContext *s, arg_incdec_pred *a,
155
+ uint32_t insn)
156
+{
157
+ if (sve_access_check(s)) {
158
+ TCGv_i64 reg = cpu_reg(s, a->rd);
159
+ TCGv_i64 val = tcg_temp_new_i64();
160
+
161
+ do_cntp(s, val, a->esz, a->pg, a->pg);
162
+ do_sat_addsub_32(reg, val, a->u, a->d);
163
+ }
164
+ return true;
165
+}
166
+
167
+static bool trans_SINCDECP_r_64(DisasContext *s, arg_incdec_pred *a,
168
+ uint32_t insn)
169
+{
170
+ if (sve_access_check(s)) {
171
+ TCGv_i64 reg = cpu_reg(s, a->rd);
172
+ TCGv_i64 val = tcg_temp_new_i64();
173
+
174
+ do_cntp(s, val, a->esz, a->pg, a->pg);
175
+ do_sat_addsub_64(reg, val, a->u, a->d);
176
+ }
177
+ return true;
178
+}
179
+
180
+static bool trans_SINCDECP_z(DisasContext *s, arg_incdec2_pred *a,
181
+ uint32_t insn)
182
+{
183
+ if (a->esz == 0) {
184
+ return false;
185
+ }
186
+ if (sve_access_check(s)) {
187
+ TCGv_i64 val = tcg_temp_new_i64();
188
+ do_cntp(s, val, a->esz, a->pg, a->pg);
189
+ do_sat_addsub_vec(s, a->esz, a->rd, a->rn, val, a->u, a->d);
190
+ }
191
+ return true;
192
+}
193
+
194
/*
195
*** SVE Memory - 32-bit Gather and Unsized Contiguous Group
196
*/
197
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
198
index XXXXXXX..XXXXXXX 100644
62
index XXXXXXX..XXXXXXX 100644
199
--- a/target/arm/sve.decode
63
--- a/hw/arm/tosa.c
200
+++ b/target/arm/sve.decode
64
+++ b/hw/arm/tosa.c
201
@@ -XXX,XX +XXX,XX @@
65
@@ -XXX,XX +XXX,XX @@
202
&ptrue rd esz pat s
66
#include "hw/hw.h"
203
&incdec_cnt rd pat esz imm d u
67
#include "hw/arm/pxa.h"
204
&incdec2_cnt rd rn pat esz imm d u
68
#include "hw/arm/arm.h"
205
+&incdec_pred rd pg esz d u
69
-#include "hw/devices.h"
206
+&incdec2_pred rd rn pg esz d u
70
#include "hw/arm/sharpsl.h"
207
71
#include "hw/pcmcia.h"
208
###########################################################################
72
#include "hw/boards.h"
209
# Named instruction formats. These are generally used to
73
+#include "hw/display/tc6393xb.h"
74
#include "hw/i2c/i2c.h"
75
#include "hw/ssi/ssi.h"
76
#include "hw/sysbus.h"
77
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/display/tc6393xb.c
80
+++ b/hw/display/tc6393xb.c
210
@@ -XXX,XX +XXX,XX @@
81
@@ -XXX,XX +XXX,XX @@
211
82
#include "qapi/error.h"
212
# One register operand, with governing predicate, vector element size
83
#include "qemu/host-utils.h"
213
@rd_pg_rn ........ esz:2 ... ... ... pg:3 rn:5 rd:5 &rpr_esz
84
#include "hw/hw.h"
214
+@rd_pg4_pn ........ esz:2 ... ... .. pg:4 . rn:4 rd:5 &rpr_esz
85
-#include "hw/devices.h"
215
86
+#include "hw/display/tc6393xb.h"
216
# Two register operands with a 6-bit signed immediate.
87
#include "hw/block/flash.h"
217
@rd_rn_i6 ........ ... rn:5 ..... imm:s6 rd:5 &rri
88
#include "ui/console.h"
218
@@ -XXX,XX +XXX,XX @@
89
#include "ui/pixel_ops.h"
219
@incdec2_cnt ........ esz:2 .. .... ...... pat:5 rd:5 \
90
diff --git a/MAINTAINERS b/MAINTAINERS
220
&incdec2_cnt imm=%imm4_16_p1 rn=%reg_movprfx
91
index XXXXXXX..XXXXXXX 100644
221
92
--- a/MAINTAINERS
222
+# One register, predicate.
93
+++ b/MAINTAINERS
223
+# User must fill in U and D.
94
@@ -XXX,XX +XXX,XX @@ F: hw/misc/mst_fpga.c
224
+@incdec_pred ........ esz:2 .... .. ..... .. pg:4 rd:5 &incdec_pred
95
F: hw/misc/max111x.c
225
+@incdec2_pred ........ esz:2 .... .. ..... .. pg:4 rd:5 \
96
F: include/hw/arm/pxa.h
226
+ &incdec2_pred rn=%reg_movprfx
97
F: include/hw/arm/sharpsl.h
227
+
98
+F: include/hw/display/tc6393xb.h
228
###########################################################################
99
229
# Instruction patterns. Grouped according to the SVE encodingindex.xhtml.
100
SABRELITE / i.MX6
230
101
M: Peter Maydell <peter.maydell@linaro.org>
231
@@ -XXX,XX +XXX,XX @@ BRKB_m 00100101 1. 01000001 .... 0 .... 1 .... @pd_pg_pn_s
232
# SVE propagate break to next partition
233
BRKN 00100101 0. 01100001 .... 0 .... 0 .... @pd_pg_pn_s
234
235
+### SVE Predicate Count Group
236
+
237
+# SVE predicate count
238
+CNTP 00100101 .. 100 000 10 .... 0 .... ..... @rd_pg4_pn
239
+
240
+# SVE inc/dec register by predicate count
241
+INCDECP_r 00100101 .. 10110 d:1 10001 00 .... ..... @incdec_pred u=1
242
+
243
+# SVE inc/dec vector by predicate count
244
+INCDECP_z 00100101 .. 10110 d:1 10000 00 .... ..... @incdec2_pred u=1
245
+
246
+# SVE saturating inc/dec register by predicate count
247
+SINCDECP_r_32 00100101 .. 1010 d:1 u:1 10001 00 .... ..... @incdec_pred
248
+SINCDECP_r_64 00100101 .. 1010 d:1 u:1 10001 10 .... ..... @incdec_pred
249
+
250
+# SVE saturating inc/dec vector by predicate count
251
+SINCDECP_z 00100101 .. 1010 d:1 u:1 10000 00 .... ..... @incdec2_pred
252
+
253
### SVE Memory - 32-bit Gather and Unsized Contiguous Group
254
255
# SVE load predicate register
256
--
102
--
257
2.17.1
103
2.20.1
258
104
259
105
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Add an entries the Blizzard device in MAINTAINERS.
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
5
Message-id: 20180613015641.5667-13-richard.henderson@linaro.org
5
Reviewed-by: Thomas Huth <thuth@redhat.com>
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190412165416.7977-6-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
target/arm/helper-sve.h | 44 +++++++++++++++++++
11
include/hw/devices.h | 7 -------
9
target/arm/sve_helper.c | 88 ++++++++++++++++++++++++++++++++++++++
12
include/hw/display/blizzard.h | 22 ++++++++++++++++++++++
10
target/arm/translate-sve.c | 66 ++++++++++++++++++++++++++++
13
hw/arm/nseries.c | 1 +
11
target/arm/sve.decode | 23 ++++++++++
14
hw/display/blizzard.c | 2 +-
12
4 files changed, 221 insertions(+)
15
MAINTAINERS | 2 ++
16
5 files changed, 26 insertions(+), 8 deletions(-)
17
create mode 100644 include/hw/display/blizzard.h
13
18
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
19
diff --git a/include/hw/devices.h b/include/hw/devices.h
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
21
--- a/include/hw/devices.h
17
+++ b/target/arm/helper-sve.h
22
+++ b/include/hw/devices.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_cmplo_ppzw_s, TCG_CALL_NO_RWG,
23
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
19
DEF_HELPER_FLAGS_5(sve_cmpls_ppzw_s, TCG_CALL_NO_RWG,
24
/* stellaris_input.c */
20
i32, ptr, ptr, ptr, ptr, i32)
25
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
21
26
22
+DEF_HELPER_FLAGS_4(sve_cmpeq_ppzi_b, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
27
-/* blizzard.c */
23
+DEF_HELPER_FLAGS_4(sve_cmpne_ppzi_b, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
28
-void *s1d13745_init(qemu_irq gpio_int);
24
+DEF_HELPER_FLAGS_4(sve_cmpgt_ppzi_b, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
29
-void s1d13745_write(void *opaque, int dc, uint16_t value);
25
+DEF_HELPER_FLAGS_4(sve_cmpge_ppzi_b, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
30
-void s1d13745_write_block(void *opaque, int dc,
26
+DEF_HELPER_FLAGS_4(sve_cmplt_ppzi_b, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
31
- void *buf, size_t len, int pitch);
27
+DEF_HELPER_FLAGS_4(sve_cmple_ppzi_b, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
32
-uint16_t s1d13745_read(void *opaque, int dc);
28
+DEF_HELPER_FLAGS_4(sve_cmphs_ppzi_b, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
33
-
29
+DEF_HELPER_FLAGS_4(sve_cmphi_ppzi_b, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
34
/* cbus.c */
30
+DEF_HELPER_FLAGS_4(sve_cmplo_ppzi_b, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
35
typedef struct {
31
+DEF_HELPER_FLAGS_4(sve_cmpls_ppzi_b, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
36
qemu_irq clk;
32
+
37
diff --git a/include/hw/display/blizzard.h b/include/hw/display/blizzard.h
33
+DEF_HELPER_FLAGS_4(sve_cmpeq_ppzi_h, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
38
new file mode 100644
34
+DEF_HELPER_FLAGS_4(sve_cmpne_ppzi_h, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
39
index XXXXXXX..XXXXXXX
35
+DEF_HELPER_FLAGS_4(sve_cmpgt_ppzi_h, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
40
--- /dev/null
36
+DEF_HELPER_FLAGS_4(sve_cmpge_ppzi_h, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
41
+++ b/include/hw/display/blizzard.h
37
+DEF_HELPER_FLAGS_4(sve_cmplt_ppzi_h, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_4(sve_cmple_ppzi_h, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_4(sve_cmphs_ppzi_h, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_4(sve_cmphi_ppzi_h, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
41
+DEF_HELPER_FLAGS_4(sve_cmplo_ppzi_h, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
42
+DEF_HELPER_FLAGS_4(sve_cmpls_ppzi_h, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
43
+
44
+DEF_HELPER_FLAGS_4(sve_cmpeq_ppzi_s, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
45
+DEF_HELPER_FLAGS_4(sve_cmpne_ppzi_s, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
46
+DEF_HELPER_FLAGS_4(sve_cmpgt_ppzi_s, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
47
+DEF_HELPER_FLAGS_4(sve_cmpge_ppzi_s, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
48
+DEF_HELPER_FLAGS_4(sve_cmplt_ppzi_s, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
49
+DEF_HELPER_FLAGS_4(sve_cmple_ppzi_s, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
50
+DEF_HELPER_FLAGS_4(sve_cmphs_ppzi_s, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
51
+DEF_HELPER_FLAGS_4(sve_cmphi_ppzi_s, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
52
+DEF_HELPER_FLAGS_4(sve_cmplo_ppzi_s, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
53
+DEF_HELPER_FLAGS_4(sve_cmpls_ppzi_s, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
54
+
55
+DEF_HELPER_FLAGS_4(sve_cmpeq_ppzi_d, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
56
+DEF_HELPER_FLAGS_4(sve_cmpne_ppzi_d, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
57
+DEF_HELPER_FLAGS_4(sve_cmpgt_ppzi_d, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
58
+DEF_HELPER_FLAGS_4(sve_cmpge_ppzi_d, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
59
+DEF_HELPER_FLAGS_4(sve_cmplt_ppzi_d, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
60
+DEF_HELPER_FLAGS_4(sve_cmple_ppzi_d, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
61
+DEF_HELPER_FLAGS_4(sve_cmphs_ppzi_d, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
62
+DEF_HELPER_FLAGS_4(sve_cmphi_ppzi_d, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
63
+DEF_HELPER_FLAGS_4(sve_cmplo_ppzi_d, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
64
+DEF_HELPER_FLAGS_4(sve_cmpls_ppzi_d, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
65
+
66
DEF_HELPER_FLAGS_5(sve_and_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
67
DEF_HELPER_FLAGS_5(sve_bic_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
68
DEF_HELPER_FLAGS_5(sve_eor_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
69
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/target/arm/sve_helper.c
72
+++ b/target/arm/sve_helper.c
73
@@ -XXX,XX +XXX,XX @@ DO_CMP_PPZW_S(sve_cmpls_ppzw_s, uint32_t, uint64_t, <=)
74
#undef DO_CMP_PPZW_H
75
#undef DO_CMP_PPZW_S
76
#undef DO_CMP_PPZW
77
+
78
+/* Similar, but the second source is immediate. */
79
+#define DO_CMP_PPZI(NAME, TYPE, OP, H, MASK) \
80
+uint32_t HELPER(NAME)(void *vd, void *vn, void *vg, uint32_t desc) \
81
+{ \
82
+ intptr_t opr_sz = simd_oprsz(desc); \
83
+ uint32_t flags = PREDTEST_INIT; \
84
+ TYPE mm = simd_data(desc); \
85
+ intptr_t i = opr_sz; \
86
+ do { \
87
+ uint64_t out = 0, pg; \
88
+ do { \
89
+ i -= sizeof(TYPE), out <<= sizeof(TYPE); \
90
+ TYPE nn = *(TYPE *)(vn + H(i)); \
91
+ out |= nn OP mm; \
92
+ } while (i & 63); \
93
+ pg = *(uint64_t *)(vg + (i >> 3)) & MASK; \
94
+ out &= pg; \
95
+ *(uint64_t *)(vd + (i >> 3)) = out; \
96
+ flags = iter_predtest_bwd(out, pg, flags); \
97
+ } while (i > 0); \
98
+ return flags; \
99
+}
100
+
101
+#define DO_CMP_PPZI_B(NAME, TYPE, OP) \
102
+ DO_CMP_PPZI(NAME, TYPE, OP, H1, 0xffffffffffffffffull)
103
+#define DO_CMP_PPZI_H(NAME, TYPE, OP) \
104
+ DO_CMP_PPZI(NAME, TYPE, OP, H1_2, 0x5555555555555555ull)
105
+#define DO_CMP_PPZI_S(NAME, TYPE, OP) \
106
+ DO_CMP_PPZI(NAME, TYPE, OP, H1_4, 0x1111111111111111ull)
107
+#define DO_CMP_PPZI_D(NAME, TYPE, OP) \
108
+ DO_CMP_PPZI(NAME, TYPE, OP, , 0x0101010101010101ull)
109
+
110
+DO_CMP_PPZI_B(sve_cmpeq_ppzi_b, uint8_t, ==)
111
+DO_CMP_PPZI_H(sve_cmpeq_ppzi_h, uint16_t, ==)
112
+DO_CMP_PPZI_S(sve_cmpeq_ppzi_s, uint32_t, ==)
113
+DO_CMP_PPZI_D(sve_cmpeq_ppzi_d, uint64_t, ==)
114
+
115
+DO_CMP_PPZI_B(sve_cmpne_ppzi_b, uint8_t, !=)
116
+DO_CMP_PPZI_H(sve_cmpne_ppzi_h, uint16_t, !=)
117
+DO_CMP_PPZI_S(sve_cmpne_ppzi_s, uint32_t, !=)
118
+DO_CMP_PPZI_D(sve_cmpne_ppzi_d, uint64_t, !=)
119
+
120
+DO_CMP_PPZI_B(sve_cmpgt_ppzi_b, int8_t, >)
121
+DO_CMP_PPZI_H(sve_cmpgt_ppzi_h, int16_t, >)
122
+DO_CMP_PPZI_S(sve_cmpgt_ppzi_s, int32_t, >)
123
+DO_CMP_PPZI_D(sve_cmpgt_ppzi_d, int64_t, >)
124
+
125
+DO_CMP_PPZI_B(sve_cmpge_ppzi_b, int8_t, >=)
126
+DO_CMP_PPZI_H(sve_cmpge_ppzi_h, int16_t, >=)
127
+DO_CMP_PPZI_S(sve_cmpge_ppzi_s, int32_t, >=)
128
+DO_CMP_PPZI_D(sve_cmpge_ppzi_d, int64_t, >=)
129
+
130
+DO_CMP_PPZI_B(sve_cmphi_ppzi_b, uint8_t, >)
131
+DO_CMP_PPZI_H(sve_cmphi_ppzi_h, uint16_t, >)
132
+DO_CMP_PPZI_S(sve_cmphi_ppzi_s, uint32_t, >)
133
+DO_CMP_PPZI_D(sve_cmphi_ppzi_d, uint64_t, >)
134
+
135
+DO_CMP_PPZI_B(sve_cmphs_ppzi_b, uint8_t, >=)
136
+DO_CMP_PPZI_H(sve_cmphs_ppzi_h, uint16_t, >=)
137
+DO_CMP_PPZI_S(sve_cmphs_ppzi_s, uint32_t, >=)
138
+DO_CMP_PPZI_D(sve_cmphs_ppzi_d, uint64_t, >=)
139
+
140
+DO_CMP_PPZI_B(sve_cmplt_ppzi_b, int8_t, <)
141
+DO_CMP_PPZI_H(sve_cmplt_ppzi_h, int16_t, <)
142
+DO_CMP_PPZI_S(sve_cmplt_ppzi_s, int32_t, <)
143
+DO_CMP_PPZI_D(sve_cmplt_ppzi_d, int64_t, <)
144
+
145
+DO_CMP_PPZI_B(sve_cmple_ppzi_b, int8_t, <=)
146
+DO_CMP_PPZI_H(sve_cmple_ppzi_h, int16_t, <=)
147
+DO_CMP_PPZI_S(sve_cmple_ppzi_s, int32_t, <=)
148
+DO_CMP_PPZI_D(sve_cmple_ppzi_d, int64_t, <=)
149
+
150
+DO_CMP_PPZI_B(sve_cmplo_ppzi_b, uint8_t, <)
151
+DO_CMP_PPZI_H(sve_cmplo_ppzi_h, uint16_t, <)
152
+DO_CMP_PPZI_S(sve_cmplo_ppzi_s, uint32_t, <)
153
+DO_CMP_PPZI_D(sve_cmplo_ppzi_d, uint64_t, <)
154
+
155
+DO_CMP_PPZI_B(sve_cmpls_ppzi_b, uint8_t, <=)
156
+DO_CMP_PPZI_H(sve_cmpls_ppzi_h, uint16_t, <=)
157
+DO_CMP_PPZI_S(sve_cmpls_ppzi_s, uint32_t, <=)
158
+DO_CMP_PPZI_D(sve_cmpls_ppzi_d, uint64_t, <=)
159
+
160
+#undef DO_CMP_PPZI_B
161
+#undef DO_CMP_PPZI_H
162
+#undef DO_CMP_PPZI_S
163
+#undef DO_CMP_PPZI_D
164
+#undef DO_CMP_PPZI
165
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
166
index XXXXXXX..XXXXXXX 100644
167
--- a/target/arm/translate-sve.c
168
+++ b/target/arm/translate-sve.c
169
@@ -XXX,XX +XXX,XX @@
42
@@ -XXX,XX +XXX,XX @@
170
#include "translate-a64.h"
171
172
173
+typedef void gen_helper_gvec_flags_3(TCGv_i32, TCGv_ptr, TCGv_ptr,
174
+ TCGv_ptr, TCGv_i32);
175
typedef void gen_helper_gvec_flags_4(TCGv_i32, TCGv_ptr, TCGv_ptr,
176
TCGv_ptr, TCGv_ptr, TCGv_i32);
177
178
@@ -XXX,XX +XXX,XX @@ DO_PPZW(CMPLS, cmpls)
179
180
#undef DO_PPZW
181
182
+/*
43
+/*
183
+ *** SVE Integer Compare - Immediate Groups
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.
184
+ */
51
+ */
185
+
52
+
186
+static bool do_ppzi_flags(DisasContext *s, arg_rpri_esz *a,
53
+#ifndef HW_DISPLAY_BLIZZARD_H
187
+ gen_helper_gvec_flags_3 *gen_fn)
54
+#define HW_DISPLAY_BLIZZARD_H
188
+{
189
+ TCGv_ptr pd, zn, pg;
190
+ unsigned vsz;
191
+ TCGv_i32 t;
192
+
55
+
193
+ if (gen_fn == NULL) {
56
+#include "hw/irq.h"
194
+ return false;
195
+ }
196
+ if (!sve_access_check(s)) {
197
+ return true;
198
+ }
199
+
57
+
200
+ vsz = vec_full_reg_size(s);
58
+void *s1d13745_init(qemu_irq gpio_int);
201
+ t = tcg_const_i32(simd_desc(vsz, vsz, a->imm));
59
+void s1d13745_write(void *opaque, int dc, uint16_t value);
202
+ pd = tcg_temp_new_ptr();
60
+void s1d13745_write_block(void *opaque, int dc,
203
+ zn = tcg_temp_new_ptr();
61
+ void *buf, size_t len, int pitch);
204
+ pg = tcg_temp_new_ptr();
62
+uint16_t s1d13745_read(void *opaque, int dc);
205
+
63
+
206
+ tcg_gen_addi_ptr(pd, cpu_env, pred_full_reg_offset(s, a->rd));
64
+#endif
207
+ tcg_gen_addi_ptr(zn, cpu_env, vec_full_reg_offset(s, a->rn));
65
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
208
+ tcg_gen_addi_ptr(pg, cpu_env, pred_full_reg_offset(s, a->pg));
209
+
210
+ gen_fn(t, pd, zn, pg, t);
211
+
212
+ tcg_temp_free_ptr(pd);
213
+ tcg_temp_free_ptr(zn);
214
+ tcg_temp_free_ptr(pg);
215
+
216
+ do_pred_flags(t);
217
+
218
+ tcg_temp_free_i32(t);
219
+ return true;
220
+}
221
+
222
+#define DO_PPZI(NAME, name) \
223
+static bool trans_##NAME##_ppzi(DisasContext *s, arg_rpri_esz *a, \
224
+ uint32_t insn) \
225
+{ \
226
+ static gen_helper_gvec_flags_3 * const fns[4] = { \
227
+ gen_helper_sve_##name##_ppzi_b, gen_helper_sve_##name##_ppzi_h, \
228
+ gen_helper_sve_##name##_ppzi_s, gen_helper_sve_##name##_ppzi_d, \
229
+ }; \
230
+ return do_ppzi_flags(s, a, fns[a->esz]); \
231
+}
232
+
233
+DO_PPZI(CMPEQ, cmpeq)
234
+DO_PPZI(CMPNE, cmpne)
235
+DO_PPZI(CMPGT, cmpgt)
236
+DO_PPZI(CMPGE, cmpge)
237
+DO_PPZI(CMPHI, cmphi)
238
+DO_PPZI(CMPHS, cmphs)
239
+DO_PPZI(CMPLT, cmplt)
240
+DO_PPZI(CMPLE, cmple)
241
+DO_PPZI(CMPLO, cmplo)
242
+DO_PPZI(CMPLS, cmpls)
243
+
244
+#undef DO_PPZI
245
+
246
/*
247
*** SVE Memory - 32-bit Gather and Unsized Contiguous Group
248
*/
249
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
250
index XXXXXXX..XXXXXXX 100644
66
index XXXXXXX..XXXXXXX 100644
251
--- a/target/arm/sve.decode
67
--- a/hw/arm/nseries.c
252
+++ b/target/arm/sve.decode
68
+++ b/hw/arm/nseries.c
253
@@ -XXX,XX +XXX,XX @@
69
@@ -XXX,XX +XXX,XX @@
254
@rdn_dbm ........ .. .... dbm:13 rd:5 \
70
#include "hw/boards.h"
255
&rr_dbm rn=%reg_movprfx
71
#include "hw/i2c/i2c.h"
256
72
#include "hw/devices.h"
257
+# Predicate output, vector and immediate input,
73
+#include "hw/display/blizzard.h"
258
+# controlling predicate, element size.
74
#include "hw/misc/tmp105.h"
259
+@pd_pg_rn_i7 ........ esz:2 . imm:7 . pg:3 rn:5 . rd:4 &rpri_esz
75
#include "hw/block/flash.h"
260
+@pd_pg_rn_i5 ........ esz:2 . imm:s5 ... pg:3 rn:5 . rd:4 &rpri_esz
76
#include "hw/hw.h"
261
+
77
diff --git a/hw/display/blizzard.c b/hw/display/blizzard.c
262
# Basic Load/Store with 9-bit immediate offset
78
index XXXXXXX..XXXXXXX 100644
263
@pd_rn_i9 ........ ........ ...... rn:5 . rd:4 \
79
--- a/hw/display/blizzard.c
264
&rri imm=%imm9_16_10
80
+++ b/hw/display/blizzard.c
265
@@ -XXX,XX +XXX,XX @@ CMPHI_ppzw 00100100 .. 0 ..... 110 ... ..... 1 .... @pd_pg_rn_rm
81
@@ -XXX,XX +XXX,XX @@
266
CMPLO_ppzw 00100100 .. 0 ..... 111 ... ..... 0 .... @pd_pg_rn_rm
82
#include "qemu/osdep.h"
267
CMPLS_ppzw 00100100 .. 0 ..... 111 ... ..... 1 .... @pd_pg_rn_rm
83
#include "qemu-common.h"
268
84
#include "ui/console.h"
269
+### SVE Integer Compare - Unsigned Immediate Group
85
-#include "hw/devices.h"
270
+
86
+#include "hw/display/blizzard.h"
271
+# SVE integer compare with unsigned immediate
87
#include "ui/pixel_ops.h"
272
+CMPHS_ppzi 00100100 .. 1 ....... 0 ... ..... 0 .... @pd_pg_rn_i7
88
273
+CMPHI_ppzi 00100100 .. 1 ....... 0 ... ..... 1 .... @pd_pg_rn_i7
89
typedef void (*blizzard_fn_t)(uint8_t *, const uint8_t *, unsigned int);
274
+CMPLO_ppzi 00100100 .. 1 ....... 1 ... ..... 0 .... @pd_pg_rn_i7
90
diff --git a/MAINTAINERS b/MAINTAINERS
275
+CMPLS_ppzi 00100100 .. 1 ....... 1 ... ..... 1 .... @pd_pg_rn_i7
91
index XXXXXXX..XXXXXXX 100644
276
+
92
--- a/MAINTAINERS
277
+### SVE Integer Compare - Signed Immediate Group
93
+++ b/MAINTAINERS
278
+
94
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
279
+# SVE integer compare with signed immediate
95
L: qemu-arm@nongnu.org
280
+CMPGE_ppzi 00100101 .. 0 ..... 000 ... ..... 0 .... @pd_pg_rn_i5
96
S: Odd Fixes
281
+CMPGT_ppzi 00100101 .. 0 ..... 000 ... ..... 1 .... @pd_pg_rn_i5
97
F: hw/arm/nseries.c
282
+CMPLT_ppzi 00100101 .. 0 ..... 001 ... ..... 0 .... @pd_pg_rn_i5
98
+F: hw/display/blizzard.c
283
+CMPLE_ppzi 00100101 .. 0 ..... 001 ... ..... 1 .... @pd_pg_rn_i5
99
F: hw/input/lm832x.c
284
+CMPEQ_ppzi 00100101 .. 0 ..... 100 ... ..... 0 .... @pd_pg_rn_i5
100
F: hw/input/tsc2005.c
285
+CMPNE_ppzi 00100101 .. 0 ..... 100 ... ..... 1 .... @pd_pg_rn_i5
101
F: hw/misc/cbus.c
286
+
102
F: hw/timer/twl92230.c
287
### SVE Predicate Logical Operations Group
103
+F: include/hw/display/blizzard.h
288
104
289
# SVE predicate logical operations
105
Palm
106
M: Andrzej Zaborowski <balrogg@gmail.com>
290
--
107
--
291
2.17.1
108
2.20.1
292
109
293
110
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
Message-id: 20180613015641.5667-6-richard.henderson@linaro.org
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190412165416.7977-7-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
---
8
target/arm/helper-sve.h | 3 +++
9
include/hw/devices.h | 14 --------------
9
target/arm/sve_helper.c | 34 ++++++++++++++++++++++++++++++++++
10
include/hw/misc/cbus.h | 32 ++++++++++++++++++++++++++++++++
10
target/arm/translate-sve.c | 12 ++++++++++++
11
hw/arm/nseries.c | 1 +
11
target/arm/sve.decode | 6 ++++++
12
hw/misc/cbus.c | 2 +-
12
4 files changed, 55 insertions(+)
13
MAINTAINERS | 1 +
14
5 files changed, 35 insertions(+), 15 deletions(-)
15
create mode 100644 include/hw/misc/cbus.h
13
16
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
19
--- a/include/hw/devices.h
17
+++ b/target/arm/helper-sve.h
20
+++ b/include/hw/devices.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_trn_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
21
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
19
DEF_HELPER_FLAGS_4(sve_trn_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
22
/* stellaris_input.c */
20
DEF_HELPER_FLAGS_4(sve_trn_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
23
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
21
24
22
+DEF_HELPER_FLAGS_4(sve_compact_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
-/* cbus.c */
23
+DEF_HELPER_FLAGS_4(sve_compact_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
-typedef struct {
24
+
27
- qemu_irq clk;
25
DEF_HELPER_FLAGS_5(sve_and_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
28
- qemu_irq dat;
26
DEF_HELPER_FLAGS_5(sve_bic_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
29
- qemu_irq sel;
27
DEF_HELPER_FLAGS_5(sve_eor_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
30
-} CBus;
28
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
31
-CBus *cbus_init(qemu_irq dat_out);
29
index XXXXXXX..XXXXXXX 100644
32
-void cbus_attach(CBus *bus, void *slave_opaque);
30
--- a/target/arm/sve_helper.c
33
-
31
+++ b/target/arm/sve_helper.c
34
-void *retu_init(qemu_irq irq, int vilma);
32
@@ -XXX,XX +XXX,XX @@ DO_TRN(sve_trn_d, uint64_t, )
35
-void *tahvo_init(qemu_irq irq, int betty);
33
#undef DO_ZIP
36
-
34
#undef DO_UZP
37
-void retu_key_event(void *retu, int state);
35
#undef DO_TRN
38
-
36
+
39
#endif
37
+void HELPER(sve_compact_s)(void *vd, void *vn, void *vg, uint32_t desc)
40
diff --git a/include/hw/misc/cbus.h b/include/hw/misc/cbus.h
38
+{
41
new file mode 100644
39
+ intptr_t i, j, opr_sz = simd_oprsz(desc) / 4;
42
index XXXXXXX..XXXXXXX
40
+ uint32_t *d = vd, *n = vn;
43
--- /dev/null
41
+ uint8_t *pg = vg;
44
+++ b/include/hw/misc/cbus.h
42
+
45
@@ -XXX,XX +XXX,XX @@
43
+ for (i = j = 0; i < opr_sz; i++) {
44
+ if (pg[H1(i / 2)] & (i & 1 ? 0x10 : 0x01)) {
45
+ d[H4(j)] = n[H4(i)];
46
+ j++;
47
+ }
48
+ }
49
+ for (; j < opr_sz; j++) {
50
+ d[H4(j)] = 0;
51
+ }
52
+}
53
+
54
+void HELPER(sve_compact_d)(void *vd, void *vn, void *vg, uint32_t desc)
55
+{
56
+ intptr_t i, j, opr_sz = simd_oprsz(desc) / 8;
57
+ uint64_t *d = vd, *n = vn;
58
+ uint8_t *pg = vg;
59
+
60
+ for (i = j = 0; i < opr_sz; i++) {
61
+ if (pg[H1(i)] & 1) {
62
+ d[j] = n[i];
63
+ j++;
64
+ }
65
+ }
66
+ for (; j < opr_sz; j++) {
67
+ d[j] = 0;
68
+ }
69
+}
70
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/arm/translate-sve.c
73
+++ b/target/arm/translate-sve.c
74
@@ -XXX,XX +XXX,XX @@ static bool trans_TRN2_z(DisasContext *s, arg_rrr_esz *a, uint32_t insn)
75
return do_zzz_data_ool(s, a, 1 << a->esz, trn_fns[a->esz]);
76
}
77
78
+/*
46
+/*
79
+ *** SVE Permute Vector - Predicated Group
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.
80
+ */
56
+ */
81
+
57
+
82
+static bool trans_COMPACT(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
58
+#ifndef HW_MISC_CBUS_H
83
+{
59
+#define HW_MISC_CBUS_H
84
+ static gen_helper_gvec_3 * const fns[4] = {
85
+ NULL, NULL, gen_helper_sve_compact_s, gen_helper_sve_compact_d
86
+ };
87
+ return do_zpz_ool(s, a, fns[a->esz]);
88
+}
89
+
60
+
90
/*
61
+#include "hw/irq.h"
91
*** SVE Memory - 32-bit Gather and Unsized Contiguous Group
62
+
92
*/
63
+typedef struct {
93
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
64
+ qemu_irq clk;
65
+ qemu_irq dat;
66
+ qemu_irq sel;
67
+} CBus;
68
+
69
+CBus *cbus_init(qemu_irq dat_out);
70
+void cbus_attach(CBus *bus, void *slave_opaque);
71
+
72
+void *retu_init(qemu_irq irq, int vilma);
73
+void *tahvo_init(qemu_irq irq, int betty);
74
+
75
+void retu_key_event(void *retu, int state);
76
+
77
+#endif
78
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
94
index XXXXXXX..XXXXXXX 100644
79
index XXXXXXX..XXXXXXX 100644
95
--- a/target/arm/sve.decode
80
--- a/hw/arm/nseries.c
96
+++ b/target/arm/sve.decode
81
+++ b/hw/arm/nseries.c
97
@@ -XXX,XX +XXX,XX @@ UZP2_z 00000101 .. 1 ..... 011 011 ..... ..... @rd_rn_rm
82
@@ -XXX,XX +XXX,XX @@
98
TRN1_z 00000101 .. 1 ..... 011 100 ..... ..... @rd_rn_rm
83
#include "hw/i2c/i2c.h"
99
TRN2_z 00000101 .. 1 ..... 011 101 ..... ..... @rd_rn_rm
84
#include "hw/devices.h"
100
85
#include "hw/display/blizzard.h"
101
+### SVE Permute - Predicated Group
86
+#include "hw/misc/cbus.h"
102
+
87
#include "hw/misc/tmp105.h"
103
+# SVE compress active elements
88
#include "hw/block/flash.h"
104
+# Note esz >= 2
89
#include "hw/hw.h"
105
+COMPACT 00000101 .. 100001 100 ... ..... ..... @rd_pg_rn
90
diff --git a/hw/misc/cbus.c b/hw/misc/cbus.c
106
+
91
index XXXXXXX..XXXXXXX 100644
107
### SVE Predicate Logical Operations Group
92
--- a/hw/misc/cbus.c
108
93
+++ b/hw/misc/cbus.c
109
# SVE predicate logical operations
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>
110
--
115
--
111
2.17.1
116
2.20.1
112
117
113
118
diff view generated by jsdifflib
1
The stellaris board is still using the legacy armv7m_init() function,
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
which predates conversion of the ARMv7M into a proper QOM container
3
object. Make the board code directly create the ARMv7M object instead.
4
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20190412165416.7977-8-philmd@redhat.com
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: Stefan Hajnoczi <stefanha@redhat.com>
8
Message-id: 20180601144328.23817-2-peter.maydell@linaro.org
9
---
7
---
10
hw/arm/stellaris.c | 12 ++++++++++--
8
include/hw/devices.h | 3 ---
11
1 file changed, 10 insertions(+), 2 deletions(-)
9
include/hw/input/gamepad.h | 19 +++++++++++++++++++
10
hw/arm/stellaris.c | 2 +-
11
hw/input/stellaris_input.c | 2 +-
12
MAINTAINERS | 1 +
13
5 files changed, 22 insertions(+), 5 deletions(-)
14
create mode 100644 include/hw/input/gamepad.h
12
15
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/devices.h
19
+++ b/include/hw/devices.h
20
@@ -XXX,XX +XXX,XX @@ void *tsc2005_init(qemu_irq pintdav);
21
uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
22
void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
23
24
-/* stellaris_input.c */
25
-void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
26
-
27
#endif
28
diff --git a/include/hw/input/gamepad.h b/include/hw/input/gamepad.h
29
new file mode 100644
30
index XXXXXXX..XXXXXXX
31
--- /dev/null
32
+++ b/include/hw/input/gamepad.h
33
@@ -XXX,XX +XXX,XX @@
34
+/*
35
+ * Gamepad style buttons connected to IRQ/GPIO lines
36
+ *
37
+ * Copyright (c) 2007 CodeSourcery.
38
+ * Written by Paul Brook
39
+ *
40
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
41
+ * See the COPYING file in the top-level directory.
42
+ */
43
+
44
+#ifndef HW_INPUT_GAMEPAD_H
45
+#define HW_INPUT_GAMEPAD_H
46
+
47
+#include "hw/irq.h"
48
+
49
+/* stellaris_input.c */
50
+void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
51
+
52
+#endif
13
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
53
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
14
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/stellaris.c
55
--- a/hw/arm/stellaris.c
16
+++ b/hw/arm/stellaris.c
56
+++ b/hw/arm/stellaris.c
17
@@ -XXX,XX +XXX,XX @@
57
@@ -XXX,XX +XXX,XX @@
18
#include "qemu/log.h"
58
#include "hw/sysbus.h"
19
#include "exec/address-spaces.h"
59
#include "hw/ssi/ssi.h"
60
#include "hw/arm/arm.h"
61
-#include "hw/devices.h"
62
#include "qemu/timer.h"
63
#include "hw/i2c/i2c.h"
64
#include "net/net.h"
65
@@ -XXX,XX +XXX,XX @@
20
#include "sysemu/sysemu.h"
66
#include "sysemu/sysemu.h"
21
+#include "hw/arm/armv7m.h"
67
#include "hw/arm/armv7m.h"
22
#include "hw/char/pl011.h"
68
#include "hw/char/pl011.h"
69
+#include "hw/input/gamepad.h"
70
#include "hw/watchdog/cmsdk-apb-watchdog.h"
23
#include "hw/misc/unimp.h"
71
#include "hw/misc/unimp.h"
24
#include "cpu.h"
72
#include "cpu.h"
25
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
73
diff --git a/hw/input/stellaris_input.c b/hw/input/stellaris_input.c
26
&error_fatal);
74
index XXXXXXX..XXXXXXX 100644
27
memory_region_add_subregion(system_memory, 0x20000000, sram);
75
--- a/hw/input/stellaris_input.c
28
76
+++ b/hw/input/stellaris_input.c
29
- nvic = armv7m_init(system_memory, flash_size, NUM_IRQ_LINES,
77
@@ -XXX,XX +XXX,XX @@
30
- ms->kernel_filename, ms->cpu_type);
78
*/
31
+ nvic = qdev_create(NULL, TYPE_ARMV7M);
79
#include "qemu/osdep.h"
32
+ qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES);
80
#include "hw/hw.h"
33
+ qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type);
81
-#include "hw/devices.h"
34
+ object_property_set_link(OBJECT(nvic), OBJECT(get_system_memory()),
82
+#include "hw/input/gamepad.h"
35
+ "memory", &error_abort);
83
#include "ui/console.h"
36
+ /* This will exit with an error if the user passed us a bad cpu_type */
84
37
+ qdev_init_nofail(nvic);
85
typedef struct {
38
86
diff --git a/MAINTAINERS b/MAINTAINERS
39
qdev_connect_gpio_out_named(nvic, "SYSRESETREQ", 0,
87
index XXXXXXX..XXXXXXX 100644
40
qemu_allocate_irq(&do_sys_reset, NULL, 0));
88
--- a/MAINTAINERS
41
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
89
+++ b/MAINTAINERS
42
create_unimplemented_device("analogue-comparator", 0x4003c000, 0x1000);
90
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
43
create_unimplemented_device("hibernation", 0x400fc000, 0x1000);
91
L: qemu-arm@nongnu.org
44
create_unimplemented_device("flash-control", 0x400fd000, 0x1000);
92
S: Maintained
45
+
93
F: hw/*/stellaris*
46
+ armv7m_load_kernel(ARM_CPU(first_cpu), ms->kernel_filename, flash_size);
94
+F: include/hw/input/gamepad.h
47
}
95
48
96
Versatile Express
49
/* FIXME: Figure out how to generate these from stellaris_boards. */
97
M: Peter Maydell <peter.maydell@linaro.org>
50
--
98
--
51
2.17.1
99
2.20.1
52
100
53
101
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Since uWireSlave is only used in this new header, there is no
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
need to expose it via "qemu/typedefs.h".
5
Message-id: 20180613015641.5667-5-richard.henderson@linaro.org
5
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190412165416.7977-9-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
target/arm/helper-sve.h | 15 ++++++++
11
include/hw/arm/omap.h | 6 +-----
9
target/arm/sve_helper.c | 72 ++++++++++++++++++++++++++++++++++++
12
include/hw/devices.h | 15 ---------------
10
target/arm/translate-sve.c | 75 ++++++++++++++++++++++++++++++++++++++
13
include/hw/input/tsc2xxx.h | 36 ++++++++++++++++++++++++++++++++++++
11
target/arm/sve.decode | 10 +++++
14
include/qemu/typedefs.h | 1 -
12
4 files changed, 172 insertions(+)
15
hw/arm/nseries.c | 2 +-
13
16
hw/arm/palm.c | 2 +-
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
17
hw/input/tsc2005.c | 2 +-
15
index XXXXXXX..XXXXXXX 100644
18
hw/input/tsc210x.c | 4 ++--
16
--- a/target/arm/helper-sve.h
19
MAINTAINERS | 2 ++
17
+++ b/target/arm/helper-sve.h
20
9 files changed, 44 insertions(+), 26 deletions(-)
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_trn_p, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
21
create mode 100644 include/hw/input/tsc2xxx.h
19
DEF_HELPER_FLAGS_3(sve_rev_p, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
22
20
DEF_HELPER_FLAGS_3(sve_punpk_p, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
23
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
21
24
index XXXXXXX..XXXXXXX 100644
22
+DEF_HELPER_FLAGS_4(sve_zip_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
--- a/include/hw/arm/omap.h
23
+DEF_HELPER_FLAGS_4(sve_zip_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
+++ b/include/hw/arm/omap.h
24
+DEF_HELPER_FLAGS_4(sve_zip_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
27
@@ -XXX,XX +XXX,XX @@
25
+DEF_HELPER_FLAGS_4(sve_zip_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
28
#include "exec/memory.h"
26
+
29
# define hw_omap_h        "omap.h"
27
+DEF_HELPER_FLAGS_4(sve_uzp_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
30
#include "hw/irq.h"
28
+DEF_HELPER_FLAGS_4(sve_uzp_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
31
+#include "hw/input/tsc2xxx.h"
29
+DEF_HELPER_FLAGS_4(sve_uzp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
32
#include "target/arm/cpu-qom.h"
30
+DEF_HELPER_FLAGS_4(sve_uzp_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
#include "qemu/log.h"
31
+
34
32
+DEF_HELPER_FLAGS_4(sve_trn_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
35
@@ -XXX,XX +XXX,XX @@ qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s);
33
+DEF_HELPER_FLAGS_4(sve_trn_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
36
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler);
34
+DEF_HELPER_FLAGS_4(sve_trn_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
37
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down);
35
+DEF_HELPER_FLAGS_4(sve_trn_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
38
36
+
39
-struct uWireSlave {
37
DEF_HELPER_FLAGS_5(sve_and_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
40
- uint16_t (*receive)(void *opaque);
38
DEF_HELPER_FLAGS_5(sve_bic_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
41
- void (*send)(void *opaque, uint16_t data);
39
DEF_HELPER_FLAGS_5(sve_eor_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
42
- void *opaque;
40
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
43
-};
41
index XXXXXXX..XXXXXXX 100644
44
struct omap_uwire_s;
42
--- a/target/arm/sve_helper.c
45
void omap_uwire_attach(struct omap_uwire_s *s,
43
+++ b/target/arm/sve_helper.c
46
uWireSlave *slave, int chipselect);
44
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_punpk_p)(void *vd, void *vn, uint32_t pred_desc)
47
diff --git a/include/hw/devices.h b/include/hw/devices.h
45
}
48
index XXXXXXX..XXXXXXX 100644
46
}
49
--- a/include/hw/devices.h
47
}
50
+++ b/include/hw/devices.h
48
+
51
@@ -XXX,XX +XXX,XX @@
49
+#define DO_ZIP(NAME, TYPE, H) \
52
/* Devices that have nowhere better to go. */
50
+void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
53
51
+{ \
54
#include "hw/hw.h"
52
+ intptr_t oprsz = simd_oprsz(desc); \
55
-#include "ui/console.h"
53
+ intptr_t i, oprsz_2 = oprsz / 2; \
56
54
+ ARMVectorReg tmp_n, tmp_m; \
57
/* smc91c111.c */
55
+ /* We produce output faster than we consume input. \
58
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
56
+ Therefore we must be mindful of possible overlap. */ \
59
@@ -XXX,XX +XXX,XX @@ void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
57
+ if (unlikely((vn - vd) < (uintptr_t)oprsz)) { \
60
/* lan9118.c */
58
+ vn = memcpy(&tmp_n, vn, oprsz_2); \
61
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
59
+ } \
62
60
+ if (unlikely((vm - vd) < (uintptr_t)oprsz)) { \
63
-/* tsc210x.c */
61
+ vm = memcpy(&tmp_m, vm, oprsz_2); \
64
-uWireSlave *tsc2102_init(qemu_irq pint);
62
+ } \
65
-uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
63
+ for (i = 0; i < oprsz_2; i += sizeof(TYPE)) { \
66
-I2SCodec *tsc210x_codec(uWireSlave *chip);
64
+ *(TYPE *)(vd + H(2 * i + 0)) = *(TYPE *)(vn + H(i)); \
67
-uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
65
+ *(TYPE *)(vd + H(2 * i + sizeof(TYPE))) = *(TYPE *)(vm + H(i)); \
68
-void tsc210x_set_transform(uWireSlave *chip,
66
+ } \
69
- MouseTransformInfo *info);
67
+}
70
-void tsc210x_key_event(uWireSlave *chip, int key, int down);
68
+
71
-
69
+DO_ZIP(sve_zip_b, uint8_t, H1)
72
-/* tsc2005.c */
70
+DO_ZIP(sve_zip_h, uint16_t, H1_2)
73
-void *tsc2005_init(qemu_irq pintdav);
71
+DO_ZIP(sve_zip_s, uint32_t, H1_4)
74
-uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
72
+DO_ZIP(sve_zip_d, uint64_t, )
75
-void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
73
+
76
-
74
+#define DO_UZP(NAME, TYPE, H) \
77
#endif
75
+void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
78
diff --git a/include/hw/input/tsc2xxx.h b/include/hw/input/tsc2xxx.h
76
+{ \
79
new file mode 100644
77
+ intptr_t oprsz = simd_oprsz(desc); \
80
index XXXXXXX..XXXXXXX
78
+ intptr_t oprsz_2 = oprsz / 2; \
81
--- /dev/null
79
+ intptr_t odd_ofs = simd_data(desc); \
82
+++ b/include/hw/input/tsc2xxx.h
80
+ intptr_t i; \
83
@@ -XXX,XX +XXX,XX @@
81
+ ARMVectorReg tmp_m; \
82
+ if (unlikely((vm - vd) < (uintptr_t)oprsz)) { \
83
+ vm = memcpy(&tmp_m, vm, oprsz); \
84
+ } \
85
+ for (i = 0; i < oprsz_2; i += sizeof(TYPE)) { \
86
+ *(TYPE *)(vd + H(i)) = *(TYPE *)(vn + H(2 * i + odd_ofs)); \
87
+ } \
88
+ for (i = 0; i < oprsz_2; i += sizeof(TYPE)) { \
89
+ *(TYPE *)(vd + H(oprsz_2 + i)) = *(TYPE *)(vm + H(2 * i + odd_ofs)); \
90
+ } \
91
+}
92
+
93
+DO_UZP(sve_uzp_b, uint8_t, H1)
94
+DO_UZP(sve_uzp_h, uint16_t, H1_2)
95
+DO_UZP(sve_uzp_s, uint32_t, H1_4)
96
+DO_UZP(sve_uzp_d, uint64_t, )
97
+
98
+#define DO_TRN(NAME, TYPE, H) \
99
+void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
100
+{ \
101
+ intptr_t oprsz = simd_oprsz(desc); \
102
+ intptr_t odd_ofs = simd_data(desc); \
103
+ intptr_t i; \
104
+ for (i = 0; i < oprsz; i += 2 * sizeof(TYPE)) { \
105
+ TYPE ae = *(TYPE *)(vn + H(i + odd_ofs)); \
106
+ TYPE be = *(TYPE *)(vm + H(i + odd_ofs)); \
107
+ *(TYPE *)(vd + H(i + 0)) = ae; \
108
+ *(TYPE *)(vd + H(i + sizeof(TYPE))) = be; \
109
+ } \
110
+}
111
+
112
+DO_TRN(sve_trn_b, uint8_t, H1)
113
+DO_TRN(sve_trn_h, uint16_t, H1_2)
114
+DO_TRN(sve_trn_s, uint32_t, H1_4)
115
+DO_TRN(sve_trn_d, uint64_t, )
116
+
117
+#undef DO_ZIP
118
+#undef DO_UZP
119
+#undef DO_TRN
120
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
121
index XXXXXXX..XXXXXXX 100644
122
--- a/target/arm/translate-sve.c
123
+++ b/target/arm/translate-sve.c
124
@@ -XXX,XX +XXX,XX @@ static bool trans_PUNPKHI(DisasContext *s, arg_PUNPKHI *a, uint32_t insn)
125
return do_perm_pred2(s, a, 1, gen_helper_sve_punpk_p);
126
}
127
128
+/*
84
+/*
129
+ *** SVE Permute - Interleaving Group
85
+ * TI touchscreen controller
86
+ *
87
+ * Copyright (c) 2006 Andrzej Zaborowski
88
+ * Copyright (C) 2008 Nokia Corporation
89
+ *
90
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
91
+ * See the COPYING file in the top-level directory.
130
+ */
92
+ */
131
+
93
+
132
+static bool do_zip(DisasContext *s, arg_rrr_esz *a, bool high)
94
+#ifndef HW_INPUT_TSC2XXX_H
133
+{
95
+#define HW_INPUT_TSC2XXX_H
134
+ static gen_helper_gvec_3 * const fns[4] = {
96
+
135
+ gen_helper_sve_zip_b, gen_helper_sve_zip_h,
97
+#include "hw/irq.h"
136
+ gen_helper_sve_zip_s, gen_helper_sve_zip_d,
98
+#include "ui/console.h"
137
+ };
99
+
138
+
100
+typedef struct uWireSlave {
139
+ if (sve_access_check(s)) {
101
+ uint16_t (*receive)(void *opaque);
140
+ unsigned vsz = vec_full_reg_size(s);
102
+ void (*send)(void *opaque, uint16_t data);
141
+ unsigned high_ofs = high ? vsz / 2 : 0;
103
+ void *opaque;
142
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
104
+} uWireSlave;
143
+ vec_full_reg_offset(s, a->rn) + high_ofs,
105
+
144
+ vec_full_reg_offset(s, a->rm) + high_ofs,
106
+/* tsc210x.c */
145
+ vsz, vsz, 0, fns[a->esz]);
107
+uWireSlave *tsc2102_init(qemu_irq pint);
146
+ }
108
+uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
147
+ return true;
109
+I2SCodec *tsc210x_codec(uWireSlave *chip);
148
+}
110
+uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
149
+
111
+void tsc210x_set_transform(uWireSlave *chip, MouseTransformInfo *info);
150
+static bool do_zzz_data_ool(DisasContext *s, arg_rrr_esz *a, int data,
112
+void tsc210x_key_event(uWireSlave *chip, int key, int down);
151
+ gen_helper_gvec_3 *fn)
113
+
152
+{
114
+/* tsc2005.c */
153
+ if (sve_access_check(s)) {
115
+void *tsc2005_init(qemu_irq pintdav);
154
+ unsigned vsz = vec_full_reg_size(s);
116
+uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
155
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
117
+void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
156
+ vec_full_reg_offset(s, a->rn),
118
+
157
+ vec_full_reg_offset(s, a->rm),
119
+#endif
158
+ vsz, vsz, data, fn);
120
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
159
+ }
121
index XXXXXXX..XXXXXXX 100644
160
+ return true;
122
--- a/include/qemu/typedefs.h
161
+}
123
+++ b/include/qemu/typedefs.h
162
+
124
@@ -XXX,XX +XXX,XX @@ typedef struct RAMBlock RAMBlock;
163
+static bool trans_ZIP1_z(DisasContext *s, arg_rrr_esz *a, uint32_t insn)
125
typedef struct Range Range;
164
+{
126
typedef struct SHPCDevice SHPCDevice;
165
+ return do_zip(s, a, false);
127
typedef struct SSIBus SSIBus;
166
+}
128
-typedef struct uWireSlave uWireSlave;
167
+
129
typedef struct VirtIODevice VirtIODevice;
168
+static bool trans_ZIP2_z(DisasContext *s, arg_rrr_esz *a, uint32_t insn)
130
typedef struct Visitor Visitor;
169
+{
131
typedef void SaveStateHandler(QEMUFile *f, void *opaque);
170
+ return do_zip(s, a, true);
132
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
171
+}
133
index XXXXXXX..XXXXXXX 100644
172
+
134
--- a/hw/arm/nseries.c
173
+static gen_helper_gvec_3 * const uzp_fns[4] = {
135
+++ b/hw/arm/nseries.c
174
+ gen_helper_sve_uzp_b, gen_helper_sve_uzp_h,
136
@@ -XXX,XX +XXX,XX @@
175
+ gen_helper_sve_uzp_s, gen_helper_sve_uzp_d,
137
#include "ui/console.h"
176
+};
138
#include "hw/boards.h"
177
+
139
#include "hw/i2c/i2c.h"
178
+static bool trans_UZP1_z(DisasContext *s, arg_rrr_esz *a, uint32_t insn)
140
-#include "hw/devices.h"
179
+{
141
#include "hw/display/blizzard.h"
180
+ return do_zzz_data_ool(s, a, 0, uzp_fns[a->esz]);
142
+#include "hw/input/tsc2xxx.h"
181
+}
143
#include "hw/misc/cbus.h"
182
+
144
#include "hw/misc/tmp105.h"
183
+static bool trans_UZP2_z(DisasContext *s, arg_rrr_esz *a, uint32_t insn)
145
#include "hw/block/flash.h"
184
+{
146
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
185
+ return do_zzz_data_ool(s, a, 1 << a->esz, uzp_fns[a->esz]);
147
index XXXXXXX..XXXXXXX 100644
186
+}
148
--- a/hw/arm/palm.c
187
+
149
+++ b/hw/arm/palm.c
188
+static gen_helper_gvec_3 * const trn_fns[4] = {
150
@@ -XXX,XX +XXX,XX @@
189
+ gen_helper_sve_trn_b, gen_helper_sve_trn_h,
151
#include "hw/arm/omap.h"
190
+ gen_helper_sve_trn_s, gen_helper_sve_trn_d,
152
#include "hw/boards.h"
191
+};
153
#include "hw/arm/arm.h"
192
+
154
-#include "hw/devices.h"
193
+static bool trans_TRN1_z(DisasContext *s, arg_rrr_esz *a, uint32_t insn)
155
+#include "hw/input/tsc2xxx.h"
194
+{
156
#include "hw/loader.h"
195
+ return do_zzz_data_ool(s, a, 0, trn_fns[a->esz]);
157
#include "exec/address-spaces.h"
196
+}
158
#include "cpu.h"
197
+
159
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
198
+static bool trans_TRN2_z(DisasContext *s, arg_rrr_esz *a, uint32_t insn)
160
index XXXXXXX..XXXXXXX 100644
199
+{
161
--- a/hw/input/tsc2005.c
200
+ return do_zzz_data_ool(s, a, 1 << a->esz, trn_fns[a->esz]);
162
+++ b/hw/input/tsc2005.c
201
+}
163
@@ -XXX,XX +XXX,XX @@
202
+
164
#include "hw/hw.h"
203
/*
165
#include "qemu/timer.h"
204
*** SVE Memory - 32-bit Gather and Unsized Contiguous Group
166
#include "ui/console.h"
205
*/
167
-#include "hw/devices.h"
206
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
168
+#include "hw/input/tsc2xxx.h"
207
index XXXXXXX..XXXXXXX 100644
169
#include "trace.h"
208
--- a/target/arm/sve.decode
170
209
+++ b/target/arm/sve.decode
171
#define TSC_CUT_RESOLUTION(value, p)    ((value) >> (16 - (p ? 12 : 10)))
210
@@ -XXX,XX +XXX,XX @@ REV_p 00000101 .. 11 0100 010 000 0 .... 0 .... @pd_pn
172
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
211
PUNPKLO 00000101 00 11 0000 010 000 0 .... 0 .... @pd_pn_e0
173
index XXXXXXX..XXXXXXX 100644
212
PUNPKHI 00000101 00 11 0001 010 000 0 .... 0 .... @pd_pn_e0
174
--- a/hw/input/tsc210x.c
213
175
+++ b/hw/input/tsc210x.c
214
+### SVE Permute - Interleaving Group
176
@@ -XXX,XX +XXX,XX @@
215
+
177
#include "audio/audio.h"
216
+# SVE permute vector elements
178
#include "qemu/timer.h"
217
+ZIP1_z 00000101 .. 1 ..... 011 000 ..... ..... @rd_rn_rm
179
#include "ui/console.h"
218
+ZIP2_z 00000101 .. 1 ..... 011 001 ..... ..... @rd_rn_rm
180
-#include "hw/arm/omap.h"    /* For I2SCodec and uWireSlave */
219
+UZP1_z 00000101 .. 1 ..... 011 010 ..... ..... @rd_rn_rm
181
-#include "hw/devices.h"
220
+UZP2_z 00000101 .. 1 ..... 011 011 ..... ..... @rd_rn_rm
182
+#include "hw/arm/omap.h" /* For I2SCodec */
221
+TRN1_z 00000101 .. 1 ..... 011 100 ..... ..... @rd_rn_rm
183
+#include "hw/input/tsc2xxx.h"
222
+TRN2_z 00000101 .. 1 ..... 011 101 ..... ..... @rd_rn_rm
184
223
+
185
#define TSC_DATA_REGISTERS_PAGE        0x0
224
### SVE Predicate Logical Operations Group
186
#define TSC_CONTROL_REGISTERS_PAGE    0x1
225
187
diff --git a/MAINTAINERS b/MAINTAINERS
226
# SVE predicate logical operations
188
index XXXXXXX..XXXXXXX 100644
189
--- a/MAINTAINERS
190
+++ b/MAINTAINERS
191
@@ -XXX,XX +XXX,XX @@ F: hw/input/tsc2005.c
192
F: hw/misc/cbus.c
193
F: hw/timer/twl92230.c
194
F: include/hw/display/blizzard.h
195
+F: include/hw/input/tsc2xxx.h
196
F: include/hw/misc/cbus.h
197
198
Palm
199
@@ -XXX,XX +XXX,XX @@ L: qemu-arm@nongnu.org
200
S: Odd Fixes
201
F: hw/arm/palm.c
202
F: hw/input/tsc210x.c
203
+F: include/hw/input/tsc2xxx.h
204
205
Raspberry Pi
206
M: Peter Maydell <peter.maydell@linaro.org>
227
--
207
--
228
2.17.1
208
2.20.1
229
209
230
210
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20180613015641.5667-4-richard.henderson@linaro.org
5
Message-id: 20190412165416.7977-10-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
target/arm/helper-sve.h | 6 +
8
include/hw/devices.h | 3 ---
9
target/arm/sve_helper.c | 290 +++++++++++++++++++++++++++++++++++++
9
include/hw/net/lan9118.h | 19 +++++++++++++++++++
10
target/arm/translate-sve.c | 120 +++++++++++++++
10
hw/arm/kzm.c | 2 +-
11
target/arm/sve.decode | 18 +++
11
hw/arm/mps2.c | 2 +-
12
4 files changed, 434 insertions(+)
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
13
17
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
18
diff --git a/include/hw/devices.h b/include/hw/devices.h
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
20
--- a/include/hw/devices.h
17
+++ b/target/arm/helper-sve.h
21
+++ b/include/hw/devices.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sve_uunpk_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
22
@@ -XXX,XX +XXX,XX @@
19
DEF_HELPER_FLAGS_3(sve_uunpk_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
23
/* smc91c111.c */
20
DEF_HELPER_FLAGS_3(sve_uunpk_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
24
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
21
25
22
+DEF_HELPER_FLAGS_4(sve_zip_p, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
-/* lan9118.c */
23
+DEF_HELPER_FLAGS_4(sve_uzp_p, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
27
-void lan9118_init(NICInfo *, uint32_t, qemu_irq);
24
+DEF_HELPER_FLAGS_4(sve_trn_p, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
28
-
25
+DEF_HELPER_FLAGS_3(sve_rev_p, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
29
#endif
26
+DEF_HELPER_FLAGS_3(sve_punpk_p, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
30
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
27
+
31
new file mode 100644
28
DEF_HELPER_FLAGS_5(sve_and_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
32
index XXXXXXX..XXXXXXX
29
DEF_HELPER_FLAGS_5(sve_bic_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
33
--- /dev/null
30
DEF_HELPER_FLAGS_5(sve_eor_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
34
+++ b/include/hw/net/lan9118.h
31
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
35
@@ -XXX,XX +XXX,XX @@
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/sve_helper.c
34
+++ b/target/arm/sve_helper.c
35
@@ -XXX,XX +XXX,XX @@ DO_UNPK(sve_uunpk_s, uint32_t, uint16_t, H4, H2)
36
DO_UNPK(sve_uunpk_d, uint64_t, uint32_t, , H4)
37
38
#undef DO_UNPK
39
+
40
+/* Mask of bits included in the even numbered predicates of width esz.
41
+ * We also use this for expand_bits/compress_bits, and so extend the
42
+ * same pattern out to 16-bit units.
43
+ */
44
+static const uint64_t even_bit_esz_masks[5] = {
45
+ 0x5555555555555555ull,
46
+ 0x3333333333333333ull,
47
+ 0x0f0f0f0f0f0f0f0full,
48
+ 0x00ff00ff00ff00ffull,
49
+ 0x0000ffff0000ffffull,
50
+};
51
+
52
+/* Zero-extend units of 2**N bits to units of 2**(N+1) bits.
53
+ * For N==0, this corresponds to the operation that in qemu/bitops.h
54
+ * we call half_shuffle64; this algorithm is from Hacker's Delight,
55
+ * section 7-2 Shuffling Bits.
56
+ */
57
+static uint64_t expand_bits(uint64_t x, int n)
58
+{
59
+ int i;
60
+
61
+ x &= 0xffffffffu;
62
+ for (i = 4; i >= n; i--) {
63
+ int sh = 1 << i;
64
+ x = ((x << sh) | x) & even_bit_esz_masks[i];
65
+ }
66
+ return x;
67
+}
68
+
69
+/* Compress units of 2**(N+1) bits to units of 2**N bits.
70
+ * For N==0, this corresponds to the operation that in qemu/bitops.h
71
+ * we call half_unshuffle64; this algorithm is from Hacker's Delight,
72
+ * section 7-2 Shuffling Bits, where it is called an inverse half shuffle.
73
+ */
74
+static uint64_t compress_bits(uint64_t x, int n)
75
+{
76
+ int i;
77
+
78
+ for (i = n; i <= 4; i++) {
79
+ int sh = 1 << i;
80
+ x &= even_bit_esz_masks[i];
81
+ x = (x >> sh) | x;
82
+ }
83
+ return x & 0xffffffffu;
84
+}
85
+
86
+void HELPER(sve_zip_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
87
+{
88
+ intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
89
+ int esz = extract32(pred_desc, SIMD_DATA_SHIFT, 2);
90
+ intptr_t high = extract32(pred_desc, SIMD_DATA_SHIFT + 2, 1);
91
+ uint64_t *d = vd;
92
+ intptr_t i;
93
+
94
+ if (oprsz <= 8) {
95
+ uint64_t nn = *(uint64_t *)vn;
96
+ uint64_t mm = *(uint64_t *)vm;
97
+ int half = 4 * oprsz;
98
+
99
+ nn = extract64(nn, high * half, half);
100
+ mm = extract64(mm, high * half, half);
101
+ nn = expand_bits(nn, esz);
102
+ mm = expand_bits(mm, esz);
103
+ d[0] = nn + (mm << (1 << esz));
104
+ } else {
105
+ ARMPredicateReg tmp_n, tmp_m;
106
+
107
+ /* We produce output faster than we consume input.
108
+ Therefore we must be mindful of possible overlap. */
109
+ if ((vn - vd) < (uintptr_t)oprsz) {
110
+ vn = memcpy(&tmp_n, vn, oprsz);
111
+ }
112
+ if ((vm - vd) < (uintptr_t)oprsz) {
113
+ vm = memcpy(&tmp_m, vm, oprsz);
114
+ }
115
+ if (high) {
116
+ high = oprsz >> 1;
117
+ }
118
+
119
+ if ((high & 3) == 0) {
120
+ uint32_t *n = vn, *m = vm;
121
+ high >>= 2;
122
+
123
+ for (i = 0; i < DIV_ROUND_UP(oprsz, 8); i++) {
124
+ uint64_t nn = n[H4(high + i)];
125
+ uint64_t mm = m[H4(high + i)];
126
+
127
+ nn = expand_bits(nn, esz);
128
+ mm = expand_bits(mm, esz);
129
+ d[i] = nn + (mm << (1 << esz));
130
+ }
131
+ } else {
132
+ uint8_t *n = vn, *m = vm;
133
+ uint16_t *d16 = vd;
134
+
135
+ for (i = 0; i < oprsz / 2; i++) {
136
+ uint16_t nn = n[H1(high + i)];
137
+ uint16_t mm = m[H1(high + i)];
138
+
139
+ nn = expand_bits(nn, esz);
140
+ mm = expand_bits(mm, esz);
141
+ d16[H2(i)] = nn + (mm << (1 << esz));
142
+ }
143
+ }
144
+ }
145
+}
146
+
147
+void HELPER(sve_uzp_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
148
+{
149
+ intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
150
+ int esz = extract32(pred_desc, SIMD_DATA_SHIFT, 2);
151
+ int odd = extract32(pred_desc, SIMD_DATA_SHIFT + 2, 1) << esz;
152
+ uint64_t *d = vd, *n = vn, *m = vm;
153
+ uint64_t l, h;
154
+ intptr_t i;
155
+
156
+ if (oprsz <= 8) {
157
+ l = compress_bits(n[0] >> odd, esz);
158
+ h = compress_bits(m[0] >> odd, esz);
159
+ d[0] = extract64(l + (h << (4 * oprsz)), 0, 8 * oprsz);
160
+ } else {
161
+ ARMPredicateReg tmp_m;
162
+ intptr_t oprsz_16 = oprsz / 16;
163
+
164
+ if ((vm - vd) < (uintptr_t)oprsz) {
165
+ m = memcpy(&tmp_m, vm, oprsz);
166
+ }
167
+
168
+ for (i = 0; i < oprsz_16; i++) {
169
+ l = n[2 * i + 0];
170
+ h = n[2 * i + 1];
171
+ l = compress_bits(l >> odd, esz);
172
+ h = compress_bits(h >> odd, esz);
173
+ d[i] = l + (h << 32);
174
+ }
175
+
176
+ /* For VL which is not a power of 2, the results from M do not
177
+ align nicely with the uint64_t for D. Put the aligned results
178
+ from M into TMP_M and then copy it into place afterward. */
179
+ if (oprsz & 15) {
180
+ d[i] = compress_bits(n[2 * i] >> odd, esz);
181
+
182
+ for (i = 0; i < oprsz_16; i++) {
183
+ l = m[2 * i + 0];
184
+ h = m[2 * i + 1];
185
+ l = compress_bits(l >> odd, esz);
186
+ h = compress_bits(h >> odd, esz);
187
+ tmp_m.p[i] = l + (h << 32);
188
+ }
189
+ tmp_m.p[i] = compress_bits(m[2 * i] >> odd, esz);
190
+
191
+ swap_memmove(vd + oprsz / 2, &tmp_m, oprsz / 2);
192
+ } else {
193
+ for (i = 0; i < oprsz_16; i++) {
194
+ l = m[2 * i + 0];
195
+ h = m[2 * i + 1];
196
+ l = compress_bits(l >> odd, esz);
197
+ h = compress_bits(h >> odd, esz);
198
+ d[oprsz_16 + i] = l + (h << 32);
199
+ }
200
+ }
201
+ }
202
+}
203
+
204
+void HELPER(sve_trn_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
205
+{
206
+ intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
207
+ uintptr_t esz = extract32(pred_desc, SIMD_DATA_SHIFT, 2);
208
+ bool odd = extract32(pred_desc, SIMD_DATA_SHIFT + 2, 1);
209
+ uint64_t *d = vd, *n = vn, *m = vm;
210
+ uint64_t mask;
211
+ int shr, shl;
212
+ intptr_t i;
213
+
214
+ shl = 1 << esz;
215
+ shr = 0;
216
+ mask = even_bit_esz_masks[esz];
217
+ if (odd) {
218
+ mask <<= shl;
219
+ shr = shl;
220
+ shl = 0;
221
+ }
222
+
223
+ for (i = 0; i < DIV_ROUND_UP(oprsz, 8); i++) {
224
+ uint64_t nn = (n[i] & mask) >> shr;
225
+ uint64_t mm = (m[i] & mask) << shl;
226
+ d[i] = nn + mm;
227
+ }
228
+}
229
+
230
+/* Reverse units of 2**N bits. */
231
+static uint64_t reverse_bits_64(uint64_t x, int n)
232
+{
233
+ int i, sh;
234
+
235
+ x = bswap64(x);
236
+ for (i = 2, sh = 4; i >= n; i--, sh >>= 1) {
237
+ uint64_t mask = even_bit_esz_masks[i];
238
+ x = ((x & mask) << sh) | ((x >> sh) & mask);
239
+ }
240
+ return x;
241
+}
242
+
243
+static uint8_t reverse_bits_8(uint8_t x, int n)
244
+{
245
+ static const uint8_t mask[3] = { 0x55, 0x33, 0x0f };
246
+ int i, sh;
247
+
248
+ for (i = 2, sh = 4; i >= n; i--, sh >>= 1) {
249
+ x = ((x & mask[i]) << sh) | ((x >> sh) & mask[i]);
250
+ }
251
+ return x;
252
+}
253
+
254
+void HELPER(sve_rev_p)(void *vd, void *vn, uint32_t pred_desc)
255
+{
256
+ intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
257
+ int esz = extract32(pred_desc, SIMD_DATA_SHIFT, 2);
258
+ intptr_t i, oprsz_2 = oprsz / 2;
259
+
260
+ if (oprsz <= 8) {
261
+ uint64_t l = *(uint64_t *)vn;
262
+ l = reverse_bits_64(l << (64 - 8 * oprsz), esz);
263
+ *(uint64_t *)vd = l;
264
+ } else if ((oprsz & 15) == 0) {
265
+ for (i = 0; i < oprsz_2; i += 8) {
266
+ intptr_t ih = oprsz - 8 - i;
267
+ uint64_t l = reverse_bits_64(*(uint64_t *)(vn + i), esz);
268
+ uint64_t h = reverse_bits_64(*(uint64_t *)(vn + ih), esz);
269
+ *(uint64_t *)(vd + i) = h;
270
+ *(uint64_t *)(vd + ih) = l;
271
+ }
272
+ } else {
273
+ for (i = 0; i < oprsz_2; i += 1) {
274
+ intptr_t il = H1(i);
275
+ intptr_t ih = H1(oprsz - 1 - i);
276
+ uint8_t l = reverse_bits_8(*(uint8_t *)(vn + il), esz);
277
+ uint8_t h = reverse_bits_8(*(uint8_t *)(vn + ih), esz);
278
+ *(uint8_t *)(vd + il) = h;
279
+ *(uint8_t *)(vd + ih) = l;
280
+ }
281
+ }
282
+}
283
+
284
+void HELPER(sve_punpk_p)(void *vd, void *vn, uint32_t pred_desc)
285
+{
286
+ intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
287
+ intptr_t high = extract32(pred_desc, SIMD_DATA_SHIFT + 2, 1);
288
+ uint64_t *d = vd;
289
+ intptr_t i;
290
+
291
+ if (oprsz <= 8) {
292
+ uint64_t nn = *(uint64_t *)vn;
293
+ int half = 4 * oprsz;
294
+
295
+ nn = extract64(nn, high * half, half);
296
+ nn = expand_bits(nn, 0);
297
+ d[0] = nn;
298
+ } else {
299
+ ARMPredicateReg tmp_n;
300
+
301
+ /* We produce output faster than we consume input.
302
+ Therefore we must be mindful of possible overlap. */
303
+ if ((vn - vd) < (uintptr_t)oprsz) {
304
+ vn = memcpy(&tmp_n, vn, oprsz);
305
+ }
306
+ if (high) {
307
+ high = oprsz >> 1;
308
+ }
309
+
310
+ if ((high & 3) == 0) {
311
+ uint32_t *n = vn;
312
+ high >>= 2;
313
+
314
+ for (i = 0; i < DIV_ROUND_UP(oprsz, 8); i++) {
315
+ uint64_t nn = n[H4(high + i)];
316
+ d[i] = expand_bits(nn, 0);
317
+ }
318
+ } else {
319
+ uint16_t *d16 = vd;
320
+ uint8_t *n = vn;
321
+
322
+ for (i = 0; i < oprsz / 2; i++) {
323
+ uint16_t nn = n[H1(high + i)];
324
+ d16[H2(i)] = expand_bits(nn, 0);
325
+ }
326
+ }
327
+ }
328
+}
329
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
330
index XXXXXXX..XXXXXXX 100644
331
--- a/target/arm/translate-sve.c
332
+++ b/target/arm/translate-sve.c
333
@@ -XXX,XX +XXX,XX @@ static bool trans_UNPK(DisasContext *s, arg_UNPK *a, uint32_t insn)
334
return true;
335
}
336
337
+/*
36
+/*
338
+ *** SVE Permute - Predicates Group
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.
339
+ */
44
+ */
340
+
45
+
341
+static bool do_perm_pred3(DisasContext *s, arg_rrr_esz *a, bool high_odd,
46
+#ifndef HW_NET_LAN9118_H
342
+ gen_helper_gvec_3 *fn)
47
+#define HW_NET_LAN9118_H
343
+{
344
+ if (!sve_access_check(s)) {
345
+ return true;
346
+ }
347
+
48
+
348
+ unsigned vsz = pred_full_reg_size(s);
49
+#include "hw/irq.h"
50
+#include "net/net.h"
349
+
51
+
350
+ /* Predicate sizes may be smaller and cannot use simd_desc.
52
+void lan9118_init(NICInfo *, uint32_t, qemu_irq);
351
+ We cannot round up, as we do elsewhere, because we need
352
+ the exact size for ZIP2 and REV. We retain the style for
353
+ the other helpers for consistency. */
354
+ TCGv_ptr t_d = tcg_temp_new_ptr();
355
+ TCGv_ptr t_n = tcg_temp_new_ptr();
356
+ TCGv_ptr t_m = tcg_temp_new_ptr();
357
+ TCGv_i32 t_desc;
358
+ int desc;
359
+
53
+
360
+ desc = vsz - 2;
54
+#endif
361
+ desc = deposit32(desc, SIMD_DATA_SHIFT, 2, a->esz);
55
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
362
+ desc = deposit32(desc, SIMD_DATA_SHIFT + 2, 2, high_odd);
363
+
364
+ tcg_gen_addi_ptr(t_d, cpu_env, pred_full_reg_offset(s, a->rd));
365
+ tcg_gen_addi_ptr(t_n, cpu_env, pred_full_reg_offset(s, a->rn));
366
+ tcg_gen_addi_ptr(t_m, cpu_env, pred_full_reg_offset(s, a->rm));
367
+ t_desc = tcg_const_i32(desc);
368
+
369
+ fn(t_d, t_n, t_m, t_desc);
370
+
371
+ tcg_temp_free_ptr(t_d);
372
+ tcg_temp_free_ptr(t_n);
373
+ tcg_temp_free_ptr(t_m);
374
+ tcg_temp_free_i32(t_desc);
375
+ return true;
376
+}
377
+
378
+static bool do_perm_pred2(DisasContext *s, arg_rr_esz *a, bool high_odd,
379
+ gen_helper_gvec_2 *fn)
380
+{
381
+ if (!sve_access_check(s)) {
382
+ return true;
383
+ }
384
+
385
+ unsigned vsz = pred_full_reg_size(s);
386
+ TCGv_ptr t_d = tcg_temp_new_ptr();
387
+ TCGv_ptr t_n = tcg_temp_new_ptr();
388
+ TCGv_i32 t_desc;
389
+ int desc;
390
+
391
+ tcg_gen_addi_ptr(t_d, cpu_env, pred_full_reg_offset(s, a->rd));
392
+ tcg_gen_addi_ptr(t_n, cpu_env, pred_full_reg_offset(s, a->rn));
393
+
394
+ /* Predicate sizes may be smaller and cannot use simd_desc.
395
+ We cannot round up, as we do elsewhere, because we need
396
+ the exact size for ZIP2 and REV. We retain the style for
397
+ the other helpers for consistency. */
398
+
399
+ desc = vsz - 2;
400
+ desc = deposit32(desc, SIMD_DATA_SHIFT, 2, a->esz);
401
+ desc = deposit32(desc, SIMD_DATA_SHIFT + 2, 2, high_odd);
402
+ t_desc = tcg_const_i32(desc);
403
+
404
+ fn(t_d, t_n, t_desc);
405
+
406
+ tcg_temp_free_i32(t_desc);
407
+ tcg_temp_free_ptr(t_d);
408
+ tcg_temp_free_ptr(t_n);
409
+ return true;
410
+}
411
+
412
+static bool trans_ZIP1_p(DisasContext *s, arg_rrr_esz *a, uint32_t insn)
413
+{
414
+ return do_perm_pred3(s, a, 0, gen_helper_sve_zip_p);
415
+}
416
+
417
+static bool trans_ZIP2_p(DisasContext *s, arg_rrr_esz *a, uint32_t insn)
418
+{
419
+ return do_perm_pred3(s, a, 1, gen_helper_sve_zip_p);
420
+}
421
+
422
+static bool trans_UZP1_p(DisasContext *s, arg_rrr_esz *a, uint32_t insn)
423
+{
424
+ return do_perm_pred3(s, a, 0, gen_helper_sve_uzp_p);
425
+}
426
+
427
+static bool trans_UZP2_p(DisasContext *s, arg_rrr_esz *a, uint32_t insn)
428
+{
429
+ return do_perm_pred3(s, a, 1, gen_helper_sve_uzp_p);
430
+}
431
+
432
+static bool trans_TRN1_p(DisasContext *s, arg_rrr_esz *a, uint32_t insn)
433
+{
434
+ return do_perm_pred3(s, a, 0, gen_helper_sve_trn_p);
435
+}
436
+
437
+static bool trans_TRN2_p(DisasContext *s, arg_rrr_esz *a, uint32_t insn)
438
+{
439
+ return do_perm_pred3(s, a, 1, gen_helper_sve_trn_p);
440
+}
441
+
442
+static bool trans_REV_p(DisasContext *s, arg_rr_esz *a, uint32_t insn)
443
+{
444
+ return do_perm_pred2(s, a, 0, gen_helper_sve_rev_p);
445
+}
446
+
447
+static bool trans_PUNPKLO(DisasContext *s, arg_PUNPKLO *a, uint32_t insn)
448
+{
449
+ return do_perm_pred2(s, a, 0, gen_helper_sve_punpk_p);
450
+}
451
+
452
+static bool trans_PUNPKHI(DisasContext *s, arg_PUNPKHI *a, uint32_t insn)
453
+{
454
+ return do_perm_pred2(s, a, 1, gen_helper_sve_punpk_p);
455
+}
456
+
457
/*
458
*** SVE Memory - 32-bit Gather and Unsized Contiguous Group
459
*/
460
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
461
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
462
--- a/target/arm/sve.decode
57
--- a/hw/arm/kzm.c
463
+++ b/target/arm/sve.decode
58
+++ b/hw/arm/kzm.c
464
@@ -XXX,XX +XXX,XX @@
59
@@ -XXX,XX +XXX,XX @@
465
60
#include "qemu/error-report.h"
466
# Three operand, vector element size
61
#include "exec/address-spaces.h"
467
@rd_rn_rm ........ esz:2 . rm:5 ... ... rn:5 rd:5 &rrr_esz
62
#include "net/net.h"
468
+@pd_pn_pm ........ esz:2 .. rm:4 ....... rn:4 . rd:4 &rrr_esz
63
-#include "hw/devices.h"
469
@rdn_rm ........ esz:2 ...... ...... rm:5 rd:5 \
64
+#include "hw/net/lan9118.h"
470
&rrr_esz rn=%reg_movprfx
65
#include "hw/char/serial.h"
471
66
#include "sysemu/qtest.h"
472
@@ -XXX,XX +XXX,XX @@ TBL 00000101 .. 1 ..... 001100 ..... ..... @rd_rn_rm
67
473
# SVE unpack vector elements
68
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
474
UNPK 00000101 esz:2 1100 u:1 h:1 001110 rn:5 rd:5
69
index XXXXXXX..XXXXXXX 100644
475
70
--- a/hw/arm/mps2.c
476
+### SVE Permute - Predicates Group
71
+++ b/hw/arm/mps2.c
477
+
72
@@ -XXX,XX +XXX,XX @@
478
+# SVE permute predicate elements
73
#include "hw/timer/cmsdk-apb-timer.h"
479
+ZIP1_p 00000101 .. 10 .... 010 000 0 .... 0 .... @pd_pn_pm
74
#include "hw/timer/cmsdk-apb-dualtimer.h"
480
+ZIP2_p 00000101 .. 10 .... 010 001 0 .... 0 .... @pd_pn_pm
75
#include "hw/misc/mps2-scc.h"
481
+UZP1_p 00000101 .. 10 .... 010 010 0 .... 0 .... @pd_pn_pm
76
-#include "hw/devices.h"
482
+UZP2_p 00000101 .. 10 .... 010 011 0 .... 0 .... @pd_pn_pm
77
+#include "hw/net/lan9118.h"
483
+TRN1_p 00000101 .. 10 .... 010 100 0 .... 0 .... @pd_pn_pm
78
#include "net/net.h"
484
+TRN2_p 00000101 .. 10 .... 010 101 0 .... 0 .... @pd_pn_pm
79
485
+
80
typedef enum MPS2FPGAType {
486
+# SVE reverse predicate elements
81
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
487
+REV_p 00000101 .. 11 0100 010 000 0 .... 0 .... @pd_pn
82
index XXXXXXX..XXXXXXX 100644
488
+
83
--- a/hw/arm/realview.c
489
+# SVE unpack predicate elements
84
+++ b/hw/arm/realview.c
490
+PUNPKLO 00000101 00 11 0000 010 000 0 .... 0 .... @pd_pn_e0
85
@@ -XXX,XX +XXX,XX @@
491
+PUNPKHI 00000101 00 11 0001 010 000 0 .... 0 .... @pd_pn_e0
86
#include "hw/arm/arm.h"
492
+
87
#include "hw/arm/primecell.h"
493
### SVE Predicate Logical Operations Group
88
#include "hw/devices.h"
494
89
+#include "hw/net/lan9118.h"
495
# SVE predicate logical operations
90
#include "hw/pci/pci.h"
91
#include "net/net.h"
92
#include "sysemu/sysemu.h"
93
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/hw/arm/vexpress.c
96
+++ b/hw/arm/vexpress.c
97
@@ -XXX,XX +XXX,XX @@
98
#include "hw/sysbus.h"
99
#include "hw/arm/arm.h"
100
#include "hw/arm/primecell.h"
101
-#include "hw/devices.h"
102
+#include "hw/net/lan9118.h"
103
#include "hw/i2c/i2c.h"
104
#include "net/net.h"
105
#include "sysemu/sysemu.h"
106
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/hw/net/lan9118.c
109
+++ b/hw/net/lan9118.c
110
@@ -XXX,XX +XXX,XX @@
111
#include "hw/sysbus.h"
112
#include "net/net.h"
113
#include "net/eth.h"
114
-#include "hw/devices.h"
115
+#include "hw/net/lan9118.h"
116
#include "sysemu/sysemu.h"
117
#include "hw/ptimer.h"
118
#include "qemu/log.h"
496
--
119
--
497
2.17.1
120
2.20.1
498
121
499
122
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
Message-id: 20180613015641.5667-11-richard.henderson@linaro.org
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190412165416.7977-11-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
---
8
target/arm/helper-sve.h | 9 +++++++
9
include/hw/net/ne2000-isa.h | 6 ++++++
9
target/arm/sve_helper.c | 55 ++++++++++++++++++++++++++++++++++++++
10
1 file changed, 6 insertions(+)
10
target/arm/translate-sve.c | 2 ++
11
target/arm/sve.decode | 6 +++++
12
4 files changed, 72 insertions(+)
13
11
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
12
diff --git a/include/hw/net/ne2000-isa.h b/include/hw/net/ne2000-isa.h
15
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
14
--- a/include/hw/net/ne2000-isa.h
17
+++ b/target/arm/helper-sve.h
15
+++ b/include/hw/net/ne2000-isa.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_lsl_zpzz_s, TCG_CALL_NO_RWG,
16
@@ -XXX,XX +XXX,XX @@
19
DEF_HELPER_FLAGS_5(sve_lsl_zpzz_d, TCG_CALL_NO_RWG,
17
* This work is licensed under the terms of the GNU GPL, version 2 or later.
20
void, ptr, ptr, ptr, ptr, i32)
18
* See the COPYING file in the top-level directory.
21
19
*/
22
+DEF_HELPER_FLAGS_5(sve_sel_zpzz_b, TCG_CALL_NO_RWG,
23
+ void, ptr, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_5(sve_sel_zpzz_h, TCG_CALL_NO_RWG,
25
+ void, ptr, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_5(sve_sel_zpzz_s, TCG_CALL_NO_RWG,
27
+ void, ptr, ptr, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_5(sve_sel_zpzz_d, TCG_CALL_NO_RWG,
29
+ void, ptr, ptr, ptr, ptr, i32)
30
+
20
+
31
DEF_HELPER_FLAGS_5(sve_asr_zpzw_b, TCG_CALL_NO_RWG,
21
+#ifndef HW_NET_NE2K_ISA_H
32
void, ptr, ptr, ptr, ptr, i32)
22
+#define HW_NET_NE2K_ISA_H
33
DEF_HELPER_FLAGS_5(sve_asr_zpzw_h, TCG_CALL_NO_RWG,
23
+
34
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
24
#include "hw/hw.h"
35
index XXXXXXX..XXXXXXX 100644
25
#include "hw/qdev.h"
36
--- a/target/arm/sve_helper.c
26
#include "hw/isa/isa.h"
37
+++ b/target/arm/sve_helper.c
27
@@ -XXX,XX +XXX,XX @@ static inline ISADevice *isa_ne2000_init(ISABus *bus, int base, int irq,
38
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_splice)(void *vd, void *vn, void *vm, void *vg, uint32_t desc)
39
}
28
}
40
swap_memmove(vd + len, vm, opr_sz * 8 - len);
29
return d;
41
}
30
}
42
+
31
+
43
+void HELPER(sve_sel_zpzz_b)(void *vd, void *vn, void *vm,
32
+#endif
44
+ void *vg, uint32_t desc)
45
+{
46
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
47
+ uint64_t *d = vd, *n = vn, *m = vm;
48
+ uint8_t *pg = vg;
49
+
50
+ for (i = 0; i < opr_sz; i += 1) {
51
+ uint64_t nn = n[i], mm = m[i];
52
+ uint64_t pp = expand_pred_b(pg[H1(i)]);
53
+ d[i] = (nn & pp) | (mm & ~pp);
54
+ }
55
+}
56
+
57
+void HELPER(sve_sel_zpzz_h)(void *vd, void *vn, void *vm,
58
+ void *vg, uint32_t desc)
59
+{
60
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
61
+ uint64_t *d = vd, *n = vn, *m = vm;
62
+ uint8_t *pg = vg;
63
+
64
+ for (i = 0; i < opr_sz; i += 1) {
65
+ uint64_t nn = n[i], mm = m[i];
66
+ uint64_t pp = expand_pred_h(pg[H1(i)]);
67
+ d[i] = (nn & pp) | (mm & ~pp);
68
+ }
69
+}
70
+
71
+void HELPER(sve_sel_zpzz_s)(void *vd, void *vn, void *vm,
72
+ void *vg, uint32_t desc)
73
+{
74
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
75
+ uint64_t *d = vd, *n = vn, *m = vm;
76
+ uint8_t *pg = vg;
77
+
78
+ for (i = 0; i < opr_sz; i += 1) {
79
+ uint64_t nn = n[i], mm = m[i];
80
+ uint64_t pp = expand_pred_s(pg[H1(i)]);
81
+ d[i] = (nn & pp) | (mm & ~pp);
82
+ }
83
+}
84
+
85
+void HELPER(sve_sel_zpzz_d)(void *vd, void *vn, void *vm,
86
+ void *vg, uint32_t desc)
87
+{
88
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
89
+ uint64_t *d = vd, *n = vn, *m = vm;
90
+ uint8_t *pg = vg;
91
+
92
+ for (i = 0; i < opr_sz; i += 1) {
93
+ uint64_t nn = n[i], mm = m[i];
94
+ d[i] = (pg[H1(i)] & 1 ? nn : mm);
95
+ }
96
+}
97
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
98
index XXXXXXX..XXXXXXX 100644
99
--- a/target/arm/translate-sve.c
100
+++ b/target/arm/translate-sve.c
101
@@ -XXX,XX +XXX,XX @@ static bool trans_UDIV_zpzz(DisasContext *s, arg_rprr_esz *a, uint32_t insn)
102
return do_zpzz_ool(s, a, fns[a->esz]);
103
}
104
105
+DO_ZPZZ(SEL, sel)
106
+
107
#undef DO_ZPZZ
108
109
/*
110
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
111
index XXXXXXX..XXXXXXX 100644
112
--- a/target/arm/sve.decode
113
+++ b/target/arm/sve.decode
114
@@ -XXX,XX +XXX,XX @@
115
&rprr_esz rn=%reg_movprfx
116
@rdm_pg_rn ........ esz:2 ... ... ... pg:3 rn:5 rd:5 \
117
&rprr_esz rm=%reg_movprfx
118
+@rd_pg4_rn_rm ........ esz:2 . rm:5 .. pg:4 rn:5 rd:5 &rprr_esz
119
120
# Three register operand, with governing predicate, vector element size
121
@rda_pg_rn_rm ........ esz:2 . rm:5 ... pg:3 rn:5 rd:5 \
122
@@ -XXX,XX +XXX,XX @@ RBIT 00000101 .. 1001 11 100 ... ..... ..... @rd_pg_rn
123
# SVE vector splice (predicated)
124
SPLICE 00000101 .. 101 100 100 ... ..... ..... @rdn_pg_rm
125
126
+### SVE Select Vectors Group
127
+
128
+# SVE select vector elements (predicated)
129
+SEL_zpzz 00000101 .. 1 ..... 11 .... ..... ..... @rd_pg4_rn_rm
130
+
131
### SVE Predicate Logical Operations Group
132
133
# SVE predicate logical operations
134
--
33
--
135
2.17.1
34
2.20.1
136
35
137
36
diff view generated by jsdifflib
1
The ethernet controller in the AN505 MPC FPGA image is behind
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
the same AHB Peripheral Protection Controller that handles
3
the graphics and GPIOs. (In the documentation this is clear
4
in the block diagram but the ethernet controller was omitted
5
from the table listing devices connected to the PPC.)
6
The ethernet sits behind AHB PPCEXP0 interface 5. We had
7
incorrectly claimed that this was a "gpio4", but there are
8
only 4 GPIOs in this image.
9
2
10
Correct the QEMU model to match the hardware.
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20190412165416.7977-12-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
include/hw/net/lan9118.h | 2 ++
9
hw/arm/exynos4_boards.c | 3 ++-
10
hw/arm/mps2-tz.c | 3 ++-
11
hw/net/lan9118.c | 1 -
12
4 files changed, 6 insertions(+), 3 deletions(-)
11
13
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
index XXXXXXX..XXXXXXX 100644
14
Message-id: 20180515171446.10834-1-peter.maydell@linaro.org
16
--- a/include/hw/net/lan9118.h
15
---
17
+++ b/include/hw/net/lan9118.h
16
hw/arm/mps2-tz.c | 32 +++++++++++++++++++++++---------
18
@@ -XXX,XX +XXX,XX @@
17
1 file changed, 23 insertions(+), 9 deletions(-)
19
#include "hw/irq.h"
18
20
#include "net/net.h"
21
22
+#define TYPE_LAN9118 "lan9118"
23
+
24
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
25
26
#endif
27
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/exynos4_boards.c
30
+++ b/hw/arm/exynos4_boards.c
31
@@ -XXX,XX +XXX,XX @@
32
#include "hw/arm/arm.h"
33
#include "exec/address-spaces.h"
34
#include "hw/arm/exynos4210.h"
35
+#include "hw/net/lan9118.h"
36
#include "hw/boards.h"
37
38
#undef DEBUG
39
@@ -XXX,XX +XXX,XX @@ static void lan9215_init(uint32_t base, qemu_irq irq)
40
/* This should be a 9215 but the 9118 is close enough */
41
if (nd_table[0].used) {
42
qemu_check_nic_model(&nd_table[0], "lan9118");
43
- dev = qdev_create(NULL, "lan9118");
44
+ dev = qdev_create(NULL, TYPE_LAN9118);
45
qdev_set_nic_properties(dev, &nd_table[0]);
46
qdev_prop_set_uint32(dev, "mode_16bit", 1);
47
qdev_init_nofail(dev);
19
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
48
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
20
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/mps2-tz.c
50
--- a/hw/arm/mps2-tz.c
22
+++ b/hw/arm/mps2-tz.c
51
+++ b/hw/arm/mps2-tz.c
23
@@ -XXX,XX +XXX,XX @@ typedef struct {
52
@@ -XXX,XX +XXX,XX @@
24
UnimplementedDeviceState spi[5];
53
#include "hw/arm/armsse.h"
25
UnimplementedDeviceState i2c[4];
54
#include "hw/dma/pl080.h"
26
UnimplementedDeviceState i2s_audio;
55
#include "hw/ssi/pl022.h"
27
- UnimplementedDeviceState gpio[5];
56
+#include "hw/net/lan9118.h"
28
+ UnimplementedDeviceState gpio[4];
57
#include "net/net.h"
29
UnimplementedDeviceState dma[4];
58
#include "hw/core/split-irq.h"
30
UnimplementedDeviceState gfx;
59
31
CMSDKAPBUART uart[5];
60
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
32
SplitIRQ sec_resp_splitter;
61
* except that it doesn't support the checksum-offload feature.
33
qemu_or_irq uart_irq_orgate;
62
*/
34
+ DeviceState *lan9118;
63
qemu_check_nic_model(nd, "lan9118");
35
} MPS2TZMachineState;
64
- mms->lan9118 = qdev_create(NULL, "lan9118");
36
65
+ mms->lan9118 = qdev_create(NULL, TYPE_LAN9118);
37
#define TYPE_MPS2TZ_MACHINE "mps2tz"
66
qdev_set_nic_properties(mms->lan9118, nd);
38
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
67
qdev_init_nofail(mms->lan9118);
39
return sysbus_mmio_get_region(SYS_BUS_DEVICE(fpgaio), 0);
68
40
}
69
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
41
70
index XXXXXXX..XXXXXXX 100644
42
+static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
71
--- a/hw/net/lan9118.c
43
+ const char *name, hwaddr size)
72
+++ b/hw/net/lan9118.c
44
+{
73
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118_packet = {
45
+ SysBusDevice *s;
46
+ DeviceState *iotkitdev = DEVICE(&mms->iotkit);
47
+ NICInfo *nd = &nd_table[0];
48
+
49
+ /* In hardware this is a LAN9220; the LAN9118 is software compatible
50
+ * except that it doesn't support the checksum-offload feature.
51
+ */
52
+ qemu_check_nic_model(nd, "lan9118");
53
+ mms->lan9118 = qdev_create(NULL, "lan9118");
54
+ qdev_set_nic_properties(mms->lan9118, nd);
55
+ qdev_init_nofail(mms->lan9118);
56
+
57
+ s = SYS_BUS_DEVICE(mms->lan9118);
58
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in_named(iotkitdev, "EXP_IRQ", 16));
59
+ return sysbus_mmio_get_region(s, 0);
60
+}
61
+
62
static void mps2tz_common_init(MachineState *machine)
63
{
64
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
65
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
66
{ "gpio1", make_unimp_dev, &mms->gpio[1], 0x40101000, 0x1000 },
67
{ "gpio2", make_unimp_dev, &mms->gpio[2], 0x40102000, 0x1000 },
68
{ "gpio3", make_unimp_dev, &mms->gpio[3], 0x40103000, 0x1000 },
69
- { "gpio4", make_unimp_dev, &mms->gpio[4], 0x40104000, 0x1000 },
70
+ { "eth", make_eth_dev, NULL, 0x42000000, 0x100000 },
71
},
72
}, {
73
.name = "ahb_ppcexp1",
74
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
75
"cfg_sec_resp", 0));
76
}
74
}
77
75
};
78
- /* In hardware this is a LAN9220; the LAN9118 is software compatible
76
79
- * except that it doesn't support the checksum-offload feature.
77
-#define TYPE_LAN9118 "lan9118"
80
- * The ethernet controller is not behind a PPC.
78
#define LAN9118(obj) OBJECT_CHECK(lan9118_state, (obj), TYPE_LAN9118)
81
- */
79
82
- lan9118_init(&nd_table[0], 0x42000000,
80
typedef struct {
83
- qdev_get_gpio_in_named(iotkitdev, "EXP_IRQ", 16));
84
-
85
create_unimplemented_device("FPGA NS PC", 0x48007000, 0x1000);
86
87
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x400000);
88
--
81
--
89
2.17.1
82
2.20.1
90
83
91
84
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
This commit finally deletes "hw/devices.h".
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
5
Message-id: 20180613015641.5667-3-richard.henderson@linaro.org
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Message-id: 20190412165416.7977-13-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
9
---
8
target/arm/helper-sve.h | 23 +++++++
10
include/hw/devices.h | 11 -----------
9
target/arm/sve_helper.c | 114 +++++++++++++++++++++++++++++++
11
include/hw/net/smc91c111.h | 19 +++++++++++++++++++
10
target/arm/translate-sve.c | 133 +++++++++++++++++++++++++++++++++++++
12
hw/arm/gumstix.c | 2 +-
11
target/arm/sve.decode | 27 ++++++++
13
hw/arm/integratorcp.c | 2 +-
12
4 files changed, 297 insertions(+)
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
13
21
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
22
diff --git a/include/hw/devices.h b/include/hw/devices.h
15
index XXXXXXX..XXXXXXX 100644
23
deleted file mode 100644
16
--- a/target/arm/helper-sve.h
24
index XXXXXXX..XXXXXXX
17
+++ b/target/arm/helper-sve.h
25
--- a/include/hw/devices.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_cpy_z_d, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
26
+++ /dev/null
19
27
@@ -XXX,XX +XXX,XX @@
20
DEF_HELPER_FLAGS_4(sve_ext, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
28
-#ifndef QEMU_DEVICES_H
21
29
-#define QEMU_DEVICES_H
22
+DEF_HELPER_FLAGS_4(sve_insr_b, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
30
-
23
+DEF_HELPER_FLAGS_4(sve_insr_h, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
31
-/* Devices that have nowhere better to go. */
24
+DEF_HELPER_FLAGS_4(sve_insr_s, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
32
-
25
+DEF_HELPER_FLAGS_4(sve_insr_d, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
33
-#include "hw/hw.h"
26
+
34
-
27
+DEF_HELPER_FLAGS_3(sve_rev_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
35
-/* smc91c111.c */
28
+DEF_HELPER_FLAGS_3(sve_rev_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
36
-void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
29
+DEF_HELPER_FLAGS_3(sve_rev_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
37
-
30
+DEF_HELPER_FLAGS_3(sve_rev_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
38
-#endif
31
+
39
diff --git a/include/hw/net/smc91c111.h b/include/hw/net/smc91c111.h
32
+DEF_HELPER_FLAGS_4(sve_tbl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
40
new file mode 100644
33
+DEF_HELPER_FLAGS_4(sve_tbl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
41
index XXXXXXX..XXXXXXX
34
+DEF_HELPER_FLAGS_4(sve_tbl_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
42
--- /dev/null
35
+DEF_HELPER_FLAGS_4(sve_tbl_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
43
+++ b/include/hw/net/smc91c111.h
36
+
44
@@ -XXX,XX +XXX,XX @@
37
+DEF_HELPER_FLAGS_3(sve_sunpk_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_3(sve_sunpk_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_3(sve_sunpk_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
40
+
41
+DEF_HELPER_FLAGS_3(sve_uunpk_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
42
+DEF_HELPER_FLAGS_3(sve_uunpk_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
43
+DEF_HELPER_FLAGS_3(sve_uunpk_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
44
+
45
DEF_HELPER_FLAGS_5(sve_and_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
46
DEF_HELPER_FLAGS_5(sve_bic_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
47
DEF_HELPER_FLAGS_5(sve_eor_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
48
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/sve_helper.c
51
+++ b/target/arm/sve_helper.c
52
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_ext)(void *vd, void *vn, void *vm, uint32_t desc)
53
memcpy(vd + n_siz, &tmp, n_ofs);
54
}
55
}
56
+
57
+#define DO_INSR(NAME, TYPE, H) \
58
+void HELPER(NAME)(void *vd, void *vn, uint64_t val, uint32_t desc) \
59
+{ \
60
+ intptr_t opr_sz = simd_oprsz(desc); \
61
+ swap_memmove(vd + sizeof(TYPE), vn, opr_sz - sizeof(TYPE)); \
62
+ *(TYPE *)(vd + H(0)) = val; \
63
+}
64
+
65
+DO_INSR(sve_insr_b, uint8_t, H1)
66
+DO_INSR(sve_insr_h, uint16_t, H1_2)
67
+DO_INSR(sve_insr_s, uint32_t, H1_4)
68
+DO_INSR(sve_insr_d, uint64_t, )
69
+
70
+#undef DO_INSR
71
+
72
+void HELPER(sve_rev_b)(void *vd, void *vn, uint32_t desc)
73
+{
74
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
75
+ for (i = 0, j = opr_sz - 8; i < opr_sz / 2; i += 8, j -= 8) {
76
+ uint64_t f = *(uint64_t *)(vn + i);
77
+ uint64_t b = *(uint64_t *)(vn + j);
78
+ *(uint64_t *)(vd + i) = bswap64(b);
79
+ *(uint64_t *)(vd + j) = bswap64(f);
80
+ }
81
+}
82
+
83
+static inline uint64_t hswap64(uint64_t h)
84
+{
85
+ uint64_t m = 0x0000ffff0000ffffull;
86
+ h = rol64(h, 32);
87
+ return ((h & m) << 16) | ((h >> 16) & m);
88
+}
89
+
90
+void HELPER(sve_rev_h)(void *vd, void *vn, uint32_t desc)
91
+{
92
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
93
+ for (i = 0, j = opr_sz - 8; i < opr_sz / 2; i += 8, j -= 8) {
94
+ uint64_t f = *(uint64_t *)(vn + i);
95
+ uint64_t b = *(uint64_t *)(vn + j);
96
+ *(uint64_t *)(vd + i) = hswap64(b);
97
+ *(uint64_t *)(vd + j) = hswap64(f);
98
+ }
99
+}
100
+
101
+void HELPER(sve_rev_s)(void *vd, void *vn, uint32_t desc)
102
+{
103
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
104
+ for (i = 0, j = opr_sz - 8; i < opr_sz / 2; i += 8, j -= 8) {
105
+ uint64_t f = *(uint64_t *)(vn + i);
106
+ uint64_t b = *(uint64_t *)(vn + j);
107
+ *(uint64_t *)(vd + i) = rol64(b, 32);
108
+ *(uint64_t *)(vd + j) = rol64(f, 32);
109
+ }
110
+}
111
+
112
+void HELPER(sve_rev_d)(void *vd, void *vn, uint32_t desc)
113
+{
114
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
115
+ for (i = 0, j = opr_sz - 8; i < opr_sz / 2; i += 8, j -= 8) {
116
+ uint64_t f = *(uint64_t *)(vn + i);
117
+ uint64_t b = *(uint64_t *)(vn + j);
118
+ *(uint64_t *)(vd + i) = b;
119
+ *(uint64_t *)(vd + j) = f;
120
+ }
121
+}
122
+
123
+#define DO_TBL(NAME, TYPE, H) \
124
+void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
125
+{ \
126
+ intptr_t i, opr_sz = simd_oprsz(desc); \
127
+ uintptr_t elem = opr_sz / sizeof(TYPE); \
128
+ TYPE *d = vd, *n = vn, *m = vm; \
129
+ ARMVectorReg tmp; \
130
+ if (unlikely(vd == vn)) { \
131
+ n = memcpy(&tmp, vn, opr_sz); \
132
+ } \
133
+ for (i = 0; i < elem; i++) { \
134
+ TYPE j = m[H(i)]; \
135
+ d[H(i)] = j < elem ? n[H(j)] : 0; \
136
+ } \
137
+}
138
+
139
+DO_TBL(sve_tbl_b, uint8_t, H1)
140
+DO_TBL(sve_tbl_h, uint16_t, H2)
141
+DO_TBL(sve_tbl_s, uint32_t, H4)
142
+DO_TBL(sve_tbl_d, uint64_t, )
143
+
144
+#undef TBL
145
+
146
+#define DO_UNPK(NAME, TYPED, TYPES, HD, HS) \
147
+void HELPER(NAME)(void *vd, void *vn, uint32_t desc) \
148
+{ \
149
+ intptr_t i, opr_sz = simd_oprsz(desc); \
150
+ TYPED *d = vd; \
151
+ TYPES *n = vn; \
152
+ ARMVectorReg tmp; \
153
+ if (unlikely(vn - vd < opr_sz)) { \
154
+ n = memcpy(&tmp, n, opr_sz / 2); \
155
+ } \
156
+ for (i = 0; i < opr_sz / sizeof(TYPED); i++) { \
157
+ d[HD(i)] = n[HS(i)]; \
158
+ } \
159
+}
160
+
161
+DO_UNPK(sve_sunpk_h, int16_t, int8_t, H2, H1)
162
+DO_UNPK(sve_sunpk_s, int32_t, int16_t, H4, H2)
163
+DO_UNPK(sve_sunpk_d, int64_t, int32_t, , H4)
164
+
165
+DO_UNPK(sve_uunpk_h, uint16_t, uint8_t, H2, H1)
166
+DO_UNPK(sve_uunpk_s, uint32_t, uint16_t, H4, H2)
167
+DO_UNPK(sve_uunpk_d, uint64_t, uint32_t, , H4)
168
+
169
+#undef DO_UNPK
170
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
171
index XXXXXXX..XXXXXXX 100644
172
--- a/target/arm/translate-sve.c
173
+++ b/target/arm/translate-sve.c
174
@@ -XXX,XX +XXX,XX @@ static bool trans_EXT(DisasContext *s, arg_EXT *a, uint32_t insn)
175
return true;
176
}
177
178
+/*
45
+/*
179
+ *** SVE Permute - Unpredicated Group
46
+ * SMSC 91C111 Ethernet interface emulation
47
+ *
48
+ * Copyright (c) 2005 CodeSourcery, LLC.
49
+ * Written by Paul Brook
50
+ *
51
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
52
+ * See the COPYING file in the top-level directory.
180
+ */
53
+ */
181
+
54
+
182
+static bool trans_DUP_s(DisasContext *s, arg_DUP_s *a, uint32_t insn)
55
+#ifndef HW_NET_SMC91C111_H
183
+{
56
+#define HW_NET_SMC91C111_H
184
+ if (sve_access_check(s)) {
185
+ unsigned vsz = vec_full_reg_size(s);
186
+ tcg_gen_gvec_dup_i64(a->esz, vec_full_reg_offset(s, a->rd),
187
+ vsz, vsz, cpu_reg_sp(s, a->rn));
188
+ }
189
+ return true;
190
+}
191
+
57
+
192
+static bool trans_DUP_x(DisasContext *s, arg_DUP_x *a, uint32_t insn)
58
+#include "hw/irq.h"
193
+{
59
+#include "net/net.h"
194
+ if ((a->imm & 0x1f) == 0) {
195
+ return false;
196
+ }
197
+ if (sve_access_check(s)) {
198
+ unsigned vsz = vec_full_reg_size(s);
199
+ unsigned dofs = vec_full_reg_offset(s, a->rd);
200
+ unsigned esz, index;
201
+
60
+
202
+ esz = ctz32(a->imm);
61
+void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
203
+ index = a->imm >> (esz + 1);
204
+
62
+
205
+ if ((index << esz) < vsz) {
63
+#endif
206
+ unsigned nofs = vec_reg_offset(s, a->rn, index, esz);
64
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
207
+ tcg_gen_gvec_dup_mem(esz, dofs, nofs, vsz, vsz);
208
+ } else {
209
+ tcg_gen_gvec_dup64i(dofs, vsz, vsz, 0);
210
+ }
211
+ }
212
+ return true;
213
+}
214
+
215
+static void do_insr_i64(DisasContext *s, arg_rrr_esz *a, TCGv_i64 val)
216
+{
217
+ typedef void gen_insr(TCGv_ptr, TCGv_ptr, TCGv_i64, TCGv_i32);
218
+ static gen_insr * const fns[4] = {
219
+ gen_helper_sve_insr_b, gen_helper_sve_insr_h,
220
+ gen_helper_sve_insr_s, gen_helper_sve_insr_d,
221
+ };
222
+ unsigned vsz = vec_full_reg_size(s);
223
+ TCGv_i32 desc = tcg_const_i32(simd_desc(vsz, vsz, 0));
224
+ TCGv_ptr t_zd = tcg_temp_new_ptr();
225
+ TCGv_ptr t_zn = tcg_temp_new_ptr();
226
+
227
+ tcg_gen_addi_ptr(t_zd, cpu_env, vec_full_reg_offset(s, a->rd));
228
+ tcg_gen_addi_ptr(t_zn, cpu_env, vec_full_reg_offset(s, a->rn));
229
+
230
+ fns[a->esz](t_zd, t_zn, val, desc);
231
+
232
+ tcg_temp_free_ptr(t_zd);
233
+ tcg_temp_free_ptr(t_zn);
234
+ tcg_temp_free_i32(desc);
235
+}
236
+
237
+static bool trans_INSR_f(DisasContext *s, arg_rrr_esz *a, uint32_t insn)
238
+{
239
+ if (sve_access_check(s)) {
240
+ TCGv_i64 t = tcg_temp_new_i64();
241
+ tcg_gen_ld_i64(t, cpu_env, vec_reg_offset(s, a->rm, 0, MO_64));
242
+ do_insr_i64(s, a, t);
243
+ tcg_temp_free_i64(t);
244
+ }
245
+ return true;
246
+}
247
+
248
+static bool trans_INSR_r(DisasContext *s, arg_rrr_esz *a, uint32_t insn)
249
+{
250
+ if (sve_access_check(s)) {
251
+ do_insr_i64(s, a, cpu_reg(s, a->rm));
252
+ }
253
+ return true;
254
+}
255
+
256
+static bool trans_REV_v(DisasContext *s, arg_rr_esz *a, uint32_t insn)
257
+{
258
+ static gen_helper_gvec_2 * const fns[4] = {
259
+ gen_helper_sve_rev_b, gen_helper_sve_rev_h,
260
+ gen_helper_sve_rev_s, gen_helper_sve_rev_d
261
+ };
262
+
263
+ if (sve_access_check(s)) {
264
+ unsigned vsz = vec_full_reg_size(s);
265
+ tcg_gen_gvec_2_ool(vec_full_reg_offset(s, a->rd),
266
+ vec_full_reg_offset(s, a->rn),
267
+ vsz, vsz, 0, fns[a->esz]);
268
+ }
269
+ return true;
270
+}
271
+
272
+static bool trans_TBL(DisasContext *s, arg_rrr_esz *a, uint32_t insn)
273
+{
274
+ static gen_helper_gvec_3 * const fns[4] = {
275
+ gen_helper_sve_tbl_b, gen_helper_sve_tbl_h,
276
+ gen_helper_sve_tbl_s, gen_helper_sve_tbl_d
277
+ };
278
+
279
+ if (sve_access_check(s)) {
280
+ unsigned vsz = vec_full_reg_size(s);
281
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
282
+ vec_full_reg_offset(s, a->rn),
283
+ vec_full_reg_offset(s, a->rm),
284
+ vsz, vsz, 0, fns[a->esz]);
285
+ }
286
+ return true;
287
+}
288
+
289
+static bool trans_UNPK(DisasContext *s, arg_UNPK *a, uint32_t insn)
290
+{
291
+ static gen_helper_gvec_2 * const fns[4][2] = {
292
+ { NULL, NULL },
293
+ { gen_helper_sve_sunpk_h, gen_helper_sve_uunpk_h },
294
+ { gen_helper_sve_sunpk_s, gen_helper_sve_uunpk_s },
295
+ { gen_helper_sve_sunpk_d, gen_helper_sve_uunpk_d },
296
+ };
297
+
298
+ if (a->esz == 0) {
299
+ return false;
300
+ }
301
+ if (sve_access_check(s)) {
302
+ unsigned vsz = vec_full_reg_size(s);
303
+ tcg_gen_gvec_2_ool(vec_full_reg_offset(s, a->rd),
304
+ vec_full_reg_offset(s, a->rn)
305
+ + (a->h ? vsz / 2 : 0),
306
+ vsz, vsz, 0, fns[a->esz][a->u]);
307
+ }
308
+ return true;
309
+}
310
+
311
/*
312
*** SVE Memory - 32-bit Gather and Unsized Contiguous Group
313
*/
314
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
315
index XXXXXXX..XXXXXXX 100644
65
index XXXXXXX..XXXXXXX 100644
316
--- a/target/arm/sve.decode
66
--- a/hw/arm/gumstix.c
317
+++ b/target/arm/sve.decode
67
+++ b/hw/arm/gumstix.c
318
@@ -XXX,XX +XXX,XX @@
68
@@ -XXX,XX +XXX,XX @@
319
69
#include "hw/arm/pxa.h"
320
%imm4_16_p1 16:4 !function=plus1
70
#include "net/net.h"
321
%imm6_22_5 22:1 5:5
71
#include "hw/block/flash.h"
322
+%imm7_22_16 22:2 16:5
72
-#include "hw/devices.h"
323
%imm8_16_10 16:5 10:3
73
+#include "hw/net/smc91c111.h"
324
%imm9_16_10 16:s6 10:3
74
#include "hw/boards.h"
325
75
#include "exec/address-spaces.h"
76
#include "sysemu/qtest.h"
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
326
@@ -XXX,XX +XXX,XX @@
81
@@ -XXX,XX +XXX,XX @@
327
82
#include "qemu-common.h"
328
# Three operand, vector element size
83
#include "cpu.h"
329
@rd_rn_rm ........ esz:2 . rm:5 ... ... rn:5 rd:5 &rrr_esz
84
#include "hw/sysbus.h"
330
+@rdn_rm ........ esz:2 ...... ...... rm:5 rd:5 \
85
-#include "hw/devices.h"
331
+ &rrr_esz rn=%reg_movprfx
86
#include "hw/boards.h"
332
87
#include "hw/arm/arm.h"
333
# Three operand with "memory" size, aka immediate left shift
88
#include "hw/misc/arm_integrator_debug.h"
334
@rd_rn_msz_rm ........ ... rm:5 .... imm:2 rn:5 rd:5 &rrri
89
+#include "hw/net/smc91c111.h"
335
@@ -XXX,XX +XXX,XX @@ CPY_z_i 00000101 .. 01 .... 00 . ........ ..... @rdn_pg4 imm=%sh8_i8s
90
#include "net/net.h"
336
EXT 00000101 001 ..... 000 ... rm:5 rd:5 \
91
#include "exec/address-spaces.h"
337
&rrri rn=%reg_movprfx imm=%imm8_16_10
92
#include "sysemu/sysemu.h"
338
93
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
339
+### SVE Permute - Unpredicated Group
94
index XXXXXXX..XXXXXXX 100644
340
+
95
--- a/hw/arm/mainstone.c
341
+# SVE broadcast general register
96
+++ b/hw/arm/mainstone.c
342
+DUP_s 00000101 .. 1 00000 001110 ..... ..... @rd_rn
97
@@ -XXX,XX +XXX,XX @@
343
+
98
#include "hw/arm/pxa.h"
344
+# SVE broadcast indexed element
99
#include "hw/arm/arm.h"
345
+DUP_x 00000101 .. 1 ..... 001000 rn:5 rd:5 \
100
#include "net/net.h"
346
+ &rri imm=%imm7_22_16
101
-#include "hw/devices.h"
347
+
102
+#include "hw/net/smc91c111.h"
348
+# SVE insert SIMD&FP scalar register
103
#include "hw/boards.h"
349
+INSR_f 00000101 .. 1 10100 001110 ..... ..... @rdn_rm
104
#include "hw/block/flash.h"
350
+
105
#include "hw/sysbus.h"
351
+# SVE insert general register
106
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
352
+INSR_r 00000101 .. 1 00100 001110 ..... ..... @rdn_rm
107
index XXXXXXX..XXXXXXX 100644
353
+
108
--- a/hw/arm/realview.c
354
+# SVE reverse vector elements
109
+++ b/hw/arm/realview.c
355
+REV_v 00000101 .. 1 11000 001110 ..... ..... @rd_rn
110
@@ -XXX,XX +XXX,XX @@
356
+
111
#include "hw/sysbus.h"
357
+# SVE vector table lookup
112
#include "hw/arm/arm.h"
358
+TBL 00000101 .. 1 ..... 001100 ..... ..... @rd_rn_rm
113
#include "hw/arm/primecell.h"
359
+
114
-#include "hw/devices.h"
360
+# SVE unpack vector elements
115
#include "hw/net/lan9118.h"
361
+UNPK 00000101 esz:2 1100 u:1 h:1 001110 rn:5 rd:5
116
+#include "hw/net/smc91c111.h"
362
+
117
#include "hw/pci/pci.h"
363
### SVE Predicate Logical Operations Group
118
#include "net/net.h"
364
119
#include "sysemu/sysemu.h"
365
# SVE predicate logical operations
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>
366
--
146
--
367
2.17.1
147
2.20.1
368
148
369
149
diff view generated by jsdifflib