1
First pullreq for arm of the 4.1 series, since I'm back from
1
Hi; this mostly contains the first slice of A64 decodetree
2
holiday now. This is mostly my M-profile FPU series and Philippe's
2
patches, plus some other minor pieces. It also has the
3
devices.h cleanup. I have a pile of other patchsets to work through
3
enablement of MTE for KVM guests.
4
in my to-review folder, but 42 patches is definitely quite
5
big enough to send now...
6
4
7
thanks
5
thanks
8
-- PMM
6
-- PMM
9
7
10
The following changes since commit 413a99a92c13ec408dcf2adaa87918dc81e890c8:
8
The following changes since commit d27e7c359330ba7020bdbed7ed2316cb4cf6ffc1:
11
9
12
Add Nios II semihosting support. (2019-04-29 16:09:51 +0100)
10
qapi/parser: Drop two bad type hints for now (2023-05-17 10:18:33 -0700)
13
11
14
are available in the Git repository at:
12
are available in the Git repository at:
15
13
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190429
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230518
17
15
18
for you to fetch changes up to 437cc27ddfded3bbab6afd5ac1761e0e195edba7:
16
for you to fetch changes up to 91608e2a44f36e79cb83f863b8a7bb57d2c98061:
19
17
20
hw/devices: Move SMSC 91C111 declaration into a new header (2019-04-29 17:57:21 +0100)
18
docs: Convert u2f.txt to rST (2023-05-18 11:40:32 +0100)
21
19
22
----------------------------------------------------------------
20
----------------------------------------------------------------
23
target-arm queue:
21
target-arm queue:
24
* remove "bag of random stuff" hw/devices.h header
22
* Fix vd == vm overlap in sve_ldff1_z
25
* implement FPU for Cortex-M and enable it for Cortex-M4 and -M33
23
* Add support for MTE with KVM guests
26
* hw/dma: Compile the bcm2835_dma device as common object
24
* Add RAZ/WI handling for DBGDTR[TX|RX]
27
* configure: Remove --source-path option
25
* Start of conversion of A64 decoder to decodetree
28
* hw/ssi/xilinx_spips: Avoid variable length array
26
* Saturate L2CTLR_EL1 core count field rather than overflowing
29
* hw/arm/smmuv3: Remove SMMUNotifierNode
27
* vexpress: Avoid trivial memory leak of 'flashalias'
28
* sbsa-ref: switch default cpu core to Neoverse-N1
29
* sbsa-ref: use Bochs graphics card instead of VGA
30
* MAINTAINERS: Add Marcin Juszkiewicz to sbsa-ref reviewer list
31
* docs: Convert u2f.txt to rST
30
32
31
----------------------------------------------------------------
33
----------------------------------------------------------------
32
Eric Auger (1):
34
Alex Bennée (1):
33
hw/arm/smmuv3: Remove SMMUNotifierNode
35
target/arm: add RAZ/WI handling for DBGDTR[TX|RX]
34
36
35
Peter Maydell (28):
37
Cornelia Huck (1):
36
hw/ssi/xilinx_spips: Avoid variable length array
38
arm/kvm: add support for MTE
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
39
65
Philippe Mathieu-Daudé (13):
40
Marcin Juszkiewicz (3):
66
hw/dma: Compile the bcm2835_dma device as common object
41
sbsa-ref: switch default cpu core to Neoverse-N1
67
hw/arm/aspeed: Use TYPE_TMP105/TYPE_PCA9552 instead of hardcoded string
42
Maintainers: add myself as reviewer for sbsa-ref
68
hw/arm/nseries: Use TYPE_TMP105 instead of hardcoded string
43
sbsa-ref: use Bochs graphics card instead of VGA
69
hw/display/tc6393xb: Remove unused functions
70
hw/devices: Move TC6393XB declarations into a new header
71
hw/devices: Move Blizzard declarations into a new header
72
hw/devices: Move CBus declarations into a new header
73
hw/devices: Move Gamepad declarations into a new header
74
hw/devices: Move TI touchscreen declarations into a new header
75
hw/devices: Move LAN9118 declarations into a new header
76
hw/net/ne2000-isa: Add guards to the header
77
hw/net/lan9118: Export TYPE_LAN9118 and use it instead of hardcoded string
78
hw/devices: Move SMSC 91C111 declaration into a new header
79
44
80
configure | 10 +-
45
Peter Maydell (14):
81
hw/dma/Makefile.objs | 2 +-
46
target/arm: Create decodetree skeleton for A64
82
include/hw/arm/omap.h | 6 +-
47
target/arm: Pull calls to disas_sve() and disas_sme() out of legacy decoder
83
include/hw/arm/smmu-common.h | 8 +-
48
target/arm: Convert Extract instructions to decodetree
84
include/hw/devices.h | 62 ---
49
target/arm: Convert unconditional branch immediate to decodetree
85
include/hw/display/blizzard.h | 22 ++
50
target/arm: Convert CBZ, CBNZ to decodetree
86
include/hw/display/tc6393xb.h | 24 ++
51
target/arm: Convert TBZ, TBNZ to decodetree
87
include/hw/input/gamepad.h | 19 +
52
target/arm: Convert conditional branch insns to decodetree
88
include/hw/input/tsc2xxx.h | 36 ++
53
target/arm: Convert BR, BLR, RET to decodetree
89
include/hw/misc/cbus.h | 32 ++
54
target/arm: Convert BRA[AB]Z, BLR[AB]Z, RETA[AB] to decodetree
90
include/hw/net/lan9118.h | 21 +
55
target/arm: Convert BRAA, BRAB, BLRAA, BLRAB to decodetree
91
include/hw/net/ne2000-isa.h | 6 +
56
target/arm: Convert ERET, ERETAA, ERETAB to decodetree
92
include/hw/net/smc91c111.h | 19 +
57
target/arm: Saturate L2CTLR_EL1 core count field rather than overflowing
93
include/qemu/typedefs.h | 1 -
58
hw/arm/vexpress: Avoid trivial memory leak of 'flashalias'
94
target/arm/cpu.h | 95 ++++-
59
docs: Convert u2f.txt to rST
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
60
61
Richard Henderson (10):
62
target/arm: Fix vd == vm overlap in sve_ldff1_z
63
target/arm: Split out disas_a64_legacy
64
target/arm: Convert PC-rel addressing to decodetree
65
target/arm: Split gen_add_CC and gen_sub_CC
66
target/arm: Convert Add/subtract (immediate) to decodetree
67
target/arm: Convert Add/subtract (immediate with tags) to decodetree
68
target/arm: Replace bitmask64 with MAKE_64BIT_MASK
69
target/arm: Convert Logical (immediate) to decodetree
70
target/arm: Convert Move wide (immediate) to decodetree
71
target/arm: Convert Bitfield to decodetree
72
73
MAINTAINERS | 1 +
74
docs/system/device-emulation.rst | 1 +
75
docs/system/devices/usb-u2f.rst | 93 +++
76
docs/system/devices/usb.rst | 2 +-
77
docs/u2f.txt | 110 ----
78
target/arm/cpu.h | 4 +
79
target/arm/kvm_arm.h | 19 +
80
target/arm/tcg/translate.h | 5 +
81
target/arm/tcg/a64.decode | 152 +++++
82
hw/arm/sbsa-ref.c | 4 +-
83
hw/arm/vexpress.c | 40 +-
84
hw/arm/virt.c | 73 ++-
85
target/arm/cortex-regs.c | 11 +-
86
target/arm/cpu.c | 9 +-
87
target/arm/debug_helper.c | 11 +-
88
target/arm/kvm.c | 35 +
89
target/arm/kvm64.c | 5 +
90
target/arm/tcg/sve_helper.c | 6 +
91
target/arm/tcg/translate-a64.c | 1321 ++++++++++++++++----------------------
92
target/arm/tcg/meson.build | 1 +
93
20 files changed, 979 insertions(+), 924 deletions(-)
94
create mode 100644 docs/system/devices/usb-u2f.rst
95
delete mode 100644 docs/u2f.txt
96
create mode 100644 target/arm/tcg/a64.decode
97
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
2
2
3
This commit finally deletes "hw/devices.h".
3
The world outside moves to newer and newer cpu cores. Let move SBSA
4
Reference Platform to something newer as well.
4
5
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
6
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
7
Message-id: 20190412165416.7977-13-philmd@redhat.com
8
Message-id: 20230506183417.1360427-1-marcin.juszkiewicz@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
include/hw/devices.h | 11 -----------
11
hw/arm/sbsa-ref.c | 2 +-
11
include/hw/net/smc91c111.h | 19 +++++++++++++++++++
12
1 file changed, 1 insertion(+), 1 deletion(-)
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
13
22
diff --git a/include/hw/devices.h b/include/hw/devices.h
14
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.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
15
index XXXXXXX..XXXXXXX 100644
66
--- a/hw/arm/gumstix.c
16
--- a/hw/arm/sbsa-ref.c
67
+++ b/hw/arm/gumstix.c
17
+++ b/hw/arm/sbsa-ref.c
68
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_class_init(ObjectClass *oc, void *data)
69
#include "hw/arm/pxa.h"
19
70
#include "net/net.h"
20
mc->init = sbsa_ref_init;
71
#include "hw/block/flash.h"
21
mc->desc = "QEMU 'SBSA Reference' ARM Virtual Machine";
72
-#include "hw/devices.h"
22
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a57");
73
+#include "hw/net/smc91c111.h"
23
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("neoverse-n1");
74
#include "hw/boards.h"
24
mc->max_cpus = 512;
75
#include "exec/address-spaces.h"
25
mc->pci_allow_0_address = true;
76
#include "sysemu/qtest.h"
26
mc->minimum_page_bits = 12;
77
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/arm/integratorcp.c
80
+++ b/hw/arm/integratorcp.c
81
@@ -XXX,XX +XXX,XX @@
82
#include "qemu-common.h"
83
#include "cpu.h"
84
#include "hw/sysbus.h"
85
-#include "hw/devices.h"
86
#include "hw/boards.h"
87
#include "hw/arm/arm.h"
88
#include "hw/misc/arm_integrator_debug.h"
89
+#include "hw/net/smc91c111.h"
90
#include "net/net.h"
91
#include "exec/address-spaces.h"
92
#include "sysemu/sysemu.h"
93
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/hw/arm/mainstone.c
96
+++ b/hw/arm/mainstone.c
97
@@ -XXX,XX +XXX,XX @@
98
#include "hw/arm/pxa.h"
99
#include "hw/arm/arm.h"
100
#include "net/net.h"
101
-#include "hw/devices.h"
102
+#include "hw/net/smc91c111.h"
103
#include "hw/boards.h"
104
#include "hw/block/flash.h"
105
#include "hw/sysbus.h"
106
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/hw/arm/realview.c
109
+++ b/hw/arm/realview.c
110
@@ -XXX,XX +XXX,XX @@
111
#include "hw/sysbus.h"
112
#include "hw/arm/arm.h"
113
#include "hw/arm/primecell.h"
114
-#include "hw/devices.h"
115
#include "hw/net/lan9118.h"
116
+#include "hw/net/smc91c111.h"
117
#include "hw/pci/pci.h"
118
#include "net/net.h"
119
#include "sysemu/sysemu.h"
120
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
121
index XXXXXXX..XXXXXXX 100644
122
--- a/hw/arm/versatilepb.c
123
+++ b/hw/arm/versatilepb.c
124
@@ -XXX,XX +XXX,XX @@
125
#include "cpu.h"
126
#include "hw/sysbus.h"
127
#include "hw/arm/arm.h"
128
-#include "hw/devices.h"
129
+#include "hw/net/smc91c111.h"
130
#include "net/net.h"
131
#include "sysemu/sysemu.h"
132
#include "hw/pci/pci.h"
133
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/hw/net/smc91c111.c
136
+++ b/hw/net/smc91c111.c
137
@@ -XXX,XX +XXX,XX @@
138
#include "qemu/osdep.h"
139
#include "hw/sysbus.h"
140
#include "net/net.h"
141
-#include "hw/devices.h"
142
+#include "hw/net/smc91c111.h"
143
#include "qemu/log.h"
144
/* For crc32 */
145
#include <zlib.h>
146
--
27
--
147
2.20.1
28
2.34.1
148
149
diff view generated by jsdifflib
1
Enforce that for M-profile various FPSCR bits which are RES0 there
1
From: Richard Henderson <richard.henderson@linaro.org>
2
but have defined meanings on A-profile are never settable. This
3
ensures that M-profile code can't enable the A-profile behaviour
4
(notably vector length/stride handling) by accident.
5
2
3
If vd == vm, copy vm to scratch, so that we can pre-zero
4
the output and still access the gather indicies.
5
6
Cc: qemu-stable@nongnu.org
7
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1612
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230504104232.1877774-1-richard.henderson@linaro.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-2-peter.maydell@linaro.org
9
---
12
---
10
target/arm/vfp_helper.c | 8 ++++++++
13
target/arm/tcg/sve_helper.c | 6 ++++++
11
1 file changed, 8 insertions(+)
14
1 file changed, 6 insertions(+)
12
15
13
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
16
diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/vfp_helper.c
18
--- a/target/arm/tcg/sve_helper.c
16
+++ b/target/arm/vfp_helper.c
19
+++ b/target/arm/tcg/sve_helper.c
17
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
20
@@ -XXX,XX +XXX,XX @@ void sve_ldff1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
18
val &= ~FPCR_FZ16;
21
intptr_t reg_off;
22
SVEHostPage info;
23
target_ulong addr, in_page;
24
+ ARMVectorReg scratch;
25
26
/* Skip to the first true predicate. */
27
reg_off = find_next_active(vg, 0, reg_max, esz);
28
@@ -XXX,XX +XXX,XX @@ void sve_ldff1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
29
return;
19
}
30
}
20
31
21
+ if (arm_feature(env, ARM_FEATURE_M)) {
32
+ /* Protect against overlap between vd and vm. */
22
+ /*
33
+ if (unlikely(vd == vm)) {
23
+ * M profile FPSCR is RES0 for the QC, STRIDE, FZ16, LEN bits
34
+ vm = memcpy(&scratch, vm, reg_max);
24
+ * and also for the trapped-exception-handling bits IxE.
25
+ */
26
+ val &= 0xf7c0009f;
27
+ }
35
+ }
28
+
36
+
29
/*
37
/*
30
* We don't implement trapped exception handling, so the
38
* Probe the first element, allowing faults.
31
* trap enable bits, IDE|IXE|UFE|OFE|DZE|IOE are all RAZ/WI (not RES0!)
39
*/
32
--
40
--
33
2.20.1
41
2.34.1
34
35
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
At Linaro I work on sbsa-ref, know direction it goes.
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
5
Message-id: 20190412165416.7977-8-philmd@redhat.com
5
May not get code details each time.
6
7
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 20230515143753.365591-1-marcin.juszkiewicz@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/devices.h | 3 ---
12
MAINTAINERS | 1 +
9
include/hw/input/gamepad.h | 19 +++++++++++++++++++
13
1 file changed, 1 insertion(+)
10
hw/arm/stellaris.c | 2 +-
11
hw/input/stellaris_input.c | 2 +-
12
MAINTAINERS | 1 +
13
5 files changed, 22 insertions(+), 5 deletions(-)
14
create mode 100644 include/hw/input/gamepad.h
15
14
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/devices.h
19
+++ b/include/hw/devices.h
20
@@ -XXX,XX +XXX,XX @@ void *tsc2005_init(qemu_irq pintdav);
21
uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
22
void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
23
24
-/* stellaris_input.c */
25
-void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
26
-
27
#endif
28
diff --git a/include/hw/input/gamepad.h b/include/hw/input/gamepad.h
29
new file mode 100644
30
index XXXXXXX..XXXXXXX
31
--- /dev/null
32
+++ b/include/hw/input/gamepad.h
33
@@ -XXX,XX +XXX,XX @@
34
+/*
35
+ * Gamepad style buttons connected to IRQ/GPIO lines
36
+ *
37
+ * Copyright (c) 2007 CodeSourcery.
38
+ * Written by Paul Brook
39
+ *
40
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
41
+ * See the COPYING file in the top-level directory.
42
+ */
43
+
44
+#ifndef HW_INPUT_GAMEPAD_H
45
+#define HW_INPUT_GAMEPAD_H
46
+
47
+#include "hw/irq.h"
48
+
49
+/* stellaris_input.c */
50
+void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
51
+
52
+#endif
53
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/arm/stellaris.c
56
+++ b/hw/arm/stellaris.c
57
@@ -XXX,XX +XXX,XX @@
58
#include "hw/sysbus.h"
59
#include "hw/ssi/ssi.h"
60
#include "hw/arm/arm.h"
61
-#include "hw/devices.h"
62
#include "qemu/timer.h"
63
#include "hw/i2c/i2c.h"
64
#include "net/net.h"
65
@@ -XXX,XX +XXX,XX @@
66
#include "sysemu/sysemu.h"
67
#include "hw/arm/armv7m.h"
68
#include "hw/char/pl011.h"
69
+#include "hw/input/gamepad.h"
70
#include "hw/watchdog/cmsdk-apb-watchdog.h"
71
#include "hw/misc/unimp.h"
72
#include "cpu.h"
73
diff --git a/hw/input/stellaris_input.c b/hw/input/stellaris_input.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/input/stellaris_input.c
76
+++ b/hw/input/stellaris_input.c
77
@@ -XXX,XX +XXX,XX @@
78
*/
79
#include "qemu/osdep.h"
80
#include "hw/hw.h"
81
-#include "hw/devices.h"
82
+#include "hw/input/gamepad.h"
83
#include "ui/console.h"
84
85
typedef struct {
86
diff --git a/MAINTAINERS b/MAINTAINERS
15
diff --git a/MAINTAINERS b/MAINTAINERS
87
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
88
--- a/MAINTAINERS
17
--- a/MAINTAINERS
89
+++ b/MAINTAINERS
18
+++ b/MAINTAINERS
90
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
19
@@ -XXX,XX +XXX,XX @@ SBSA-REF
20
M: Radoslaw Biernacki <rad@semihalf.com>
21
M: Peter Maydell <peter.maydell@linaro.org>
22
R: Leif Lindholm <quic_llindhol@quicinc.com>
23
+R: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
91
L: qemu-arm@nongnu.org
24
L: qemu-arm@nongnu.org
92
S: Maintained
25
S: Maintained
93
F: hw/*/stellaris*
26
F: hw/arm/sbsa-ref.c
94
+F: include/hw/input/gamepad.h
95
96
Versatile Express
97
M: Peter Maydell <peter.maydell@linaro.org>
98
--
27
--
99
2.20.1
28
2.34.1
100
29
101
30
diff view generated by jsdifflib
1
We are close to running out of TB flags for AArch32; we could
1
From: Cornelia Huck <cohuck@redhat.com>
2
start using the cs_base word, but before we do that we can
2
3
economise on our usage by sharing the same bits for the VFP
3
Extend the 'mte' property for the virt machine to cover KVM as
4
VECSTRIDE field and the XScale XSCALE_CPAR field. This
4
well. For KVM, we don't allocate tag memory, but instead enable the
5
works because no XScale CPU ever had VFP.
5
capability.
6
6
7
If MTE has been enabled, we need to disable migration, as we do not
8
yet have a way to migrate the tags as well. Therefore, MTE will stay
9
off with KVM unless requested explicitly.
10
11
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20230428095533.21747-2-cohuck@redhat.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-18-peter.maydell@linaro.org
10
---
16
---
11
target/arm/cpu.h | 10 ++++++----
17
target/arm/cpu.h | 4 +++
12
target/arm/cpu.c | 7 +++++++
18
target/arm/kvm_arm.h | 19 ++++++++++++
13
target/arm/helper.c | 6 +++++-
19
hw/arm/virt.c | 73 +++++++++++++++++++++++++-------------------
14
target/arm/translate.c | 9 +++++++--
20
target/arm/cpu.c | 9 +++---
15
4 files changed, 25 insertions(+), 7 deletions(-)
21
target/arm/kvm.c | 35 +++++++++++++++++++++
22
target/arm/kvm64.c | 5 +++
23
6 files changed, 109 insertions(+), 36 deletions(-)
16
24
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
25
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
27
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
28
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
29
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
30
*/
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
31
uint32_t psci_conduit;
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
32
25
+/*
33
+ /* CPU has Memory Tag Extension */
26
+ * We store the bottom two bits of the CPAR as TB flags and handle
34
+ bool has_mte;
27
+ * checks on the other bits at runtime. This shares the same bits as
35
+
28
+ * VECSTRIDE, which is OK as no XScale CPU has VFP.
36
/* For v8M, initial value of the Secure VTOR */
37
uint32_t init_svtor;
38
/* For v8M, initial value of the Non-secure VTOR */
39
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
40
bool prop_pauth;
41
bool prop_pauth_impdef;
42
bool prop_lpa2;
43
+ OnOffAuto prop_mte;
44
45
/* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
46
uint32_t dcz_blocksize;
47
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/kvm_arm.h
50
+++ b/target/arm/kvm_arm.h
51
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_pmu_supported(void);
52
*/
53
bool kvm_arm_sve_supported(void);
54
55
+/**
56
+ * kvm_arm_mte_supported:
57
+ *
58
+ * Returns: true if KVM can enable MTE, and false otherwise.
29
+ */
59
+ */
30
+FIELD(TBFLAG_A32, XSCALE_CPAR, 4, 2)
60
+bool kvm_arm_mte_supported(void);
61
+
62
/**
63
* kvm_arm_get_max_vm_ipa_size:
64
* @ms: Machine state handle
65
@@ -XXX,XX +XXX,XX @@ void kvm_arm_pvtime_init(CPUState *cs, uint64_t ipa);
66
67
int kvm_arm_set_irq(int cpu, int irqtype, int irq, int level);
68
69
+void kvm_arm_enable_mte(Object *cpuobj, Error **errp);
70
+
71
#else
72
31
/*
73
/*
32
* Indicates whether cp register reads and writes by guest code should access
74
@@ -XXX,XX +XXX,XX @@ static inline bool kvm_arm_steal_time_supported(void)
33
* the secure or nonsecure bank of banked registers; note that this is not
75
return false;
34
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
76
}
35
FIELD(TBFLAG_A32, VFPEN, 7, 1)
77
36
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
78
+static inline bool kvm_arm_mte_supported(void)
37
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
79
+{
38
-/* We store the bottom two bits of the CPAR as TB flags and handle
80
+ return false;
39
- * checks on the other bits at runtime
81
+}
40
- */
82
+
41
-FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
83
/*
42
/* For M profile only, Handler (ie not Thread) mode */
84
* These functions should never actually be called without KVM support.
43
FIELD(TBFLAG_A32, HANDLER, 21, 1)
85
*/
44
/* For M profile only, whether we should generate stack-limit checks */
86
@@ -XXX,XX +XXX,XX @@ static inline uint32_t kvm_arm_sve_get_vls(CPUState *cs)
87
g_assert_not_reached();
88
}
89
90
+static inline void kvm_arm_enable_mte(Object *cpuobj, Error **errp)
91
+{
92
+ g_assert_not_reached();
93
+}
94
+
95
#endif
96
97
static inline const char *gic_class_name(void)
98
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/hw/arm/virt.c
101
+++ b/hw/arm/virt.c
102
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
103
exit(1);
104
}
105
106
- if (vms->mte && (kvm_enabled() || hvf_enabled())) {
107
+ if (vms->mte && hvf_enabled()) {
108
error_report("mach-virt: %s does not support providing "
109
"MTE to the guest CPU",
110
current_accel_name());
111
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
112
}
113
114
if (vms->mte) {
115
- /* Create the memory region only once, but link to all cpus. */
116
- if (!tag_sysmem) {
117
- /*
118
- * The property exists only if MemTag is supported.
119
- * If it is, we must allocate the ram to back that up.
120
- */
121
- if (!object_property_find(cpuobj, "tag-memory")) {
122
- error_report("MTE requested, but not supported "
123
- "by the guest CPU");
124
+ if (tcg_enabled()) {
125
+ /* Create the memory region only once, but link to all cpus. */
126
+ if (!tag_sysmem) {
127
+ /*
128
+ * The property exists only if MemTag is supported.
129
+ * If it is, we must allocate the ram to back that up.
130
+ */
131
+ if (!object_property_find(cpuobj, "tag-memory")) {
132
+ error_report("MTE requested, but not supported "
133
+ "by the guest CPU");
134
+ exit(1);
135
+ }
136
+
137
+ tag_sysmem = g_new(MemoryRegion, 1);
138
+ memory_region_init(tag_sysmem, OBJECT(machine),
139
+ "tag-memory", UINT64_MAX / 32);
140
+
141
+ if (vms->secure) {
142
+ secure_tag_sysmem = g_new(MemoryRegion, 1);
143
+ memory_region_init(secure_tag_sysmem, OBJECT(machine),
144
+ "secure-tag-memory",
145
+ UINT64_MAX / 32);
146
+
147
+ /* As with ram, secure-tag takes precedence over tag. */
148
+ memory_region_add_subregion_overlap(secure_tag_sysmem,
149
+ 0, tag_sysmem, -1);
150
+ }
151
+ }
152
+
153
+ object_property_set_link(cpuobj, "tag-memory",
154
+ OBJECT(tag_sysmem), &error_abort);
155
+ if (vms->secure) {
156
+ object_property_set_link(cpuobj, "secure-tag-memory",
157
+ OBJECT(secure_tag_sysmem),
158
+ &error_abort);
159
+ }
160
+ } else if (kvm_enabled()) {
161
+ if (!kvm_arm_mte_supported()) {
162
+ error_report("MTE requested, but not supported by KVM");
163
exit(1);
164
}
165
-
166
- tag_sysmem = g_new(MemoryRegion, 1);
167
- memory_region_init(tag_sysmem, OBJECT(machine),
168
- "tag-memory", UINT64_MAX / 32);
169
-
170
- if (vms->secure) {
171
- secure_tag_sysmem = g_new(MemoryRegion, 1);
172
- memory_region_init(secure_tag_sysmem, OBJECT(machine),
173
- "secure-tag-memory", UINT64_MAX / 32);
174
-
175
- /* As with ram, secure-tag takes precedence over tag. */
176
- memory_region_add_subregion_overlap(secure_tag_sysmem, 0,
177
- tag_sysmem, -1);
178
- }
179
- }
180
-
181
- object_property_set_link(cpuobj, "tag-memory", OBJECT(tag_sysmem),
182
- &error_abort);
183
- if (vms->secure) {
184
- object_property_set_link(cpuobj, "secure-tag-memory",
185
- OBJECT(secure_tag_sysmem),
186
- &error_abort);
187
+ kvm_arm_enable_mte(cpuobj, &error_abort);
188
}
189
}
190
45
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
191
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
46
index XXXXXXX..XXXXXXX 100644
192
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/cpu.c
193
--- a/target/arm/cpu.c
48
+++ b/target/arm/cpu.c
194
+++ b/target/arm/cpu.c
195
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
196
qdev_prop_allow_set_link_before_realize,
197
OBJ_PROP_LINK_STRONG);
198
}
199
+ cpu->has_mte = true;
200
}
201
#endif
202
}
49
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
203
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
50
set_feature(env, ARM_FEATURE_THUMB_DSP);
204
}
205
if (cpu->tag_memory) {
206
error_setg(errp,
207
- "Cannot enable %s when guest CPUs has MTE enabled",
208
+ "Cannot enable %s when guest CPUs has tag memory enabled",
209
current_accel_name());
210
return;
211
}
212
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
51
}
213
}
52
214
53
+ /*
215
#ifndef CONFIG_USER_ONLY
54
+ * We rely on no XScale CPU having VFP so we can use the same bits in the
216
- if (cpu->tag_memory == NULL && cpu_isar_feature(aa64_mte, cpu)) {
55
+ * TB flags field for VECSTRIDE and XSCALE_CPAR.
217
+ if (!cpu->has_mte && cpu_isar_feature(aa64_mte, cpu)) {
56
+ */
218
/*
57
+ assert(!(arm_feature(env, ARM_FEATURE_VFP) &&
219
- * Disable the MTE feature bits if we do not have tag-memory
58
+ arm_feature(env, ARM_FEATURE_XSCALE)));
220
- * provided by the machine.
59
+
221
+ * Disable the MTE feature bits if we do not have the feature
60
if (arm_feature(env, ARM_FEATURE_V7) &&
222
+ * setup by the machine.
61
!arm_feature(env, ARM_FEATURE_M) &&
223
*/
62
!arm_feature(env, ARM_FEATURE_PMSA)) {
224
cpu->isar.id_aa64pfr1 =
63
diff --git a/target/arm/helper.c b/target/arm/helper.c
225
FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 0);
64
index XXXXXXX..XXXXXXX 100644
226
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
65
--- a/target/arm/helper.c
227
index XXXXXXX..XXXXXXX 100644
66
+++ b/target/arm/helper.c
228
--- a/target/arm/kvm.c
67
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
229
+++ b/target/arm/kvm.c
68
|| arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
230
@@ -XXX,XX +XXX,XX @@
69
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
231
#include "hw/boards.h"
70
}
232
#include "hw/irq.h"
71
- flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
233
#include "qemu/log.h"
72
+ /* Note that XSCALE_CPAR shares bits with VECSTRIDE */
234
+#include "migration/blocker.h"
73
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
235
74
+ flags = FIELD_DP32(flags, TBFLAG_A32,
236
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
75
+ XSCALE_CPAR, env->cp15.c15_cpar);
237
KVM_CAP_LAST_INFO
238
@@ -XXX,XX +XXX,XX @@ bool kvm_arch_cpu_check_are_resettable(void)
239
void kvm_arch_accel_class_init(ObjectClass *oc)
240
{
241
}
242
+
243
+void kvm_arm_enable_mte(Object *cpuobj, Error **errp)
244
+{
245
+ static bool tried_to_enable;
246
+ static bool succeeded_to_enable;
247
+ Error *mte_migration_blocker = NULL;
248
+ int ret;
249
+
250
+ if (!tried_to_enable) {
251
+ /*
252
+ * MTE on KVM is enabled on a per-VM basis (and retrying doesn't make
253
+ * sense), and we only want a single migration blocker as well.
254
+ */
255
+ tried_to_enable = true;
256
+
257
+ ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_ARM_MTE, 0);
258
+ if (ret) {
259
+ error_setg_errno(errp, -ret, "Failed to enable KVM_CAP_ARM_MTE");
260
+ return;
76
+ }
261
+ }
77
}
262
+
78
263
+ /* TODO: add proper migration support with MTE enabled */
79
flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
264
+ error_setg(&mte_migration_blocker,
80
diff --git a/target/arm/translate.c b/target/arm/translate.c
265
+ "Live migration disabled due to MTE enabled");
81
index XXXXXXX..XXXXXXX 100644
266
+ if (migrate_add_blocker(mte_migration_blocker, errp)) {
82
--- a/target/arm/translate.c
267
+ error_free(mte_migration_blocker);
83
+++ b/target/arm/translate.c
268
+ return;
84
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
269
+ }
85
dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
270
+ succeeded_to_enable = true;
86
dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
87
dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
88
- dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
89
- dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
90
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
91
+ dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
92
+ dc->vec_stride = 0;
93
+ } else {
94
+ dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
95
+ dc->c15_cpar = 0;
96
+ }
271
+ }
97
dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
272
+ if (succeeded_to_enable) {
98
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
273
+ object_property_set_bool(cpuobj, "has_mte", true, NULL);
99
regime_is_secure(env, dc->mmu_idx);
274
+ }
275
+}
276
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
277
index XXXXXXX..XXXXXXX 100644
278
--- a/target/arm/kvm64.c
279
+++ b/target/arm/kvm64.c
280
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_steal_time_supported(void)
281
return kvm_check_extension(kvm_state, KVM_CAP_STEAL_TIME);
282
}
283
284
+bool kvm_arm_mte_supported(void)
285
+{
286
+ return kvm_check_extension(kvm_state, KVM_CAP_ARM_MTE);
287
+}
288
+
289
QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1);
290
291
uint32_t kvm_arm_sve_get_vls(CPUState *cs)
100
--
292
--
101
2.20.1
293
2.34.1
102
103
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
The commit b3aa2f2128 (target/arm: provide stubs for more external
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
debug registers) was added to handle HyperV's unconditional usage of
5
Message-id: 20190412165416.7977-12-philmd@redhat.com
5
Debug Communications Channel. It turns out that Linux will similarly
6
break if you enable CONFIG_HVC_DCC "ARM JTAG DCC console".
7
8
Extend the registers we RAZ/WI set to avoid this.
9
10
Cc: Anders Roxell <anders.roxell@linaro.org>
11
Cc: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
12
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20230516104420.407912-1-alex.bennee@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
16
---
8
include/hw/net/lan9118.h | 2 ++
17
target/arm/debug_helper.c | 11 +++++++++--
9
hw/arm/exynos4_boards.c | 3 ++-
18
1 file changed, 9 insertions(+), 2 deletions(-)
10
hw/arm/mps2-tz.c | 3 ++-
11
hw/net/lan9118.c | 1 -
12
4 files changed, 6 insertions(+), 3 deletions(-)
13
19
14
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
20
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/net/lan9118.h
22
--- a/target/arm/debug_helper.c
17
+++ b/include/hw/net/lan9118.h
23
+++ b/target/arm/debug_helper.c
18
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
19
#include "hw/irq.h"
25
.access = PL0_R, .accessfn = access_tdcc,
20
#include "net/net.h"
26
.type = ARM_CP_CONST, .resetvalue = 0 },
21
27
/*
22
+#define TYPE_LAN9118 "lan9118"
28
- * OSDTRRX_EL1/OSDTRTX_EL1 are used for save and restore of DBGDTRRX_EL0.
23
+
29
- * It is a component of the Debug Communications Channel, which is not implemented.
24
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
30
+ * These registers belong to the Debug Communications Channel,
25
31
+ * which is not implemented. However we implement RAZ/WI behaviour
26
#endif
32
+ * with trapping to prevent spurious SIGILLs if the guest OS does
27
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
33
+ * access them as the support cannot be probed for.
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/exynos4_boards.c
30
+++ b/hw/arm/exynos4_boards.c
31
@@ -XXX,XX +XXX,XX @@
32
#include "hw/arm/arm.h"
33
#include "exec/address-spaces.h"
34
#include "hw/arm/exynos4210.h"
35
+#include "hw/net/lan9118.h"
36
#include "hw/boards.h"
37
38
#undef DEBUG
39
@@ -XXX,XX +XXX,XX @@ static void lan9215_init(uint32_t base, qemu_irq irq)
40
/* This should be a 9215 but the 9118 is close enough */
41
if (nd_table[0].used) {
42
qemu_check_nic_model(&nd_table[0], "lan9118");
43
- dev = qdev_create(NULL, "lan9118");
44
+ dev = qdev_create(NULL, TYPE_LAN9118);
45
qdev_set_nic_properties(dev, &nd_table[0]);
46
qdev_prop_set_uint32(dev, "mode_16bit", 1);
47
qdev_init_nofail(dev);
48
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/arm/mps2-tz.c
51
+++ b/hw/arm/mps2-tz.c
52
@@ -XXX,XX +XXX,XX @@
53
#include "hw/arm/armsse.h"
54
#include "hw/dma/pl080.h"
55
#include "hw/ssi/pl022.h"
56
+#include "hw/net/lan9118.h"
57
#include "net/net.h"
58
#include "hw/core/split-irq.h"
59
60
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
61
* except that it doesn't support the checksum-offload feature.
62
*/
34
*/
63
qemu_check_nic_model(nd, "lan9118");
35
{ .name = "OSDTRRX_EL1", .state = ARM_CP_STATE_BOTH, .cp = 14,
64
- mms->lan9118 = qdev_create(NULL, "lan9118");
36
.opc0 = 2, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 2,
65
+ mms->lan9118 = qdev_create(NULL, TYPE_LAN9118);
37
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
66
qdev_set_nic_properties(mms->lan9118, nd);
38
.opc0 = 2, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2,
67
qdev_init_nofail(mms->lan9118);
39
.access = PL1_RW, .accessfn = access_tdcc,
68
40
.type = ARM_CP_CONST, .resetvalue = 0 },
69
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
41
+ /* DBGDTRTX_EL0/DBGDTRRX_EL0 depend on direction */
70
index XXXXXXX..XXXXXXX 100644
42
+ { .name = "DBGDTR_EL0", .state = ARM_CP_STATE_BOTH, .cp = 14,
71
--- a/hw/net/lan9118.c
43
+ .opc0 = 2, .opc1 = 3, .crn = 0, .crm = 5, .opc2 = 0,
72
+++ b/hw/net/lan9118.c
44
+ .access = PL0_RW, .accessfn = access_tdcc,
73
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118_packet = {
45
+ .type = ARM_CP_CONST, .resetvalue = 0 },
74
}
46
/*
75
};
47
* OSECCR_EL1 provides a mechanism for an operating system
76
48
* to access the contents of EDECCR. EDECCR is not implemented though,
77
-#define TYPE_LAN9118 "lan9118"
78
#define LAN9118(obj) OBJECT_CHECK(lan9118_state, (obj), TYPE_LAN9118)
79
80
typedef struct {
81
--
49
--
82
2.20.1
50
2.34.1
83
51
84
52
diff view generated by jsdifflib
1
Currently the code in v7m_push_stack() which detects a violation
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
2
of the v8M stack limit simply returns early if it does so. This
3
is OK for the current integer-only code, but won't work for the
4
floating point handling we're about to add. We need to continue
5
executing the rest of the function so that we check for other
6
exceptions like not having permission to use the FPU and so
7
that we correctly set the FPCCR state if we are doing lazy
8
stacking. Refactor to avoid the early return.
9
2
3
Bochs card is normal PCI Express card so it fits better in system with
4
PCI Express bus. VGA is simple legacy PCI card.
5
6
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
7
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
8
Message-id: 20230505120936.1097060-1-marcin.juszkiewicz@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20190416125744.27770-10-peter.maydell@linaro.org
13
---
10
---
14
target/arm/helper.c | 23 ++++++++++++++++++-----
11
hw/arm/sbsa-ref.c | 2 +-
15
1 file changed, 18 insertions(+), 5 deletions(-)
12
1 file changed, 1 insertion(+), 1 deletion(-)
16
13
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
16
--- a/hw/arm/sbsa-ref.c
20
+++ b/target/arm/helper.c
17
+++ b/hw/arm/sbsa-ref.c
21
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
18
@@ -XXX,XX +XXX,XX @@ static void create_pcie(SBSAMachineState *sms)
22
* should ignore further stack faults trying to process
23
* that derived exception.)
24
*/
25
- bool stacked_ok;
26
+ bool stacked_ok = true, limitviol = false;
27
CPUARMState *env = &cpu->env;
28
uint32_t xpsr = xpsr_read(env);
29
uint32_t frameptr = env->regs[13];
30
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
31
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
32
env->v7m.secure);
33
env->regs[13] = limit;
34
- return true;
35
+ /*
36
+ * We won't try to perform any further memory accesses but
37
+ * we must continue through the following code to check for
38
+ * permission faults during FPU state preservation, and we
39
+ * must update FPCCR if lazy stacking is enabled.
40
+ */
41
+ limitviol = true;
42
+ stacked_ok = false;
43
}
19
}
44
}
20
}
45
21
46
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
22
- pci_create_simple(pci->bus, -1, "VGA");
47
* (which may be taken in preference to the one we started with
23
+ pci_create_simple(pci->bus, -1, "bochs-display");
48
* if it has higher priority).
24
49
*/
25
create_smmu(sms, pci->bus);
50
- stacked_ok =
51
+ stacked_ok = stacked_ok &&
52
v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, false) &&
53
v7m_stack_write(cpu, frameptr + 4, env->regs[1], mmu_idx, false) &&
54
v7m_stack_write(cpu, frameptr + 8, env->regs[2], mmu_idx, false) &&
55
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
56
v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
57
v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
58
59
- /* Update SP regardless of whether any of the stack accesses failed. */
60
- env->regs[13] = frameptr;
61
+ /*
62
+ * If we broke a stack limit then SP was already updated earlier;
63
+ * otherwise we update SP regardless of whether any of the stack
64
+ * accesses failed or we took some other kind of fault.
65
+ */
66
+ if (!limitviol) {
67
+ env->regs[13] = frameptr;
68
+ }
69
70
return !stacked_ok;
71
}
26
}
72
--
27
--
73
2.20.1
28
2.34.1
74
75
diff view generated by jsdifflib
1
In the v7M architecture, if an exception is generated in the process
1
From: Richard Henderson <richard.henderson@linaro.org>
2
of doing the lazy stacking of FP registers, the handling of
3
possible escalation to HardFault is treated differently to the normal
4
approach: it works based on the saved information about exception
5
readiness that was stored in the FPCCR when the stack frame was
6
created. Provide a new function armv7m_nvic_set_pending_lazyfp()
7
which pends exceptions during lazy stacking, and implements
8
this logic.
9
2
10
This corresponds to the pseudocode TakePreserveFPException().
3
Split out all of the decode stuff from aarch64_tr_translate_insn.
4
Call it disas_a64_legacy to indicate it will be replaced.
11
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 20190416125744.27770-22-peter.maydell@linaro.org
9
Message-id: 20230512144106.3608981-2-peter.maydell@linaro.org
10
[PMM: Rebased]
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
13
---
16
target/arm/cpu.h | 12 ++++++
14
target/arm/tcg/translate-a64.c | 82 ++++++++++++++++++----------------
17
hw/intc/armv7m_nvic.c | 96 +++++++++++++++++++++++++++++++++++++++++++
15
1 file changed, 44 insertions(+), 38 deletions(-)
18
2 files changed, 108 insertions(+)
19
16
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
21
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
19
--- a/target/arm/tcg/translate-a64.c
23
+++ b/target/arm/cpu.h
20
+++ b/target/arm/tcg/translate-a64.c
24
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
21
@@ -XXX,XX +XXX,XX @@ static bool btype_destination_ok(uint32_t insn, bool bt, int btype)
25
* a different exception).
22
return false;
26
*/
27
void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
28
+/**
29
+ * armv7m_nvic_set_pending_lazyfp: mark this lazy FP exception as pending
30
+ * @opaque: the NVIC
31
+ * @irq: the exception number to mark pending
32
+ * @secure: false for non-banked exceptions or for the nonsecure
33
+ * version of a banked exception, true for the secure version of a banked
34
+ * exception.
35
+ *
36
+ * Similar to armv7m_nvic_set_pending(), but specifically for exceptions
37
+ * generated in the course of lazy stacking of FP registers.
38
+ */
39
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure);
40
/**
41
* armv7m_nvic_get_pending_irq_info: return highest priority pending
42
* exception, and whether it targets Secure state
43
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/intc/armv7m_nvic.c
46
+++ b/hw/intc/armv7m_nvic.c
47
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
48
do_armv7m_nvic_set_pending(opaque, irq, secure, true);
49
}
23
}
50
24
51
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
25
+/* C3.1 A64 instruction index by encoding */
26
+static void disas_a64_legacy(DisasContext *s, uint32_t insn)
52
+{
27
+{
53
+ /*
28
+ switch (extract32(insn, 25, 4)) {
54
+ * Pend an exception during lazy FP stacking. This differs
29
+ case 0x0:
55
+ * from the usual exception pending because the logic for
30
+ if (!extract32(insn, 31, 1) || !disas_sme(s, insn)) {
56
+ * whether we should escalate depends on the saved context
31
+ unallocated_encoding(s);
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
+
72
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
73
+ assert(!secure || banked);
74
+
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
76
+
77
+ targets_secure = banked ? secure : exc_targets_secure(s, irq);
78
+
79
+ switch (irq) {
80
+ case ARMV7M_EXCP_DEBUG:
81
+ if (!(fpccr_s & R_V7M_FPCCR_MONRDY_MASK)) {
82
+ /* Ignore DebugMonitor exception */
83
+ return;
84
+ }
32
+ }
85
+ break;
33
+ break;
86
+ case ARMV7M_EXCP_MEM:
34
+ case 0x1: case 0x3: /* UNALLOCATED */
87
+ escalate = !(fpccr & R_V7M_FPCCR_MMRDY_MASK);
35
+ unallocated_encoding(s);
88
+ break;
36
+ break;
89
+ case ARMV7M_EXCP_USAGE:
37
+ case 0x2:
90
+ escalate = !(fpccr & R_V7M_FPCCR_UFRDY_MASK);
38
+ if (!disas_sve(s, insn)) {
39
+ unallocated_encoding(s);
40
+ }
91
+ break;
41
+ break;
92
+ case ARMV7M_EXCP_BUS:
42
+ case 0x8: case 0x9: /* Data processing - immediate */
93
+ escalate = !(fpccr_s & R_V7M_FPCCR_BFRDY_MASK);
43
+ disas_data_proc_imm(s, insn);
94
+ break;
44
+ break;
95
+ case ARMV7M_EXCP_SECURE:
45
+ case 0xa: case 0xb: /* Branch, exception generation and system insns */
96
+ escalate = !(fpccr_s & R_V7M_FPCCR_SFRDY_MASK);
46
+ disas_b_exc_sys(s, insn);
47
+ break;
48
+ case 0x4:
49
+ case 0x6:
50
+ case 0xc:
51
+ case 0xe: /* Loads and stores */
52
+ disas_ldst(s, insn);
53
+ break;
54
+ case 0x5:
55
+ case 0xd: /* Data processing - register */
56
+ disas_data_proc_reg(s, insn);
57
+ break;
58
+ case 0x7:
59
+ case 0xf: /* Data processing - SIMD and floating point */
60
+ disas_data_proc_simd_fp(s, insn);
97
+ break;
61
+ break;
98
+ default:
62
+ default:
99
+ g_assert_not_reached();
63
+ assert(FALSE); /* all 15 cases should be handled above */
100
+ }
64
+ break;
101
+
102
+ if (escalate) {
103
+ /*
104
+ * Escalate to HardFault: faults that initially targeted Secure
105
+ * continue to do so, even if HF normally targets NonSecure.
106
+ */
107
+ irq = ARMV7M_EXCP_HARD;
108
+ if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY) &&
109
+ (targets_secure ||
110
+ !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK))) {
111
+ vec = &s->sec_vectors[irq];
112
+ } else {
113
+ vec = &s->vectors[irq];
114
+ }
115
+ }
116
+
117
+ if (!vec->enabled ||
118
+ nvic_exec_prio(s) <= exc_group_prio(s, vec->prio, secure)) {
119
+ if (!(fpccr_s & R_V7M_FPCCR_HFRDY_MASK)) {
120
+ /*
121
+ * We want to escalate to HardFault but the context the
122
+ * FP state belongs to prevents the exception pre-empting.
123
+ */
124
+ cpu_abort(&s->cpu->parent_obj,
125
+ "Lockup: can't escalate to HardFault during "
126
+ "lazy FP register stacking\n");
127
+ }
128
+ }
129
+
130
+ if (escalate) {
131
+ s->cpu->env.v7m.hfsr |= R_V7M_HFSR_FORCED_MASK;
132
+ }
133
+ if (!vec->pending) {
134
+ vec->pending = 1;
135
+ /*
136
+ * We do not call nvic_irq_update(), because we know our caller
137
+ * is going to handle causing us to take the exception by
138
+ * raising EXCP_LAZYFP, so raising the IRQ line would be
139
+ * pointless extra work. We just need to recompute the
140
+ * priorities so that armv7m_nvic_can_take_pending_exception()
141
+ * returns the right answer.
142
+ */
143
+ nvic_recompute_state(s);
144
+ }
65
+ }
145
+}
66
+}
146
+
67
+
147
/* Make pending IRQ active. */
68
static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
148
void armv7m_nvic_acknowledge_irq(void *opaque)
69
CPUState *cpu)
149
{
70
{
71
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
72
disas_sme_fa64(s, insn);
73
}
74
75
- switch (extract32(insn, 25, 4)) {
76
- case 0x0:
77
- if (!extract32(insn, 31, 1) || !disas_sme(s, insn)) {
78
- unallocated_encoding(s);
79
- }
80
- break;
81
- case 0x1: case 0x3: /* UNALLOCATED */
82
- unallocated_encoding(s);
83
- break;
84
- case 0x2:
85
- if (!disas_sve(s, insn)) {
86
- unallocated_encoding(s);
87
- }
88
- break;
89
- case 0x8: case 0x9: /* Data processing - immediate */
90
- disas_data_proc_imm(s, insn);
91
- break;
92
- case 0xa: case 0xb: /* Branch, exception generation and system insns */
93
- disas_b_exc_sys(s, insn);
94
- break;
95
- case 0x4:
96
- case 0x6:
97
- case 0xc:
98
- case 0xe: /* Loads and stores */
99
- disas_ldst(s, insn);
100
- break;
101
- case 0x5:
102
- case 0xd: /* Data processing - register */
103
- disas_data_proc_reg(s, insn);
104
- break;
105
- case 0x7:
106
- case 0xf: /* Data processing - SIMD and floating point */
107
- disas_data_proc_simd_fp(s, insn);
108
- break;
109
- default:
110
- assert(FALSE); /* all 15 cases should be handled above */
111
- break;
112
- }
113
+ disas_a64_legacy(s, insn);
114
115
/*
116
* After execution of most insns, btype is reset to 0.
150
--
117
--
151
2.20.1
118
2.34.1
152
153
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
The A64 translator uses a hand-written decoder for everything except
2
SVE or SME. It's fairly well structured, but it's becoming obvious
3
that it's still more painful to add instructions to than the A32
4
translator, because putting a new instruction into the right place in
5
a hand-written decoder is much harder than adding new instruction
6
patterns to a decodetree file.
2
7
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
8
As the first step in conversion to decodetree, create the skeleton of
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
the decodetree decoder; where it does not handle instructions we will
5
Message-id: 20190412165416.7977-10-philmd@redhat.com
10
fall back to the legacy decoder (which will be for everything at the
11
moment, since there are no patterns in a64.decode).
12
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20230512144106.3608981-3-peter.maydell@linaro.org
7
---
16
---
8
include/hw/devices.h | 3 ---
17
target/arm/tcg/a64.decode | 20 ++++++++++++++++++++
9
include/hw/net/lan9118.h | 19 +++++++++++++++++++
18
target/arm/tcg/translate-a64.c | 18 +++++++++++-------
10
hw/arm/kzm.c | 2 +-
19
target/arm/tcg/meson.build | 1 +
11
hw/arm/mps2.c | 2 +-
20
3 files changed, 32 insertions(+), 7 deletions(-)
12
hw/arm/realview.c | 1 +
21
create mode 100644 target/arm/tcg/a64.decode
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
22
18
diff --git a/include/hw/devices.h b/include/hw/devices.h
23
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/devices.h
21
+++ b/include/hw/devices.h
22
@@ -XXX,XX +XXX,XX @@
23
/* smc91c111.c */
24
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
25
26
-/* lan9118.c */
27
-void lan9118_init(NICInfo *, uint32_t, qemu_irq);
28
-
29
#endif
30
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
31
new file mode 100644
24
new file mode 100644
32
index XXXXXXX..XXXXXXX
25
index XXXXXXX..XXXXXXX
33
--- /dev/null
26
--- /dev/null
34
+++ b/include/hw/net/lan9118.h
27
+++ b/target/arm/tcg/a64.decode
35
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@
29
+# AArch64 A64 allowed instruction decoding
30
+#
31
+# Copyright (c) 2023 Linaro, Ltd
32
+#
33
+# This library is free software; you can redistribute it and/or
34
+# modify it under the terms of the GNU Lesser General Public
35
+# License as published by the Free Software Foundation; either
36
+# version 2.1 of the License, or (at your option) any later version.
37
+#
38
+# This library is distributed in the hope that it will be useful,
39
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
40
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41
+# Lesser General Public License for more details.
42
+#
43
+# You should have received a copy of the GNU Lesser General Public
44
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
45
+
46
+#
47
+# This file is processed by scripts/decodetree.py
48
+#
49
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/tcg/translate-a64.c
52
+++ b/target/arm/tcg/translate-a64.c
53
@@ -XXX,XX +XXX,XX @@ enum a64_shift_type {
54
A64_SHIFT_TYPE_ROR = 3
55
};
56
36
+/*
57
+/*
37
+ * SMSC LAN9118 Ethernet interface emulation
58
+ * Include the generated decoders.
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
+ */
59
+ */
45
+
60
+
46
+#ifndef HW_NET_LAN9118_H
61
+#include "decode-sme-fa64.c.inc"
47
+#define HW_NET_LAN9118_H
62
+#include "decode-a64.c.inc"
48
+
63
+
49
+#include "hw/irq.h"
64
/* Table based decoder typedefs - used when the relevant bits for decode
50
+#include "net/net.h"
65
* are too awkwardly scattered across the instruction (eg SIMD).
66
*/
67
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn)
68
}
69
}
70
71
-/*
72
- * Include the generated SME FA64 decoder.
73
- */
74
-
75
-#include "decode-sme-fa64.c.inc"
76
-
77
static bool trans_OK(DisasContext *s, arg_OK *a)
78
{
79
return true;
80
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
81
disas_sme_fa64(s, insn);
82
}
83
84
- disas_a64_legacy(s, insn);
51
+
85
+
52
+void lan9118_init(NICInfo *, uint32_t, qemu_irq);
86
+ if (!disas_a64(s, insn)) {
53
+
87
+ disas_a64_legacy(s, insn);
54
+#endif
88
+ }
55
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
89
90
/*
91
* After execution of most insns, btype is reset to 0.
92
diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build
56
index XXXXXXX..XXXXXXX 100644
93
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/kzm.c
94
--- a/target/arm/tcg/meson.build
58
+++ b/hw/arm/kzm.c
95
+++ b/target/arm/tcg/meson.build
59
@@ -XXX,XX +XXX,XX @@
96
@@ -XXX,XX +XXX,XX @@ gen = [
60
#include "qemu/error-report.h"
97
decodetree.process('a32-uncond.decode', extra_args: '--static-decode=disas_a32_uncond'),
61
#include "exec/address-spaces.h"
98
decodetree.process('t32.decode', extra_args: '--static-decode=disas_t32'),
62
#include "net/net.h"
99
decodetree.process('t16.decode', extra_args: ['-w', '16', '--static-decode=disas_t16']),
63
-#include "hw/devices.h"
100
+ decodetree.process('a64.decode', extra_args: ['--static-decode=disas_a64']),
64
+#include "hw/net/lan9118.h"
101
]
65
#include "hw/char/serial.h"
102
66
#include "sysemu/qtest.h"
103
arm_ss.add(gen)
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
--
104
--
120
2.20.1
105
2.34.1
121
122
diff view generated by jsdifflib
1
The M-profile FPCCR.ASPEN bit indicates that automatic floating-point
1
The SVE and SME decode is already done by decodetree. Pull the calls
2
context preservation is enabled. Before executing any floating-point
2
to these decoders out of the legacy decoder. This doesn't change
3
instruction, if FPCCR.ASPEN is set and the CONTROL FPCA/SFPA bits
3
behaviour because all the patterns in sve.decode and sme.decode
4
indicate that there is no active floating point context then we
4
already require the bits that the legacy decoder is decoding to have
5
must create a new context (by initializing FPSCR and setting
5
the correct values.
6
FPCA/SFPA to indicate that the context is now active). In the
7
pseudocode this is handled by ExecuteFPCheck().
8
9
Implement this with a new TB flag which tracks whether we
10
need to create a new FP context.
11
6
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190416125744.27770-20-peter.maydell@linaro.org
9
Message-id: 20230512144106.3608981-4-peter.maydell@linaro.org
15
---
10
---
16
target/arm/cpu.h | 2 ++
11
target/arm/tcg/translate-a64.c | 20 ++++----------------
17
target/arm/translate.h | 1 +
12
1 file changed, 4 insertions(+), 16 deletions(-)
18
target/arm/helper.c | 13 +++++++++++++
19
target/arm/translate.c | 29 +++++++++++++++++++++++++++++
20
4 files changed, 45 insertions(+)
21
13
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
23
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
16
--- a/target/arm/tcg/translate-a64.c
25
+++ b/target/arm/cpu.h
17
+++ b/target/arm/tcg/translate-a64.c
26
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
18
@@ -XXX,XX +XXX,XX @@ static bool btype_destination_ok(uint32_t insn, bool bt, int btype)
27
FIELD(TBFLAG_A32, VFPEN, 7, 1)
19
static void disas_a64_legacy(DisasContext *s, uint32_t insn)
28
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
20
{
29
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
21
switch (extract32(insn, 25, 4)) {
30
+/* For M profile only, set if we must create a new FP context */
22
- case 0x0:
31
+FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
23
- if (!extract32(insn, 31, 1) || !disas_sme(s, insn)) {
32
/* For M profile only, set if FPCCR.S does not match current security state */
24
- unallocated_encoding(s);
33
FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
25
- }
34
/* For M profile only, Handler (ie not Thread) mode */
26
- break;
35
diff --git a/target/arm/translate.h b/target/arm/translate.h
27
- case 0x1: case 0x3: /* UNALLOCATED */
36
index XXXXXXX..XXXXXXX 100644
28
- unallocated_encoding(s);
37
--- a/target/arm/translate.h
29
- break;
38
+++ b/target/arm/translate.h
30
- case 0x2:
39
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
31
- if (!disas_sve(s, insn)) {
40
bool v8m_secure; /* true if v8M and we're in Secure mode */
32
- unallocated_encoding(s);
41
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
33
- }
42
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
34
- break;
43
+ bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
35
case 0x8: case 0x9: /* Data processing - immediate */
44
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
36
disas_data_proc_imm(s, insn);
45
* so that top level loop can generate correct syndrome information.
37
break;
46
*/
38
@@ -XXX,XX +XXX,XX @@ static void disas_a64_legacy(DisasContext *s, uint32_t insn)
47
diff --git a/target/arm/helper.c b/target/arm/helper.c
39
disas_data_proc_simd_fp(s, insn);
48
index XXXXXXX..XXXXXXX 100644
40
break;
49
--- a/target/arm/helper.c
41
default:
50
+++ b/target/arm/helper.c
42
- assert(FALSE); /* all 15 cases should be handled above */
51
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
43
+ unallocated_encoding(s);
52
flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
44
break;
53
}
45
}
54
55
+ if (arm_feature(env, ARM_FEATURE_M) &&
56
+ (env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) &&
57
+ (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) ||
58
+ (env->v7m.secure &&
59
+ !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)))) {
60
+ /*
61
+ * ASPEN is set, but FPCA/SFPA indicate that there is no active
62
+ * FP context; we must create a new FP context before executing
63
+ * any FP insn.
64
+ */
65
+ flags = FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED, 1);
66
+ }
67
+
68
*pflags = flags;
69
*cs_base = 0;
70
}
46
}
71
diff --git a/target/arm/translate.c b/target/arm/translate.c
47
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
72
index XXXXXXX..XXXXXXX 100644
48
disas_sme_fa64(s, insn);
73
--- a/target/arm/translate.c
74
+++ b/target/arm/translate.c
75
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
76
/* Don't need to do this for any further FP insns in this TB */
77
s->v8m_fpccr_s_wrong = false;
78
}
79
+
80
+ if (s->v7m_new_fp_ctxt_needed) {
81
+ /*
82
+ * Create new FP context by updating CONTROL.FPCA, CONTROL.SFPA
83
+ * and the FPSCR.
84
+ */
85
+ TCGv_i32 control, fpscr;
86
+ uint32_t bits = R_V7M_CONTROL_FPCA_MASK;
87
+
88
+ fpscr = load_cpu_field(v7m.fpdscr[s->v8m_secure]);
89
+ gen_helper_vfp_set_fpscr(cpu_env, fpscr);
90
+ tcg_temp_free_i32(fpscr);
91
+ /*
92
+ * We don't need to arrange to end the TB, because the only
93
+ * parts of FPSCR which we cache in the TB flags are the VECLEN
94
+ * and VECSTRIDE, and those don't exist for M-profile.
95
+ */
96
+
97
+ if (s->v8m_secure) {
98
+ bits |= R_V7M_CONTROL_SFPA_MASK;
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
}
49
}
107
50
108
if (extract32(insn, 28, 4) == 0xf) {
51
-
109
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
52
- if (!disas_a64(s, insn)) {
110
regime_is_secure(env, dc->mmu_idx);
53
+ if (!disas_a64(s, insn) &&
111
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
54
+ !disas_sme(s, insn) &&
112
dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
55
+ !disas_sve(s, insn)) {
113
+ dc->v7m_new_fp_ctxt_needed =
56
disas_a64_legacy(s, insn);
114
+ FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
57
}
115
dc->cp_regs = cpu->cp_regs;
116
dc->features = env->features;
117
58
118
--
59
--
119
2.20.1
60
2.34.1
120
121
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
Convert the ADR and ADRP instructions.
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20190412165416.7977-11-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20230512144106.3608981-5-peter.maydell@linaro.org
9
[PMM: Rebased]
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
12
---
9
include/hw/net/ne2000-isa.h | 6 ++++++
13
target/arm/tcg/a64.decode | 13 ++++++++++++
10
1 file changed, 6 insertions(+)
14
target/arm/tcg/translate-a64.c | 38 +++++++++++++---------------------
15
2 files changed, 27 insertions(+), 24 deletions(-)
11
16
12
diff --git a/include/hw/net/ne2000-isa.h b/include/hw/net/ne2000-isa.h
17
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/net/ne2000-isa.h
19
--- a/target/arm/tcg/a64.decode
15
+++ b/include/hw/net/ne2000-isa.h
20
+++ b/target/arm/tcg/a64.decode
16
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
17
* This work is licensed under the terms of the GNU GPL, version 2 or later.
22
#
18
* See the COPYING file in the top-level directory.
23
# This file is processed by scripts/decodetree.py
24
#
25
+
26
+&ri rd imm
27
+
28
+
29
+### Data Processing - Immediate
30
+
31
+# PC-rel addressing
32
+
33
+%imm_pcrel 5:s19 29:2
34
+@pcrel . .. ..... ................... rd:5 &ri imm=%imm_pcrel
35
+
36
+ADR 0 .. 10000 ................... ..... @pcrel
37
+ADRP 1 .. 10000 ................... ..... @pcrel
38
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/tcg/translate-a64.c
41
+++ b/target/arm/tcg/translate-a64.c
42
@@ -XXX,XX +XXX,XX @@ static void disas_ldst(DisasContext *s, uint32_t insn)
43
}
44
}
45
46
-/* PC-rel. addressing
47
- * 31 30 29 28 24 23 5 4 0
48
- * +----+-------+-----------+-------------------+------+
49
- * | op | immlo | 1 0 0 0 0 | immhi | Rd |
50
- * +----+-------+-----------+-------------------+------+
51
+/*
52
+ * PC-rel. addressing
19
*/
53
*/
54
-static void disas_pc_rel_adr(DisasContext *s, uint32_t insn)
20
+
55
+
21
+#ifndef HW_NET_NE2K_ISA_H
56
+static bool trans_ADR(DisasContext *s, arg_ri *a)
22
+#define HW_NET_NE2K_ISA_H
57
{
23
+
58
- unsigned int page, rd;
24
#include "hw/hw.h"
59
- int64_t offset;
25
#include "hw/qdev.h"
60
+ gen_pc_plus_diff(s, cpu_reg(s, a->rd), a->imm);
26
#include "hw/isa/isa.h"
61
+ return true;
27
@@ -XXX,XX +XXX,XX @@ static inline ISADevice *isa_ne2000_init(ISABus *bus, int base, int irq,
62
+}
28
}
63
29
return d;
64
- page = extract32(insn, 31, 1);
65
- /* SignExtend(immhi:immlo) -> offset */
66
- offset = sextract64(insn, 5, 19);
67
- offset = offset << 2 | extract32(insn, 29, 2);
68
- rd = extract32(insn, 0, 5);
69
+static bool trans_ADRP(DisasContext *s, arg_ri *a)
70
+{
71
+ int64_t offset = (int64_t)a->imm << 12;
72
73
- if (page) {
74
- /* ADRP (page based) */
75
- offset <<= 12;
76
- /* The page offset is ok for CF_PCREL. */
77
- offset -= s->pc_curr & 0xfff;
78
- }
79
-
80
- gen_pc_plus_diff(s, cpu_reg(s, rd), offset);
81
+ /* The page offset is ok for CF_PCREL. */
82
+ offset -= s->pc_curr & 0xfff;
83
+ gen_pc_plus_diff(s, cpu_reg(s, a->rd), offset);
84
+ return true;
30
}
85
}
31
+
86
32
+#endif
87
/*
88
@@ -XXX,XX +XXX,XX @@ static void disas_extract(DisasContext *s, uint32_t insn)
89
static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
90
{
91
switch (extract32(insn, 23, 6)) {
92
- case 0x20: case 0x21: /* PC-rel. addressing */
93
- disas_pc_rel_adr(s, insn);
94
- break;
95
case 0x22: /* Add/subtract (immediate) */
96
disas_add_sub_imm(s, insn);
97
break;
33
--
98
--
34
2.20.1
99
2.34.1
35
36
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The SMMUNotifierNode struct is not necessary and brings extra
3
Split out specific 32-bit and 64-bit functions.
4
complexity so let's remove it. We now directly track the SMMUDevices
4
These carry the same signature as tcg_gen_add_i64,
5
which have registered IOMMU MR notifiers.
5
and so will be easier to pass as callbacks.
6
6
7
This is inspired from the same transformation on intel-iommu
7
Retain gen_add_CC and gen_sub_CC during conversion.
8
done in commit b4a4ba0d68f50f218ee3957b6638dbee32a5eeef
9
("intel-iommu: remove IntelIOMMUNotifierNode")
10
8
11
Signed-off-by: Eric Auger <eric.auger@redhat.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Peter Xu <peterx@redhat.com>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20190409160219.19026-1-eric.auger@redhat.com
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20230512144106.3608981-6-peter.maydell@linaro.org
13
[PMM: rebased]
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
---
16
include/hw/arm/smmu-common.h | 8 ++------
17
target/arm/tcg/translate-a64.c | 149 +++++++++++++++++++--------------
17
hw/arm/smmu-common.c | 6 +++---
18
1 file changed, 84 insertions(+), 65 deletions(-)
18
hw/arm/smmuv3.c | 28 +++++++---------------------
19
3 files changed, 12 insertions(+), 30 deletions(-)
20
19
21
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
20
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
22
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/smmu-common.h
22
--- a/target/arm/tcg/translate-a64.c
24
+++ b/include/hw/arm/smmu-common.h
23
+++ b/target/arm/tcg/translate-a64.c
25
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUDevice {
24
@@ -XXX,XX +XXX,XX @@ static inline void gen_logic_CC(int sf, TCGv_i64 result)
26
AddressSpace as;
25
}
27
uint32_t cfg_cache_hits;
26
28
uint32_t cfg_cache_misses;
27
/* dest = T0 + T1; compute C, N, V and Z flags */
29
+ QLIST_ENTRY(SMMUDevice) next;
28
+static void gen_add64_CC(TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
30
} SMMUDevice;
29
+{
31
30
+ TCGv_i64 result, flag, tmp;
32
-typedef struct SMMUNotifierNode {
31
+ result = tcg_temp_new_i64();
33
- SMMUDevice *sdev;
32
+ flag = tcg_temp_new_i64();
34
- QLIST_ENTRY(SMMUNotifierNode) next;
33
+ tmp = tcg_temp_new_i64();
35
-} SMMUNotifierNode;
34
+
35
+ tcg_gen_movi_i64(tmp, 0);
36
+ tcg_gen_add2_i64(result, flag, t0, tmp, t1, tmp);
37
+
38
+ tcg_gen_extrl_i64_i32(cpu_CF, flag);
39
+
40
+ gen_set_NZ64(result);
41
+
42
+ tcg_gen_xor_i64(flag, result, t0);
43
+ tcg_gen_xor_i64(tmp, t0, t1);
44
+ tcg_gen_andc_i64(flag, flag, tmp);
45
+ tcg_gen_extrh_i64_i32(cpu_VF, flag);
46
+
47
+ tcg_gen_mov_i64(dest, result);
48
+}
49
+
50
+static void gen_add32_CC(TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
51
+{
52
+ TCGv_i32 t0_32 = tcg_temp_new_i32();
53
+ TCGv_i32 t1_32 = tcg_temp_new_i32();
54
+ TCGv_i32 tmp = tcg_temp_new_i32();
55
+
56
+ tcg_gen_movi_i32(tmp, 0);
57
+ tcg_gen_extrl_i64_i32(t0_32, t0);
58
+ tcg_gen_extrl_i64_i32(t1_32, t1);
59
+ tcg_gen_add2_i32(cpu_NF, cpu_CF, t0_32, tmp, t1_32, tmp);
60
+ tcg_gen_mov_i32(cpu_ZF, cpu_NF);
61
+ tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
62
+ tcg_gen_xor_i32(tmp, t0_32, t1_32);
63
+ tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
64
+ tcg_gen_extu_i32_i64(dest, cpu_NF);
65
+}
66
+
67
static void gen_add_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
68
{
69
if (sf) {
70
- TCGv_i64 result, flag, tmp;
71
- result = tcg_temp_new_i64();
72
- flag = tcg_temp_new_i64();
73
- tmp = tcg_temp_new_i64();
36
-
74
-
37
typedef struct SMMUPciBus {
75
- tcg_gen_movi_i64(tmp, 0);
38
PCIBus *bus;
76
- tcg_gen_add2_i64(result, flag, t0, tmp, t1, tmp);
39
SMMUDevice *pbdev[0]; /* Parent array is sparse, so dynamically alloc */
77
-
40
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUState {
78
- tcg_gen_extrl_i64_i32(cpu_CF, flag);
41
GHashTable *iotlb;
79
-
42
SMMUPciBus *smmu_pcibus_by_bus_num[SMMU_PCI_BUS_MAX];
80
- gen_set_NZ64(result);
43
PCIBus *pci_bus;
81
-
44
- QLIST_HEAD(, SMMUNotifierNode) notifiers_list;
82
- tcg_gen_xor_i64(flag, result, t0);
45
+ QLIST_HEAD(, SMMUDevice) devices_with_notifiers;
83
- tcg_gen_xor_i64(tmp, t0, t1);
46
uint8_t bus_num;
84
- tcg_gen_andc_i64(flag, flag, tmp);
47
PCIBus *primary_bus;
85
- tcg_gen_extrh_i64_i32(cpu_VF, flag);
48
} SMMUState;
86
-
49
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
87
- tcg_gen_mov_i64(dest, result);
50
index XXXXXXX..XXXXXXX 100644
88
+ gen_add64_CC(dest, t0, t1);
51
--- a/hw/arm/smmu-common.c
89
} else {
52
+++ b/hw/arm/smmu-common.c
90
- /* 32 bit arithmetic */
53
@@ -XXX,XX +XXX,XX @@ inline void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
91
- TCGv_i32 t0_32 = tcg_temp_new_i32();
54
/* Unmap all notifiers of all mr's */
92
- TCGv_i32 t1_32 = tcg_temp_new_i32();
55
void smmu_inv_notifiers_all(SMMUState *s)
93
- TCGv_i32 tmp = tcg_temp_new_i32();
56
{
94
-
57
- SMMUNotifierNode *node;
95
- tcg_gen_movi_i32(tmp, 0);
58
+ SMMUDevice *sdev;
96
- tcg_gen_extrl_i64_i32(t0_32, t0);
59
97
- tcg_gen_extrl_i64_i32(t1_32, t1);
60
- QLIST_FOREACH(node, &s->notifiers_list, next) {
98
- tcg_gen_add2_i32(cpu_NF, cpu_CF, t0_32, tmp, t1_32, tmp);
61
- smmu_inv_notifiers_mr(&node->sdev->iommu);
99
- tcg_gen_mov_i32(cpu_ZF, cpu_NF);
62
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
100
- tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
63
+ smmu_inv_notifiers_mr(&sdev->iommu);
101
- tcg_gen_xor_i32(tmp, t0_32, t1_32);
102
- tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
103
- tcg_gen_extu_i32_i64(dest, cpu_NF);
104
+ gen_add32_CC(dest, t0, t1);
64
}
105
}
65
}
106
}
66
107
67
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
108
/* dest = T0 - T1; compute C, N, V and Z flags */
68
index XXXXXXX..XXXXXXX 100644
109
+static void gen_sub64_CC(TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
69
--- a/hw/arm/smmuv3.c
110
+{
70
+++ b/hw/arm/smmuv3.c
111
+ /* 64 bit arithmetic */
71
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
112
+ TCGv_i64 result, flag, tmp;
72
/* invalidate an asid/iova tuple in all mr's */
113
+
73
static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova)
114
+ result = tcg_temp_new_i64();
115
+ flag = tcg_temp_new_i64();
116
+ tcg_gen_sub_i64(result, t0, t1);
117
+
118
+ gen_set_NZ64(result);
119
+
120
+ tcg_gen_setcond_i64(TCG_COND_GEU, flag, t0, t1);
121
+ tcg_gen_extrl_i64_i32(cpu_CF, flag);
122
+
123
+ tcg_gen_xor_i64(flag, result, t0);
124
+ tmp = tcg_temp_new_i64();
125
+ tcg_gen_xor_i64(tmp, t0, t1);
126
+ tcg_gen_and_i64(flag, flag, tmp);
127
+ tcg_gen_extrh_i64_i32(cpu_VF, flag);
128
+ tcg_gen_mov_i64(dest, result);
129
+}
130
+
131
+static void gen_sub32_CC(TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
132
+{
133
+ /* 32 bit arithmetic */
134
+ TCGv_i32 t0_32 = tcg_temp_new_i32();
135
+ TCGv_i32 t1_32 = tcg_temp_new_i32();
136
+ TCGv_i32 tmp;
137
+
138
+ tcg_gen_extrl_i64_i32(t0_32, t0);
139
+ tcg_gen_extrl_i64_i32(t1_32, t1);
140
+ tcg_gen_sub_i32(cpu_NF, t0_32, t1_32);
141
+ tcg_gen_mov_i32(cpu_ZF, cpu_NF);
142
+ tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0_32, t1_32);
143
+ tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
144
+ tmp = tcg_temp_new_i32();
145
+ tcg_gen_xor_i32(tmp, t0_32, t1_32);
146
+ tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
147
+ tcg_gen_extu_i32_i64(dest, cpu_NF);
148
+}
149
+
150
static void gen_sub_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
74
{
151
{
75
- SMMUNotifierNode *node;
152
if (sf) {
76
+ SMMUDevice *sdev;
153
- /* 64 bit arithmetic */
77
154
- TCGv_i64 result, flag, tmp;
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
-
155
-
104
- /* update notifier node with new flags */
156
- result = tcg_temp_new_i64();
105
- QLIST_FOREACH_SAFE(node, &s->notifiers_list, next, next_node) {
157
- flag = tcg_temp_new_i64();
106
- if (node->sdev == sdev) {
158
- tcg_gen_sub_i64(result, t0, t1);
107
- if (new == IOMMU_NOTIFIER_NONE) {
159
-
108
- trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
160
- gen_set_NZ64(result);
109
- QLIST_REMOVE(node, next);
161
-
110
- g_free(node);
162
- tcg_gen_setcond_i64(TCG_COND_GEU, flag, t0, t1);
111
- }
163
- tcg_gen_extrl_i64_i32(cpu_CF, flag);
112
- return;
164
-
113
- }
165
- tcg_gen_xor_i64(flag, result, t0);
114
+ QLIST_INSERT_HEAD(&s->devices_with_notifiers, sdev, next);
166
- tmp = tcg_temp_new_i64();
115
+ } else if (new == IOMMU_NOTIFIER_NONE) {
167
- tcg_gen_xor_i64(tmp, t0, t1);
116
+ trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
168
- tcg_gen_and_i64(flag, flag, tmp);
117
+ QLIST_REMOVE(sdev, next);
169
- tcg_gen_extrh_i64_i32(cpu_VF, flag);
170
- tcg_gen_mov_i64(dest, result);
171
+ gen_sub64_CC(dest, t0, t1);
172
} else {
173
- /* 32 bit arithmetic */
174
- TCGv_i32 t0_32 = tcg_temp_new_i32();
175
- TCGv_i32 t1_32 = tcg_temp_new_i32();
176
- TCGv_i32 tmp;
177
-
178
- tcg_gen_extrl_i64_i32(t0_32, t0);
179
- tcg_gen_extrl_i64_i32(t1_32, t1);
180
- tcg_gen_sub_i32(cpu_NF, t0_32, t1_32);
181
- tcg_gen_mov_i32(cpu_ZF, cpu_NF);
182
- tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0_32, t1_32);
183
- tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
184
- tmp = tcg_temp_new_i32();
185
- tcg_gen_xor_i32(tmp, t0_32, t1_32);
186
- tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
187
- tcg_gen_extu_i32_i64(dest, cpu_NF);
188
+ gen_sub32_CC(dest, t0, t1);
118
}
189
}
119
}
190
}
120
191
121
--
192
--
122
2.20.1
193
2.34.1
123
124
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
Deleted patch
1
For M-profile the MVFR* ID registers are memory mapped, in the
2
range we implement via the NVIC. Allow them to be read.
3
(If the CPU has no FPU, these registers are defined to be RAZ.)
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190416125744.27770-3-peter.maydell@linaro.org
8
---
9
hw/intc/armv7m_nvic.c | 6 ++++++
10
1 file changed, 6 insertions(+)
11
12
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/intc/armv7m_nvic.c
15
+++ b/hw/intc/armv7m_nvic.c
16
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
17
return 0;
18
}
19
return cpu->env.v7m.sfar;
20
+ case 0xf40: /* MVFR0 */
21
+ return cpu->isar.mvfr0;
22
+ case 0xf44: /* MVFR1 */
23
+ return cpu->isar.mvfr1;
24
+ case 0xf48: /* MVFR2 */
25
+ return cpu->isar.mvfr2;
26
default:
27
bad_offset:
28
qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
29
--
30
2.20.1
31
32
diff view generated by jsdifflib
Deleted patch
1
The M-profile floating point support has three associated config
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
1
7
The main complexity here is handling the FPCCR register, which
8
has a mix of banked and unbanked bits.
9
10
Note that we don't share storage with the A-profile
11
cpu->cp15.nsacr and cpu->cp15.cpacr_el1, though the behaviour
12
is quite similar, for two reasons:
13
* the M profile CPACR is banked between security states
14
* it preserves the invariant that M profile uses no state
15
inside the cp15 substruct
16
17
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
---
21
target/arm/cpu.h | 34 ++++++++++++
22
hw/intc/armv7m_nvic.c | 125 ++++++++++++++++++++++++++++++++++++++++++
23
target/arm/cpu.c | 5 ++
24
target/arm/machine.c | 16 ++++++
25
4 files changed, 180 insertions(+)
26
27
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/cpu.h
30
+++ b/target/arm/cpu.h
31
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
32
uint32_t scr[M_REG_NUM_BANKS];
33
uint32_t msplim[M_REG_NUM_BANKS];
34
uint32_t psplim[M_REG_NUM_BANKS];
35
+ uint32_t fpcar[M_REG_NUM_BANKS];
36
+ uint32_t fpccr[M_REG_NUM_BANKS];
37
+ uint32_t fpdscr[M_REG_NUM_BANKS];
38
+ uint32_t cpacr[M_REG_NUM_BANKS];
39
+ uint32_t nsacr;
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
237
index XXXXXXX..XXXXXXX 100644
238
--- a/target/arm/cpu.c
239
+++ b/target/arm/cpu.c
240
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
241
env->v7m.ccr[M_REG_S] |= R_V7M_CCR_UNALIGN_TRP_MASK;
242
}
243
244
+ if (arm_feature(env, ARM_FEATURE_VFP)) {
245
+ env->v7m.fpccr[M_REG_NS] = R_V7M_FPCCR_ASPEN_MASK;
246
+ env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK |
247
+ R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK;
248
+ }
249
/* Unlike A/R profile, M profile defines the reset LR value */
250
env->regs[14] = 0xffffffff;
251
252
diff --git a/target/arm/machine.c b/target/arm/machine.c
253
index XXXXXXX..XXXXXXX 100644
254
--- a/target/arm/machine.c
255
+++ b/target/arm/machine.c
256
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_v8m = {
257
}
258
};
259
260
+static const VMStateDescription vmstate_m_fp = {
261
+ .name = "cpu/m/fp",
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
--
287
2.20.1
288
289
diff view generated by jsdifflib
Deleted patch
1
The only "system register" that M-profile floating point exposes
2
via the VMRS/VMRS instructions is FPSCR, and it does not have
3
the odd special case for rd==15. Add a check to ensure we only
4
expose FPSCR.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-5-peter.maydell@linaro.org
9
---
10
target/arm/translate.c | 19 +++++++++++++++++--
11
1 file changed, 17 insertions(+), 2 deletions(-)
12
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
16
+++ b/target/arm/translate.c
17
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
18
}
19
}
20
} else { /* !dp */
21
+ bool is_sysreg;
22
+
23
if ((insn & 0x6f) != 0x00)
24
return 1;
25
rn = VFP_SREG_N(insn);
26
+
27
+ is_sysreg = extract32(insn, 21, 1);
28
+
29
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
30
+ /*
31
+ * The only M-profile VFP vmrs/vmsr sysreg is FPSCR.
32
+ * Writes to R15 are UNPREDICTABLE; we choose to undef.
33
+ */
34
+ if (is_sysreg && (rd == 15 || (rn >> 1) != ARM_VFP_FPSCR)) {
35
+ return 1;
36
+ }
37
+ }
38
+
39
if (insn & ARM_CP_RW_BIT) {
40
/* vfp->arm */
41
- if (insn & (1 << 21)) {
42
+ if (is_sysreg) {
43
/* system register */
44
rn >>= 1;
45
46
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
47
}
48
} else {
49
/* arm->vfp */
50
- if (insn & (1 << 21)) {
51
+ if (is_sysreg) {
52
rn >>= 1;
53
/* system register */
54
switch (rn) {
55
--
56
2.20.1
57
58
diff view generated by jsdifflib
1
Implement the code which updates the FPCCR register on an
1
From: Richard Henderson <richard.henderson@linaro.org>
2
exception entry where we are going to use lazy FP stacking.
3
We have to defer to the NVIC to determine whether the
4
various exceptions are currently ready or not.
5
2
3
Convert the ADD and SUB (immediate) instructions.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20190416125744.27770-12-peter.maydell@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20230512144106.3608981-7-peter.maydell@linaro.org
9
[PMM: Rebased; adjusted to use translate.h's TRANS macro]
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
12
---
9
target/arm/cpu.h | 14 +++++++++
13
target/arm/tcg/translate.h | 5 +++
10
hw/intc/armv7m_nvic.c | 34 ++++++++++++++++++++++
14
target/arm/tcg/a64.decode | 17 ++++++++
11
target/arm/helper.c | 67 ++++++++++++++++++++++++++++++++++++++++++-
15
target/arm/tcg/translate-a64.c | 73 ++++++++++------------------------
12
3 files changed, 114 insertions(+), 1 deletion(-)
16
3 files changed, 42 insertions(+), 53 deletions(-)
13
17
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
20
--- a/target/arm/tcg/translate.h
17
+++ b/target/arm/cpu.h
21
+++ b/target/arm/tcg/translate.h
18
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_acknowledge_irq(void *opaque);
22
@@ -XXX,XX +XXX,XX @@ static inline int rsub_8(DisasContext *s, int x)
19
* (Ignoring -1, this is the same as the RETTOBASE value before completion.)
23
return 8 - x;
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 int shl_12(DisasContext *s, int x)
48
+{
27
+{
49
+ /*
28
+ return x << 12;
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
static inline int neon_3same_fp_size(DisasContext *s, int x)
82
static void set_irq_level(void *opaque, int n, int level)
83
{
32
{
84
diff --git a/target/arm/helper.c b/target/arm/helper.c
33
/* Convert 0==fp32, 1==fp16 into a MO_* value */
34
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
85
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/helper.c
36
--- a/target/arm/tcg/a64.decode
87
+++ b/target/arm/helper.c
37
+++ b/target/arm/tcg/a64.decode
88
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
38
@@ -XXX,XX +XXX,XX @@
89
env->thumb = addr & 1;
39
#
40
41
&ri rd imm
42
+&rri_sf rd rn imm sf
43
44
45
### Data Processing - Immediate
46
@@ -XXX,XX +XXX,XX @@
47
48
ADR 0 .. 10000 ................... ..... @pcrel
49
ADRP 1 .. 10000 ................... ..... @pcrel
50
+
51
+# Add/subtract (immediate)
52
+
53
+%imm12_sh12 10:12 !function=shl_12
54
+@addsub_imm sf:1 .. ...... . imm:12 rn:5 rd:5
55
+@addsub_imm12 sf:1 .. ...... . ............ rn:5 rd:5 imm=%imm12_sh12
56
+
57
+ADD_i . 00 100010 0 ............ ..... ..... @addsub_imm
58
+ADD_i . 00 100010 1 ............ ..... ..... @addsub_imm12
59
+ADDS_i . 01 100010 0 ............ ..... ..... @addsub_imm
60
+ADDS_i . 01 100010 1 ............ ..... ..... @addsub_imm12
61
+
62
+SUB_i . 10 100010 0 ............ ..... ..... @addsub_imm
63
+SUB_i . 10 100010 1 ............ ..... ..... @addsub_imm12
64
+SUBS_i . 11 100010 0 ............ ..... ..... @addsub_imm
65
+SUBS_i . 11 100010 1 ............ ..... ..... @addsub_imm12
66
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/tcg/translate-a64.c
69
+++ b/target/arm/tcg/translate-a64.c
70
@@ -XXX,XX +XXX,XX @@ static void disas_ldst(DisasContext *s, uint32_t insn)
71
}
90
}
72
}
91
73
92
+static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
74
+typedef void ArithTwoOp(TCGv_i64, TCGv_i64, TCGv_i64);
93
+ bool apply_splim)
75
+
76
+static bool gen_rri(DisasContext *s, arg_rri_sf *a,
77
+ bool rd_sp, bool rn_sp, ArithTwoOp *fn)
94
+{
78
+{
95
+ /*
79
+ TCGv_i64 tcg_rn = rn_sp ? cpu_reg_sp(s, a->rn) : cpu_reg(s, a->rn);
96
+ * Like the pseudocode UpdateFPCCR: save state in FPCAR and FPCCR
80
+ TCGv_i64 tcg_rd = rd_sp ? cpu_reg_sp(s, a->rd) : cpu_reg(s, a->rd);
97
+ * that we will need later in order to do lazy FP reg stacking.
81
+ TCGv_i64 tcg_imm = tcg_constant_i64(a->imm);
98
+ */
99
+ bool is_secure = env->v7m.secure;
100
+ void *nvic = env->nvic;
101
+ /*
102
+ * Some bits are unbanked and live always in fpccr[M_REG_S]; some bits
103
+ * are banked and we want to update the bit in the bank for the
104
+ * current security state; and in one case we want to specifically
105
+ * update the NS banked version of a bit even if we are secure.
106
+ */
107
+ uint32_t *fpccr_s = &env->v7m.fpccr[M_REG_S];
108
+ uint32_t *fpccr_ns = &env->v7m.fpccr[M_REG_NS];
109
+ uint32_t *fpccr = &env->v7m.fpccr[is_secure];
110
+ bool hfrdy, bfrdy, mmrdy, ns_ufrdy, s_ufrdy, sfrdy, monrdy;
111
+
82
+
112
+ env->v7m.fpcar[is_secure] = frameptr & ~0x7;
83
+ fn(tcg_rd, tcg_rn, tcg_imm);
113
+
84
+ if (!a->sf) {
114
+ if (apply_splim && arm_feature(env, ARM_FEATURE_V8)) {
85
+ tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
115
+ bool splimviol;
116
+ uint32_t splim = v7m_sp_limit(env);
117
+ bool ign = armv7m_nvic_neg_prio_requested(nvic, is_secure) &&
118
+ (env->v7m.ccr[is_secure] & R_V7M_CCR_STKOFHFNMIGN_MASK);
119
+
120
+ splimviol = !ign && frameptr < splim;
121
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, SPLIMVIOL, splimviol);
122
+ }
86
+ }
123
+
87
+ return true;
124
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, LSPACT, 1);
125
+
126
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, S, is_secure);
127
+
128
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, USER, arm_current_el(env) == 0);
129
+
130
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, THREAD,
131
+ !arm_v7m_is_handler_mode(env));
132
+
133
+ hfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_HARD, false);
134
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, HFRDY, hfrdy);
135
+
136
+ bfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_BUS, false);
137
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, BFRDY, bfrdy);
138
+
139
+ mmrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_MEM, is_secure);
140
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, MMRDY, mmrdy);
141
+
142
+ ns_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, false);
143
+ *fpccr_ns = FIELD_DP32(*fpccr_ns, V7M_FPCCR, UFRDY, ns_ufrdy);
144
+
145
+ monrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_DEBUG, false);
146
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, MONRDY, monrdy);
147
+
148
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
149
+ s_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, true);
150
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, UFRDY, s_ufrdy);
151
+
152
+ sfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_SECURE, false);
153
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, SFRDY, sfrdy);
154
+ }
155
+}
88
+}
156
+
89
+
157
static bool v7m_push_stack(ARMCPU *cpu)
90
/*
91
* PC-rel. addressing
92
*/
93
@@ -XXX,XX +XXX,XX @@ static bool trans_ADRP(DisasContext *s, arg_ri *a)
94
95
/*
96
* Add/subtract (immediate)
97
- *
98
- * 31 30 29 28 23 22 21 10 9 5 4 0
99
- * +--+--+--+-------------+--+-------------+-----+-----+
100
- * |sf|op| S| 1 0 0 0 1 0 |sh| imm12 | Rn | Rd |
101
- * +--+--+--+-------------+--+-------------+-----+-----+
102
- *
103
- * sf: 0 -> 32bit, 1 -> 64bit
104
- * op: 0 -> add , 1 -> sub
105
- * S: 1 -> set flags
106
- * sh: 1 -> LSL imm by 12
107
*/
108
-static void disas_add_sub_imm(DisasContext *s, uint32_t insn)
109
-{
110
- int rd = extract32(insn, 0, 5);
111
- int rn = extract32(insn, 5, 5);
112
- uint64_t imm = extract32(insn, 10, 12);
113
- bool shift = extract32(insn, 22, 1);
114
- bool setflags = extract32(insn, 29, 1);
115
- bool sub_op = extract32(insn, 30, 1);
116
- bool is_64bit = extract32(insn, 31, 1);
117
-
118
- TCGv_i64 tcg_rn = cpu_reg_sp(s, rn);
119
- TCGv_i64 tcg_rd = setflags ? cpu_reg(s, rd) : cpu_reg_sp(s, rd);
120
- TCGv_i64 tcg_result;
121
-
122
- if (shift) {
123
- imm <<= 12;
124
- }
125
-
126
- tcg_result = tcg_temp_new_i64();
127
- if (!setflags) {
128
- if (sub_op) {
129
- tcg_gen_subi_i64(tcg_result, tcg_rn, imm);
130
- } else {
131
- tcg_gen_addi_i64(tcg_result, tcg_rn, imm);
132
- }
133
- } else {
134
- TCGv_i64 tcg_imm = tcg_constant_i64(imm);
135
- if (sub_op) {
136
- gen_sub_CC(is_64bit, tcg_result, tcg_rn, tcg_imm);
137
- } else {
138
- gen_add_CC(is_64bit, tcg_result, tcg_rn, tcg_imm);
139
- }
140
- }
141
-
142
- if (is_64bit) {
143
- tcg_gen_mov_i64(tcg_rd, tcg_result);
144
- } else {
145
- tcg_gen_ext32u_i64(tcg_rd, tcg_result);
146
- }
147
-}
148
+TRANS(ADD_i, gen_rri, a, 1, 1, tcg_gen_add_i64)
149
+TRANS(SUB_i, gen_rri, a, 1, 1, tcg_gen_sub_i64)
150
+TRANS(ADDS_i, gen_rri, a, 0, 1, a->sf ? gen_add64_CC : gen_add32_CC)
151
+TRANS(SUBS_i, gen_rri, a, 0, 1, a->sf ? gen_sub64_CC : gen_sub32_CC)
152
153
/*
154
* Add/subtract (immediate, with tags)
155
@@ -XXX,XX +XXX,XX @@ static void disas_extract(DisasContext *s, uint32_t insn)
156
static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
158
{
157
{
159
/* Do the "set up stack frame" part of exception entry,
158
switch (extract32(insn, 23, 6)) {
160
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
159
- case 0x22: /* Add/subtract (immediate) */
161
}
160
- disas_add_sub_imm(s, insn);
162
} else {
161
- break;
163
/* Lazy stacking enabled, save necessary info to stack later */
162
case 0x23: /* Add/subtract (immediate, with tags) */
164
- /* TODO : equivalent of UpdateFPCCR() pseudocode */
163
disas_add_sub_imm_with_tags(s, insn);
165
+ v7m_update_fpccr(env, frameptr + 0x20, true);
164
break;
166
}
167
}
168
}
169
--
165
--
170
2.20.1
166
2.34.1
171
172
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
No code used the tc6393xb_gpio_in_get() and tc6393xb_gpio_out_set()
3
Convert the ADDG and SUBG (immediate) instructions.
4
functions since their introduction in commit 88d2c950b002. Time to
5
remove them.
6
4
7
Suggested-by: Markus Armbruster <armbru@redhat.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20190412165416.7977-4-philmd@redhat.com
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20230512144106.3608981-8-peter.maydell@linaro.org
9
[PMM: Rebased; use TRANS_FEAT()]
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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
target/arm/tcg/a64.decode | 8 +++++++
14
hw/display/tc6393xb.c | 16 ----------------
14
target/arm/tcg/translate-a64.c | 38 ++++++++++------------------------
15
2 files changed, 19 deletions(-)
15
2 files changed, 19 insertions(+), 27 deletions(-)
16
16
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
17
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/devices.h
19
--- a/target/arm/tcg/a64.decode
20
+++ b/include/hw/devices.h
20
+++ b/target/arm/tcg/a64.decode
21
@@ -XXX,XX +XXX,XX @@ void retu_key_event(void *retu, int state);
21
@@ -XXX,XX +XXX,XX @@ SUB_i . 10 100010 0 ............ ..... ..... @addsub_imm
22
typedef struct TC6393xbState TC6393xbState;
22
SUB_i . 10 100010 1 ............ ..... ..... @addsub_imm12
23
TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
23
SUBS_i . 11 100010 0 ............ ..... ..... @addsub_imm
24
uint32_t base, qemu_irq irq);
24
SUBS_i . 11 100010 1 ............ ..... ..... @addsub_imm12
25
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
25
+
26
- qemu_irq handler);
26
+# Add/subtract (immediate with tags)
27
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s);
27
+
28
qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
28
+&rri_tag rd rn uimm6 uimm4
29
29
+@addsub_imm_tag . .. ...... . uimm6:6 .. uimm4:4 rn:5 rd:5 &rri_tag
30
#endif
30
+
31
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
31
+ADDG_i 1 00 100011 0 ...... 00 .... ..... ..... @addsub_imm_tag
32
+SUBG_i 1 10 100011 0 ...... 00 .... ..... ..... @addsub_imm_tag
33
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
32
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/display/tc6393xb.c
35
--- a/target/arm/tcg/translate-a64.c
34
+++ b/hw/display/tc6393xb.c
36
+++ b/target/arm/tcg/translate-a64.c
35
@@ -XXX,XX +XXX,XX @@ struct TC6393xbState {
37
@@ -XXX,XX +XXX,XX @@ TRANS(SUBS_i, gen_rri, a, 0, 1, a->sf ? gen_sub64_CC : gen_sub32_CC)
36
blanked : 1;
38
37
};
39
/*
38
40
* Add/subtract (immediate, with tags)
39
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s)
41
- *
40
-{
42
- * 31 30 29 28 23 22 21 16 14 10 9 5 4 0
41
- return s->gpio_in;
43
- * +--+--+--+-------------+--+---------+--+-------+-----+-----+
42
-}
44
- * |sf|op| S| 1 0 0 0 1 1 |o2| uimm6 |o3| uimm4 | Rn | Rd |
43
-
45
- * +--+--+--+-------------+--+---------+--+-------+-----+-----+
44
static void tc6393xb_gpio_set(void *opaque, int line, int level)
46
- *
47
- * op: 0 -> add, 1 -> sub
48
*/
49
-static void disas_add_sub_imm_with_tags(DisasContext *s, uint32_t insn)
50
+
51
+static bool gen_add_sub_imm_with_tags(DisasContext *s, arg_rri_tag *a,
52
+ bool sub_op)
45
{
53
{
46
// TC6393xbState *s = opaque;
54
- int rd = extract32(insn, 0, 5);
47
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_gpio_set(void *opaque, int line, int level)
55
- int rn = extract32(insn, 5, 5);
48
// FIXME: how does the chip reflect the GPIO input level change?
56
- int uimm4 = extract32(insn, 10, 4);
49
}
57
- int uimm6 = extract32(insn, 16, 6);
50
58
- bool sub_op = extract32(insn, 30, 1);
51
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
59
TCGv_i64 tcg_rn, tcg_rd;
52
- qemu_irq handler)
60
int imm;
53
-{
61
54
- if (line >= TC6393XB_GPIOS) {
62
- /* Test all of sf=1, S=0, o2=0, o3=0. */
55
- fprintf(stderr, "TC6393xb: no GPIO pin %d\n", line);
63
- if ((insn & 0xa040c000u) != 0x80000000u ||
64
- !dc_isar_feature(aa64_mte_insn_reg, s)) {
65
- unallocated_encoding(s);
56
- return;
66
- return;
57
- }
67
- }
58
-
68
-
59
- s->handler[line] = handler;
69
- imm = uimm6 << LOG2_TAG_GRANULE;
60
-}
70
+ imm = a->uimm6 << LOG2_TAG_GRANULE;
61
-
71
if (sub_op) {
62
static void tc6393xb_gpio_handler_update(TC6393xbState *s)
72
imm = -imm;
73
}
74
75
- tcg_rn = cpu_reg_sp(s, rn);
76
- tcg_rd = cpu_reg_sp(s, rd);
77
+ tcg_rn = cpu_reg_sp(s, a->rn);
78
+ tcg_rd = cpu_reg_sp(s, a->rd);
79
80
if (s->ata) {
81
gen_helper_addsubg(tcg_rd, cpu_env, tcg_rn,
82
tcg_constant_i32(imm),
83
- tcg_constant_i32(uimm4));
84
+ tcg_constant_i32(a->uimm4));
85
} else {
86
tcg_gen_addi_i64(tcg_rd, tcg_rn, imm);
87
gen_address_with_allocation_tag0(tcg_rd, tcg_rd);
88
}
89
+ return true;
90
}
91
92
+TRANS_FEAT(ADDG_i, aa64_mte_insn_reg, gen_add_sub_imm_with_tags, a, false)
93
+TRANS_FEAT(SUBG_i, aa64_mte_insn_reg, gen_add_sub_imm_with_tags, a, true)
94
+
95
/* The input should be a value in the bottom e bits (with higher
96
* bits zero); returns that value replicated into every element
97
* of size e in a 64 bit integer.
98
@@ -XXX,XX +XXX,XX @@ static void disas_extract(DisasContext *s, uint32_t insn)
99
static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
63
{
100
{
64
uint32_t level, diff;
101
switch (extract32(insn, 23, 6)) {
102
- case 0x23: /* Add/subtract (immediate, with tags) */
103
- disas_add_sub_imm_with_tags(s, insn);
104
- break;
105
case 0x24: /* Logical (immediate) */
106
disas_logic_imm(s, insn);
107
break;
65
--
108
--
66
2.20.1
109
2.34.1
67
68
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This device is used by both ARM (BCM2836, for raspi2) and AArch64
3
Use the bitops.h macro rather than rolling our own here.
4
(BCM2837, for raspi3) targets, and is not CPU-specific.
5
Move it to common object, so we build it once for all targets.
6
4
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190427133028.12874-1-philmd@redhat.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20230512144106.3608981-9-peter.maydell@linaro.org
11
---
9
---
12
hw/dma/Makefile.objs | 2 +-
10
target/arm/tcg/translate-a64.c | 11 ++---------
13
1 file changed, 1 insertion(+), 1 deletion(-)
11
1 file changed, 2 insertions(+), 9 deletions(-)
14
12
15
diff --git a/hw/dma/Makefile.objs b/hw/dma/Makefile.objs
13
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/dma/Makefile.objs
15
--- a/target/arm/tcg/translate-a64.c
18
+++ b/hw/dma/Makefile.objs
16
+++ b/target/arm/tcg/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zdma.o
17
@@ -XXX,XX +XXX,XX @@ static uint64_t bitfield_replicate(uint64_t mask, unsigned int e)
20
18
return mask;
21
obj-$(CONFIG_OMAP) += omap_dma.o soc_dma.o
19
}
22
obj-$(CONFIG_PXA2XX) += pxa2xx_dma.o
20
23
-obj-$(CONFIG_RASPI) += bcm2835_dma.o
21
-/* Return a value with the bottom len bits set (where 0 < len <= 64) */
24
+common-obj-$(CONFIG_RASPI) += bcm2835_dma.o
22
-static inline uint64_t bitmask64(unsigned int length)
23
-{
24
- assert(length > 0 && length <= 64);
25
- return ~0ULL >> (64 - length);
26
-}
27
-
28
/* Simplified variant of pseudocode DecodeBitMasks() for the case where we
29
* only require the wmask. Returns false if the imms/immr/immn are a reserved
30
* value (ie should cause a guest UNDEF exception), and true if they are
31
@@ -XXX,XX +XXX,XX @@ bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
32
/* Create the value of one element: s+1 set bits rotated
33
* by r within the element (which is e bits wide)...
34
*/
35
- mask = bitmask64(s + 1);
36
+ mask = MAKE_64BIT_MASK(0, s + 1);
37
if (r) {
38
mask = (mask >> r) | (mask << (e - r));
39
- mask &= bitmask64(e);
40
+ mask &= MAKE_64BIT_MASK(0, e);
41
}
42
/* ...then replicate the element over the whole 64 bit value */
43
mask = bitfield_replicate(mask, e);
25
--
44
--
26
2.20.1
45
2.34.1
27
28
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Since uWireSlave is only used in this new header, there is no
3
Convert the ADD, ORR, EOR, ANDS (immediate) instructions.
4
need to expose it via "qemu/typedefs.h".
5
4
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20190412165416.7977-9-philmd@redhat.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20230512144106.3608981-10-peter.maydell@linaro.org
9
[PMM: rebased]
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
target/arm/tcg/a64.decode | 15 ++++++
12
include/hw/devices.h | 15 ---------------
13
target/arm/tcg/translate-a64.c | 94 +++++++++++-----------------------
13
include/hw/input/tsc2xxx.h | 36 ++++++++++++++++++++++++++++++++++++
14
2 files changed, 44 insertions(+), 65 deletions(-)
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
15
23
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
16
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
24
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/omap.h
18
--- a/target/arm/tcg/a64.decode
26
+++ b/include/hw/arm/omap.h
19
+++ b/target/arm/tcg/a64.decode
27
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ SUBS_i . 11 100010 1 ............ ..... ..... @addsub_imm12
28
#include "exec/memory.h"
21
29
# define hw_omap_h        "omap.h"
22
ADDG_i 1 00 100011 0 ...... 00 .... ..... ..... @addsub_imm_tag
30
#include "hw/irq.h"
23
SUBG_i 1 10 100011 0 ...... 00 .... ..... ..... @addsub_imm_tag
31
+#include "hw/input/tsc2xxx.h"
24
+
32
#include "target/arm/cpu-qom.h"
25
+# Logical (immediate)
33
#include "qemu/log.h"
26
+
34
27
+&rri_log rd rn sf dbm
35
@@ -XXX,XX +XXX,XX @@ qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s);
28
+@logic_imm_64 1 .. ...... dbm:13 rn:5 rd:5 &rri_log sf=1
36
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler);
29
+@logic_imm_32 0 .. ...... 0 dbm:12 rn:5 rd:5 &rri_log sf=0
37
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down);
30
+
38
31
+AND_i . 00 100100 . ...... ...... ..... ..... @logic_imm_64
39
-struct uWireSlave {
32
+AND_i . 00 100100 . ...... ...... ..... ..... @logic_imm_32
40
- uint16_t (*receive)(void *opaque);
33
+ORR_i . 01 100100 . ...... ...... ..... ..... @logic_imm_64
41
- void (*send)(void *opaque, uint16_t data);
34
+ORR_i . 01 100100 . ...... ...... ..... ..... @logic_imm_32
42
- void *opaque;
35
+EOR_i . 10 100100 . ...... ...... ..... ..... @logic_imm_64
43
-};
36
+EOR_i . 10 100100 . ...... ...... ..... ..... @logic_imm_32
44
struct omap_uwire_s;
37
+ANDS_i . 11 100100 . ...... ...... ..... ..... @logic_imm_64
45
void omap_uwire_attach(struct omap_uwire_s *s,
38
+ANDS_i . 11 100100 . ...... ...... ..... ..... @logic_imm_32
46
uWireSlave *slave, int chipselect);
39
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
47
diff --git a/include/hw/devices.h b/include/hw/devices.h
48
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
49
--- a/include/hw/devices.h
41
--- a/target/arm/tcg/translate-a64.c
50
+++ b/include/hw/devices.h
42
+++ b/target/arm/tcg/translate-a64.c
51
@@ -XXX,XX +XXX,XX @@
43
@@ -XXX,XX +XXX,XX @@ static uint64_t bitfield_replicate(uint64_t mask, unsigned int e)
52
/* Devices that have nowhere better to go. */
44
return mask;
53
45
}
54
#include "hw/hw.h"
46
55
-#include "ui/console.h"
47
-/* Simplified variant of pseudocode DecodeBitMasks() for the case where we
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
+/*
48
+/*
85
+ * TI touchscreen controller
49
+ * Logical (immediate)
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
+ */
50
+ */
93
+
51
+
94
+#ifndef HW_INPUT_TSC2XXX_H
52
+/*
95
+#define HW_INPUT_TSC2XXX_H
53
+ * Simplified variant of pseudocode DecodeBitMasks() for the case where we
54
* only require the wmask. Returns false if the imms/immr/immn are a reserved
55
* value (ie should cause a guest UNDEF exception), and true if they are
56
* valid, in which case the decoded bit pattern is written to result.
57
@@ -XXX,XX +XXX,XX @@ bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
58
return true;
59
}
60
61
-/* Logical (immediate)
62
- * 31 30 29 28 23 22 21 16 15 10 9 5 4 0
63
- * +----+-----+-------------+---+------+------+------+------+
64
- * | sf | opc | 1 0 0 1 0 0 | N | immr | imms | Rn | Rd |
65
- * +----+-----+-------------+---+------+------+------+------+
66
- */
67
-static void disas_logic_imm(DisasContext *s, uint32_t insn)
68
+static bool gen_rri_log(DisasContext *s, arg_rri_log *a, bool set_cc,
69
+ void (*fn)(TCGv_i64, TCGv_i64, int64_t))
70
{
71
- unsigned int sf, opc, is_n, immr, imms, rn, rd;
72
TCGv_i64 tcg_rd, tcg_rn;
73
- uint64_t wmask;
74
- bool is_and = false;
75
+ uint64_t imm;
76
77
- sf = extract32(insn, 31, 1);
78
- opc = extract32(insn, 29, 2);
79
- is_n = extract32(insn, 22, 1);
80
- immr = extract32(insn, 16, 6);
81
- imms = extract32(insn, 10, 6);
82
- rn = extract32(insn, 5, 5);
83
- rd = extract32(insn, 0, 5);
84
-
85
- if (!sf && is_n) {
86
- unallocated_encoding(s);
87
- return;
88
+ /* Some immediate field values are reserved. */
89
+ if (!logic_imm_decode_wmask(&imm, extract32(a->dbm, 12, 1),
90
+ extract32(a->dbm, 0, 6),
91
+ extract32(a->dbm, 6, 6))) {
92
+ return false;
93
+ }
94
+ if (!a->sf) {
95
+ imm &= 0xffffffffull;
96
}
97
98
- if (opc == 0x3) { /* ANDS */
99
- tcg_rd = cpu_reg(s, rd);
100
- } else {
101
- tcg_rd = cpu_reg_sp(s, rd);
102
- }
103
- tcg_rn = cpu_reg(s, rn);
104
+ tcg_rd = set_cc ? cpu_reg(s, a->rd) : cpu_reg_sp(s, a->rd);
105
+ tcg_rn = cpu_reg(s, a->rn);
106
107
- if (!logic_imm_decode_wmask(&wmask, is_n, imms, immr)) {
108
- /* some immediate field values are reserved */
109
- unallocated_encoding(s);
110
- return;
111
+ fn(tcg_rd, tcg_rn, imm);
112
+ if (set_cc) {
113
+ gen_logic_CC(a->sf, tcg_rd);
114
}
115
-
116
- if (!sf) {
117
- wmask &= 0xffffffff;
118
- }
119
-
120
- switch (opc) {
121
- case 0x3: /* ANDS */
122
- case 0x0: /* AND */
123
- tcg_gen_andi_i64(tcg_rd, tcg_rn, wmask);
124
- is_and = true;
125
- break;
126
- case 0x1: /* ORR */
127
- tcg_gen_ori_i64(tcg_rd, tcg_rn, wmask);
128
- break;
129
- case 0x2: /* EOR */
130
- tcg_gen_xori_i64(tcg_rd, tcg_rn, wmask);
131
- break;
132
- default:
133
- assert(FALSE); /* must handle all above */
134
- break;
135
- }
136
-
137
- if (!sf && !is_and) {
138
- /* zero extend final result; we know we can skip this for AND
139
- * since the immediate had the high 32 bits clear.
140
- */
141
+ if (!a->sf) {
142
tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
143
}
144
-
145
- if (opc == 3) { /* ANDS */
146
- gen_logic_CC(sf, tcg_rd);
147
- }
148
+ return true;
149
}
150
151
+TRANS(AND_i, gen_rri_log, a, false, tcg_gen_andi_i64)
152
+TRANS(ORR_i, gen_rri_log, a, false, tcg_gen_ori_i64)
153
+TRANS(EOR_i, gen_rri_log, a, false, tcg_gen_xori_i64)
154
+TRANS(ANDS_i, gen_rri_log, a, true, tcg_gen_andi_i64)
96
+
155
+
97
+#include "hw/irq.h"
156
/*
98
+#include "ui/console.h"
157
* Move wide (immediate)
99
+
158
*
100
+typedef struct uWireSlave {
159
@@ -XXX,XX +XXX,XX @@ static void disas_extract(DisasContext *s, uint32_t insn)
101
+ uint16_t (*receive)(void *opaque);
160
static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
102
+ void (*send)(void *opaque, uint16_t data);
161
{
103
+ void *opaque;
162
switch (extract32(insn, 23, 6)) {
104
+} uWireSlave;
163
- case 0x24: /* Logical (immediate) */
105
+
164
- disas_logic_imm(s, insn);
106
+/* tsc210x.c */
165
- break;
107
+uWireSlave *tsc2102_init(qemu_irq pint);
166
case 0x25: /* Move wide (immediate) */
108
+uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
167
disas_movw_imm(s, insn);
109
+I2SCodec *tsc210x_codec(uWireSlave *chip);
168
break;
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
--
169
--
208
2.20.1
170
2.34.1
209
210
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Suggested-by: Markus Armbruster <armbru@redhat.com>
3
Convert the MON, MOVZ, MOVK instructions.
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
5
Message-id: 20190412165416.7977-3-philmd@redhat.com
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20230512144106.3608981-11-peter.maydell@linaro.org
9
[PMM: Rebased]
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
12
---
9
hw/arm/nseries.c | 3 ++-
13
target/arm/tcg/a64.decode | 13 ++++++
10
1 file changed, 2 insertions(+), 1 deletion(-)
14
target/arm/tcg/translate-a64.c | 73 ++++++++++++++--------------------
15
2 files changed, 42 insertions(+), 44 deletions(-)
11
16
12
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
17
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/nseries.c
19
--- a/target/arm/tcg/a64.decode
15
+++ b/hw/arm/nseries.c
20
+++ b/target/arm/tcg/a64.decode
16
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ EOR_i . 10 100100 . ...... ...... ..... ..... @logic_imm_64
17
#include "hw/boards.h"
22
EOR_i . 10 100100 . ...... ...... ..... ..... @logic_imm_32
18
#include "hw/i2c/i2c.h"
23
ANDS_i . 11 100100 . ...... ...... ..... ..... @logic_imm_64
19
#include "hw/devices.h"
24
ANDS_i . 11 100100 . ...... ...... ..... ..... @logic_imm_32
20
+#include "hw/misc/tmp105.h"
25
+
21
#include "hw/block/flash.h"
26
+# Move wide (immediate)
22
#include "hw/hw.h"
27
+
23
#include "hw/bt.h"
28
+&movw rd sf imm hw
24
@@ -XXX,XX +XXX,XX @@ static void n8x0_i2c_setup(struct n800_s *s)
29
+@movw_64 1 .. ...... hw:2 imm:16 rd:5 &movw sf=1
25
qemu_register_powerdown_notifier(&n8x0_system_powerdown_notifier);
30
+@movw_32 0 .. ...... 0 hw:1 imm:16 rd:5 &movw sf=0
26
31
+
27
/* Attach a TMP105 PM chip (A0 wired to ground) */
32
+MOVN . 00 100101 .. ................ ..... @movw_64
28
- dev = i2c_create_slave(i2c, "tmp105", N8X0_TMP105_ADDR);
33
+MOVN . 00 100101 .. ................ ..... @movw_32
29
+ dev = i2c_create_slave(i2c, TYPE_TMP105, N8X0_TMP105_ADDR);
34
+MOVZ . 10 100101 .. ................ ..... @movw_64
30
qdev_connect_gpio_out(dev, 0, tmp_irq);
35
+MOVZ . 10 100101 .. ................ ..... @movw_32
36
+MOVK . 11 100101 .. ................ ..... @movw_64
37
+MOVK . 11 100101 .. ................ ..... @movw_32
38
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/tcg/translate-a64.c
41
+++ b/target/arm/tcg/translate-a64.c
42
@@ -XXX,XX +XXX,XX @@ TRANS(ANDS_i, gen_rri_log, a, true, tcg_gen_andi_i64)
43
44
/*
45
* Move wide (immediate)
46
- *
47
- * 31 30 29 28 23 22 21 20 5 4 0
48
- * +--+-----+-------------+-----+----------------+------+
49
- * |sf| opc | 1 0 0 1 0 1 | hw | imm16 | Rd |
50
- * +--+-----+-------------+-----+----------------+------+
51
- *
52
- * sf: 0 -> 32 bit, 1 -> 64 bit
53
- * opc: 00 -> N, 10 -> Z, 11 -> K
54
- * hw: shift/16 (0,16, and sf only 32, 48)
55
*/
56
-static void disas_movw_imm(DisasContext *s, uint32_t insn)
57
+
58
+static bool trans_MOVZ(DisasContext *s, arg_movw *a)
59
{
60
- int rd = extract32(insn, 0, 5);
61
- uint64_t imm = extract32(insn, 5, 16);
62
- int sf = extract32(insn, 31, 1);
63
- int opc = extract32(insn, 29, 2);
64
- int pos = extract32(insn, 21, 2) << 4;
65
- TCGv_i64 tcg_rd = cpu_reg(s, rd);
66
+ int pos = a->hw << 4;
67
+ tcg_gen_movi_i64(cpu_reg(s, a->rd), (uint64_t)a->imm << pos);
68
+ return true;
69
+}
70
71
- if (!sf && (pos >= 32)) {
72
- unallocated_encoding(s);
73
- return;
74
- }
75
+static bool trans_MOVN(DisasContext *s, arg_movw *a)
76
+{
77
+ int pos = a->hw << 4;
78
+ uint64_t imm = a->imm;
79
80
- switch (opc) {
81
- case 0: /* MOVN */
82
- case 2: /* MOVZ */
83
- imm <<= pos;
84
- if (opc == 0) {
85
- imm = ~imm;
86
- }
87
- if (!sf) {
88
- imm &= 0xffffffffu;
89
- }
90
- tcg_gen_movi_i64(tcg_rd, imm);
91
- break;
92
- case 3: /* MOVK */
93
- tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_constant_i64(imm), pos, 16);
94
- if (!sf) {
95
- tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
96
- }
97
- break;
98
- default:
99
- unallocated_encoding(s);
100
- break;
101
+ imm = ~(imm << pos);
102
+ if (!a->sf) {
103
+ imm = (uint32_t)imm;
104
}
105
+ tcg_gen_movi_i64(cpu_reg(s, a->rd), imm);
106
+ return true;
107
+}
108
+
109
+static bool trans_MOVK(DisasContext *s, arg_movw *a)
110
+{
111
+ int pos = a->hw << 4;
112
+ TCGv_i64 tcg_rd, tcg_im;
113
+
114
+ tcg_rd = cpu_reg(s, a->rd);
115
+ tcg_im = tcg_constant_i64(a->imm);
116
+ tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_im, pos, 16);
117
+ if (!a->sf) {
118
+ tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
119
+ }
120
+ return true;
31
}
121
}
32
122
123
/* Bitfield
124
@@ -XXX,XX +XXX,XX @@ static void disas_extract(DisasContext *s, uint32_t insn)
125
static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
126
{
127
switch (extract32(insn, 23, 6)) {
128
- case 0x25: /* Move wide (immediate) */
129
- disas_movw_imm(s, insn);
130
- break;
131
case 0x26: /* Bitfield */
132
disas_bitfield(s, insn);
133
break;
33
--
134
--
34
2.20.1
135
2.34.1
35
36
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
Convert the BFM, SBFM, UBFM instructions.
4
Reviewed-by: Cédric Le Goater <clg@kaod.org>
4
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20190412165416.7977-2-philmd@redhat.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20230512144106.3608981-12-peter.maydell@linaro.org
9
[PMM: Rebased]
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
target/arm/tcg/a64.decode | 13 +++
11
1 file changed, 9 insertions(+), 4 deletions(-)
13
target/arm/tcg/translate-a64.c | 144 ++++++++++++++++++---------------
14
2 files changed, 94 insertions(+), 63 deletions(-)
12
15
13
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
16
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/aspeed.c
18
--- a/target/arm/tcg/a64.decode
16
+++ b/hw/arm/aspeed.c
19
+++ b/target/arm/tcg/a64.decode
17
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ MOVZ . 10 100101 .. ................ ..... @movw_64
18
#include "hw/arm/aspeed_soc.h"
21
MOVZ . 10 100101 .. ................ ..... @movw_32
19
#include "hw/boards.h"
22
MOVK . 11 100101 .. ................ ..... @movw_64
20
#include "hw/i2c/smbus_eeprom.h"
23
MOVK . 11 100101 .. ................ ..... @movw_32
21
+#include "hw/misc/pca9552.h"
24
+
22
+#include "hw/misc/tmp105.h"
25
+# Bitfield
23
#include "qemu/log.h"
26
+
24
#include "sysemu/block-backend.h"
27
+&bitfield rd rn sf immr imms
25
#include "hw/loader.h"
28
+@bitfield_64 1 .. ...... 1 immr:6 imms:6 rn:5 rd:5 &bitfield sf=1
26
@@ -XXX,XX +XXX,XX @@ static void ast2500_evb_i2c_init(AspeedBoardState *bmc)
29
+@bitfield_32 0 .. ...... 0 0 immr:5 0 imms:5 rn:5 rd:5 &bitfield sf=0
27
eeprom_buf);
30
+
28
31
+SBFM . 00 100110 . ...... ...... ..... ..... @bitfield_64
29
/* The AST2500 EVB expects a LM75 but a TMP105 is compatible */
32
+SBFM . 00 100110 . ...... ...... ..... ..... @bitfield_32
30
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7), "tmp105", 0x4d);
33
+BFM . 01 100110 . ...... ...... ..... ..... @bitfield_64
31
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7),
34
+BFM . 01 100110 . ...... ...... ..... ..... @bitfield_32
32
+ TYPE_TMP105, 0x4d);
35
+UBFM . 10 100110 . ...... ...... ..... ..... @bitfield_64
33
36
+UBFM . 10 100110 . ...... ...... ..... ..... @bitfield_32
34
/* The AST2500 EVB does not have an RTC. Let's pretend that one is
37
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
35
* plugged on the I2C bus header */
38
index XXXXXXX..XXXXXXX 100644
36
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
39
--- a/target/arm/tcg/translate-a64.c
37
AspeedSoCState *soc = &bmc->soc;
40
+++ b/target/arm/tcg/translate-a64.c
38
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
41
@@ -XXX,XX +XXX,XX @@ static bool trans_MOVK(DisasContext *s, arg_movw *a)
39
42
return true;
40
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), "pca9552", 0x60);
41
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), TYPE_PCA9552,
42
+ 0x60);
43
44
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), "tmp423", 0x4c);
45
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 5), "tmp423", 0x4c);
46
47
/* The Witherspoon expects a TMP275 but a TMP105 is compatible */
48
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), "tmp105", 0x4a);
49
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), TYPE_TMP105,
50
+ 0x4a);
51
52
/* The witherspoon board expects Epson RX8900 I2C RTC but a ds1338 is
53
* good enough */
54
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
55
56
smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), 0x51,
57
eeprom_buf);
58
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "pca9552",
59
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), TYPE_PCA9552,
60
0x60);
61
}
43
}
62
44
45
-/* Bitfield
46
- * 31 30 29 28 23 22 21 16 15 10 9 5 4 0
47
- * +----+-----+-------------+---+------+------+------+------+
48
- * | sf | opc | 1 0 0 1 1 0 | N | immr | imms | Rn | Rd |
49
- * +----+-----+-------------+---+------+------+------+------+
50
+/*
51
+ * Bitfield
52
*/
53
-static void disas_bitfield(DisasContext *s, uint32_t insn)
54
+
55
+static bool trans_SBFM(DisasContext *s, arg_SBFM *a)
56
{
57
- unsigned int sf, n, opc, ri, si, rn, rd, bitsize, pos, len;
58
- TCGv_i64 tcg_rd, tcg_tmp;
59
+ TCGv_i64 tcg_rd = cpu_reg(s, a->rd);
60
+ TCGv_i64 tcg_tmp = read_cpu_reg(s, a->rn, 1);
61
+ unsigned int bitsize = a->sf ? 64 : 32;
62
+ unsigned int ri = a->immr;
63
+ unsigned int si = a->imms;
64
+ unsigned int pos, len;
65
66
- sf = extract32(insn, 31, 1);
67
- opc = extract32(insn, 29, 2);
68
- n = extract32(insn, 22, 1);
69
- ri = extract32(insn, 16, 6);
70
- si = extract32(insn, 10, 6);
71
- rn = extract32(insn, 5, 5);
72
- rd = extract32(insn, 0, 5);
73
- bitsize = sf ? 64 : 32;
74
-
75
- if (sf != n || ri >= bitsize || si >= bitsize || opc > 2) {
76
- unallocated_encoding(s);
77
- return;
78
- }
79
-
80
- tcg_rd = cpu_reg(s, rd);
81
-
82
- /* Suppress the zero-extend for !sf. Since RI and SI are constrained
83
- to be smaller than bitsize, we'll never reference data outside the
84
- low 32-bits anyway. */
85
- tcg_tmp = read_cpu_reg(s, rn, 1);
86
-
87
- /* Recognize simple(r) extractions. */
88
if (si >= ri) {
89
/* Wd<s-r:0> = Wn<s:r> */
90
len = (si - ri) + 1;
91
- if (opc == 0) { /* SBFM: ASR, SBFX, SXTB, SXTH, SXTW */
92
- tcg_gen_sextract_i64(tcg_rd, tcg_tmp, ri, len);
93
- goto done;
94
- } else if (opc == 2) { /* UBFM: UBFX, LSR, UXTB, UXTH */
95
- tcg_gen_extract_i64(tcg_rd, tcg_tmp, ri, len);
96
- return;
97
+ tcg_gen_sextract_i64(tcg_rd, tcg_tmp, ri, len);
98
+ if (!a->sf) {
99
+ tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
100
}
101
- /* opc == 1, BFXIL fall through to deposit */
102
+ } else {
103
+ /* Wd<32+s-r,32-r> = Wn<s:0> */
104
+ len = si + 1;
105
+ pos = (bitsize - ri) & (bitsize - 1);
106
+
107
+ if (len < ri) {
108
+ /*
109
+ * Sign extend the destination field from len to fill the
110
+ * balance of the word. Let the deposit below insert all
111
+ * of those sign bits.
112
+ */
113
+ tcg_gen_sextract_i64(tcg_tmp, tcg_tmp, 0, len);
114
+ len = ri;
115
+ }
116
+
117
+ /*
118
+ * We start with zero, and we haven't modified any bits outside
119
+ * bitsize, therefore no final zero-extension is unneeded for !sf.
120
+ */
121
+ tcg_gen_deposit_z_i64(tcg_rd, tcg_tmp, pos, len);
122
+ }
123
+ return true;
124
+}
125
+
126
+static bool trans_UBFM(DisasContext *s, arg_UBFM *a)
127
+{
128
+ TCGv_i64 tcg_rd = cpu_reg(s, a->rd);
129
+ TCGv_i64 tcg_tmp = read_cpu_reg(s, a->rn, 1);
130
+ unsigned int bitsize = a->sf ? 64 : 32;
131
+ unsigned int ri = a->immr;
132
+ unsigned int si = a->imms;
133
+ unsigned int pos, len;
134
+
135
+ tcg_rd = cpu_reg(s, a->rd);
136
+ tcg_tmp = read_cpu_reg(s, a->rn, 1);
137
+
138
+ if (si >= ri) {
139
+ /* Wd<s-r:0> = Wn<s:r> */
140
+ len = (si - ri) + 1;
141
+ tcg_gen_extract_i64(tcg_rd, tcg_tmp, ri, len);
142
+ } else {
143
+ /* Wd<32+s-r,32-r> = Wn<s:0> */
144
+ len = si + 1;
145
+ pos = (bitsize - ri) & (bitsize - 1);
146
+ tcg_gen_deposit_z_i64(tcg_rd, tcg_tmp, pos, len);
147
+ }
148
+ return true;
149
+}
150
+
151
+static bool trans_BFM(DisasContext *s, arg_BFM *a)
152
+{
153
+ TCGv_i64 tcg_rd = cpu_reg(s, a->rd);
154
+ TCGv_i64 tcg_tmp = read_cpu_reg(s, a->rn, 1);
155
+ unsigned int bitsize = a->sf ? 64 : 32;
156
+ unsigned int ri = a->immr;
157
+ unsigned int si = a->imms;
158
+ unsigned int pos, len;
159
+
160
+ tcg_rd = cpu_reg(s, a->rd);
161
+ tcg_tmp = read_cpu_reg(s, a->rn, 1);
162
+
163
+ if (si >= ri) {
164
+ /* Wd<s-r:0> = Wn<s:r> */
165
tcg_gen_shri_i64(tcg_tmp, tcg_tmp, ri);
166
+ len = (si - ri) + 1;
167
pos = 0;
168
} else {
169
- /* Handle the ri > si case with a deposit
170
- * Wd<32+s-r,32-r> = Wn<s:0>
171
- */
172
+ /* Wd<32+s-r,32-r> = Wn<s:0> */
173
len = si + 1;
174
pos = (bitsize - ri) & (bitsize - 1);
175
}
176
177
- if (opc == 0 && len < ri) {
178
- /* SBFM: sign extend the destination field from len to fill
179
- the balance of the word. Let the deposit below insert all
180
- of those sign bits. */
181
- tcg_gen_sextract_i64(tcg_tmp, tcg_tmp, 0, len);
182
- len = ri;
183
- }
184
-
185
- if (opc == 1) { /* BFM, BFXIL */
186
- tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, pos, len);
187
- } else {
188
- /* SBFM or UBFM: We start with zero, and we haven't modified
189
- any bits outside bitsize, therefore the zero-extension
190
- below is unneeded. */
191
- tcg_gen_deposit_z_i64(tcg_rd, tcg_tmp, pos, len);
192
- return;
193
- }
194
-
195
- done:
196
- if (!sf) { /* zero extend final result */
197
+ tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, pos, len);
198
+ if (!a->sf) {
199
tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
200
}
201
+ return true;
202
}
203
204
/* Extract
205
@@ -XXX,XX +XXX,XX @@ static void disas_extract(DisasContext *s, uint32_t insn)
206
static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
207
{
208
switch (extract32(insn, 23, 6)) {
209
- case 0x26: /* Bitfield */
210
- disas_bitfield(s, insn);
211
- break;
212
case 0x27: /* Extract */
213
disas_extract(s, insn);
214
break;
63
--
215
--
64
2.20.1
216
2.34.1
65
66
diff view generated by jsdifflib
1
The M-profile FPCCR.S bit indicates the security status of
1
Convert the EXTR instruction to decodetree (this is the
2
the floating point context. In the pseudocode ExecuteFPCheck()
2
only one in the 'Extract" class). This is the last of
3
function it is unconditionally set to match the current
3
the dp-immediate insns in the legacy decoder, so we
4
security state whenever a floating point instruction is
4
can now remove disas_data_proc_imm().
5
executed.
6
7
Implement this by adding a new TB flag which tracks whether
8
FPCCR.S is different from the current security state, so
9
that we only need to emit the code to update it in the
10
less-common case when it is not already set correctly.
11
12
Note that we will add the handling for the other work done
13
by ExecuteFPCheck() in later commits.
14
5
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20190416125744.27770-19-peter.maydell@linaro.org
8
Message-id: 20230512144106.3608981-13-peter.maydell@linaro.org
18
---
9
---
19
target/arm/cpu.h | 2 ++
10
target/arm/tcg/a64.decode | 7 +++
20
target/arm/translate.h | 1 +
11
target/arm/tcg/translate-a64.c | 94 +++++++++++-----------------------
21
target/arm/helper.c | 5 +++++
12
2 files changed, 36 insertions(+), 65 deletions(-)
22
target/arm/translate.c | 20 ++++++++++++++++++++
23
4 files changed, 28 insertions(+)
24
13
25
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
26
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/cpu.h
16
--- a/target/arm/tcg/a64.decode
28
+++ b/target/arm/cpu.h
17
+++ b/target/arm/tcg/a64.decode
29
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
18
@@ -XXX,XX +XXX,XX @@ BFM . 01 100110 . ...... ...... ..... ..... @bitfield_64
30
FIELD(TBFLAG_A32, VFPEN, 7, 1)
19
BFM . 01 100110 . ...... ...... ..... ..... @bitfield_32
31
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
20
UBFM . 10 100110 . ...... ...... ..... ..... @bitfield_64
32
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
21
UBFM . 10 100110 . ...... ...... ..... ..... @bitfield_32
33
+/* For M profile only, set if FPCCR.S does not match current security state */
22
+
34
+FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
23
+# Extract
35
/* For M profile only, Handler (ie not Thread) mode */
24
+
36
FIELD(TBFLAG_A32, HANDLER, 21, 1)
25
+&extract rd rn rm imm sf
37
/* For M profile only, whether we should generate stack-limit checks */
26
+
38
diff --git a/target/arm/translate.h b/target/arm/translate.h
27
+EXTR 1 00 100111 1 0 rm:5 imm:6 rn:5 rd:5 &extract sf=1
28
+EXTR 0 00 100111 0 0 rm:5 0 imm:5 rn:5 rd:5 &extract sf=0
29
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
39
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/translate.h
31
--- a/target/arm/tcg/translate-a64.c
41
+++ b/target/arm/translate.h
32
+++ b/target/arm/tcg/translate-a64.c
42
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
33
@@ -XXX,XX +XXX,XX @@ static bool trans_BFM(DisasContext *s, arg_BFM *a)
43
bool v7m_handler_mode;
34
return true;
44
bool v8m_secure; /* true if v8M and we're in Secure mode */
35
}
45
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
36
46
+ bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
37
-/* Extract
47
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
38
- * 31 30 29 28 23 22 21 20 16 15 10 9 5 4 0
48
* so that top level loop can generate correct syndrome information.
39
- * +----+------+-------------+---+----+------+--------+------+------+
49
*/
40
- * | sf | op21 | 1 0 0 1 1 1 | N | o0 | Rm | imms | Rn | Rd |
50
diff --git a/target/arm/helper.c b/target/arm/helper.c
41
- * +----+------+-------------+---+----+------+--------+------+------+
51
index XXXXXXX..XXXXXXX 100644
42
- */
52
--- a/target/arm/helper.c
43
-static void disas_extract(DisasContext *s, uint32_t insn)
53
+++ b/target/arm/helper.c
44
+static bool trans_EXTR(DisasContext *s, arg_extract *a)
54
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
45
{
55
flags = FIELD_DP32(flags, TBFLAG_A32, STACKCHECK, 1);
46
- unsigned int sf, n, rm, imm, rn, rd, bitsize, op21, op0;
56
}
47
+ TCGv_i64 tcg_rd, tcg_rm, tcg_rn;
57
48
58
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
49
- sf = extract32(insn, 31, 1);
59
+ FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S) != env->v7m.secure) {
50
- n = extract32(insn, 22, 1);
60
+ flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
51
- rm = extract32(insn, 16, 5);
61
+ }
52
- imm = extract32(insn, 10, 6);
53
- rn = extract32(insn, 5, 5);
54
- rd = extract32(insn, 0, 5);
55
- op21 = extract32(insn, 29, 2);
56
- op0 = extract32(insn, 21, 1);
57
- bitsize = sf ? 64 : 32;
58
+ tcg_rd = cpu_reg(s, a->rd);
59
60
- if (sf != n || op21 || op0 || imm >= bitsize) {
61
- unallocated_encoding(s);
62
- } else {
63
- TCGv_i64 tcg_rd, tcg_rm, tcg_rn;
64
-
65
- tcg_rd = cpu_reg(s, rd);
66
-
67
- if (unlikely(imm == 0)) {
68
- /* tcg shl_i32/shl_i64 is undefined for 32/64 bit shifts,
69
- * so an extract from bit 0 is a special case.
70
- */
71
- if (sf) {
72
- tcg_gen_mov_i64(tcg_rd, cpu_reg(s, rm));
73
- } else {
74
- tcg_gen_ext32u_i64(tcg_rd, cpu_reg(s, rm));
75
- }
76
+ if (unlikely(a->imm == 0)) {
77
+ /*
78
+ * tcg shl_i32/shl_i64 is undefined for 32/64 bit shifts,
79
+ * so an extract from bit 0 is a special case.
80
+ */
81
+ if (a->sf) {
82
+ tcg_gen_mov_i64(tcg_rd, cpu_reg(s, a->rm));
83
} else {
84
- tcg_rm = cpu_reg(s, rm);
85
- tcg_rn = cpu_reg(s, rn);
86
+ tcg_gen_ext32u_i64(tcg_rd, cpu_reg(s, a->rm));
87
+ }
88
+ } else {
89
+ tcg_rm = cpu_reg(s, a->rm);
90
+ tcg_rn = cpu_reg(s, a->rn);
91
92
- if (sf) {
93
- /* Specialization to ROR happens in EXTRACT2. */
94
- tcg_gen_extract2_i64(tcg_rd, tcg_rm, tcg_rn, imm);
95
+ if (a->sf) {
96
+ /* Specialization to ROR happens in EXTRACT2. */
97
+ tcg_gen_extract2_i64(tcg_rd, tcg_rm, tcg_rn, a->imm);
98
+ } else {
99
+ TCGv_i32 t0 = tcg_temp_new_i32();
62
+
100
+
63
*pflags = flags;
101
+ tcg_gen_extrl_i64_i32(t0, tcg_rm);
64
*cs_base = 0;
102
+ if (a->rm == a->rn) {
65
}
103
+ tcg_gen_rotri_i32(t0, t0, a->imm);
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
104
} else {
67
index XXXXXXX..XXXXXXX 100644
105
- TCGv_i32 t0 = tcg_temp_new_i32();
68
--- a/target/arm/translate.c
106
-
69
+++ b/target/arm/translate.c
107
- tcg_gen_extrl_i64_i32(t0, tcg_rm);
70
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
108
- if (rm == rn) {
109
- tcg_gen_rotri_i32(t0, t0, imm);
110
- } else {
111
- TCGv_i32 t1 = tcg_temp_new_i32();
112
- tcg_gen_extrl_i64_i32(t1, tcg_rn);
113
- tcg_gen_extract2_i32(t0, t0, t1, imm);
114
- }
115
- tcg_gen_extu_i32_i64(tcg_rd, t0);
116
+ TCGv_i32 t1 = tcg_temp_new_i32();
117
+ tcg_gen_extrl_i64_i32(t1, tcg_rn);
118
+ tcg_gen_extract2_i32(t0, t0, t1, a->imm);
119
}
120
+ tcg_gen_extu_i32_i64(tcg_rd, t0);
71
}
121
}
72
}
122
}
73
123
-}
74
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
124
-
75
+ /* Handle M-profile lazy FP state mechanics */
125
-/* Data processing - immediate */
76
+
126
-static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
77
+ /* Update ownership of FP context: set FPCCR.S to match current state */
127
-{
78
+ if (s->v8m_fpccr_s_wrong) {
128
- switch (extract32(insn, 23, 6)) {
79
+ TCGv_i32 tmp;
129
- case 0x27: /* Extract */
80
+
130
- disas_extract(s, insn);
81
+ tmp = load_cpu_field(v7m.fpccr[M_REG_S]);
131
- break;
82
+ if (s->v8m_secure) {
132
- default:
83
+ tcg_gen_ori_i32(tmp, tmp, R_V7M_FPCCR_S_MASK);
133
- unallocated_encoding(s);
84
+ } else {
134
- break;
85
+ tcg_gen_andi_i32(tmp, tmp, ~R_V7M_FPCCR_S_MASK);
135
- }
86
+ }
136
+ return true;
87
+ store_cpu_field(tmp, v7m.fpccr[M_REG_S]);
137
}
88
+ /* Don't need to do this for any further FP insns in this TB */
138
89
+ s->v8m_fpccr_s_wrong = false;
139
/* Shift a TCGv src by TCGv shift_amount, put result in dst.
90
+ }
140
@@ -XXX,XX +XXX,XX @@ static bool btype_destination_ok(uint32_t insn, bool bt, int btype)
91
+ }
141
static void disas_a64_legacy(DisasContext *s, uint32_t insn)
92
+
142
{
93
if (extract32(insn, 28, 4) == 0xf) {
143
switch (extract32(insn, 25, 4)) {
94
/*
144
- case 0x8: case 0x9: /* Data processing - immediate */
95
* Encodings with T=1 (Thumb) or unconditional (ARM):
145
- disas_data_proc_imm(s, insn);
96
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
146
- break;
97
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
147
case 0xa: case 0xb: /* Branch, exception generation and system insns */
98
regime_is_secure(env, dc->mmu_idx);
148
disas_b_exc_sys(s, insn);
99
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
149
break;
100
+ dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
101
dc->cp_regs = cpu->cp_regs;
102
dc->features = env->features;
103
104
--
150
--
105
2.20.1
151
2.34.1
106
107
diff view generated by jsdifflib
1
Enable the FPU by default for the Cortex-M4 and Cortex-M33.
1
Convert the unconditional branch immediate insns B and BL 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-27-peter.maydell@linaro.org
6
Message-id: 20230512144106.3608981-14-peter.maydell@linaro.org
6
---
7
---
7
target/arm/cpu.c | 8 ++++++++
8
target/arm/tcg/a64.decode | 9 +++++++++
8
1 file changed, 8 insertions(+)
9
target/arm/tcg/translate-a64.c | 31 +++++++++++--------------------
10
2 files changed, 20 insertions(+), 20 deletions(-)
9
11
10
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
12
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
11
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
12
--- a/target/arm/cpu.c
14
--- a/target/arm/tcg/a64.decode
13
+++ b/target/arm/cpu.c
15
+++ b/target/arm/tcg/a64.decode
14
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
16
@@ -XXX,XX +XXX,XX @@
15
set_feature(&cpu->env, ARM_FEATURE_M);
17
16
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
18
&ri rd imm
17
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
19
&rri_sf rd rn imm sf
18
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
20
+&i imm
19
cpu->midr = 0x410fc240; /* r0p0 */
21
20
cpu->pmsav7_dregion = 8;
22
21
+ cpu->isar.mvfr0 = 0x10110021;
23
### Data Processing - Immediate
22
+ cpu->isar.mvfr1 = 0x11000011;
24
@@ -XXX,XX +XXX,XX @@ UBFM . 10 100110 . ...... ...... ..... ..... @bitfield_32
23
+ cpu->isar.mvfr2 = 0x00000000;
25
24
cpu->id_pfr0 = 0x00000030;
26
EXTR 1 00 100111 1 0 rm:5 imm:6 rn:5 rd:5 &extract sf=1
25
cpu->id_pfr1 = 0x00000200;
27
EXTR 0 00 100111 0 0 rm:5 0 imm:5 rn:5 rd:5 &extract sf=0
26
cpu->id_dfr0 = 0x00100000;
28
+
27
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
29
+# Branches
28
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
30
+
29
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
31
+%imm26 0:s26 !function=times_4
30
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
32
+@branch . ..... .......................... &i imm=%imm26
31
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
33
+
32
cpu->midr = 0x410fd213; /* r0p3 */
34
+B 0 00101 .......................... @branch
33
cpu->pmsav7_dregion = 16;
35
+BL 1 00101 .......................... @branch
34
cpu->sau_sregion = 8;
36
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
35
+ cpu->isar.mvfr0 = 0x10110021;
37
index XXXXXXX..XXXXXXX 100644
36
+ cpu->isar.mvfr1 = 0x11000011;
38
--- a/target/arm/tcg/translate-a64.c
37
+ cpu->isar.mvfr2 = 0x00000040;
39
+++ b/target/arm/tcg/translate-a64.c
38
cpu->id_pfr0 = 0x00000030;
40
@@ -XXX,XX +XXX,XX @@ static inline AArch64DecodeFn *lookup_disas_fn(const AArch64DecodeTable *table,
39
cpu->id_pfr1 = 0x00000210;
41
* match up with those in the manual.
40
cpu->id_dfr0 = 0x00200000;
42
*/
43
44
-/* Unconditional branch (immediate)
45
- * 31 30 26 25 0
46
- * +----+-----------+-------------------------------------+
47
- * | op | 0 0 1 0 1 | imm26 |
48
- * +----+-----------+-------------------------------------+
49
- */
50
-static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
51
+static bool trans_B(DisasContext *s, arg_i *a)
52
{
53
- int64_t diff = sextract32(insn, 0, 26) * 4;
54
-
55
- if (insn & (1U << 31)) {
56
- /* BL Branch with link */
57
- gen_pc_plus_diff(s, cpu_reg(s, 30), curr_insn_len(s));
58
- }
59
-
60
- /* B Branch / BL Branch with link */
61
reset_btype(s);
62
- gen_goto_tb(s, 0, diff);
63
+ gen_goto_tb(s, 0, a->imm);
64
+ return true;
65
+}
66
+
67
+static bool trans_BL(DisasContext *s, arg_i *a)
68
+{
69
+ gen_pc_plus_diff(s, cpu_reg(s, 30), curr_insn_len(s));
70
+ reset_btype(s);
71
+ gen_goto_tb(s, 0, a->imm);
72
+ return true;
73
}
74
75
/* Compare and branch (immediate)
76
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
77
static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
78
{
79
switch (extract32(insn, 25, 7)) {
80
- case 0x0a: case 0x0b:
81
- case 0x4a: case 0x4b: /* Unconditional branch (immediate) */
82
- disas_uncond_b_imm(s, insn);
83
- break;
84
case 0x1a: case 0x5a: /* Compare & branch (immediate) */
85
disas_comp_b_imm(s, insn);
86
break;
41
--
87
--
42
2.20.1
88
2.34.1
43
44
diff view generated by jsdifflib
1
Pushing registers to the stack for v7M needs to handle three cases:
1
Convert the compare-and-branch-immediate insns CBZ and CBNZ
2
* the "normal" case where we pend exceptions
2
to decodetree.
3
* an "ignore faults" case where we set FSR bits but
4
do not pend exceptions (this is used when we are
5
handling some kinds of derived exception on exception entry)
6
* a "lazy FP stacking" case, where different FSR bits
7
are set and the exception is pended differently
8
9
Implement this by changing the existing flag argument that
10
tells us whether to ignore faults or not into an enum that
11
specifies which of the 3 modes we should handle.
12
3
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20190416125744.27770-23-peter.maydell@linaro.org
6
Message-id: 20230512144106.3608981-15-peter.maydell@linaro.org
16
---
7
---
17
target/arm/helper.c | 118 +++++++++++++++++++++++++++++---------------
8
target/arm/tcg/a64.decode | 5 +++++
18
1 file changed, 79 insertions(+), 39 deletions(-)
9
target/arm/tcg/translate-a64.c | 26 ++++++--------------------
10
2 files changed, 11 insertions(+), 20 deletions(-)
19
11
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
21
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
14
--- a/target/arm/tcg/a64.decode
23
+++ b/target/arm/helper.c
15
+++ b/target/arm/tcg/a64.decode
24
@@ -XXX,XX +XXX,XX @@ static bool v7m_cpacr_pass(CPUARMState *env, bool is_secure, bool is_priv)
16
@@ -XXX,XX +XXX,XX @@ EXTR 0 00 100111 0 0 rm:5 0 imm:5 rn:5 rd:5 &extract sf=0
25
}
17
18
B 0 00101 .......................... @branch
19
BL 1 00101 .......................... @branch
20
+
21
+%imm19 5:s19 !function=times_4
22
+&cbz rt imm sf nz
23
+
24
+CBZ sf:1 011010 nz:1 ................... rt:5 &cbz imm=%imm19
25
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/tcg/translate-a64.c
28
+++ b/target/arm/tcg/translate-a64.c
29
@@ -XXX,XX +XXX,XX @@ static bool trans_BL(DisasContext *s, arg_i *a)
30
return true;
26
}
31
}
27
32
28
+/*
33
-/* Compare and branch (immediate)
29
+ * What kind of stack write are we doing? This affects how exceptions
34
- * 31 30 25 24 23 5 4 0
30
+ * generated during the stacking are treated.
35
- * +----+-------------+----+---------------------+--------+
31
+ */
36
- * | sf | 0 1 1 0 1 0 | op | imm19 | Rt |
32
+typedef enum StackingMode {
37
- * +----+-------------+----+---------------------+--------+
33
+ STACK_NORMAL,
38
- */
34
+ STACK_IGNFAULTS,
39
-static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
35
+ STACK_LAZYFP,
36
+} StackingMode;
37
+
40
+
38
static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
41
+static bool trans_CBZ(DisasContext *s, arg_cbz *a)
39
- ARMMMUIdx mmu_idx, bool ignfault)
40
+ ARMMMUIdx mmu_idx, StackingMode mode)
41
{
42
{
42
CPUState *cs = CPU(cpu);
43
- unsigned int sf, op, rt;
43
CPUARMState *env = &cpu->env;
44
- int64_t diff;
44
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
45
DisasLabel match;
45
&attrs, &prot, &page_size, &fi, NULL)) {
46
TCGv_i64 tcg_cmp;
46
/* MPU/SAU lookup failed */
47
47
if (fi.type == ARMFault_QEMU_SFault) {
48
- sf = extract32(insn, 31, 1);
48
- qemu_log_mask(CPU_LOG_INT,
49
- op = extract32(insn, 24, 1); /* 0: CBZ; 1: CBNZ */
49
- "...SecureFault with SFSR.AUVIOL during stacking\n");
50
- rt = extract32(insn, 0, 5);
50
- env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK | R_V7M_SFSR_SFARVALID_MASK;
51
- diff = sextract32(insn, 5, 19) * 4;
51
+ if (mode == STACK_LAZYFP) {
52
-
52
+ qemu_log_mask(CPU_LOG_INT,
53
- tcg_cmp = read_cpu_reg(s, rt, sf);
53
+ "...SecureFault with SFSR.LSPERR "
54
+ tcg_cmp = read_cpu_reg(s, a->rt, a->sf);
54
+ "during lazy stacking\n");
55
reset_btype(s);
55
+ env->v7m.sfsr |= R_V7M_SFSR_LSPERR_MASK;
56
56
+ } else {
57
match = gen_disas_label(s);
57
+ qemu_log_mask(CPU_LOG_INT,
58
- tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
58
+ "...SecureFault with SFSR.AUVIOL "
59
+ tcg_gen_brcondi_i64(a->nz ? TCG_COND_NE : TCG_COND_EQ,
59
+ "during stacking\n");
60
tcg_cmp, 0, match.label);
60
+ env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK;
61
gen_goto_tb(s, 0, 4);
61
+ }
62
set_disas_label(s, match);
62
+ env->v7m.sfsr |= R_V7M_SFSR_SFARVALID_MASK;
63
- gen_goto_tb(s, 1, diff);
63
env->v7m.sfar = addr;
64
+ gen_goto_tb(s, 1, a->imm);
64
exc = ARMV7M_EXCP_SECURE;
65
+ return true;
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
}
66
}
120
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
67
121
uint32_t limit;
68
/* Test and branch (immediate)
122
bool want_psp;
69
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
123
uint32_t sig;
70
static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
124
+ StackingMode smode = ignore_faults ? STACK_IGNFAULTS : STACK_NORMAL;
71
{
125
72
switch (extract32(insn, 25, 7)) {
126
if (dotailchain) {
73
- case 0x1a: case 0x5a: /* Compare & branch (immediate) */
127
bool mode = lr & R_V7M_EXCRET_MODE_MASK;
74
- disas_comp_b_imm(s, insn);
128
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
75
- break;
129
*/
76
case 0x1b: case 0x5b: /* Test & branch (immediate) */
130
sig = v7m_integrity_sig(env, lr);
77
disas_test_b_imm(s, insn);
131
stacked_ok =
78
break;
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
--
79
--
209
2.20.1
80
2.34.1
210
211
diff view generated by jsdifflib
1
Move the NS TBFLAG down from bit 19 to bit 6, which has not
1
Convert the test-and-branch-immediate insns TBZ and TBNZ
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: 20230512144106.3608981-16-peter.maydell@linaro.org
13
---
7
---
14
target/arm/cpu.h | 11 ++++++-----
8
target/arm/tcg/a64.decode | 6 ++++++
15
1 file changed, 6 insertions(+), 5 deletions(-)
9
target/arm/tcg/translate-a64.c | 25 +++++--------------------
10
2 files changed, 11 insertions(+), 20 deletions(-)
16
11
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
12
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
14
--- a/target/arm/tcg/a64.decode
20
+++ b/target/arm/cpu.h
15
+++ b/target/arm/tcg/a64.decode
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
16
@@ -XXX,XX +XXX,XX @@ BL 1 00101 .......................... @branch
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
17
&cbz rt imm sf nz
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
18
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
19
CBZ sf:1 011010 nz:1 ................... rt:5 &cbz imm=%imm19
25
+/*
20
+
26
+ * Indicates whether cp register reads and writes by guest code should access
21
+%imm14 5:s14 !function=times_4
27
+ * the secure or nonsecure bank of banked registers; note that this is not
22
+%imm31_19 31:1 19:5
28
+ * the same thing as the current security state of the processor!
23
+&tbz rt imm nz bitpos
29
+ */
24
+
30
+FIELD(TBFLAG_A32, NS, 6, 1)
25
+TBZ . 011011 nz:1 ..... .............. rt:5 &tbz imm=%imm14 bitpos=%imm31_19
31
FIELD(TBFLAG_A32, VFPEN, 7, 1)
26
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
32
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
27
index XXXXXXX..XXXXXXX 100644
33
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
28
--- a/target/arm/tcg/translate-a64.c
34
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
29
+++ b/target/arm/tcg/translate-a64.c
35
* checks on the other bits at runtime
30
@@ -XXX,XX +XXX,XX @@ static bool trans_CBZ(DisasContext *s, arg_cbz *a)
36
*/
31
return true;
37
FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
32
}
38
-/* Indicates whether cp register reads and writes by guest code should access
33
39
- * the secure or nonsecure bank of banked registers; note that this is not
34
-/* Test and branch (immediate)
40
- * the same thing as the current security state of the processor!
35
- * 31 30 25 24 23 19 18 5 4 0
36
- * +----+-------------+----+-------+-------------+------+
37
- * | b5 | 0 1 1 0 1 1 | op | b40 | imm14 | Rt |
38
- * +----+-------------+----+-------+-------------+------+
41
- */
39
- */
42
-FIELD(TBFLAG_A32, NS, 19, 1)
40
-static void disas_test_b_imm(DisasContext *s, uint32_t insn)
43
/* For M profile only, Handler (ie not Thread) mode */
41
+static bool trans_TBZ(DisasContext *s, arg_tbz *a)
44
FIELD(TBFLAG_A32, HANDLER, 21, 1)
42
{
45
/* For M profile only, whether we should generate stack-limit checks */
43
- unsigned int bit_pos, op, rt;
44
- int64_t diff;
45
DisasLabel match;
46
TCGv_i64 tcg_cmp;
47
48
- bit_pos = (extract32(insn, 31, 1) << 5) | extract32(insn, 19, 5);
49
- op = extract32(insn, 24, 1); /* 0: TBZ; 1: TBNZ */
50
- diff = sextract32(insn, 5, 14) * 4;
51
- rt = extract32(insn, 0, 5);
52
-
53
tcg_cmp = tcg_temp_new_i64();
54
- tcg_gen_andi_i64(tcg_cmp, cpu_reg(s, rt), (1ULL << bit_pos));
55
+ tcg_gen_andi_i64(tcg_cmp, cpu_reg(s, a->rt), 1ULL << a->bitpos);
56
57
reset_btype(s);
58
59
match = gen_disas_label(s);
60
- tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
61
+ tcg_gen_brcondi_i64(a->nz ? TCG_COND_NE : TCG_COND_EQ,
62
tcg_cmp, 0, match.label);
63
gen_goto_tb(s, 0, 4);
64
set_disas_label(s, match);
65
- gen_goto_tb(s, 1, diff);
66
+ gen_goto_tb(s, 1, a->imm);
67
+ return true;
68
}
69
70
/* Conditional branch (immediate)
71
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
72
static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
73
{
74
switch (extract32(insn, 25, 7)) {
75
- case 0x1b: case 0x5b: /* Test & branch (immediate) */
76
- disas_test_b_imm(s, insn);
77
- break;
78
case 0x2a: /* Conditional branch (immediate) */
79
disas_cond_b_imm(s, insn);
80
break;
46
--
81
--
47
2.20.1
82
2.34.1
48
49
diff view generated by jsdifflib
1
The M-profile architecture floating point system supports
1
Convert the immediate conditional branch insn B.cond to
2
lazy FP state preservation, where FP registers are not
2
decodetree.
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
3
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20190416125744.27770-24-peter.maydell@linaro.org
6
Message-id: 20230512144106.3608981-17-peter.maydell@linaro.org
11
---
7
---
12
target/arm/cpu.h | 3 ++
8
target/arm/tcg/a64.decode | 2 ++
13
target/arm/helper.h | 2 +
9
target/arm/tcg/translate-a64.c | 30 ++++++------------------------
14
target/arm/translate.h | 1 +
10
2 files changed, 8 insertions(+), 24 deletions(-)
15
target/arm/helper.c | 112 +++++++++++++++++++++++++++++++++++++++++
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/tcg/a64.decode b/target/arm/tcg/a64.decode
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
14
--- a/target/arm/tcg/a64.decode
22
+++ b/target/arm/cpu.h
15
+++ b/target/arm/tcg/a64.decode
23
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ CBZ sf:1 011010 nz:1 ................... rt:5 &cbz imm=%imm19
24
#define EXCP_NOCP 17 /* v7M NOCP UsageFault */
17
&tbz rt imm nz bitpos
25
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
18
26
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
19
TBZ . 011011 nz:1 ..... .............. rt:5 &tbz imm=%imm14 bitpos=%imm31_19
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
+B_cond 0101010 0 ................... 0 cond:4 imm=%imm19
29
22
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
30
#define ARMV7M_EXCP_RESET 1
31
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
32
FIELD(TBFLAG_A32, VFPEN, 7, 1)
33
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
34
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
35
+/* For M profile only, set if FPCCR.LSPACT is set */
36
+FIELD(TBFLAG_A32, LSPACT, 18, 1)
37
/* For M profile only, set if we must create a new FP context */
38
FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
39
/* For M profile only, set if FPCCR.S does not match current security state */
40
diff --git a/target/arm/helper.h b/target/arm/helper.h
41
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/helper.h
24
--- a/target/arm/tcg/translate-a64.c
43
+++ b/target/arm/helper.h
25
+++ b/target/arm/tcg/translate-a64.c
44
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(v7m_blxns, void, env, i32)
26
@@ -XXX,XX +XXX,XX @@ static bool trans_TBZ(DisasContext *s, arg_tbz *a)
45
27
return true;
46
DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
47
48
+DEF_HELPER_1(v7m_preserve_fp_state, void, env)
49
+
50
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
51
52
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
53
diff --git a/target/arm/translate.h b/target/arm/translate.h
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/translate.h
56
+++ b/target/arm/translate.h
57
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
58
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
59
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
60
bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
61
+ bool v7m_lspact; /* FPCCR.LSPACT set */
62
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
63
* so that top level loop can generate correct syndrome information.
64
*/
65
diff --git a/target/arm/helper.c b/target/arm/helper.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/helper.c
68
+++ b/target/arm/helper.c
69
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
70
g_assert_not_reached();
71
}
28
}
72
29
73
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
30
-/* Conditional branch (immediate)
74
+{
31
- * 31 25 24 23 5 4 3 0
75
+ /* translate.c should never generate calls here in user-only mode */
32
- * +---------------+----+---------------------+----+------+
76
+ g_assert_not_reached();
33
- * | 0 1 0 1 0 1 0 | o1 | imm19 | o0 | cond |
77
+}
34
- * +---------------+----+---------------------+----+------+
78
+
35
- */
79
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
36
-static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
37
+static bool trans_B_cond(DisasContext *s, arg_B_cond *a)
80
{
38
{
81
/* The TT instructions can be used by unprivileged code, but in
39
- unsigned int cond;
82
@@ -XXX,XX +XXX,XX @@ pend_fault:
40
- int64_t diff;
83
return false;
41
-
42
- if ((insn & (1 << 4)) || (insn & (1 << 24))) {
43
- unallocated_encoding(s);
44
- return;
45
- }
46
- diff = sextract32(insn, 5, 19) * 4;
47
- cond = extract32(insn, 0, 4);
48
-
49
reset_btype(s);
50
- if (cond < 0x0e) {
51
+ if (a->cond < 0x0e) {
52
/* genuinely conditional branches */
53
DisasLabel match = gen_disas_label(s);
54
- arm_gen_test_cc(cond, match.label);
55
+ arm_gen_test_cc(a->cond, match.label);
56
gen_goto_tb(s, 0, 4);
57
set_disas_label(s, match);
58
- gen_goto_tb(s, 1, diff);
59
+ gen_goto_tb(s, 1, a->imm);
60
} else {
61
/* 0xe and 0xf are both "always" conditions */
62
- gen_goto_tb(s, 0, diff);
63
+ gen_goto_tb(s, 0, a->imm);
64
}
65
+ return true;
84
}
66
}
85
67
86
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
68
/* HINT instruction group, including various allocated HINTs */
87
+{
69
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
88
+ /*
70
static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
89
+ * Preserve FP state (because LSPACT was set and we are about
71
{
90
+ * to execute an FP instruction). This corresponds to the
72
switch (extract32(insn, 25, 7)) {
91
+ * PreserveFPState() pseudocode.
73
- case 0x2a: /* Conditional branch (immediate) */
92
+ * We may throw an exception if the stacking fails.
74
- disas_cond_b_imm(s, insn);
93
+ */
75
- break;
94
+ ARMCPU *cpu = arm_env_get_cpu(env);
76
case 0x6a: /* Exception generation / System */
95
+ bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
77
if (insn & (1 << 24)) {
96
+ bool negpri = !(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_HFRDY_MASK);
78
if (extract32(insn, 22, 2) == 0) {
97
+ bool is_priv = !(env->v7m.fpccr[is_secure] & R_V7M_FPCCR_USER_MASK);
98
+ bool splimviol = env->v7m.fpccr[is_secure] & R_V7M_FPCCR_SPLIMVIOL_MASK;
99
+ uint32_t fpcar = env->v7m.fpcar[is_secure];
100
+ bool stacked_ok = true;
101
+ bool ts = is_secure && (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
102
+ bool take_exception;
103
+
104
+ /* Take the iothread lock as we are going to touch the NVIC */
105
+ qemu_mutex_lock_iothread();
106
+
107
+ /* Check the background context had access to the FPU */
108
+ if (!v7m_cpacr_pass(env, is_secure, is_priv)) {
109
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, is_secure);
110
+ env->v7m.cfsr[is_secure] |= R_V7M_CFSR_NOCP_MASK;
111
+ stacked_ok = false;
112
+ } else if (!is_secure && !extract32(env->v7m.nsacr, 10, 1)) {
113
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
114
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
115
+ stacked_ok = false;
116
+ }
117
+
118
+ if (!splimviol && stacked_ok) {
119
+ /* We only stack if the stack limit wasn't violated */
120
+ int i;
121
+ ARMMMUIdx mmu_idx;
122
+
123
+ mmu_idx = arm_v7m_mmu_idx_all(env, is_secure, is_priv, negpri);
124
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
125
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
126
+ uint32_t faddr = fpcar + 4 * i;
127
+ uint32_t slo = extract64(dn, 0, 32);
128
+ uint32_t shi = extract64(dn, 32, 32);
129
+
130
+ if (i >= 16) {
131
+ faddr += 8; /* skip the slot for the FPSCR */
132
+ }
133
+ stacked_ok = stacked_ok &&
134
+ v7m_stack_write(cpu, faddr, slo, mmu_idx, STACK_LAZYFP) &&
135
+ v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, STACK_LAZYFP);
136
+ }
137
+
138
+ stacked_ok = stacked_ok &&
139
+ v7m_stack_write(cpu, fpcar + 0x40,
140
+ vfp_get_fpscr(env), mmu_idx, STACK_LAZYFP);
141
+ }
142
+
143
+ /*
144
+ * We definitely pended an exception, but it's possible that it
145
+ * might not be able to be taken now. If its priority permits us
146
+ * to take it now, then we must not update the LSPACT or FP regs,
147
+ * but instead jump out to take the exception immediately.
148
+ * If it's just pending and won't be taken until the current
149
+ * handler exits, then we do update LSPACT and the FP regs.
150
+ */
151
+ take_exception = !stacked_ok &&
152
+ armv7m_nvic_can_take_pending_exception(env->nvic);
153
+
154
+ qemu_mutex_unlock_iothread();
155
+
156
+ if (take_exception) {
157
+ raise_exception_ra(env, EXCP_LAZYFP, 0, 1, GETPC());
158
+ }
159
+
160
+ env->v7m.fpccr[is_secure] &= ~R_V7M_FPCCR_LSPACT_MASK;
161
+
162
+ if (ts) {
163
+ /* Clear s0 to s31 and the FPSCR */
164
+ int i;
165
+
166
+ for (i = 0; i < 32; i += 2) {
167
+ *aa32_vfp_dreg(env, i / 2) = 0;
168
+ }
169
+ vfp_set_fpscr(env, 0);
170
+ }
171
+ /*
172
+ * Otherwise s0 to s15 and FPSCR are UNKNOWN; we choose to leave them
173
+ * unchanged.
174
+ */
175
+}
176
+
177
/* Write to v7M CONTROL.SPSEL bit for the specified security bank.
178
* This may change the current stack pointer between Main and Process
179
* stack pointers if it is done for the CONTROL register for the current
180
@@ -XXX,XX +XXX,XX @@ static void arm_log_exception(int idx)
181
[EXCP_NOCP] = "v7M NOCP UsageFault",
182
[EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
183
[EXCP_STKOF] = "v8M STKOF UsageFault",
184
+ [EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
185
};
186
187
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
188
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
189
return;
190
}
191
break;
192
+ case EXCP_LAZYFP:
193
+ /*
194
+ * We already pended the specific exception in the NVIC in the
195
+ * v7m_preserve_fp_state() helper function.
196
+ */
197
+ break;
198
default:
199
cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
200
return; /* Never happens. Keep compiler happy. */
201
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
202
flags = FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED, 1);
203
}
204
205
+ if (arm_feature(env, ARM_FEATURE_M)) {
206
+ bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
207
+
208
+ if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) {
209
+ flags = FIELD_DP32(flags, TBFLAG_A32, LSPACT, 1);
210
+ }
211
+ }
212
+
213
*pflags = flags;
214
*cs_base = 0;
215
}
216
diff --git a/target/arm/translate.c b/target/arm/translate.c
217
index XXXXXXX..XXXXXXX 100644
218
--- a/target/arm/translate.c
219
+++ b/target/arm/translate.c
220
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
221
if (arm_dc_feature(s, ARM_FEATURE_M)) {
222
/* Handle M-profile lazy FP state mechanics */
223
224
+ /* Trigger lazy-state preservation if necessary */
225
+ if (s->v7m_lspact) {
226
+ /*
227
+ * Lazy state saving affects external memory and also the NVIC,
228
+ * so we must mark it as an IO operation for icount.
229
+ */
230
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
231
+ gen_io_start();
232
+ }
233
+ gen_helper_v7m_preserve_fp_state(cpu_env);
234
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
235
+ gen_io_end();
236
+ }
237
+ /*
238
+ * If the preserve_fp_state helper doesn't throw an exception
239
+ * then it will clear LSPACT; we don't need to repeat this for
240
+ * any further FP insns in this TB.
241
+ */
242
+ s->v7m_lspact = false;
243
+ }
244
+
245
/* Update ownership of FP context: set FPCCR.S to match current state */
246
if (s->v8m_fpccr_s_wrong) {
247
TCGv_i32 tmp;
248
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
249
dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
250
dc->v7m_new_fp_ctxt_needed =
251
FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
252
+ dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_A32, LSPACT);
253
dc->cp_regs = cpu->cp_regs;
254
dc->features = env->features;
255
256
--
79
--
257
2.20.1
80
2.34.1
258
259
diff view generated by jsdifflib
1
Like AArch64, M-profile floating point has no FPEXC enable
1
Convert the simple (non-pointer-auth) BR, BLR and RET insns
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: 20230512144106.3608981-18-peter.maydell@linaro.org
19
---
7
---
20
target/arm/helper.c | 55 +++++++++++++++++++++++++++++++++++++++---
8
target/arm/tcg/a64.decode | 5 ++++
21
target/arm/translate.c | 10 ++++++--
9
target/arm/tcg/translate-a64.c | 55 ++++++++++++++++++++++++++++++----
22
2 files changed, 60 insertions(+), 5 deletions(-)
10
2 files changed, 54 insertions(+), 6 deletions(-)
23
11
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
25
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.c
14
--- a/target/arm/tcg/a64.decode
27
+++ b/target/arm/helper.c
15
+++ b/target/arm/tcg/a64.decode
28
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
16
@@ -XXX,XX +XXX,XX @@
29
return target_el;
17
# This file is processed by scripts/decodetree.py
18
#
19
20
+&r rn
21
&ri rd imm
22
&rri_sf rd rn imm sf
23
&i imm
24
@@ -XXX,XX +XXX,XX @@ CBZ sf:1 011010 nz:1 ................... rt:5 &cbz imm=%imm19
25
TBZ . 011011 nz:1 ..... .............. rt:5 &tbz imm=%imm14 bitpos=%imm31_19
26
27
B_cond 0101010 0 ................... 0 cond:4 imm=%imm19
28
+
29
+BR 1101011 0000 11111 000000 rn:5 00000 &r
30
+BLR 1101011 0001 11111 000000 rn:5 00000 &r
31
+RET 1101011 0010 11111 000000 rn:5 00000 &r
32
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/tcg/translate-a64.c
35
+++ b/target/arm/tcg/translate-a64.c
36
@@ -XXX,XX +XXX,XX @@ static bool trans_B_cond(DisasContext *s, arg_B_cond *a)
37
return true;
30
}
38
}
31
39
32
+/*
40
+static void set_btype_for_br(DisasContext *s, int rn)
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
+{
41
+{
38
+ switch (extract32(env->v7m.cpacr[is_secure], 20, 2)) {
42
+ if (dc_isar_feature(aa64_bti, s)) {
39
+ case 0:
43
+ /* BR to {x16,x17} or !guard -> 1, else 3. */
40
+ case 2: /* UNPREDICTABLE: we treat like 0 */
44
+ set_btype(s, rn == 16 || rn == 17 || !s->guarded_page ? 1 : 3);
41
+ return false;
42
+ case 1:
43
+ return is_priv;
44
+ case 3:
45
+ return true;
46
+ default:
47
+ g_assert_not_reached();
48
+ }
45
+ }
49
+}
46
+}
50
+
47
+
51
static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
48
+static void set_btype_for_blr(DisasContext *s)
52
ARMMMUIdx mmu_idx, bool ignfault)
49
+{
53
{
50
+ if (dc_isar_feature(aa64_bti, s)) {
54
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
51
+ /* BLR sets BTYPE to 2, regardless of source guarded page. */
55
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNDEFINSTR_MASK;
52
+ set_btype(s, 2);
56
break;
53
+ }
57
case EXCP_NOCP:
54
+}
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
+
55
+
68
+ if (env->exception.target_el == 3) {
56
+static bool trans_BR(DisasContext *s, arg_r *a)
69
+ target_secstate = M_REG_S;
57
+{
70
+ } else {
58
+ gen_a64_set_pc(s, cpu_reg(s, a->rn));
71
+ target_secstate = env->v7m.secure;
59
+ set_btype_for_br(s, a->rn);
72
+ }
60
+ s->base.is_jmp = DISAS_JUMP;
73
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, target_secstate);
61
+ return true;
74
+ env->v7m.cfsr[target_secstate] |= R_V7M_CFSR_NOCP_MASK;
62
+}
75
break;
63
+
64
+static bool trans_BLR(DisasContext *s, arg_r *a)
65
+{
66
+ TCGv_i64 dst = cpu_reg(s, a->rn);
67
+ TCGv_i64 lr = cpu_reg(s, 30);
68
+ if (dst == lr) {
69
+ TCGv_i64 tmp = tcg_temp_new_i64();
70
+ tcg_gen_mov_i64(tmp, dst);
71
+ dst = tmp;
76
+ }
72
+ }
77
case EXCP_INVSTATE:
73
+ gen_pc_plus_diff(s, lr, curr_insn_len(s));
78
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
74
+ gen_a64_set_pc(s, dst);
79
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVSTATE_MASK;
75
+ set_btype_for_blr(s);
80
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
76
+ s->base.is_jmp = DISAS_JUMP;
81
return 0;
77
+ return true;
82
}
78
+}
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
+
79
+
90
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) && !env->v7m.secure) {
80
+static bool trans_RET(DisasContext *s, arg_r *a)
91
+ if (!extract32(env->v7m.nsacr, 10, 1)) {
81
+{
92
+ /* FP insns cause a NOCP UsageFault taken to Secure */
82
+ gen_a64_set_pc(s, cpu_reg(s, a->rn));
93
+ return 3;
83
+ s->base.is_jmp = DISAS_JUMP;
94
+ }
84
+ return true;
95
+ }
85
+}
96
+
86
+
97
+ return 0;
87
/* HINT instruction group, including various allocated HINTs */
98
+ }
88
static void handle_hint(DisasContext *s, uint32_t insn,
99
+
89
unsigned int op1, unsigned int op2, unsigned int crm)
100
/* The CPACR controls traps to EL1, or PL1 if we're 32 bit:
90
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
101
* 0, 2 : trap EL0 and EL1/PL1 accesses
91
btype_mod = opc;
102
* 1 : trap only EL0 accesses
92
switch (op3) {
103
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
93
case 0:
104
flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, arm_sctlr_b(env));
94
- /* BR, BLR, RET */
105
flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
95
- if (op4 != 0) {
106
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
96
- goto do_unallocated;
107
- || arm_el_is_aa64(env, 1)) {
97
- }
108
+ || arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
98
- dst = cpu_reg(s, rn);
109
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
99
- break;
110
}
100
+ /* BR, BLR, RET : handled in decodetree */
111
flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
101
+ goto do_unallocated;
112
diff --git a/target/arm/translate.c b/target/arm/translate.c
102
113
index XXXXXXX..XXXXXXX 100644
103
case 2:
114
--- a/target/arm/translate.c
104
case 3:
115
+++ b/target/arm/translate.c
116
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
117
* for attempts to execute invalid vfp/neon encodings with FP disabled.
118
*/
119
if (s->fp_excp_el) {
120
- gen_exception_insn(s, 4, EXCP_UDEF,
121
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
122
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
123
+ gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
124
+ s->fp_excp_el);
125
+ } else {
126
+ gen_exception_insn(s, 4, EXCP_UDEF,
127
+ syn_fp_access_trap(1, 0xe, false),
128
+ s->fp_excp_el);
129
+ }
130
return 0;
131
}
132
133
--
105
--
134
2.20.1
106
2.34.1
135
136
diff view generated by jsdifflib
Deleted patch
1
Correct the decode of the M-profile "coprocessor and
2
floating-point instructions" space:
3
* op0 == 0b11 is always unallocated
4
* if the CPU has an FPU then all insns with op1 == 0b101
5
are floating point and go to disas_vfp_insn()
6
1
7
For the moment we leave VLLDM and VLSTM as NOPs; in
8
a later commit we will fill in the proper implementation
9
for the case where an FPU is present.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20190416125744.27770-7-peter.maydell@linaro.org
14
---
15
target/arm/translate.c | 26 ++++++++++++++++++++++----
16
1 file changed, 22 insertions(+), 4 deletions(-)
17
18
diff --git a/target/arm/translate.c b/target/arm/translate.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate.c
21
+++ b/target/arm/translate.c
22
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
23
case 6: case 7: case 14: case 15:
24
/* Coprocessor. */
25
if (arm_dc_feature(s, ARM_FEATURE_M)) {
26
- /* We don't currently implement M profile FP support,
27
- * so this entire space should give a NOCP fault, with
28
- * the exception of the v8M VLLDM and VLSTM insns, which
29
- * must be NOPs in Secure state and UNDEF in Nonsecure state.
30
+ /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
31
+ if (extract32(insn, 24, 2) == 3) {
32
+ goto illegal_op; /* op0 = 0b11 : unallocated */
33
+ }
34
+
35
+ /*
36
+ * Decode VLLDM and VLSTM first: these are nonstandard because:
37
+ * * if there is no FPU then these insns must NOP in
38
+ * Secure state and UNDEF in Nonsecure state
39
+ * * if there is an FPU then these insns do not have
40
+ * the usual behaviour that disas_vfp_insn() provides of
41
+ * being controlled by CPACR/NSACR enable bits or the
42
+ * lazy-stacking logic.
43
*/
44
if (arm_dc_feature(s, ARM_FEATURE_V8) &&
45
(insn & 0xffa00f00) == 0xec200a00) {
46
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
47
/* Just NOP since FP support is not implemented */
48
break;
49
}
50
+ if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
51
+ ((insn >> 8) & 0xe) == 10) {
52
+ /* FP, and the CPU supports it */
53
+ if (disas_vfp_insn(s, insn)) {
54
+ goto illegal_op;
55
+ }
56
+ break;
57
+ }
58
+
59
/* All other insns: NOCP */
60
gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
61
default_exception_el(s));
62
--
63
2.20.1
64
65
diff view generated by jsdifflib
Deleted patch
1
If the floating point extension is present, then the SG instruction
2
must clear the CONTROL_S.SFPA bit. Implement this.
3
1
4
(On a no-FPU system the bit will always be zero, so we don't need
5
to make the clearing of the bit conditional on ARM_FEATURE_VFP.)
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-8-peter.maydell@linaro.org
10
---
11
target/arm/helper.c | 1 +
12
1 file changed, 1 insertion(+)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
19
qemu_log_mask(CPU_LOG_INT, "...really an SG instruction at 0x%08" PRIx32
20
", executing it\n", env->regs[15]);
21
env->regs[14] &= ~1;
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
23
switch_v7m_security_state(env, true);
24
xpsr_write(env, 0, XPSR_IT);
25
env->regs[15] += 4;
26
--
27
2.20.1
28
29
diff view generated by jsdifflib
Deleted patch
1
The M-profile CONTROL register has two bits -- SFPA and FPCA --
2
which relate to floating-point support, and should be RES0 otherwise.
3
Handle them correctly in the MSR/MRS register access code.
4
Neither is banked between security states, so they are stored
5
in v7m.control[M_REG_S] regardless of current security state.
6
1
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-9-peter.maydell@linaro.org
10
---
11
target/arm/helper.c | 57 ++++++++++++++++++++++++++++++++++++++-------
12
1 file changed, 49 insertions(+), 8 deletions(-)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
19
return xpsr_read(env) & mask;
20
break;
21
case 20: /* CONTROL */
22
- return env->v7m.control[env->v7m.secure];
23
+ {
24
+ uint32_t value = env->v7m.control[env->v7m.secure];
25
+ if (!env->v7m.secure) {
26
+ /* SFPA is RAZ/WI from NS; FPCA is stored in the M_REG_S bank */
27
+ value |= env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK;
28
+ }
29
+ return value;
30
+ }
31
case 0x94: /* CONTROL_NS */
32
/* We have to handle this here because unprivileged Secure code
33
* can read the NS CONTROL register.
34
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
35
if (!env->v7m.secure) {
36
return 0;
37
}
38
- return env->v7m.control[M_REG_NS];
39
+ return env->v7m.control[M_REG_NS] |
40
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK);
41
}
42
43
if (el == 0) {
44
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
45
*/
46
uint32_t mask = extract32(maskreg, 8, 4);
47
uint32_t reg = extract32(maskreg, 0, 8);
48
+ int cur_el = arm_current_el(env);
49
50
- if (arm_current_el(env) == 0 && reg > 7) {
51
- /* only xPSR sub-fields may be written by unprivileged */
52
+ if (cur_el == 0 && reg > 7 && reg != 20) {
53
+ /*
54
+ * only xPSR sub-fields and CONTROL.SFPA may be written by
55
+ * unprivileged code
56
+ */
57
return;
58
}
59
60
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
61
env->v7m.control[M_REG_NS] &= ~R_V7M_CONTROL_NPRIV_MASK;
62
env->v7m.control[M_REG_NS] |= val & R_V7M_CONTROL_NPRIV_MASK;
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
--
123
2.20.1
124
125
diff view generated by jsdifflib
Deleted patch
1
Handle floating point registers in exception entry.
2
This corresponds to the FP-specific parts of the pseudocode
3
functions ActivateException() and PushStack().
4
1
5
We defer the code corresponding to UpdateFPCCR() to a later patch.
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-11-peter.maydell@linaro.org
10
---
11
target/arm/helper.c | 98 +++++++++++++++++++++++++++++++++++++++++++--
12
1 file changed, 95 insertions(+), 3 deletions(-)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
19
switch_v7m_security_state(env, targets_secure);
20
write_v7m_control_spsel(env, 0);
21
arm_clear_exclusive(env);
22
+ /* Clear SFPA and FPCA (has no effect if no FPU) */
23
+ env->v7m.control[M_REG_S] &=
24
+ ~(R_V7M_CONTROL_FPCA_MASK | R_V7M_CONTROL_SFPA_MASK);
25
/* Clear IT bits */
26
env->condexec_bits = 0;
27
env->regs[14] = lr;
28
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
29
uint32_t xpsr = xpsr_read(env);
30
uint32_t frameptr = env->regs[13];
31
ARMMMUIdx mmu_idx = arm_mmu_idx(env);
32
+ uint32_t framesize;
33
+ bool nsacr_cp10 = extract32(env->v7m.nsacr, 10, 1);
34
+
35
+ if ((env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) &&
36
+ (env->v7m.secure || nsacr_cp10)) {
37
+ if (env->v7m.secure &&
38
+ env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK) {
39
+ framesize = 0xa8;
40
+ } else {
41
+ framesize = 0x68;
42
+ }
43
+ } else {
44
+ framesize = 0x20;
45
+ }
46
47
/* Align stack pointer if the guest wants that */
48
if ((frameptr & 4) &&
49
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
50
xpsr |= XPSR_SPREALIGN;
51
}
52
53
- frameptr -= 0x20;
54
+ xpsr &= ~XPSR_SFPA;
55
+ if (env->v7m.secure &&
56
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
57
+ xpsr |= XPSR_SFPA;
58
+ }
59
+
60
+ frameptr -= framesize;
61
62
if (arm_feature(env, ARM_FEATURE_V8)) {
63
uint32_t limit = v7m_sp_limit(env);
64
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
65
v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
66
v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
67
68
+ if (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) {
69
+ /* FPU is active, try to save its registers */
70
+ bool fpccr_s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
71
+ bool lspact = env->v7m.fpccr[fpccr_s] & R_V7M_FPCCR_LSPACT_MASK;
72
+
73
+ if (lspact && arm_feature(env, ARM_FEATURE_M_SECURITY)) {
74
+ qemu_log_mask(CPU_LOG_INT,
75
+ "...SecureFault because LSPACT and FPCA both set\n");
76
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
77
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
78
+ } else if (!env->v7m.secure && !nsacr_cp10) {
79
+ qemu_log_mask(CPU_LOG_INT,
80
+ "...Secure UsageFault with CFSR.NOCP because "
81
+ "NSACR.CP10 prevents stacking FP regs\n");
82
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
83
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
84
+ } else {
85
+ if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) {
86
+ /* Lazy stacking disabled, save registers now */
87
+ int i;
88
+ bool cpacr_pass = v7m_cpacr_pass(env, env->v7m.secure,
89
+ arm_current_el(env) != 0);
90
+
91
+ if (stacked_ok && !cpacr_pass) {
92
+ /*
93
+ * Take UsageFault if CPACR forbids access. The pseudocode
94
+ * here does a full CheckCPEnabled() but we know the NSACR
95
+ * check can never fail as we have already handled that.
96
+ */
97
+ qemu_log_mask(CPU_LOG_INT,
98
+ "...UsageFault with CFSR.NOCP because "
99
+ "CPACR.CP10 prevents stacking FP regs\n");
100
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
101
+ env->v7m.secure);
102
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_NOCP_MASK;
103
+ stacked_ok = false;
104
+ }
105
+
106
+ for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
107
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
108
+ uint32_t faddr = frameptr + 0x20 + 4 * i;
109
+ uint32_t slo = extract64(dn, 0, 32);
110
+ uint32_t shi = extract64(dn, 32, 32);
111
+
112
+ if (i >= 16) {
113
+ faddr += 8; /* skip the slot for the FPSCR */
114
+ }
115
+ stacked_ok = stacked_ok &&
116
+ v7m_stack_write(cpu, faddr, slo, mmu_idx, false) &&
117
+ v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, false);
118
+ }
119
+ stacked_ok = stacked_ok &&
120
+ v7m_stack_write(cpu, frameptr + 0x60,
121
+ vfp_get_fpscr(env), mmu_idx, false);
122
+ if (cpacr_pass) {
123
+ for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
124
+ *aa32_vfp_dreg(env, i / 2) = 0;
125
+ }
126
+ vfp_set_fpscr(env, 0);
127
+ }
128
+ } else {
129
+ /* Lazy stacking enabled, save necessary info to stack later */
130
+ /* TODO : equivalent of UpdateFPCCR() pseudocode */
131
+ }
132
+ }
133
+ }
134
+
135
/*
136
* If we broke a stack limit then SP was already updated earlier;
137
* otherwise we update SP regardless of whether any of the stack
138
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
139
140
if (arm_feature(env, ARM_FEATURE_V8)) {
141
lr = R_V7M_EXCRET_RES1_MASK |
142
- R_V7M_EXCRET_DCRS_MASK |
143
- R_V7M_EXCRET_FTYPE_MASK;
144
+ R_V7M_EXCRET_DCRS_MASK;
145
/* The S bit indicates whether we should return to Secure
146
* or NonSecure (ie our current state).
147
* The ES bit indicates whether we're taking this exception
148
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
149
if (env->v7m.secure) {
150
lr |= R_V7M_EXCRET_S_MASK;
151
}
152
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
153
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
154
+ }
155
} else {
156
lr = R_V7M_EXCRET_RES1_MASK |
157
R_V7M_EXCRET_S_MASK |
158
--
159
2.20.1
160
161
diff view generated by jsdifflib
Deleted patch
1
For v8M floating point support, transitions from Secure
2
to Non-secure state via BLNS and BLXNS must clear the
3
CONTROL.SFPA bit. (This corresponds to the pseudocode
4
BranchToNS() function.)
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-13-peter.maydell@linaro.org
9
---
10
target/arm/helper.c | 4 ++++
11
1 file changed, 4 insertions(+)
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest)
18
/* translate.c should have made BXNS UNDEF unless we're secure */
19
assert(env->v7m.secure);
20
21
+ if (!(dest & 1)) {
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
23
+ }
24
switch_v7m_security_state(env, dest & 1);
25
env->thumb = 1;
26
env->regs[15] = dest & ~1;
27
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
28
*/
29
write_v7m_exception(env, 1);
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
--
36
2.20.1
37
38
diff view generated by jsdifflib
Deleted patch
1
The TailChain() pseudocode specifies that a tail chaining
2
exception should sanitize the excReturn all-ones bits and
3
(if there is no FPU) the excReturn FType bits; we weren't
4
doing this.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-14-peter.maydell@linaro.org
9
---
10
target/arm/helper.c | 8 ++++++++
11
1 file changed, 8 insertions(+)
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
18
qemu_log_mask(CPU_LOG_INT, "...taking pending %s exception %d\n",
19
targets_secure ? "secure" : "nonsecure", exc);
20
21
+ if (dotailchain) {
22
+ /* Sanitize LR FType and PREFIX bits */
23
+ if (!arm_feature(env, ARM_FEATURE_VFP)) {
24
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
25
+ }
26
+ lr = deposit32(lr, 24, 8, 0xff);
27
+ }
28
+
29
if (arm_feature(env, ARM_FEATURE_V8)) {
30
if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
31
(lr & R_V7M_EXCRET_S_MASK)) {
32
--
33
2.20.1
34
35
diff view generated by jsdifflib
1
Implement the VLLDM instruction for v7M for the FPU present cas.
1
Convert the single-register pointer-authentication variants of BR,
2
BLR, RET to decodetree. (BRAA/BLRAA are in a different branch of
3
the legacy decoder and will be dealt with in the next commit.)
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-26-peter.maydell@linaro.org
7
Message-id: 20230512144106.3608981-19-peter.maydell@linaro.org
6
---
8
---
7
target/arm/helper.h | 1 +
9
target/arm/tcg/a64.decode | 7 ++
8
target/arm/helper.c | 54 ++++++++++++++++++++++++++++++++++++++++++
10
target/arm/tcg/translate-a64.c | 132 +++++++++++++++++++--------------
9
target/arm/translate.c | 2 +-
11
2 files changed, 84 insertions(+), 55 deletions(-)
10
3 files changed, 56 insertions(+), 1 deletion(-)
11
12
12
diff --git a/target/arm/helper.h b/target/arm/helper.h
13
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
13
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.h
15
--- a/target/arm/tcg/a64.decode
15
+++ b/target/arm/helper.h
16
+++ b/target/arm/tcg/a64.decode
16
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
17
@@ -XXX,XX +XXX,XX @@ B_cond 0101010 0 ................... 0 cond:4 imm=%imm19
17
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
18
BR 1101011 0000 11111 000000 rn:5 00000 &r
18
19
BLR 1101011 0001 11111 000000 rn:5 00000 &r
19
DEF_HELPER_2(v7m_vlstm, void, env, i32)
20
RET 1101011 0010 11111 000000 rn:5 00000 &r
20
+DEF_HELPER_2(v7m_vlldm, void, env, i32)
21
+
21
22
+&braz rn m
22
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
23
+BRAZ 1101011 0000 11111 00001 m:1 rn:5 11111 &braz # BRAAZ, BRABZ
23
24
+BLRAZ 1101011 0001 11111 00001 m:1 rn:5 11111 &braz # BLRAAZ, BLRABZ
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
25
+
26
+&reta m
27
+RETA 1101011 0010 11111 00001 m:1 11111 11111 &reta # RETAA, RETAB
28
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
25
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.c
30
--- a/target/arm/tcg/translate-a64.c
27
+++ b/target/arm/helper.c
31
+++ b/target/arm/tcg/translate-a64.c
28
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
32
@@ -XXX,XX +XXX,XX @@ static bool trans_RET(DisasContext *s, arg_r *a)
29
g_assert_not_reached();
33
return true;
30
}
34
}
31
35
32
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
36
+static TCGv_i64 auth_branch_target(DisasContext *s, TCGv_i64 dst,
37
+ TCGv_i64 modifier, bool use_key_a)
33
+{
38
+{
34
+ /* translate.c should never generate calls here in user-only mode */
39
+ TCGv_i64 truedst;
35
+ g_assert_not_reached();
40
+ /*
41
+ * Return the branch target for a BRAA/RETA/etc, which is either
42
+ * just the destination dst, or that value with the pauth check
43
+ * done and the code removed from the high bits.
44
+ */
45
+ if (!s->pauth_active) {
46
+ return dst;
47
+ }
48
+
49
+ truedst = tcg_temp_new_i64();
50
+ if (use_key_a) {
51
+ gen_helper_autia(truedst, cpu_env, dst, modifier);
52
+ } else {
53
+ gen_helper_autib(truedst, cpu_env, dst, modifier);
54
+ }
55
+ return truedst;
36
+}
56
+}
37
+
57
+
38
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
58
+static bool trans_BRAZ(DisasContext *s, arg_braz *a)
39
{
40
/* The TT instructions can be used by unprivileged code, but in
41
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
42
env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
43
}
44
45
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
46
+{
59
+{
47
+ /* fptr is the value of Rn, the frame pointer we load the FP regs from */
60
+ TCGv_i64 dst;
48
+ assert(env->v7m.secure);
49
+
61
+
50
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
62
+ if (!dc_isar_feature(aa64_pauth, s)) {
51
+ return;
63
+ return false;
52
+ }
64
+ }
53
+
65
+
54
+ /* Check access to the coprocessor is permitted */
66
+ dst = auth_branch_target(s, cpu_reg(s, a->rn), tcg_constant_i64(0), !a->m);
55
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
67
+ gen_a64_set_pc(s, dst);
56
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
68
+ set_btype_for_br(s, a->rn);
69
+ s->base.is_jmp = DISAS_JUMP;
70
+ return true;
71
+}
72
+
73
+static bool trans_BLRAZ(DisasContext *s, arg_braz *a)
74
+{
75
+ TCGv_i64 dst, lr;
76
+
77
+ if (!dc_isar_feature(aa64_pauth, s)) {
78
+ return false;
57
+ }
79
+ }
58
+
80
+
59
+ if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
81
+ dst = auth_branch_target(s, cpu_reg(s, a->rn), tcg_constant_i64(0), !a->m);
60
+ /* State in FP is still valid */
82
+ lr = cpu_reg(s, 30);
61
+ env->v7m.fpccr[M_REG_S] &= ~R_V7M_FPCCR_LSPACT_MASK;
83
+ if (dst == lr) {
62
+ } else {
84
+ TCGv_i64 tmp = tcg_temp_new_i64();
63
+ bool ts = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK;
85
+ tcg_gen_mov_i64(tmp, dst);
64
+ int i;
86
+ dst = tmp;
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
+ }
87
+ }
89
+
88
+ gen_pc_plus_diff(s, lr, curr_insn_len(s));
90
+ env->v7m.control[M_REG_S] |= R_V7M_CONTROL_FPCA_MASK;
89
+ gen_a64_set_pc(s, dst);
90
+ set_btype_for_blr(s);
91
+ s->base.is_jmp = DISAS_JUMP;
92
+ return true;
91
+}
93
+}
92
+
94
+
93
static bool v7m_push_stack(ARMCPU *cpu)
95
+static bool trans_RETA(DisasContext *s, arg_reta *a)
94
{
96
+{
95
/* Do the "set up stack frame" part of exception entry,
97
+ TCGv_i64 dst;
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
98
+
97
index XXXXXXX..XXXXXXX 100644
99
+ dst = auth_branch_target(s, cpu_reg(s, 30), cpu_X[31], !a->m);
98
--- a/target/arm/translate.c
100
+ gen_a64_set_pc(s, dst);
99
+++ b/target/arm/translate.c
101
+ s->base.is_jmp = DISAS_JUMP;
100
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
102
+ return true;
101
TCGv_i32 fptr = load_reg(s, rn);
103
+}
102
104
+
103
if (extract32(insn, 20, 1)) {
105
/* HINT instruction group, including various allocated HINTs */
104
- /* VLLDM */
106
static void handle_hint(DisasContext *s, uint32_t insn,
105
+ gen_helper_v7m_vlldm(cpu_env, fptr);
107
unsigned int op1, unsigned int op2, unsigned int crm)
106
} else {
108
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
107
gen_helper_v7m_vlstm(cpu_env, fptr);
109
}
108
}
110
111
switch (opc) {
112
- case 0: /* BR */
113
- case 1: /* BLR */
114
- case 2: /* RET */
115
- btype_mod = opc;
116
- switch (op3) {
117
- case 0:
118
- /* BR, BLR, RET : handled in decodetree */
119
- goto do_unallocated;
120
-
121
- case 2:
122
- case 3:
123
- if (!dc_isar_feature(aa64_pauth, s)) {
124
- goto do_unallocated;
125
- }
126
- if (opc == 2) {
127
- /* RETAA, RETAB */
128
- if (rn != 0x1f || op4 != 0x1f) {
129
- goto do_unallocated;
130
- }
131
- rn = 30;
132
- modifier = cpu_X[31];
133
- } else {
134
- /* BRAAZ, BRABZ, BLRAAZ, BLRABZ */
135
- if (op4 != 0x1f) {
136
- goto do_unallocated;
137
- }
138
- modifier = tcg_constant_i64(0);
139
- }
140
- if (s->pauth_active) {
141
- dst = tcg_temp_new_i64();
142
- if (op3 == 2) {
143
- gen_helper_autia(dst, cpu_env, cpu_reg(s, rn), modifier);
144
- } else {
145
- gen_helper_autib(dst, cpu_env, cpu_reg(s, rn), modifier);
146
- }
147
- } else {
148
- dst = cpu_reg(s, rn);
149
- }
150
- break;
151
-
152
- default:
153
- goto do_unallocated;
154
- }
155
- /* BLR also needs to load return address */
156
- if (opc == 1) {
157
- TCGv_i64 lr = cpu_reg(s, 30);
158
- if (dst == lr) {
159
- TCGv_i64 tmp = tcg_temp_new_i64();
160
- tcg_gen_mov_i64(tmp, dst);
161
- dst = tmp;
162
- }
163
- gen_pc_plus_diff(s, lr, curr_insn_len(s));
164
- }
165
- gen_a64_set_pc(s, dst);
166
- break;
167
+ case 0:
168
+ case 1:
169
+ case 2:
170
+ /*
171
+ * BR, BLR, RET, RETAA, RETAB, BRAAZ, BRABZ, BLRAAZ, BLRABZ:
172
+ * handled in decodetree
173
+ */
174
+ goto do_unallocated;
175
176
case 8: /* BRAA */
177
case 9: /* BLRAA */
109
--
178
--
110
2.20.1
179
2.34.1
111
112
diff view generated by jsdifflib
1
The magic value pushed onto the callee stack as an integrity
1
Convert the last four BR-with-pointer-auth insns to decodetree.
2
check is different if floating point is present.
2
The remaining cases in the outer switch in disas_uncond_b_reg()
3
all return early rather than leaving the case statement, so we
4
can delete the now-unused code at the end of that function.
3
5
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20190416125744.27770-15-peter.maydell@linaro.org
8
Message-id: 20230512144106.3608981-20-peter.maydell@linaro.org
7
---
9
---
8
target/arm/helper.c | 22 +++++++++++++++++++---
10
target/arm/tcg/a64.decode | 4 ++
9
1 file changed, 19 insertions(+), 3 deletions(-)
11
target/arm/tcg/translate-a64.c | 97 ++++++++++++++--------------------
12
2 files changed, 43 insertions(+), 58 deletions(-)
10
13
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
16
--- a/target/arm/tcg/a64.decode
14
+++ b/target/arm/helper.c
17
+++ b/target/arm/tcg/a64.decode
15
@@ -XXX,XX +XXX,XX @@ load_fail:
18
@@ -XXX,XX +XXX,XX @@ BLRAZ 1101011 0001 11111 00001 m:1 rn:5 11111 &braz # BLRAAZ, BLRABZ
16
return false;
19
20
&reta m
21
RETA 1101011 0010 11111 00001 m:1 11111 11111 &reta # RETAA, RETAB
22
+
23
+&bra rn rm m
24
+BRA 1101011 1000 11111 00001 m:1 rn:5 rm:5 &bra # BRAA, BRAB
25
+BLRA 1101011 1001 11111 00001 m:1 rn:5 rm:5 &bra # BLRAA, BLRAB
26
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/tcg/translate-a64.c
29
+++ b/target/arm/tcg/translate-a64.c
30
@@ -XXX,XX +XXX,XX @@ static bool trans_RETA(DisasContext *s, arg_reta *a)
31
return true;
17
}
32
}
18
33
19
+static uint32_t v7m_integrity_sig(CPUARMState *env, uint32_t lr)
34
+static bool trans_BRA(DisasContext *s, arg_bra *a)
20
+{
35
+{
21
+ /*
36
+ TCGv_i64 dst;
22
+ * Return the integrity signature value for the callee-saves
23
+ * stack frame section. @lr is the exception return payload/LR value
24
+ * whose FType bit forms bit 0 of the signature if FP is present.
25
+ */
26
+ uint32_t sig = 0xfefa125a;
27
+
37
+
28
+ if (!arm_feature(env, ARM_FEATURE_VFP) || (lr & R_V7M_EXCRET_FTYPE_MASK)) {
38
+ if (!dc_isar_feature(aa64_pauth, s)) {
29
+ sig |= 1;
39
+ return false;
30
+ }
40
+ }
31
+ return sig;
41
+ dst = auth_branch_target(s, cpu_reg(s,a->rn), cpu_reg_sp(s, a->rm), !a->m);
42
+ gen_a64_set_pc(s, dst);
43
+ set_btype_for_br(s, a->rn);
44
+ s->base.is_jmp = DISAS_JUMP;
45
+ return true;
32
+}
46
+}
33
+
47
+
34
static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
48
+static bool trans_BLRA(DisasContext *s, arg_bra *a)
35
bool ignore_faults)
49
+{
50
+ TCGv_i64 dst, lr;
51
+
52
+ if (!dc_isar_feature(aa64_pauth, s)) {
53
+ return false;
54
+ }
55
+ dst = auth_branch_target(s, cpu_reg(s, a->rn), cpu_reg_sp(s, a->rm), !a->m);
56
+ lr = cpu_reg(s, 30);
57
+ if (dst == lr) {
58
+ TCGv_i64 tmp = tcg_temp_new_i64();
59
+ tcg_gen_mov_i64(tmp, dst);
60
+ dst = tmp;
61
+ }
62
+ gen_pc_plus_diff(s, lr, curr_insn_len(s));
63
+ gen_a64_set_pc(s, dst);
64
+ set_btype_for_blr(s);
65
+ s->base.is_jmp = DISAS_JUMP;
66
+ return true;
67
+}
68
+
69
/* HINT instruction group, including various allocated HINTs */
70
static void handle_hint(DisasContext *s, uint32_t insn,
71
unsigned int op1, unsigned int op2, unsigned int crm)
72
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
73
static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
36
{
74
{
37
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
75
unsigned int opc, op2, op3, rn, op4;
38
bool stacked_ok;
76
- unsigned btype_mod = 2; /* 0: BR, 1: BLR, 2: other */
39
uint32_t limit;
77
TCGv_i64 dst;
40
bool want_psp;
78
TCGv_i64 modifier;
41
+ uint32_t sig;
79
42
80
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
43
if (dotailchain) {
81
case 0:
44
bool mode = lr & R_V7M_EXCRET_MODE_MASK;
82
case 1:
45
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
83
case 2:
46
/* Write as much of the stack frame as we can. A write failure may
84
+ case 8:
47
* cause us to pend a derived exception.
85
+ case 9:
48
*/
86
/*
49
+ sig = v7m_integrity_sig(env, lr);
87
- * BR, BLR, RET, RETAA, RETAB, BRAAZ, BRABZ, BLRAAZ, BLRABZ:
50
stacked_ok =
88
- * handled in decodetree
51
- v7m_stack_write(cpu, frameptr, 0xfefa125b, mmu_idx, ignore_faults) &&
89
+ * BR, BLR, RET, RETAA, RETAB, BRAAZ, BRABZ, BLRAAZ, BLRABZ,
52
+ v7m_stack_write(cpu, frameptr, sig, mmu_idx, ignore_faults) &&
90
+ * BRAA, BLRAA: handled in decodetree
53
v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
91
*/
54
ignore_faults) &&
92
goto do_unallocated;
55
v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
93
56
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
94
- case 8: /* BRAA */
57
if (return_to_secure &&
95
- case 9: /* BLRAA */
58
((excret & R_V7M_EXCRET_ES_MASK) == 0 ||
96
- if (!dc_isar_feature(aa64_pauth, s)) {
59
(excret & R_V7M_EXCRET_DCRS_MASK) == 0)) {
97
- goto do_unallocated;
60
- uint32_t expected_sig = 0xfefa125b;
98
- }
61
uint32_t actual_sig;
99
- if ((op3 & ~1) != 2) {
62
100
- goto do_unallocated;
63
pop_ok = v7m_stack_read(cpu, &actual_sig, frameptr, mmu_idx);
101
- }
64
102
- btype_mod = opc & 1;
65
- if (pop_ok && expected_sig != actual_sig) {
103
- if (s->pauth_active) {
66
+ if (pop_ok && v7m_integrity_sig(env, excret) != actual_sig) {
104
- dst = tcg_temp_new_i64();
67
/* Take a SecureFault on the current stack */
105
- modifier = cpu_reg_sp(s, op4);
68
env->v7m.sfsr |= R_V7M_SFSR_INVIS_MASK;
106
- if (op3 == 2) {
69
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
107
- gen_helper_autia(dst, cpu_env, cpu_reg(s, rn), modifier);
108
- } else {
109
- gen_helper_autib(dst, cpu_env, cpu_reg(s, rn), modifier);
110
- }
111
- } else {
112
- dst = cpu_reg(s, rn);
113
- }
114
- /* BLRAA also needs to load return address */
115
- if (opc == 9) {
116
- TCGv_i64 lr = cpu_reg(s, 30);
117
- if (dst == lr) {
118
- TCGv_i64 tmp = tcg_temp_new_i64();
119
- tcg_gen_mov_i64(tmp, dst);
120
- dst = tmp;
121
- }
122
- gen_pc_plus_diff(s, lr, curr_insn_len(s));
123
- }
124
- gen_a64_set_pc(s, dst);
125
- break;
126
-
127
case 4: /* ERET */
128
if (s->current_el == 0) {
129
goto do_unallocated;
130
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
131
unallocated_encoding(s);
132
return;
133
}
134
-
135
- switch (btype_mod) {
136
- case 0: /* BR */
137
- if (dc_isar_feature(aa64_bti, s)) {
138
- /* BR to {x16,x17} or !guard -> 1, else 3. */
139
- set_btype(s, rn == 16 || rn == 17 || !s->guarded_page ? 1 : 3);
140
- }
141
- break;
142
-
143
- case 1: /* BLR */
144
- if (dc_isar_feature(aa64_bti, s)) {
145
- /* BLR sets BTYPE to 2, regardless of source guarded page. */
146
- set_btype(s, 2);
147
- }
148
- break;
149
-
150
- default: /* RET or none of the above. */
151
- /* BTYPE will be set to 0 by normal end-of-insn processing. */
152
- break;
153
- }
154
-
155
- s->base.is_jmp = DISAS_JUMP;
156
}
157
158
/* Branches, exception generating and system instructions */
70
--
159
--
71
2.20.1
160
2.34.1
72
73
diff view generated by jsdifflib
1
Implement the VLSTM instruction for v7M for the FPU present case.
1
Convert the exception-return insns ERET, ERETA and ERETB to
2
decodetree. These were the last insns left in the legacy
3
decoder function disas_uncond_reg_b(), which allows us to
4
remove it.
5
6
The old decoder explicitly decoded the DRPS instruction,
7
only in order to call unallocated_encoding() on it, exactly
8
as would have happened if it hadn't decoded it. This is
9
because this insn always UNDEFs unless the CPU is in
10
halting-debug state, which we don't emulate. So we list
11
the pattern in a comment in a64.decode, but don't actively
12
decode it.
2
13
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-25-peter.maydell@linaro.org
16
Message-id: 20230512144106.3608981-21-peter.maydell@linaro.org
6
---
17
---
7
target/arm/cpu.h | 2 +
18
target/arm/tcg/a64.decode | 8 ++
8
target/arm/helper.h | 2 +
19
target/arm/tcg/translate-a64.c | 163 +++++++++++----------------------
9
target/arm/helper.c | 84 ++++++++++++++++++++++++++++++++++++++++++
20
2 files changed, 63 insertions(+), 108 deletions(-)
10
target/arm/translate.c | 15 +++++++-
11
4 files changed, 102 insertions(+), 1 deletion(-)
12
21
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
14
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
24
--- a/target/arm/tcg/a64.decode
16
+++ b/target/arm/cpu.h
25
+++ b/target/arm/tcg/a64.decode
17
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@ RETA 1101011 0010 11111 00001 m:1 11111 11111 &reta # RETAA, RETAB
18
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
27
&bra rn rm m
19
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
28
BRA 1101011 1000 11111 00001 m:1 rn:5 rm:5 &bra # BRAA, BRAB
20
#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
29
BLRA 1101011 1001 11111 00001 m:1 rn:5 rm:5 &bra # BLRAA, BLRAB
21
+#define EXCP_LSERR 21 /* v8M LSERR SecureFault */
30
+
22
+#define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */
31
+ERET 1101011 0100 11111 000000 11111 00000
23
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
32
+ERETA 1101011 0100 11111 00001 m:1 11111 11111 &reta # ERETAA, ERETAB
24
33
+
25
#define ARMV7M_EXCP_RESET 1
34
+# We don't need to decode DRPS because it always UNDEFs except when
26
diff --git a/target/arm/helper.h b/target/arm/helper.h
35
+# the processor is in halting debug state (which we don't implement).
36
+# The pattern is listed here as documentation.
37
+# DRPS 1101011 0101 11111 000000 11111 00000
38
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
27
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/helper.h
40
--- a/target/arm/tcg/translate-a64.c
29
+++ b/target/arm/helper.h
41
+++ b/target/arm/tcg/translate-a64.c
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
42
@@ -XXX,XX +XXX,XX @@ static bool trans_BLRA(DisasContext *s, arg_bra *a)
31
43
return true;
32
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
33
34
+DEF_HELPER_2(v7m_vlstm, void, env, i32)
35
+
36
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
37
38
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
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
}
44
}
46
45
47
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
46
+static bool trans_ERET(DisasContext *s, arg_ERET *a)
48
+{
47
+{
49
+ /* translate.c should never generate calls here in user-only mode */
48
+ TCGv_i64 dst;
50
+ g_assert_not_reached();
49
+
50
+ if (s->current_el == 0) {
51
+ return false;
52
+ }
53
+ if (s->fgt_eret) {
54
+ gen_exception_insn_el(s, 0, EXCP_UDEF, 0, 2);
55
+ return true;
56
+ }
57
+ dst = tcg_temp_new_i64();
58
+ tcg_gen_ld_i64(dst, cpu_env,
59
+ offsetof(CPUARMState, elr_el[s->current_el]));
60
+
61
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
62
+ gen_io_start();
63
+ }
64
+
65
+ gen_helper_exception_return(cpu_env, dst);
66
+ /* Must exit loop to check un-masked IRQs */
67
+ s->base.is_jmp = DISAS_EXIT;
68
+ return true;
51
+}
69
+}
52
+
70
+
53
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
71
+static bool trans_ERETA(DisasContext *s, arg_reta *a)
54
{
72
+{
55
/* The TT instructions can be used by unprivileged code, but in
73
+ TCGv_i64 dst;
56
@@ -XXX,XX +XXX,XX @@ static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
74
+
75
+ if (!dc_isar_feature(aa64_pauth, s)) {
76
+ return false;
77
+ }
78
+ if (s->current_el == 0) {
79
+ return false;
80
+ }
81
+ /* The FGT trap takes precedence over an auth trap. */
82
+ if (s->fgt_eret) {
83
+ gen_exception_insn_el(s, 0, EXCP_UDEF, a->m ? 3 : 2, 2);
84
+ return true;
85
+ }
86
+ dst = tcg_temp_new_i64();
87
+ tcg_gen_ld_i64(dst, cpu_env,
88
+ offsetof(CPUARMState, elr_el[s->current_el]));
89
+
90
+ dst = auth_branch_target(s, dst, cpu_X[31], !a->m);
91
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
92
+ gen_io_start();
93
+ }
94
+
95
+ gen_helper_exception_return(cpu_env, dst);
96
+ /* Must exit loop to check un-masked IRQs */
97
+ s->base.is_jmp = DISAS_EXIT;
98
+ return true;
99
+}
100
+
101
/* HINT instruction group, including various allocated HINTs */
102
static void handle_hint(DisasContext *s, uint32_t insn,
103
unsigned int op1, unsigned int op2, unsigned int crm)
104
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
57
}
105
}
58
}
106
}
59
107
60
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
108
-/* Unconditional branch (register)
61
+{
109
- * 31 25 24 21 20 16 15 10 9 5 4 0
62
+ /* fptr is the value of Rn, the frame pointer we store the FP regs to */
110
- * +---------------+-------+-------+-------+------+-------+
63
+ bool s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
111
- * | 1 1 0 1 0 1 1 | opc | op2 | op3 | Rn | op4 |
64
+ bool lspact = env->v7m.fpccr[s] & R_V7M_FPCCR_LSPACT_MASK;
112
- * +---------------+-------+-------+-------+------+-------+
65
+
113
- */
66
+ assert(env->v7m.secure);
114
-static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
67
+
115
-{
68
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
116
- unsigned int opc, op2, op3, rn, op4;
69
+ return;
117
- TCGv_i64 dst;
70
+ }
118
- TCGv_i64 modifier;
71
+
119
-
72
+ /* Check access to the coprocessor is permitted */
120
- opc = extract32(insn, 21, 4);
73
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
121
- op2 = extract32(insn, 16, 5);
74
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
122
- op3 = extract32(insn, 10, 6);
75
+ }
123
- rn = extract32(insn, 5, 5);
76
+
124
- op4 = extract32(insn, 0, 5);
77
+ if (lspact) {
125
-
78
+ /* LSPACT should not be active when there is active FP state */
126
- if (op2 != 0x1f) {
79
+ raise_exception_ra(env, EXCP_LSERR, 0, 1, GETPC());
127
- goto do_unallocated;
80
+ }
128
- }
81
+
129
-
82
+ if (fptr & 7) {
130
- switch (opc) {
83
+ raise_exception_ra(env, EXCP_UNALIGNED, 0, 1, GETPC());
131
- case 0:
84
+ }
132
- case 1:
85
+
133
- case 2:
86
+ /*
134
- case 8:
87
+ * Note that we do not use v7m_stack_write() here, because the
135
- case 9:
88
+ * accesses should not set the FSR bits for stacking errors if they
136
- /*
89
+ * fail. (In pseudocode terms, they are AccType_NORMAL, not AccType_STACK
137
- * BR, BLR, RET, RETAA, RETAB, BRAAZ, BRABZ, BLRAAZ, BLRABZ,
90
+ * or AccType_LAZYFP). Faults in cpu_stl_data() will throw exceptions
138
- * BRAA, BLRAA: handled in decodetree
91
+ * and longjmp out.
139
- */
92
+ */
140
- goto do_unallocated;
93
+ if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) {
141
-
94
+ bool ts = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK;
142
- case 4: /* ERET */
95
+ int i;
143
- if (s->current_el == 0) {
96
+
144
- goto do_unallocated;
97
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
145
- }
98
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
146
- switch (op3) {
99
+ uint32_t faddr = fptr + 4 * i;
147
- case 0: /* ERET */
100
+ uint32_t slo = extract64(dn, 0, 32);
148
- if (op4 != 0) {
101
+ uint32_t shi = extract64(dn, 32, 32);
149
- goto do_unallocated;
102
+
150
- }
103
+ if (i >= 16) {
151
- if (s->fgt_eret) {
104
+ faddr += 8; /* skip the slot for the FPSCR */
152
- gen_exception_insn_el(s, 0, EXCP_UDEF, syn_erettrap(op3), 2);
105
+ }
153
- return;
106
+ cpu_stl_data(env, faddr, slo);
154
- }
107
+ cpu_stl_data(env, faddr + 4, shi);
155
- dst = tcg_temp_new_i64();
108
+ }
156
- tcg_gen_ld_i64(dst, cpu_env,
109
+ cpu_stl_data(env, fptr + 0x40, vfp_get_fpscr(env));
157
- offsetof(CPUARMState, elr_el[s->current_el]));
110
+
158
- break;
111
+ /*
159
-
112
+ * If TS is 0 then s0 to s15 and FPSCR are UNKNOWN; we choose to
160
- case 2: /* ERETAA */
113
+ * leave them unchanged, matching our choice in v7m_preserve_fp_state.
161
- case 3: /* ERETAB */
114
+ */
162
- if (!dc_isar_feature(aa64_pauth, s)) {
115
+ if (ts) {
163
- goto do_unallocated;
116
+ for (i = 0; i < 32; i += 2) {
164
- }
117
+ *aa32_vfp_dreg(env, i / 2) = 0;
165
- if (rn != 0x1f || op4 != 0x1f) {
118
+ }
166
- goto do_unallocated;
119
+ vfp_set_fpscr(env, 0);
167
- }
120
+ }
168
- /* The FGT trap takes precedence over an auth trap. */
121
+ } else {
169
- if (s->fgt_eret) {
122
+ v7m_update_fpccr(env, fptr, false);
170
- gen_exception_insn_el(s, 0, EXCP_UDEF, syn_erettrap(op3), 2);
123
+ }
171
- return;
124
+
172
- }
125
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
173
- dst = tcg_temp_new_i64();
126
+}
174
- tcg_gen_ld_i64(dst, cpu_env,
127
+
175
- offsetof(CPUARMState, elr_el[s->current_el]));
128
static bool v7m_push_stack(ARMCPU *cpu)
176
- if (s->pauth_active) {
177
- modifier = cpu_X[31];
178
- if (op3 == 2) {
179
- gen_helper_autia(dst, cpu_env, dst, modifier);
180
- } else {
181
- gen_helper_autib(dst, cpu_env, dst, modifier);
182
- }
183
- }
184
- break;
185
-
186
- default:
187
- goto do_unallocated;
188
- }
189
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
190
- gen_io_start();
191
- }
192
-
193
- gen_helper_exception_return(cpu_env, dst);
194
- /* Must exit loop to check un-masked IRQs */
195
- s->base.is_jmp = DISAS_EXIT;
196
- return;
197
-
198
- case 5: /* DRPS */
199
- if (op3 != 0 || op4 != 0 || rn != 0x1f) {
200
- goto do_unallocated;
201
- } else {
202
- unallocated_encoding(s);
203
- }
204
- return;
205
-
206
- default:
207
- do_unallocated:
208
- unallocated_encoding(s);
209
- return;
210
- }
211
-}
212
-
213
/* Branches, exception generating and system instructions */
214
static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
129
{
215
{
130
/* Do the "set up stack frame" part of exception entry,
216
@@ -XXX,XX +XXX,XX @@ static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
131
@@ -XXX,XX +XXX,XX @@ static void arm_log_exception(int idx)
217
disas_exc(s, insn);
132
[EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
218
}
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;
219
break;
144
+ case EXCP_LSERR:
220
- case 0x6b: /* Unconditional branch (register) */
145
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
221
- disas_uncond_b_reg(s, insn);
146
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
222
- break;
147
+ break;
223
default:
148
+ case EXCP_UNALIGNED:
224
unallocated_encoding(s);
149
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
225
break;
150
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNALIGNED_MASK;
151
+ break;
152
case EXCP_SWI:
153
/* The PC already points to the next instruction. */
154
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC, env->v7m.secure);
155
diff --git a/target/arm/translate.c b/target/arm/translate.c
156
index XXXXXXX..XXXXXXX 100644
157
--- a/target/arm/translate.c
158
+++ b/target/arm/translate.c
159
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
160
if (!s->v8m_secure || (insn & 0x0040f0ff)) {
161
goto illegal_op;
162
}
163
- /* Just NOP since FP support is not implemented */
164
+
165
+ if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
166
+ TCGv_i32 fptr = load_reg(s, rn);
167
+
168
+ if (extract32(insn, 20, 1)) {
169
+ /* VLLDM */
170
+ } else {
171
+ gen_helper_v7m_vlstm(cpu_env, fptr);
172
+ }
173
+ tcg_temp_free_i32(fptr);
174
+
175
+ /* End the TB, because we have updated FP control bits */
176
+ s->base.is_jmp = DISAS_UPDATE;
177
+ }
178
break;
179
}
180
if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
181
--
226
--
182
2.20.1
227
2.34.1
183
184
diff view generated by jsdifflib
1
Handle floating point registers in exception return.
1
The IMPDEF sysreg L2CTLR_EL1 found on the Cortex-A35, A53, A57, A72
2
This corresponds to pseudocode functions ValidateExceptionReturn(),
2
and which we (arguably dubiously) also provide in '-cpu max' has a
3
ExceptionReturn(), PopStack() and ConsumeExcStackFrame().
3
2 bit field for the number of processors in the cluster. On real
4
hardware this must be sufficient because it can only be configured
5
with up to 4 CPUs in the cluster. However on QEMU if the board code
6
does not explicitly configure the code into clusters with the right
7
CPU count we default to "give the value assuming that all CPUs in
8
the system are in a single cluster", which might be too big to fit
9
in the field.
10
11
Instead of just overflowing this 2-bit field, saturate to 3 (meaning
12
"4 CPUs", so at least we don't overwrite other fields in the register.
13
It's unlikely that any guest code really cares about the value in
14
this field; at least, if it does it probably also wants the system
15
to be more closely matching real hardware, i.e. not to have more
16
than 4 CPUs.
17
18
This issue has been present since the L2CTLR was first added in
19
commit 377a44ec8f2fac5b back in 2014. It was only noticed because
20
Coverity complains (CID 1509227) that the shift might overflow 32 bits
21
and inadvertently sign extend into the top half of the 64 bit value.
4
22
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190416125744.27770-16-peter.maydell@linaro.org
25
Message-id: 20230512170223.3801643-2-peter.maydell@linaro.org
8
---
26
---
9
target/arm/helper.c | 142 +++++++++++++++++++++++++++++++++++++++++++-
27
target/arm/cortex-regs.c | 11 +++++++++--
10
1 file changed, 141 insertions(+), 1 deletion(-)
28
1 file changed, 9 insertions(+), 2 deletions(-)
11
29
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
30
diff --git a/target/arm/cortex-regs.c b/target/arm/cortex-regs.c
13
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
32
--- a/target/arm/cortex-regs.c
15
+++ b/target/arm/helper.c
33
+++ b/target/arm/cortex-regs.c
16
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
34
@@ -XXX,XX +XXX,XX @@ static uint64_t l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
17
bool rettobase = false;
35
{
18
bool exc_secure = false;
36
ARMCPU *cpu = env_archcpu(env);
19
bool return_to_secure;
37
20
+ bool ftype;
38
- /* Number of cores is in [25:24]; otherwise we RAZ */
21
+ bool restore_s16_s31;
39
- return (cpu->core_count - 1) << 24;
22
23
/* If we're not in Handler mode then jumps to magic exception-exit
24
* addresses don't have magic behaviour. However for the v8M
25
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
26
excret);
27
}
28
29
+ ftype = excret & R_V7M_EXCRET_FTYPE_MASK;
30
+
31
+ if (!arm_feature(env, ARM_FEATURE_VFP) && !ftype) {
32
+ qemu_log_mask(LOG_GUEST_ERROR, "M profile: zero FTYPE in exception "
33
+ "exit PC value 0x%" PRIx32 " is UNPREDICTABLE "
34
+ "if FPU not present\n",
35
+ excret);
36
+ ftype = true;
37
+ }
38
+
39
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
40
/* EXC_RETURN.ES validation check (R_SMFL). We must do this before
41
* we pick which FAULTMASK to clear.
42
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
43
*/
44
write_v7m_control_spsel_for_secstate(env, return_to_sp_process, exc_secure);
45
46
+ /*
40
+ /*
47
+ * Clear scratch FP values left in caller saved registers; this
41
+ * Number of cores is in [25:24]; otherwise we RAZ.
48
+ * must happen before any kind of tail chaining.
42
+ * If the board didn't configure the CPUs into clusters,
43
+ * we default to "all CPUs in one cluster", which might be
44
+ * more than the 4 that the hardware permits and which is
45
+ * all you can report in this two-bit field. Saturate to
46
+ * 0b11 (== 4 CPUs) rather than overflowing the field.
49
+ */
47
+ */
50
+ if ((env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_CLRONRET_MASK) &&
48
+ return MIN(cpu->core_count - 1, 3) << 24;
51
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
49
}
52
+ if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
50
53
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
51
static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = {
54
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
55
+ qemu_log_mask(CPU_LOG_INT, "...taking SecureFault on existing "
56
+ "stackframe: error during lazy state deactivation\n");
57
+ v7m_exception_taken(cpu, excret, true, false);
58
+ return;
59
+ } else {
60
+ /* Clear s0..s15 and FPSCR */
61
+ int i;
62
+
63
+ for (i = 0; i < 16; i += 2) {
64
+ *aa32_vfp_dreg(env, i / 2) = 0;
65
+ }
66
+ vfp_set_fpscr(env, 0);
67
+ }
68
+ }
69
+
70
if (sfault) {
71
env->v7m.sfsr |= R_V7M_SFSR_INVER_MASK;
72
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
73
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
74
}
75
}
76
77
+ if (!ftype) {
78
+ /* FP present and we need to handle it */
79
+ if (!return_to_secure &&
80
+ (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK)) {
81
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
82
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
83
+ qemu_log_mask(CPU_LOG_INT,
84
+ "...taking SecureFault on existing stackframe: "
85
+ "Secure LSPACT set but exception return is "
86
+ "not to secure state\n");
87
+ v7m_exception_taken(cpu, excret, true, false);
88
+ return;
89
+ }
90
+
91
+ restore_s16_s31 = return_to_secure &&
92
+ (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
93
+
94
+ if (env->v7m.fpccr[return_to_secure] & R_V7M_FPCCR_LSPACT_MASK) {
95
+ /* State in FPU is still valid, just clear LSPACT */
96
+ env->v7m.fpccr[return_to_secure] &= ~R_V7M_FPCCR_LSPACT_MASK;
97
+ } else {
98
+ int i;
99
+ uint32_t fpscr;
100
+ bool cpacr_pass, nsacr_pass;
101
+
102
+ cpacr_pass = v7m_cpacr_pass(env, return_to_secure,
103
+ return_to_priv);
104
+ nsacr_pass = return_to_secure ||
105
+ extract32(env->v7m.nsacr, 10, 1);
106
+
107
+ if (!cpacr_pass) {
108
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
109
+ return_to_secure);
110
+ env->v7m.cfsr[return_to_secure] |= R_V7M_CFSR_NOCP_MASK;
111
+ qemu_log_mask(CPU_LOG_INT,
112
+ "...taking UsageFault on existing "
113
+ "stackframe: CPACR.CP10 prevents unstacking "
114
+ "FP regs\n");
115
+ v7m_exception_taken(cpu, excret, true, false);
116
+ return;
117
+ } else if (!nsacr_pass) {
118
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, true);
119
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_INVPC_MASK;
120
+ qemu_log_mask(CPU_LOG_INT,
121
+ "...taking Secure UsageFault on existing "
122
+ "stackframe: NSACR.CP10 prevents unstacking "
123
+ "FP regs\n");
124
+ v7m_exception_taken(cpu, excret, true, false);
125
+ return;
126
+ }
127
+
128
+ for (i = 0; i < (restore_s16_s31 ? 32 : 16); i += 2) {
129
+ uint32_t slo, shi;
130
+ uint64_t dn;
131
+ uint32_t faddr = frameptr + 0x20 + 4 * i;
132
+
133
+ if (i >= 16) {
134
+ faddr += 8; /* Skip the slot for the FPSCR */
135
+ }
136
+
137
+ pop_ok = pop_ok &&
138
+ v7m_stack_read(cpu, &slo, faddr, mmu_idx) &&
139
+ v7m_stack_read(cpu, &shi, faddr + 4, mmu_idx);
140
+
141
+ if (!pop_ok) {
142
+ break;
143
+ }
144
+
145
+ dn = (uint64_t)shi << 32 | slo;
146
+ *aa32_vfp_dreg(env, i / 2) = dn;
147
+ }
148
+ pop_ok = pop_ok &&
149
+ v7m_stack_read(cpu, &fpscr, frameptr + 0x60, mmu_idx);
150
+ if (pop_ok) {
151
+ vfp_set_fpscr(env, fpscr);
152
+ }
153
+ if (!pop_ok) {
154
+ /*
155
+ * These regs are 0 if security extension present;
156
+ * otherwise merely UNKNOWN. We zero always.
157
+ */
158
+ for (i = 0; i < (restore_s16_s31 ? 32 : 16); i += 2) {
159
+ *aa32_vfp_dreg(env, i / 2) = 0;
160
+ }
161
+ vfp_set_fpscr(env, 0);
162
+ }
163
+ }
164
+ }
165
+ env->v7m.control[M_REG_S] = FIELD_DP32(env->v7m.control[M_REG_S],
166
+ V7M_CONTROL, FPCA, !ftype);
167
+
168
/* Commit to consuming the stack frame */
169
frameptr += 0x20;
170
+ if (!ftype) {
171
+ frameptr += 0x48;
172
+ if (restore_s16_s31) {
173
+ frameptr += 0x40;
174
+ }
175
+ }
176
/* Undo stack alignment (the SPREALIGN bit indicates that the original
177
* pre-exception SP was not 8-aligned and we added a padding word to
178
* align it, so we undo this by ORing in the bit that increases it
179
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
180
*frame_sp_p = frameptr;
181
}
182
/* This xpsr_write() will invalidate frame_sp_p as it may switch stack */
183
- xpsr_write(env, xpsr, ~XPSR_SPREALIGN);
184
+ xpsr_write(env, xpsr, ~(XPSR_SPREALIGN | XPSR_SFPA));
185
+
186
+ if (env->v7m.secure) {
187
+ bool sfpa = xpsr & XPSR_SFPA;
188
+
189
+ env->v7m.control[M_REG_S] = FIELD_DP32(env->v7m.control[M_REG_S],
190
+ V7M_CONTROL, SFPA, sfpa);
191
+ }
192
193
/* The restored xPSR exception field will be zero if we're
194
* resuming in Thread mode. If that doesn't match what the
195
--
52
--
196
2.20.1
53
2.34.1
197
198
diff view generated by jsdifflib
1
Add a new helper function which returns the MMU index to use
1
In the vexpress board code, we allocate a new MemoryRegion at the top
2
for v7M, where the caller specifies all of the security
2
of vexpress_common_init() but only set it up and use it inside the
3
state, privilege level and whether the execution priority
3
"if (map[VE_NORFLASHALIAS] != -1)" conditional, so we leak it if not.
4
is negative, and reimplement the existing
4
This isn't a very interesting leak as it's a tiny amount of memory
5
arm_v7m_mmu_idx_for_secstate_and_priv() in terms of it.
5
once at startup, but it's easy to fix.
6
6
7
We are going to need this for the lazy-FP-stacking code.
7
We could silence Coverity simply by moving the g_new() into the
8
if() block, but this use of g_new(MemoryRegion, 1) is a legacy from
9
when this board model was originally written; we wouldn't do that
10
if we wrote it today. The MemoryRegions are conceptually a part of
11
the board and must not go away until the whole board is done with
12
(at the end of the simulation), so they belong in its state struct.
13
14
This machine already has a VexpressMachineState struct that extends
15
MachineState, so statically put the MemoryRegions in there instead of
16
dynamically allocating them separately at runtime.
17
18
Spotted by Coverity (CID 1509083).
8
19
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20190416125744.27770-21-peter.maydell@linaro.org
22
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
23
Message-id: 20230512170223.3801643-3-peter.maydell@linaro.org
12
---
24
---
13
target/arm/cpu.h | 7 +++++++
25
hw/arm/vexpress.c | 40 ++++++++++++++++++++--------------------
14
target/arm/helper.c | 14 +++++++++++---
26
1 file changed, 20 insertions(+), 20 deletions(-)
15
2 files changed, 18 insertions(+), 3 deletions(-)
16
27
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
28
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
18
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
30
--- a/hw/arm/vexpress.c
20
+++ b/target/arm/cpu.h
31
+++ b/hw/arm/vexpress.c
21
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
32
@@ -XXX,XX +XXX,XX @@ struct VexpressMachineClass {
33
34
struct VexpressMachineState {
35
MachineState parent;
36
+ MemoryRegion vram;
37
+ MemoryRegion sram;
38
+ MemoryRegion flashalias;
39
+ MemoryRegion lowram;
40
+ MemoryRegion a15sram;
41
bool secure;
42
bool virt;
43
};
44
@@ -XXX,XX +XXX,XX @@ struct VexpressMachineState {
45
#define TYPE_VEXPRESS_A15_MACHINE MACHINE_TYPE_NAME("vexpress-a15")
46
OBJECT_DECLARE_TYPE(VexpressMachineState, VexpressMachineClass, VEXPRESS_MACHINE)
47
48
-typedef void DBoardInitFn(const VexpressMachineState *machine,
49
+typedef void DBoardInitFn(VexpressMachineState *machine,
50
ram_addr_t ram_size,
51
const char *cpu_type,
52
qemu_irq *pic);
53
@@ -XXX,XX +XXX,XX @@ static void init_cpus(MachineState *ms, const char *cpu_type,
22
}
54
}
23
}
55
}
24
56
25
+/*
57
-static void a9_daughterboard_init(const VexpressMachineState *vms,
26
+ * Return the MMU index for a v7M CPU with all relevant information
58
+static void a9_daughterboard_init(VexpressMachineState *vms,
27
+ * manually specified.
59
ram_addr_t ram_size,
28
+ */
60
const char *cpu_type,
29
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
61
qemu_irq *pic)
30
+ bool secstate, bool priv, bool negpri);
31
+
32
/* Return the MMU index for a v7M CPU in the specified security and
33
* privilege state.
34
*/
35
diff --git a/target/arm/helper.c b/target/arm/helper.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper.c
38
+++ b/target/arm/helper.c
39
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
40
return 0;
41
}
42
43
-ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
44
- bool secstate, bool priv)
45
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
46
+ bool secstate, bool priv, bool negpri)
47
{
62
{
48
ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
63
MachineState *machine = MACHINE(vms);
49
64
MemoryRegion *sysmem = get_system_memory();
50
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
65
- MemoryRegion *lowram = g_new(MemoryRegion, 1);
51
mmu_idx |= ARM_MMU_IDX_M_PRIV;
66
ram_addr_t low_ram_size;
67
68
if (ram_size > 0x40000000) {
69
@@ -XXX,XX +XXX,XX @@ static void a9_daughterboard_init(const VexpressMachineState *vms,
70
* address space should in theory be remappable to various
71
* things including ROM or RAM; we always map the RAM there.
72
*/
73
- memory_region_init_alias(lowram, NULL, "vexpress.lowmem", machine->ram,
74
- 0, low_ram_size);
75
- memory_region_add_subregion(sysmem, 0x0, lowram);
76
+ memory_region_init_alias(&vms->lowram, NULL, "vexpress.lowmem",
77
+ machine->ram, 0, low_ram_size);
78
+ memory_region_add_subregion(sysmem, 0x0, &vms->lowram);
79
memory_region_add_subregion(sysmem, 0x60000000, machine->ram);
80
81
/* 0x1e000000 A9MPCore (SCU) private memory region */
82
@@ -XXX,XX +XXX,XX @@ static VEDBoardInfo a9_daughterboard = {
83
.init = a9_daughterboard_init,
84
};
85
86
-static void a15_daughterboard_init(const VexpressMachineState *vms,
87
+static void a15_daughterboard_init(VexpressMachineState *vms,
88
ram_addr_t ram_size,
89
const char *cpu_type,
90
qemu_irq *pic)
91
{
92
MachineState *machine = MACHINE(vms);
93
MemoryRegion *sysmem = get_system_memory();
94
- MemoryRegion *sram = g_new(MemoryRegion, 1);
95
96
{
97
/* We have to use a separate 64 bit variable here to avoid the gcc
98
@@ -XXX,XX +XXX,XX @@ static void a15_daughterboard_init(const VexpressMachineState *vms,
99
/* 0x2b060000: SP805 watchdog: not modelled */
100
/* 0x2b0a0000: PL341 dynamic memory controller: not modelled */
101
/* 0x2e000000: system SRAM */
102
- memory_region_init_ram(sram, NULL, "vexpress.a15sram", 0x10000,
103
+ memory_region_init_ram(&vms->a15sram, NULL, "vexpress.a15sram", 0x10000,
104
&error_fatal);
105
- memory_region_add_subregion(sysmem, 0x2e000000, sram);
106
+ memory_region_add_subregion(sysmem, 0x2e000000, &vms->a15sram);
107
108
/* 0x7ffb0000: DMA330 DMA controller: not modelled */
109
/* 0x7ffd0000: PL354 static memory controller: not modelled */
110
@@ -XXX,XX +XXX,XX @@ static void vexpress_common_init(MachineState *machine)
111
I2CBus *i2c;
112
ram_addr_t vram_size, sram_size;
113
MemoryRegion *sysmem = get_system_memory();
114
- MemoryRegion *vram = g_new(MemoryRegion, 1);
115
- MemoryRegion *sram = g_new(MemoryRegion, 1);
116
- MemoryRegion *flashalias = g_new(MemoryRegion, 1);
117
- MemoryRegion *flash0mem;
118
const hwaddr *map = daughterboard->motherboard_map;
119
int i;
120
121
@@ -XXX,XX +XXX,XX @@ static void vexpress_common_init(MachineState *machine)
122
123
if (map[VE_NORFLASHALIAS] != -1) {
124
/* Map flash 0 as an alias into low memory */
125
+ MemoryRegion *flash0mem;
126
flash0mem = sysbus_mmio_get_region(SYS_BUS_DEVICE(pflash0), 0);
127
- memory_region_init_alias(flashalias, NULL, "vexpress.flashalias",
128
+ memory_region_init_alias(&vms->flashalias, NULL, "vexpress.flashalias",
129
flash0mem, 0, VEXPRESS_FLASH_SIZE);
130
- memory_region_add_subregion(sysmem, map[VE_NORFLASHALIAS], flashalias);
131
+ memory_region_add_subregion(sysmem, map[VE_NORFLASHALIAS], &vms->flashalias);
52
}
132
}
53
133
54
- if (armv7m_nvic_neg_prio_requested(env->nvic, secstate)) {
134
dinfo = drive_get(IF_PFLASH, 0, 1);
55
+ if (negpri) {
135
ve_pflash_cfi01_register(map[VE_NORFLASH1], "vexpress.flash1", dinfo);
56
mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
136
57
}
137
sram_size = 0x2000000;
58
138
- memory_region_init_ram(sram, NULL, "vexpress.sram", sram_size,
59
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
139
+ memory_region_init_ram(&vms->sram, NULL, "vexpress.sram", sram_size,
60
return mmu_idx;
140
&error_fatal);
61
}
141
- memory_region_add_subregion(sysmem, map[VE_SRAM], sram);
62
142
+ memory_region_add_subregion(sysmem, map[VE_SRAM], &vms->sram);
63
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
143
64
+ bool secstate, bool priv)
144
vram_size = 0x800000;
65
+{
145
- memory_region_init_ram(vram, NULL, "vexpress.vram", vram_size,
66
+ bool negpri = armv7m_nvic_neg_prio_requested(env->nvic, secstate);
146
+ memory_region_init_ram(&vms->vram, NULL, "vexpress.vram", vram_size,
67
+
147
&error_fatal);
68
+ return arm_v7m_mmu_idx_all(env, secstate, priv, negpri);
148
- memory_region_add_subregion(sysmem, map[VE_VIDEORAM], vram);
69
+}
149
+ memory_region_add_subregion(sysmem, map[VE_VIDEORAM], &vms->vram);
70
+
150
71
/* Return the MMU index for a v7M CPU in the specified security state */
151
/* 0x4e000000 LAN9118 Ethernet */
72
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
152
if (nd_table[0].used) {
73
{
74
--
153
--
75
2.20.1
154
2.34.1
76
155
77
156
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
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
Add an entries the Blizzard device in MAINTAINERS.
4
5
Reviewed-by: Thomas Huth <thuth@redhat.com>
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190412165416.7977-6-philmd@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/devices.h | 7 -------
12
include/hw/display/blizzard.h | 22 ++++++++++++++++++++++
13
hw/arm/nseries.c | 1 +
14
hw/display/blizzard.c | 2 +-
15
MAINTAINERS | 2 ++
16
5 files changed, 26 insertions(+), 8 deletions(-)
17
create mode 100644 include/hw/display/blizzard.h
18
19
diff --git a/include/hw/devices.h b/include/hw/devices.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/devices.h
22
+++ b/include/hw/devices.h
23
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
24
/* stellaris_input.c */
25
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
26
27
-/* blizzard.c */
28
-void *s1d13745_init(qemu_irq gpio_int);
29
-void s1d13745_write(void *opaque, int dc, uint16_t value);
30
-void s1d13745_write_block(void *opaque, int dc,
31
- void *buf, size_t len, int pitch);
32
-uint16_t s1d13745_read(void *opaque, int dc);
33
-
34
/* cbus.c */
35
typedef struct {
36
qemu_irq clk;
37
diff --git a/include/hw/display/blizzard.h b/include/hw/display/blizzard.h
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/include/hw/display/blizzard.h
42
@@ -XXX,XX +XXX,XX @@
43
+/*
44
+ * Epson S1D13744/S1D13745 (Blizzard/Hailstorm/Tornado) LCD/TV controller.
45
+ *
46
+ * Copyright (C) 2008 Nokia Corporation
47
+ * Written by Andrzej Zaborowski
48
+ *
49
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
50
+ * See the COPYING file in the top-level directory.
51
+ */
52
+
53
+#ifndef HW_DISPLAY_BLIZZARD_H
54
+#define HW_DISPLAY_BLIZZARD_H
55
+
56
+#include "hw/irq.h"
57
+
58
+void *s1d13745_init(qemu_irq gpio_int);
59
+void s1d13745_write(void *opaque, int dc, uint16_t value);
60
+void s1d13745_write_block(void *opaque, int dc,
61
+ void *buf, size_t len, int pitch);
62
+uint16_t s1d13745_read(void *opaque, int dc);
63
+
64
+#endif
65
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/arm/nseries.c
68
+++ b/hw/arm/nseries.c
69
@@ -XXX,XX +XXX,XX @@
70
#include "hw/boards.h"
71
#include "hw/i2c/i2c.h"
72
#include "hw/devices.h"
73
+#include "hw/display/blizzard.h"
74
#include "hw/misc/tmp105.h"
75
#include "hw/block/flash.h"
76
#include "hw/hw.h"
77
diff --git a/hw/display/blizzard.c b/hw/display/blizzard.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/display/blizzard.c
80
+++ b/hw/display/blizzard.c
81
@@ -XXX,XX +XXX,XX @@
82
#include "qemu/osdep.h"
83
#include "qemu-common.h"
84
#include "ui/console.h"
85
-#include "hw/devices.h"
86
+#include "hw/display/blizzard.h"
87
#include "ui/pixel_ops.h"
88
89
typedef void (*blizzard_fn_t)(uint8_t *, const uint8_t *, unsigned int);
90
diff --git a/MAINTAINERS b/MAINTAINERS
91
index XXXXXXX..XXXXXXX 100644
92
--- a/MAINTAINERS
93
+++ b/MAINTAINERS
94
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
95
L: qemu-arm@nongnu.org
96
S: Odd Fixes
97
F: hw/arm/nseries.c
98
+F: hw/display/blizzard.c
99
F: hw/input/lm832x.c
100
F: hw/input/tsc2005.c
101
F: hw/misc/cbus.c
102
F: hw/timer/twl92230.c
103
+F: include/hw/display/blizzard.h
104
105
Palm
106
M: Andrzej Zaborowski <balrogg@gmail.com>
107
--
108
2.20.1
109
110
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
Convert the u2f.txt file to rST, and place it in the right place
2
2
in our manual layout. The old text didn't fit very well into our
3
manual style, so the new version ends up looking like a rewrite,
4
although some of the original text is preserved:
5
6
* the 'building' section of the old file is removed, since we
7
generally assume that users have already built QEMU
8
* some rather verbose text has been cut back
9
* document the passthrough device first, on the assumption
10
that's most likely to be of interest to users
11
* cut back on the duplication of text between sections
12
* format example command lines etc with rST
13
14
As it's a short document it seemed simplest to do this all
15
in one go rather than try to do a minimal syntactic conversion
16
and then clean up the wording and layout.
17
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
19
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
20
Message-id: 20230421163734.1152076-1-peter.maydell@linaro.org
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190412165416.7977-7-philmd@redhat.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
21
---
9
include/hw/devices.h | 14 --------------
22
docs/system/device-emulation.rst | 1 +
10
include/hw/misc/cbus.h | 32 ++++++++++++++++++++++++++++++++
23
docs/system/devices/usb-u2f.rst | 93 ++++++++++++++++++++++++++
11
hw/arm/nseries.c | 1 +
24
docs/system/devices/usb.rst | 2 +-
12
hw/misc/cbus.c | 2 +-
25
docs/u2f.txt | 110 -------------------------------
13
MAINTAINERS | 1 +
26
4 files changed, 95 insertions(+), 111 deletions(-)
14
5 files changed, 35 insertions(+), 15 deletions(-)
27
create mode 100644 docs/system/devices/usb-u2f.rst
15
create mode 100644 include/hw/misc/cbus.h
28
delete mode 100644 docs/u2f.txt
16
29
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
30
diff --git a/docs/system/device-emulation.rst b/docs/system/device-emulation.rst
18
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/devices.h
32
--- a/docs/system/device-emulation.rst
20
+++ b/include/hw/devices.h
33
+++ b/docs/system/device-emulation.rst
21
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
34
@@ -XXX,XX +XXX,XX @@ Emulated Devices
22
/* stellaris_input.c */
35
devices/virtio-pmem.rst
23
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
36
devices/vhost-user-rng.rst
24
37
devices/canokey.rst
25
-/* cbus.c */
38
+ devices/usb-u2f.rst
26
-typedef struct {
39
devices/igb.rst
27
- qemu_irq clk;
40
diff --git a/docs/system/devices/usb-u2f.rst b/docs/system/devices/usb-u2f.rst
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
41
new file mode 100644
42
index XXXXXXX..XXXXXXX
42
index XXXXXXX..XXXXXXX
43
--- /dev/null
43
--- /dev/null
44
+++ b/include/hw/misc/cbus.h
44
+++ b/docs/system/devices/usb-u2f.rst
45
@@ -XXX,XX +XXX,XX @@
45
@@ -XXX,XX +XXX,XX @@
46
+/*
46
+Universal Second Factor (U2F) USB Key Device
47
+ * CBUS three-pin bus and the Retu / Betty / Tahvo / Vilma / Avilma /
47
+============================================
48
+ * Hinku / Vinku / Ahne / Pihi chips used in various Nokia platforms.
48
+
49
+ * Based on reverse-engineering of a linux driver.
49
+U2F is an open authentication standard that enables relying parties
50
+ *
50
+exposed to the internet to offer a strong second factor option for end
51
+ * Copyright (C) 2008 Nokia Corporation
51
+user authentication.
52
+ * Written by Andrzej Zaborowski
52
+
53
+ *
53
+The second factor is provided by a device implementing the U2F
54
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
54
+protocol. In case of a USB U2F security key, it is a USB HID device
55
+ * See the COPYING file in the top-level directory.
55
+that implements the U2F protocol.
56
+ */
56
+
57
+
57
+QEMU supports both pass-through of a host U2F key device to a VM,
58
+#ifndef HW_MISC_CBUS_H
58
+and software emulation of a U2F key.
59
+#define HW_MISC_CBUS_H
59
+
60
+
60
+``u2f-passthru``
61
+#include "hw/irq.h"
61
+----------------
62
+
62
+
63
+typedef struct {
63
+The ``u2f-passthru`` device allows you to connect a real hardware
64
+ qemu_irq clk;
64
+U2F key on your host to a guest VM. All requests made from the guest
65
+ qemu_irq dat;
65
+are passed through to the physical security key connected to the
66
+ qemu_irq sel;
66
+host machine and vice versa.
67
+} CBus;
67
+
68
+
68
+In addition, the dedicated pass-through allows you to share a single
69
+CBus *cbus_init(qemu_irq dat_out);
69
+U2F security key with several guest VMs, which is not possible with a
70
+void cbus_attach(CBus *bus, void *slave_opaque);
70
+simple host device assignment pass-through.
71
+
71
+
72
+void *retu_init(qemu_irq irq, int vilma);
72
+You can specify the host U2F key to use with the ``hidraw``
73
+void *tahvo_init(qemu_irq irq, int betty);
73
+option, which takes the host path to a Linux ``/dev/hidrawN`` device:
74
+
74
+
75
+void retu_key_event(void *retu, int state);
75
+.. parsed-literal::
76
+
76
+ |qemu_system| -usb -device u2f-passthru,hidraw=/dev/hidraw0
77
+#endif
77
+
78
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
78
+If you don't specify the device, the ``u2f-passthru`` device will
79
+autoscan to take the first U2F device it finds on the host (this
80
+requires a working libudev):
81
+
82
+.. parsed-literal::
83
+ |qemu_system| -usb -device u2f-passthru
84
+
85
+``u2f-emulated``
86
+----------------
87
+
88
+``u2f-emulated`` is a completely software emulated U2F device.
89
+It uses `libu2f-emu <https://github.com/MattGorko/libu2f-emu>`__
90
+for the U2F key emulation. libu2f-emu
91
+provides a complete implementation of the U2F protocol device part for
92
+all specified transports given by the FIDO Alliance.
93
+
94
+To work, an emulated U2F device must have four elements:
95
+
96
+ * ec x509 certificate
97
+ * ec private key
98
+ * counter (four bytes value)
99
+ * 48 bytes of entropy (random bits)
100
+
101
+To use this type of device, these have to be configured, and these
102
+four elements must be passed one way or another.
103
+
104
+Assuming that you have a working libu2f-emu installed on the host,
105
+there are three possible ways to configure the ``u2f-emulated`` device:
106
+
107
+ * ephemeral
108
+ * setup directory
109
+ * manual
110
+
111
+Ephemeral is the simplest way to configure; it lets the device generate
112
+all the elements it needs for a single use of the lifetime of the device.
113
+It is the default if you do not pass any other options to the device.
114
+
115
+.. parsed-literal::
116
+ |qemu_system| -usb -device u2f-emulated
117
+
118
+You can pass the device the path of a setup directory on the host
119
+using the ``dir`` option; the directory must contain these four files:
120
+
121
+ * ``certificate.pem``: ec x509 certificate
122
+ * ``private-key.pem``: ec private key
123
+ * ``counter``: counter value
124
+ * ``entropy``: 48 bytes of entropy
125
+
126
+.. parsed-literal::
127
+ |qemu_system| -usb -device u2f-emulated,dir=$dir
128
+
129
+You can also manually pass the device the paths to each of these files,
130
+if you don't want them all to be in the same directory, using the options
131
+
132
+ * ``cert``
133
+ * ``priv``
134
+ * ``counter``
135
+ * ``entropy``
136
+
137
+.. parsed-literal::
138
+ |qemu_system| -usb -device u2f-emulated,cert=$DIR1/$FILE1,priv=$DIR2/$FILE2,counter=$DIR3/$FILE3,entropy=$DIR4/$FILE4
139
diff --git a/docs/system/devices/usb.rst b/docs/system/devices/usb.rst
79
index XXXXXXX..XXXXXXX 100644
140
index XXXXXXX..XXXXXXX 100644
80
--- a/hw/arm/nseries.c
141
--- a/docs/system/devices/usb.rst
81
+++ b/hw/arm/nseries.c
142
+++ b/docs/system/devices/usb.rst
143
@@ -XXX,XX +XXX,XX @@ option or the ``device_add`` monitor command. Available devices are:
144
USB audio device
145
146
``u2f-{emulated,passthru}``
147
- Universal Second Factor device
148
+ :doc:`usb-u2f`
149
150
``canokey``
151
An Open-source Secure Key implementing FIDO2, OpenPGP, PIV and more.
152
diff --git a/docs/u2f.txt b/docs/u2f.txt
153
deleted file mode 100644
154
index XXXXXXX..XXXXXXX
155
--- a/docs/u2f.txt
156
+++ /dev/null
82
@@ -XXX,XX +XXX,XX @@
157
@@ -XXX,XX +XXX,XX @@
83
#include "hw/i2c/i2c.h"
158
-QEMU U2F Key Device Documentation.
84
#include "hw/devices.h"
159
-
85
#include "hw/display/blizzard.h"
160
-Contents
86
+#include "hw/misc/cbus.h"
161
-1. USB U2F key device
87
#include "hw/misc/tmp105.h"
162
-2. Building
88
#include "hw/block/flash.h"
163
-3. Using u2f-emulated
89
#include "hw/hw.h"
164
-4. Using u2f-passthru
90
diff --git a/hw/misc/cbus.c b/hw/misc/cbus.c
165
-5. Libu2f-emu
91
index XXXXXXX..XXXXXXX 100644
166
-
92
--- a/hw/misc/cbus.c
167
-1. USB U2F key device
93
+++ b/hw/misc/cbus.c
168
-
94
@@ -XXX,XX +XXX,XX @@
169
-U2F is an open authentication standard that enables relying parties
95
#include "qemu/osdep.h"
170
-exposed to the internet to offer a strong second factor option for end
96
#include "hw/hw.h"
171
-user authentication.
97
#include "hw/irq.h"
172
-
98
-#include "hw/devices.h"
173
-The standard brings many advantages to both parties, client and server,
99
+#include "hw/misc/cbus.h"
174
-allowing to reduce over-reliance on passwords, it increases authentication
100
#include "sysemu/sysemu.h"
175
-security and simplifies passwords.
101
176
-
102
//#define DEBUG
177
-The second factor is materialized by a device implementing the U2F
103
diff --git a/MAINTAINERS b/MAINTAINERS
178
-protocol. In case of a USB U2F security key, it is a USB HID device
104
index XXXXXXX..XXXXXXX 100644
179
-that implements the U2F protocol.
105
--- a/MAINTAINERS
180
-
106
+++ b/MAINTAINERS
181
-In QEMU, the USB U2F key device offers a dedicated support of U2F, allowing
107
@@ -XXX,XX +XXX,XX @@ F: hw/input/tsc2005.c
182
-guest USB FIDO/U2F security keys operating in two possible modes:
108
F: hw/misc/cbus.c
183
-pass-through and emulated.
109
F: hw/timer/twl92230.c
184
-
110
F: include/hw/display/blizzard.h
185
-The pass-through mode consists of passing all requests made from the guest
111
+F: include/hw/misc/cbus.h
186
-to the physical security key connected to the host machine and vice versa.
112
187
-In addition, the dedicated pass-through allows to have a U2F security key
113
Palm
188
-shared on several guests which is not possible with a simple host device
114
M: Andrzej Zaborowski <balrogg@gmail.com>
189
-assignment pass-through.
190
-
191
-The emulated mode consists of completely emulating the behavior of an
192
-U2F device through software part. Libu2f-emu is used for that.
193
-
194
-
195
-2. Building
196
-
197
-To ensure the build of the u2f-emulated device variant which depends
198
-on libu2f-emu: configuring and building:
199
-
200
- ./configure --enable-u2f && make
201
-
202
-The pass-through mode is built by default on Linux. To take advantage
203
-of the autoscan option it provides, make sure you have a working libudev
204
-installed on the host.
205
-
206
-
207
-3. Using u2f-emulated
208
-
209
-To work, an emulated U2F device must have four elements:
210
- * ec x509 certificate
211
- * ec private key
212
- * counter (four bytes value)
213
- * 48 bytes of entropy (random bits)
214
-
215
-To use this type of device, this one has to be configured, and these
216
-four elements must be passed one way or another.
217
-
218
-Assuming that you have a working libu2f-emu installed on the host.
219
-There are three possible ways of configurations:
220
- * ephemeral
221
- * setup directory
222
- * manual
223
-
224
-Ephemeral is the simplest way to configure, it lets the device generate
225
-all the elements it needs for a single use of the lifetime of the device.
226
-
227
- qemu -usb -device u2f-emulated
228
-
229
-Setup directory allows to configure the device from a directory containing
230
-four files:
231
- * certificate.pem: ec x509 certificate
232
- * private-key.pem: ec private key
233
- * counter: counter value
234
- * entropy: 48 bytes of entropy
235
-
236
- qemu -usb -device u2f-emulated,dir=$dir
237
-
238
-Manual allows to configure the device more finely by specifying each
239
-of the elements necessary for the device:
240
- * cert
241
- * priv
242
- * counter
243
- * entropy
244
-
245
- qemu -usb -device u2f-emulated,cert=$DIR1/$FILE1,priv=$DIR2/$FILE2,counter=$DIR3/$FILE3,entropy=$DIR4/$FILE4
246
-
247
-
248
-4. Using u2f-passthru
249
-
250
-On the host specify the u2f-passthru device with a suitable hidraw:
251
-
252
- qemu -usb -device u2f-passthru,hidraw=/dev/hidraw0
253
-
254
-Alternately, the u2f-passthru device can autoscan to take the first
255
-U2F device it finds on the host (this requires a working libudev):
256
-
257
- qemu -usb -device u2f-passthru
258
-
259
-
260
-5. Libu2f-emu
261
-
262
-The u2f-emulated device uses libu2f-emu for the U2F key emulation. Libu2f-emu
263
-implements completely the U2F protocol device part for all specified
264
-transport given by the FIDO Alliance.
265
-
266
-For more information about libu2f-emu see this page:
267
-https://github.com/MattGorko/libu2f-emu.
115
--
268
--
116
2.20.1
269
2.34.1
117
118
diff view generated by jsdifflib