1
First pullreq for arm of the 4.1 series, since I'm back from
1
Most of this is the Neon decodetree patches, followed by Edgar's versal cleanups.
2
holiday now. This is mostly my M-profile FPU series and Philippe's
3
devices.h cleanup. I have a pile of other patchsets to work through
4
in my to-review folder, but 42 patches is definitely quite
5
big enough to send now...
6
2
7
thanks
3
thanks
8
-- PMM
4
-- PMM
9
5
10
The following changes since commit 413a99a92c13ec408dcf2adaa87918dc81e890c8:
11
6
12
Add Nios II semihosting support. (2019-04-29 16:09:51 +0100)
7
The following changes since commit 2ef486e76d64436be90f7359a3071fb2a56ce835:
8
9
Merge remote-tracking branch 'remotes/marcel/tags/rdma-pull-request' into staging (2020-05-03 14:12:56 +0100)
13
10
14
are available in the Git repository at:
11
are available in the Git repository at:
15
12
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190429
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200504
17
14
18
for you to fetch changes up to 437cc27ddfded3bbab6afd5ac1761e0e195edba7:
15
for you to fetch changes up to 9aefc6cf9b73f66062d2f914a0136756e7a28211:
19
16
20
hw/devices: Move SMSC 91C111 declaration into a new header (2019-04-29 17:57:21 +0100)
17
target/arm: Move gen_ function typedefs to translate.h (2020-05-04 12:59:26 +0100)
21
18
22
----------------------------------------------------------------
19
----------------------------------------------------------------
23
target-arm queue:
20
target-arm queue:
24
* remove "bag of random stuff" hw/devices.h header
21
* Start of conversion of Neon insns to decodetree
25
* implement FPU for Cortex-M and enable it for Cortex-M4 and -M33
22
* versal board: support SD and RTC
26
* hw/dma: Compile the bcm2835_dma device as common object
23
* Implement ARMv8.2-TTS2UXN
27
* configure: Remove --source-path option
24
* Make VQDMULL undefined when U=1
28
* hw/ssi/xilinx_spips: Avoid variable length array
25
* Some minor code cleanups
29
* hw/arm/smmuv3: Remove SMMUNotifierNode
30
26
31
----------------------------------------------------------------
27
----------------------------------------------------------------
32
Eric Auger (1):
28
Edgar E. Iglesias (11):
33
hw/arm/smmuv3: Remove SMMUNotifierNode
29
hw/arm: versal: Remove inclusion of arm_gicv3_common.h
30
hw/arm: versal: Move misplaced comment
31
hw/arm: versal-virt: Fix typo xlnx-ve -> xlnx-versal
32
hw/arm: versal: Embed the UARTs into the SoC type
33
hw/arm: versal: Embed the GEMs into the SoC type
34
hw/arm: versal: Embed the ADMAs into the SoC type
35
hw/arm: versal: Embed the APUs into the SoC type
36
hw/arm: versal: Add support for SD
37
hw/arm: versal: Add support for the RTC
38
hw/arm: versal-virt: Add support for SD
39
hw/arm: versal-virt: Add support for the RTC
34
40
35
Peter Maydell (28):
41
Fredrik Strupe (1):
36
hw/ssi/xilinx_spips: Avoid variable length array
42
target/arm: Make VQDMULL undefined when U=1
37
configure: Remove --source-path option
38
target/arm: Make sure M-profile FPSCR RES0 bits are not settable
39
hw/intc/armv7m_nvic: Allow reading of M-profile MVFR* registers
40
target/arm: Implement dummy versions of M-profile FP-related registers
41
target/arm: Disable most VFP sysregs for M-profile
42
target/arm: Honour M-profile FP enable bits
43
target/arm: Decode FP instructions for M profile
44
target/arm: Clear CONTROL_S.SFPA in SG insn if FPU present
45
target/arm: Handle SFPA and FPCA bits in reads and writes of CONTROL
46
target/arm/helper: don't return early for STKOF faults during stacking
47
target/arm: Handle floating point registers in exception entry
48
target/arm: Implement v7m_update_fpccr()
49
target/arm: Clear CONTROL.SFPA in BXNS and BLXNS
50
target/arm: Clean excReturn bits when tail chaining
51
target/arm: Allow for floating point in callee stack integrity check
52
target/arm: Handle floating point registers in exception return
53
target/arm: Move NS TBFLAG from bit 19 to bit 6
54
target/arm: Overlap VECSTRIDE and XSCALE_CPAR TB flags
55
target/arm: Set FPCCR.S when executing M-profile floating point insns
56
target/arm: Activate M-profile floating point context when FPCCR.ASPEN is set
57
target/arm: New helper function arm_v7m_mmu_idx_all()
58
target/arm: New function armv7m_nvic_set_pending_lazyfp()
59
target/arm: Add lazy-FP-stacking support to v7m_stack_write()
60
target/arm: Implement M-profile lazy FP state preservation
61
target/arm: Implement VLSTM for v7M CPUs with an FPU
62
target/arm: Implement VLLDM for v7M CPUs with an FPU
63
target/arm: Enable FPU for Cortex-M4 and Cortex-M33
64
43
65
Philippe Mathieu-Daudé (13):
44
Peter Maydell (25):
66
hw/dma: Compile the bcm2835_dma device as common object
45
target/arm: Don't use a TLB for ARMMMUIdx_Stage2
67
hw/arm/aspeed: Use TYPE_TMP105/TYPE_PCA9552 instead of hardcoded string
46
target/arm: Use enum constant in get_phys_addr_lpae() call
68
hw/arm/nseries: Use TYPE_TMP105 instead of hardcoded string
47
target/arm: Add new 's1_is_el0' argument to get_phys_addr_lpae()
69
hw/display/tc6393xb: Remove unused functions
48
target/arm: Implement ARMv8.2-TTS2UXN
70
hw/devices: Move TC6393XB declarations into a new header
49
target/arm: Use correct variable for setting 'max' cpu's ID_AA64DFR0
71
hw/devices: Move Blizzard declarations into a new header
50
target/arm/translate-vfp.inc.c: Remove duplicate simd_r32 check
72
hw/devices: Move CBus declarations into a new header
51
target/arm: Don't allow Thumb Neon insns without FEATURE_NEON
73
hw/devices: Move Gamepad declarations into a new header
52
target/arm: Add stubs for AArch32 Neon decodetree
74
hw/devices: Move TI touchscreen declarations into a new header
53
target/arm: Convert VCMLA (vector) to decodetree
75
hw/devices: Move LAN9118 declarations into a new header
54
target/arm: Convert VCADD (vector) to decodetree
76
hw/net/ne2000-isa: Add guards to the header
55
target/arm: Convert V[US]DOT (vector) to decodetree
77
hw/net/lan9118: Export TYPE_LAN9118 and use it instead of hardcoded string
56
target/arm: Convert VFM[AS]L (vector) to decodetree
78
hw/devices: Move SMSC 91C111 declaration into a new header
57
target/arm: Convert VCMLA (scalar) to decodetree
58
target/arm: Convert V[US]DOT (scalar) to decodetree
59
target/arm: Convert VFM[AS]L (scalar) to decodetree
60
target/arm: Convert Neon load/store multiple structures to decodetree
61
target/arm: Convert Neon 'load single structure to all lanes' to decodetree
62
target/arm: Convert Neon 'load/store single structure' to decodetree
63
target/arm: Convert Neon 3-reg-same VADD/VSUB to decodetree
64
target/arm: Convert Neon 3-reg-same logic ops to decodetree
65
target/arm: Convert Neon 3-reg-same VMAX/VMIN to decodetree
66
target/arm: Convert Neon 3-reg-same comparisons to decodetree
67
target/arm: Convert Neon 3-reg-same VQADD/VQSUB to decodetree
68
target/arm: Convert Neon 3-reg-same VMUL, VMLA, VMLS, VSHL to decodetree
69
target/arm: Move gen_ function typedefs to translate.h
79
70
80
configure | 10 +-
71
Philippe Mathieu-Daudé (2):
81
hw/dma/Makefile.objs | 2 +-
72
hw/arm/mps2-tz: Use TYPE_IOTKIT instead of hardcoded string
82
include/hw/arm/omap.h | 6 +-
73
target/arm: Use uint64_t for midr field in CPU state struct
83
include/hw/arm/smmu-common.h | 8 +-
84
include/hw/devices.h | 62 ---
85
include/hw/display/blizzard.h | 22 ++
86
include/hw/display/tc6393xb.h | 24 ++
87
include/hw/input/gamepad.h | 19 +
88
include/hw/input/tsc2xxx.h | 36 ++
89
include/hw/misc/cbus.h | 32 ++
90
include/hw/net/lan9118.h | 21 +
91
include/hw/net/ne2000-isa.h | 6 +
92
include/hw/net/smc91c111.h | 19 +
93
include/qemu/typedefs.h | 1 -
94
target/arm/cpu.h | 95 ++++-
95
target/arm/helper.h | 5 +
96
target/arm/translate.h | 3 +
97
hw/arm/aspeed.c | 13 +-
98
hw/arm/exynos4_boards.c | 3 +-
99
hw/arm/gumstix.c | 2 +-
100
hw/arm/integratorcp.c | 2 +-
101
hw/arm/kzm.c | 2 +-
102
hw/arm/mainstone.c | 2 +-
103
hw/arm/mps2-tz.c | 3 +-
104
hw/arm/mps2.c | 2 +-
105
hw/arm/nseries.c | 7 +-
106
hw/arm/palm.c | 2 +-
107
hw/arm/realview.c | 3 +-
108
hw/arm/smmu-common.c | 6 +-
109
hw/arm/smmuv3.c | 28 +-
110
hw/arm/stellaris.c | 2 +-
111
hw/arm/tosa.c | 2 +-
112
hw/arm/versatilepb.c | 2 +-
113
hw/arm/vexpress.c | 2 +-
114
hw/display/blizzard.c | 2 +-
115
hw/display/tc6393xb.c | 18 +-
116
hw/input/stellaris_input.c | 2 +-
117
hw/input/tsc2005.c | 2 +-
118
hw/input/tsc210x.c | 4 +-
119
hw/intc/armv7m_nvic.c | 261 +++++++++++++
120
hw/misc/cbus.c | 2 +-
121
hw/net/lan9118.c | 3 +-
122
hw/net/smc91c111.c | 2 +-
123
hw/ssi/xilinx_spips.c | 6 +-
124
target/arm/cpu.c | 20 +
125
target/arm/helper.c | 873 +++++++++++++++++++++++++++++++++++++++---
126
target/arm/machine.c | 16 +
127
target/arm/translate.c | 150 +++++++-
128
target/arm/vfp_helper.c | 8 +
129
MAINTAINERS | 7 +
130
50 files changed, 1595 insertions(+), 235 deletions(-)
131
delete mode 100644 include/hw/devices.h
132
create mode 100644 include/hw/display/blizzard.h
133
create mode 100644 include/hw/display/tc6393xb.h
134
create mode 100644 include/hw/input/gamepad.h
135
create mode 100644 include/hw/input/tsc2xxx.h
136
create mode 100644 include/hw/misc/cbus.h
137
create mode 100644 include/hw/net/lan9118.h
138
create mode 100644 include/hw/net/smc91c111.h
139
74
75
include/hw/arm/xlnx-versal.h | 31 +-
76
target/arm/cpu-param.h | 2 +-
77
target/arm/cpu.h | 38 ++-
78
target/arm/translate-a64.h | 9 -
79
target/arm/translate.h | 26 ++
80
target/arm/neon-dp.decode | 86 +++++
81
target/arm/neon-ls.decode | 52 +++
82
target/arm/neon-shared.decode | 66 ++++
83
hw/arm/mps2-tz.c | 2 +-
84
hw/arm/xlnx-versal-virt.c | 74 ++++-
85
hw/arm/xlnx-versal.c | 115 +++++--
86
target/arm/cpu.c | 3 +-
87
target/arm/cpu64.c | 8 +-
88
target/arm/helper.c | 183 ++++------
89
target/arm/translate-a64.c | 17 -
90
target/arm/translate-neon.inc.c | 714 +++++++++++++++++++++++++++++++++++++++
91
target/arm/translate-vfp.inc.c | 6 -
92
target/arm/translate.c | 716 +++-------------------------------------
93
target/arm/Makefile.objs | 18 +
94
19 files changed, 1302 insertions(+), 864 deletions(-)
95
create mode 100644 target/arm/neon-dp.decode
96
create mode 100644 target/arm/neon-ls.decode
97
create mode 100644 target/arm/neon-shared.decode
98
create mode 100644 target/arm/translate-neon.inc.c
99
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Fredrik Strupe <fredrik@strupe.net>
2
2
3
This device is used by both ARM (BCM2836, for raspi2) and AArch64
3
According to Arm ARM, VQDMULL is only valid when U=0, while having
4
(BCM2837, for raspi3) targets, and is not CPU-specific.
4
U=1 is unallocated.
5
Move it to common object, so we build it once for all targets.
6
5
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Signed-off-by: Fredrik Strupe <fredrik@strupe.net>
8
Message-id: 20190427133028.12874-1-philmd@redhat.com
7
Fixes: 695272dcb976 ("target-arm: Handle UNDEF cases for Neon 3-regs-different-widths")
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
hw/dma/Makefile.objs | 2 +-
11
target/arm/translate.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 1 insertion(+), 1 deletion(-)
14
13
15
diff --git a/hw/dma/Makefile.objs b/hw/dma/Makefile.objs
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/dma/Makefile.objs
16
--- a/target/arm/translate.c
18
+++ b/hw/dma/Makefile.objs
17
+++ b/target/arm/translate.c
19
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zdma.o
18
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
20
19
{0, 0, 0, 0}, /* VMLSL */
21
obj-$(CONFIG_OMAP) += omap_dma.o soc_dma.o
20
{0, 0, 0, 9}, /* VQDMLSL */
22
obj-$(CONFIG_PXA2XX) += pxa2xx_dma.o
21
{0, 0, 0, 0}, /* Integer VMULL */
23
-obj-$(CONFIG_RASPI) += bcm2835_dma.o
22
- {0, 0, 0, 1}, /* VQDMULL */
24
+common-obj-$(CONFIG_RASPI) += bcm2835_dma.o
23
+ {0, 0, 0, 9}, /* VQDMULL */
24
{0, 0, 0, 0xa}, /* Polynomial VMULL */
25
{0, 0, 0, 7}, /* Reserved: always UNDEF */
26
};
25
--
27
--
26
2.20.1
28
2.20.1
27
29
28
30
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
By using the TYPE_* definitions for devices, we can:
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
- quickly find where devices are used with 'git-grep'
5
Message-id: 20190412165416.7977-12-philmd@redhat.com
5
- easily rename a device (one-line change).
6
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20200428154650.21991-1-f4bug@amsat.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
include/hw/net/lan9118.h | 2 ++
12
hw/arm/mps2-tz.c | 2 +-
9
hw/arm/exynos4_boards.c | 3 ++-
13
1 file changed, 1 insertion(+), 1 deletion(-)
10
hw/arm/mps2-tz.c | 3 ++-
11
hw/net/lan9118.c | 1 -
12
4 files changed, 6 insertions(+), 3 deletions(-)
13
14
14
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/net/lan9118.h
17
+++ b/include/hw/net/lan9118.h
18
@@ -XXX,XX +XXX,XX @@
19
#include "hw/irq.h"
20
#include "net/net.h"
21
22
+#define TYPE_LAN9118 "lan9118"
23
+
24
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
25
26
#endif
27
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/exynos4_boards.c
30
+++ b/hw/arm/exynos4_boards.c
31
@@ -XXX,XX +XXX,XX @@
32
#include "hw/arm/arm.h"
33
#include "exec/address-spaces.h"
34
#include "hw/arm/exynos4210.h"
35
+#include "hw/net/lan9118.h"
36
#include "hw/boards.h"
37
38
#undef DEBUG
39
@@ -XXX,XX +XXX,XX @@ static void lan9215_init(uint32_t base, qemu_irq irq)
40
/* This should be a 9215 but the 9118 is close enough */
41
if (nd_table[0].used) {
42
qemu_check_nic_model(&nd_table[0], "lan9118");
43
- dev = qdev_create(NULL, "lan9118");
44
+ dev = qdev_create(NULL, TYPE_LAN9118);
45
qdev_set_nic_properties(dev, &nd_table[0]);
46
qdev_prop_set_uint32(dev, "mode_16bit", 1);
47
qdev_init_nofail(dev);
48
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
49
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/arm/mps2-tz.c
17
--- a/hw/arm/mps2-tz.c
51
+++ b/hw/arm/mps2-tz.c
18
+++ b/hw/arm/mps2-tz.c
52
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
53
#include "hw/arm/armsse.h"
20
exit(EXIT_FAILURE);
54
#include "hw/dma/pl080.h"
55
#include "hw/ssi/pl022.h"
56
+#include "hw/net/lan9118.h"
57
#include "net/net.h"
58
#include "hw/core/split-irq.h"
59
60
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
61
* except that it doesn't support the checksum-offload feature.
62
*/
63
qemu_check_nic_model(nd, "lan9118");
64
- mms->lan9118 = qdev_create(NULL, "lan9118");
65
+ mms->lan9118 = qdev_create(NULL, TYPE_LAN9118);
66
qdev_set_nic_properties(mms->lan9118, nd);
67
qdev_init_nofail(mms->lan9118);
68
69
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/hw/net/lan9118.c
72
+++ b/hw/net/lan9118.c
73
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118_packet = {
74
}
21
}
75
};
22
76
23
- sysbus_init_child_obj(OBJECT(machine), "iotkit", &mms->iotkit,
77
-#define TYPE_LAN9118 "lan9118"
24
+ sysbus_init_child_obj(OBJECT(machine), TYPE_IOTKIT, &mms->iotkit,
78
#define LAN9118(obj) OBJECT_CHECK(lan9118_state, (obj), TYPE_LAN9118)
25
sizeof(mms->iotkit), mmc->armsse_type);
79
26
iotkitdev = DEVICE(&mms->iotkit);
80
typedef struct {
27
object_property_set_link(OBJECT(&mms->iotkit), OBJECT(system_memory),
81
--
28
--
82
2.20.1
29
2.20.1
83
30
84
31
diff view generated by jsdifflib
1
Add a new helper function which returns the MMU index to use
1
We define ARMMMUIdx_Stage2 as being an MMU index which uses a QEMU
2
for v7M, where the caller specifies all of the security
2
TLB. However we never actually use the TLB -- all stage 2 lookups
3
state, privilege level and whether the execution priority
3
are done by direct calls to get_phys_addr_lpae() followed by a
4
is negative, and reimplement the existing
4
physical address load via address_space_ld*().
5
arm_v7m_mmu_idx_for_secstate_and_priv() in terms of it.
5
6
6
Remove Stage2 from the list of ARM MMU indexes which correspond to
7
We are going to need this for the lazy-FP-stacking code.
7
real core MMU indexes, and instead put it in the set of "NOTLB" ARM
8
MMU indexes.
9
10
This allows us to drop NB_MMU_MODES to 11. It also means we can
11
safely add support for the ARMv8.3-TTS2UXN extension, which adds
12
permission bits to the stage 2 descriptors which define execute
13
permission separatel for EL0 and EL1; supporting that while keeping
14
Stage2 in a QEMU TLB would require us to use separate TLBs for
15
"Stage2 for an EL0 access" and "Stage2 for an EL1 access", which is a
16
lot of extra complication given we aren't even using the QEMU TLB.
17
18
In the process of updating the comment on our MMU index use,
19
fix a couple of other minor errors:
20
* NS EL2 EL2&0 was missing from the list in the comment
21
* some text hadn't been updated from when we bumped NB_MMU_MODES
22
above 8
8
23
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20190416125744.27770-21-peter.maydell@linaro.org
27
Message-id: 20200330210400.11724-2-peter.maydell@linaro.org
12
---
28
---
13
target/arm/cpu.h | 7 +++++++
29
target/arm/cpu-param.h | 2 +-
14
target/arm/helper.c | 14 +++++++++++---
30
target/arm/cpu.h | 21 +++++---
15
2 files changed, 18 insertions(+), 3 deletions(-)
31
target/arm/helper.c | 112 ++++-------------------------------------
16
32
3 files changed, 27 insertions(+), 108 deletions(-)
33
34
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/cpu-param.h
37
+++ b/target/arm/cpu-param.h
38
@@ -XXX,XX +XXX,XX @@
39
# define TARGET_PAGE_BITS_MIN 10
40
#endif
41
42
-#define NB_MMU_MODES 12
43
+#define NB_MMU_MODES 11
44
45
#endif
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
46
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
48
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
49
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
50
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
22
}
51
* handling via the TLB. The only way to do a stage 1 translation without
23
}
52
* the immediate stage 2 translation is via the ATS or AT system insns,
24
53
* which can be slow-pathed and always do a page table walk.
25
+/*
54
+ * The only use of stage 2 translations is either as part of an s1+2
26
+ * Return the MMU index for a v7M CPU with all relevant information
55
+ * lookup or when loading the descriptors during a stage 1 page table walk,
27
+ * manually specified.
56
+ * and in both those cases we don't use the TLB.
28
+ */
57
* 4. we can also safely fold together the "32 bit EL3" and "64 bit EL3"
29
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
58
* translation regimes, because they map reasonably well to each other
30
+ bool secstate, bool priv, bool negpri);
59
* and they can't both be active at the same time.
31
+
60
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
32
/* Return the MMU index for a v7M CPU in the specified security and
61
* NS EL1 EL1&0 stage 1+2 (aka NS PL1)
33
* privilege state.
62
* NS EL1 EL1&0 stage 1+2 +PAN
34
*/
63
* NS EL0 EL2&0
64
+ * NS EL2 EL2&0
65
* NS EL2 EL2&0 +PAN
66
* NS EL2 (aka NS PL2)
67
* S EL0 EL1&0 (aka S PL0)
68
* S EL1 EL1&0 (not used if EL3 is 32 bit)
69
* S EL1 EL1&0 +PAN
70
* S EL3 (aka S PL1)
71
- * NS EL1&0 stage 2
72
*
73
- * for a total of 12 different mmu_idx.
74
+ * for a total of 11 different mmu_idx.
75
*
76
* R profile CPUs have an MPU, but can use the same set of MMU indexes
77
* as A profile. They only need to distinguish NS EL0 and NS EL1 (and
78
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
79
* are not quite the same -- different CPU types (most notably M profile
80
* vs A/R profile) would like to use MMU indexes with different semantics,
81
* but since we don't ever need to use all of those in a single CPU we
82
- * can avoid setting NB_MMU_MODES to more than 8. The lower bits of
83
+ * can avoid having to set NB_MMU_MODES to "total number of A profile MMU
84
+ * modes + total number of M profile MMU modes". The lower bits of
85
* ARMMMUIdx are the core TLB mmu index, and the higher bits are always
86
* the same for any particular CPU.
87
* Variables of type ARMMUIdx are always full values, and the core
88
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
89
ARMMMUIdx_SE10_1_PAN = 9 | ARM_MMU_IDX_A,
90
ARMMMUIdx_SE3 = 10 | ARM_MMU_IDX_A,
91
92
- ARMMMUIdx_Stage2 = 11 | ARM_MMU_IDX_A,
93
-
94
/*
95
* These are not allocated TLBs and are used only for AT system
96
* instructions or for the first stage of an S12 page table walk.
97
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
98
ARMMMUIdx_Stage1_E0 = 0 | ARM_MMU_IDX_NOTLB,
99
ARMMMUIdx_Stage1_E1 = 1 | ARM_MMU_IDX_NOTLB,
100
ARMMMUIdx_Stage1_E1_PAN = 2 | ARM_MMU_IDX_NOTLB,
101
+ /*
102
+ * Not allocated a TLB: used only for second stage of an S12 page
103
+ * table walk, or for descriptor loads during first stage of an S1
104
+ * page table walk. Note that if we ever want to have a TLB for this
105
+ * then various TLB flush insns which currently are no-ops or flush
106
+ * only stage 1 MMU indexes will need to change to flush stage 2.
107
+ */
108
+ ARMMMUIdx_Stage2 = 3 | ARM_MMU_IDX_NOTLB,
109
110
/*
111
* M-profile.
112
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
113
TO_CORE_BIT(SE10_1),
114
TO_CORE_BIT(SE10_1_PAN),
115
TO_CORE_BIT(SE3),
116
- TO_CORE_BIT(Stage2),
117
118
TO_CORE_BIT(MUser),
119
TO_CORE_BIT(MPriv),
35
diff --git a/target/arm/helper.c b/target/arm/helper.c
120
diff --git a/target/arm/helper.c b/target/arm/helper.c
36
index XXXXXXX..XXXXXXX 100644
121
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper.c
122
--- a/target/arm/helper.c
38
+++ b/target/arm/helper.c
123
+++ b/target/arm/helper.c
39
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
124
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
40
return 0;
125
tlb_flush_by_mmuidx(cs,
126
ARMMMUIdxBit_E10_1 |
127
ARMMMUIdxBit_E10_1_PAN |
128
- ARMMMUIdxBit_E10_0 |
129
- ARMMMUIdxBit_Stage2);
130
+ ARMMMUIdxBit_E10_0);
41
}
131
}
42
132
43
-ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
133
static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
44
- bool secstate, bool priv)
134
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
45
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
135
tlb_flush_by_mmuidx_all_cpus_synced(cs,
46
+ bool secstate, bool priv, bool negpri)
136
ARMMMUIdxBit_E10_1 |
137
ARMMMUIdxBit_E10_1_PAN |
138
- ARMMMUIdxBit_E10_0 |
139
- ARMMMUIdxBit_Stage2);
140
+ ARMMMUIdxBit_E10_0);
141
}
142
143
-static void tlbiipas2_write(CPUARMState *env, const ARMCPRegInfo *ri,
144
- uint64_t value)
145
-{
146
- /* Invalidate by IPA. This has to invalidate any structures that
147
- * contain only stage 2 translation information, but does not need
148
- * to apply to structures that contain combined stage 1 and stage 2
149
- * translation information.
150
- * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
151
- */
152
- CPUState *cs = env_cpu(env);
153
- uint64_t pageaddr;
154
-
155
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
156
- return;
157
- }
158
-
159
- pageaddr = sextract64(value << 12, 0, 40);
160
-
161
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
162
-}
163
-
164
-static void tlbiipas2_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
165
- uint64_t value)
166
-{
167
- CPUState *cs = env_cpu(env);
168
- uint64_t pageaddr;
169
-
170
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
171
- return;
172
- }
173
-
174
- pageaddr = sextract64(value << 12, 0, 40);
175
-
176
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
177
- ARMMMUIdxBit_Stage2);
178
-}
179
180
static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
181
uint64_t value)
182
@@ -XXX,XX +XXX,XX @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
183
tlb_flush_by_mmuidx(cs,
184
ARMMMUIdxBit_E10_1 |
185
ARMMMUIdxBit_E10_1_PAN |
186
- ARMMMUIdxBit_E10_0 |
187
- ARMMMUIdxBit_Stage2);
188
+ ARMMMUIdxBit_E10_0);
189
raw_write(env, ri, value);
190
}
191
}
192
@@ -XXX,XX +XXX,XX @@ static int alle1_tlbmask(CPUARMState *env)
193
return ARMMMUIdxBit_SE10_1 |
194
ARMMMUIdxBit_SE10_1_PAN |
195
ARMMMUIdxBit_SE10_0;
196
- } else if (arm_feature(env, ARM_FEATURE_EL2)) {
197
- return ARMMMUIdxBit_E10_1 |
198
- ARMMMUIdxBit_E10_1_PAN |
199
- ARMMMUIdxBit_E10_0 |
200
- ARMMMUIdxBit_Stage2;
201
} else {
202
return ARMMMUIdxBit_E10_1 |
203
ARMMMUIdxBit_E10_1_PAN |
204
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
205
ARMMMUIdxBit_SE3);
206
}
207
208
-static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri,
209
- uint64_t value)
210
-{
211
- /* Invalidate by IPA. This has to invalidate any structures that
212
- * contain only stage 2 translation information, but does not need
213
- * to apply to structures that contain combined stage 1 and stage 2
214
- * translation information.
215
- * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
216
- */
217
- ARMCPU *cpu = env_archcpu(env);
218
- CPUState *cs = CPU(cpu);
219
- uint64_t pageaddr;
220
-
221
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
222
- return;
223
- }
224
-
225
- pageaddr = sextract64(value << 12, 0, 48);
226
-
227
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
228
-}
229
-
230
-static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
231
- uint64_t value)
232
-{
233
- CPUState *cs = env_cpu(env);
234
- uint64_t pageaddr;
235
-
236
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
237
- return;
238
- }
239
-
240
- pageaddr = sextract64(value << 12, 0, 48);
241
-
242
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
243
- ARMMMUIdxBit_Stage2);
244
-}
245
-
246
static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
247
bool isread)
47
{
248
{
48
ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
249
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
49
250
.writefn = tlbi_aa64_vae1_write },
50
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
251
{ .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64,
51
mmu_idx |= ARM_MMU_IDX_M_PRIV;
252
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
52
}
253
- .access = PL2_W, .type = ARM_CP_NO_RAW,
53
254
- .writefn = tlbi_aa64_ipas2e1is_write },
54
- if (armv7m_nvic_neg_prio_requested(env->nvic, secstate)) {
255
+ .access = PL2_W, .type = ARM_CP_NOP },
55
+ if (negpri) {
256
{ .name = "TLBI_IPAS2LE1IS", .state = ARM_CP_STATE_AA64,
56
mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
257
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
57
}
258
- .access = PL2_W, .type = ARM_CP_NO_RAW,
58
259
- .writefn = tlbi_aa64_ipas2e1is_write },
59
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
260
+ .access = PL2_W, .type = ARM_CP_NOP },
60
return mmu_idx;
261
{ .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64,
61
}
262
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
62
263
.access = PL2_W, .type = ARM_CP_NO_RAW,
63
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
264
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
64
+ bool secstate, bool priv)
265
.writefn = tlbi_aa64_alle1is_write },
65
+{
266
{ .name = "TLBI_IPAS2E1", .state = ARM_CP_STATE_AA64,
66
+ bool negpri = armv7m_nvic_neg_prio_requested(env->nvic, secstate);
267
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
67
+
268
- .access = PL2_W, .type = ARM_CP_NO_RAW,
68
+ return arm_v7m_mmu_idx_all(env, secstate, priv, negpri);
269
- .writefn = tlbi_aa64_ipas2e1_write },
69
+}
270
+ .access = PL2_W, .type = ARM_CP_NOP },
70
+
271
{ .name = "TLBI_IPAS2LE1", .state = ARM_CP_STATE_AA64,
71
/* Return the MMU index for a v7M CPU in the specified security state */
272
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
72
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
273
- .access = PL2_W, .type = ARM_CP_NO_RAW,
73
{
274
- .writefn = tlbi_aa64_ipas2e1_write },
275
+ .access = PL2_W, .type = ARM_CP_NOP },
276
{ .name = "TLBI_ALLE1", .state = ARM_CP_STATE_AA64,
277
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4,
278
.access = PL2_W, .type = ARM_CP_NO_RAW,
279
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
280
.writefn = tlbimva_hyp_is_write },
281
{ .name = "TLBIIPAS2",
282
.cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
283
- .type = ARM_CP_NO_RAW, .access = PL2_W,
284
- .writefn = tlbiipas2_write },
285
+ .type = ARM_CP_NOP, .access = PL2_W },
286
{ .name = "TLBIIPAS2IS",
287
.cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
288
- .type = ARM_CP_NO_RAW, .access = PL2_W,
289
- .writefn = tlbiipas2_is_write },
290
+ .type = ARM_CP_NOP, .access = PL2_W },
291
{ .name = "TLBIIPAS2L",
292
.cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
293
- .type = ARM_CP_NO_RAW, .access = PL2_W,
294
- .writefn = tlbiipas2_write },
295
+ .type = ARM_CP_NOP, .access = PL2_W },
296
{ .name = "TLBIIPAS2LIS",
297
.cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
298
- .type = ARM_CP_NO_RAW, .access = PL2_W,
299
- .writefn = tlbiipas2_is_write },
300
+ .type = ARM_CP_NOP, .access = PL2_W },
301
/* 32 bit cache operations */
302
{ .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
303
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
74
--
304
--
75
2.20.1
305
2.20.1
76
306
77
307
diff view generated by jsdifflib
1
For v8M floating point support, transitions from Secure
1
The access_type argument to get_phys_addr_lpae() is an MMUAccessType;
2
to Non-secure state via BLNS and BLXNS must clear the
2
use the enum constant MMU_DATA_LOAD rather than a literal 0 when we
3
CONTROL.SFPA bit. (This corresponds to the pseudocode
3
call it in S1_ptw_translate().
4
BranchToNS() function.)
5
4
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-13-peter.maydell@linaro.org
8
Message-id: 20200330210400.11724-3-peter.maydell@linaro.org
9
---
9
---
10
target/arm/helper.c | 4 ++++
10
target/arm/helper.c | 5 +++--
11
1 file changed, 4 insertions(+)
11
1 file changed, 3 insertions(+), 2 deletions(-)
12
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
15
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest)
17
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
18
/* translate.c should have made BXNS UNDEF unless we're secure */
18
pcacheattrs = &cacheattrs;
19
assert(env->v7m.secure);
19
}
20
20
21
+ if (!(dest & 1)) {
21
- ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_Stage2, &s2pa,
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
22
- &txattrs, &s2prot, &s2size, fi, pcacheattrs);
23
+ }
23
+ ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
24
switch_v7m_security_state(env, dest & 1);
24
+ &s2pa, &txattrs, &s2prot, &s2size, fi,
25
env->thumb = 1;
25
+ pcacheattrs);
26
env->regs[15] = dest & ~1;
26
if (ret) {
27
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
27
assert(fi->type != ARMFault_None);
28
*/
28
fi->s2addr = addr;
29
write_v7m_exception(env, 1);
30
}
31
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
32
switch_v7m_security_state(env, 0);
33
env->thumb = 1;
34
env->regs[15] = dest;
35
--
29
--
36
2.20.1
30
2.20.1
37
31
38
32
diff view generated by jsdifflib
1
Currently the code in v7m_push_stack() which detects a violation
1
For ARMv8.2-TTS2UXN, the stage 2 page table walk wants to know
2
of the v8M stack limit simply returns early if it does so. This
2
whether the stage 1 access is for EL0 or not, because whether
3
is OK for the current integer-only code, but won't work for the
3
exec permission is given can depend on whether this is an EL0
4
floating point handling we're about to add. We need to continue
4
or EL1 access. Add a new argument to get_phys_addr_lpae() so
5
executing the rest of the function so that we check for other
5
the call sites can pass this information in.
6
exceptions like not having permission to use the FPU and so
6
7
that we correctly set the FPCCR state if we are doing lazy
7
Since get_phys_addr_lpae() doesn't already have a doc comment,
8
stacking. Refactor to avoid the early return.
8
add one so we have a place to put the documentation of the
9
semantics of the new s1_is_el0 argument.
9
10
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20190416125744.27770-10-peter.maydell@linaro.org
14
Message-id: 20200330210400.11724-4-peter.maydell@linaro.org
13
---
15
---
14
target/arm/helper.c | 23 ++++++++++++++++++-----
16
target/arm/helper.c | 29 ++++++++++++++++++++++++++++-
15
1 file changed, 18 insertions(+), 5 deletions(-)
17
1 file changed, 28 insertions(+), 1 deletion(-)
16
18
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
21
--- a/target/arm/helper.c
20
+++ b/target/arm/helper.c
22
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
23
@@ -XXX,XX +XXX,XX @@
22
* should ignore further stack faults trying to process
24
23
* that derived exception.)
25
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
24
*/
26
MMUAccessType access_type, ARMMMUIdx mmu_idx,
25
- bool stacked_ok;
27
+ bool s1_is_el0,
26
+ bool stacked_ok = true, limitviol = false;
28
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
27
CPUARMState *env = &cpu->env;
29
target_ulong *page_size_ptr,
28
uint32_t xpsr = xpsr_read(env);
30
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs);
29
uint32_t frameptr = env->regs[13];
31
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
30
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
31
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
32
env->v7m.secure);
33
env->regs[13] = limit;
34
- return true;
35
+ /*
36
+ * We won't try to perform any further memory accesses but
37
+ * we must continue through the following code to check for
38
+ * permission faults during FPU state preservation, and we
39
+ * must update FPCCR if lazy stacking is enabled.
40
+ */
41
+ limitviol = true;
42
+ stacked_ok = false;
43
}
32
}
33
34
ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
35
+ false,
36
&s2pa, &txattrs, &s2prot, &s2size, fi,
37
pcacheattrs);
38
if (ret) {
39
@@ -XXX,XX +XXX,XX @@ static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
40
};
41
}
42
43
+/**
44
+ * get_phys_addr_lpae: perform one stage of page table walk, LPAE format
45
+ *
46
+ * Returns false if the translation was successful. Otherwise, phys_ptr, attrs,
47
+ * prot and page_size may not be filled in, and the populated fsr value provides
48
+ * information on why the translation aborted, in the format of a long-format
49
+ * DFSR/IFSR fault register, with the following caveats:
50
+ * * the WnR bit is never set (the caller must do this).
51
+ *
52
+ * @env: CPUARMState
53
+ * @address: virtual address to get physical address for
54
+ * @access_type: MMU_DATA_LOAD, MMU_DATA_STORE or MMU_INST_FETCH
55
+ * @mmu_idx: MMU index indicating required translation regime
56
+ * @s1_is_el0: if @mmu_idx is ARMMMUIdx_Stage2 (so this is a stage 2 page table
57
+ * walk), must be true if this is stage 2 of a stage 1+2 walk for an
58
+ * EL0 access). If @mmu_idx is anything else, @s1_is_el0 is ignored.
59
+ * @phys_ptr: set to the physical address corresponding to the virtual address
60
+ * @attrs: set to the memory transaction attributes to use
61
+ * @prot: set to the permissions for the page containing phys_ptr
62
+ * @page_size_ptr: set to the size of the page containing phys_ptr
63
+ * @fi: set to fault info if the translation fails
64
+ * @cacheattrs: (if non-NULL) set to the cacheability/shareability attributes
65
+ */
66
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
67
MMUAccessType access_type, ARMMMUIdx mmu_idx,
68
+ bool s1_is_el0,
69
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
70
target_ulong *page_size_ptr,
71
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
72
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
73
74
/* S1 is done. Now do S2 translation. */
75
ret = get_phys_addr_lpae(env, ipa, access_type, ARMMMUIdx_Stage2,
76
+ mmu_idx == ARMMMUIdx_E10_0,
77
phys_ptr, attrs, &s2_prot,
78
page_size, fi,
79
cacheattrs != NULL ? &cacheattrs2 : NULL);
80
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
44
}
81
}
45
82
46
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
83
if (regime_using_lpae_format(env, mmu_idx)) {
47
* (which may be taken in preference to the one we started with
84
- return get_phys_addr_lpae(env, address, access_type, mmu_idx,
48
* if it has higher priority).
85
+ return get_phys_addr_lpae(env, address, access_type, mmu_idx, false,
49
*/
86
phys_ptr, attrs, prot, page_size,
50
- stacked_ok =
87
fi, cacheattrs);
51
+ stacked_ok = stacked_ok &&
88
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
52
v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, false) &&
53
v7m_stack_write(cpu, frameptr + 4, env->regs[1], mmu_idx, false) &&
54
v7m_stack_write(cpu, frameptr + 8, env->regs[2], mmu_idx, false) &&
55
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
56
v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
57
v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
58
59
- /* Update SP regardless of whether any of the stack accesses failed. */
60
- env->regs[13] = frameptr;
61
+ /*
62
+ * If we broke a stack limit then SP was already updated earlier;
63
+ * otherwise we update SP regardless of whether any of the stack
64
+ * accesses failed or we took some other kind of fault.
65
+ */
66
+ if (!limitviol) {
67
+ env->regs[13] = frameptr;
68
+ }
69
70
return !stacked_ok;
71
}
72
--
89
--
73
2.20.1
90
2.20.1
74
91
75
92
diff view generated by jsdifflib
1
Implement the code which updates the FPCCR register on an
1
The ARMv8.2-TTS2UXN feature extends the XN field in stage 2
2
exception entry where we are going to use lazy FP stacking.
2
translation table descriptors from just bit [54] to bits [54:53],
3
We have to defer to the NVIC to determine whether the
3
allowing stage 2 to control execution permissions separately for EL0
4
various exceptions are currently ready or not.
4
and EL1. Implement the new semantics of the XN field and enable
5
the feature for our 'max' CPU.
5
6
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20190416125744.27770-12-peter.maydell@linaro.org
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20200330210400.11724-5-peter.maydell@linaro.org
8
---
11
---
9
target/arm/cpu.h | 14 +++++++++
12
target/arm/cpu.h | 15 +++++++++++++++
10
hw/intc/armv7m_nvic.c | 34 ++++++++++++++++++++++
13
target/arm/cpu.c | 1 +
11
target/arm/helper.c | 67 ++++++++++++++++++++++++++++++++++++++++++-
14
target/arm/cpu64.c | 2 ++
12
3 files changed, 114 insertions(+), 1 deletion(-)
15
target/arm/helper.c | 37 +++++++++++++++++++++++++++++++------
16
4 files changed, 49 insertions(+), 6 deletions(-)
13
17
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
20
--- a/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_acknowledge_irq(void *opaque);
22
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_ccidx(const ARMISARegisters *id)
19
* (Ignoring -1, this is the same as the RETTOBASE value before completion.)
23
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, CCIDX) != 0;
20
*/
21
int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure);
22
+/**
23
+ * armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
24
+ * @opaque: the NVIC
25
+ * @irq: the exception number to mark pending
26
+ * @secure: false for non-banked exceptions or for the nonsecure
27
+ * version of a banked exception, true for the secure version of a banked
28
+ * exception.
29
+ *
30
+ * Return whether an exception is "ready", i.e. whether the exception is
31
+ * enabled and is configured at a priority which would allow it to
32
+ * interrupt the current execution priority. This controls whether the
33
+ * RDY bit for it in the FPCCR is set.
34
+ */
35
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure);
36
/**
37
* armv7m_nvic_raw_execution_priority: return the raw execution priority
38
* @opaque: the NVIC
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
}
24
}
46
25
47
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
26
+static inline bool isar_feature_aa32_tts2uxn(const ARMISARegisters *id)
48
+{
27
+{
49
+ /*
28
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, XNX) != 0;
50
+ * Return whether an exception is "ready", i.e. it is enabled and is
51
+ * configured at a priority which would allow it to interrupt the
52
+ * current execution priority.
53
+ *
54
+ * irq and secure have the same semantics as for armv7m_nvic_set_pending():
55
+ * for non-banked exceptions secure is always false; for banked exceptions
56
+ * it indicates which of the exceptions is required.
57
+ */
58
+ NVICState *s = (NVICState *)opaque;
59
+ bool banked = exc_is_banked(irq);
60
+ VecInfo *vec;
61
+ int running = nvic_exec_prio(s);
62
+
63
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
64
+ assert(!secure || banked);
65
+
66
+ /*
67
+ * HardFault is an odd special case: we always check against -1,
68
+ * even if we're secure and HardFault has priority -3; we never
69
+ * need to check for enabled state.
70
+ */
71
+ if (irq == ARMV7M_EXCP_HARD) {
72
+ return running > -1;
73
+ }
74
+
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
76
+
77
+ return vec->enabled &&
78
+ exc_group_prio(s, vec->prio, secure) < running;
79
+}
29
+}
80
+
30
+
81
/* callback when external interrupt line is changed */
31
/*
82
static void set_irq_level(void *opaque, int n, int level)
32
* 64-bit feature tests via id registers.
83
{
33
*/
34
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
35
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
36
}
37
38
+static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
39
+{
40
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
41
+}
42
+
43
/*
44
* Feature tests for "does this exist in either 32-bit or 64-bit?"
45
*/
46
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_ccidx(const ARMISARegisters *id)
47
return isar_feature_aa64_ccidx(id) || isar_feature_aa32_ccidx(id);
48
}
49
50
+static inline bool isar_feature_any_tts2uxn(const ARMISARegisters *id)
51
+{
52
+ return isar_feature_aa64_tts2uxn(id) || isar_feature_aa32_tts2uxn(id);
53
+}
54
+
55
/*
56
* Forward to the above feature tests given an ARMCPU pointer.
57
*/
58
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/cpu.c
61
+++ b/target/arm/cpu.c
62
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
63
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
64
t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
65
t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
66
+ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
67
cpu->isar.id_mmfr4 = t;
68
}
69
#endif
70
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/arm/cpu64.c
73
+++ b/target/arm/cpu64.c
74
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
75
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1);
76
t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */
77
t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */
78
+ t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* TTS2UXN */
79
cpu->isar.id_aa64mmfr1 = t;
80
81
t = cpu->isar.id_aa64mmfr2;
82
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
83
u = FIELD_DP32(u, ID_MMFR4, HPDS, 1); /* AA32HPD */
84
u = FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
85
u = FIELD_DP32(u, ID_MMFR4, CNP, 1); /* TTCNP */
86
+ u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
87
cpu->isar.id_mmfr4 = u;
88
89
u = cpu->isar.id_aa64dfr0;
84
diff --git a/target/arm/helper.c b/target/arm/helper.c
90
diff --git a/target/arm/helper.c b/target/arm/helper.c
85
index XXXXXXX..XXXXXXX 100644
91
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/helper.c
92
--- a/target/arm/helper.c
87
+++ b/target/arm/helper.c
93
+++ b/target/arm/helper.c
88
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
94
@@ -XXX,XX +XXX,XX @@ simple_ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, int ap)
89
env->thumb = addr & 1;
95
*
90
}
96
* @env: CPUARMState
91
97
* @s2ap: The 2-bit stage2 access permissions (S2AP)
92
+static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
98
- * @xn: XN (execute-never) bit
93
+ bool apply_splim)
99
+ * @xn: XN (execute-never) bits
94
+{
100
+ * @s1_is_el0: true if this is S2 of an S1+2 walk for EL0
95
+ /*
101
*/
96
+ * Like the pseudocode UpdateFPCCR: save state in FPCAR and FPCCR
102
-static int get_S2prot(CPUARMState *env, int s2ap, int xn)
97
+ * that we will need later in order to do lazy FP reg stacking.
103
+static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
98
+ */
104
{
99
+ bool is_secure = env->v7m.secure;
105
int prot = 0;
100
+ void *nvic = env->nvic;
106
101
+ /*
107
@@ -XXX,XX +XXX,XX @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn)
102
+ * Some bits are unbanked and live always in fpccr[M_REG_S]; some bits
108
if (s2ap & 2) {
103
+ * are banked and we want to update the bit in the bank for the
109
prot |= PAGE_WRITE;
104
+ * current security state; and in one case we want to specifically
110
}
105
+ * update the NS banked version of a bit even if we are secure.
111
- if (!xn) {
106
+ */
112
- if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
107
+ uint32_t *fpccr_s = &env->v7m.fpccr[M_REG_S];
108
+ uint32_t *fpccr_ns = &env->v7m.fpccr[M_REG_NS];
109
+ uint32_t *fpccr = &env->v7m.fpccr[is_secure];
110
+ bool hfrdy, bfrdy, mmrdy, ns_ufrdy, s_ufrdy, sfrdy, monrdy;
111
+
113
+
112
+ env->v7m.fpcar[is_secure] = frameptr & ~0x7;
114
+ if (cpu_isar_feature(any_tts2uxn, env_archcpu(env))) {
113
+
115
+ switch (xn) {
114
+ if (apply_splim && arm_feature(env, ARM_FEATURE_V8)) {
116
+ case 0:
115
+ bool splimviol;
117
prot |= PAGE_EXEC;
116
+ uint32_t splim = v7m_sp_limit(env);
118
+ break;
117
+ bool ign = armv7m_nvic_neg_prio_requested(nvic, is_secure) &&
119
+ case 1:
118
+ (env->v7m.ccr[is_secure] & R_V7M_CCR_STKOFHFNMIGN_MASK);
120
+ if (s1_is_el0) {
119
+
121
+ prot |= PAGE_EXEC;
120
+ splimviol = !ign && frameptr < splim;
122
+ }
121
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, SPLIMVIOL, splimviol);
123
+ break;
122
+ }
124
+ case 2:
123
+
125
+ break;
124
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, LSPACT, 1);
126
+ case 3:
125
+
127
+ if (!s1_is_el0) {
126
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, S, is_secure);
128
+ prot |= PAGE_EXEC;
127
+
129
+ }
128
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, USER, arm_current_el(env) == 0);
130
+ break;
129
+
131
+ default:
130
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, THREAD,
132
+ g_assert_not_reached();
131
+ !arm_v7m_is_handler_mode(env));
133
+ }
132
+
134
+ } else {
133
+ hfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_HARD, false);
135
+ if (!extract32(xn, 1, 1)) {
134
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, HFRDY, hfrdy);
136
+ if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
135
+
137
+ prot |= PAGE_EXEC;
136
+ bfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_BUS, false);
138
+ }
137
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, BFRDY, bfrdy);
138
+
139
+ mmrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_MEM, is_secure);
140
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, MMRDY, mmrdy);
141
+
142
+ ns_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, false);
143
+ *fpccr_ns = FIELD_DP32(*fpccr_ns, V7M_FPCCR, UFRDY, ns_ufrdy);
144
+
145
+ monrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_DEBUG, false);
146
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, MONRDY, monrdy);
147
+
148
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
149
+ s_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, true);
150
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, UFRDY, s_ufrdy);
151
+
152
+ sfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_SECURE, false);
153
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, SFRDY, sfrdy);
154
+ }
155
+}
156
+
157
static bool v7m_push_stack(ARMCPU *cpu)
158
{
159
/* Do the "set up stack frame" part of exception entry,
160
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
161
}
162
} else {
163
/* Lazy stacking enabled, save necessary info to stack later */
164
- /* TODO : equivalent of UpdateFPCCR() pseudocode */
165
+ v7m_update_fpccr(env, frameptr + 0x20, true);
166
}
167
}
139
}
140
}
141
return prot;
142
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
143
}
144
145
ap = extract32(attrs, 4, 2);
146
- xn = extract32(attrs, 12, 1);
147
148
if (mmu_idx == ARMMMUIdx_Stage2) {
149
ns = true;
150
- *prot = get_S2prot(env, ap, xn);
151
+ xn = extract32(attrs, 11, 2);
152
+ *prot = get_S2prot(env, ap, xn, s1_is_el0);
153
} else {
154
ns = extract32(attrs, 3, 1);
155
+ xn = extract32(attrs, 12, 1);
156
pxn = extract32(attrs, 11, 1);
157
*prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
168
}
158
}
169
--
159
--
170
2.20.1
160
2.20.1
171
161
172
162
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
In aarch64_max_initfn() we update both 32-bit and 64-bit ID
2
registers. The intended pattern is that for 64-bit ID registers we
3
use FIELD_DP64 and the uint64_t 't' register, while 32-bit ID
4
registers use FIELD_DP32 and the uint32_t 'u' register. For
5
ID_AA64DFR0 we accidentally used 'u', meaning that the top 32 bits of
6
this 64-bit ID register would end up always zero. Luckily at the
7
moment that's what they should be anyway, so this bug has no visible
8
effects.
2
9
3
This commit finally deletes "hw/devices.h".
10
Use the right-sized variable.
4
11
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
12
Fixes: 3bec78447a958d481991
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Message-id: 20190412165416.7977-13-philmd@redhat.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Message-id: 20200423110915.10527-1-peter.maydell@linaro.org
9
---
17
---
10
include/hw/devices.h | 11 -----------
18
target/arm/cpu64.c | 6 +++---
11
include/hw/net/smc91c111.h | 19 +++++++++++++++++++
19
1 file changed, 3 insertions(+), 3 deletions(-)
12
hw/arm/gumstix.c | 2 +-
13
hw/arm/integratorcp.c | 2 +-
14
hw/arm/mainstone.c | 2 +-
15
hw/arm/realview.c | 2 +-
16
hw/arm/versatilepb.c | 2 +-
17
hw/net/smc91c111.c | 2 +-
18
8 files changed, 25 insertions(+), 17 deletions(-)
19
delete mode 100644 include/hw/devices.h
20
create mode 100644 include/hw/net/smc91c111.h
21
20
22
diff --git a/include/hw/devices.h b/include/hw/devices.h
21
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
23
deleted file mode 100644
24
index XXXXXXX..XXXXXXX
25
--- a/include/hw/devices.h
26
+++ /dev/null
27
@@ -XXX,XX +XXX,XX @@
28
-#ifndef QEMU_DEVICES_H
29
-#define QEMU_DEVICES_H
30
-
31
-/* Devices that have nowhere better to go. */
32
-
33
-#include "hw/hw.h"
34
-
35
-/* smc91c111.c */
36
-void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
37
-
38
-#endif
39
diff --git a/include/hw/net/smc91c111.h b/include/hw/net/smc91c111.h
40
new file mode 100644
41
index XXXXXXX..XXXXXXX
42
--- /dev/null
43
+++ b/include/hw/net/smc91c111.h
44
@@ -XXX,XX +XXX,XX @@
45
+/*
46
+ * SMSC 91C111 Ethernet interface emulation
47
+ *
48
+ * Copyright (c) 2005 CodeSourcery, LLC.
49
+ * Written by Paul Brook
50
+ *
51
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
52
+ * See the COPYING file in the top-level directory.
53
+ */
54
+
55
+#ifndef HW_NET_SMC91C111_H
56
+#define HW_NET_SMC91C111_H
57
+
58
+#include "hw/irq.h"
59
+#include "net/net.h"
60
+
61
+void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
62
+
63
+#endif
64
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
65
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
66
--- a/hw/arm/gumstix.c
23
--- a/target/arm/cpu64.c
67
+++ b/hw/arm/gumstix.c
24
+++ b/target/arm/cpu64.c
68
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
69
#include "hw/arm/pxa.h"
26
u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
70
#include "net/net.h"
27
cpu->isar.id_mmfr4 = u;
71
#include "hw/block/flash.h"
28
72
-#include "hw/devices.h"
29
- u = cpu->isar.id_aa64dfr0;
73
+#include "hw/net/smc91c111.h"
30
- u = FIELD_DP64(u, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
74
#include "hw/boards.h"
31
- cpu->isar.id_aa64dfr0 = u;
75
#include "exec/address-spaces.h"
32
+ t = cpu->isar.id_aa64dfr0;
76
#include "sysemu/qtest.h"
33
+ t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
77
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
34
+ cpu->isar.id_aa64dfr0 = t;
78
index XXXXXXX..XXXXXXX 100644
35
79
--- a/hw/arm/integratorcp.c
36
u = cpu->isar.id_dfr0;
80
+++ b/hw/arm/integratorcp.c
37
u = FIELD_DP32(u, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
81
@@ -XXX,XX +XXX,XX @@
82
#include "qemu-common.h"
83
#include "cpu.h"
84
#include "hw/sysbus.h"
85
-#include "hw/devices.h"
86
#include "hw/boards.h"
87
#include "hw/arm/arm.h"
88
#include "hw/misc/arm_integrator_debug.h"
89
+#include "hw/net/smc91c111.h"
90
#include "net/net.h"
91
#include "exec/address-spaces.h"
92
#include "sysemu/sysemu.h"
93
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/hw/arm/mainstone.c
96
+++ b/hw/arm/mainstone.c
97
@@ -XXX,XX +XXX,XX @@
98
#include "hw/arm/pxa.h"
99
#include "hw/arm/arm.h"
100
#include "net/net.h"
101
-#include "hw/devices.h"
102
+#include "hw/net/smc91c111.h"
103
#include "hw/boards.h"
104
#include "hw/block/flash.h"
105
#include "hw/sysbus.h"
106
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/hw/arm/realview.c
109
+++ b/hw/arm/realview.c
110
@@ -XXX,XX +XXX,XX @@
111
#include "hw/sysbus.h"
112
#include "hw/arm/arm.h"
113
#include "hw/arm/primecell.h"
114
-#include "hw/devices.h"
115
#include "hw/net/lan9118.h"
116
+#include "hw/net/smc91c111.h"
117
#include "hw/pci/pci.h"
118
#include "net/net.h"
119
#include "sysemu/sysemu.h"
120
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
121
index XXXXXXX..XXXXXXX 100644
122
--- a/hw/arm/versatilepb.c
123
+++ b/hw/arm/versatilepb.c
124
@@ -XXX,XX +XXX,XX @@
125
#include "cpu.h"
126
#include "hw/sysbus.h"
127
#include "hw/arm/arm.h"
128
-#include "hw/devices.h"
129
+#include "hw/net/smc91c111.h"
130
#include "net/net.h"
131
#include "sysemu/sysemu.h"
132
#include "hw/pci/pci.h"
133
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/hw/net/smc91c111.c
136
+++ b/hw/net/smc91c111.c
137
@@ -XXX,XX +XXX,XX @@
138
#include "qemu/osdep.h"
139
#include "hw/sysbus.h"
140
#include "net/net.h"
141
-#include "hw/devices.h"
142
+#include "hw/net/smc91c111.h"
143
#include "qemu/log.h"
144
/* For crc32 */
145
#include <zlib.h>
146
--
38
--
147
2.20.1
39
2.20.1
148
40
149
41
diff view generated by jsdifflib
1
The M-profile floating point support has three associated config
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
registers: FPCAR, FPCCR and FPDSCR. It also makes the registers
3
CPACR and NSACR have behaviour other than reads-as-zero.
4
Add support for all of these as simple reads-as-written registers.
5
We will hook up actual functionality later.
6
2
7
The main complexity here is handling the FPCCR register, which
3
MIDR_EL1 is a 64-bit system register with the top 32-bit being RES0.
8
has a mix of banked and unbanked bits.
4
Represent it in QEMU's ARMCPU struct with a uint64_t, not a
5
uint32_t.
9
6
10
Note that we don't share storage with the A-profile
7
This fixes an error when compiling with -Werror=conversion
11
cpu->cp15.nsacr and cpu->cp15.cpacr_el1, though the behaviour
8
because we were manipulating the register value using a
12
is quite similar, for two reasons:
9
local uint64_t variable:
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
16
10
11
target/arm/cpu64.c: In function ‘aarch64_max_initfn’:
12
target/arm/cpu64.c:628:21: error: conversion from ‘uint64_t’ {aka ‘long unsigned int’} to ‘uint32_t’ {aka ‘unsigned int’} may change value [-Werror=conversion]
13
628 | cpu->midr = t;
14
| ^
15
16
and future-proofs us against a possible future architecture
17
change using some of the top 32 bits.
18
19
Suggested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
20
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
23
Message-id: 20200428172634.29707-1-f4bug@amsat.org
24
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20190416125744.27770-4-peter.maydell@linaro.org
20
---
26
---
21
target/arm/cpu.h | 34 ++++++++++++
27
target/arm/cpu.h | 2 +-
22
hw/intc/armv7m_nvic.c | 125 ++++++++++++++++++++++++++++++++++++++++++
28
target/arm/cpu.c | 2 +-
23
target/arm/cpu.c | 5 ++
29
2 files changed, 2 insertions(+), 2 deletions(-)
24
target/arm/machine.c | 16 ++++++
25
4 files changed, 180 insertions(+)
26
30
27
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
31
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
28
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/cpu.h
33
--- a/target/arm/cpu.h
30
+++ b/target/arm/cpu.h
34
+++ b/target/arm/cpu.h
31
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
35
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
32
uint32_t scr[M_REG_NUM_BANKS];
36
uint64_t id_aa64dfr0;
33
uint32_t msplim[M_REG_NUM_BANKS];
37
uint64_t id_aa64dfr1;
34
uint32_t psplim[M_REG_NUM_BANKS];
38
} isar;
35
+ uint32_t fpcar[M_REG_NUM_BANKS];
39
- uint32_t midr;
36
+ uint32_t fpccr[M_REG_NUM_BANKS];
40
+ uint64_t midr;
37
+ uint32_t fpdscr[M_REG_NUM_BANKS];
41
uint32_t revidr;
38
+ uint32_t cpacr[M_REG_NUM_BANKS];
42
uint32_t reset_fpsid;
39
+ uint32_t nsacr;
43
uint32_t ctr;
40
} v7m;
41
42
/* Information associated with an exception about to be taken:
43
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_CSSELR, LEVEL, 1, 3)
44
*/
45
FIELD(V7M_CSSELR, INDEX, 0, 4)
46
47
+/* v7M FPCCR bits */
48
+FIELD(V7M_FPCCR, LSPACT, 0, 1)
49
+FIELD(V7M_FPCCR, USER, 1, 1)
50
+FIELD(V7M_FPCCR, S, 2, 1)
51
+FIELD(V7M_FPCCR, THREAD, 3, 1)
52
+FIELD(V7M_FPCCR, HFRDY, 4, 1)
53
+FIELD(V7M_FPCCR, MMRDY, 5, 1)
54
+FIELD(V7M_FPCCR, BFRDY, 6, 1)
55
+FIELD(V7M_FPCCR, SFRDY, 7, 1)
56
+FIELD(V7M_FPCCR, MONRDY, 8, 1)
57
+FIELD(V7M_FPCCR, SPLIMVIOL, 9, 1)
58
+FIELD(V7M_FPCCR, UFRDY, 10, 1)
59
+FIELD(V7M_FPCCR, RES0, 11, 15)
60
+FIELD(V7M_FPCCR, TS, 26, 1)
61
+FIELD(V7M_FPCCR, CLRONRETS, 27, 1)
62
+FIELD(V7M_FPCCR, CLRONRET, 28, 1)
63
+FIELD(V7M_FPCCR, LSPENS, 29, 1)
64
+FIELD(V7M_FPCCR, LSPEN, 30, 1)
65
+FIELD(V7M_FPCCR, ASPEN, 31, 1)
66
+/* These bits are banked. Others are non-banked and live in the M_REG_S bank */
67
+#define R_V7M_FPCCR_BANKED_MASK \
68
+ (R_V7M_FPCCR_LSPACT_MASK | \
69
+ R_V7M_FPCCR_USER_MASK | \
70
+ R_V7M_FPCCR_THREAD_MASK | \
71
+ R_V7M_FPCCR_MMRDY_MASK | \
72
+ R_V7M_FPCCR_SPLIMVIOL_MASK | \
73
+ R_V7M_FPCCR_UFRDY_MASK | \
74
+ R_V7M_FPCCR_ASPEN_MASK)
75
+
76
/*
77
* System register ID fields.
78
*/
79
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
80
index XXXXXXX..XXXXXXX 100644
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
44
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
237
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
238
--- a/target/arm/cpu.c
46
--- a/target/arm/cpu.c
239
+++ b/target/arm/cpu.c
47
+++ b/target/arm/cpu.c
240
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
48
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
241
env->v7m.ccr[M_REG_S] |= R_V7M_CCR_UNALIGN_TRP_MASK;
49
static Property arm_cpu_properties[] = {
242
}
50
DEFINE_PROP_BOOL("start-powered-off", ARMCPU, start_powered_off, false),
243
51
DEFINE_PROP_UINT32("psci-conduit", ARMCPU, psci_conduit, 0),
244
+ if (arm_feature(env, ARM_FEATURE_VFP)) {
52
- DEFINE_PROP_UINT32("midr", ARMCPU, midr, 0),
245
+ env->v7m.fpccr[M_REG_NS] = R_V7M_FPCCR_ASPEN_MASK;
53
+ DEFINE_PROP_UINT64("midr", ARMCPU, midr, 0),
246
+ env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK |
54
DEFINE_PROP_UINT64("mp-affinity", ARMCPU,
247
+ R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK;
55
mp_affinity, ARM64_AFFINITY_INVALID),
248
+ }
56
DEFINE_PROP_INT32("node-id", ARMCPU, node_id, CPU_UNSET_NUMA_NODE_ID),
249
/* Unlike A/R profile, M profile defines the reset LR value */
250
env->regs[14] = 0xffffffff;
251
252
diff --git a/target/arm/machine.c b/target/arm/machine.c
253
index XXXXXXX..XXXXXXX 100644
254
--- a/target/arm/machine.c
255
+++ b/target/arm/machine.c
256
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_v8m = {
257
}
258
};
259
260
+static const VMStateDescription vmstate_m_fp = {
261
+ .name = "cpu/m/fp",
262
+ .version_id = 1,
263
+ .minimum_version_id = 1,
264
+ .needed = vfp_needed,
265
+ .fields = (VMStateField[]) {
266
+ VMSTATE_UINT32_ARRAY(env.v7m.fpcar, ARMCPU, M_REG_NUM_BANKS),
267
+ VMSTATE_UINT32_ARRAY(env.v7m.fpccr, ARMCPU, M_REG_NUM_BANKS),
268
+ VMSTATE_UINT32_ARRAY(env.v7m.fpdscr, ARMCPU, M_REG_NUM_BANKS),
269
+ VMSTATE_UINT32_ARRAY(env.v7m.cpacr, ARMCPU, M_REG_NUM_BANKS),
270
+ VMSTATE_UINT32(env.v7m.nsacr, ARMCPU),
271
+ VMSTATE_END_OF_LIST()
272
+ }
273
+};
274
+
275
static const VMStateDescription vmstate_m = {
276
.name = "cpu/m",
277
.version_id = 4,
278
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
279
&vmstate_m_scr,
280
&vmstate_m_other_sp,
281
&vmstate_m_v8m,
282
+ &vmstate_m_fp,
283
NULL
284
}
285
};
286
--
57
--
287
2.20.1
58
2.20.1
288
59
289
60
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
Remove inclusion of arm_gicv3_common.h, this already gets
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
included via xlnx-versal.h.
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
6
Message-id: 20190412165416.7977-11-philmd@redhat.com
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-2-edgar.iglesias@gmail.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
11
---
9
include/hw/net/ne2000-isa.h | 6 ++++++
12
hw/arm/xlnx-versal.c | 1 -
10
1 file changed, 6 insertions(+)
13
1 file changed, 1 deletion(-)
11
14
12
diff --git a/include/hw/net/ne2000-isa.h b/include/hw/net/ne2000-isa.h
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/net/ne2000-isa.h
17
--- a/hw/arm/xlnx-versal.c
15
+++ b/include/hw/net/ne2000-isa.h
18
+++ b/hw/arm/xlnx-versal.c
16
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
17
* This work is licensed under the terms of the GNU GPL, version 2 or later.
20
#include "hw/arm/boot.h"
18
* See the COPYING file in the top-level directory.
21
#include "kvm_arm.h"
19
*/
22
#include "hw/misc/unimp.h"
20
+
23
-#include "hw/intc/arm_gicv3_common.h"
21
+#ifndef HW_NET_NE2K_ISA_H
24
#include "hw/arm/xlnx-versal.h"
22
+#define HW_NET_NE2K_ISA_H
25
#include "hw/char/pl011.h"
23
+
26
24
#include "hw/hw.h"
25
#include "hw/qdev.h"
26
#include "hw/isa/isa.h"
27
@@ -XXX,XX +XXX,XX @@ static inline ISADevice *isa_ne2000_init(ISABus *bus, int base, int irq,
28
}
29
return d;
30
}
31
+
32
+#endif
33
--
27
--
34
2.20.1
28
2.20.1
35
29
36
30
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
Move misplaced comment.
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
5
Message-id: 20190412165416.7977-10-philmd@redhat.com
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-3-edgar.iglesias@gmail.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
include/hw/devices.h | 3 ---
12
hw/arm/xlnx-versal.c | 2 +-
9
include/hw/net/lan9118.h | 19 +++++++++++++++++++
13
1 file changed, 1 insertion(+), 1 deletion(-)
10
hw/arm/kzm.c | 2 +-
11
hw/arm/mps2.c | 2 +-
12
hw/arm/realview.c | 1 +
13
hw/arm/vexpress.c | 2 +-
14
hw/net/lan9118.c | 2 +-
15
7 files changed, 24 insertions(+), 7 deletions(-)
16
create mode 100644 include/hw/net/lan9118.h
17
14
18
diff --git a/include/hw/devices.h b/include/hw/devices.h
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/devices.h
17
--- a/hw/arm/xlnx-versal.c
21
+++ b/include/hw/devices.h
18
+++ b/hw/arm/xlnx-versal.c
22
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
23
/* smc91c111.c */
20
24
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
21
obj = object_new(XLNX_VERSAL_ACPU_TYPE);
25
22
if (!obj) {
26
-/* lan9118.c */
23
- /* Secondary CPUs start in PSCI powered-down state */
27
-void lan9118_init(NICInfo *, uint32_t, qemu_irq);
24
error_report("Unable to create apu.cpu[%d] of type %s",
28
-
25
i, XLNX_VERSAL_ACPU_TYPE);
29
#endif
26
exit(EXIT_FAILURE);
30
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
27
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
31
new file mode 100644
28
object_property_set_int(obj, s->cfg.psci_conduit,
32
index XXXXXXX..XXXXXXX
29
"psci-conduit", &error_abort);
33
--- /dev/null
30
if (i) {
34
+++ b/include/hw/net/lan9118.h
31
+ /* Secondary CPUs start in PSCI powered-down state */
35
@@ -XXX,XX +XXX,XX @@
32
object_property_set_bool(obj, true,
36
+/*
33
"start-powered-off", &error_abort);
37
+ * SMSC LAN9118 Ethernet interface emulation
34
}
38
+ *
39
+ * Copyright (c) 2009 CodeSourcery, LLC.
40
+ * Written by Paul Brook
41
+ *
42
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
43
+ * See the COPYING file in the top-level directory.
44
+ */
45
+
46
+#ifndef HW_NET_LAN9118_H
47
+#define HW_NET_LAN9118_H
48
+
49
+#include "hw/irq.h"
50
+#include "net/net.h"
51
+
52
+void lan9118_init(NICInfo *, uint32_t, qemu_irq);
53
+
54
+#endif
55
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/kzm.c
58
+++ b/hw/arm/kzm.c
59
@@ -XXX,XX +XXX,XX @@
60
#include "qemu/error-report.h"
61
#include "exec/address-spaces.h"
62
#include "net/net.h"
63
-#include "hw/devices.h"
64
+#include "hw/net/lan9118.h"
65
#include "hw/char/serial.h"
66
#include "sysemu/qtest.h"
67
68
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/arm/mps2.c
71
+++ b/hw/arm/mps2.c
72
@@ -XXX,XX +XXX,XX @@
73
#include "hw/timer/cmsdk-apb-timer.h"
74
#include "hw/timer/cmsdk-apb-dualtimer.h"
75
#include "hw/misc/mps2-scc.h"
76
-#include "hw/devices.h"
77
+#include "hw/net/lan9118.h"
78
#include "net/net.h"
79
80
typedef enum MPS2FPGAType {
81
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/hw/arm/realview.c
84
+++ b/hw/arm/realview.c
85
@@ -XXX,XX +XXX,XX @@
86
#include "hw/arm/arm.h"
87
#include "hw/arm/primecell.h"
88
#include "hw/devices.h"
89
+#include "hw/net/lan9118.h"
90
#include "hw/pci/pci.h"
91
#include "net/net.h"
92
#include "sysemu/sysemu.h"
93
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/hw/arm/vexpress.c
96
+++ b/hw/arm/vexpress.c
97
@@ -XXX,XX +XXX,XX @@
98
#include "hw/sysbus.h"
99
#include "hw/arm/arm.h"
100
#include "hw/arm/primecell.h"
101
-#include "hw/devices.h"
102
+#include "hw/net/lan9118.h"
103
#include "hw/i2c/i2c.h"
104
#include "net/net.h"
105
#include "sysemu/sysemu.h"
106
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/hw/net/lan9118.c
109
+++ b/hw/net/lan9118.c
110
@@ -XXX,XX +XXX,XX @@
111
#include "hw/sysbus.h"
112
#include "net/net.h"
113
#include "net/eth.h"
114
-#include "hw/devices.h"
115
+#include "hw/net/lan9118.h"
116
#include "sysemu/sysemu.h"
117
#include "hw/ptimer.h"
118
#include "qemu/log.h"
119
--
35
--
120
2.20.1
36
2.20.1
121
37
122
38
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
Since uWireSlave is only used in this new header, there is no
3
Fix typo xlnx-ve -> xlnx-versal.
4
need to expose it via "qemu/typedefs.h".
5
4
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20190412165416.7977-9-philmd@redhat.com
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-4-edgar.iglesias@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
include/hw/arm/omap.h | 6 +-----
12
hw/arm/xlnx-versal-virt.c | 2 +-
12
include/hw/devices.h | 15 ---------------
13
1 file changed, 1 insertion(+), 1 deletion(-)
13
include/hw/input/tsc2xxx.h | 36 ++++++++++++++++++++++++++++++++++++
14
include/qemu/typedefs.h | 1 -
15
hw/arm/nseries.c | 2 +-
16
hw/arm/palm.c | 2 +-
17
hw/input/tsc2005.c | 2 +-
18
hw/input/tsc210x.c | 4 ++--
19
MAINTAINERS | 2 ++
20
9 files changed, 44 insertions(+), 26 deletions(-)
21
create mode 100644 include/hw/input/tsc2xxx.h
22
14
23
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
15
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
24
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/omap.h
17
--- a/hw/arm/xlnx-versal-virt.c
26
+++ b/include/hw/arm/omap.h
18
+++ b/hw/arm/xlnx-versal-virt.c
27
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
28
#include "exec/memory.h"
20
psci_conduit = QEMU_PSCI_CONDUIT_SMC;
29
# define hw_omap_h        "omap.h"
21
}
30
#include "hw/irq.h"
22
31
+#include "hw/input/tsc2xxx.h"
23
- sysbus_init_child_obj(OBJECT(machine), "xlnx-ve", &s->soc,
32
#include "target/arm/cpu-qom.h"
24
+ sysbus_init_child_obj(OBJECT(machine), "xlnx-versal", &s->soc,
33
#include "qemu/log.h"
25
sizeof(s->soc), TYPE_XLNX_VERSAL);
34
26
object_property_set_link(OBJECT(&s->soc), OBJECT(machine->ram),
35
@@ -XXX,XX +XXX,XX @@ qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s);
27
"ddr", &error_abort);
36
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler);
37
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down);
38
39
-struct uWireSlave {
40
- uint16_t (*receive)(void *opaque);
41
- void (*send)(void *opaque, uint16_t data);
42
- void *opaque;
43
-};
44
struct omap_uwire_s;
45
void omap_uwire_attach(struct omap_uwire_s *s,
46
uWireSlave *slave, int chipselect);
47
diff --git a/include/hw/devices.h b/include/hw/devices.h
48
index XXXXXXX..XXXXXXX 100644
49
--- a/include/hw/devices.h
50
+++ b/include/hw/devices.h
51
@@ -XXX,XX +XXX,XX @@
52
/* Devices that have nowhere better to go. */
53
54
#include "hw/hw.h"
55
-#include "ui/console.h"
56
57
/* smc91c111.c */
58
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
59
@@ -XXX,XX +XXX,XX @@ void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
60
/* lan9118.c */
61
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
62
63
-/* tsc210x.c */
64
-uWireSlave *tsc2102_init(qemu_irq pint);
65
-uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
66
-I2SCodec *tsc210x_codec(uWireSlave *chip);
67
-uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
68
-void tsc210x_set_transform(uWireSlave *chip,
69
- MouseTransformInfo *info);
70
-void tsc210x_key_event(uWireSlave *chip, int key, int down);
71
-
72
-/* tsc2005.c */
73
-void *tsc2005_init(qemu_irq pintdav);
74
-uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
75
-void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
76
-
77
#endif
78
diff --git a/include/hw/input/tsc2xxx.h b/include/hw/input/tsc2xxx.h
79
new file mode 100644
80
index XXXXXXX..XXXXXXX
81
--- /dev/null
82
+++ b/include/hw/input/tsc2xxx.h
83
@@ -XXX,XX +XXX,XX @@
84
+/*
85
+ * TI touchscreen controller
86
+ *
87
+ * Copyright (c) 2006 Andrzej Zaborowski
88
+ * Copyright (C) 2008 Nokia Corporation
89
+ *
90
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
91
+ * See the COPYING file in the top-level directory.
92
+ */
93
+
94
+#ifndef HW_INPUT_TSC2XXX_H
95
+#define HW_INPUT_TSC2XXX_H
96
+
97
+#include "hw/irq.h"
98
+#include "ui/console.h"
99
+
100
+typedef struct uWireSlave {
101
+ uint16_t (*receive)(void *opaque);
102
+ void (*send)(void *opaque, uint16_t data);
103
+ void *opaque;
104
+} uWireSlave;
105
+
106
+/* tsc210x.c */
107
+uWireSlave *tsc2102_init(qemu_irq pint);
108
+uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
109
+I2SCodec *tsc210x_codec(uWireSlave *chip);
110
+uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
111
+void tsc210x_set_transform(uWireSlave *chip, MouseTransformInfo *info);
112
+void tsc210x_key_event(uWireSlave *chip, int key, int down);
113
+
114
+/* tsc2005.c */
115
+void *tsc2005_init(qemu_irq pintdav);
116
+uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
117
+void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
118
+
119
+#endif
120
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
121
index XXXXXXX..XXXXXXX 100644
122
--- a/include/qemu/typedefs.h
123
+++ b/include/qemu/typedefs.h
124
@@ -XXX,XX +XXX,XX @@ typedef struct RAMBlock RAMBlock;
125
typedef struct Range Range;
126
typedef struct SHPCDevice SHPCDevice;
127
typedef struct SSIBus SSIBus;
128
-typedef struct uWireSlave uWireSlave;
129
typedef struct VirtIODevice VirtIODevice;
130
typedef struct Visitor Visitor;
131
typedef void SaveStateHandler(QEMUFile *f, void *opaque);
132
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/hw/arm/nseries.c
135
+++ b/hw/arm/nseries.c
136
@@ -XXX,XX +XXX,XX @@
137
#include "ui/console.h"
138
#include "hw/boards.h"
139
#include "hw/i2c/i2c.h"
140
-#include "hw/devices.h"
141
#include "hw/display/blizzard.h"
142
+#include "hw/input/tsc2xxx.h"
143
#include "hw/misc/cbus.h"
144
#include "hw/misc/tmp105.h"
145
#include "hw/block/flash.h"
146
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
147
index XXXXXXX..XXXXXXX 100644
148
--- a/hw/arm/palm.c
149
+++ b/hw/arm/palm.c
150
@@ -XXX,XX +XXX,XX @@
151
#include "hw/arm/omap.h"
152
#include "hw/boards.h"
153
#include "hw/arm/arm.h"
154
-#include "hw/devices.h"
155
+#include "hw/input/tsc2xxx.h"
156
#include "hw/loader.h"
157
#include "exec/address-spaces.h"
158
#include "cpu.h"
159
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/hw/input/tsc2005.c
162
+++ b/hw/input/tsc2005.c
163
@@ -XXX,XX +XXX,XX @@
164
#include "hw/hw.h"
165
#include "qemu/timer.h"
166
#include "ui/console.h"
167
-#include "hw/devices.h"
168
+#include "hw/input/tsc2xxx.h"
169
#include "trace.h"
170
171
#define TSC_CUT_RESOLUTION(value, p)    ((value) >> (16 - (p ? 12 : 10)))
172
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
173
index XXXXXXX..XXXXXXX 100644
174
--- a/hw/input/tsc210x.c
175
+++ b/hw/input/tsc210x.c
176
@@ -XXX,XX +XXX,XX @@
177
#include "audio/audio.h"
178
#include "qemu/timer.h"
179
#include "ui/console.h"
180
-#include "hw/arm/omap.h"    /* For I2SCodec and uWireSlave */
181
-#include "hw/devices.h"
182
+#include "hw/arm/omap.h" /* For I2SCodec */
183
+#include "hw/input/tsc2xxx.h"
184
185
#define TSC_DATA_REGISTERS_PAGE        0x0
186
#define TSC_CONTROL_REGISTERS_PAGE    0x1
187
diff --git a/MAINTAINERS b/MAINTAINERS
188
index XXXXXXX..XXXXXXX 100644
189
--- a/MAINTAINERS
190
+++ b/MAINTAINERS
191
@@ -XXX,XX +XXX,XX @@ F: hw/input/tsc2005.c
192
F: hw/misc/cbus.c
193
F: hw/timer/twl92230.c
194
F: include/hw/display/blizzard.h
195
+F: include/hw/input/tsc2xxx.h
196
F: include/hw/misc/cbus.h
197
198
Palm
199
@@ -XXX,XX +XXX,XX @@ L: qemu-arm@nongnu.org
200
S: Odd Fixes
201
F: hw/arm/palm.c
202
F: hw/input/tsc210x.c
203
+F: include/hw/input/tsc2xxx.h
204
205
Raspberry Pi
206
M: Peter Maydell <peter.maydell@linaro.org>
207
--
28
--
208
2.20.1
29
2.20.1
209
30
210
31
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
Embed the UARTs into the SoC type.
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
5
Message-id: 20190412165416.7977-8-philmd@redhat.com
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-5-edgar.iglesias@gmail.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
12
---
8
include/hw/devices.h | 3 ---
13
include/hw/arm/xlnx-versal.h | 3 ++-
9
include/hw/input/gamepad.h | 19 +++++++++++++++++++
14
hw/arm/xlnx-versal.c | 12 ++++++------
10
hw/arm/stellaris.c | 2 +-
15
2 files changed, 8 insertions(+), 7 deletions(-)
11
hw/input/stellaris_input.c | 2 +-
12
MAINTAINERS | 1 +
13
5 files changed, 22 insertions(+), 5 deletions(-)
14
create mode 100644 include/hw/input/gamepad.h
15
16
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/devices.h
19
--- a/include/hw/arm/xlnx-versal.h
19
+++ b/include/hw/devices.h
20
+++ b/include/hw/arm/xlnx-versal.h
20
@@ -XXX,XX +XXX,XX @@ void *tsc2005_init(qemu_irq pintdav);
21
uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
22
void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
23
24
-/* stellaris_input.c */
25
-void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
26
-
27
#endif
28
diff --git a/include/hw/input/gamepad.h b/include/hw/input/gamepad.h
29
new file mode 100644
30
index XXXXXXX..XXXXXXX
31
--- /dev/null
32
+++ b/include/hw/input/gamepad.h
33
@@ -XXX,XX +XXX,XX @@
34
+/*
35
+ * Gamepad style buttons connected to IRQ/GPIO lines
36
+ *
37
+ * Copyright (c) 2007 CodeSourcery.
38
+ * Written by Paul Brook
39
+ *
40
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
41
+ * See the COPYING file in the top-level directory.
42
+ */
43
+
44
+#ifndef HW_INPUT_GAMEPAD_H
45
+#define HW_INPUT_GAMEPAD_H
46
+
47
+#include "hw/irq.h"
48
+
49
+/* stellaris_input.c */
50
+void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
51
+
52
+#endif
53
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/arm/stellaris.c
56
+++ b/hw/arm/stellaris.c
57
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
58
#include "hw/sysbus.h"
22
#include "hw/sysbus.h"
59
#include "hw/ssi/ssi.h"
23
#include "hw/arm/boot.h"
60
#include "hw/arm/arm.h"
24
#include "hw/intc/arm_gicv3.h"
61
-#include "hw/devices.h"
25
+#include "hw/char/pl011.h"
62
#include "qemu/timer.h"
26
63
#include "hw/i2c/i2c.h"
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
64
#include "net/net.h"
28
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
30
MemoryRegion mr_ocm;
31
32
struct {
33
- SysBusDevice *uart[XLNX_VERSAL_NR_UARTS];
34
+ PL011State uart[XLNX_VERSAL_NR_UARTS];
35
SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
36
SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
37
} iou;
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/xlnx-versal.c
41
+++ b/hw/arm/xlnx-versal.c
65
@@ -XXX,XX +XXX,XX @@
42
@@ -XXX,XX +XXX,XX @@
66
#include "sysemu/sysemu.h"
43
#include "kvm_arm.h"
67
#include "hw/arm/armv7m.h"
68
#include "hw/char/pl011.h"
69
+#include "hw/input/gamepad.h"
70
#include "hw/watchdog/cmsdk-apb-watchdog.h"
71
#include "hw/misc/unimp.h"
44
#include "hw/misc/unimp.h"
72
#include "cpu.h"
45
#include "hw/arm/xlnx-versal.h"
73
diff --git a/hw/input/stellaris_input.c b/hw/input/stellaris_input.c
46
-#include "hw/char/pl011.h"
74
index XXXXXXX..XXXXXXX 100644
47
75
--- a/hw/input/stellaris_input.c
48
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
76
+++ b/hw/input/stellaris_input.c
49
#define GEM_REVISION 0x40070106
77
@@ -XXX,XX +XXX,XX @@
50
@@ -XXX,XX +XXX,XX @@ static void versal_create_uarts(Versal *s, qemu_irq *pic)
78
*/
51
DeviceState *dev;
79
#include "qemu/osdep.h"
52
MemoryRegion *mr;
80
#include "hw/hw.h"
53
81
-#include "hw/devices.h"
54
- dev = qdev_create(NULL, TYPE_PL011);
82
+#include "hw/input/gamepad.h"
55
- s->lpd.iou.uart[i] = SYS_BUS_DEVICE(dev);
83
#include "ui/console.h"
56
+ sysbus_init_child_obj(OBJECT(s), name,
84
57
+ &s->lpd.iou.uart[i], sizeof(s->lpd.iou.uart[i]),
85
typedef struct {
58
+ TYPE_PL011);
86
diff --git a/MAINTAINERS b/MAINTAINERS
59
+ dev = DEVICE(&s->lpd.iou.uart[i]);
87
index XXXXXXX..XXXXXXX 100644
60
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
88
--- a/MAINTAINERS
61
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
89
+++ b/MAINTAINERS
62
qdev_init_nofail(dev);
90
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
63
91
L: qemu-arm@nongnu.org
64
- mr = sysbus_mmio_get_region(s->lpd.iou.uart[i], 0);
92
S: Maintained
65
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
93
F: hw/*/stellaris*
66
memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
94
+F: include/hw/input/gamepad.h
67
95
68
- sysbus_connect_irq(s->lpd.iou.uart[i], 0, pic[irqs[i]]);
96
Versatile Express
69
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
97
M: Peter Maydell <peter.maydell@linaro.org>
70
g_free(name);
71
}
72
}
98
--
73
--
99
2.20.1
74
2.20.1
100
75
101
76
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
Embed the GEMs into the SoC type.
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
Message-id: 20190412165416.7977-7-philmd@redhat.com
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-6-edgar.iglesias@gmail.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
12
---
9
include/hw/devices.h | 14 --------------
13
include/hw/arm/xlnx-versal.h | 3 ++-
10
include/hw/misc/cbus.h | 32 ++++++++++++++++++++++++++++++++
14
hw/arm/xlnx-versal.c | 15 ++++++++-------
11
hw/arm/nseries.c | 1 +
15
2 files changed, 10 insertions(+), 8 deletions(-)
12
hw/misc/cbus.c | 2 +-
13
MAINTAINERS | 1 +
14
5 files changed, 35 insertions(+), 15 deletions(-)
15
create mode 100644 include/hw/misc/cbus.h
16
16
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/devices.h
19
--- a/include/hw/arm/xlnx-versal.h
20
+++ b/include/hw/devices.h
20
+++ b/include/hw/arm/xlnx-versal.h
21
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
22
/* stellaris_input.c */
23
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
24
25
-/* cbus.c */
26
-typedef struct {
27
- qemu_irq clk;
28
- qemu_irq dat;
29
- qemu_irq sel;
30
-} CBus;
31
-CBus *cbus_init(qemu_irq dat_out);
32
-void cbus_attach(CBus *bus, void *slave_opaque);
33
-
34
-void *retu_init(qemu_irq irq, int vilma);
35
-void *tahvo_init(qemu_irq irq, int betty);
36
-
37
-void retu_key_event(void *retu, int state);
38
-
39
#endif
40
diff --git a/include/hw/misc/cbus.h b/include/hw/misc/cbus.h
41
new file mode 100644
42
index XXXXXXX..XXXXXXX
43
--- /dev/null
44
+++ b/include/hw/misc/cbus.h
45
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
46
+/*
22
#include "hw/arm/boot.h"
47
+ * CBUS three-pin bus and the Retu / Betty / Tahvo / Vilma / Avilma /
23
#include "hw/intc/arm_gicv3.h"
48
+ * Hinku / Vinku / Ahne / Pihi chips used in various Nokia platforms.
24
#include "hw/char/pl011.h"
49
+ * Based on reverse-engineering of a linux driver.
25
+#include "hw/net/cadence_gem.h"
50
+ *
26
51
+ * Copyright (C) 2008 Nokia Corporation
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
52
+ * Written by Andrzej Zaborowski
28
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
53
+ *
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
54
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
30
55
+ * See the COPYING file in the top-level directory.
31
struct {
56
+ */
32
PL011State uart[XLNX_VERSAL_NR_UARTS];
57
+
33
- SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
58
+#ifndef HW_MISC_CBUS_H
34
+ CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
59
+#define HW_MISC_CBUS_H
35
SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
60
+
36
} iou;
61
+#include "hw/irq.h"
37
} lpd;
62
+
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
63
+typedef struct {
64
+ qemu_irq clk;
65
+ qemu_irq dat;
66
+ qemu_irq sel;
67
+} CBus;
68
+
69
+CBus *cbus_init(qemu_irq dat_out);
70
+void cbus_attach(CBus *bus, void *slave_opaque);
71
+
72
+void *retu_init(qemu_irq irq, int vilma);
73
+void *tahvo_init(qemu_irq irq, int betty);
74
+
75
+void retu_key_event(void *retu, int state);
76
+
77
+#endif
78
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
79
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
80
--- a/hw/arm/nseries.c
40
--- a/hw/arm/xlnx-versal.c
81
+++ b/hw/arm/nseries.c
41
+++ b/hw/arm/xlnx-versal.c
82
@@ -XXX,XX +XXX,XX @@
42
@@ -XXX,XX +XXX,XX @@ static void versal_create_gems(Versal *s, qemu_irq *pic)
83
#include "hw/i2c/i2c.h"
43
DeviceState *dev;
84
#include "hw/devices.h"
44
MemoryRegion *mr;
85
#include "hw/display/blizzard.h"
45
86
+#include "hw/misc/cbus.h"
46
- dev = qdev_create(NULL, "cadence_gem");
87
#include "hw/misc/tmp105.h"
47
- s->lpd.iou.gem[i] = SYS_BUS_DEVICE(dev);
88
#include "hw/block/flash.h"
48
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
89
#include "hw/hw.h"
49
+ sysbus_init_child_obj(OBJECT(s), name,
90
diff --git a/hw/misc/cbus.c b/hw/misc/cbus.c
50
+ &s->lpd.iou.gem[i], sizeof(s->lpd.iou.gem[i]),
91
index XXXXXXX..XXXXXXX 100644
51
+ TYPE_CADENCE_GEM);
92
--- a/hw/misc/cbus.c
52
+ dev = DEVICE(&s->lpd.iou.gem[i]);
93
+++ b/hw/misc/cbus.c
53
if (nd->used) {
94
@@ -XXX,XX +XXX,XX @@
54
qemu_check_nic_model(nd, "cadence_gem");
95
#include "qemu/osdep.h"
55
qdev_set_nic_properties(dev, nd);
96
#include "hw/hw.h"
56
}
97
#include "hw/irq.h"
57
- object_property_set_int(OBJECT(s->lpd.iou.gem[i]),
98
-#include "hw/devices.h"
58
+ object_property_set_int(OBJECT(dev),
99
+#include "hw/misc/cbus.h"
59
2, "num-priority-queues",
100
#include "sysemu/sysemu.h"
60
&error_abort);
101
61
- object_property_set_link(OBJECT(s->lpd.iou.gem[i]),
102
//#define DEBUG
62
+ object_property_set_link(OBJECT(dev),
103
diff --git a/MAINTAINERS b/MAINTAINERS
63
OBJECT(&s->mr_ps), "dma",
104
index XXXXXXX..XXXXXXX 100644
64
&error_abort);
105
--- a/MAINTAINERS
65
qdev_init_nofail(dev);
106
+++ b/MAINTAINERS
66
107
@@ -XXX,XX +XXX,XX @@ F: hw/input/tsc2005.c
67
- mr = sysbus_mmio_get_region(s->lpd.iou.gem[i], 0);
108
F: hw/misc/cbus.c
68
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
109
F: hw/timer/twl92230.c
69
memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
110
F: include/hw/display/blizzard.h
70
111
+F: include/hw/misc/cbus.h
71
- sysbus_connect_irq(s->lpd.iou.gem[i], 0, pic[irqs[i]]);
112
72
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
113
Palm
73
g_free(name);
114
M: Andrzej Zaborowski <balrogg@gmail.com>
74
}
75
}
115
--
76
--
116
2.20.1
77
2.20.1
117
78
118
79
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
Add an entries the Blizzard device in MAINTAINERS.
3
Embed the ADMAs into the SoC type.
4
4
5
Reviewed-by: Thomas Huth <thuth@redhat.com>
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20190412165416.7977-6-philmd@redhat.com
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-7-edgar.iglesias@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
include/hw/devices.h | 7 -------
13
include/hw/arm/xlnx-versal.h | 3 ++-
12
include/hw/display/blizzard.h | 22 ++++++++++++++++++++++
14
hw/arm/xlnx-versal.c | 14 +++++++-------
13
hw/arm/nseries.c | 1 +
15
2 files changed, 9 insertions(+), 8 deletions(-)
14
hw/display/blizzard.c | 2 +-
15
MAINTAINERS | 2 ++
16
5 files changed, 26 insertions(+), 8 deletions(-)
17
create mode 100644 include/hw/display/blizzard.h
18
16
19
diff --git a/include/hw/devices.h b/include/hw/devices.h
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/devices.h
19
--- a/include/hw/arm/xlnx-versal.h
22
+++ b/include/hw/devices.h
20
+++ b/include/hw/arm/xlnx-versal.h
23
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
24
/* stellaris_input.c */
25
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
26
27
-/* blizzard.c */
28
-void *s1d13745_init(qemu_irq gpio_int);
29
-void s1d13745_write(void *opaque, int dc, uint16_t value);
30
-void s1d13745_write_block(void *opaque, int dc,
31
- void *buf, size_t len, int pitch);
32
-uint16_t s1d13745_read(void *opaque, int dc);
33
-
34
/* cbus.c */
35
typedef struct {
36
qemu_irq clk;
37
diff --git a/include/hw/display/blizzard.h b/include/hw/display/blizzard.h
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/include/hw/display/blizzard.h
42
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
43
+/*
22
#include "hw/arm/boot.h"
44
+ * Epson S1D13744/S1D13745 (Blizzard/Hailstorm/Tornado) LCD/TV controller.
23
#include "hw/intc/arm_gicv3.h"
45
+ *
24
#include "hw/char/pl011.h"
46
+ * Copyright (C) 2008 Nokia Corporation
25
+#include "hw/dma/xlnx-zdma.h"
47
+ * Written by Andrzej Zaborowski
26
#include "hw/net/cadence_gem.h"
48
+ *
27
49
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
28
#define TYPE_XLNX_VERSAL "xlnx-versal"
50
+ * See the COPYING file in the top-level directory.
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
51
+ */
30
struct {
52
+
31
PL011State uart[XLNX_VERSAL_NR_UARTS];
53
+#ifndef HW_DISPLAY_BLIZZARD_H
32
CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
54
+#define HW_DISPLAY_BLIZZARD_H
33
- SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
55
+
34
+ XlnxZDMA adma[XLNX_VERSAL_NR_ADMAS];
56
+#include "hw/irq.h"
35
} iou;
57
+
36
} lpd;
58
+void *s1d13745_init(qemu_irq gpio_int);
37
59
+void s1d13745_write(void *opaque, int dc, uint16_t value);
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
60
+void s1d13745_write_block(void *opaque, int dc,
61
+ void *buf, size_t len, int pitch);
62
+uint16_t s1d13745_read(void *opaque, int dc);
63
+
64
+#endif
65
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
66
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/arm/nseries.c
40
--- a/hw/arm/xlnx-versal.c
68
+++ b/hw/arm/nseries.c
41
+++ b/hw/arm/xlnx-versal.c
69
@@ -XXX,XX +XXX,XX @@
42
@@ -XXX,XX +XXX,XX @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
70
#include "hw/boards.h"
43
DeviceState *dev;
71
#include "hw/i2c/i2c.h"
44
MemoryRegion *mr;
72
#include "hw/devices.h"
45
73
+#include "hw/display/blizzard.h"
46
- dev = qdev_create(NULL, "xlnx.zdma");
74
#include "hw/misc/tmp105.h"
47
- s->lpd.iou.adma[i] = SYS_BUS_DEVICE(dev);
75
#include "hw/block/flash.h"
48
- object_property_set_int(OBJECT(s->lpd.iou.adma[i]), 128, "bus-width",
76
#include "hw/hw.h"
49
- &error_abort);
77
diff --git a/hw/display/blizzard.c b/hw/display/blizzard.c
50
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
78
index XXXXXXX..XXXXXXX 100644
51
+ sysbus_init_child_obj(OBJECT(s), name,
79
--- a/hw/display/blizzard.c
52
+ &s->lpd.iou.adma[i], sizeof(s->lpd.iou.adma[i]),
80
+++ b/hw/display/blizzard.c
53
+ TYPE_XLNX_ZDMA);
81
@@ -XXX,XX +XXX,XX @@
54
+ dev = DEVICE(&s->lpd.iou.adma[i]);
82
#include "qemu/osdep.h"
55
+ object_property_set_int(OBJECT(dev), 128, "bus-width", &error_abort);
83
#include "qemu-common.h"
56
qdev_init_nofail(dev);
84
#include "ui/console.h"
57
85
-#include "hw/devices.h"
58
- mr = sysbus_mmio_get_region(s->lpd.iou.adma[i], 0);
86
+#include "hw/display/blizzard.h"
59
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
87
#include "ui/pixel_ops.h"
60
memory_region_add_subregion(&s->mr_ps,
88
61
MM_ADMA_CH0 + i * MM_ADMA_CH0_SIZE, mr);
89
typedef void (*blizzard_fn_t)(uint8_t *, const uint8_t *, unsigned int);
62
90
diff --git a/MAINTAINERS b/MAINTAINERS
63
- sysbus_connect_irq(s->lpd.iou.adma[i], 0, pic[VERSAL_ADMA_IRQ_0 + i]);
91
index XXXXXXX..XXXXXXX 100644
64
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_ADMA_IRQ_0 + i]);
92
--- a/MAINTAINERS
65
g_free(name);
93
+++ b/MAINTAINERS
66
}
94
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
67
}
95
L: qemu-arm@nongnu.org
96
S: Odd Fixes
97
F: hw/arm/nseries.c
98
+F: hw/display/blizzard.c
99
F: hw/input/lm832x.c
100
F: hw/input/tsc2005.c
101
F: hw/misc/cbus.c
102
F: hw/timer/twl92230.c
103
+F: include/hw/display/blizzard.h
104
105
Palm
106
M: Andrzej Zaborowski <balrogg@gmail.com>
107
--
68
--
108
2.20.1
69
2.20.1
109
70
110
71
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
No code used the tc6393xb_gpio_in_get() and tc6393xb_gpio_out_set()
3
Embed the APUs into the SoC type.
4
functions since their introduction in commit 88d2c950b002. Time to
5
remove them.
6
4
7
Suggested-by: Markus Armbruster <armbru@redhat.com>
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Message-id: 20190412165416.7977-4-philmd@redhat.com
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-8-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
12
---
13
include/hw/devices.h | 3 ---
13
include/hw/arm/xlnx-versal.h | 2 +-
14
hw/display/tc6393xb.c | 16 ----------------
14
hw/arm/xlnx-versal-virt.c | 4 ++--
15
2 files changed, 19 deletions(-)
15
hw/arm/xlnx-versal.c | 19 +++++--------------
16
3 files changed, 8 insertions(+), 17 deletions(-)
16
17
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
18
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/devices.h
20
--- a/include/hw/arm/xlnx-versal.h
20
+++ b/include/hw/devices.h
21
+++ b/include/hw/arm/xlnx-versal.h
21
@@ -XXX,XX +XXX,XX @@ void retu_key_event(void *retu, int state);
22
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
22
typedef struct TC6393xbState TC6393xbState;
23
struct {
23
TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
24
struct {
24
uint32_t base, qemu_irq irq);
25
MemoryRegion mr;
25
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
26
- ARMCPU *cpu[XLNX_VERSAL_NR_ACPUS];
26
- qemu_irq handler);
27
+ ARMCPU cpu[XLNX_VERSAL_NR_ACPUS];
27
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s);
28
GICv3State gic;
28
qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
29
} apu;
29
30
} fpd;
30
#endif
31
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
31
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
32
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/display/tc6393xb.c
33
--- a/hw/arm/xlnx-versal-virt.c
34
+++ b/hw/display/tc6393xb.c
34
+++ b/hw/arm/xlnx-versal-virt.c
35
@@ -XXX,XX +XXX,XX @@ struct TC6393xbState {
35
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
36
blanked : 1;
36
s->binfo.get_dtb = versal_virt_get_dtb;
37
};
37
s->binfo.modify_dtb = versal_virt_modify_dtb;
38
38
if (machine->kernel_filename) {
39
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s)
39
- arm_load_kernel(s->soc.fpd.apu.cpu[0], machine, &s->binfo);
40
-{
40
+ arm_load_kernel(&s->soc.fpd.apu.cpu[0], machine, &s->binfo);
41
- return s->gpio_in;
41
} else {
42
-}
42
- AddressSpace *as = arm_boot_address_space(s->soc.fpd.apu.cpu[0],
43
+ AddressSpace *as = arm_boot_address_space(&s->soc.fpd.apu.cpu[0],
44
&s->binfo);
45
/* Some boot-loaders (e.g u-boot) don't like blobs at address 0 (NULL).
46
* Offset things by 4K. */
47
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/xlnx-versal.c
50
+++ b/hw/arm/xlnx-versal.c
51
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
52
53
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
54
Object *obj;
55
- char *name;
43
-
56
-
44
static void tc6393xb_gpio_set(void *opaque, int line, int level)
57
- obj = object_new(XLNX_VERSAL_ACPU_TYPE);
45
{
58
- if (!obj) {
46
// TC6393xbState *s = opaque;
59
- error_report("Unable to create apu.cpu[%d] of type %s",
47
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_gpio_set(void *opaque, int line, int level)
60
- i, XLNX_VERSAL_ACPU_TYPE);
48
// FIXME: how does the chip reflect the GPIO input level change?
61
- exit(EXIT_FAILURE);
62
- }
63
-
64
- name = g_strdup_printf("apu-cpu[%d]", i);
65
- object_property_add_child(OBJECT(s), name, obj, &error_fatal);
66
- g_free(name);
67
68
+ object_initialize_child(OBJECT(s), "apu-cpu[*]",
69
+ &s->fpd.apu.cpu[i], sizeof(s->fpd.apu.cpu[i]),
70
+ XLNX_VERSAL_ACPU_TYPE, &error_abort, NULL);
71
+ obj = OBJECT(&s->fpd.apu.cpu[i]);
72
object_property_set_int(obj, s->cfg.psci_conduit,
73
"psci-conduit", &error_abort);
74
if (i) {
75
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
76
object_property_set_link(obj, OBJECT(&s->fpd.apu.mr), "memory",
77
&error_abort);
78
object_property_set_bool(obj, true, "realized", &error_fatal);
79
- s->fpd.apu.cpu[i] = ARM_CPU(obj);
80
}
49
}
81
}
50
82
51
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
83
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
52
- qemu_irq handler)
84
}
53
-{
85
54
- if (line >= TC6393XB_GPIOS) {
86
for (i = 0; i < nr_apu_cpus; i++) {
55
- fprintf(stderr, "TC6393xb: no GPIO pin %d\n", line);
87
- DeviceState *cpudev = DEVICE(s->fpd.apu.cpu[i]);
56
- return;
88
+ DeviceState *cpudev = DEVICE(&s->fpd.apu.cpu[i]);
57
- }
89
int ppibase = XLNX_VERSAL_NR_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
58
-
90
qemu_irq maint_irq;
59
- s->handler[line] = handler;
91
int ti;
60
-}
61
-
62
static void tc6393xb_gpio_handler_update(TC6393xbState *s)
63
{
64
uint32_t level, diff;
65
--
92
--
66
2.20.1
93
2.20.1
67
94
68
95
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
Suggested-by: Markus Armbruster <armbru@redhat.com>
3
Add support for SD.
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
5
Message-id: 20190412165416.7977-3-philmd@redhat.com
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-9-edgar.iglesias@gmail.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
11
---
9
hw/arm/nseries.c | 3 ++-
12
include/hw/arm/xlnx-versal.h | 12 ++++++++++++
10
1 file changed, 2 insertions(+), 1 deletion(-)
13
hw/arm/xlnx-versal.c | 31 +++++++++++++++++++++++++++++++
14
2 files changed, 43 insertions(+)
11
15
12
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/nseries.c
18
--- a/include/hw/arm/xlnx-versal.h
15
+++ b/hw/arm/nseries.c
19
+++ b/include/hw/arm/xlnx-versal.h
16
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
17
#include "hw/boards.h"
21
18
#include "hw/i2c/i2c.h"
22
#include "hw/sysbus.h"
19
#include "hw/devices.h"
23
#include "hw/arm/boot.h"
20
+#include "hw/misc/tmp105.h"
24
+#include "hw/sd/sdhci.h"
21
#include "hw/block/flash.h"
25
#include "hw/intc/arm_gicv3.h"
22
#include "hw/hw.h"
26
#include "hw/char/pl011.h"
23
#include "hw/bt.h"
27
#include "hw/dma/xlnx-zdma.h"
24
@@ -XXX,XX +XXX,XX @@ static void n8x0_i2c_setup(struct n800_s *s)
28
@@ -XXX,XX +XXX,XX @@
25
qemu_register_powerdown_notifier(&n8x0_system_powerdown_notifier);
29
#define XLNX_VERSAL_NR_UARTS 2
26
30
#define XLNX_VERSAL_NR_GEMS 2
27
/* Attach a TMP105 PM chip (A0 wired to ground) */
31
#define XLNX_VERSAL_NR_ADMAS 8
28
- dev = i2c_create_slave(i2c, "tmp105", N8X0_TMP105_ADDR);
32
+#define XLNX_VERSAL_NR_SDS 2
29
+ dev = i2c_create_slave(i2c, TYPE_TMP105, N8X0_TMP105_ADDR);
33
#define XLNX_VERSAL_NR_IRQS 192
30
qdev_connect_gpio_out(dev, 0, tmp_irq);
34
35
typedef struct Versal {
36
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
37
} iou;
38
} lpd;
39
40
+ /* The Platform Management Controller subsystem. */
41
+ struct {
42
+ struct {
43
+ SDHCIState sd[XLNX_VERSAL_NR_SDS];
44
+ } iou;
45
+ } pmc;
46
+
47
struct {
48
MemoryRegion *mr_ddr;
49
uint32_t psci_conduit;
50
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
51
#define VERSAL_GEM1_IRQ_0 58
52
#define VERSAL_GEM1_WAKE_IRQ_0 59
53
#define VERSAL_ADMA_IRQ_0 60
54
+#define VERSAL_SD0_IRQ_0 126
55
56
/* Architecturally reserved IRQs suitable for virtualization. */
57
#define VERSAL_RSVD_IRQ_FIRST 111
58
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
59
#define MM_FPD_CRF 0xfd1a0000U
60
#define MM_FPD_CRF_SIZE 0x140000
61
62
+#define MM_PMC_SD0 0xf1040000U
63
+#define MM_PMC_SD0_SIZE 0x10000
64
#define MM_PMC_CRP 0xf1260000U
65
#define MM_PMC_CRP_SIZE 0x10000
66
#endif
67
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/hw/arm/xlnx-versal.c
70
+++ b/hw/arm/xlnx-versal.c
71
@@ -XXX,XX +XXX,XX @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
72
}
31
}
73
}
74
75
+#define SDHCI_CAPABILITIES 0x280737ec6481 /* Same as on ZynqMP. */
76
+static void versal_create_sds(Versal *s, qemu_irq *pic)
77
+{
78
+ int i;
79
+
80
+ for (i = 0; i < ARRAY_SIZE(s->pmc.iou.sd); i++) {
81
+ DeviceState *dev;
82
+ MemoryRegion *mr;
83
+
84
+ sysbus_init_child_obj(OBJECT(s), "sd[*]",
85
+ &s->pmc.iou.sd[i], sizeof(s->pmc.iou.sd[i]),
86
+ TYPE_SYSBUS_SDHCI);
87
+ dev = DEVICE(&s->pmc.iou.sd[i]);
88
+
89
+ object_property_set_uint(OBJECT(dev),
90
+ 3, "sd-spec-version", &error_fatal);
91
+ object_property_set_uint(OBJECT(dev), SDHCI_CAPABILITIES, "capareg",
92
+ &error_fatal);
93
+ object_property_set_uint(OBJECT(dev), UHS_I, "uhs", &error_fatal);
94
+ qdev_init_nofail(dev);
95
+
96
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
97
+ memory_region_add_subregion(&s->mr_ps,
98
+ MM_PMC_SD0 + i * MM_PMC_SD0_SIZE, mr);
99
+
100
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
101
+ pic[VERSAL_SD0_IRQ_0 + i * 2]);
102
+ }
103
+}
104
+
105
/* This takes the board allocated linear DDR memory and creates aliases
106
* for each split DDR range/aperture on the Versal address map.
107
*/
108
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
109
versal_create_uarts(s, pic);
110
versal_create_gems(s, pic);
111
versal_create_admas(s, pic);
112
+ versal_create_sds(s, pic);
113
versal_map_ddr(s);
114
versal_unimp(s);
32
115
33
--
116
--
34
2.20.1
117
2.20.1
35
118
36
119
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
hw/arm: versal: Add support for the RTC.
4
Reviewed-by: Cédric Le Goater <clg@kaod.org>
4
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20190412165416.7977-2-philmd@redhat.com
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-10-edgar.iglesias@gmail.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
11
---
10
hw/arm/aspeed.c | 13 +++++++++----
12
include/hw/arm/xlnx-versal.h | 8 ++++++++
11
1 file changed, 9 insertions(+), 4 deletions(-)
13
hw/arm/xlnx-versal.c | 21 +++++++++++++++++++++
14
2 files changed, 29 insertions(+)
12
15
13
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/aspeed.c
18
--- a/include/hw/arm/xlnx-versal.h
16
+++ b/hw/arm/aspeed.c
19
+++ b/include/hw/arm/xlnx-versal.h
17
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
18
#include "hw/arm/aspeed_soc.h"
21
#include "hw/char/pl011.h"
19
#include "hw/boards.h"
22
#include "hw/dma/xlnx-zdma.h"
20
#include "hw/i2c/smbus_eeprom.h"
23
#include "hw/net/cadence_gem.h"
21
+#include "hw/misc/pca9552.h"
24
+#include "hw/rtc/xlnx-zynqmp-rtc.h"
22
+#include "hw/misc/tmp105.h"
25
23
#include "qemu/log.h"
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
24
#include "sysemu/block-backend.h"
27
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
25
#include "hw/loader.h"
28
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
26
@@ -XXX,XX +XXX,XX @@ static void ast2500_evb_i2c_init(AspeedBoardState *bmc)
29
struct {
27
eeprom_buf);
30
SDHCIState sd[XLNX_VERSAL_NR_SDS];
28
31
} iou;
29
/* The AST2500 EVB expects a LM75 but a TMP105 is compatible */
32
+
30
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7), "tmp105", 0x4d);
33
+ XlnxZynqMPRTC rtc;
31
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7),
34
} pmc;
32
+ TYPE_TMP105, 0x4d);
35
33
36
struct {
34
/* The AST2500 EVB does not have an RTC. Let's pretend that one is
37
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
35
* plugged on the I2C bus header */
38
#define VERSAL_GEM1_IRQ_0 58
36
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
39
#define VERSAL_GEM1_WAKE_IRQ_0 59
37
AspeedSoCState *soc = &bmc->soc;
40
#define VERSAL_ADMA_IRQ_0 60
38
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
41
+#define VERSAL_RTC_APB_ERR_IRQ 121
39
42
#define VERSAL_SD0_IRQ_0 126
40
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), "pca9552", 0x60);
43
+#define VERSAL_RTC_ALARM_IRQ 142
41
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), TYPE_PCA9552,
44
+#define VERSAL_RTC_SECONDS_IRQ 143
42
+ 0x60);
45
43
46
/* Architecturally reserved IRQs suitable for virtualization. */
44
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), "tmp423", 0x4c);
47
#define VERSAL_RSVD_IRQ_FIRST 111
45
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 5), "tmp423", 0x4c);
48
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
46
49
#define MM_PMC_SD0_SIZE 0x10000
47
/* The Witherspoon expects a TMP275 but a TMP105 is compatible */
50
#define MM_PMC_CRP 0xf1260000U
48
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), "tmp105", 0x4a);
51
#define MM_PMC_CRP_SIZE 0x10000
49
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), TYPE_TMP105,
52
+#define MM_PMC_RTC 0xf12a0000
50
+ 0x4a);
53
+#define MM_PMC_RTC_SIZE 0x10000
51
54
#endif
52
/* The witherspoon board expects Epson RX8900 I2C RTC but a ds1338 is
55
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
53
* good enough */
56
index XXXXXXX..XXXXXXX 100644
54
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
57
--- a/hw/arm/xlnx-versal.c
55
58
+++ b/hw/arm/xlnx-versal.c
56
smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), 0x51,
59
@@ -XXX,XX +XXX,XX @@ static void versal_create_sds(Versal *s, qemu_irq *pic)
57
eeprom_buf);
60
}
58
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "pca9552",
59
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), TYPE_PCA9552,
60
0x60);
61
}
61
}
62
63
+static void versal_create_rtc(Versal *s, qemu_irq *pic)
64
+{
65
+ SysBusDevice *sbd;
66
+ MemoryRegion *mr;
67
+
68
+ sysbus_init_child_obj(OBJECT(s), "rtc", &s->pmc.rtc, sizeof(s->pmc.rtc),
69
+ TYPE_XLNX_ZYNQMP_RTC);
70
+ sbd = SYS_BUS_DEVICE(&s->pmc.rtc);
71
+ qdev_init_nofail(DEVICE(sbd));
72
+
73
+ mr = sysbus_mmio_get_region(sbd, 0);
74
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_RTC, mr);
75
+
76
+ /*
77
+ * TODO: Connect the ALARM and SECONDS interrupts once our RTC model
78
+ * supports them.
79
+ */
80
+ sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]);
81
+}
82
+
83
/* This takes the board allocated linear DDR memory and creates aliases
84
* for each split DDR range/aperture on the Versal address map.
85
*/
86
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
87
versal_create_gems(s, pic);
88
versal_create_admas(s, pic);
89
versal_create_sds(s, pic);
90
+ versal_create_rtc(s, pic);
91
versal_map_ddr(s);
92
versal_unimp(s);
62
93
63
--
94
--
64
2.20.1
95
2.20.1
65
96
66
97
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
The SMMUNotifierNode struct is not necessary and brings extra
3
Add support for SD.
4
complexity so let's remove it. We now directly track the SMMUDevices
5
which have registered IOMMU MR notifiers.
6
4
7
This is inspired from the same transformation on intel-iommu
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
done in commit b4a4ba0d68f50f218ee3957b6638dbee32a5eeef
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
("intel-iommu: remove IntelIOMMUNotifierNode")
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
8
Message-id: 20200427181649.26851-11-edgar.iglesias@gmail.com
11
Signed-off-by: Eric Auger <eric.auger@redhat.com>
12
Reviewed-by: Peter Xu <peterx@redhat.com>
13
Message-id: 20190409160219.19026-1-eric.auger@redhat.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
10
---
16
include/hw/arm/smmu-common.h | 8 ++------
11
hw/arm/xlnx-versal-virt.c | 46 +++++++++++++++++++++++++++++++++++++++
17
hw/arm/smmu-common.c | 6 +++---
12
1 file changed, 46 insertions(+)
18
hw/arm/smmuv3.c | 28 +++++++---------------------
19
3 files changed, 12 insertions(+), 30 deletions(-)
20
13
21
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
22
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/smmu-common.h
16
--- a/hw/arm/xlnx-versal-virt.c
24
+++ b/include/hw/arm/smmu-common.h
17
+++ b/hw/arm/xlnx-versal-virt.c
25
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUDevice {
18
@@ -XXX,XX +XXX,XX @@
26
AddressSpace as;
19
#include "hw/arm/sysbus-fdt.h"
27
uint32_t cfg_cache_hits;
20
#include "hw/arm/fdt.h"
28
uint32_t cfg_cache_misses;
21
#include "cpu.h"
29
+ QLIST_ENTRY(SMMUDevice) next;
22
+#include "hw/qdev-properties.h"
30
} SMMUDevice;
23
#include "hw/arm/xlnx-versal.h"
31
24
32
-typedef struct SMMUNotifierNode {
25
#define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
33
- SMMUDevice *sdev;
26
@@ -XXX,XX +XXX,XX @@ static void fdt_add_zdma_nodes(VersalVirt *s)
34
- QLIST_ENTRY(SMMUNotifierNode) next;
35
-} SMMUNotifierNode;
36
-
37
typedef struct SMMUPciBus {
38
PCIBus *bus;
39
SMMUDevice *pbdev[0]; /* Parent array is sparse, so dynamically alloc */
40
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUState {
41
GHashTable *iotlb;
42
SMMUPciBus *smmu_pcibus_by_bus_num[SMMU_PCI_BUS_MAX];
43
PCIBus *pci_bus;
44
- QLIST_HEAD(, SMMUNotifierNode) notifiers_list;
45
+ QLIST_HEAD(, SMMUDevice) devices_with_notifiers;
46
uint8_t bus_num;
47
PCIBus *primary_bus;
48
} SMMUState;
49
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/smmu-common.c
52
+++ b/hw/arm/smmu-common.c
53
@@ -XXX,XX +XXX,XX @@ inline void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
54
/* Unmap all notifiers of all mr's */
55
void smmu_inv_notifiers_all(SMMUState *s)
56
{
57
- SMMUNotifierNode *node;
58
+ SMMUDevice *sdev;
59
60
- QLIST_FOREACH(node, &s->notifiers_list, next) {
61
- smmu_inv_notifiers_mr(&node->sdev->iommu);
62
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
63
+ smmu_inv_notifiers_mr(&sdev->iommu);
64
}
27
}
65
}
28
}
66
29
67
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
30
+static void fdt_add_sd_nodes(VersalVirt *s)
68
index XXXXXXX..XXXXXXX 100644
31
+{
69
--- a/hw/arm/smmuv3.c
32
+ const char clocknames[] = "clk_xin\0clk_ahb";
70
+++ b/hw/arm/smmuv3.c
33
+ const char compat[] = "arasan,sdhci-8.9a";
71
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
34
+ int i;
72
/* invalidate an asid/iova tuple in all mr's */
35
+
73
static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova)
36
+ for (i = ARRAY_SIZE(s->soc.pmc.iou.sd) - 1; i >= 0; i--) {
37
+ uint64_t addr = MM_PMC_SD0 + MM_PMC_SD0_SIZE * i;
38
+ char *name = g_strdup_printf("/sdhci@%" PRIx64, addr);
39
+
40
+ qemu_fdt_add_subnode(s->fdt, name);
41
+
42
+ qemu_fdt_setprop_cells(s->fdt, name, "clocks",
43
+ s->phandle.clk_25Mhz, s->phandle.clk_25Mhz);
44
+ qemu_fdt_setprop(s->fdt, name, "clock-names",
45
+ clocknames, sizeof(clocknames));
46
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
47
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_SD0_IRQ_0 + i * 2,
48
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
49
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
50
+ 2, addr, 2, MM_PMC_SD0_SIZE);
51
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
52
+ g_free(name);
53
+ }
54
+}
55
+
56
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
74
{
57
{
75
- SMMUNotifierNode *node;
58
Error *err = NULL;
76
+ SMMUDevice *sdev;
59
@@ -XXX,XX +XXX,XX @@ static void create_virtio_regions(VersalVirt *s)
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
}
60
}
119
}
61
}
120
62
63
+static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
64
+{
65
+ BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
66
+ DeviceState *card;
67
+
68
+ card = qdev_create(qdev_get_child_bus(DEVICE(sd), "sd-bus"), TYPE_SD_CARD);
69
+ object_property_add_child(OBJECT(sd), "card[*]", OBJECT(card),
70
+ &error_fatal);
71
+ qdev_prop_set_drive(card, "drive", blk, &error_fatal);
72
+ object_property_set_bool(OBJECT(card), true, "realized", &error_fatal);
73
+}
74
+
75
static void versal_virt_init(MachineState *machine)
76
{
77
VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(machine);
78
int psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
79
+ int i;
80
81
/*
82
* If the user provides an Operating System to be loaded, we expect them
83
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
84
fdt_add_gic_nodes(s);
85
fdt_add_timer_nodes(s);
86
fdt_add_zdma_nodes(s);
87
+ fdt_add_sd_nodes(s);
88
fdt_add_cpu_nodes(s, psci_conduit);
89
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
90
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
91
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
92
memory_region_add_subregion_overlap(get_system_memory(),
93
0, &s->soc.fpd.apu.mr, 0);
94
95
+ /* Plugin SD cards. */
96
+ for (i = 0; i < ARRAY_SIZE(s->soc.pmc.iou.sd); i++) {
97
+ sd_plugin_card(&s->soc.pmc.iou.sd[i], drive_get_next(IF_SD));
98
+ }
99
+
100
s->binfo.ram_size = machine->ram_size;
101
s->binfo.loader_start = 0x0;
102
s->binfo.get_dtb = versal_virt_get_dtb;
121
--
103
--
122
2.20.1
104
2.20.1
123
105
124
106
diff view generated by jsdifflib
Deleted patch
1
In the stripe8() function we use a variable length array; however
2
we know that the maximum length required is MAX_NUM_BUSSES. Use
3
a fixed-length array and an assert instead.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
10
Message-id: 20190328152635.2794-1-peter.maydell@linaro.org
11
---
12
hw/ssi/xilinx_spips.c | 6 ++++--
13
1 file changed, 4 insertions(+), 2 deletions(-)
14
15
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/ssi/xilinx_spips.c
18
+++ b/hw/ssi/xilinx_spips.c
19
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_reset(DeviceState *d)
20
21
static inline void stripe8(uint8_t *x, int num, bool dir)
22
{
23
- uint8_t r[num];
24
- memset(r, 0, sizeof(uint8_t) * num);
25
+ uint8_t r[MAX_NUM_BUSSES];
26
int idx[2] = {0, 0};
27
int bit[2] = {0, 7};
28
int d = dir;
29
30
+ assert(num <= MAX_NUM_BUSSES);
31
+ memset(r, 0, sizeof(uint8_t) * num);
32
+
33
for (idx[0] = 0; idx[0] < num; ++idx[0]) {
34
for (bit[0] = 7; bit[0] >= 0; bit[0]--) {
35
r[idx[!d]] |= x[idx[d]] & 1 << bit[d] ? 1 << bit[!d] : 0;
36
--
37
2.20.1
38
39
diff view generated by jsdifflib
Deleted patch
1
Normally configure identifies the source path by looking
2
at the location where the configure script itself exists.
3
We also provide a --source-path option which lets the user
4
manually override this.
5
1
6
There isn't really an obvious use case for the --source-path
7
option, and in commit 927128222b0a91f56c13a in 2017 we
8
accidentally added some logic that looks at $source_path
9
before the command line option that overrides it has been
10
processed.
11
12
The fact that nobody complained suggests that there isn't
13
any use of this option and we aren't testing it either;
14
remove it. This allows us to move the "make $source_path
15
absolute" logic up so that there is no window in the script
16
where $source_path is set but not yet absolute.
17
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
20
Message-id: 20190318134019.23729-1-peter.maydell@linaro.org
21
---
22
configure | 10 ++--------
23
1 file changed, 2 insertions(+), 8 deletions(-)
24
25
diff --git a/configure b/configure
26
index XXXXXXX..XXXXXXX 100755
27
--- a/configure
28
+++ b/configure
29
@@ -XXX,XX +XXX,XX @@ ld_has() {
30
31
# default parameters
32
source_path=$(dirname "$0")
33
+# make source path absolute
34
+source_path=$(cd "$source_path"; pwd)
35
cpu=""
36
iasl="iasl"
37
interp_prefix="/usr/gnemul/qemu-%M"
38
@@ -XXX,XX +XXX,XX @@ for opt do
39
;;
40
--cxx=*) CXX="$optarg"
41
;;
42
- --source-path=*) source_path="$optarg"
43
- ;;
44
--cpu=*) cpu="$optarg"
45
;;
46
--extra-cflags=*) QEMU_CFLAGS="$QEMU_CFLAGS $optarg"
47
@@ -XXX,XX +XXX,XX @@ if test "$debug_info" = "yes"; then
48
LDFLAGS="-g $LDFLAGS"
49
fi
50
51
-# make source path absolute
52
-source_path=$(cd "$source_path"; pwd)
53
-
54
# running configure in the source tree?
55
# we know that's the case if configure is there.
56
if test -f "./configure"; then
57
@@ -XXX,XX +XXX,XX @@ for opt do
58
;;
59
--interp-prefix=*) interp_prefix="$optarg"
60
;;
61
- --source-path=*)
62
- ;;
63
--cross-prefix=*)
64
;;
65
--cc=*)
66
@@ -XXX,XX +XXX,XX @@ $(echo Available targets: $default_target_list | \
67
--target-list-exclude=LIST exclude a set of targets from the default target-list
68
69
Advanced options (experts only):
70
- --source-path=PATH path of source code [$source_path]
71
--cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]
72
--cc=CC use C compiler CC [$cc]
73
--iasl=IASL use ACPI compiler IASL [$iasl]
74
--
75
2.20.1
76
77
diff view generated by jsdifflib
1
Pushing registers to the stack for v7M needs to handle three cases:
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
* the "normal" case where we pend exceptions
3
* an "ignore faults" case where we set FSR bits but
4
do not pend exceptions (this is used when we are
5
handling some kinds of derived exception on exception entry)
6
* a "lazy FP stacking" case, where different FSR bits
7
are set and the exception is pended differently
8
2
9
Implement this by changing the existing flag argument that
3
Add support for the RTC.
10
tells us whether to ignore faults or not into an enum that
11
specifies which of the 3 modes we should handle.
12
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Message-id: 20200427181649.26851-12-edgar.iglesias@gmail.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20190416125744.27770-23-peter.maydell@linaro.org
16
---
10
---
17
target/arm/helper.c | 118 +++++++++++++++++++++++++++++---------------
11
hw/arm/xlnx-versal-virt.c | 22 ++++++++++++++++++++++
18
1 file changed, 79 insertions(+), 39 deletions(-)
12
1 file changed, 22 insertions(+)
19
13
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
16
--- a/hw/arm/xlnx-versal-virt.c
23
+++ b/target/arm/helper.c
17
+++ b/hw/arm/xlnx-versal-virt.c
24
@@ -XXX,XX +XXX,XX @@ static bool v7m_cpacr_pass(CPUARMState *env, bool is_secure, bool is_priv)
18
@@ -XXX,XX +XXX,XX @@ static void fdt_add_sd_nodes(VersalVirt *s)
25
}
19
}
26
}
20
}
27
21
28
+/*
22
+static void fdt_add_rtc_node(VersalVirt *s)
29
+ * What kind of stack write are we doing? This affects how exceptions
23
+{
30
+ * generated during the stacking are treated.
24
+ const char compat[] = "xlnx,zynqmp-rtc";
31
+ */
25
+ const char interrupt_names[] = "alarm\0sec";
32
+typedef enum StackingMode {
26
+ char *name = g_strdup_printf("/rtc@%x", MM_PMC_RTC);
33
+ STACK_NORMAL,
34
+ STACK_IGNFAULTS,
35
+ STACK_LAZYFP,
36
+} StackingMode;
37
+
27
+
38
static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
28
+ qemu_fdt_add_subnode(s->fdt, name);
39
- ARMMMUIdx mmu_idx, bool ignfault)
29
+
40
+ ARMMMUIdx mmu_idx, StackingMode mode)
30
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
31
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_RTC_ALARM_IRQ,
32
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI,
33
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_RTC_SECONDS_IRQ,
34
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
35
+ qemu_fdt_setprop(s->fdt, name, "interrupt-names",
36
+ interrupt_names, sizeof(interrupt_names));
37
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
38
+ 2, MM_PMC_RTC, 2, MM_PMC_RTC_SIZE);
39
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
40
+ g_free(name);
41
+}
42
+
43
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
41
{
44
{
42
CPUState *cs = CPU(cpu);
45
Error *err = NULL;
43
CPUARMState *env = &cpu->env;
46
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
44
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
47
fdt_add_timer_nodes(s);
45
&attrs, &prot, &page_size, &fi, NULL)) {
48
fdt_add_zdma_nodes(s);
46
/* MPU/SAU lookup failed */
49
fdt_add_sd_nodes(s);
47
if (fi.type == ARMFault_QEMU_SFault) {
50
+ fdt_add_rtc_node(s);
48
- qemu_log_mask(CPU_LOG_INT,
51
fdt_add_cpu_nodes(s, psci_conduit);
49
- "...SecureFault with SFSR.AUVIOL during stacking\n");
52
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
50
- env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK | R_V7M_SFSR_SFARVALID_MASK;
53
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
51
+ if (mode == STACK_LAZYFP) {
52
+ qemu_log_mask(CPU_LOG_INT,
53
+ "...SecureFault with SFSR.LSPERR "
54
+ "during lazy stacking\n");
55
+ env->v7m.sfsr |= R_V7M_SFSR_LSPERR_MASK;
56
+ } else {
57
+ qemu_log_mask(CPU_LOG_INT,
58
+ "...SecureFault with SFSR.AUVIOL "
59
+ "during stacking\n");
60
+ env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK;
61
+ }
62
+ env->v7m.sfsr |= R_V7M_SFSR_SFARVALID_MASK;
63
env->v7m.sfar = addr;
64
exc = ARMV7M_EXCP_SECURE;
65
exc_secure = false;
66
} else {
67
- qemu_log_mask(CPU_LOG_INT, "...MemManageFault with CFSR.MSTKERR\n");
68
- env->v7m.cfsr[secure] |= R_V7M_CFSR_MSTKERR_MASK;
69
+ if (mode == STACK_LAZYFP) {
70
+ qemu_log_mask(CPU_LOG_INT,
71
+ "...MemManageFault with CFSR.MLSPERR\n");
72
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MLSPERR_MASK;
73
+ } else {
74
+ qemu_log_mask(CPU_LOG_INT,
75
+ "...MemManageFault with CFSR.MSTKERR\n");
76
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MSTKERR_MASK;
77
+ }
78
exc = ARMV7M_EXCP_MEM;
79
exc_secure = secure;
80
}
81
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
82
attrs, &txres);
83
if (txres != MEMTX_OK) {
84
/* BusFault trying to write the data */
85
- qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.STKERR\n");
86
- env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_STKERR_MASK;
87
+ if (mode == STACK_LAZYFP) {
88
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.LSPERR\n");
89
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_LSPERR_MASK;
90
+ } else {
91
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.STKERR\n");
92
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_STKERR_MASK;
93
+ }
94
exc = ARMV7M_EXCP_BUS;
95
exc_secure = false;
96
goto pend_fault;
97
@@ -XXX,XX +XXX,XX @@ pend_fault:
98
* later if we have two derived exceptions.
99
* The only case when we must not pend the exception but instead
100
* throw it away is if we are doing the push of the callee registers
101
- * and we've already generated a derived exception. Even in this
102
- * case we will still update the fault status registers.
103
+ * and we've already generated a derived exception (this is indicated
104
+ * by the caller passing STACK_IGNFAULTS). Even in this case we will
105
+ * still update the fault status registers.
106
*/
107
- if (!ignfault) {
108
+ switch (mode) {
109
+ case STACK_NORMAL:
110
armv7m_nvic_set_pending_derived(env->nvic, exc, exc_secure);
111
+ break;
112
+ case STACK_LAZYFP:
113
+ armv7m_nvic_set_pending_lazyfp(env->nvic, exc, exc_secure);
114
+ break;
115
+ case STACK_IGNFAULTS:
116
+ break;
117
}
118
return false;
119
}
120
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
121
uint32_t limit;
122
bool want_psp;
123
uint32_t sig;
124
+ StackingMode smode = ignore_faults ? STACK_IGNFAULTS : STACK_NORMAL;
125
126
if (dotailchain) {
127
bool mode = lr & R_V7M_EXCRET_MODE_MASK;
128
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
129
*/
130
sig = v7m_integrity_sig(env, lr);
131
stacked_ok =
132
- v7m_stack_write(cpu, frameptr, sig, mmu_idx, ignore_faults) &&
133
- v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
134
- ignore_faults) &&
135
- v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
136
- ignore_faults) &&
137
- v7m_stack_write(cpu, frameptr + 0x10, env->regs[6], mmu_idx,
138
- ignore_faults) &&
139
- v7m_stack_write(cpu, frameptr + 0x14, env->regs[7], mmu_idx,
140
- ignore_faults) &&
141
- v7m_stack_write(cpu, frameptr + 0x18, env->regs[8], mmu_idx,
142
- ignore_faults) &&
143
- v7m_stack_write(cpu, frameptr + 0x1c, env->regs[9], mmu_idx,
144
- ignore_faults) &&
145
- v7m_stack_write(cpu, frameptr + 0x20, env->regs[10], mmu_idx,
146
- ignore_faults) &&
147
- v7m_stack_write(cpu, frameptr + 0x24, env->regs[11], mmu_idx,
148
- ignore_faults);
149
+ v7m_stack_write(cpu, frameptr, sig, mmu_idx, smode) &&
150
+ v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx, smode) &&
151
+ v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx, smode) &&
152
+ v7m_stack_write(cpu, frameptr + 0x10, env->regs[6], mmu_idx, smode) &&
153
+ v7m_stack_write(cpu, frameptr + 0x14, env->regs[7], mmu_idx, smode) &&
154
+ v7m_stack_write(cpu, frameptr + 0x18, env->regs[8], mmu_idx, smode) &&
155
+ v7m_stack_write(cpu, frameptr + 0x1c, env->regs[9], mmu_idx, smode) &&
156
+ v7m_stack_write(cpu, frameptr + 0x20, env->regs[10], mmu_idx, smode) &&
157
+ v7m_stack_write(cpu, frameptr + 0x24, env->regs[11], mmu_idx, smode);
158
159
/* Update SP regardless of whether any of the stack accesses failed. */
160
*frame_sp_p = frameptr;
161
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
162
* if it has higher priority).
163
*/
164
stacked_ok = stacked_ok &&
165
- v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, false) &&
166
- v7m_stack_write(cpu, frameptr + 4, env->regs[1], mmu_idx, false) &&
167
- v7m_stack_write(cpu, frameptr + 8, env->regs[2], mmu_idx, false) &&
168
- v7m_stack_write(cpu, frameptr + 12, env->regs[3], mmu_idx, false) &&
169
- v7m_stack_write(cpu, frameptr + 16, env->regs[12], mmu_idx, false) &&
170
- v7m_stack_write(cpu, frameptr + 20, env->regs[14], mmu_idx, false) &&
171
- v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
172
- v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
173
+ v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, STACK_NORMAL) &&
174
+ v7m_stack_write(cpu, frameptr + 4, env->regs[1],
175
+ mmu_idx, STACK_NORMAL) &&
176
+ v7m_stack_write(cpu, frameptr + 8, env->regs[2],
177
+ mmu_idx, STACK_NORMAL) &&
178
+ v7m_stack_write(cpu, frameptr + 12, env->regs[3],
179
+ mmu_idx, STACK_NORMAL) &&
180
+ v7m_stack_write(cpu, frameptr + 16, env->regs[12],
181
+ mmu_idx, STACK_NORMAL) &&
182
+ v7m_stack_write(cpu, frameptr + 20, env->regs[14],
183
+ mmu_idx, STACK_NORMAL) &&
184
+ v7m_stack_write(cpu, frameptr + 24, env->regs[15],
185
+ mmu_idx, STACK_NORMAL) &&
186
+ v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, STACK_NORMAL);
187
188
if (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) {
189
/* FPU is active, try to save its registers */
190
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
191
faddr += 8; /* skip the slot for the FPSCR */
192
}
193
stacked_ok = stacked_ok &&
194
- v7m_stack_write(cpu, faddr, slo, mmu_idx, false) &&
195
- v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, false);
196
+ v7m_stack_write(cpu, faddr, slo,
197
+ mmu_idx, STACK_NORMAL) &&
198
+ v7m_stack_write(cpu, faddr + 4, shi,
199
+ mmu_idx, STACK_NORMAL);
200
}
201
stacked_ok = stacked_ok &&
202
v7m_stack_write(cpu, frameptr + 0x60,
203
- vfp_get_fpscr(env), mmu_idx, false);
204
+ vfp_get_fpscr(env), mmu_idx, STACK_NORMAL);
205
if (cpacr_pass) {
206
for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
207
*aa32_vfp_dreg(env, i / 2) = 0;
208
--
54
--
209
2.20.1
55
2.20.1
210
56
211
57
diff view generated by jsdifflib
1
The M-profile CONTROL register has two bits -- SFPA and FPCA --
1
Somewhere along theline we accidentally added a duplicate
2
which relate to floating-point support, and should be RES0 otherwise.
2
"using D16-D31 when they don't exist" check to do_vfm_dp()
3
Handle them correctly in the MSR/MRS register access code.
3
(probably an artifact of a patchseries rebase). Remove it.
4
Neither is banked between security states, so they are stored
5
in v7m.control[M_REG_S] regardless of current security state.
6
4
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-9-peter.maydell@linaro.org
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20200430181003.21682-2-peter.maydell@linaro.org
10
---
9
---
11
target/arm/helper.c | 57 ++++++++++++++++++++++++++++++++++++++-------
10
target/arm/translate-vfp.inc.c | 6 ------
12
1 file changed, 49 insertions(+), 8 deletions(-)
11
1 file changed, 6 deletions(-)
13
12
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
15
--- a/target/arm/translate-vfp.inc.c
17
+++ b/target/arm/helper.c
16
+++ b/target/arm/translate-vfp.inc.c
18
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
17
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_dp(DisasContext *s, arg_VFMA_dp *a, bool neg_n, bool neg_d)
19
return xpsr_read(env) & mask;
18
return false;
20
break;
21
case 20: /* CONTROL */
22
- return env->v7m.control[env->v7m.secure];
23
+ {
24
+ uint32_t value = env->v7m.control[env->v7m.secure];
25
+ if (!env->v7m.secure) {
26
+ /* SFPA is RAZ/WI from NS; FPCA is stored in the M_REG_S bank */
27
+ value |= env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK;
28
+ }
29
+ return value;
30
+ }
31
case 0x94: /* CONTROL_NS */
32
/* We have to handle this here because unprivileged Secure code
33
* can read the NS CONTROL register.
34
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
35
if (!env->v7m.secure) {
36
return 0;
37
}
38
- return env->v7m.control[M_REG_NS];
39
+ return env->v7m.control[M_REG_NS] |
40
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK);
41
}
19
}
42
20
43
if (el == 0) {
21
- /* UNDEF accesses to D16-D31 if they don't exist. */
44
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
22
- if (!dc_isar_feature(aa32_simd_r32, s) &&
45
*/
23
- ((a->vd | a->vn | a->vm) & 0x10)) {
46
uint32_t mask = extract32(maskreg, 8, 4);
24
- return false;
47
uint32_t reg = extract32(maskreg, 0, 8);
25
- }
48
+ int cur_el = arm_current_el(env);
26
-
49
27
if (!vfp_access_check(s)) {
50
- if (arm_current_el(env) == 0 && reg > 7) {
28
return true;
51
- /* only xPSR sub-fields may be written by unprivileged */
52
+ if (cur_el == 0 && reg > 7 && reg != 20) {
53
+ /*
54
+ * only xPSR sub-fields and CONTROL.SFPA may be written by
55
+ * unprivileged code
56
+ */
57
return;
58
}
29
}
59
60
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
61
env->v7m.control[M_REG_NS] &= ~R_V7M_CONTROL_NPRIV_MASK;
62
env->v7m.control[M_REG_NS] |= val & R_V7M_CONTROL_NPRIV_MASK;
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:
122
--
30
--
123
2.20.1
31
2.20.1
124
32
125
33
diff view generated by jsdifflib
1
Correct the decode of the M-profile "coprocessor and
1
We were accidentally permitting decode of Thumb Neon insns even if
2
floating-point instructions" space:
2
the CPU didn't have the FEATURE_NEON bit set, because the feature
3
* op0 == 0b11 is always unallocated
3
check was being done before the call to disas_neon_data_insn() and
4
* if the CPU has an FPU then all insns with op1 == 0b101
4
disas_neon_ls_insn() in the Arm decoder but was omitted from the
5
are floating point and go to disas_vfp_insn()
5
Thumb decoder. Push the feature bit check down into the called
6
6
functions so it is done for both Arm and Thumb encodings.
7
For the moment we leave VLLDM and VLSTM as NOPs; in
8
a later commit we will fill in the proper implementation
9
for the case where an FPU is present.
10
7
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20190416125744.27770-7-peter.maydell@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20200430181003.21682-3-peter.maydell@linaro.org
14
---
12
---
15
target/arm/translate.c | 26 ++++++++++++++++++++++----
13
target/arm/translate.c | 16 ++++++++--------
16
1 file changed, 22 insertions(+), 4 deletions(-)
14
1 file changed, 8 insertions(+), 8 deletions(-)
17
15
18
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate.c
18
--- a/target/arm/translate.c
21
+++ b/target/arm/translate.c
19
+++ b/target/arm/translate.c
22
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
20
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
23
case 6: case 7: case 14: case 15:
21
TCGv_i32 tmp2;
24
/* Coprocessor. */
22
TCGv_i64 tmp64;
25
if (arm_dc_feature(s, ARM_FEATURE_M)) {
23
26
- /* We don't currently implement M profile FP support,
24
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
27
- * so this entire space should give a NOCP fault, with
25
+ return 1;
28
- * the exception of the v8M VLLDM and VLSTM insns, which
26
+ }
29
- * must be NOPs in Secure state and UNDEF in Nonsecure state.
30
+ /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
31
+ if (extract32(insn, 24, 2) == 3) {
32
+ goto illegal_op; /* op0 = 0b11 : unallocated */
33
+ }
34
+
27
+
35
+ /*
28
/* FIXME: this access check should not take precedence over UNDEF
36
+ * Decode VLLDM and VLSTM first: these are nonstandard because:
29
* for invalid encodings; we will generate incorrect syndrome information
37
+ * * if there is no FPU then these insns must NOP in
30
* for attempts to execute invalid vfp/neon encodings with FP disabled.
38
+ * Secure state and UNDEF in Nonsecure state
31
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
39
+ * * if there is an FPU then these insns do not have
32
TCGv_ptr ptr1, ptr2, ptr3;
40
+ * the usual behaviour that disas_vfp_insn() provides of
33
TCGv_i64 tmp64;
41
+ * being controlled by CPACR/NSACR enable bits or the
34
42
+ * lazy-stacking logic.
35
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
43
*/
36
+ return 1;
44
if (arm_dc_feature(s, ARM_FEATURE_V8) &&
37
+ }
45
(insn & 0xffa00f00) == 0xec200a00) {
38
+
46
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
39
/* FIXME: this access check should not take precedence over UNDEF
47
/* Just NOP since FP support is not implemented */
40
* for invalid encodings; we will generate incorrect syndrome information
48
break;
41
* for attempts to execute invalid vfp/neon encodings with FP disabled.
42
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
43
44
if (((insn >> 25) & 7) == 1) {
45
/* NEON Data processing. */
46
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
47
- goto illegal_op;
48
- }
49
-
50
if (disas_neon_data_insn(s, insn)) {
51
goto illegal_op;
49
}
52
}
50
+ if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
53
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
51
+ ((insn >> 8) & 0xe) == 10) {
54
}
52
+ /* FP, and the CPU supports it */
55
if ((insn & 0x0f100000) == 0x04000000) {
53
+ if (disas_vfp_insn(s, insn)) {
56
/* NEON load/store. */
54
+ goto illegal_op;
57
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
55
+ }
58
- goto illegal_op;
56
+ break;
59
- }
57
+ }
60
-
58
+
61
if (disas_neon_ls_insn(s, insn)) {
59
/* All other insns: NOCP */
62
goto illegal_op;
60
gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
63
}
61
default_exception_el(s));
62
--
64
--
63
2.20.1
65
2.20.1
64
66
65
67
diff view generated by jsdifflib
1
The M-profile FPCCR.S bit indicates the security status of
1
Add the infrastructure for building and invoking a decodetree decoder
2
the floating point context. In the pseudocode ExecuteFPCheck()
2
for the AArch32 Neon encodings. At the moment the new decoder covers
3
function it is unconditionally set to match the current
3
nothing, so we always fall back to the existing hand-written decode.
4
security state whenever a floating point instruction is
4
5
executed.
5
We follow the same pattern we did for the VFP decodetree conversion
6
6
(commit 78e138bc1f672c145ef6ace74617d and following): code that deals
7
Implement this by adding a new TB flag which tracks whether
7
with Neon will be moving gradually out to translate-neon.vfp.inc,
8
FPCCR.S is different from the current security state, so
8
which we #include into translate.c.
9
that we only need to emit the code to update it in the
9
10
less-common case when it is not already set correctly.
10
In order to share the decode files between A32 and T32, we
11
11
split Neon into 3 parts:
12
Note that we will add the handling for the other work done
12
* data-processing
13
by ExecuteFPCheck() in later commits.
13
* load-store
14
* 'shared' encodings
15
16
The first two groups of instructions have similar but not identical
17
A32 and T32 encodings, so we need to manually transform the T32
18
encoding into the A32 one before calling the decoder; the third group
19
covers the Neon instructions which are identical in A32 and T32.
14
20
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20190416125744.27770-19-peter.maydell@linaro.org
23
Message-id: 20200430181003.21682-4-peter.maydell@linaro.org
18
---
24
---
19
target/arm/cpu.h | 2 ++
25
target/arm/neon-dp.decode | 29 ++++++++++++++++++++++++++
20
target/arm/translate.h | 1 +
26
target/arm/neon-ls.decode | 29 ++++++++++++++++++++++++++
21
target/arm/helper.c | 5 +++++
27
target/arm/neon-shared.decode | 27 +++++++++++++++++++++++++
22
target/arm/translate.c | 20 ++++++++++++++++++++
28
target/arm/translate-neon.inc.c | 32 +++++++++++++++++++++++++++++
23
4 files changed, 28 insertions(+)
29
target/arm/translate.c | 36 +++++++++++++++++++++++++++++++--
24
30
target/arm/Makefile.objs | 18 +++++++++++++++++
25
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
31
6 files changed, 169 insertions(+), 2 deletions(-)
26
index XXXXXXX..XXXXXXX 100644
32
create mode 100644 target/arm/neon-dp.decode
27
--- a/target/arm/cpu.h
33
create mode 100644 target/arm/neon-ls.decode
28
+++ b/target/arm/cpu.h
34
create mode 100644 target/arm/neon-shared.decode
29
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
35
create mode 100644 target/arm/translate-neon.inc.c
30
FIELD(TBFLAG_A32, VFPEN, 7, 1)
36
31
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
37
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
32
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
38
new file mode 100644
33
+/* For M profile only, set if FPCCR.S does not match current security state */
39
index XXXXXXX..XXXXXXX
34
+FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
40
--- /dev/null
35
/* For M profile only, Handler (ie not Thread) mode */
41
+++ b/target/arm/neon-dp.decode
36
FIELD(TBFLAG_A32, HANDLER, 21, 1)
42
@@ -XXX,XX +XXX,XX @@
37
/* For M profile only, whether we should generate stack-limit checks */
43
+# AArch32 Neon data-processing instruction descriptions
38
diff --git a/target/arm/translate.h b/target/arm/translate.h
44
+#
39
index XXXXXXX..XXXXXXX 100644
45
+# Copyright (c) 2020 Linaro, Ltd
40
--- a/target/arm/translate.h
46
+#
41
+++ b/target/arm/translate.h
47
+# This library is free software; you can redistribute it and/or
42
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
48
+# modify it under the terms of the GNU Lesser General Public
43
bool v7m_handler_mode;
49
+# License as published by the Free Software Foundation; either
44
bool v8m_secure; /* true if v8M and we're in Secure mode */
50
+# version 2 of the License, or (at your option) any later version.
45
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
51
+#
46
+ bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
52
+# This library is distributed in the hope that it will be useful,
47
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
53
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
48
* so that top level loop can generate correct syndrome information.
54
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
49
*/
55
+# Lesser General Public License for more details.
50
diff --git a/target/arm/helper.c b/target/arm/helper.c
56
+#
51
index XXXXXXX..XXXXXXX 100644
57
+# You should have received a copy of the GNU Lesser General Public
52
--- a/target/arm/helper.c
58
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
53
+++ b/target/arm/helper.c
59
+
54
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
60
+#
55
flags = FIELD_DP32(flags, TBFLAG_A32, STACKCHECK, 1);
61
+# This file is processed by scripts/decodetree.py
56
}
62
+#
57
63
+
58
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
64
+# Encodings for Neon data processing instructions where the T32 encoding
59
+ FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S) != env->v7m.secure) {
65
+# is a simple transformation of the A32 encoding.
60
+ flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
66
+# More specifically, this file covers instructions where the A32 encoding is
61
+ }
67
+# 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
62
+
68
+# and the T32 encoding is
63
*pflags = flags;
69
+# 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
64
*cs_base = 0;
70
+# This file works on the A32 encoding only; calling code for T32 has to
65
}
71
+# transform the insn into the A32 version first.
72
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
73
new file mode 100644
74
index XXXXXXX..XXXXXXX
75
--- /dev/null
76
+++ b/target/arm/neon-ls.decode
77
@@ -XXX,XX +XXX,XX @@
78
+# AArch32 Neon load/store instruction descriptions
79
+#
80
+# Copyright (c) 2020 Linaro, Ltd
81
+#
82
+# This library is free software; you can redistribute it and/or
83
+# modify it under the terms of the GNU Lesser General Public
84
+# License as published by the Free Software Foundation; either
85
+# version 2 of the License, or (at your option) any later version.
86
+#
87
+# This library is distributed in the hope that it will be useful,
88
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
89
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
90
+# Lesser General Public License for more details.
91
+#
92
+# You should have received a copy of the GNU Lesser General Public
93
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
94
+
95
+#
96
+# This file is processed by scripts/decodetree.py
97
+#
98
+
99
+# Encodings for Neon load/store instructions where the T32 encoding
100
+# is a simple transformation of the A32 encoding.
101
+# More specifically, this file covers instructions where the A32 encoding is
102
+# 0b1111_0100_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
103
+# and the T32 encoding is
104
+# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
105
+# This file works on the A32 encoding only; calling code for T32 has to
106
+# transform the insn into the A32 version first.
107
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
108
new file mode 100644
109
index XXXXXXX..XXXXXXX
110
--- /dev/null
111
+++ b/target/arm/neon-shared.decode
112
@@ -XXX,XX +XXX,XX @@
113
+# AArch32 Neon instruction descriptions
114
+#
115
+# Copyright (c) 2020 Linaro, Ltd
116
+#
117
+# This library is free software; you can redistribute it and/or
118
+# modify it under the terms of the GNU Lesser General Public
119
+# License as published by the Free Software Foundation; either
120
+# version 2 of the License, or (at your option) any later version.
121
+#
122
+# This library is distributed in the hope that it will be useful,
123
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
124
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
125
+# Lesser General Public License for more details.
126
+#
127
+# You should have received a copy of the GNU Lesser General Public
128
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
129
+
130
+#
131
+# This file is processed by scripts/decodetree.py
132
+#
133
+
134
+# Encodings for Neon instructions whose encoding is the same for
135
+# both A32 and T32.
136
+
137
+# More specifically, this covers:
138
+# 2reg scalar ext: 0b1111_1110_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
139
+# 3same ext: 0b1111_110x_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
140
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
141
new file mode 100644
142
index XXXXXXX..XXXXXXX
143
--- /dev/null
144
+++ b/target/arm/translate-neon.inc.c
145
@@ -XXX,XX +XXX,XX @@
146
+/*
147
+ * ARM translation: AArch32 Neon instructions
148
+ *
149
+ * Copyright (c) 2003 Fabrice Bellard
150
+ * Copyright (c) 2005-2007 CodeSourcery
151
+ * Copyright (c) 2007 OpenedHand, Ltd.
152
+ * Copyright (c) 2020 Linaro, Ltd.
153
+ *
154
+ * This library is free software; you can redistribute it and/or
155
+ * modify it under the terms of the GNU Lesser General Public
156
+ * License as published by the Free Software Foundation; either
157
+ * version 2 of the License, or (at your option) any later version.
158
+ *
159
+ * This library is distributed in the hope that it will be useful,
160
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
161
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
162
+ * Lesser General Public License for more details.
163
+ *
164
+ * You should have received a copy of the GNU Lesser General Public
165
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
166
+ */
167
+
168
+/*
169
+ * This file is intended to be included from translate.c; it uses
170
+ * some macros and definitions provided by that file.
171
+ * It might be possible to convert it to a standalone .c file eventually.
172
+ */
173
+
174
+/* Include the generated Neon decoder */
175
+#include "decode-neon-dp.inc.c"
176
+#include "decode-neon-ls.inc.c"
177
+#include "decode-neon-shared.inc.c"
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
178
diff --git a/target/arm/translate.c b/target/arm/translate.c
67
index XXXXXXX..XXXXXXX 100644
179
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate.c
180
--- a/target/arm/translate.c
69
+++ b/target/arm/translate.c
181
+++ b/target/arm/translate.c
70
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
182
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
183
184
#define ARM_CP_RW_BIT (1 << 20)
185
186
-/* Include the VFP decoder */
187
+/* Include the VFP and Neon decoders */
188
#include "translate-vfp.inc.c"
189
+#include "translate-neon.inc.c"
190
191
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
192
{
193
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
194
/* Unconditional instructions. */
195
/* TODO: Perhaps merge these into one decodetree output file. */
196
if (disas_a32_uncond(s, insn) ||
197
- disas_vfp_uncond(s, insn)) {
198
+ disas_vfp_uncond(s, insn) ||
199
+ disas_neon_dp(s, insn) ||
200
+ disas_neon_ls(s, insn) ||
201
+ disas_neon_shared(s, insn)) {
202
return;
71
}
203
}
204
/* fall back to legacy decoder */
205
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
206
ARCH(6T2);
72
}
207
}
73
208
74
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
209
+ if ((insn & 0xef000000) == 0xef000000) {
75
+ /* Handle M-profile lazy FP state mechanics */
210
+ /*
76
+
211
+ * T32 encodings 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
77
+ /* Update ownership of FP context: set FPCCR.S to match current state */
212
+ * transform into
78
+ if (s->v8m_fpccr_s_wrong) {
213
+ * A32 encodings 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
79
+ TCGv_i32 tmp;
214
+ */
80
+
215
+ uint32_t a32_insn = (insn & 0xe2ffffff) |
81
+ tmp = load_cpu_field(v7m.fpccr[M_REG_S]);
216
+ ((insn & (1 << 28)) >> 4) | (1 << 28);
82
+ if (s->v8m_secure) {
217
+
83
+ tcg_gen_ori_i32(tmp, tmp, R_V7M_FPCCR_S_MASK);
218
+ if (disas_neon_dp(s, a32_insn)) {
84
+ } else {
219
+ return;
85
+ tcg_gen_andi_i32(tmp, tmp, ~R_V7M_FPCCR_S_MASK);
86
+ }
87
+ store_cpu_field(tmp, v7m.fpccr[M_REG_S]);
88
+ /* Don't need to do this for any further FP insns in this TB */
89
+ s->v8m_fpccr_s_wrong = false;
90
+ }
220
+ }
91
+ }
221
+ }
92
+
222
+
93
if (extract32(insn, 28, 4) == 0xf) {
223
+ if ((insn & 0xff100000) == 0xf9000000) {
94
/*
224
+ /*
95
* Encodings with T=1 (Thumb) or unconditional (ARM):
225
+ * T32 encodings 0b1111_1001_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
96
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
226
+ * transform into
97
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
227
+ * A32 encodings 0b1111_0100_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
98
regime_is_secure(env, dc->mmu_idx);
228
+ */
99
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
229
+ uint32_t a32_insn = (insn & 0x00ffffff) | 0xf4000000;
100
+ dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
230
+
101
dc->cp_regs = cpu->cp_regs;
231
+ if (disas_neon_ls(s, a32_insn)) {
102
dc->features = env->features;
232
+ return;
103
233
+ }
234
+ }
235
+
236
/*
237
* TODO: Perhaps merge these into one decodetree output file.
238
* Note disas_vfp is written for a32 with cond field in the
239
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
240
*/
241
if (disas_t32(s, insn) ||
242
disas_vfp_uncond(s, insn) ||
243
+ disas_neon_shared(s, insn) ||
244
((insn >> 28) == 0xe && disas_vfp(s, insn))) {
245
return;
246
}
247
diff --git a/target/arm/Makefile.objs b/target/arm/Makefile.objs
248
index XXXXXXX..XXXXXXX 100644
249
--- a/target/arm/Makefile.objs
250
+++ b/target/arm/Makefile.objs
251
@@ -XXX,XX +XXX,XX @@ target/arm/decode-sve.inc.c: $(SRC_PATH)/target/arm/sve.decode $(DECODETREE)
252
     $(PYTHON) $(DECODETREE) --decode disas_sve -o $@ $<,\
253
     "GEN", $(TARGET_DIR)$@)
254
255
+target/arm/decode-neon-shared.inc.c: $(SRC_PATH)/target/arm/neon-shared.decode $(DECODETREE)
256
+    $(call quiet-command,\
257
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_shared -o $@ $<,\
258
+     "GEN", $(TARGET_DIR)$@)
259
+
260
+target/arm/decode-neon-dp.inc.c: $(SRC_PATH)/target/arm/neon-dp.decode $(DECODETREE)
261
+    $(call quiet-command,\
262
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_dp -o $@ $<,\
263
+     "GEN", $(TARGET_DIR)$@)
264
+
265
+target/arm/decode-neon-ls.inc.c: $(SRC_PATH)/target/arm/neon-ls.decode $(DECODETREE)
266
+    $(call quiet-command,\
267
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_ls -o $@ $<,\
268
+     "GEN", $(TARGET_DIR)$@)
269
+
270
target/arm/decode-vfp.inc.c: $(SRC_PATH)/target/arm/vfp.decode $(DECODETREE)
271
    $(call quiet-command,\
272
     $(PYTHON) $(DECODETREE) --static-decode disas_vfp -o $@ $<,\
273
@@ -XXX,XX +XXX,XX @@ target/arm/decode-t16.inc.c: $(SRC_PATH)/target/arm/t16.decode $(DECODETREE)
274
     "GEN", $(TARGET_DIR)$@)
275
276
target/arm/translate-sve.o: target/arm/decode-sve.inc.c
277
+target/arm/translate.o: target/arm/decode-neon-shared.inc.c
278
+target/arm/translate.o: target/arm/decode-neon-dp.inc.c
279
+target/arm/translate.o: target/arm/decode-neon-ls.inc.c
280
target/arm/translate.o: target/arm/decode-vfp.inc.c
281
target/arm/translate.o: target/arm/decode-vfp-uncond.inc.c
282
target/arm/translate.o: target/arm/decode-a32.inc.c
104
--
283
--
105
2.20.1
284
2.20.1
106
285
107
286
diff view generated by jsdifflib
1
In the v7M architecture, if an exception is generated in the process
1
Convert the VCMLA (vector) insns in the 3same extension group to
2
of doing the lazy stacking of FP registers, the handling of
2
decodetree.
3
possible escalation to HardFault is treated differently to the normal
4
approach: it works based on the saved information about exception
5
readiness that was stored in the FPCCR when the stack frame was
6
created. Provide a new function armv7m_nvic_set_pending_lazyfp()
7
which pends exceptions during lazy stacking, and implements
8
this logic.
9
10
This corresponds to the pseudocode TakePreserveFPException().
11
3
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190416125744.27770-22-peter.maydell@linaro.org
6
Message-id: 20200430181003.21682-5-peter.maydell@linaro.org
15
---
7
---
16
target/arm/cpu.h | 12 ++++++
8
target/arm/neon-shared.decode | 11 ++++++++++
17
hw/intc/armv7m_nvic.c | 96 +++++++++++++++++++++++++++++++++++++++++++
9
target/arm/translate-neon.inc.c | 37 +++++++++++++++++++++++++++++++++
18
2 files changed, 108 insertions(+)
10
target/arm/translate.c | 11 +---------
11
3 files changed, 49 insertions(+), 10 deletions(-)
19
12
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
21
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
15
--- a/target/arm/neon-shared.decode
23
+++ b/target/arm/cpu.h
16
+++ b/target/arm/neon-shared.decode
24
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
17
@@ -XXX,XX +XXX,XX @@
25
* a different exception).
18
# More specifically, this covers:
26
*/
19
# 2reg scalar ext: 0b1111_1110_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
27
void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
20
# 3same ext: 0b1111_110x_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
28
+/**
21
+
29
+ * armv7m_nvic_set_pending_lazyfp: mark this lazy FP exception as pending
22
+# VFP/Neon register fields; same as vfp.decode
30
+ * @opaque: the NVIC
23
+%vm_dp 5:1 0:4
31
+ * @irq: the exception number to mark pending
24
+%vm_sp 0:4 5:1
32
+ * @secure: false for non-banked exceptions or for the nonsecure
25
+%vn_dp 7:1 16:4
33
+ * version of a banked exception, true for the secure version of a banked
26
+%vn_sp 16:4 7:1
34
+ * exception.
27
+%vd_dp 22:1 12:4
35
+ *
28
+%vd_sp 12:4 22:1
36
+ * Similar to armv7m_nvic_set_pending(), but specifically for exceptions
29
+
37
+ * generated in the course of lazy stacking of FP registers.
30
+VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
38
+ */
31
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
39
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure);
32
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
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
33
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/intc/armv7m_nvic.c
34
--- a/target/arm/translate-neon.inc.c
46
+++ b/hw/intc/armv7m_nvic.c
35
+++ b/target/arm/translate-neon.inc.c
47
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
36
@@ -XXX,XX +XXX,XX @@
48
do_armv7m_nvic_set_pending(opaque, irq, secure, true);
37
#include "decode-neon-dp.inc.c"
49
}
38
#include "decode-neon-ls.inc.c"
50
39
#include "decode-neon-shared.inc.c"
51
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
40
+
41
+static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
52
+{
42
+{
53
+ /*
43
+ int opr_sz;
54
+ * Pend an exception during lazy FP stacking. This differs
44
+ TCGv_ptr fpst;
55
+ * from the usual exception pending because the logic for
45
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
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];
71
+
46
+
72
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
47
+ if (!dc_isar_feature(aa32_vcma, s)
73
+ assert(!secure || banked);
48
+ || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
74
+
49
+ return false;
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
76
+
77
+ targets_secure = banked ? secure : exc_targets_secure(s, irq);
78
+
79
+ switch (irq) {
80
+ case ARMV7M_EXCP_DEBUG:
81
+ if (!(fpccr_s & R_V7M_FPCCR_MONRDY_MASK)) {
82
+ /* Ignore DebugMonitor exception */
83
+ return;
84
+ }
85
+ break;
86
+ case ARMV7M_EXCP_MEM:
87
+ escalate = !(fpccr & R_V7M_FPCCR_MMRDY_MASK);
88
+ break;
89
+ case ARMV7M_EXCP_USAGE:
90
+ escalate = !(fpccr & R_V7M_FPCCR_UFRDY_MASK);
91
+ break;
92
+ case ARMV7M_EXCP_BUS:
93
+ escalate = !(fpccr_s & R_V7M_FPCCR_BFRDY_MASK);
94
+ break;
95
+ case ARMV7M_EXCP_SECURE:
96
+ escalate = !(fpccr_s & R_V7M_FPCCR_SFRDY_MASK);
97
+ break;
98
+ default:
99
+ g_assert_not_reached();
100
+ }
50
+ }
101
+
51
+
102
+ if (escalate) {
52
+ /* UNDEF accesses to D16-D31 if they don't exist. */
103
+ /*
53
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
104
+ * Escalate to HardFault: faults that initially targeted Secure
54
+ ((a->vd | a->vn | a->vm) & 0x10)) {
105
+ * continue to do so, even if HF normally targets NonSecure.
55
+ return false;
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
+ }
56
+ }
116
+
57
+
117
+ if (!vec->enabled ||
58
+ if ((a->vn | a->vm | a->vd) & a->q) {
118
+ nvic_exec_prio(s) <= exc_group_prio(s, vec->prio, secure)) {
59
+ return false;
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
+ }
60
+ }
129
+
61
+
130
+ if (escalate) {
62
+ if (!vfp_access_check(s)) {
131
+ s->cpu->env.v7m.hfsr |= R_V7M_HFSR_FORCED_MASK;
63
+ return true;
132
+ }
64
+ }
133
+ if (!vec->pending) {
65
+
134
+ vec->pending = 1;
66
+ opr_sz = (1 + a->q) * 8;
135
+ /*
67
+ fpst = get_fpstatus_ptr(1);
136
+ * We do not call nvic_irq_update(), because we know our caller
68
+ fn_gvec_ptr = a->size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
137
+ * is going to handle causing us to take the exception by
69
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
138
+ * raising EXCP_LAZYFP, so raising the IRQ line would be
70
+ vfp_reg_offset(1, a->vn),
139
+ * pointless extra work. We just need to recompute the
71
+ vfp_reg_offset(1, a->vm),
140
+ * priorities so that armv7m_nvic_can_take_pending_exception()
72
+ fpst, opr_sz, opr_sz, a->rot,
141
+ * returns the right answer.
73
+ fn_gvec_ptr);
142
+ */
74
+ tcg_temp_free_ptr(fpst);
143
+ nvic_recompute_state(s);
75
+ return true;
144
+ }
145
+}
76
+}
146
+
77
diff --git a/target/arm/translate.c b/target/arm/translate.c
147
/* Make pending IRQ active. */
78
index XXXXXXX..XXXXXXX 100644
148
void armv7m_nvic_acknowledge_irq(void *opaque)
79
--- a/target/arm/translate.c
149
{
80
+++ b/target/arm/translate.c
81
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
82
bool is_long = false, q = extract32(insn, 6, 1);
83
bool ptr_is_env = false;
84
85
- if ((insn & 0xfe200f10) == 0xfc200800) {
86
- /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
87
- int size = extract32(insn, 20, 1);
88
- data = extract32(insn, 23, 2); /* rot */
89
- if (!dc_isar_feature(aa32_vcma, s)
90
- || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
91
- return 1;
92
- }
93
- fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
94
- } else if ((insn & 0xfea00f10) == 0xfc800800) {
95
+ if ((insn & 0xfea00f10) == 0xfc800800) {
96
/* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
97
int size = extract32(insn, 20, 1);
98
data = extract32(insn, 24, 1); /* rot */
150
--
99
--
151
2.20.1
100
2.20.1
152
101
153
102
diff view generated by jsdifflib
1
Implement the VLLDM instruction for v7M for the FPU present cas.
1
Convert the VCADD (vector) insns to decodetree.
2
2
3
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>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-26-peter.maydell@linaro.org
5
Message-id: 20200430181003.21682-6-peter.maydell@linaro.org
6
---
6
---
7
target/arm/helper.h | 1 +
7
target/arm/neon-shared.decode | 3 +++
8
target/arm/helper.c | 54 ++++++++++++++++++++++++++++++++++++++++++
8
target/arm/translate-neon.inc.c | 37 +++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 2 +-
9
target/arm/translate.c | 11 +---------
10
3 files changed, 56 insertions(+), 1 deletion(-)
10
3 files changed, 41 insertions(+), 10 deletions(-)
11
11
12
diff --git a/target/arm/helper.h b/target/arm/helper.h
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.h
14
--- a/target/arm/neon-shared.decode
15
+++ b/target/arm/helper.h
15
+++ b/target/arm/neon-shared.decode
16
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
16
@@ -XXX,XX +XXX,XX @@
17
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
17
18
18
VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
19
DEF_HELPER_2(v7m_vlstm, void, env, i32)
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp
20
+DEF_HELPER_2(v7m_vlldm, void, env, i32)
20
+
21
21
+VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
22
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
22
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
23
23
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
25
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.c
25
--- a/target/arm/translate-neon.inc.c
27
+++ b/target/arm/helper.c
26
+++ b/target/arm/translate-neon.inc.c
28
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
27
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
29
g_assert_not_reached();
28
tcg_temp_free_ptr(fpst);
29
return true;
30
}
30
}
31
31
+
32
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
32
+static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
33
+{
33
+{
34
+ /* translate.c should never generate calls here in user-only mode */
34
+ int opr_sz;
35
+ g_assert_not_reached();
35
+ TCGv_ptr fpst;
36
+}
36
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
37
+
37
+
38
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
38
+ if (!dc_isar_feature(aa32_vcma, s)
39
{
39
+ || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
40
/* The TT instructions can be used by unprivileged code, but in
40
+ return false;
41
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
42
env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
43
}
44
45
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
46
+{
47
+ /* fptr is the value of Rn, the frame pointer we load the FP regs from */
48
+ assert(env->v7m.secure);
49
+
50
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
51
+ return;
52
+ }
41
+ }
53
+
42
+
54
+ /* Check access to the coprocessor is permitted */
43
+ /* UNDEF accesses to D16-D31 if they don't exist. */
55
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
44
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
56
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
45
+ ((a->vd | a->vn | a->vm) & 0x10)) {
46
+ return false;
57
+ }
47
+ }
58
+
48
+
59
+ if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
49
+ if ((a->vn | a->vm | a->vd) & a->q) {
60
+ /* State in FP is still valid */
50
+ return false;
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
+ }
51
+ }
89
+
52
+
90
+ env->v7m.control[M_REG_S] |= R_V7M_CONTROL_FPCA_MASK;
53
+ if (!vfp_access_check(s)) {
54
+ return true;
55
+ }
56
+
57
+ opr_sz = (1 + a->q) * 8;
58
+ fpst = get_fpstatus_ptr(1);
59
+ fn_gvec_ptr = a->size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
60
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
61
+ vfp_reg_offset(1, a->vn),
62
+ vfp_reg_offset(1, a->vm),
63
+ fpst, opr_sz, opr_sz, a->rot,
64
+ fn_gvec_ptr);
65
+ tcg_temp_free_ptr(fpst);
66
+ return true;
91
+}
67
+}
92
+
93
static bool v7m_push_stack(ARMCPU *cpu)
94
{
95
/* Do the "set up stack frame" part of exception entry,
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
68
diff --git a/target/arm/translate.c b/target/arm/translate.c
97
index XXXXXXX..XXXXXXX 100644
69
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate.c
70
--- a/target/arm/translate.c
99
+++ b/target/arm/translate.c
71
+++ b/target/arm/translate.c
100
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
72
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
101
TCGv_i32 fptr = load_reg(s, rn);
73
bool is_long = false, q = extract32(insn, 6, 1);
102
74
bool ptr_is_env = false;
103
if (extract32(insn, 20, 1)) {
75
104
- /* VLLDM */
76
- if ((insn & 0xfea00f10) == 0xfc800800) {
105
+ gen_helper_v7m_vlldm(cpu_env, fptr);
77
- /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
106
} else {
78
- int size = extract32(insn, 20, 1);
107
gen_helper_v7m_vlstm(cpu_env, fptr);
79
- data = extract32(insn, 24, 1); /* rot */
108
}
80
- if (!dc_isar_feature(aa32_vcma, s)
81
- || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
82
- return 1;
83
- }
84
- fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
85
- } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
86
+ if ((insn & 0xfeb00f00) == 0xfc200d00) {
87
/* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
88
bool u = extract32(insn, 4, 1);
89
if (!dc_isar_feature(aa32_dp, s)) {
109
--
90
--
110
2.20.1
91
2.20.1
111
92
112
93
diff view generated by jsdifflib
1
Handle floating point registers in exception return.
1
Convert the V[US]DOT (vector) insns to decodetree.
2
This corresponds to pseudocode functions ValidateExceptionReturn(),
3
ExceptionReturn(), PopStack() and ConsumeExcStackFrame().
4
2
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190416125744.27770-16-peter.maydell@linaro.org
5
Message-id: 20200430181003.21682-7-peter.maydell@linaro.org
8
---
6
---
9
target/arm/helper.c | 142 +++++++++++++++++++++++++++++++++++++++++++-
7
target/arm/neon-shared.decode | 4 ++++
10
1 file changed, 141 insertions(+), 1 deletion(-)
8
target/arm/translate-neon.inc.c | 32 ++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 9 +--------
10
3 files changed, 37 insertions(+), 8 deletions(-)
11
11
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
14
--- a/target/arm/neon-shared.decode
15
+++ b/target/arm/helper.c
15
+++ b/target/arm/neon-shared.decode
16
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
16
@@ -XXX,XX +XXX,XX @@ VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
17
bool rettobase = false;
17
18
bool exc_secure = false;
18
VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
19
bool return_to_secure;
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp
20
+ bool ftype;
21
+ bool restore_s16_s31;
22
23
/* If we're not in Handler mode then jumps to magic exception-exit
24
* addresses don't have magic behaviour. However for the v8M
25
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
26
excret);
27
}
28
29
+ ftype = excret & R_V7M_EXCRET_FTYPE_MASK;
30
+
20
+
31
+ if (!arm_feature(env, ARM_FEATURE_VFP) && !ftype) {
21
+# VUDOT and VSDOT
32
+ qemu_log_mask(LOG_GUEST_ERROR, "M profile: zero FTYPE in exception "
22
+VDOT 1111 110 00 . 10 .... .... 1101 . q:1 . u:1 .... \
33
+ "exit PC value 0x%" PRIx32 " is UNPREDICTABLE "
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
34
+ "if FPU not present\n",
24
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
35
+ excret);
25
index XXXXXXX..XXXXXXX 100644
36
+ ftype = true;
26
--- a/target/arm/translate-neon.inc.c
27
+++ b/target/arm/translate-neon.inc.c
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
29
tcg_temp_free_ptr(fpst);
30
return true;
31
}
32
+
33
+static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
34
+{
35
+ int opr_sz;
36
+ gen_helper_gvec_3 *fn_gvec;
37
+
38
+ if (!dc_isar_feature(aa32_dp, s)) {
39
+ return false;
37
+ }
40
+ }
38
+
41
+
39
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
42
+ /* UNDEF accesses to D16-D31 if they don't exist. */
40
/* EXC_RETURN.ES validation check (R_SMFL). We must do this before
43
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
41
* we pick which FAULTMASK to clear.
44
+ ((a->vd | a->vn | a->vm) & 0x10)) {
42
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
45
+ return false;
43
*/
44
write_v7m_control_spsel_for_secstate(env, return_to_sp_process, exc_secure);
45
46
+ /*
47
+ * Clear scratch FP values left in caller saved registers; this
48
+ * must happen before any kind of tail chaining.
49
+ */
50
+ if ((env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_CLRONRET_MASK) &&
51
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
52
+ if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
53
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
54
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
55
+ qemu_log_mask(CPU_LOG_INT, "...taking SecureFault on existing "
56
+ "stackframe: error during lazy state deactivation\n");
57
+ v7m_exception_taken(cpu, excret, true, false);
58
+ return;
59
+ } else {
60
+ /* Clear s0..s15 and FPSCR */
61
+ int i;
62
+
63
+ for (i = 0; i < 16; i += 2) {
64
+ *aa32_vfp_dreg(env, i / 2) = 0;
65
+ }
66
+ vfp_set_fpscr(env, 0);
67
+ }
68
+ }
46
+ }
69
+
47
+
70
if (sfault) {
48
+ if ((a->vn | a->vm | a->vd) & a->q) {
71
env->v7m.sfsr |= R_V7M_SFSR_INVER_MASK;
49
+ return false;
72
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
50
+ }
73
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
74
}
75
}
76
77
+ if (!ftype) {
78
+ /* FP present and we need to handle it */
79
+ if (!return_to_secure &&
80
+ (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK)) {
81
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
82
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
83
+ qemu_log_mask(CPU_LOG_INT,
84
+ "...taking SecureFault on existing stackframe: "
85
+ "Secure LSPACT set but exception return is "
86
+ "not to secure state\n");
87
+ v7m_exception_taken(cpu, excret, true, false);
88
+ return;
89
+ }
90
+
51
+
91
+ restore_s16_s31 = return_to_secure &&
52
+ if (!vfp_access_check(s)) {
92
+ (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
53
+ return true;
54
+ }
93
+
55
+
94
+ if (env->v7m.fpccr[return_to_secure] & R_V7M_FPCCR_LSPACT_MASK) {
56
+ opr_sz = (1 + a->q) * 8;
95
+ /* State in FPU is still valid, just clear LSPACT */
57
+ fn_gvec = a->u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
96
+ env->v7m.fpccr[return_to_secure] &= ~R_V7M_FPCCR_LSPACT_MASK;
58
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
97
+ } else {
59
+ vfp_reg_offset(1, a->vn),
98
+ int i;
60
+ vfp_reg_offset(1, a->vm),
99
+ uint32_t fpscr;
61
+ opr_sz, opr_sz, 0, fn_gvec);
100
+ bool cpacr_pass, nsacr_pass;
62
+ return true;
101
+
63
+}
102
+ cpacr_pass = v7m_cpacr_pass(env, return_to_secure,
64
diff --git a/target/arm/translate.c b/target/arm/translate.c
103
+ return_to_priv);
65
index XXXXXXX..XXXXXXX 100644
104
+ nsacr_pass = return_to_secure ||
66
--- a/target/arm/translate.c
105
+ extract32(env->v7m.nsacr, 10, 1);
67
+++ b/target/arm/translate.c
106
+
68
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
107
+ if (!cpacr_pass) {
69
bool is_long = false, q = extract32(insn, 6, 1);
108
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
70
bool ptr_is_env = false;
109
+ return_to_secure);
71
110
+ env->v7m.cfsr[return_to_secure] |= R_V7M_CFSR_NOCP_MASK;
72
- if ((insn & 0xfeb00f00) == 0xfc200d00) {
111
+ qemu_log_mask(CPU_LOG_INT,
73
- /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
112
+ "...taking UsageFault on existing "
74
- bool u = extract32(insn, 4, 1);
113
+ "stackframe: CPACR.CP10 prevents unstacking "
75
- if (!dc_isar_feature(aa32_dp, s)) {
114
+ "FP regs\n");
76
- return 1;
115
+ v7m_exception_taken(cpu, excret, true, false);
77
- }
116
+ return;
78
- fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
117
+ } else if (!nsacr_pass) {
79
- } else if ((insn & 0xff300f10) == 0xfc200810) {
118
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, true);
80
+ if ((insn & 0xff300f10) == 0xfc200810) {
119
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_INVPC_MASK;
81
/* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
120
+ qemu_log_mask(CPU_LOG_INT,
82
int is_s = extract32(insn, 23, 1);
121
+ "...taking Secure UsageFault on existing "
83
if (!dc_isar_feature(aa32_fhm, s)) {
122
+ "stackframe: NSACR.CP10 prevents unstacking "
123
+ "FP regs\n");
124
+ v7m_exception_taken(cpu, excret, true, false);
125
+ return;
126
+ }
127
+
128
+ for (i = 0; i < (restore_s16_s31 ? 32 : 16); i += 2) {
129
+ uint32_t slo, shi;
130
+ uint64_t dn;
131
+ uint32_t faddr = frameptr + 0x20 + 4 * i;
132
+
133
+ if (i >= 16) {
134
+ faddr += 8; /* Skip the slot for the FPSCR */
135
+ }
136
+
137
+ pop_ok = pop_ok &&
138
+ v7m_stack_read(cpu, &slo, faddr, mmu_idx) &&
139
+ v7m_stack_read(cpu, &shi, faddr + 4, mmu_idx);
140
+
141
+ if (!pop_ok) {
142
+ break;
143
+ }
144
+
145
+ dn = (uint64_t)shi << 32 | slo;
146
+ *aa32_vfp_dreg(env, i / 2) = dn;
147
+ }
148
+ pop_ok = pop_ok &&
149
+ v7m_stack_read(cpu, &fpscr, frameptr + 0x60, mmu_idx);
150
+ if (pop_ok) {
151
+ vfp_set_fpscr(env, fpscr);
152
+ }
153
+ if (!pop_ok) {
154
+ /*
155
+ * These regs are 0 if security extension present;
156
+ * otherwise merely UNKNOWN. We zero always.
157
+ */
158
+ for (i = 0; i < (restore_s16_s31 ? 32 : 16); i += 2) {
159
+ *aa32_vfp_dreg(env, i / 2) = 0;
160
+ }
161
+ vfp_set_fpscr(env, 0);
162
+ }
163
+ }
164
+ }
165
+ env->v7m.control[M_REG_S] = FIELD_DP32(env->v7m.control[M_REG_S],
166
+ V7M_CONTROL, FPCA, !ftype);
167
+
168
/* Commit to consuming the stack frame */
169
frameptr += 0x20;
170
+ if (!ftype) {
171
+ frameptr += 0x48;
172
+ if (restore_s16_s31) {
173
+ frameptr += 0x40;
174
+ }
175
+ }
176
/* Undo stack alignment (the SPREALIGN bit indicates that the original
177
* pre-exception SP was not 8-aligned and we added a padding word to
178
* align it, so we undo this by ORing in the bit that increases it
179
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
180
*frame_sp_p = frameptr;
181
}
182
/* This xpsr_write() will invalidate frame_sp_p as it may switch stack */
183
- xpsr_write(env, xpsr, ~XPSR_SPREALIGN);
184
+ xpsr_write(env, xpsr, ~(XPSR_SPREALIGN | XPSR_SFPA));
185
+
186
+ if (env->v7m.secure) {
187
+ bool sfpa = xpsr & XPSR_SFPA;
188
+
189
+ env->v7m.control[M_REG_S] = FIELD_DP32(env->v7m.control[M_REG_S],
190
+ V7M_CONTROL, SFPA, sfpa);
191
+ }
192
193
/* The restored xPSR exception field will be zero if we're
194
* resuming in Thread mode. If that doesn't match what the
195
--
84
--
196
2.20.1
85
2.20.1
197
86
198
87
diff view generated by jsdifflib
1
The TailChain() pseudocode specifies that a tail chaining
1
Convert the VFM[AS]L (vector) insns to decodetree. This is the last
2
exception should sanitize the excReturn all-ones bits and
2
insn in the legacy decoder for the 3same_ext group, so we can
3
(if there is no FPU) the excReturn FType bits; we weren't
3
delete the legacy decoder function for the group entirely.
4
doing this.
4
5
Note that in disas_thumb2_insn() the parts of this encoding space
6
where the decodetree decoder returns false will correctly be directed
7
to illegal_op by the "(insn & (1 << 28))" check so they won't fall
8
into disas_coproc_insn() by mistake.
5
9
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-14-peter.maydell@linaro.org
12
Message-id: 20200430181003.21682-8-peter.maydell@linaro.org
9
---
13
---
10
target/arm/helper.c | 8 ++++++++
14
target/arm/neon-shared.decode | 6 +++
11
1 file changed, 8 insertions(+)
15
target/arm/translate-neon.inc.c | 31 +++++++++++
16
target/arm/translate.c | 92 +--------------------------------
17
3 files changed, 38 insertions(+), 91 deletions(-)
12
18
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
21
--- a/target/arm/neon-shared.decode
16
+++ b/target/arm/helper.c
22
+++ b/target/arm/neon-shared.decode
17
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
23
@@ -XXX,XX +XXX,XX @@ VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
18
qemu_log_mask(CPU_LOG_INT, "...taking pending %s exception %d\n",
24
# VUDOT and VSDOT
19
targets_secure ? "secure" : "nonsecure", exc);
25
VDOT 1111 110 00 . 10 .... .... 1101 . q:1 . u:1 .... \
20
26
vm=%vm_dp vn=%vn_dp vd=%vd_dp
21
+ if (dotailchain) {
27
+
22
+ /* Sanitize LR FType and PREFIX bits */
28
+# VFM[AS]L
23
+ if (!arm_feature(env, ARM_FEATURE_VFP)) {
29
+VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
24
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
30
+ vm=%vm_sp vn=%vn_sp vd=%vd_dp q=0
25
+ }
31
+VFML 1111 110 0 s:1 . 10 .... .... 1000 . 1 . 1 .... \
26
+ lr = deposit32(lr, 24, 8, 0xff);
32
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp q=1
33
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-neon.inc.c
36
+++ b/target/arm/translate-neon.inc.c
37
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
38
opr_sz, opr_sz, 0, fn_gvec);
39
return true;
40
}
41
+
42
+static bool trans_VFML(DisasContext *s, arg_VFML *a)
43
+{
44
+ int opr_sz;
45
+
46
+ if (!dc_isar_feature(aa32_fhm, s)) {
47
+ return false;
27
+ }
48
+ }
28
+
49
+
29
if (arm_feature(env, ARM_FEATURE_V8)) {
50
+ /* UNDEF accesses to D16-D31 if they don't exist. */
30
if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
51
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
31
(lr & R_V7M_EXCRET_S_MASK)) {
52
+ (a->vd & 0x10)) {
53
+ return false;
54
+ }
55
+
56
+ if (a->vd & a->q) {
57
+ return false;
58
+ }
59
+
60
+ if (!vfp_access_check(s)) {
61
+ return true;
62
+ }
63
+
64
+ opr_sz = (1 + a->q) * 8;
65
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
66
+ vfp_reg_offset(a->q, a->vn),
67
+ vfp_reg_offset(a->q, a->vm),
68
+ cpu_env, opr_sz, opr_sz, a->s, /* is_2 == 0 */
69
+ gen_helper_gvec_fmlal_a32);
70
+ return true;
71
+}
72
diff --git a/target/arm/translate.c b/target/arm/translate.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/translate.c
75
+++ b/target/arm/translate.c
76
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
77
return 0;
78
}
79
80
-/* Advanced SIMD three registers of the same length extension.
81
- * 31 25 23 22 20 16 12 11 10 9 8 3 0
82
- * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
83
- * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
84
- * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
85
- */
86
-static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
87
-{
88
- gen_helper_gvec_3 *fn_gvec = NULL;
89
- gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
90
- int rd, rn, rm, opr_sz;
91
- int data = 0;
92
- int off_rn, off_rm;
93
- bool is_long = false, q = extract32(insn, 6, 1);
94
- bool ptr_is_env = false;
95
-
96
- if ((insn & 0xff300f10) == 0xfc200810) {
97
- /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
98
- int is_s = extract32(insn, 23, 1);
99
- if (!dc_isar_feature(aa32_fhm, s)) {
100
- return 1;
101
- }
102
- is_long = true;
103
- data = is_s; /* is_2 == 0 */
104
- fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
105
- ptr_is_env = true;
106
- } else {
107
- return 1;
108
- }
109
-
110
- VFP_DREG_D(rd, insn);
111
- if (rd & q) {
112
- return 1;
113
- }
114
- if (q || !is_long) {
115
- VFP_DREG_N(rn, insn);
116
- VFP_DREG_M(rm, insn);
117
- if ((rn | rm) & q & !is_long) {
118
- return 1;
119
- }
120
- off_rn = vfp_reg_offset(1, rn);
121
- off_rm = vfp_reg_offset(1, rm);
122
- } else {
123
- rn = VFP_SREG_N(insn);
124
- rm = VFP_SREG_M(insn);
125
- off_rn = vfp_reg_offset(0, rn);
126
- off_rm = vfp_reg_offset(0, rm);
127
- }
128
-
129
- if (s->fp_excp_el) {
130
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
131
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
132
- return 0;
133
- }
134
- if (!s->vfp_enabled) {
135
- return 1;
136
- }
137
-
138
- opr_sz = (1 + q) * 8;
139
- if (fn_gvec_ptr) {
140
- TCGv_ptr ptr;
141
- if (ptr_is_env) {
142
- ptr = cpu_env;
143
- } else {
144
- ptr = get_fpstatus_ptr(1);
145
- }
146
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
147
- opr_sz, opr_sz, data, fn_gvec_ptr);
148
- if (!ptr_is_env) {
149
- tcg_temp_free_ptr(ptr);
150
- }
151
- } else {
152
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
153
- opr_sz, opr_sz, data, fn_gvec);
154
- }
155
- return 0;
156
-}
157
-
158
/* Advanced SIMD two registers and a scalar extension.
159
* 31 24 23 22 20 16 12 11 10 9 8 3 0
160
* +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
161
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
162
}
163
}
164
}
165
- } else if ((insn & 0x0e000a00) == 0x0c000800
166
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
167
- if (disas_neon_insn_3same_ext(s, insn)) {
168
- goto illegal_op;
169
- }
170
- return;
171
} else if ((insn & 0x0f000a00) == 0x0e000800
172
&& arm_dc_feature(s, ARM_FEATURE_V8)) {
173
if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
174
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
175
}
176
break;
177
}
178
- if ((insn & 0xfe000a00) == 0xfc000800
179
+ if ((insn & 0xff000a00) == 0xfe000800
180
&& arm_dc_feature(s, ARM_FEATURE_V8)) {
181
/* The Thumb2 and ARM encodings are identical. */
182
- if (disas_neon_insn_3same_ext(s, insn)) {
183
- goto illegal_op;
184
- }
185
- } else if ((insn & 0xff000a00) == 0xfe000800
186
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
187
- /* The Thumb2 and ARM encodings are identical. */
188
if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
189
goto illegal_op;
190
}
32
--
191
--
33
2.20.1
192
2.20.1
34
193
35
194
diff view generated by jsdifflib
1
The M-profile architecture floating point system supports
1
Convert VCMLA (scalar) in the 2reg-scalar-ext group to decodetree.
2
lazy FP state preservation, where FP registers are not
3
pushed to the stack when an exception occurs but are instead
4
only saved if and when the first FP instruction in the exception
5
handler is executed. Implement this in QEMU, corresponding
6
to the check of LSPACT in the pseudocode ExecuteFPCheck().
7
2
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20190416125744.27770-24-peter.maydell@linaro.org
5
Message-id: 20200430181003.21682-9-peter.maydell@linaro.org
11
---
6
---
12
target/arm/cpu.h | 3 ++
7
target/arm/neon-shared.decode | 5 +++++
13
target/arm/helper.h | 2 +
8
target/arm/translate-neon.inc.c | 40 +++++++++++++++++++++++++++++++++
14
target/arm/translate.h | 1 +
9
target/arm/translate.c | 26 +--------------------
15
target/arm/helper.c | 112 +++++++++++++++++++++++++++++++++++++++++
10
3 files changed, 46 insertions(+), 25 deletions(-)
16
target/arm/translate.c | 22 ++++++++
17
5 files changed, 140 insertions(+)
18
11
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
14
--- a/target/arm/neon-shared.decode
22
+++ b/target/arm/cpu.h
15
+++ b/target/arm/neon-shared.decode
23
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
24
#define EXCP_NOCP 17 /* v7M NOCP UsageFault */
17
vm=%vm_sp vn=%vn_sp vd=%vd_dp q=0
25
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
18
VFML 1111 110 0 s:1 . 10 .... .... 1000 . 1 . 1 .... \
26
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp q=1
27
+#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
20
+
28
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
21
+VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
29
22
+ vn=%vn_dp vd=%vd_dp size=0
30
#define ARMV7M_EXCP_RESET 1
23
+VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
31
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
24
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp size=1 index=0
32
FIELD(TBFLAG_A32, VFPEN, 7, 1)
25
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
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
26
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/helper.h
27
--- a/target/arm/translate-neon.inc.c
43
+++ b/target/arm/helper.h
28
+++ b/target/arm/translate-neon.inc.c
44
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(v7m_blxns, void, env, i32)
29
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML(DisasContext *s, arg_VFML *a)
45
30
gen_helper_gvec_fmlal_a32);
46
DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
31
return true;
47
32
}
48
+DEF_HELPER_1(v7m_preserve_fp_state, void, env)
49
+
33
+
50
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
34
+static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
51
52
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
53
diff --git a/target/arm/translate.h b/target/arm/translate.h
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/translate.h
56
+++ b/target/arm/translate.h
57
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
58
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
59
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
60
bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
61
+ bool v7m_lspact; /* FPCCR.LSPACT set */
62
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
63
* so that top level loop can generate correct syndrome information.
64
*/
65
diff --git a/target/arm/helper.c b/target/arm/helper.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/helper.c
68
+++ b/target/arm/helper.c
69
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
70
g_assert_not_reached();
71
}
72
73
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
74
+{
35
+{
75
+ /* translate.c should never generate calls here in user-only mode */
36
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
76
+ g_assert_not_reached();
37
+ int opr_sz;
77
+}
38
+ TCGv_ptr fpst;
78
+
39
+
79
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
40
+ if (!dc_isar_feature(aa32_vcma, s)) {
80
{
41
+ return false;
81
/* The TT instructions can be used by unprivileged code, but in
42
+ }
82
@@ -XXX,XX +XXX,XX @@ pend_fault:
43
+ if (a->size == 0 && !dc_isar_feature(aa32_fp16_arith, s)) {
83
return false;
44
+ return false;
84
}
85
86
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
87
+{
88
+ /*
89
+ * Preserve FP state (because LSPACT was set and we are about
90
+ * to execute an FP instruction). This corresponds to the
91
+ * PreserveFPState() pseudocode.
92
+ * We may throw an exception if the stacking fails.
93
+ */
94
+ ARMCPU *cpu = arm_env_get_cpu(env);
95
+ bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
96
+ bool negpri = !(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_HFRDY_MASK);
97
+ bool is_priv = !(env->v7m.fpccr[is_secure] & R_V7M_FPCCR_USER_MASK);
98
+ bool splimviol = env->v7m.fpccr[is_secure] & R_V7M_FPCCR_SPLIMVIOL_MASK;
99
+ uint32_t fpcar = env->v7m.fpcar[is_secure];
100
+ bool stacked_ok = true;
101
+ bool ts = is_secure && (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
102
+ bool take_exception;
103
+
104
+ /* Take the iothread lock as we are going to touch the NVIC */
105
+ qemu_mutex_lock_iothread();
106
+
107
+ /* Check the background context had access to the FPU */
108
+ if (!v7m_cpacr_pass(env, is_secure, is_priv)) {
109
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, is_secure);
110
+ env->v7m.cfsr[is_secure] |= R_V7M_CFSR_NOCP_MASK;
111
+ stacked_ok = false;
112
+ } else if (!is_secure && !extract32(env->v7m.nsacr, 10, 1)) {
113
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
114
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
115
+ stacked_ok = false;
116
+ }
45
+ }
117
+
46
+
118
+ if (!splimviol && stacked_ok) {
47
+ /* UNDEF accesses to D16-D31 if they don't exist. */
119
+ /* We only stack if the stack limit wasn't violated */
48
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
120
+ int i;
49
+ ((a->vd | a->vn | a->vm) & 0x10)) {
121
+ ARMMMUIdx mmu_idx;
50
+ return false;
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
+ }
51
+ }
142
+
52
+
143
+ /*
53
+ if ((a->vd | a->vn) & a->q) {
144
+ * We definitely pended an exception, but it's possible that it
54
+ return false;
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
+ }
55
+ }
159
+
56
+
160
+ env->v7m.fpccr[is_secure] &= ~R_V7M_FPCCR_LSPACT_MASK;
57
+ if (!vfp_access_check(s)) {
161
+
58
+ return true;
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
+ }
59
+ }
212
+
60
+
213
*pflags = flags;
61
+ fn_gvec_ptr = (a->size ? gen_helper_gvec_fcmlas_idx
214
*cs_base = 0;
62
+ : gen_helper_gvec_fcmlah_idx);
215
}
63
+ opr_sz = (1 + a->q) * 8;
64
+ fpst = get_fpstatus_ptr(1);
65
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
66
+ vfp_reg_offset(1, a->vn),
67
+ vfp_reg_offset(1, a->vm),
68
+ fpst, opr_sz, opr_sz,
69
+ (a->index << 2) | a->rot, fn_gvec_ptr);
70
+ tcg_temp_free_ptr(fpst);
71
+ return true;
72
+}
216
diff --git a/target/arm/translate.c b/target/arm/translate.c
73
diff --git a/target/arm/translate.c b/target/arm/translate.c
217
index XXXXXXX..XXXXXXX 100644
74
index XXXXXXX..XXXXXXX 100644
218
--- a/target/arm/translate.c
75
--- a/target/arm/translate.c
219
+++ b/target/arm/translate.c
76
+++ b/target/arm/translate.c
220
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
77
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
221
if (arm_dc_feature(s, ARM_FEATURE_M)) {
78
bool is_long = false, q = extract32(insn, 6, 1);
222
/* Handle M-profile lazy FP state mechanics */
79
bool ptr_is_env = false;
223
80
224
+ /* Trigger lazy-state preservation if necessary */
81
- if ((insn & 0xff000f10) == 0xfe000800) {
225
+ if (s->v7m_lspact) {
82
- /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
226
+ /*
83
- int rot = extract32(insn, 20, 2);
227
+ * Lazy state saving affects external memory and also the NVIC,
84
- int size = extract32(insn, 23, 1);
228
+ * so we must mark it as an IO operation for icount.
85
- int index;
229
+ */
86
-
230
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
87
- if (!dc_isar_feature(aa32_vcma, s)) {
231
+ gen_io_start();
88
- return 1;
232
+ }
89
- }
233
+ gen_helper_v7m_preserve_fp_state(cpu_env);
90
- if (size == 0) {
234
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
91
- if (!dc_isar_feature(aa32_fp16_arith, s)) {
235
+ gen_io_end();
92
- return 1;
236
+ }
93
- }
237
+ /*
94
- /* For fp16, rm is just Vm, and index is M. */
238
+ * If the preserve_fp_state helper doesn't throw an exception
95
- rm = extract32(insn, 0, 4);
239
+ * then it will clear LSPACT; we don't need to repeat this for
96
- index = extract32(insn, 5, 1);
240
+ * any further FP insns in this TB.
97
- } else {
241
+ */
98
- /* For fp32, rm is the usual M:Vm, and index is 0. */
242
+ s->v7m_lspact = false;
99
- VFP_DREG_M(rm, insn);
243
+ }
100
- index = 0;
244
+
101
- }
245
/* Update ownership of FP context: set FPCCR.S to match current state */
102
- data = (index << 2) | rot;
246
if (s->v8m_fpccr_s_wrong) {
103
- fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
247
TCGv_i32 tmp;
104
- : gen_helper_gvec_fcmlah_idx);
248
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
105
- } else if ((insn & 0xffb00f00) == 0xfe200d00) {
249
dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
106
+ if ((insn & 0xffb00f00) == 0xfe200d00) {
250
dc->v7m_new_fp_ctxt_needed =
107
/* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
251
FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
108
int u = extract32(insn, 4, 1);
252
+ dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_A32, LSPACT);
253
dc->cp_regs = cpu->cp_regs;
254
dc->features = env->features;
255
109
256
--
110
--
257
2.20.1
111
2.20.1
258
112
259
113
diff view generated by jsdifflib
1
Like AArch64, M-profile floating point has no FPEXC enable
1
Convert the V[US]DOT (scalar) insns in the 2reg-scalar-ext group
2
bit to gate floating point; so always set the VFPEN TB flag.
2
to decodetree.
3
4
M-profile also has CPACR and NSACR similar to A-profile;
5
they behave slightly differently:
6
* the CPACR is banked between Secure and Non-Secure
7
* if the NSACR forces a trap then this is taken to
8
the Secure state, not the Non-Secure state
9
10
Honour the CPACR and NSACR settings. The NSACR handling
11
requires us to borrow the exception.target_el field
12
(usually meaningless for M profile) to distinguish the
13
NOCP UsageFault taken to Secure state from the more
14
usual fault taken to the current security state.
15
3
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Message-id: 20190416125744.27770-6-peter.maydell@linaro.org
6
Message-id: 20200430181003.21682-10-peter.maydell@linaro.org
19
---
7
---
20
target/arm/helper.c | 55 +++++++++++++++++++++++++++++++++++++++---
8
target/arm/neon-shared.decode | 3 +++
21
target/arm/translate.c | 10 ++++++--
9
target/arm/translate-neon.inc.c | 35 +++++++++++++++++++++++++++++++++
22
2 files changed, 60 insertions(+), 5 deletions(-)
10
target/arm/translate.c | 13 +-----------
11
3 files changed, 39 insertions(+), 12 deletions(-)
23
12
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
25
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.c
15
--- a/target/arm/neon-shared.decode
27
+++ b/target/arm/helper.c
16
+++ b/target/arm/neon-shared.decode
28
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
17
@@ -XXX,XX +XXX,XX @@ VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
29
return target_el;
18
vn=%vn_dp vd=%vd_dp size=0
19
VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
20
vm=%vm_dp vn=%vn_dp vd=%vd_dp size=1 index=0
21
+
22
+VDOT_scalar 1111 1110 0 . 10 .... .... 1101 . q:1 index:1 u:1 rm:4 \
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
24
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/translate-neon.inc.c
27
+++ b/target/arm/translate-neon.inc.c
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
29
tcg_temp_free_ptr(fpst);
30
return true;
30
}
31
}
31
32
+
32
+/*
33
+static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
33
+ * Return true if the v7M CPACR permits access to the FPU for the specified
34
+ * security state and privilege level.
35
+ */
36
+static bool v7m_cpacr_pass(CPUARMState *env, bool is_secure, bool is_priv)
37
+{
34
+{
38
+ switch (extract32(env->v7m.cpacr[is_secure], 20, 2)) {
35
+ gen_helper_gvec_3 *fn_gvec;
39
+ case 0:
36
+ int opr_sz;
40
+ case 2: /* UNPREDICTABLE: we treat like 0 */
37
+ TCGv_ptr fpst;
38
+
39
+ if (!dc_isar_feature(aa32_dp, s)) {
41
+ return false;
40
+ return false;
42
+ case 1:
43
+ return is_priv;
44
+ case 3:
45
+ return true;
46
+ default:
47
+ g_assert_not_reached();
48
+ }
49
+}
50
+
51
static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
52
ARMMMUIdx mmu_idx, bool ignfault)
53
{
54
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
55
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNDEFINSTR_MASK;
56
break;
57
case EXCP_NOCP:
58
- armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
59
- env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_NOCP_MASK;
60
+ {
61
+ /*
62
+ * NOCP might be directed to something other than the current
63
+ * security state if this fault is because of NSACR; we indicate
64
+ * the target security state using exception.target_el.
65
+ */
66
+ int target_secstate;
67
+
68
+ if (env->exception.target_el == 3) {
69
+ target_secstate = M_REG_S;
70
+ } else {
71
+ target_secstate = env->v7m.secure;
72
+ }
73
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, target_secstate);
74
+ env->v7m.cfsr[target_secstate] |= R_V7M_CFSR_NOCP_MASK;
75
break;
76
+ }
77
case EXCP_INVSTATE:
78
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
79
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVSTATE_MASK;
80
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
81
return 0;
82
}
83
84
+ if (arm_feature(env, ARM_FEATURE_M)) {
85
+ /* CPACR can cause a NOCP UsageFault taken to current security state */
86
+ if (!v7m_cpacr_pass(env, env->v7m.secure, cur_el != 0)) {
87
+ return 1;
88
+ }
89
+
90
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) && !env->v7m.secure) {
91
+ if (!extract32(env->v7m.nsacr, 10, 1)) {
92
+ /* FP insns cause a NOCP UsageFault taken to Secure */
93
+ return 3;
94
+ }
95
+ }
96
+
97
+ return 0;
98
+ }
41
+ }
99
+
42
+
100
/* The CPACR controls traps to EL1, or PL1 if we're 32 bit:
43
+ /* UNDEF accesses to D16-D31 if they don't exist. */
101
* 0, 2 : trap EL0 and EL1/PL1 accesses
44
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
102
* 1 : trap only EL0 accesses
45
+ ((a->vd | a->vn) & 0x10)) {
103
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
46
+ return false;
104
flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, arm_sctlr_b(env));
47
+ }
105
flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
48
+
106
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
49
+ if ((a->vd | a->vn) & a->q) {
107
- || arm_el_is_aa64(env, 1)) {
50
+ return false;
108
+ || arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
51
+ }
109
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
52
+
110
}
53
+ if (!vfp_access_check(s)) {
111
flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
54
+ return true;
55
+ }
56
+
57
+ fn_gvec = a->u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
58
+ opr_sz = (1 + a->q) * 8;
59
+ fpst = get_fpstatus_ptr(1);
60
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
61
+ vfp_reg_offset(1, a->vn),
62
+ vfp_reg_offset(1, a->rm),
63
+ opr_sz, opr_sz, a->index, fn_gvec);
64
+ tcg_temp_free_ptr(fpst);
65
+ return true;
66
+}
112
diff --git a/target/arm/translate.c b/target/arm/translate.c
67
diff --git a/target/arm/translate.c b/target/arm/translate.c
113
index XXXXXXX..XXXXXXX 100644
68
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/translate.c
69
--- a/target/arm/translate.c
115
+++ b/target/arm/translate.c
70
+++ b/target/arm/translate.c
116
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
71
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
117
* for attempts to execute invalid vfp/neon encodings with FP disabled.
72
bool is_long = false, q = extract32(insn, 6, 1);
118
*/
73
bool ptr_is_env = false;
119
if (s->fp_excp_el) {
74
120
- gen_exception_insn(s, 4, EXCP_UDEF,
75
- if ((insn & 0xffb00f00) == 0xfe200d00) {
121
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
76
- /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
122
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
77
- int u = extract32(insn, 4, 1);
123
+ gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
78
-
124
+ s->fp_excp_el);
79
- if (!dc_isar_feature(aa32_dp, s)) {
125
+ } else {
80
- return 1;
126
+ gen_exception_insn(s, 4, EXCP_UDEF,
81
- }
127
+ syn_fp_access_trap(1, 0xe, false),
82
- fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
128
+ s->fp_excp_el);
83
- /* rm is just Vm, and index is M. */
129
+ }
84
- data = extract32(insn, 5, 1); /* index */
130
return 0;
85
- rm = extract32(insn, 0, 4);
131
}
86
- } else if ((insn & 0xffa00f10) == 0xfe000810) {
132
87
+ if ((insn & 0xffa00f10) == 0xfe000810) {
88
/* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
89
int is_s = extract32(insn, 20, 1);
90
int vm20 = extract32(insn, 0, 3);
133
--
91
--
134
2.20.1
92
2.20.1
135
93
136
94
diff view generated by jsdifflib
1
The only "system register" that M-profile floating point exposes
1
Convert the VFM[AS]L (scalar) insns in the 2reg-scalar-ext group
2
via the VMRS/VMRS instructions is FPSCR, and it does not have
2
to decodetree. These are the last ones in the group so we can remove
3
the odd special case for rd==15. Add a check to ensure we only
3
all the legacy decode for the group.
4
expose FPSCR.
4
5
Note that in disas_thumb2_insn() the parts of this encoding space
6
where the decodetree decoder returns false will correctly be directed
7
to illegal_op by the "(insn & (1 << 28))" check so they won't fall
8
into disas_coproc_insn() by mistake.
5
9
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-5-peter.maydell@linaro.org
12
Message-id: 20200430181003.21682-11-peter.maydell@linaro.org
9
---
13
---
10
target/arm/translate.c | 19 +++++++++++++++++--
14
target/arm/neon-shared.decode | 7 +++
11
1 file changed, 17 insertions(+), 2 deletions(-)
15
target/arm/translate-neon.inc.c | 32 ++++++++++
12
16
target/arm/translate.c | 107 +-------------------------------
17
3 files changed, 40 insertions(+), 106 deletions(-)
18
19
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/neon-shared.decode
22
+++ b/target/arm/neon-shared.decode
23
@@ -XXX,XX +XXX,XX @@ VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
24
25
VDOT_scalar 1111 1110 0 . 10 .... .... 1101 . q:1 index:1 u:1 rm:4 \
26
vm=%vm_dp vn=%vn_dp vd=%vd_dp
27
+
28
+%vfml_scalar_q0_rm 0:3 5:1
29
+%vfml_scalar_q1_index 5:1 3:1
30
+VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 0 . 1 index:1 ... \
31
+ rm=%vfml_scalar_q0_rm vn=%vn_sp vd=%vd_dp q=0
32
+VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 1 . 1 . rm:3 \
33
+ index=%vfml_scalar_q1_index vn=%vn_dp vd=%vd_dp q=1
34
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-neon.inc.c
37
+++ b/target/arm/translate-neon.inc.c
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
39
tcg_temp_free_ptr(fpst);
40
return true;
41
}
42
+
43
+static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
44
+{
45
+ int opr_sz;
46
+
47
+ if (!dc_isar_feature(aa32_fhm, s)) {
48
+ return false;
49
+ }
50
+
51
+ /* UNDEF accesses to D16-D31 if they don't exist. */
52
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
53
+ ((a->vd & 0x10) || (a->q && (a->vn & 0x10)))) {
54
+ return false;
55
+ }
56
+
57
+ if (a->vd & a->q) {
58
+ return false;
59
+ }
60
+
61
+ if (!vfp_access_check(s)) {
62
+ return true;
63
+ }
64
+
65
+ opr_sz = (1 + a->q) * 8;
66
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
67
+ vfp_reg_offset(a->q, a->vn),
68
+ vfp_reg_offset(a->q, a->rm),
69
+ cpu_env, opr_sz, opr_sz,
70
+ (a->index << 2) | a->s, /* is_2 == 0 */
71
+ gen_helper_gvec_fmlal_idx_a32);
72
+ return true;
73
+}
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
74
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
index XXXXXXX..XXXXXXX 100644
75
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
76
--- a/target/arm/translate.c
16
+++ b/target/arm/translate.c
77
+++ b/target/arm/translate.c
17
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
78
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
79
}
80
81
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
82
-#define VFP_SREG(insn, bigbit, smallbit) \
83
- ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
84
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
85
if (dc_isar_feature(aa32_simd_r32, s)) { \
86
reg = (((insn) >> (bigbit)) & 0x0f) \
87
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
88
reg = ((insn) >> (bigbit)) & 0x0f; \
89
}} while (0)
90
91
-#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
92
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
93
-#define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
94
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
95
-#define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
96
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
97
98
static void gen_neon_dup_low16(TCGv_i32 var)
99
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
100
return 0;
101
}
102
103
-/* Advanced SIMD two registers and a scalar extension.
104
- * 31 24 23 22 20 16 12 11 10 9 8 3 0
105
- * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
106
- * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
107
- * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
108
- *
109
- */
110
-
111
-static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
112
-{
113
- gen_helper_gvec_3 *fn_gvec = NULL;
114
- gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
115
- int rd, rn, rm, opr_sz, data;
116
- int off_rn, off_rm;
117
- bool is_long = false, q = extract32(insn, 6, 1);
118
- bool ptr_is_env = false;
119
-
120
- if ((insn & 0xffa00f10) == 0xfe000810) {
121
- /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
122
- int is_s = extract32(insn, 20, 1);
123
- int vm20 = extract32(insn, 0, 3);
124
- int vm3 = extract32(insn, 3, 1);
125
- int m = extract32(insn, 5, 1);
126
- int index;
127
-
128
- if (!dc_isar_feature(aa32_fhm, s)) {
129
- return 1;
130
- }
131
- if (q) {
132
- rm = vm20;
133
- index = m * 2 + vm3;
134
- } else {
135
- rm = vm20 * 2 + m;
136
- index = vm3;
137
- }
138
- is_long = true;
139
- data = (index << 2) | is_s; /* is_2 == 0 */
140
- fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
141
- ptr_is_env = true;
142
- } else {
143
- return 1;
144
- }
145
-
146
- VFP_DREG_D(rd, insn);
147
- if (rd & q) {
148
- return 1;
149
- }
150
- if (q || !is_long) {
151
- VFP_DREG_N(rn, insn);
152
- if (rn & q & !is_long) {
153
- return 1;
154
- }
155
- off_rn = vfp_reg_offset(1, rn);
156
- off_rm = vfp_reg_offset(1, rm);
157
- } else {
158
- rn = VFP_SREG_N(insn);
159
- off_rn = vfp_reg_offset(0, rn);
160
- off_rm = vfp_reg_offset(0, rm);
161
- }
162
- if (s->fp_excp_el) {
163
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
164
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
165
- return 0;
166
- }
167
- if (!s->vfp_enabled) {
168
- return 1;
169
- }
170
-
171
- opr_sz = (1 + q) * 8;
172
- if (fn_gvec_ptr) {
173
- TCGv_ptr ptr;
174
- if (ptr_is_env) {
175
- ptr = cpu_env;
176
- } else {
177
- ptr = get_fpstatus_ptr(1);
178
- }
179
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
180
- opr_sz, opr_sz, data, fn_gvec_ptr);
181
- if (!ptr_is_env) {
182
- tcg_temp_free_ptr(ptr);
183
- }
184
- } else {
185
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
186
- opr_sz, opr_sz, data, fn_gvec);
187
- }
188
- return 0;
189
-}
190
-
191
static int disas_coproc_insn(DisasContext *s, uint32_t insn)
192
{
193
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
194
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
18
}
195
}
19
}
196
}
20
} else { /* !dp */
197
}
21
+ bool is_sysreg;
198
- } else if ((insn & 0x0f000a00) == 0x0e000800
22
+
199
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
23
if ((insn & 0x6f) != 0x00)
200
- if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
24
return 1;
201
- goto illegal_op;
25
rn = VFP_SREG_N(insn);
202
- }
26
+
203
- return;
27
+ is_sysreg = extract32(insn, 21, 1);
204
}
28
+
205
goto illegal_op;
29
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
206
}
30
+ /*
207
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
31
+ * The only M-profile VFP vmrs/vmsr sysreg is FPSCR.
208
}
32
+ * Writes to R15 are UNPREDICTABLE; we choose to undef.
209
break;
33
+ */
210
}
34
+ if (is_sysreg && (rd == 15 || (rn >> 1) != ARM_VFP_FPSCR)) {
211
- if ((insn & 0xff000a00) == 0xfe000800
35
+ return 1;
212
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
36
+ }
213
- /* The Thumb2 and ARM encodings are identical. */
37
+ }
214
- if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
38
+
215
- goto illegal_op;
39
if (insn & ARM_CP_RW_BIT) {
216
- }
40
/* vfp->arm */
217
- } else if (((insn >> 24) & 3) == 3) {
41
- if (insn & (1 << 21)) {
218
+ if (((insn >> 24) & 3) == 3) {
42
+ if (is_sysreg) {
219
/* Translate into the equivalent ARM encoding. */
43
/* system register */
220
insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
44
rn >>= 1;
221
if (disas_neon_data_insn(s, insn)) {
45
46
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
47
}
48
} else {
49
/* arm->vfp */
50
- if (insn & (1 << 21)) {
51
+ if (is_sysreg) {
52
rn >>= 1;
53
/* system register */
54
switch (rn) {
55
--
222
--
56
2.20.1
223
2.20.1
57
224
58
225
diff view generated by jsdifflib
1
Handle floating point registers in exception entry.
1
Convert the Neon "load/store multiple structures" insns to decodetree.
2
This corresponds to the FP-specific parts of the pseudocode
3
functions ActivateException() and PushStack().
4
5
We defer the code corresponding to UpdateFPCCR() to a later patch.
6
2
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-11-peter.maydell@linaro.org
5
Message-id: 20200430181003.21682-12-peter.maydell@linaro.org
10
---
6
---
11
target/arm/helper.c | 98 +++++++++++++++++++++++++++++++++++++++++++--
7
target/arm/neon-ls.decode | 7 ++
12
1 file changed, 95 insertions(+), 3 deletions(-)
8
target/arm/translate-neon.inc.c | 124 ++++++++++++++++++++++++++++++++
13
9
target/arm/translate.c | 91 +----------------------
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
10
3 files changed, 133 insertions(+), 89 deletions(-)
11
12
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
15
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
14
--- a/target/arm/neon-ls.decode
17
+++ b/target/arm/helper.c
15
+++ b/target/arm/neon-ls.decode
18
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
16
@@ -XXX,XX +XXX,XX @@
19
switch_v7m_security_state(env, targets_secure);
17
# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
20
write_v7m_control_spsel(env, 0);
18
# This file works on the A32 encoding only; calling code for T32 has to
21
arm_clear_exclusive(env);
19
# transform the insn into the A32 version first.
22
+ /* Clear SFPA and FPCA (has no effect if no FPU) */
20
+
23
+ env->v7m.control[M_REG_S] &=
21
+%vd_dp 22:1 12:4
24
+ ~(R_V7M_CONTROL_FPCA_MASK | R_V7M_CONTROL_SFPA_MASK);
22
+
25
/* Clear IT bits */
23
+# Neon load/store multiple structures
26
env->condexec_bits = 0;
24
+
27
env->regs[14] = lr;
25
+VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
28
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
26
+ vd=%vd_dp
29
uint32_t xpsr = xpsr_read(env);
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
30
uint32_t frameptr = env->regs[13];
28
index XXXXXXX..XXXXXXX 100644
31
ARMMMUIdx mmu_idx = arm_mmu_idx(env);
29
--- a/target/arm/translate-neon.inc.c
32
+ uint32_t framesize;
30
+++ b/target/arm/translate-neon.inc.c
33
+ bool nsacr_cp10 = extract32(env->v7m.nsacr, 10, 1);
31
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
34
+
32
gen_helper_gvec_fmlal_idx_a32);
35
+ if ((env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) &&
33
return true;
36
+ (env->v7m.secure || nsacr_cp10)) {
34
}
37
+ if (env->v7m.secure &&
35
+
38
+ env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK) {
36
+static struct {
39
+ framesize = 0xa8;
37
+ int nregs;
38
+ int interleave;
39
+ int spacing;
40
+} const neon_ls_element_type[11] = {
41
+ {1, 4, 1},
42
+ {1, 4, 2},
43
+ {4, 1, 1},
44
+ {2, 2, 2},
45
+ {1, 3, 1},
46
+ {1, 3, 2},
47
+ {3, 1, 1},
48
+ {1, 1, 1},
49
+ {1, 2, 1},
50
+ {1, 2, 2},
51
+ {2, 1, 1}
52
+};
53
+
54
+static void gen_neon_ldst_base_update(DisasContext *s, int rm, int rn,
55
+ int stride)
56
+{
57
+ if (rm != 15) {
58
+ TCGv_i32 base;
59
+
60
+ base = load_reg(s, rn);
61
+ if (rm == 13) {
62
+ tcg_gen_addi_i32(base, base, stride);
40
+ } else {
63
+ } else {
41
+ framesize = 0x68;
64
+ TCGv_i32 index;
42
+ }
65
+ index = load_reg(s, rm);
43
+ } else {
66
+ tcg_gen_add_i32(base, base, index);
44
+ framesize = 0x20;
67
+ tcg_temp_free_i32(index);
45
+ }
68
+ }
46
69
+ store_reg(s, rn, base);
47
/* Align stack pointer if the guest wants that */
70
+ }
48
if ((frameptr & 4) &&
71
+}
49
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
72
+
50
xpsr |= XPSR_SPREALIGN;
73
+static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
51
}
74
+{
52
75
+ /* Neon load/store multiple structures */
53
- frameptr -= 0x20;
76
+ int nregs, interleave, spacing, reg, n;
54
+ xpsr &= ~XPSR_SFPA;
77
+ MemOp endian = s->be_data;
55
+ if (env->v7m.secure &&
78
+ int mmu_idx = get_mem_index(s);
56
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
79
+ int size = a->size;
57
+ xpsr |= XPSR_SFPA;
80
+ TCGv_i64 tmp64;
58
+ }
81
+ TCGv_i32 addr, tmp;
59
+
82
+
60
+ frameptr -= framesize;
83
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
61
84
+ return false;
62
if (arm_feature(env, ARM_FEATURE_V8)) {
85
+ }
63
uint32_t limit = v7m_sp_limit(env);
86
+
64
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
87
+ /* UNDEF accesses to D16-D31 if they don't exist */
65
v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
88
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
66
v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
89
+ return false;
67
90
+ }
68
+ if (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) {
91
+ if (a->itype > 10) {
69
+ /* FPU is active, try to save its registers */
92
+ return false;
70
+ bool fpccr_s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
93
+ }
71
+ bool lspact = env->v7m.fpccr[fpccr_s] & R_V7M_FPCCR_LSPACT_MASK;
94
+ /* Catch UNDEF cases for bad values of align field */
72
+
95
+ switch (a->itype & 0xc) {
73
+ if (lspact && arm_feature(env, ARM_FEATURE_M_SECURITY)) {
96
+ case 4:
74
+ qemu_log_mask(CPU_LOG_INT,
97
+ if (a->align >= 2) {
75
+ "...SecureFault because LSPACT and FPCA both set\n");
98
+ return false;
76
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
99
+ }
77
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
100
+ break;
78
+ } else if (!env->v7m.secure && !nsacr_cp10) {
101
+ case 8:
79
+ qemu_log_mask(CPU_LOG_INT,
102
+ if (a->align == 3) {
80
+ "...Secure UsageFault with CFSR.NOCP because "
103
+ return false;
81
+ "NSACR.CP10 prevents stacking FP regs\n");
104
+ }
82
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
105
+ break;
83
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
106
+ default:
84
+ } else {
107
+ break;
85
+ if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) {
108
+ }
86
+ /* Lazy stacking disabled, save registers now */
109
+ nregs = neon_ls_element_type[a->itype].nregs;
87
+ int i;
110
+ interleave = neon_ls_element_type[a->itype].interleave;
88
+ bool cpacr_pass = v7m_cpacr_pass(env, env->v7m.secure,
111
+ spacing = neon_ls_element_type[a->itype].spacing;
89
+ arm_current_el(env) != 0);
112
+ if (size == 3 && (interleave | spacing) != 1) {
90
+
113
+ return false;
91
+ if (stacked_ok && !cpacr_pass) {
114
+ }
92
+ /*
115
+
93
+ * Take UsageFault if CPACR forbids access. The pseudocode
116
+ if (!vfp_access_check(s)) {
94
+ * here does a full CheckCPEnabled() but we know the NSACR
117
+ return true;
95
+ * check can never fail as we have already handled that.
118
+ }
96
+ */
119
+
97
+ qemu_log_mask(CPU_LOG_INT,
120
+ /* For our purposes, bytes are always little-endian. */
98
+ "...UsageFault with CFSR.NOCP because "
121
+ if (size == 0) {
99
+ "CPACR.CP10 prevents stacking FP regs\n");
122
+ endian = MO_LE;
100
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
123
+ }
101
+ env->v7m.secure);
124
+ /*
102
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_NOCP_MASK;
125
+ * Consecutive little-endian elements from a single register
103
+ stacked_ok = false;
126
+ * can be promoted to a larger little-endian operation.
127
+ */
128
+ if (interleave == 1 && endian == MO_LE) {
129
+ size = 3;
130
+ }
131
+ tmp64 = tcg_temp_new_i64();
132
+ addr = tcg_temp_new_i32();
133
+ tmp = tcg_const_i32(1 << size);
134
+ load_reg_var(s, addr, a->rn);
135
+ for (reg = 0; reg < nregs; reg++) {
136
+ for (n = 0; n < 8 >> size; n++) {
137
+ int xs;
138
+ for (xs = 0; xs < interleave; xs++) {
139
+ int tt = a->vd + reg + spacing * xs;
140
+
141
+ if (a->l) {
142
+ gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
143
+ neon_store_element64(tt, n, size, tmp64);
144
+ } else {
145
+ neon_load_element64(tmp64, tt, n, size);
146
+ gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
104
+ }
147
+ }
105
+
148
+ tcg_gen_add_i32(addr, addr, tmp);
106
+ for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
107
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
108
+ uint32_t faddr = frameptr + 0x20 + 4 * i;
109
+ uint32_t slo = extract64(dn, 0, 32);
110
+ uint32_t shi = extract64(dn, 32, 32);
111
+
112
+ if (i >= 16) {
113
+ faddr += 8; /* skip the slot for the FPSCR */
114
+ }
115
+ stacked_ok = stacked_ok &&
116
+ v7m_stack_write(cpu, faddr, slo, mmu_idx, false) &&
117
+ v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, false);
118
+ }
119
+ stacked_ok = stacked_ok &&
120
+ v7m_stack_write(cpu, frameptr + 0x60,
121
+ vfp_get_fpscr(env), mmu_idx, false);
122
+ if (cpacr_pass) {
123
+ for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
124
+ *aa32_vfp_dreg(env, i / 2) = 0;
125
+ }
126
+ vfp_set_fpscr(env, 0);
127
+ }
128
+ } else {
129
+ /* Lazy stacking enabled, save necessary info to stack later */
130
+ /* TODO : equivalent of UpdateFPCCR() pseudocode */
131
+ }
149
+ }
132
+ }
150
+ }
133
+ }
151
+ }
134
+
152
+ tcg_temp_free_i32(addr);
135
/*
153
+ tcg_temp_free_i32(tmp);
136
* If we broke a stack limit then SP was already updated earlier;
154
+ tcg_temp_free_i64(tmp64);
137
* otherwise we update SP regardless of whether any of the stack
155
+
138
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
156
+ gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
139
157
+ return true;
140
if (arm_feature(env, ARM_FEATURE_V8)) {
158
+}
141
lr = R_V7M_EXCRET_RES1_MASK |
159
diff --git a/target/arm/translate.c b/target/arm/translate.c
142
- R_V7M_EXCRET_DCRS_MASK |
160
index XXXXXXX..XXXXXXX 100644
143
- R_V7M_EXCRET_FTYPE_MASK;
161
--- a/target/arm/translate.c
144
+ R_V7M_EXCRET_DCRS_MASK;
162
+++ b/target/arm/translate.c
145
/* The S bit indicates whether we should return to Secure
163
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
146
* or NonSecure (ie our current state).
164
}
147
* The ES bit indicates whether we're taking this exception
165
148
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
166
149
if (env->v7m.secure) {
167
-static struct {
150
lr |= R_V7M_EXCRET_S_MASK;
168
- int nregs;
151
}
169
- int interleave;
152
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
170
- int spacing;
153
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
171
-} const neon_ls_element_type[11] = {
154
+ }
172
- {1, 4, 1},
173
- {1, 4, 2},
174
- {4, 1, 1},
175
- {2, 2, 2},
176
- {1, 3, 1},
177
- {1, 3, 2},
178
- {3, 1, 1},
179
- {1, 1, 1},
180
- {1, 2, 1},
181
- {1, 2, 2},
182
- {2, 1, 1}
183
-};
184
-
185
/* Translate a NEON load/store element instruction. Return nonzero if the
186
instruction is invalid. */
187
static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
188
{
189
int rd, rn, rm;
190
- int op;
191
int nregs;
192
- int interleave;
193
- int spacing;
194
int stride;
195
int size;
196
int reg;
197
int load;
198
- int n;
199
int vec_size;
200
- int mmu_idx;
201
- MemOp endian;
202
TCGv_i32 addr;
203
TCGv_i32 tmp;
204
- TCGv_i32 tmp2;
205
- TCGv_i64 tmp64;
206
207
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
208
return 1;
209
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
210
rn = (insn >> 16) & 0xf;
211
rm = insn & 0xf;
212
load = (insn & (1 << 21)) != 0;
213
- endian = s->be_data;
214
- mmu_idx = get_mem_index(s);
215
if ((insn & (1 << 23)) == 0) {
216
- /* Load store all elements. */
217
- op = (insn >> 8) & 0xf;
218
- size = (insn >> 6) & 3;
219
- if (op > 10)
220
- return 1;
221
- /* Catch UNDEF cases for bad values of align field */
222
- switch (op & 0xc) {
223
- case 4:
224
- if (((insn >> 5) & 1) == 1) {
225
- return 1;
226
- }
227
- break;
228
- case 8:
229
- if (((insn >> 4) & 3) == 3) {
230
- return 1;
231
- }
232
- break;
233
- default:
234
- break;
235
- }
236
- nregs = neon_ls_element_type[op].nregs;
237
- interleave = neon_ls_element_type[op].interleave;
238
- spacing = neon_ls_element_type[op].spacing;
239
- if (size == 3 && (interleave | spacing) != 1) {
240
- return 1;
241
- }
242
- /* For our purposes, bytes are always little-endian. */
243
- if (size == 0) {
244
- endian = MO_LE;
245
- }
246
- /* Consecutive little-endian elements from a single register
247
- * can be promoted to a larger little-endian operation.
248
- */
249
- if (interleave == 1 && endian == MO_LE) {
250
- size = 3;
251
- }
252
- tmp64 = tcg_temp_new_i64();
253
- addr = tcg_temp_new_i32();
254
- tmp2 = tcg_const_i32(1 << size);
255
- load_reg_var(s, addr, rn);
256
- for (reg = 0; reg < nregs; reg++) {
257
- for (n = 0; n < 8 >> size; n++) {
258
- int xs;
259
- for (xs = 0; xs < interleave; xs++) {
260
- int tt = rd + reg + spacing * xs;
261
-
262
- if (load) {
263
- gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
264
- neon_store_element64(tt, n, size, tmp64);
265
- } else {
266
- neon_load_element64(tmp64, tt, n, size);
267
- gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
268
- }
269
- tcg_gen_add_i32(addr, addr, tmp2);
270
- }
271
- }
272
- }
273
- tcg_temp_free_i32(addr);
274
- tcg_temp_free_i32(tmp2);
275
- tcg_temp_free_i64(tmp64);
276
- stride = nregs * interleave * 8;
277
+ /* Load store all elements -- handled already by decodetree */
278
+ return 1;
155
} else {
279
} else {
156
lr = R_V7M_EXCRET_RES1_MASK |
280
size = (insn >> 10) & 3;
157
R_V7M_EXCRET_S_MASK |
281
if (size == 3) {
158
--
282
--
159
2.20.1
283
2.20.1
160
284
161
285
diff view generated by jsdifflib
1
Implement the VLSTM instruction for v7M for the FPU present case.
1
Convert the Neon "load single structure to all lanes" insns to
2
decodetree.
2
3
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-25-peter.maydell@linaro.org
6
Message-id: 20200430181003.21682-13-peter.maydell@linaro.org
6
---
7
---
7
target/arm/cpu.h | 2 +
8
target/arm/neon-ls.decode | 5 +++
8
target/arm/helper.h | 2 +
9
target/arm/translate-neon.inc.c | 73 +++++++++++++++++++++++++++++++++
9
target/arm/helper.c | 84 ++++++++++++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 55 +------------------------
10
target/arm/translate.c | 15 +++++++-
11
3 files changed, 80 insertions(+), 53 deletions(-)
11
4 files changed, 102 insertions(+), 1 deletion(-)
12
12
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
15
--- a/target/arm/neon-ls.decode
16
+++ b/target/arm/cpu.h
16
+++ b/target/arm/neon-ls.decode
17
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@
18
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
18
19
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
19
VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
20
#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
20
vd=%vd_dp
21
+#define EXCP_LSERR 21 /* v8M LSERR SecureFault */
21
+
22
+#define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */
22
+# Neon load single element to all lanes
23
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
23
+
24
24
+VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
25
#define ARMV7M_EXCP_RESET 1
25
+ vd=%vd_dp
26
diff --git a/target/arm/helper.h b/target/arm/helper.h
26
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
27
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/helper.h
28
--- a/target/arm/translate-neon.inc.c
29
+++ b/target/arm/helper.h
29
+++ b/target/arm/translate-neon.inc.c
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
30
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
31
31
gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
32
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
32
return true;
33
33
}
34
+DEF_HELPER_2(v7m_vlstm, void, env, i32)
35
+
34
+
36
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
35
+static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
37
38
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/helper.c
42
+++ b/target/arm/helper.c
43
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
44
g_assert_not_reached();
45
}
46
47
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
48
+{
36
+{
49
+ /* translate.c should never generate calls here in user-only mode */
37
+ /* Neon load single structure to all lanes */
50
+ g_assert_not_reached();
38
+ int reg, stride, vec_size;
51
+}
39
+ int vd = a->vd;
40
+ int size = a->size;
41
+ int nregs = a->n + 1;
42
+ TCGv_i32 addr, tmp;
52
+
43
+
53
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
44
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
54
{
45
+ return false;
55
/* The TT instructions can be used by unprivileged code, but in
56
@@ -XXX,XX +XXX,XX @@ static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
57
}
58
}
59
60
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
61
+{
62
+ /* fptr is the value of Rn, the frame pointer we store the FP regs to */
63
+ bool s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
64
+ bool lspact = env->v7m.fpccr[s] & R_V7M_FPCCR_LSPACT_MASK;
65
+
66
+ assert(env->v7m.secure);
67
+
68
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
69
+ return;
70
+ }
46
+ }
71
+
47
+
72
+ /* Check access to the coprocessor is permitted */
48
+ /* UNDEF accesses to D16-D31 if they don't exist */
73
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
49
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
74
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
50
+ return false;
75
+ }
51
+ }
76
+
52
+
77
+ if (lspact) {
53
+ if (size == 3) {
78
+ /* LSPACT should not be active when there is active FP state */
54
+ if (nregs != 4 || a->a == 0) {
79
+ raise_exception_ra(env, EXCP_LSERR, 0, 1, GETPC());
55
+ return false;
56
+ }
57
+ /* For VLD4 size == 3 a == 1 means 32 bits at 16 byte alignment */
58
+ size = 2;
59
+ }
60
+ if (nregs == 1 && a->a == 1 && size == 0) {
61
+ return false;
62
+ }
63
+ if (nregs == 3 && a->a == 1) {
64
+ return false;
80
+ }
65
+ }
81
+
66
+
82
+ if (fptr & 7) {
67
+ if (!vfp_access_check(s)) {
83
+ raise_exception_ra(env, EXCP_UNALIGNED, 0, 1, GETPC());
68
+ return true;
84
+ }
69
+ }
85
+
70
+
86
+ /*
71
+ /*
87
+ * Note that we do not use v7m_stack_write() here, because the
72
+ * VLD1 to all lanes: T bit indicates how many Dregs to write.
88
+ * accesses should not set the FSR bits for stacking errors if they
73
+ * VLD2/3/4 to all lanes: T bit indicates register stride.
89
+ * fail. (In pseudocode terms, they are AccType_NORMAL, not AccType_STACK
90
+ * or AccType_LAZYFP). Faults in cpu_stl_data() will throw exceptions
91
+ * and longjmp out.
92
+ */
74
+ */
93
+ if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) {
75
+ stride = a->t ? 2 : 1;
94
+ bool ts = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK;
76
+ vec_size = nregs == 1 ? stride * 8 : 8;
95
+ int i;
96
+
77
+
97
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
78
+ tmp = tcg_temp_new_i32();
98
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
79
+ addr = tcg_temp_new_i32();
99
+ uint32_t faddr = fptr + 4 * i;
80
+ load_reg_var(s, addr, a->rn);
100
+ uint32_t slo = extract64(dn, 0, 32);
81
+ for (reg = 0; reg < nregs; reg++) {
101
+ uint32_t shi = extract64(dn, 32, 32);
82
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
83
+ s->be_data | size);
84
+ if ((vd & 1) && vec_size == 16) {
85
+ /*
86
+ * We cannot write 16 bytes at once because the
87
+ * destination is unaligned.
88
+ */
89
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
90
+ 8, 8, tmp);
91
+ tcg_gen_gvec_mov(0, neon_reg_offset(vd + 1, 0),
92
+ neon_reg_offset(vd, 0), 8, 8);
93
+ } else {
94
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
95
+ vec_size, vec_size, tmp);
96
+ }
97
+ tcg_gen_addi_i32(addr, addr, 1 << size);
98
+ vd += stride;
99
+ }
100
+ tcg_temp_free_i32(tmp);
101
+ tcg_temp_free_i32(addr);
102
+
102
+
103
+ if (i >= 16) {
103
+ gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << size) * nregs);
104
+ faddr += 8; /* skip the slot for the FPSCR */
105
+ }
106
+ cpu_stl_data(env, faddr, slo);
107
+ cpu_stl_data(env, faddr + 4, shi);
108
+ }
109
+ cpu_stl_data(env, fptr + 0x40, vfp_get_fpscr(env));
110
+
104
+
111
+ /*
105
+ return true;
112
+ * If TS is 0 then s0 to s15 and FPSCR are UNKNOWN; we choose to
113
+ * leave them unchanged, matching our choice in v7m_preserve_fp_state.
114
+ */
115
+ if (ts) {
116
+ for (i = 0; i < 32; i += 2) {
117
+ *aa32_vfp_dreg(env, i / 2) = 0;
118
+ }
119
+ vfp_set_fpscr(env, 0);
120
+ }
121
+ } else {
122
+ v7m_update_fpccr(env, fptr, false);
123
+ }
124
+
125
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
126
+}
106
+}
127
+
128
static bool v7m_push_stack(ARMCPU *cpu)
129
{
130
/* Do the "set up stack frame" part of exception entry,
131
@@ -XXX,XX +XXX,XX @@ static void arm_log_exception(int idx)
132
[EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
133
[EXCP_STKOF] = "v8M STKOF UsageFault",
134
[EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
135
+ [EXCP_LSERR] = "v8M LSERR UsageFault",
136
+ [EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
137
};
138
139
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
140
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
141
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
142
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_STKOF_MASK;
143
break;
144
+ case EXCP_LSERR:
145
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
146
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
147
+ break;
148
+ case EXCP_UNALIGNED:
149
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
150
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNALIGNED_MASK;
151
+ break;
152
case EXCP_SWI:
153
/* The PC already points to the next instruction. */
154
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC, env->v7m.secure);
155
diff --git a/target/arm/translate.c b/target/arm/translate.c
107
diff --git a/target/arm/translate.c b/target/arm/translate.c
156
index XXXXXXX..XXXXXXX 100644
108
index XXXXXXX..XXXXXXX 100644
157
--- a/target/arm/translate.c
109
--- a/target/arm/translate.c
158
+++ b/target/arm/translate.c
110
+++ b/target/arm/translate.c
159
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
160
if (!s->v8m_secure || (insn & 0x0040f0ff)) {
112
int size;
161
goto illegal_op;
113
int reg;
162
}
114
int load;
163
- /* Just NOP since FP support is not implemented */
115
- int vec_size;
164
+
116
TCGv_i32 addr;
165
+ if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
117
TCGv_i32 tmp;
166
+ TCGv_i32 fptr = load_reg(s, rn);
118
167
+
119
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
168
+ if (extract32(insn, 20, 1)) {
120
} else {
169
+ /* VLLDM */
121
size = (insn >> 10) & 3;
170
+ } else {
122
if (size == 3) {
171
+ gen_helper_v7m_vlstm(cpu_env, fptr);
123
- /* Load single element to all lanes. */
172
+ }
124
- int a = (insn >> 4) & 1;
173
+ tcg_temp_free_i32(fptr);
125
- if (!load) {
174
+
126
- return 1;
175
+ /* End the TB, because we have updated FP control bits */
127
- }
176
+ s->base.is_jmp = DISAS_UPDATE;
128
- size = (insn >> 6) & 3;
177
+ }
129
- nregs = ((insn >> 8) & 3) + 1;
178
break;
130
-
179
}
131
- if (size == 3) {
180
if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
132
- if (nregs != 4 || a == 0) {
133
- return 1;
134
- }
135
- /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
136
- size = 2;
137
- }
138
- if (nregs == 1 && a == 1 && size == 0) {
139
- return 1;
140
- }
141
- if (nregs == 3 && a == 1) {
142
- return 1;
143
- }
144
- addr = tcg_temp_new_i32();
145
- load_reg_var(s, addr, rn);
146
-
147
- /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
148
- * VLD2/3/4 to all lanes: bit 5 indicates register stride.
149
- */
150
- stride = (insn & (1 << 5)) ? 2 : 1;
151
- vec_size = nregs == 1 ? stride * 8 : 8;
152
-
153
- tmp = tcg_temp_new_i32();
154
- for (reg = 0; reg < nregs; reg++) {
155
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
156
- s->be_data | size);
157
- if ((rd & 1) && vec_size == 16) {
158
- /* We cannot write 16 bytes at once because the
159
- * destination is unaligned.
160
- */
161
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
162
- 8, 8, tmp);
163
- tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
164
- neon_reg_offset(rd, 0), 8, 8);
165
- } else {
166
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
167
- vec_size, vec_size, tmp);
168
- }
169
- tcg_gen_addi_i32(addr, addr, 1 << size);
170
- rd += stride;
171
- }
172
- tcg_temp_free_i32(tmp);
173
- tcg_temp_free_i32(addr);
174
- stride = (1 << size) * nregs;
175
+ /* Load single element to all lanes -- handled by decodetree */
176
+ return 1;
177
} else {
178
/* Single element. */
179
int idx = (insn >> 4) & 0xf;
181
--
180
--
182
2.20.1
181
2.20.1
183
182
184
183
diff view generated by jsdifflib
1
For M-profile the MVFR* ID registers are memory mapped, in the
1
Convert the Neon "load/store single structure to one lane" insns to
2
range we implement via the NVIC. Allow them to be read.
2
decodetree.
3
(If the CPU has no FPU, these registers are defined to be RAZ.)
3
4
As this is the last set of insns in the neon load/store group,
5
we can remove the whole disas_neon_ls_insn() function.
4
6
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190416125744.27770-3-peter.maydell@linaro.org
9
Message-id: 20200430181003.21682-14-peter.maydell@linaro.org
8
---
10
---
9
hw/intc/armv7m_nvic.c | 6 ++++++
11
target/arm/neon-ls.decode | 11 +++
10
1 file changed, 6 insertions(+)
12
target/arm/translate-neon.inc.c | 89 +++++++++++++++++++
11
13
target/arm/translate.c | 147 --------------------------------
12
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
14
3 files changed, 100 insertions(+), 147 deletions(-)
15
16
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/intc/armv7m_nvic.c
18
--- a/target/arm/neon-ls.decode
15
+++ b/hw/intc/armv7m_nvic.c
19
+++ b/target/arm/neon-ls.decode
16
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
20
@@ -XXX,XX +XXX,XX @@ VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
17
return 0;
21
22
VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
23
vd=%vd_dp
24
+
25
+# Neon load/store single structure to one lane
26
+%imm1_5_p1 5:1 !function=plus1
27
+%imm1_6_p1 6:1 !function=plus1
28
+
29
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 00 n:2 reg_idx:3 align:1 rm:4 \
30
+ vd=%vd_dp size=0 stride=1
31
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 01 n:2 reg_idx:2 align:2 rm:4 \
32
+ vd=%vd_dp size=1 stride=%imm1_5_p1
33
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 10 n:2 reg_idx:1 align:3 rm:4 \
34
+ vd=%vd_dp size=2 stride=%imm1_6_p1
35
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/translate-neon.inc.c
38
+++ b/target/arm/translate-neon.inc.c
39
@@ -XXX,XX +XXX,XX @@
40
* It might be possible to convert it to a standalone .c file eventually.
41
*/
42
43
+static inline int plus1(DisasContext *s, int x)
44
+{
45
+ return x + 1;
46
+}
47
+
48
/* Include the generated Neon decoder */
49
#include "decode-neon-dp.inc.c"
50
#include "decode-neon-ls.inc.c"
51
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
52
53
return true;
54
}
55
+
56
+static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
57
+{
58
+ /* Neon load/store single structure to one lane */
59
+ int reg;
60
+ int nregs = a->n + 1;
61
+ int vd = a->vd;
62
+ TCGv_i32 addr, tmp;
63
+
64
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
65
+ return false;
66
+ }
67
+
68
+ /* UNDEF accesses to D16-D31 if they don't exist */
69
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
70
+ return false;
71
+ }
72
+
73
+ /* Catch the UNDEF cases. This is unavoidably a bit messy. */
74
+ switch (nregs) {
75
+ case 1:
76
+ if (((a->align & (1 << a->size)) != 0) ||
77
+ (a->size == 2 && ((a->align & 3) == 1 || (a->align & 3) == 2))) {
78
+ return false;
79
+ }
80
+ break;
81
+ case 3:
82
+ if ((a->align & 1) != 0) {
83
+ return false;
84
+ }
85
+ /* fall through */
86
+ case 2:
87
+ if (a->size == 2 && (a->align & 2) != 0) {
88
+ return false;
89
+ }
90
+ break;
91
+ case 4:
92
+ if ((a->size == 2) && ((a->align & 3) == 3)) {
93
+ return false;
94
+ }
95
+ break;
96
+ default:
97
+ abort();
98
+ }
99
+ if ((vd + a->stride * (nregs - 1)) > 31) {
100
+ /*
101
+ * Attempts to write off the end of the register file are
102
+ * UNPREDICTABLE; we choose to UNDEF because otherwise we would
103
+ * access off the end of the array that holds the register data.
104
+ */
105
+ return false;
106
+ }
107
+
108
+ if (!vfp_access_check(s)) {
109
+ return true;
110
+ }
111
+
112
+ tmp = tcg_temp_new_i32();
113
+ addr = tcg_temp_new_i32();
114
+ load_reg_var(s, addr, a->rn);
115
+ /*
116
+ * TODO: if we implemented alignment exceptions, we should check
117
+ * addr against the alignment encoded in a->align here.
118
+ */
119
+ for (reg = 0; reg < nregs; reg++) {
120
+ if (a->l) {
121
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
122
+ s->be_data | a->size);
123
+ neon_store_element(vd, a->reg_idx, a->size, tmp);
124
+ } else { /* Store */
125
+ neon_load_element(tmp, vd, a->reg_idx, a->size);
126
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
127
+ s->be_data | a->size);
128
+ }
129
+ vd += a->stride;
130
+ tcg_gen_addi_i32(addr, addr, 1 << a->size);
131
+ }
132
+ tcg_temp_free_i32(addr);
133
+ tcg_temp_free_i32(tmp);
134
+
135
+ gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << a->size) * nregs);
136
+
137
+ return true;
138
+}
139
diff --git a/target/arm/translate.c b/target/arm/translate.c
140
index XXXXXXX..XXXXXXX 100644
141
--- a/target/arm/translate.c
142
+++ b/target/arm/translate.c
143
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
144
tcg_temp_free_i32(rd);
145
}
146
147
-
148
-/* Translate a NEON load/store element instruction. Return nonzero if the
149
- instruction is invalid. */
150
-static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
151
-{
152
- int rd, rn, rm;
153
- int nregs;
154
- int stride;
155
- int size;
156
- int reg;
157
- int load;
158
- TCGv_i32 addr;
159
- TCGv_i32 tmp;
160
-
161
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
162
- return 1;
163
- }
164
-
165
- /* FIXME: this access check should not take precedence over UNDEF
166
- * for invalid encodings; we will generate incorrect syndrome information
167
- * for attempts to execute invalid vfp/neon encodings with FP disabled.
168
- */
169
- if (s->fp_excp_el) {
170
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
171
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
172
- return 0;
173
- }
174
-
175
- if (!s->vfp_enabled)
176
- return 1;
177
- VFP_DREG_D(rd, insn);
178
- rn = (insn >> 16) & 0xf;
179
- rm = insn & 0xf;
180
- load = (insn & (1 << 21)) != 0;
181
- if ((insn & (1 << 23)) == 0) {
182
- /* Load store all elements -- handled already by decodetree */
183
- return 1;
184
- } else {
185
- size = (insn >> 10) & 3;
186
- if (size == 3) {
187
- /* Load single element to all lanes -- handled by decodetree */
188
- return 1;
189
- } else {
190
- /* Single element. */
191
- int idx = (insn >> 4) & 0xf;
192
- int reg_idx;
193
- switch (size) {
194
- case 0:
195
- reg_idx = (insn >> 5) & 7;
196
- stride = 1;
197
- break;
198
- case 1:
199
- reg_idx = (insn >> 6) & 3;
200
- stride = (insn & (1 << 5)) ? 2 : 1;
201
- break;
202
- case 2:
203
- reg_idx = (insn >> 7) & 1;
204
- stride = (insn & (1 << 6)) ? 2 : 1;
205
- break;
206
- default:
207
- abort();
208
- }
209
- nregs = ((insn >> 8) & 3) + 1;
210
- /* Catch the UNDEF cases. This is unavoidably a bit messy. */
211
- switch (nregs) {
212
- case 1:
213
- if (((idx & (1 << size)) != 0) ||
214
- (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
215
- return 1;
216
- }
217
- break;
218
- case 3:
219
- if ((idx & 1) != 0) {
220
- return 1;
221
- }
222
- /* fall through */
223
- case 2:
224
- if (size == 2 && (idx & 2) != 0) {
225
- return 1;
226
- }
227
- break;
228
- case 4:
229
- if ((size == 2) && ((idx & 3) == 3)) {
230
- return 1;
231
- }
232
- break;
233
- default:
234
- abort();
235
- }
236
- if ((rd + stride * (nregs - 1)) > 31) {
237
- /* Attempts to write off the end of the register file
238
- * are UNPREDICTABLE; we choose to UNDEF because otherwise
239
- * the neon_load_reg() would write off the end of the array.
240
- */
241
- return 1;
242
- }
243
- tmp = tcg_temp_new_i32();
244
- addr = tcg_temp_new_i32();
245
- load_reg_var(s, addr, rn);
246
- for (reg = 0; reg < nregs; reg++) {
247
- if (load) {
248
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
249
- s->be_data | size);
250
- neon_store_element(rd, reg_idx, size, tmp);
251
- } else { /* Store */
252
- neon_load_element(tmp, rd, reg_idx, size);
253
- gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
254
- s->be_data | size);
255
- }
256
- rd += stride;
257
- tcg_gen_addi_i32(addr, addr, 1 << size);
258
- }
259
- tcg_temp_free_i32(addr);
260
- tcg_temp_free_i32(tmp);
261
- stride = nregs * (1 << size);
262
- }
263
- }
264
- if (rm != 15) {
265
- TCGv_i32 base;
266
-
267
- base = load_reg(s, rn);
268
- if (rm == 13) {
269
- tcg_gen_addi_i32(base, base, stride);
270
- } else {
271
- TCGv_i32 index;
272
- index = load_reg(s, rm);
273
- tcg_gen_add_i32(base, base, index);
274
- tcg_temp_free_i32(index);
275
- }
276
- store_reg(s, rn, base);
277
- }
278
- return 0;
279
-}
280
-
281
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
282
{
283
switch (size) {
284
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
285
}
286
return;
18
}
287
}
19
return cpu->env.v7m.sfar;
288
- if ((insn & 0x0f100000) == 0x04000000) {
20
+ case 0xf40: /* MVFR0 */
289
- /* NEON load/store. */
21
+ return cpu->isar.mvfr0;
290
- if (disas_neon_ls_insn(s, insn)) {
22
+ case 0xf44: /* MVFR1 */
291
- goto illegal_op;
23
+ return cpu->isar.mvfr1;
292
- }
24
+ case 0xf48: /* MVFR2 */
293
- return;
25
+ return cpu->isar.mvfr2;
294
- }
295
if ((insn & 0x0e000f00) == 0x0c000100) {
296
if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
297
/* iWMMXt register transfer. */
298
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
299
}
300
break;
301
case 12:
302
- if ((insn & 0x01100000) == 0x01000000) {
303
- if (disas_neon_ls_insn(s, insn)) {
304
- goto illegal_op;
305
- }
306
- break;
307
- }
308
goto illegal_op;
26
default:
309
default:
27
bad_offset:
310
illegal_op:
28
qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
29
--
311
--
30
2.20.1
312
2.20.1
31
313
32
314
diff view generated by jsdifflib
1
The M-profile FPCCR.ASPEN bit indicates that automatic floating-point
1
Convert the Neon 3-reg-same VADD and VSUB insns to decodetree.
2
context preservation is enabled. Before executing any floating-point
3
instruction, if FPCCR.ASPEN is set and the CONTROL FPCA/SFPA bits
4
indicate that there is no active floating point context then we
5
must create a new context (by initializing FPSCR and setting
6
FPCA/SFPA to indicate that the context is now active). In the
7
pseudocode this is handled by ExecuteFPCheck().
8
2
9
Implement this with a new TB flag which tracks whether we
3
Note that we don't need the neon_3r_sizes[op] check here because all
10
need to create a new FP context.
4
size values are OK for VADD and VSUB; we'll add this when we convert
5
the first insn that has size restrictions.
6
7
For this we need one of the GVecGen*Fn typedefs currently in
8
translate-a64.h; move them all to translate.h as a block so they
9
are visible to the 32-bit decoder.
11
10
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190416125744.27770-20-peter.maydell@linaro.org
13
Message-id: 20200430181003.21682-15-peter.maydell@linaro.org
15
---
14
---
16
target/arm/cpu.h | 2 ++
15
target/arm/translate-a64.h | 9 --------
17
target/arm/translate.h | 1 +
16
target/arm/translate.h | 9 ++++++++
18
target/arm/helper.c | 13 +++++++++++++
17
target/arm/neon-dp.decode | 17 +++++++++++++++
19
target/arm/translate.c | 29 +++++++++++++++++++++++++++++
18
target/arm/translate-neon.inc.c | 38 +++++++++++++++++++++++++++++++++
20
4 files changed, 45 insertions(+)
19
target/arm/translate.c | 14 ++++--------
20
5 files changed, 68 insertions(+), 19 deletions(-)
21
21
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
23
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
24
--- a/target/arm/translate-a64.h
25
+++ b/target/arm/cpu.h
25
+++ b/target/arm/translate-a64.h
26
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
26
@@ -XXX,XX +XXX,XX @@ static inline int vec_full_reg_size(DisasContext *s)
27
FIELD(TBFLAG_A32, VFPEN, 7, 1)
27
28
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
28
bool disas_sve(DisasContext *, uint32_t);
29
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
29
30
+/* For M profile only, set if we must create a new FP context */
30
-/* Note that the gvec expanders operate on offsets + sizes. */
31
+FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
31
-typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
32
/* For M profile only, set if FPCCR.S does not match current security state */
32
-typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
33
FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
33
- uint32_t, uint32_t);
34
/* For M profile only, Handler (ie not Thread) mode */
34
-typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
35
- uint32_t, uint32_t, uint32_t);
36
-typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
37
- uint32_t, uint32_t, uint32_t);
38
-
39
#endif /* TARGET_ARM_TRANSLATE_A64_H */
35
diff --git a/target/arm/translate.h b/target/arm/translate.h
40
diff --git a/target/arm/translate.h b/target/arm/translate.h
36
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/translate.h
42
--- a/target/arm/translate.h
38
+++ b/target/arm/translate.h
43
+++ b/target/arm/translate.h
39
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
44
@@ -XXX,XX +XXX,XX @@ void gen_sshl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
40
bool v8m_secure; /* true if v8M and we're in Secure mode */
45
#define dc_isar_feature(name, ctx) \
41
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
46
({ DisasContext *ctx_ = (ctx); isar_feature_##name(ctx_->isar); })
42
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
47
43
+ bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
48
+/* Note that the gvec expanders operate on offsets + sizes. */
44
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
49
+typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
45
* so that top level loop can generate correct syndrome information.
50
+typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
46
*/
51
+ uint32_t, uint32_t);
47
diff --git a/target/arm/helper.c b/target/arm/helper.c
52
+typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
53
+ uint32_t, uint32_t, uint32_t);
54
+typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
55
+ uint32_t, uint32_t, uint32_t);
56
+
57
#endif /* TARGET_ARM_TRANSLATE_H */
58
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
48
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/helper.c
60
--- a/target/arm/neon-dp.decode
50
+++ b/target/arm/helper.c
61
+++ b/target/arm/neon-dp.decode
51
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
62
@@ -XXX,XX +XXX,XX @@
52
flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
63
#
53
}
64
# This file is processed by scripts/decodetree.py
54
65
#
55
+ if (arm_feature(env, ARM_FEATURE_M) &&
66
+# VFP/Neon register fields; same as vfp.decode
56
+ (env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) &&
67
+%vm_dp 5:1 0:4
57
+ (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) ||
68
+%vn_dp 7:1 16:4
58
+ (env->v7m.secure &&
69
+%vd_dp 22:1 12:4
59
+ !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)))) {
70
60
+ /*
71
# Encodings for Neon data processing instructions where the T32 encoding
61
+ * ASPEN is set, but FPCA/SFPA indicate that there is no active
72
# is a simple transformation of the A32 encoding.
62
+ * FP context; we must create a new FP context before executing
73
@@ -XXX,XX +XXX,XX @@
63
+ * any FP insn.
74
# 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
64
+ */
75
# This file works on the A32 encoding only; calling code for T32 has to
65
+ flags = FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED, 1);
76
# transform the insn into the A32 version first.
77
+
78
+######################################################################
79
+# 3-reg-same grouping:
80
+# 1111 001 U 0 D sz:2 Vn:4 Vd:4 opc:4 N Q M op Vm:4
81
+######################################################################
82
+
83
+&3same vm vn vd q size
84
+
85
+@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
86
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
87
+
88
+VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
89
+VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
90
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/translate-neon.inc.c
93
+++ b/target/arm/translate-neon.inc.c
94
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
95
96
return true;
97
}
98
+
99
+static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
100
+{
101
+ int vec_size = a->q ? 16 : 8;
102
+ int rd_ofs = neon_reg_offset(a->vd, 0);
103
+ int rn_ofs = neon_reg_offset(a->vn, 0);
104
+ int rm_ofs = neon_reg_offset(a->vm, 0);
105
+
106
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
107
+ return false;
66
+ }
108
+ }
67
+
109
+
68
*pflags = flags;
110
+ /* UNDEF accesses to D16-D31 if they don't exist. */
69
*cs_base = 0;
111
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
70
}
112
+ ((a->vd | a->vn | a->vm) & 0x10)) {
113
+ return false;
114
+ }
115
+
116
+ if ((a->vn | a->vm | a->vd) & a->q) {
117
+ return false;
118
+ }
119
+
120
+ if (!vfp_access_check(s)) {
121
+ return true;
122
+ }
123
+
124
+ fn(a->size, rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
125
+ return true;
126
+}
127
+
128
+#define DO_3SAME(INSN, FUNC) \
129
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
130
+ { \
131
+ return do_3same(s, a, FUNC); \
132
+ }
133
+
134
+DO_3SAME(VADD, tcg_gen_gvec_add)
135
+DO_3SAME(VSUB, tcg_gen_gvec_sub)
71
diff --git a/target/arm/translate.c b/target/arm/translate.c
136
diff --git a/target/arm/translate.c b/target/arm/translate.c
72
index XXXXXXX..XXXXXXX 100644
137
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/translate.c
138
--- a/target/arm/translate.c
74
+++ b/target/arm/translate.c
139
+++ b/target/arm/translate.c
75
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
140
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
76
/* Don't need to do this for any further FP insns in this TB */
141
}
77
s->v8m_fpccr_s_wrong = false;
142
return 0;
143
144
- case NEON_3R_VADD_VSUB:
145
- if (u) {
146
- tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
147
- vec_size, vec_size);
148
- } else {
149
- tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
150
- vec_size, vec_size);
151
- }
152
- return 0;
153
-
154
case NEON_3R_VQADD:
155
tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
156
rn_ofs, rm_ofs, vec_size, vec_size,
157
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
158
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
159
u ? &ushl_op[size] : &sshl_op[size]);
160
return 0;
161
+
162
+ case NEON_3R_VADD_VSUB:
163
+ /* Already handled by decodetree */
164
+ return 1;
78
}
165
}
79
+
166
80
+ if (s->v7m_new_fp_ctxt_needed) {
167
if (size == 3) {
81
+ /*
82
+ * Create new FP context by updating CONTROL.FPCA, CONTROL.SFPA
83
+ * and the FPSCR.
84
+ */
85
+ TCGv_i32 control, fpscr;
86
+ uint32_t bits = R_V7M_CONTROL_FPCA_MASK;
87
+
88
+ fpscr = load_cpu_field(v7m.fpdscr[s->v8m_secure]);
89
+ gen_helper_vfp_set_fpscr(cpu_env, fpscr);
90
+ tcg_temp_free_i32(fpscr);
91
+ /*
92
+ * We don't need to arrange to end the TB, because the only
93
+ * parts of FPSCR which we cache in the TB flags are the VECLEN
94
+ * and VECSTRIDE, and those don't exist for M-profile.
95
+ */
96
+
97
+ if (s->v8m_secure) {
98
+ bits |= R_V7M_CONTROL_SFPA_MASK;
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;
105
+ }
106
}
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;
117
118
--
168
--
119
2.20.1
169
2.20.1
120
170
121
171
diff view generated by jsdifflib
1
Enable the FPU by default for the Cortex-M4 and Cortex-M33.
1
Convert the Neon logic ops in the 3-reg-same grouping to decodetree.
2
Note that for the logic ops the 'size' field forms part of their
3
decode and the actual operations are always bitwise.
2
4
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-27-peter.maydell@linaro.org
7
Message-id: 20200430181003.21682-16-peter.maydell@linaro.org
6
---
8
---
7
target/arm/cpu.c | 8 ++++++++
9
target/arm/neon-dp.decode | 12 +++++++++++
8
1 file changed, 8 insertions(+)
10
target/arm/translate-neon.inc.c | 19 +++++++++++++++++
11
target/arm/translate.c | 38 +--------------------------------
12
3 files changed, 32 insertions(+), 37 deletions(-)
9
13
10
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
11
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
12
--- a/target/arm/cpu.c
16
--- a/target/arm/neon-dp.decode
13
+++ b/target/arm/cpu.c
17
+++ b/target/arm/neon-dp.decode
14
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
18
@@ -XXX,XX +XXX,XX @@
15
set_feature(&cpu->env, ARM_FEATURE_M);
19
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
16
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
20
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
17
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
21
18
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
22
+@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
19
cpu->midr = 0x410fc240; /* r0p0 */
23
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
20
cpu->pmsav7_dregion = 8;
24
+
21
+ cpu->isar.mvfr0 = 0x10110021;
25
+VAND_3s 1111 001 0 0 . 00 .... .... 0001 ... 1 .... @3same_logic
22
+ cpu->isar.mvfr1 = 0x11000011;
26
+VBIC_3s 1111 001 0 0 . 01 .... .... 0001 ... 1 .... @3same_logic
23
+ cpu->isar.mvfr2 = 0x00000000;
27
+VORR_3s 1111 001 0 0 . 10 .... .... 0001 ... 1 .... @3same_logic
24
cpu->id_pfr0 = 0x00000030;
28
+VORN_3s 1111 001 0 0 . 11 .... .... 0001 ... 1 .... @3same_logic
25
cpu->id_pfr1 = 0x00000200;
29
+VEOR_3s 1111 001 1 0 . 00 .... .... 0001 ... 1 .... @3same_logic
26
cpu->id_dfr0 = 0x00100000;
30
+VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
27
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
31
+VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
28
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
32
+VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
29
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
33
+
30
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
34
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
31
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
35
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
32
cpu->midr = 0x410fd213; /* r0p3 */
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
33
cpu->pmsav7_dregion = 16;
37
index XXXXXXX..XXXXXXX 100644
34
cpu->sau_sregion = 8;
38
--- a/target/arm/translate-neon.inc.c
35
+ cpu->isar.mvfr0 = 0x10110021;
39
+++ b/target/arm/translate-neon.inc.c
36
+ cpu->isar.mvfr1 = 0x11000011;
40
@@ -XXX,XX +XXX,XX @@ static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
37
+ cpu->isar.mvfr2 = 0x00000040;
41
38
cpu->id_pfr0 = 0x00000030;
42
DO_3SAME(VADD, tcg_gen_gvec_add)
39
cpu->id_pfr1 = 0x00000210;
43
DO_3SAME(VSUB, tcg_gen_gvec_sub)
40
cpu->id_dfr0 = 0x00200000;
44
+DO_3SAME(VAND, tcg_gen_gvec_and)
45
+DO_3SAME(VBIC, tcg_gen_gvec_andc)
46
+DO_3SAME(VORR, tcg_gen_gvec_or)
47
+DO_3SAME(VORN, tcg_gen_gvec_orc)
48
+DO_3SAME(VEOR, tcg_gen_gvec_xor)
49
+
50
+/* These insns are all gvec_bitsel but with the inputs in various orders. */
51
+#define DO_3SAME_BITSEL(INSN, O1, O2, O3) \
52
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
53
+ uint32_t rn_ofs, uint32_t rm_ofs, \
54
+ uint32_t oprsz, uint32_t maxsz) \
55
+ { \
56
+ tcg_gen_gvec_bitsel(vece, rd_ofs, O1, O2, O3, oprsz, maxsz); \
57
+ } \
58
+ DO_3SAME(INSN, gen_##INSN##_3s)
59
+
60
+DO_3SAME_BITSEL(VBSL, rd_ofs, rn_ofs, rm_ofs)
61
+DO_3SAME_BITSEL(VBIT, rm_ofs, rn_ofs, rd_ofs)
62
+DO_3SAME_BITSEL(VBIF, rm_ofs, rd_ofs, rn_ofs)
63
diff --git a/target/arm/translate.c b/target/arm/translate.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/translate.c
66
+++ b/target/arm/translate.c
67
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
68
}
69
return 1;
70
71
- case NEON_3R_LOGIC: /* Logic ops. */
72
- switch ((u << 2) | size) {
73
- case 0: /* VAND */
74
- tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
75
- vec_size, vec_size);
76
- break;
77
- case 1: /* VBIC */
78
- tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
79
- vec_size, vec_size);
80
- break;
81
- case 2: /* VORR */
82
- tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
83
- vec_size, vec_size);
84
- break;
85
- case 3: /* VORN */
86
- tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
87
- vec_size, vec_size);
88
- break;
89
- case 4: /* VEOR */
90
- tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
91
- vec_size, vec_size);
92
- break;
93
- case 5: /* VBSL */
94
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
95
- vec_size, vec_size);
96
- break;
97
- case 6: /* VBIT */
98
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
99
- vec_size, vec_size);
100
- break;
101
- case 7: /* VBIF */
102
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
103
- vec_size, vec_size);
104
- break;
105
- }
106
- return 0;
107
-
108
case NEON_3R_VQADD:
109
tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
110
rn_ofs, rm_ofs, vec_size, vec_size,
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
112
return 0;
113
114
case NEON_3R_VADD_VSUB:
115
+ case NEON_3R_LOGIC:
116
/* Already handled by decodetree */
117
return 1;
118
}
41
--
119
--
42
2.20.1
120
2.20.1
43
121
44
122
diff view generated by jsdifflib
1
Enforce that for M-profile various FPSCR bits which are RES0 there
1
Convert the Neon 3-reg-same VMAX and VMIN insns to decodetree.
2
but have defined meanings on A-profile are never settable. This
3
ensures that M-profile code can't enable the A-profile behaviour
4
(notably vector length/stride handling) by accident.
5
2
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-2-peter.maydell@linaro.org
5
Message-id: 20200430181003.21682-17-peter.maydell@linaro.org
9
---
6
---
10
target/arm/vfp_helper.c | 8 ++++++++
7
target/arm/neon-dp.decode | 5 +++++
11
1 file changed, 8 insertions(+)
8
target/arm/translate-neon.inc.c | 14 ++++++++++++++
9
target/arm/translate.c | 21 ++-------------------
10
3 files changed, 21 insertions(+), 19 deletions(-)
12
11
13
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
12
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/vfp_helper.c
14
--- a/target/arm/neon-dp.decode
16
+++ b/target/arm/vfp_helper.c
15
+++ b/target/arm/neon-dp.decode
17
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
16
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
18
val &= ~FPCR_FZ16;
17
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
19
}
18
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
20
19
21
+ if (arm_feature(env, ARM_FEATURE_M)) {
20
+VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
22
+ /*
21
+VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
23
+ * M profile FPSCR is RES0 for the QC, STRIDE, FZ16, LEN bits
22
+VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
24
+ * and also for the trapped-exception-handling bits IxE.
23
+VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
25
+ */
24
+
26
+ val &= 0xf7c0009f;
25
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
26
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/translate-neon.inc.c
30
+++ b/target/arm/translate-neon.inc.c
31
@@ -XXX,XX +XXX,XX @@ DO_3SAME(VEOR, tcg_gen_gvec_xor)
32
DO_3SAME_BITSEL(VBSL, rd_ofs, rn_ofs, rm_ofs)
33
DO_3SAME_BITSEL(VBIT, rm_ofs, rn_ofs, rd_ofs)
34
DO_3SAME_BITSEL(VBIF, rm_ofs, rd_ofs, rn_ofs)
35
+
36
+#define DO_3SAME_NO_SZ_3(INSN, FUNC) \
37
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
38
+ { \
39
+ if (a->size == 3) { \
40
+ return false; \
41
+ } \
42
+ return do_3same(s, a, FUNC); \
27
+ }
43
+ }
28
+
44
+
29
/*
45
+DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
30
* We don't implement trapped exception handling, so the
46
+DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
31
* trap enable bits, IDE|IXE|UFE|OFE|DZE|IOE are all RAZ/WI (not RES0!)
47
+DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
48
+DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
49
diff --git a/target/arm/translate.c b/target/arm/translate.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/translate.c
52
+++ b/target/arm/translate.c
53
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
54
rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
55
return 0;
56
57
- case NEON_3R_VMAX:
58
- if (u) {
59
- tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
60
- vec_size, vec_size);
61
- } else {
62
- tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
63
- vec_size, vec_size);
64
- }
65
- return 0;
66
- case NEON_3R_VMIN:
67
- if (u) {
68
- tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
69
- vec_size, vec_size);
70
- } else {
71
- tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
72
- vec_size, vec_size);
73
- }
74
- return 0;
75
-
76
case NEON_3R_VSHL:
77
/* Note the operation is vshl vd,vm,vn */
78
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
79
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
80
81
case NEON_3R_VADD_VSUB:
82
case NEON_3R_LOGIC:
83
+ case NEON_3R_VMAX:
84
+ case NEON_3R_VMIN:
85
/* Already handled by decodetree */
86
return 1;
87
}
32
--
88
--
33
2.20.1
89
2.20.1
34
90
35
91
diff view generated by jsdifflib
1
Move the NS TBFLAG down from bit 19 to bit 6, which has not
1
Convert the Neon comparison ops in the 3-reg-same grouping
2
been used since commit c1e3781090b9d36c60 in 2015, when we
2
to decodetree.
3
started passing the entire MMU index in the TB flags rather
4
than just a 'privilege level' bit.
5
6
This rearrangement is not strictly necessary, but means that
7
we can put M-profile-only bits next to each other rather
8
than scattered across the flag word.
9
3
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20190416125744.27770-17-peter.maydell@linaro.org
6
Message-id: 20200430181003.21682-18-peter.maydell@linaro.org
13
---
7
---
14
target/arm/cpu.h | 11 ++++++-----
8
target/arm/neon-dp.decode | 8 ++++++++
15
1 file changed, 6 insertions(+), 5 deletions(-)
9
target/arm/translate-neon.inc.c | 22 ++++++++++++++++++++++
10
target/arm/translate.c | 23 +++--------------------
11
3 files changed, 33 insertions(+), 20 deletions(-)
16
12
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
15
--- a/target/arm/neon-dp.decode
20
+++ b/target/arm/cpu.h
16
+++ b/target/arm/neon-dp.decode
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
17
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
18
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
19
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
20
25
+/*
21
+VCGT_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 0 .... @3same
26
+ * Indicates whether cp register reads and writes by guest code should access
22
+VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
27
+ * the secure or nonsecure bank of banked registers; note that this is not
23
+VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
28
+ * the same thing as the current security state of the processor!
24
+VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
29
+ */
25
+
30
+FIELD(TBFLAG_A32, NS, 6, 1)
26
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
31
FIELD(TBFLAG_A32, VFPEN, 7, 1)
27
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
32
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
28
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
33
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
29
@@ -XXX,XX +XXX,XX @@ VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
34
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
30
35
* checks on the other bits at runtime
31
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
36
*/
32
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
37
FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
33
+
38
-/* Indicates whether cp register reads and writes by guest code should access
34
+VTST_3s 1111 001 0 0 . .. .... .... 1000 . . . 1 .... @3same
39
- * the secure or nonsecure bank of banked registers; note that this is not
35
+VCEQ_3s 1111 001 1 0 . .. .... .... 1000 . . . 1 .... @3same
40
- * the same thing as the current security state of the processor!
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
41
- */
37
index XXXXXXX..XXXXXXX 100644
42
-FIELD(TBFLAG_A32, NS, 19, 1)
38
--- a/target/arm/translate-neon.inc.c
43
/* For M profile only, Handler (ie not Thread) mode */
39
+++ b/target/arm/translate-neon.inc.c
44
FIELD(TBFLAG_A32, HANDLER, 21, 1)
40
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
45
/* For M profile only, whether we should generate stack-limit checks */
41
DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
42
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
43
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
44
+
45
+#define DO_3SAME_CMP(INSN, COND) \
46
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
47
+ uint32_t rn_ofs, uint32_t rm_ofs, \
48
+ uint32_t oprsz, uint32_t maxsz) \
49
+ { \
50
+ tcg_gen_gvec_cmp(COND, vece, rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz); \
51
+ } \
52
+ DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
53
+
54
+DO_3SAME_CMP(VCGT_S, TCG_COND_GT)
55
+DO_3SAME_CMP(VCGT_U, TCG_COND_GTU)
56
+DO_3SAME_CMP(VCGE_S, TCG_COND_GE)
57
+DO_3SAME_CMP(VCGE_U, TCG_COND_GEU)
58
+DO_3SAME_CMP(VCEQ, TCG_COND_EQ)
59
+
60
+static void gen_VTST_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
61
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
62
+{
63
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &cmtst_op[vece]);
64
+}
65
+DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate.c
69
+++ b/target/arm/translate.c
70
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
71
u ? &mls_op[size] : &mla_op[size]);
72
return 0;
73
74
- case NEON_3R_VTST_VCEQ:
75
- if (u) { /* VCEQ */
76
- tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
77
- vec_size, vec_size);
78
- } else { /* VTST */
79
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
80
- vec_size, vec_size, &cmtst_op[size]);
81
- }
82
- return 0;
83
-
84
- case NEON_3R_VCGT:
85
- tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
86
- rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
87
- return 0;
88
-
89
- case NEON_3R_VCGE:
90
- tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
91
- rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
92
- return 0;
93
-
94
case NEON_3R_VSHL:
95
/* Note the operation is vshl vd,vm,vn */
96
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
97
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
98
case NEON_3R_LOGIC:
99
case NEON_3R_VMAX:
100
case NEON_3R_VMIN:
101
+ case NEON_3R_VTST_VCEQ:
102
+ case NEON_3R_VCGT:
103
+ case NEON_3R_VCGE:
104
/* Already handled by decodetree */
105
return 1;
106
}
46
--
107
--
47
2.20.1
108
2.20.1
48
109
49
110
diff view generated by jsdifflib
1
We are close to running out of TB flags for AArch32; we could
1
Convert the Neon VQADD/VQSUB insns in the 3-reg-same grouping
2
start using the cs_base word, but before we do that we can
2
to decodetree.
3
economise on our usage by sharing the same bits for the VFP
4
VECSTRIDE field and the XScale XSCALE_CPAR field. This
5
works because no XScale CPU ever had VFP.
6
3
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-18-peter.maydell@linaro.org
6
Message-id: 20200430181003.21682-19-peter.maydell@linaro.org
10
---
7
---
11
target/arm/cpu.h | 10 ++++++----
8
target/arm/neon-dp.decode | 6 ++++++
12
target/arm/cpu.c | 7 +++++++
9
target/arm/translate-neon.inc.c | 15 +++++++++++++++
13
target/arm/helper.c | 6 +++++-
10
target/arm/translate.c | 14 ++------------
14
target/arm/translate.c | 9 +++++++--
11
3 files changed, 23 insertions(+), 12 deletions(-)
15
4 files changed, 25 insertions(+), 7 deletions(-)
16
12
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
15
--- a/target/arm/neon-dp.decode
20
+++ b/target/arm/cpu.h
16
+++ b/target/arm/neon-dp.decode
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
17
@@ -XXX,XX +XXX,XX @@
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
18
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
19
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
20
25
+/*
21
+VQADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 1 .... @3same
26
+ * We store the bottom two bits of the CPAR as TB flags and handle
22
+VQADD_U_3s 1111 001 1 0 . .. .... .... 0000 . . . 1 .... @3same
27
+ * checks on the other bits at runtime. This shares the same bits as
23
+
28
+ * VECSTRIDE, which is OK as no XScale CPU has VFP.
24
@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
29
+ */
25
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
30
+FIELD(TBFLAG_A32, XSCALE_CPAR, 4, 2)
26
31
/*
27
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
32
* Indicates whether cp register reads and writes by guest code should access
28
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
33
* the secure or nonsecure bank of banked registers; note that this is not
29
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
34
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
30
35
FIELD(TBFLAG_A32, VFPEN, 7, 1)
31
+VQSUB_S_3s 1111 001 0 0 . .. .... .... 0010 . . . 1 .... @3same
36
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
32
+VQSUB_U_3s 1111 001 1 0 . .. .... .... 0010 . . . 1 .... @3same
37
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
33
+
38
-/* We store the bottom two bits of the CPAR as TB flags and handle
34
VCGT_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 0 .... @3same
39
- * checks on the other bits at runtime
35
VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
40
- */
36
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
41
-FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
37
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
42
/* For M profile only, Handler (ie not Thread) mode */
43
FIELD(TBFLAG_A32, HANDLER, 21, 1)
44
/* For M profile only, whether we should generate stack-limit checks */
45
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
46
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/cpu.c
39
--- a/target/arm/translate-neon.inc.c
48
+++ b/target/arm/cpu.c
40
+++ b/target/arm/translate-neon.inc.c
49
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
41
@@ -XXX,XX +XXX,XX @@ static void gen_VTST_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
50
set_feature(env, ARM_FEATURE_THUMB_DSP);
42
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &cmtst_op[vece]);
51
}
43
}
52
44
DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
53
+ /*
54
+ * We rely on no XScale CPU having VFP so we can use the same bits in the
55
+ * TB flags field for VECSTRIDE and XSCALE_CPAR.
56
+ */
57
+ assert(!(arm_feature(env, ARM_FEATURE_VFP) &&
58
+ arm_feature(env, ARM_FEATURE_XSCALE)));
59
+
45
+
60
if (arm_feature(env, ARM_FEATURE_V7) &&
46
+#define DO_3SAME_GVEC4(INSN, OPARRAY) \
61
!arm_feature(env, ARM_FEATURE_M) &&
47
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
62
!arm_feature(env, ARM_FEATURE_PMSA)) {
48
+ uint32_t rn_ofs, uint32_t rm_ofs, \
63
diff --git a/target/arm/helper.c b/target/arm/helper.c
49
+ uint32_t oprsz, uint32_t maxsz) \
64
index XXXXXXX..XXXXXXX 100644
50
+ { \
65
--- a/target/arm/helper.c
51
+ tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc), \
66
+++ b/target/arm/helper.c
52
+ rn_ofs, rm_ofs, oprsz, maxsz, &OPARRAY[vece]); \
67
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
53
+ } \
68
|| arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
54
+ DO_3SAME(INSN, gen_##INSN##_3s)
69
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
55
+
70
}
56
+DO_3SAME_GVEC4(VQADD_S, sqadd_op)
71
- flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
57
+DO_3SAME_GVEC4(VQADD_U, uqadd_op)
72
+ /* Note that XSCALE_CPAR shares bits with VECSTRIDE */
58
+DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
73
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
59
+DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
74
+ flags = FIELD_DP32(flags, TBFLAG_A32,
75
+ XSCALE_CPAR, env->cp15.c15_cpar);
76
+ }
77
}
78
79
flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
80
diff --git a/target/arm/translate.c b/target/arm/translate.c
60
diff --git a/target/arm/translate.c b/target/arm/translate.c
81
index XXXXXXX..XXXXXXX 100644
61
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/translate.c
62
--- a/target/arm/translate.c
83
+++ b/target/arm/translate.c
63
+++ b/target/arm/translate.c
84
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
64
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
85
dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
65
}
86
dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
66
return 1;
87
dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
67
88
- dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
68
- case NEON_3R_VQADD:
89
- dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
69
- tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
90
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
70
- rn_ofs, rm_ofs, vec_size, vec_size,
91
+ dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
71
- (u ? uqadd_op : sqadd_op) + size);
92
+ dc->vec_stride = 0;
72
- return 0;
93
+ } else {
73
-
94
+ dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
74
- case NEON_3R_VQSUB:
95
+ dc->c15_cpar = 0;
75
- tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
96
+ }
76
- rn_ofs, rm_ofs, vec_size, vec_size,
97
dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
77
- (u ? uqsub_op : sqsub_op) + size);
98
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
78
- return 0;
99
regime_is_secure(env, dc->mmu_idx);
79
-
80
case NEON_3R_VMUL: /* VMUL */
81
if (u) {
82
/* Polynomial case allows only P8. */
83
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
84
case NEON_3R_VTST_VCEQ:
85
case NEON_3R_VCGT:
86
case NEON_3R_VCGE:
87
+ case NEON_3R_VQADD:
88
+ case NEON_3R_VQSUB:
89
/* Already handled by decodetree */
90
return 1;
91
}
100
--
92
--
101
2.20.1
93
2.20.1
102
94
103
95
diff view generated by jsdifflib
1
The magic value pushed onto the callee stack as an integrity
1
Convert the Neon VMUL, VMLA, VMLS and VSHL insns in the
2
check is different if floating point is present.
2
3-reg-same grouping to decodetree.
3
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20190416125744.27770-15-peter.maydell@linaro.org
6
Message-id: 20200430181003.21682-20-peter.maydell@linaro.org
7
---
7
---
8
target/arm/helper.c | 22 +++++++++++++++++++---
8
target/arm/neon-dp.decode | 9 +++++++
9
1 file changed, 19 insertions(+), 3 deletions(-)
9
target/arm/translate-neon.inc.c | 44 +++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 28 +++------------------
11
3 files changed, 56 insertions(+), 25 deletions(-)
10
12
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
15
--- a/target/arm/neon-dp.decode
14
+++ b/target/arm/helper.c
16
+++ b/target/arm/neon-dp.decode
15
@@ -XXX,XX +XXX,XX @@ load_fail:
17
@@ -XXX,XX +XXX,XX @@ VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
16
return false;
18
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
17
}
19
VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
18
20
19
+static uint32_t v7m_integrity_sig(CPUARMState *env, uint32_t lr)
21
+VSHL_S_3s 1111 001 0 0 . .. .... .... 0100 . . . 0 .... @3same
22
+VSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 0 .... @3same
23
+
24
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
25
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
26
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
27
@@ -XXX,XX +XXX,XX @@ VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
28
29
VTST_3s 1111 001 0 0 . .. .... .... 1000 . . . 1 .... @3same
30
VCEQ_3s 1111 001 1 0 . .. .... .... 1000 . . . 1 .... @3same
31
+
32
+VMLA_3s 1111 001 0 0 . .. .... .... 1001 . . . 0 .... @3same
33
+VMLS_3s 1111 001 1 0 . .. .... .... 1001 . . . 0 .... @3same
34
+
35
+VMUL_3s 1111 001 0 0 . .. .... .... 1001 . . . 1 .... @3same
36
+VMUL_p_3s 1111 001 1 0 . .. .... .... 1001 . . . 1 .... @3same
37
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate-neon.inc.c
40
+++ b/target/arm/translate-neon.inc.c
41
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
42
DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
43
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
44
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
45
+DO_3SAME_NO_SZ_3(VMUL, tcg_gen_gvec_mul)
46
47
#define DO_3SAME_CMP(INSN, COND) \
48
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
49
@@ -XXX,XX +XXX,XX @@ DO_3SAME_GVEC4(VQADD_S, sqadd_op)
50
DO_3SAME_GVEC4(VQADD_U, uqadd_op)
51
DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
52
DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
53
+
54
+static void gen_VMUL_p_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
55
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
20
+{
56
+{
21
+ /*
57
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz,
22
+ * Return the integrity signature value for the callee-saves
58
+ 0, gen_helper_gvec_pmul_b);
23
+ * stack frame section. @lr is the exception return payload/LR value
24
+ * whose FType bit forms bit 0 of the signature if FP is present.
25
+ */
26
+ uint32_t sig = 0xfefa125a;
27
+
28
+ if (!arm_feature(env, ARM_FEATURE_VFP) || (lr & R_V7M_EXCRET_FTYPE_MASK)) {
29
+ sig |= 1;
30
+ }
31
+ return sig;
32
+}
59
+}
33
+
60
+
34
static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
61
+static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
35
bool ignore_faults)
62
+{
36
{
63
+ if (a->size != 0) {
37
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
64
+ return false;
38
bool stacked_ok;
65
+ }
39
uint32_t limit;
66
+ return do_3same(s, a, gen_VMUL_p_3s);
40
bool want_psp;
67
+}
41
+ uint32_t sig;
68
+
42
69
+#define DO_3SAME_GVEC3_NO_SZ_3(INSN, OPARRAY) \
43
if (dotailchain) {
70
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
44
bool mode = lr & R_V7M_EXCRET_MODE_MASK;
71
+ uint32_t rn_ofs, uint32_t rm_ofs, \
45
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
72
+ uint32_t oprsz, uint32_t maxsz) \
46
/* Write as much of the stack frame as we can. A write failure may
73
+ { \
47
* cause us to pend a derived exception.
74
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, \
48
*/
75
+ oprsz, maxsz, &OPARRAY[vece]); \
49
+ sig = v7m_integrity_sig(env, lr);
76
+ } \
50
stacked_ok =
77
+ DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
51
- v7m_stack_write(cpu, frameptr, 0xfefa125b, mmu_idx, ignore_faults) &&
78
+
52
+ v7m_stack_write(cpu, frameptr, sig, mmu_idx, ignore_faults) &&
79
+
53
v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
80
+DO_3SAME_GVEC3_NO_SZ_3(VMLA, mla_op)
54
ignore_faults) &&
81
+DO_3SAME_GVEC3_NO_SZ_3(VMLS, mls_op)
55
v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
82
+
56
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
83
+#define DO_3SAME_GVEC3_SHIFT(INSN, OPARRAY) \
57
if (return_to_secure &&
84
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
58
((excret & R_V7M_EXCRET_ES_MASK) == 0 ||
85
+ uint32_t rn_ofs, uint32_t rm_ofs, \
59
(excret & R_V7M_EXCRET_DCRS_MASK) == 0)) {
86
+ uint32_t oprsz, uint32_t maxsz) \
60
- uint32_t expected_sig = 0xfefa125b;
87
+ { \
61
uint32_t actual_sig;
88
+ /* Note the operation is vshl vd,vm,vn */ \
62
89
+ tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, \
63
pop_ok = v7m_stack_read(cpu, &actual_sig, frameptr, mmu_idx);
90
+ oprsz, maxsz, &OPARRAY[vece]); \
64
91
+ } \
65
- if (pop_ok && expected_sig != actual_sig) {
92
+ DO_3SAME(INSN, gen_##INSN##_3s)
66
+ if (pop_ok && v7m_integrity_sig(env, excret) != actual_sig) {
93
+
67
/* Take a SecureFault on the current stack */
94
+DO_3SAME_GVEC3_SHIFT(VSHL_S, sshl_op)
68
env->v7m.sfsr |= R_V7M_SFSR_INVIS_MASK;
95
+DO_3SAME_GVEC3_SHIFT(VSHL_U, ushl_op)
69
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate.c
99
+++ b/target/arm/translate.c
100
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
101
}
102
return 1;
103
104
- case NEON_3R_VMUL: /* VMUL */
105
- if (u) {
106
- /* Polynomial case allows only P8. */
107
- if (size != 0) {
108
- return 1;
109
- }
110
- tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
111
- 0, gen_helper_gvec_pmul_b);
112
- } else {
113
- tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
114
- vec_size, vec_size);
115
- }
116
- return 0;
117
-
118
- case NEON_3R_VML: /* VMLA, VMLS */
119
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
120
- u ? &mls_op[size] : &mla_op[size]);
121
- return 0;
122
-
123
- case NEON_3R_VSHL:
124
- /* Note the operation is vshl vd,vm,vn */
125
- tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
126
- u ? &ushl_op[size] : &sshl_op[size]);
127
- return 0;
128
-
129
case NEON_3R_VADD_VSUB:
130
case NEON_3R_LOGIC:
131
case NEON_3R_VMAX:
132
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
133
case NEON_3R_VCGE:
134
case NEON_3R_VQADD:
135
case NEON_3R_VQSUB:
136
+ case NEON_3R_VMUL:
137
+ case NEON_3R_VML:
138
+ case NEON_3R_VSHL:
139
/* Already handled by decodetree */
140
return 1;
141
}
70
--
142
--
71
2.20.1
143
2.20.1
72
144
73
145
diff view generated by jsdifflib
1
If the floating point extension is present, then the SG instruction
1
We're going to want at least some of the NeonGen* typedefs
2
must clear the CONTROL_S.SFPA bit. Implement this.
2
for the refactored 32-bit Neon decoder, so move them all
3
3
to translate.h since it makes more sense to keep them in
4
(On a no-FPU system the bit will always be zero, so we don't need
4
one group.
5
to make the clearing of the bit conditional on ARM_FEATURE_VFP.)
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
Message-id: 20190416125744.27770-8-peter.maydell@linaro.org
8
Message-id: 20200430181003.21682-23-peter.maydell@linaro.org
10
---
9
---
11
target/arm/helper.c | 1 +
10
target/arm/translate.h | 17 +++++++++++++++++
12
1 file changed, 1 insertion(+)
11
target/arm/translate-a64.c | 17 -----------------
12
2 files changed, 17 insertions(+), 17 deletions(-)
13
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
16
--- a/target/arm/translate.h
17
+++ b/target/arm/helper.c
17
+++ b/target/arm/translate.h
18
@@ -XXX,XX +XXX,XX @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
18
@@ -XXX,XX +XXX,XX @@ typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
19
qemu_log_mask(CPU_LOG_INT, "...really an SG instruction at 0x%08" PRIx32
19
typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
20
", executing it\n", env->regs[15]);
20
uint32_t, uint32_t, uint32_t);
21
env->regs[14] &= ~1;
21
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
22
+/* Function prototype for gen_ functions for calling Neon helpers */
23
switch_v7m_security_state(env, true);
23
+typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
24
xpsr_write(env, 0, XPSR_IT);
24
+typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
25
env->regs[15] += 4;
25
+typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
26
+typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
27
+typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
28
+typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
29
+typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
30
+typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
31
+typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
32
+typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
33
+typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
34
+typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
35
+typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
36
+typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
37
+typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
38
+
39
#endif /* TARGET_ARM_TRANSLATE_H */
40
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate-a64.c
43
+++ b/target/arm/translate-a64.c
44
@@ -XXX,XX +XXX,XX @@ typedef struct AArch64DecodeTable {
45
AArch64DecodeFn *disas_fn;
46
} AArch64DecodeTable;
47
48
-/* Function prototype for gen_ functions for calling Neon helpers */
49
-typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
50
-typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
51
-typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
52
-typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
53
-typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
54
-typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
55
-typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
56
-typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
57
-typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
58
-typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
59
-typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
60
-typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
61
-typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
62
-typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
63
-typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
64
-
65
/* initialize TCG globals. */
66
void a64_translate_init(void)
67
{
26
--
68
--
27
2.20.1
69
2.20.1
28
70
29
71
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20190412165416.7977-5-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
include/hw/devices.h | 6 ------
9
include/hw/display/tc6393xb.h | 24 ++++++++++++++++++++++++
10
hw/arm/tosa.c | 2 +-
11
hw/display/tc6393xb.c | 2 +-
12
MAINTAINERS | 1 +
13
5 files changed, 27 insertions(+), 8 deletions(-)
14
create mode 100644 include/hw/display/tc6393xb.h
15
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/devices.h
19
+++ b/include/hw/devices.h
20
@@ -XXX,XX +XXX,XX @@ void *tahvo_init(qemu_irq irq, int betty);
21
22
void retu_key_event(void *retu, int state);
23
24
-/* tc6393xb.c */
25
-typedef struct TC6393xbState TC6393xbState;
26
-TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
27
- uint32_t base, qemu_irq irq);
28
-qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
29
-
30
#endif
31
diff --git a/include/hw/display/tc6393xb.h b/include/hw/display/tc6393xb.h
32
new file mode 100644
33
index XXXXXXX..XXXXXXX
34
--- /dev/null
35
+++ b/include/hw/display/tc6393xb.h
36
@@ -XXX,XX +XXX,XX @@
37
+/*
38
+ * Toshiba TC6393XB I/O Controller.
39
+ * Found in Sharp Zaurus SL-6000 (tosa) or some
40
+ * Toshiba e-Series PDAs.
41
+ *
42
+ * Copyright (c) 2007 Hervé Poussineau
43
+ *
44
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
45
+ * See the COPYING file in the top-level directory.
46
+ */
47
+
48
+#ifndef HW_DISPLAY_TC6393XB_H
49
+#define HW_DISPLAY_TC6393XB_H
50
+
51
+#include "exec/memory.h"
52
+#include "hw/irq.h"
53
+
54
+typedef struct TC6393xbState TC6393xbState;
55
+
56
+TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
57
+ uint32_t base, qemu_irq irq);
58
+qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
59
+
60
+#endif
61
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/tosa.c
64
+++ b/hw/arm/tosa.c
65
@@ -XXX,XX +XXX,XX @@
66
#include "hw/hw.h"
67
#include "hw/arm/pxa.h"
68
#include "hw/arm/arm.h"
69
-#include "hw/devices.h"
70
#include "hw/arm/sharpsl.h"
71
#include "hw/pcmcia.h"
72
#include "hw/boards.h"
73
+#include "hw/display/tc6393xb.h"
74
#include "hw/i2c/i2c.h"
75
#include "hw/ssi/ssi.h"
76
#include "hw/sysbus.h"
77
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/display/tc6393xb.c
80
+++ b/hw/display/tc6393xb.c
81
@@ -XXX,XX +XXX,XX @@
82
#include "qapi/error.h"
83
#include "qemu/host-utils.h"
84
#include "hw/hw.h"
85
-#include "hw/devices.h"
86
+#include "hw/display/tc6393xb.h"
87
#include "hw/block/flash.h"
88
#include "ui/console.h"
89
#include "ui/pixel_ops.h"
90
diff --git a/MAINTAINERS b/MAINTAINERS
91
index XXXXXXX..XXXXXXX 100644
92
--- a/MAINTAINERS
93
+++ b/MAINTAINERS
94
@@ -XXX,XX +XXX,XX @@ F: hw/misc/mst_fpga.c
95
F: hw/misc/max111x.c
96
F: include/hw/arm/pxa.h
97
F: include/hw/arm/sharpsl.h
98
+F: include/hw/display/tc6393xb.h
99
100
SABRELITE / i.MX6
101
M: Peter Maydell <peter.maydell@linaro.org>
102
--
103
2.20.1
104
105
diff view generated by jsdifflib