1
First pullreq for arm of the 4.1 series, since I'm back from
1
The following changes since commit 61fee7f45955cd0bf9b79be9fa9c7ebabb5e6a85:
2
holiday now. This is mostly my M-profile FPU series and Philippe's
3
devices.h cleanup. I have a pile of other patchsets to work through
4
in my to-review folder, but 42 patches is definitely quite
5
big enough to send now...
6
2
7
thanks
3
Merge remote-tracking branch 'remotes/philmd-gitlab/tags/acceptance-testing-20200622' into staging (2020-06-22 20:50:10 +0100)
8
-- PMM
9
10
The following changes since commit 413a99a92c13ec408dcf2adaa87918dc81e890c8:
11
12
Add Nios II semihosting support. (2019-04-29 16:09:51 +0100)
13
4
14
are available in the Git repository at:
5
are available in the Git repository at:
15
6
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190429
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200623
17
8
18
for you to fetch changes up to 437cc27ddfded3bbab6afd5ac1761e0e195edba7:
9
for you to fetch changes up to 539533b85fbd269f777bed931de8ccae1dd837e9:
19
10
20
hw/devices: Move SMSC 91C111 declaration into a new header (2019-04-29 17:57:21 +0100)
11
arm/virt: Add memory hot remove support (2020-06-23 11:39:48 +0100)
21
12
22
----------------------------------------------------------------
13
----------------------------------------------------------------
23
target-arm queue:
14
target-arm queue:
24
* remove "bag of random stuff" hw/devices.h header
15
* util/oslib-posix : qemu_init_exec_dir implementation for Mac
25
* implement FPU for Cortex-M and enable it for Cortex-M4 and -M33
16
* target/arm: Last parts of neon decodetree conversion
26
* hw/dma: Compile the bcm2835_dma device as common object
17
* hw/arm/virt: Add 5.0 HW compat props
27
* configure: Remove --source-path option
18
* hw/watchdog/cmsdk-apb-watchdog: Add trace event for lock status
28
* hw/ssi/xilinx_spips: Avoid variable length array
19
* mps2: Add CMSDK APB watchdog, FPGAIO block, S2I devices and I2C devices
29
* hw/arm/smmuv3: Remove SMMUNotifierNode
20
* mps2: Add some unimplemented-device stubs for audio and GPIO
21
* mps2-tz: Use the ARM SBCon two-wire serial bus interface
22
* target/arm: Check supported KVM features globally (not per vCPU)
23
* tests/qtest/arm-cpu-features: Add feature setting tests
24
* arm/virt: Add memory hot remove support
30
25
31
----------------------------------------------------------------
26
----------------------------------------------------------------
32
Eric Auger (1):
27
Andrew Jones (2):
33
hw/arm/smmuv3: Remove SMMUNotifierNode
28
hw/arm/virt: Add 5.0 HW compat props
29
tests/qtest/arm-cpu-features: Add feature setting tests
34
30
35
Peter Maydell (28):
31
David CARLIER (1):
36
hw/ssi/xilinx_spips: Avoid variable length array
32
util/oslib-posix : qemu_init_exec_dir implementation for Mac
37
configure: Remove --source-path option
38
target/arm: Make sure M-profile FPSCR RES0 bits are not settable
39
hw/intc/armv7m_nvic: Allow reading of M-profile MVFR* registers
40
target/arm: Implement dummy versions of M-profile FP-related registers
41
target/arm: Disable most VFP sysregs for M-profile
42
target/arm: Honour M-profile FP enable bits
43
target/arm: Decode FP instructions for M profile
44
target/arm: Clear CONTROL_S.SFPA in SG insn if FPU present
45
target/arm: Handle SFPA and FPCA bits in reads and writes of CONTROL
46
target/arm/helper: don't return early for STKOF faults during stacking
47
target/arm: Handle floating point registers in exception entry
48
target/arm: Implement v7m_update_fpccr()
49
target/arm: Clear CONTROL.SFPA in BXNS and BLXNS
50
target/arm: Clean excReturn bits when tail chaining
51
target/arm: Allow for floating point in callee stack integrity check
52
target/arm: Handle floating point registers in exception return
53
target/arm: Move NS TBFLAG from bit 19 to bit 6
54
target/arm: Overlap VECSTRIDE and XSCALE_CPAR TB flags
55
target/arm: Set FPCCR.S when executing M-profile floating point insns
56
target/arm: Activate M-profile floating point context when FPCCR.ASPEN is set
57
target/arm: New helper function arm_v7m_mmu_idx_all()
58
target/arm: New function armv7m_nvic_set_pending_lazyfp()
59
target/arm: Add lazy-FP-stacking support to v7m_stack_write()
60
target/arm: Implement M-profile lazy FP state preservation
61
target/arm: Implement VLSTM for v7M CPUs with an FPU
62
target/arm: Implement VLLDM for v7M CPUs with an FPU
63
target/arm: Enable FPU for Cortex-M4 and Cortex-M33
64
33
65
Philippe Mathieu-Daudé (13):
34
Peter Maydell (23):
66
hw/dma: Compile the bcm2835_dma device as common object
35
target/arm: Convert Neon 2-reg-misc VREV64 to decodetree
67
hw/arm/aspeed: Use TYPE_TMP105/TYPE_PCA9552 instead of hardcoded string
36
target/arm: Convert Neon 2-reg-misc pairwise ops to decodetree
68
hw/arm/nseries: Use TYPE_TMP105 instead of hardcoded string
37
target/arm: Convert VZIP, VUZP to decodetree
69
hw/display/tc6393xb: Remove unused functions
38
target/arm: Convert Neon narrowing moves to decodetree
70
hw/devices: Move TC6393XB declarations into a new header
39
target/arm: Convert Neon 2-reg-misc VSHLL to decodetree
71
hw/devices: Move Blizzard declarations into a new header
40
target/arm: Convert Neon VCVT f16/f32 insns to decodetree
72
hw/devices: Move CBus declarations into a new header
41
target/arm: Convert vectorised 2-reg-misc Neon ops to decodetree
73
hw/devices: Move Gamepad declarations into a new header
42
target/arm: Convert Neon 2-reg-misc crypto operations to decodetree
74
hw/devices: Move TI touchscreen declarations into a new header
43
target/arm: Rename NeonGenOneOpFn to NeonGenOne64OpFn
75
hw/devices: Move LAN9118 declarations into a new header
44
target/arm: Fix capitalization in NeonGenTwo{Single, Double}OPFn typedefs
76
hw/net/ne2000-isa: Add guards to the header
45
target/arm: Make gen_swap_half() take separate src and dest
77
hw/net/lan9118: Export TYPE_LAN9118 and use it instead of hardcoded string
46
target/arm: Convert Neon 2-reg-misc VREV32 and VREV16 to decodetree
78
hw/devices: Move SMSC 91C111 declaration into a new header
47
target/arm: Convert remaining simple 2-reg-misc Neon ops
48
target/arm: Convert Neon VQABS, VQNEG to decodetree
49
target/arm: Convert simple fp Neon 2-reg-misc insns
50
target/arm: Convert Neon 2-reg-misc fp-compare-with-zero insns to decodetree
51
target/arm: Convert Neon 2-reg-misc VRINT insns to decodetree
52
target/arm: Convert Neon 2-reg-misc VCVT insns to decodetree
53
target/arm: Convert Neon VSWP to decodetree
54
target/arm: Convert Neon VTRN to decodetree
55
target/arm: Move some functions used only in translate-neon.inc.c to that file
56
target/arm: Remove unnecessary gen_io_end() calls
57
target/arm: Remove dead code relating to SABA and UABA
79
58
80
configure | 10 +-
59
Philippe Mathieu-Daudé (15):
81
hw/dma/Makefile.objs | 2 +-
60
hw/watchdog/cmsdk-apb-watchdog: Add trace event for lock status
82
include/hw/arm/omap.h | 6 +-
61
hw/i2c/versatile_i2c: Add definitions for register addresses
83
include/hw/arm/smmu-common.h | 8 +-
62
hw/i2c/versatile_i2c: Add SCL/SDA definitions
84
include/hw/devices.h | 62 ---
63
hw/i2c: Add header for ARM SBCon two-wire serial bus interface
85
include/hw/display/blizzard.h | 22 ++
64
hw/arm: Use TYPE_VERSATILE_I2C instead of hardcoded string
86
include/hw/display/tc6393xb.h | 24 ++
65
hw/arm/mps2: Document CMSDK/FPGA APB subsystem sections
87
include/hw/input/gamepad.h | 19 +
66
hw/arm/mps2: Rename CMSDK AHB peripheral region
88
include/hw/input/tsc2xxx.h | 36 ++
67
hw/arm/mps2: Add CMSDK APB watchdog device
89
include/hw/misc/cbus.h | 32 ++
68
hw/arm/mps2: Add CMSDK AHB GPIO peripherals as unimplemented devices
90
include/hw/net/lan9118.h | 21 +
69
hw/arm/mps2: Map the FPGA I/O block
91
include/hw/net/ne2000-isa.h | 6 +
70
hw/arm/mps2: Add SPI devices
92
include/hw/net/smc91c111.h | 19 +
71
hw/arm/mps2: Add I2C devices
93
include/qemu/typedefs.h | 1 -
72
hw/arm/mps2: Add audio I2S interface as unimplemented device
94
target/arm/cpu.h | 95 ++++-
73
hw/arm/mps2-tz: Use the ARM SBCon two-wire serial bus interface
95
target/arm/helper.h | 5 +
74
target/arm: Check supported KVM features globally (not per vCPU)
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
75
76
Shameer Kolothum (1):
77
arm/virt: Add memory hot remove support
78
79
include/hw/i2c/arm_sbcon_i2c.h | 35 ++
80
target/arm/cpu.h | 2 +-
81
target/arm/kvm_arm.h | 21 +-
82
target/arm/translate.h | 8 +-
83
target/arm/neon-dp.decode | 106 ++++
84
hw/acpi/generic_event_device.c | 29 +
85
hw/arm/mps2-tz.c | 23 +-
86
hw/arm/mps2.c | 65 ++-
87
hw/arm/realview.c | 3 +-
88
hw/arm/versatilepb.c | 3 +-
89
hw/arm/vexpress.c | 3 +-
90
hw/arm/virt.c | 63 +-
91
hw/i2c/versatile_i2c.c | 38 +-
92
hw/watchdog/cmsdk-apb-watchdog.c | 1 +
93
target/arm/cpu.c | 2 +-
94
target/arm/cpu64.c | 10 +-
95
target/arm/kvm.c | 4 +-
96
target/arm/kvm64.c | 14 +-
97
target/arm/translate-a64.c | 20 +-
98
target/arm/translate-neon.inc.c | 1191 +++++++++++++++++++++++++++++++++++++-
99
target/arm/translate-vfp.inc.c | 7 +-
100
target/arm/translate.c | 1064 +---------------------------------
101
tests/qtest/arm-cpu-features.c | 38 +-
102
util/oslib-posix.c | 15 +
103
MAINTAINERS | 1 +
104
hw/arm/Kconfig | 8 +-
105
hw/watchdog/trace-events | 1 +
106
27 files changed, 1624 insertions(+), 1151 deletions(-)
107
create mode 100644 include/hw/i2c/arm_sbcon_i2c.h
108
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Andrew Jones <drjones@redhat.com>
2
2
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
Cc: Cornelia Huck <cohuck@redhat.com>
4
Reviewed-by: Cédric Le Goater <clg@kaod.org>
4
Signed-off-by: Andrew Jones <drjones@redhat.com>
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20200616140803.25515-1-drjones@redhat.com
7
Message-id: 20190412165416.7977-2-philmd@redhat.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
8
---
10
hw/arm/aspeed.c | 13 +++++++++----
9
hw/arm/virt.c | 1 +
11
1 file changed, 9 insertions(+), 4 deletions(-)
10
1 file changed, 1 insertion(+)
12
11
13
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
12
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
14
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/aspeed.c
14
--- a/hw/arm/virt.c
16
+++ b/hw/arm/aspeed.c
15
+++ b/hw/arm/virt.c
17
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(5, 1)
18
#include "hw/arm/aspeed_soc.h"
17
static void virt_machine_5_0_options(MachineClass *mc)
19
#include "hw/boards.h"
18
{
20
#include "hw/i2c/smbus_eeprom.h"
19
virt_machine_5_1_options(mc);
21
+#include "hw/misc/pca9552.h"
20
+ compat_props_add(mc->compat_props, hw_compat_5_0, hw_compat_5_0_len);
22
+#include "hw/misc/tmp105.h"
23
#include "qemu/log.h"
24
#include "sysemu/block-backend.h"
25
#include "hw/loader.h"
26
@@ -XXX,XX +XXX,XX @@ static void ast2500_evb_i2c_init(AspeedBoardState *bmc)
27
eeprom_buf);
28
29
/* The AST2500 EVB expects a LM75 but a TMP105 is compatible */
30
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7), "tmp105", 0x4d);
31
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7),
32
+ TYPE_TMP105, 0x4d);
33
34
/* The AST2500 EVB does not have an RTC. Let's pretend that one is
35
* plugged on the I2C bus header */
36
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
37
AspeedSoCState *soc = &bmc->soc;
38
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
39
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
}
21
}
22
DEFINE_VIRT_MACHINE(5, 0)
62
23
63
--
24
--
64
2.20.1
25
2.20.1
65
26
66
27
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: David CARLIER <devnexen@gmail.com>
2
2
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
From 3025a0ce3fdf7d3559fc35a52c659f635f5c750c Mon Sep 17 00:00:00 2001
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
From: David Carlier <devnexen@gmail.com>
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Date: Tue, 26 May 2020 21:35:27 +0100
6
Message-id: 20190412165416.7977-11-philmd@redhat.com
6
Subject: [PATCH] util/oslib-posix : qemu_init_exec_dir implementation for Mac
7
8
Using dyld API to get the full path of the current process.
9
10
Signed-off-by: David Carlier <devnexen@gmail.com>
11
Message-id: CA+XhMqxwC10XHVs4Z-JfE0-WLAU3ztDuU9QKVi31mjr59HWCxg@mail.gmail.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
14
---
9
include/hw/net/ne2000-isa.h | 6 ++++++
15
util/oslib-posix.c | 15 +++++++++++++++
10
1 file changed, 6 insertions(+)
16
1 file changed, 15 insertions(+)
11
17
12
diff --git a/include/hw/net/ne2000-isa.h b/include/hw/net/ne2000-isa.h
18
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
13
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/net/ne2000-isa.h
20
--- a/util/oslib-posix.c
15
+++ b/include/hw/net/ne2000-isa.h
21
+++ b/util/oslib-posix.c
16
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@
17
* This work is licensed under the terms of the GNU GPL, version 2 or later.
23
#include <lwp.h>
18
* See the COPYING file in the top-level directory.
24
#endif
19
*/
25
26
+#ifdef __APPLE__
27
+#include <mach-o/dyld.h>
28
+#endif
20
+
29
+
21
+#ifndef HW_NET_NE2K_ISA_H
30
#include "qemu/mmap-alloc.h"
22
+#define HW_NET_NE2K_ISA_H
31
23
+
32
#ifdef CONFIG_DEBUG_STACK_USAGE
24
#include "hw/hw.h"
33
@@ -XXX,XX +XXX,XX @@ void qemu_init_exec_dir(const char *argv0)
25
#include "hw/qdev.h"
34
p = buf;
26
#include "hw/isa/isa.h"
35
}
27
@@ -XXX,XX +XXX,XX @@ static inline ISADevice *isa_ne2000_init(ISABus *bus, int base, int irq,
28
}
36
}
29
return d;
37
+#elif defined(__APPLE__)
30
}
38
+ {
31
+
39
+ char fpath[PATH_MAX];
32
+#endif
40
+ uint32_t len = sizeof(fpath);
41
+ if (_NSGetExecutablePath(fpath, &len) == 0) {
42
+ p = realpath(fpath, buf);
43
+ if (!p) {
44
+ return;
45
+ }
46
+ }
47
+ }
48
#endif
49
/* If we don't have any way of figuring out the actual executable
50
location then try argv[0]. */
33
--
51
--
34
2.20.1
52
2.20.1
35
53
36
54
diff view generated by jsdifflib
1
Handle floating point registers in exception return.
1
Convert the Neon VREV64 insn from the 2-reg-misc grouping to decodetree.
2
This corresponds to pseudocode functions ValidateExceptionReturn(),
3
ExceptionReturn(), PopStack() and ConsumeExcStackFrame().
4
2
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190416125744.27770-16-peter.maydell@linaro.org
5
Message-id: 20200616170844.13318-2-peter.maydell@linaro.org
8
---
6
---
9
target/arm/helper.c | 142 +++++++++++++++++++++++++++++++++++++++++++-
7
target/arm/neon-dp.decode | 12 ++++++++
10
1 file changed, 141 insertions(+), 1 deletion(-)
8
target/arm/translate-neon.inc.c | 50 +++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 24 ++--------------
10
3 files changed, 64 insertions(+), 22 deletions(-)
11
11
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
14
--- a/target/arm/neon-dp.decode
15
+++ b/target/arm/helper.c
15
+++ b/target/arm/neon-dp.decode
16
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
16
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
17
bool rettobase = false;
17
vm=%vm_dp vd=%vd_dp size=1
18
bool exc_secure = false;
18
VDUP_scalar 1111 001 1 1 . 11 index:1 100 .... 11 000 q:1 . 0 .... \
19
bool return_to_secure;
19
vm=%vm_dp vd=%vd_dp size=2
20
+ bool ftype;
21
+ bool restore_s16_s31;
22
23
/* If we're not in Handler mode then jumps to magic exception-exit
24
* addresses don't have magic behaviour. However for the v8M
25
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
26
excret);
27
}
28
29
+ ftype = excret & R_V7M_EXCRET_FTYPE_MASK;
30
+
20
+
31
+ if (!arm_feature(env, ARM_FEATURE_VFP) && !ftype) {
21
+ ##################################################################
32
+ qemu_log_mask(LOG_GUEST_ERROR, "M profile: zero FTYPE in exception "
22
+ # 2-reg-misc grouping:
33
+ "exit PC value 0x%" PRIx32 " is UNPREDICTABLE "
23
+ # 1111 001 11 D 11 size:2 opc1:2 Vd:4 0 opc2:4 q:1 M 0 Vm:4
34
+ "if FPU not present\n",
24
+ ##################################################################
35
+ excret);
25
+
36
+ ftype = true;
26
+ &2misc vd vm q size
27
+
28
+ @2misc .... ... .. . .. size:2 .. .... . .... q:1 . . .... \
29
+ &2misc vm=%vm_dp vd=%vd_dp
30
+
31
+ VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
32
]
33
34
# Subgroup for size != 0b11
35
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/translate-neon.inc.c
38
+++ b/target/arm/translate-neon.inc.c
39
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a)
40
a->q ? 16 : 8, a->q ? 16 : 8);
41
return true;
42
}
43
+
44
+static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
45
+{
46
+ int pass, half;
47
+
48
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
49
+ return false;
37
+ }
50
+ }
38
+
51
+
39
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
52
+ /* UNDEF accesses to D16-D31 if they don't exist. */
40
/* EXC_RETURN.ES validation check (R_SMFL). We must do this before
53
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
41
* we pick which FAULTMASK to clear.
54
+ ((a->vd | a->vm) & 0x10)) {
42
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
55
+ return false;
43
*/
44
write_v7m_control_spsel_for_secstate(env, return_to_sp_process, exc_secure);
45
46
+ /*
47
+ * Clear scratch FP values left in caller saved registers; this
48
+ * must happen before any kind of tail chaining.
49
+ */
50
+ if ((env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_CLRONRET_MASK) &&
51
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
52
+ if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
53
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
54
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
55
+ qemu_log_mask(CPU_LOG_INT, "...taking SecureFault on existing "
56
+ "stackframe: error during lazy state deactivation\n");
57
+ v7m_exception_taken(cpu, excret, true, false);
58
+ return;
59
+ } else {
60
+ /* Clear s0..s15 and FPSCR */
61
+ int i;
62
+
63
+ for (i = 0; i < 16; i += 2) {
64
+ *aa32_vfp_dreg(env, i / 2) = 0;
65
+ }
66
+ vfp_set_fpscr(env, 0);
67
+ }
68
+ }
56
+ }
69
+
57
+
70
if (sfault) {
58
+ if ((a->vd | a->vm) & a->q) {
71
env->v7m.sfsr |= R_V7M_SFSR_INVER_MASK;
59
+ return false;
72
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
60
+ }
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
+
61
+
91
+ restore_s16_s31 = return_to_secure &&
62
+ if (a->size == 3) {
92
+ (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
63
+ return false;
64
+ }
93
+
65
+
94
+ if (env->v7m.fpccr[return_to_secure] & R_V7M_FPCCR_LSPACT_MASK) {
66
+ if (!vfp_access_check(s)) {
95
+ /* State in FPU is still valid, just clear LSPACT */
67
+ return true;
96
+ env->v7m.fpccr[return_to_secure] &= ~R_V7M_FPCCR_LSPACT_MASK;
68
+ }
97
+ } else {
98
+ int i;
99
+ uint32_t fpscr;
100
+ bool cpacr_pass, nsacr_pass;
101
+
69
+
102
+ cpacr_pass = v7m_cpacr_pass(env, return_to_secure,
70
+ for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
103
+ return_to_priv);
71
+ TCGv_i32 tmp[2];
104
+ nsacr_pass = return_to_secure ||
105
+ extract32(env->v7m.nsacr, 10, 1);
106
+
72
+
107
+ if (!cpacr_pass) {
73
+ for (half = 0; half < 2; half++) {
108
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
74
+ tmp[half] = neon_load_reg(a->vm, pass * 2 + half);
109
+ return_to_secure);
75
+ switch (a->size) {
110
+ env->v7m.cfsr[return_to_secure] |= R_V7M_CFSR_NOCP_MASK;
76
+ case 0:
111
+ qemu_log_mask(CPU_LOG_INT,
77
+ tcg_gen_bswap32_i32(tmp[half], tmp[half]);
112
+ "...taking UsageFault on existing "
78
+ break;
113
+ "stackframe: CPACR.CP10 prevents unstacking "
79
+ case 1:
114
+ "FP regs\n");
80
+ gen_swap_half(tmp[half]);
115
+ v7m_exception_taken(cpu, excret, true, false);
81
+ break;
116
+ return;
82
+ case 2:
117
+ } else if (!nsacr_pass) {
83
+ break;
118
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, true);
84
+ default:
119
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_INVPC_MASK;
85
+ g_assert_not_reached();
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
+ }
86
+ }
164
+ }
87
+ }
165
+ env->v7m.control[M_REG_S] = FIELD_DP32(env->v7m.control[M_REG_S],
88
+ neon_store_reg(a->vd, pass * 2, tmp[1]);
166
+ V7M_CONTROL, FPCA, !ftype);
89
+ neon_store_reg(a->vd, pass * 2 + 1, tmp[0]);
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
+ }
90
+ }
192
91
+ return true;
193
/* The restored xPSR exception field will be zero if we're
92
+}
194
* resuming in Thread mode. If that doesn't match what the
93
diff --git a/target/arm/translate.c b/target/arm/translate.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/target/arm/translate.c
96
+++ b/target/arm/translate.c
97
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
98
}
99
switch (op) {
100
case NEON_2RM_VREV64:
101
- for (pass = 0; pass < (q ? 2 : 1); pass++) {
102
- tmp = neon_load_reg(rm, pass * 2);
103
- tmp2 = neon_load_reg(rm, pass * 2 + 1);
104
- switch (size) {
105
- case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
106
- case 1: gen_swap_half(tmp); break;
107
- case 2: /* no-op */ break;
108
- default: abort();
109
- }
110
- neon_store_reg(rd, pass * 2 + 1, tmp);
111
- if (size == 2) {
112
- neon_store_reg(rd, pass * 2, tmp2);
113
- } else {
114
- switch (size) {
115
- case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
116
- case 1: gen_swap_half(tmp2); break;
117
- default: abort();
118
- }
119
- neon_store_reg(rd, pass * 2, tmp2);
120
- }
121
- }
122
- break;
123
+ /* handled by decodetree */
124
+ return 1;
125
case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
126
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
127
for (pass = 0; pass < q + 1; pass++) {
195
--
128
--
196
2.20.1
129
2.20.1
197
130
198
131
diff view generated by jsdifflib
1
For v8M floating point support, transitions from Secure
1
Convert the pairwise ops VPADDL and VPADAL in the 2-reg-misc grouping
2
to Non-secure state via BLNS and BLXNS must clear the
2
to decodetree.
3
CONTROL.SFPA bit. (This corresponds to the pseudocode
3
4
BranchToNS() function.)
4
At this point we can get rid of the weird CPU_V001 #define that was
5
used to avoid having to explicitly list all the arguments being
6
passed to some TCG gen/helper functions.
5
7
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-13-peter.maydell@linaro.org
10
Message-id: 20200616170844.13318-3-peter.maydell@linaro.org
9
---
11
---
10
target/arm/helper.c | 4 ++++
12
target/arm/neon-dp.decode | 6 ++
11
1 file changed, 4 insertions(+)
13
target/arm/translate-neon.inc.c | 149 ++++++++++++++++++++++++++++++++
12
14
target/arm/translate.c | 35 +-------
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
3 files changed, 157 insertions(+), 33 deletions(-)
16
17
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
19
--- a/target/arm/neon-dp.decode
16
+++ b/target/arm/helper.c
20
+++ b/target/arm/neon-dp.decode
17
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest)
21
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
18
/* translate.c should have made BXNS UNDEF unless we're secure */
22
&2misc vm=%vm_dp vd=%vd_dp
19
assert(env->v7m.secure);
23
20
24
VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
21
+ if (!(dest & 1)) {
25
+
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
26
+ VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc
23
+ }
27
+ VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc
24
switch_v7m_security_state(env, dest & 1);
28
+
25
env->thumb = 1;
29
+ VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
26
env->regs[15] = dest & ~1;
30
+ VPADAL_U 1111 001 11 . 11 .. 00 .... 0 1101 . . 0 .... @2misc
27
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
31
]
28
*/
32
29
write_v7m_exception(env, 1);
33
# Subgroup for size != 0b11
34
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-neon.inc.c
37
+++ b/target/arm/translate-neon.inc.c
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
30
}
39
}
31
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
40
return true;
32
switch_v7m_security_state(env, 0);
41
}
33
env->thumb = 1;
42
+
34
env->regs[15] = dest;
43
+static bool do_2misc_pairwise(DisasContext *s, arg_2misc *a,
44
+ NeonGenWidenFn *widenfn,
45
+ NeonGenTwo64OpFn *opfn,
46
+ NeonGenTwo64OpFn *accfn)
47
+{
48
+ /*
49
+ * Pairwise long operations: widen both halves of the pair,
50
+ * combine the pairs with the opfn, and then possibly accumulate
51
+ * into the destination with the accfn.
52
+ */
53
+ int pass;
54
+
55
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
56
+ return false;
57
+ }
58
+
59
+ /* UNDEF accesses to D16-D31 if they don't exist. */
60
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
61
+ ((a->vd | a->vm) & 0x10)) {
62
+ return false;
63
+ }
64
+
65
+ if ((a->vd | a->vm) & a->q) {
66
+ return false;
67
+ }
68
+
69
+ if (!widenfn) {
70
+ return false;
71
+ }
72
+
73
+ if (!vfp_access_check(s)) {
74
+ return true;
75
+ }
76
+
77
+ for (pass = 0; pass < a->q + 1; pass++) {
78
+ TCGv_i32 tmp;
79
+ TCGv_i64 rm0_64, rm1_64, rd_64;
80
+
81
+ rm0_64 = tcg_temp_new_i64();
82
+ rm1_64 = tcg_temp_new_i64();
83
+ rd_64 = tcg_temp_new_i64();
84
+ tmp = neon_load_reg(a->vm, pass * 2);
85
+ widenfn(rm0_64, tmp);
86
+ tcg_temp_free_i32(tmp);
87
+ tmp = neon_load_reg(a->vm, pass * 2 + 1);
88
+ widenfn(rm1_64, tmp);
89
+ tcg_temp_free_i32(tmp);
90
+ opfn(rd_64, rm0_64, rm1_64);
91
+ tcg_temp_free_i64(rm0_64);
92
+ tcg_temp_free_i64(rm1_64);
93
+
94
+ if (accfn) {
95
+ TCGv_i64 tmp64 = tcg_temp_new_i64();
96
+ neon_load_reg64(tmp64, a->vd + pass);
97
+ accfn(rd_64, tmp64, rd_64);
98
+ tcg_temp_free_i64(tmp64);
99
+ }
100
+ neon_store_reg64(rd_64, a->vd + pass);
101
+ tcg_temp_free_i64(rd_64);
102
+ }
103
+ return true;
104
+}
105
+
106
+static bool trans_VPADDL_S(DisasContext *s, arg_2misc *a)
107
+{
108
+ static NeonGenWidenFn * const widenfn[] = {
109
+ gen_helper_neon_widen_s8,
110
+ gen_helper_neon_widen_s16,
111
+ tcg_gen_ext_i32_i64,
112
+ NULL,
113
+ };
114
+ static NeonGenTwo64OpFn * const opfn[] = {
115
+ gen_helper_neon_paddl_u16,
116
+ gen_helper_neon_paddl_u32,
117
+ tcg_gen_add_i64,
118
+ NULL,
119
+ };
120
+
121
+ return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size], NULL);
122
+}
123
+
124
+static bool trans_VPADDL_U(DisasContext *s, arg_2misc *a)
125
+{
126
+ static NeonGenWidenFn * const widenfn[] = {
127
+ gen_helper_neon_widen_u8,
128
+ gen_helper_neon_widen_u16,
129
+ tcg_gen_extu_i32_i64,
130
+ NULL,
131
+ };
132
+ static NeonGenTwo64OpFn * const opfn[] = {
133
+ gen_helper_neon_paddl_u16,
134
+ gen_helper_neon_paddl_u32,
135
+ tcg_gen_add_i64,
136
+ NULL,
137
+ };
138
+
139
+ return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size], NULL);
140
+}
141
+
142
+static bool trans_VPADAL_S(DisasContext *s, arg_2misc *a)
143
+{
144
+ static NeonGenWidenFn * const widenfn[] = {
145
+ gen_helper_neon_widen_s8,
146
+ gen_helper_neon_widen_s16,
147
+ tcg_gen_ext_i32_i64,
148
+ NULL,
149
+ };
150
+ static NeonGenTwo64OpFn * const opfn[] = {
151
+ gen_helper_neon_paddl_u16,
152
+ gen_helper_neon_paddl_u32,
153
+ tcg_gen_add_i64,
154
+ NULL,
155
+ };
156
+ static NeonGenTwo64OpFn * const accfn[] = {
157
+ gen_helper_neon_addl_u16,
158
+ gen_helper_neon_addl_u32,
159
+ tcg_gen_add_i64,
160
+ NULL,
161
+ };
162
+
163
+ return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size],
164
+ accfn[a->size]);
165
+}
166
+
167
+static bool trans_VPADAL_U(DisasContext *s, arg_2misc *a)
168
+{
169
+ static NeonGenWidenFn * const widenfn[] = {
170
+ gen_helper_neon_widen_u8,
171
+ gen_helper_neon_widen_u16,
172
+ tcg_gen_extu_i32_i64,
173
+ NULL,
174
+ };
175
+ static NeonGenTwo64OpFn * const opfn[] = {
176
+ gen_helper_neon_paddl_u16,
177
+ gen_helper_neon_paddl_u32,
178
+ tcg_gen_add_i64,
179
+ NULL,
180
+ };
181
+ static NeonGenTwo64OpFn * const accfn[] = {
182
+ gen_helper_neon_addl_u16,
183
+ gen_helper_neon_addl_u32,
184
+ tcg_gen_add_i64,
185
+ NULL,
186
+ };
187
+
188
+ return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size],
189
+ accfn[a->size]);
190
+}
191
diff --git a/target/arm/translate.c b/target/arm/translate.c
192
index XXXXXXX..XXXXXXX 100644
193
--- a/target/arm/translate.c
194
+++ b/target/arm/translate.c
195
@@ -XXX,XX +XXX,XX @@ static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
196
gen_rfe(s, pc, load_cpu_field(spsr));
197
}
198
199
-#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
200
-
201
static int gen_neon_unzip(int rd, int rm, int size, int q)
202
{
203
TCGv_ptr pd, pm;
204
@@ -XXX,XX +XXX,XX @@ static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
205
tcg_temp_free_i32(src);
206
}
207
208
-static inline void gen_neon_addl(int size)
209
-{
210
- switch (size) {
211
- case 0: gen_helper_neon_addl_u16(CPU_V001); break;
212
- case 1: gen_helper_neon_addl_u32(CPU_V001); break;
213
- case 2: tcg_gen_add_i64(CPU_V001); break;
214
- default: abort();
215
- }
216
-}
217
-
218
static void gen_neon_narrow_op(int op, int u, int size,
219
TCGv_i32 dest, TCGv_i64 src)
220
{
221
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
222
}
223
switch (op) {
224
case NEON_2RM_VREV64:
225
- /* handled by decodetree */
226
- return 1;
227
case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
228
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
229
- for (pass = 0; pass < q + 1; pass++) {
230
- tmp = neon_load_reg(rm, pass * 2);
231
- gen_neon_widen(cpu_V0, tmp, size, op & 1);
232
- tmp = neon_load_reg(rm, pass * 2 + 1);
233
- gen_neon_widen(cpu_V1, tmp, size, op & 1);
234
- switch (size) {
235
- case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
236
- case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
237
- case 2: tcg_gen_add_i64(CPU_V001); break;
238
- default: abort();
239
- }
240
- if (op >= NEON_2RM_VPADAL) {
241
- /* Accumulate. */
242
- neon_load_reg64(cpu_V1, rd + pass);
243
- gen_neon_addl(size);
244
- }
245
- neon_store_reg64(cpu_V0, rd + pass);
246
- }
247
- break;
248
+ /* handled by decodetree */
249
+ return 1;
250
case NEON_2RM_VTRN:
251
if (size == 2) {
252
int n;
35
--
253
--
36
2.20.1
254
2.20.1
37
255
38
256
diff view generated by jsdifflib
1
Enable the FPU by default for the Cortex-M4 and Cortex-M33.
1
Convert the Neon VZIP and VUZP insns in the 2-reg-misc group 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: 20200616170844.13318-4-peter.maydell@linaro.org
6
---
7
---
7
target/arm/cpu.c | 8 ++++++++
8
target/arm/neon-dp.decode | 3 ++
8
1 file changed, 8 insertions(+)
9
target/arm/translate-neon.inc.c | 74 ++++++++++++++++++++++++++
9
10
target/arm/translate.c | 92 +--------------------------------
10
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
11
3 files changed, 79 insertions(+), 90 deletions(-)
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
11
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
12
--- a/target/arm/cpu.c
15
--- a/target/arm/neon-dp.decode
13
+++ b/target/arm/cpu.c
16
+++ b/target/arm/neon-dp.decode
14
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
15
set_feature(&cpu->env, ARM_FEATURE_M);
18
16
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
19
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
17
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
20
VPADAL_U 1111 001 11 . 11 .. 00 .... 0 1101 . . 0 .... @2misc
18
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
21
+
19
cpu->midr = 0x410fc240; /* r0p0 */
22
+ VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
20
cpu->pmsav7_dregion = 8;
23
+ VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
21
+ cpu->isar.mvfr0 = 0x10110021;
24
]
22
+ cpu->isar.mvfr1 = 0x11000011;
25
23
+ cpu->isar.mvfr2 = 0x00000000;
26
# Subgroup for size != 0b11
24
cpu->id_pfr0 = 0x00000030;
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
25
cpu->id_pfr1 = 0x00000200;
28
index XXXXXXX..XXXXXXX 100644
26
cpu->id_dfr0 = 0x00100000;
29
--- a/target/arm/translate-neon.inc.c
27
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
30
+++ b/target/arm/translate-neon.inc.c
28
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
31
@@ -XXX,XX +XXX,XX @@ static bool trans_VPADAL_U(DisasContext *s, arg_2misc *a)
29
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
32
return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size],
30
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
33
accfn[a->size]);
31
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
34
}
32
cpu->midr = 0x410fd213; /* r0p3 */
35
+
33
cpu->pmsav7_dregion = 16;
36
+typedef void ZipFn(TCGv_ptr, TCGv_ptr);
34
cpu->sau_sregion = 8;
37
+
35
+ cpu->isar.mvfr0 = 0x10110021;
38
+static bool do_zip_uzp(DisasContext *s, arg_2misc *a,
36
+ cpu->isar.mvfr1 = 0x11000011;
39
+ ZipFn *fn)
37
+ cpu->isar.mvfr2 = 0x00000040;
40
+{
38
cpu->id_pfr0 = 0x00000030;
41
+ TCGv_ptr pd, pm;
39
cpu->id_pfr1 = 0x00000210;
42
+
40
cpu->id_dfr0 = 0x00200000;
43
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
44
+ return false;
45
+ }
46
+
47
+ /* UNDEF accesses to D16-D31 if they don't exist. */
48
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
49
+ ((a->vd | a->vm) & 0x10)) {
50
+ return false;
51
+ }
52
+
53
+ if ((a->vd | a->vm) & a->q) {
54
+ return false;
55
+ }
56
+
57
+ if (!fn) {
58
+ /* Bad size or size/q combination */
59
+ return false;
60
+ }
61
+
62
+ if (!vfp_access_check(s)) {
63
+ return true;
64
+ }
65
+
66
+ pd = vfp_reg_ptr(true, a->vd);
67
+ pm = vfp_reg_ptr(true, a->vm);
68
+ fn(pd, pm);
69
+ tcg_temp_free_ptr(pd);
70
+ tcg_temp_free_ptr(pm);
71
+ return true;
72
+}
73
+
74
+static bool trans_VUZP(DisasContext *s, arg_2misc *a)
75
+{
76
+ static ZipFn * const fn[2][4] = {
77
+ {
78
+ gen_helper_neon_unzip8,
79
+ gen_helper_neon_unzip16,
80
+ NULL,
81
+ NULL,
82
+ }, {
83
+ gen_helper_neon_qunzip8,
84
+ gen_helper_neon_qunzip16,
85
+ gen_helper_neon_qunzip32,
86
+ NULL,
87
+ }
88
+ };
89
+ return do_zip_uzp(s, a, fn[a->q][a->size]);
90
+}
91
+
92
+static bool trans_VZIP(DisasContext *s, arg_2misc *a)
93
+{
94
+ static ZipFn * const fn[2][4] = {
95
+ {
96
+ gen_helper_neon_zip8,
97
+ gen_helper_neon_zip16,
98
+ NULL,
99
+ NULL,
100
+ }, {
101
+ gen_helper_neon_qzip8,
102
+ gen_helper_neon_qzip16,
103
+ gen_helper_neon_qzip32,
104
+ NULL,
105
+ }
106
+ };
107
+ return do_zip_uzp(s, a, fn[a->q][a->size]);
108
+}
109
diff --git a/target/arm/translate.c b/target/arm/translate.c
110
index XXXXXXX..XXXXXXX 100644
111
--- a/target/arm/translate.c
112
+++ b/target/arm/translate.c
113
@@ -XXX,XX +XXX,XX @@ static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
114
gen_rfe(s, pc, load_cpu_field(spsr));
115
}
116
117
-static int gen_neon_unzip(int rd, int rm, int size, int q)
118
-{
119
- TCGv_ptr pd, pm;
120
-
121
- if (!q && size == 2) {
122
- return 1;
123
- }
124
- pd = vfp_reg_ptr(true, rd);
125
- pm = vfp_reg_ptr(true, rm);
126
- if (q) {
127
- switch (size) {
128
- case 0:
129
- gen_helper_neon_qunzip8(pd, pm);
130
- break;
131
- case 1:
132
- gen_helper_neon_qunzip16(pd, pm);
133
- break;
134
- case 2:
135
- gen_helper_neon_qunzip32(pd, pm);
136
- break;
137
- default:
138
- abort();
139
- }
140
- } else {
141
- switch (size) {
142
- case 0:
143
- gen_helper_neon_unzip8(pd, pm);
144
- break;
145
- case 1:
146
- gen_helper_neon_unzip16(pd, pm);
147
- break;
148
- default:
149
- abort();
150
- }
151
- }
152
- tcg_temp_free_ptr(pd);
153
- tcg_temp_free_ptr(pm);
154
- return 0;
155
-}
156
-
157
-static int gen_neon_zip(int rd, int rm, int size, int q)
158
-{
159
- TCGv_ptr pd, pm;
160
-
161
- if (!q && size == 2) {
162
- return 1;
163
- }
164
- pd = vfp_reg_ptr(true, rd);
165
- pm = vfp_reg_ptr(true, rm);
166
- if (q) {
167
- switch (size) {
168
- case 0:
169
- gen_helper_neon_qzip8(pd, pm);
170
- break;
171
- case 1:
172
- gen_helper_neon_qzip16(pd, pm);
173
- break;
174
- case 2:
175
- gen_helper_neon_qzip32(pd, pm);
176
- break;
177
- default:
178
- abort();
179
- }
180
- } else {
181
- switch (size) {
182
- case 0:
183
- gen_helper_neon_zip8(pd, pm);
184
- break;
185
- case 1:
186
- gen_helper_neon_zip16(pd, pm);
187
- break;
188
- default:
189
- abort();
190
- }
191
- }
192
- tcg_temp_free_ptr(pd);
193
- tcg_temp_free_ptr(pm);
194
- return 0;
195
-}
196
-
197
static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
198
{
199
TCGv_i32 rd, tmp;
200
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
201
case NEON_2RM_VREV64:
202
case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
203
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
204
+ case NEON_2RM_VUZP:
205
+ case NEON_2RM_VZIP:
206
/* handled by decodetree */
207
return 1;
208
case NEON_2RM_VTRN:
209
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
210
goto elementwise;
211
}
212
break;
213
- case NEON_2RM_VUZP:
214
- if (gen_neon_unzip(rd, rm, size, q)) {
215
- return 1;
216
- }
217
- break;
218
- case NEON_2RM_VZIP:
219
- if (gen_neon_zip(rd, rm, size, q)) {
220
- return 1;
221
- }
222
- break;
223
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
224
/* also VQMOVUN; op field and mnemonics don't line up */
225
if (rm & 1) {
41
--
226
--
42
2.20.1
227
2.20.1
43
228
44
229
diff view generated by jsdifflib
1
For M-profile the MVFR* ID registers are memory mapped, in the
1
Convert the Neon narrowing moves VMQNV, VQMOVN, VQMOVUN in the 2-reg-misc
2
range we implement via the NVIC. Allow them to be read.
2
group to decodetree.
3
(If the CPU has no FPU, these registers are defined to be RAZ.)
4
3
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190416125744.27770-3-peter.maydell@linaro.org
6
Message-id: 20200616170844.13318-5-peter.maydell@linaro.org
8
---
7
---
9
hw/intc/armv7m_nvic.c | 6 ++++++
8
target/arm/neon-dp.decode | 9 ++++
10
1 file changed, 6 insertions(+)
9
target/arm/translate-neon.inc.c | 59 ++++++++++++++++++++++++
11
10
target/arm/translate.c | 81 +--------------------------------
12
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
11
3 files changed, 70 insertions(+), 79 deletions(-)
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
13
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/intc/armv7m_nvic.c
15
--- a/target/arm/neon-dp.decode
15
+++ b/hw/intc/armv7m_nvic.c
16
+++ b/target/arm/neon-dp.decode
16
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
17
return 0;
18
18
}
19
@2misc .... ... .. . .. size:2 .. .... . .... q:1 . . .... \
19
return cpu->env.v7m.sfar;
20
&2misc vm=%vm_dp vd=%vd_dp
20
+ case 0xf40: /* MVFR0 */
21
+ @2misc_q0 .... ... .. . .. size:2 .. .... . .... . . . .... \
21
+ return cpu->isar.mvfr0;
22
+ &2misc vm=%vm_dp vd=%vd_dp q=0
22
+ case 0xf44: /* MVFR1 */
23
23
+ return cpu->isar.mvfr1;
24
VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
24
+ case 0xf48: /* MVFR2 */
25
25
+ return cpu->isar.mvfr2;
26
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
26
default:
27
27
bad_offset:
28
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
28
qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
29
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
30
+
31
+ VMOVN 1111 001 11 . 11 .. 10 .... 0 0100 0 . 0 .... @2misc_q0
32
+ # VQMOVUN: unsigned result (source is always signed)
33
+ VQMOVUN 1111 001 11 . 11 .. 10 .... 0 0100 1 . 0 .... @2misc_q0
34
+ # VQMOVN: signed result, source may be signed (_S) or unsigned (_U)
35
+ VQMOVN_S 1111 001 11 . 11 .. 10 .... 0 0101 0 . 0 .... @2misc_q0
36
+ VQMOVN_U 1111 001 11 . 11 .. 10 .... 0 0101 1 . 0 .... @2misc_q0
37
]
38
39
# Subgroup for size != 0b11
40
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate-neon.inc.c
43
+++ b/target/arm/translate-neon.inc.c
44
@@ -XXX,XX +XXX,XX @@ static bool trans_VZIP(DisasContext *s, arg_2misc *a)
45
};
46
return do_zip_uzp(s, a, fn[a->q][a->size]);
47
}
48
+
49
+static bool do_vmovn(DisasContext *s, arg_2misc *a,
50
+ NeonGenNarrowEnvFn *narrowfn)
51
+{
52
+ TCGv_i64 rm;
53
+ TCGv_i32 rd0, rd1;
54
+
55
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
56
+ return false;
57
+ }
58
+
59
+ /* UNDEF accesses to D16-D31 if they don't exist. */
60
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
61
+ ((a->vd | a->vm) & 0x10)) {
62
+ return false;
63
+ }
64
+
65
+ if (a->vm & 1) {
66
+ return false;
67
+ }
68
+
69
+ if (!narrowfn) {
70
+ return false;
71
+ }
72
+
73
+ if (!vfp_access_check(s)) {
74
+ return true;
75
+ }
76
+
77
+ rm = tcg_temp_new_i64();
78
+ rd0 = tcg_temp_new_i32();
79
+ rd1 = tcg_temp_new_i32();
80
+
81
+ neon_load_reg64(rm, a->vm);
82
+ narrowfn(rd0, cpu_env, rm);
83
+ neon_load_reg64(rm, a->vm + 1);
84
+ narrowfn(rd1, cpu_env, rm);
85
+ neon_store_reg(a->vd, 0, rd0);
86
+ neon_store_reg(a->vd, 1, rd1);
87
+ tcg_temp_free_i64(rm);
88
+ return true;
89
+}
90
+
91
+#define DO_VMOVN(INSN, FUNC) \
92
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
93
+ { \
94
+ static NeonGenNarrowEnvFn * const narrowfn[] = { \
95
+ FUNC##8, \
96
+ FUNC##16, \
97
+ FUNC##32, \
98
+ NULL, \
99
+ }; \
100
+ return do_vmovn(s, a, narrowfn[a->size]); \
101
+ }
102
+
103
+DO_VMOVN(VMOVN, gen_neon_narrow_u)
104
+DO_VMOVN(VQMOVUN, gen_helper_neon_unarrow_sat)
105
+DO_VMOVN(VQMOVN_S, gen_helper_neon_narrow_sat_s)
106
+DO_VMOVN(VQMOVN_U, gen_helper_neon_narrow_sat_u)
107
diff --git a/target/arm/translate.c b/target/arm/translate.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/target/arm/translate.c
110
+++ b/target/arm/translate.c
111
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
112
tcg_temp_free_i32(rd);
113
}
114
115
-static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
116
-{
117
- switch (size) {
118
- case 0: gen_helper_neon_narrow_u8(dest, src); break;
119
- case 1: gen_helper_neon_narrow_u16(dest, src); break;
120
- case 2: tcg_gen_extrl_i64_i32(dest, src); break;
121
- default: abort();
122
- }
123
-}
124
-
125
-static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
126
-{
127
- switch (size) {
128
- case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
129
- case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
130
- case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
131
- default: abort();
132
- }
133
-}
134
-
135
-static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
136
-{
137
- switch (size) {
138
- case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
139
- case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
140
- case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
141
- default: abort();
142
- }
143
-}
144
-
145
-static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
146
-{
147
- switch (size) {
148
- case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
149
- case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
150
- case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
151
- default: abort();
152
- }
153
-}
154
-
155
static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
156
{
157
if (u) {
158
@@ -XXX,XX +XXX,XX @@ static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
159
tcg_temp_free_i32(src);
160
}
161
162
-static void gen_neon_narrow_op(int op, int u, int size,
163
- TCGv_i32 dest, TCGv_i64 src)
164
-{
165
- if (op) {
166
- if (u) {
167
- gen_neon_unarrow_sats(size, dest, src);
168
- } else {
169
- gen_neon_narrow(size, dest, src);
170
- }
171
- } else {
172
- if (u) {
173
- gen_neon_narrow_satu(size, dest, src);
174
- } else {
175
- gen_neon_narrow_sats(size, dest, src);
176
- }
177
- }
178
-}
179
-
180
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
181
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
182
* table A7-13.
183
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
184
!arm_dc_feature(s, ARM_FEATURE_V8)) {
185
return 1;
186
}
187
- if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
188
- q && ((rm | rd) & 1)) {
189
+ if (q && ((rm | rd) & 1)) {
190
return 1;
191
}
192
switch (op) {
193
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
194
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
195
case NEON_2RM_VUZP:
196
case NEON_2RM_VZIP:
197
+ case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
198
/* handled by decodetree */
199
return 1;
200
case NEON_2RM_VTRN:
201
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
202
goto elementwise;
203
}
204
break;
205
- case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
206
- /* also VQMOVUN; op field and mnemonics don't line up */
207
- if (rm & 1) {
208
- return 1;
209
- }
210
- tmp2 = NULL;
211
- for (pass = 0; pass < 2; pass++) {
212
- neon_load_reg64(cpu_V0, rm + pass);
213
- tmp = tcg_temp_new_i32();
214
- gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
215
- tmp, cpu_V0);
216
- if (pass == 0) {
217
- tmp2 = tmp;
218
- } else {
219
- neon_store_reg(rd, 0, tmp2);
220
- neon_store_reg(rd, 1, tmp);
221
- }
222
- }
223
- break;
224
case NEON_2RM_VSHLL:
225
if (q || (rd & 1)) {
226
return 1;
29
--
227
--
30
2.20.1
228
2.20.1
31
229
32
230
diff view generated by jsdifflib
1
Enforce that for M-profile various FPSCR bits which are RES0 there
1
Convert the VSHLL insn in the 2-reg-misc Neon group to decodetree.
2
but have defined meanings on A-profile are never settable. This
3
ensures that M-profile code can't enable the A-profile behaviour
4
(notably vector length/stride handling) by accident.
5
2
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-2-peter.maydell@linaro.org
5
Message-id: 20200616170844.13318-6-peter.maydell@linaro.org
9
---
6
---
10
target/arm/vfp_helper.c | 8 ++++++++
7
target/arm/neon-dp.decode | 2 ++
11
1 file changed, 8 insertions(+)
8
target/arm/translate-neon.inc.c | 52 +++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 35 +---------------------
10
3 files changed, 55 insertions(+), 34 deletions(-)
12
11
13
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
12
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/vfp_helper.c
14
--- a/target/arm/neon-dp.decode
16
+++ b/target/arm/vfp_helper.c
15
+++ b/target/arm/neon-dp.decode
17
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
16
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
18
val &= ~FPCR_FZ16;
17
# VQMOVN: signed result, source may be signed (_S) or unsigned (_U)
19
}
18
VQMOVN_S 1111 001 11 . 11 .. 10 .... 0 0101 0 . 0 .... @2misc_q0
20
19
VQMOVN_U 1111 001 11 . 11 .. 10 .... 0 0101 1 . 0 .... @2misc_q0
21
+ if (arm_feature(env, ARM_FEATURE_M)) {
20
+
22
+ /*
21
+ VSHLL 1111 001 11 . 11 .. 10 .... 0 0110 0 . 0 .... @2misc_q0
23
+ * M profile FPSCR is RES0 for the QC, STRIDE, FZ16, LEN bits
22
]
24
+ * and also for the trapped-exception-handling bits IxE.
23
25
+ */
24
# Subgroup for size != 0b11
26
+ val &= 0xf7c0009f;
25
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/translate-neon.inc.c
28
+++ b/target/arm/translate-neon.inc.c
29
@@ -XXX,XX +XXX,XX @@ DO_VMOVN(VMOVN, gen_neon_narrow_u)
30
DO_VMOVN(VQMOVUN, gen_helper_neon_unarrow_sat)
31
DO_VMOVN(VQMOVN_S, gen_helper_neon_narrow_sat_s)
32
DO_VMOVN(VQMOVN_U, gen_helper_neon_narrow_sat_u)
33
+
34
+static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
35
+{
36
+ TCGv_i32 rm0, rm1;
37
+ TCGv_i64 rd;
38
+ static NeonGenWidenFn * const widenfns[] = {
39
+ gen_helper_neon_widen_u8,
40
+ gen_helper_neon_widen_u16,
41
+ tcg_gen_extu_i32_i64,
42
+ NULL,
43
+ };
44
+ NeonGenWidenFn *widenfn = widenfns[a->size];
45
+
46
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
47
+ return false;
27
+ }
48
+ }
28
+
49
+
29
/*
50
+ /* UNDEF accesses to D16-D31 if they don't exist. */
30
* We don't implement trapped exception handling, so the
51
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
31
* trap enable bits, IDE|IXE|UFE|OFE|DZE|IOE are all RAZ/WI (not RES0!)
52
+ ((a->vd | a->vm) & 0x10)) {
53
+ return false;
54
+ }
55
+
56
+ if (a->vd & 1) {
57
+ return false;
58
+ }
59
+
60
+ if (!widenfn) {
61
+ return false;
62
+ }
63
+
64
+ if (!vfp_access_check(s)) {
65
+ return true;
66
+ }
67
+
68
+ rd = tcg_temp_new_i64();
69
+
70
+ rm0 = neon_load_reg(a->vm, 0);
71
+ rm1 = neon_load_reg(a->vm, 1);
72
+
73
+ widenfn(rd, rm0);
74
+ tcg_gen_shli_i64(rd, rd, 8 << a->size);
75
+ neon_store_reg64(rd, a->vd);
76
+ widenfn(rd, rm1);
77
+ tcg_gen_shli_i64(rd, rd, 8 << a->size);
78
+ neon_store_reg64(rd, a->vd + 1);
79
+
80
+ tcg_temp_free_i64(rd);
81
+ tcg_temp_free_i32(rm0);
82
+ tcg_temp_free_i32(rm1);
83
+ return true;
84
+}
85
diff --git a/target/arm/translate.c b/target/arm/translate.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/target/arm/translate.c
88
+++ b/target/arm/translate.c
89
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
90
tcg_temp_free_i32(rd);
91
}
92
93
-static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
94
-{
95
- if (u) {
96
- switch (size) {
97
- case 0: gen_helper_neon_widen_u8(dest, src); break;
98
- case 1: gen_helper_neon_widen_u16(dest, src); break;
99
- case 2: tcg_gen_extu_i32_i64(dest, src); break;
100
- default: abort();
101
- }
102
- } else {
103
- switch (size) {
104
- case 0: gen_helper_neon_widen_s8(dest, src); break;
105
- case 1: gen_helper_neon_widen_s16(dest, src); break;
106
- case 2: tcg_gen_ext_i32_i64(dest, src); break;
107
- default: abort();
108
- }
109
- }
110
- tcg_temp_free_i32(src);
111
-}
112
-
113
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
114
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
115
* table A7-13.
116
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
117
case NEON_2RM_VUZP:
118
case NEON_2RM_VZIP:
119
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
120
+ case NEON_2RM_VSHLL:
121
/* handled by decodetree */
122
return 1;
123
case NEON_2RM_VTRN:
124
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
125
goto elementwise;
126
}
127
break;
128
- case NEON_2RM_VSHLL:
129
- if (q || (rd & 1)) {
130
- return 1;
131
- }
132
- tmp = neon_load_reg(rm, 0);
133
- tmp2 = neon_load_reg(rm, 1);
134
- for (pass = 0; pass < 2; pass++) {
135
- if (pass == 1)
136
- tmp = tmp2;
137
- gen_neon_widen(cpu_V0, tmp, size, 1);
138
- tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
139
- neon_store_reg64(cpu_V0, rd + pass);
140
- }
141
- break;
142
case NEON_2RM_VCVT_F16_F32:
143
{
144
TCGv_ptr fpst;
32
--
145
--
33
2.20.1
146
2.20.1
34
147
35
148
diff view generated by jsdifflib
1
Like AArch64, M-profile floating point has no FPEXC enable
1
Convert the Neon insns in the 2-reg-misc group which are
2
bit to gate floating point; so always set the VFPEN TB flag.
2
VCVT between f32 and f16 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: 20200616170844.13318-7-peter.maydell@linaro.org
19
---
7
---
20
target/arm/helper.c | 55 +++++++++++++++++++++++++++++++++++++++---
8
target/arm/neon-dp.decode | 3 ++
21
target/arm/translate.c | 10 ++++++--
9
target/arm/translate-neon.inc.c | 96 +++++++++++++++++++++++++++++++++
22
2 files changed, 60 insertions(+), 5 deletions(-)
10
target/arm/translate.c | 65 ++--------------------
23
11
3 files changed, 102 insertions(+), 62 deletions(-)
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
25
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.c
15
--- a/target/arm/neon-dp.decode
27
+++ b/target/arm/helper.c
16
+++ b/target/arm/neon-dp.decode
28
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
29
return target_el;
18
VQMOVN_U 1111 001 11 . 11 .. 10 .... 0 0101 1 . 0 .... @2misc_q0
19
20
VSHLL 1111 001 11 . 11 .. 10 .... 0 0110 0 . 0 .... @2misc_q0
21
+
22
+ VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
23
+ VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
24
]
25
26
# Subgroup for size != 0b11
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/translate-neon.inc.c
30
+++ b/target/arm/translate-neon.inc.c
31
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
32
tcg_temp_free_i32(rm1);
33
return true;
30
}
34
}
31
35
+
32
+/*
36
+static bool trans_VCVT_F16_F32(DisasContext *s, arg_2misc *a)
33
+ * Return true if the v7M CPACR permits access to the FPU for the specified
34
+ * security state and privilege level.
35
+ */
36
+static bool v7m_cpacr_pass(CPUARMState *env, bool is_secure, bool is_priv)
37
+{
37
+{
38
+ switch (extract32(env->v7m.cpacr[is_secure], 20, 2)) {
38
+ TCGv_ptr fpst;
39
+ case 0:
39
+ TCGv_i32 ahp, tmp, tmp2, tmp3;
40
+ case 2: /* UNPREDICTABLE: we treat like 0 */
40
+
41
+ return false;
41
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
42
+ case 1:
42
+ !dc_isar_feature(aa32_fp16_spconv, s)) {
43
+ return is_priv;
43
+ return false;
44
+ case 3:
44
+ }
45
+
46
+ /* UNDEF accesses to D16-D31 if they don't exist. */
47
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
48
+ ((a->vd | a->vm) & 0x10)) {
49
+ return false;
50
+ }
51
+
52
+ if ((a->vm & 1) || (a->size != 1)) {
53
+ return false;
54
+ }
55
+
56
+ if (!vfp_access_check(s)) {
45
+ return true;
57
+ return true;
46
+ default:
58
+ }
47
+ g_assert_not_reached();
59
+
48
+ }
60
+ fpst = get_fpstatus_ptr(true);
61
+ ahp = get_ahp_flag();
62
+ tmp = neon_load_reg(a->vm, 0);
63
+ gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
64
+ tmp2 = neon_load_reg(a->vm, 1);
65
+ gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
66
+ tcg_gen_shli_i32(tmp2, tmp2, 16);
67
+ tcg_gen_or_i32(tmp2, tmp2, tmp);
68
+ tcg_temp_free_i32(tmp);
69
+ tmp = neon_load_reg(a->vm, 2);
70
+ gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
71
+ tmp3 = neon_load_reg(a->vm, 3);
72
+ neon_store_reg(a->vd, 0, tmp2);
73
+ gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
74
+ tcg_gen_shli_i32(tmp3, tmp3, 16);
75
+ tcg_gen_or_i32(tmp3, tmp3, tmp);
76
+ neon_store_reg(a->vd, 1, tmp3);
77
+ tcg_temp_free_i32(tmp);
78
+ tcg_temp_free_i32(ahp);
79
+ tcg_temp_free_ptr(fpst);
80
+
81
+ return true;
49
+}
82
+}
50
+
83
+
51
static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
84
+static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a)
52
ARMMMUIdx mmu_idx, bool ignfault)
85
+{
53
{
86
+ TCGv_ptr fpst;
54
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
87
+ TCGv_i32 ahp, tmp, tmp2, tmp3;
55
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNDEFINSTR_MASK;
88
+
56
break;
89
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
57
case EXCP_NOCP:
90
+ !dc_isar_feature(aa32_fp16_spconv, s)) {
58
- armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
91
+ return false;
59
- env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_NOCP_MASK;
92
+ }
60
+ {
93
+
61
+ /*
94
+ /* UNDEF accesses to D16-D31 if they don't exist. */
62
+ * NOCP might be directed to something other than the current
95
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
63
+ * security state if this fault is because of NSACR; we indicate
96
+ ((a->vd | a->vm) & 0x10)) {
64
+ * the target security state using exception.target_el.
97
+ return false;
65
+ */
98
+ }
66
+ int target_secstate;
99
+
67
+
100
+ if ((a->vd & 1) || (a->size != 1)) {
68
+ if (env->exception.target_el == 3) {
101
+ return false;
69
+ target_secstate = M_REG_S;
102
+ }
70
+ } else {
103
+
71
+ target_secstate = env->v7m.secure;
104
+ if (!vfp_access_check(s)) {
72
+ }
105
+ return true;
73
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, target_secstate);
106
+ }
74
+ env->v7m.cfsr[target_secstate] |= R_V7M_CFSR_NOCP_MASK;
107
+
75
break;
108
+ fpst = get_fpstatus_ptr(true);
76
+ }
109
+ ahp = get_ahp_flag();
77
case EXCP_INVSTATE:
110
+ tmp3 = tcg_temp_new_i32();
78
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
111
+ tmp = neon_load_reg(a->vm, 0);
79
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVSTATE_MASK;
112
+ tmp2 = neon_load_reg(a->vm, 1);
80
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
113
+ tcg_gen_ext16u_i32(tmp3, tmp);
81
return 0;
114
+ gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
82
}
115
+ neon_store_reg(a->vd, 0, tmp3);
83
116
+ tcg_gen_shri_i32(tmp, tmp, 16);
84
+ if (arm_feature(env, ARM_FEATURE_M)) {
117
+ gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
85
+ /* CPACR can cause a NOCP UsageFault taken to current security state */
118
+ neon_store_reg(a->vd, 1, tmp);
86
+ if (!v7m_cpacr_pass(env, env->v7m.secure, cur_el != 0)) {
119
+ tmp3 = tcg_temp_new_i32();
87
+ return 1;
120
+ tcg_gen_ext16u_i32(tmp3, tmp2);
88
+ }
121
+ gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
89
+
122
+ neon_store_reg(a->vd, 2, tmp3);
90
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) && !env->v7m.secure) {
123
+ tcg_gen_shri_i32(tmp2, tmp2, 16);
91
+ if (!extract32(env->v7m.nsacr, 10, 1)) {
124
+ gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
92
+ /* FP insns cause a NOCP UsageFault taken to Secure */
125
+ neon_store_reg(a->vd, 3, tmp2);
93
+ return 3;
126
+ tcg_temp_free_i32(ahp);
94
+ }
127
+ tcg_temp_free_ptr(fpst);
95
+ }
128
+
96
+
129
+ return true;
97
+ return 0;
130
+}
98
+ }
99
+
100
/* The CPACR controls traps to EL1, or PL1 if we're 32 bit:
101
* 0, 2 : trap EL0 and EL1/PL1 accesses
102
* 1 : trap only EL0 accesses
103
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
104
flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, arm_sctlr_b(env));
105
flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
106
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
107
- || arm_el_is_aa64(env, 1)) {
108
+ || arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
109
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
110
}
111
flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
112
diff --git a/target/arm/translate.c b/target/arm/translate.c
131
diff --git a/target/arm/translate.c b/target/arm/translate.c
113
index XXXXXXX..XXXXXXX 100644
132
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/translate.c
133
--- a/target/arm/translate.c
115
+++ b/target/arm/translate.c
134
+++ b/target/arm/translate.c
116
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
135
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
117
* for attempts to execute invalid vfp/neon encodings with FP disabled.
136
int pass;
118
*/
137
int u;
119
if (s->fp_excp_el) {
138
int vec_size;
120
- gen_exception_insn(s, 4, EXCP_UDEF,
139
- TCGv_i32 tmp, tmp2, tmp3;
121
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
140
+ TCGv_i32 tmp, tmp2;
122
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
141
123
+ gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
142
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
124
+ s->fp_excp_el);
143
return 1;
125
+ } else {
144
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
126
+ gen_exception_insn(s, 4, EXCP_UDEF,
145
case NEON_2RM_VZIP:
127
+ syn_fp_access_trap(1, 0xe, false),
146
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
128
+ s->fp_excp_el);
147
case NEON_2RM_VSHLL:
129
+ }
148
+ case NEON_2RM_VCVT_F16_F32:
130
return 0;
149
+ case NEON_2RM_VCVT_F32_F16:
131
}
150
/* handled by decodetree */
132
151
return 1;
152
case NEON_2RM_VTRN:
153
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
154
goto elementwise;
155
}
156
break;
157
- case NEON_2RM_VCVT_F16_F32:
158
- {
159
- TCGv_ptr fpst;
160
- TCGv_i32 ahp;
161
-
162
- if (!dc_isar_feature(aa32_fp16_spconv, s) ||
163
- q || (rm & 1)) {
164
- return 1;
165
- }
166
- fpst = get_fpstatus_ptr(true);
167
- ahp = get_ahp_flag();
168
- tmp = neon_load_reg(rm, 0);
169
- gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
170
- tmp2 = neon_load_reg(rm, 1);
171
- gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
172
- tcg_gen_shli_i32(tmp2, tmp2, 16);
173
- tcg_gen_or_i32(tmp2, tmp2, tmp);
174
- tcg_temp_free_i32(tmp);
175
- tmp = neon_load_reg(rm, 2);
176
- gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
177
- tmp3 = neon_load_reg(rm, 3);
178
- neon_store_reg(rd, 0, tmp2);
179
- gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
180
- tcg_gen_shli_i32(tmp3, tmp3, 16);
181
- tcg_gen_or_i32(tmp3, tmp3, tmp);
182
- neon_store_reg(rd, 1, tmp3);
183
- tcg_temp_free_i32(tmp);
184
- tcg_temp_free_i32(ahp);
185
- tcg_temp_free_ptr(fpst);
186
- break;
187
- }
188
- case NEON_2RM_VCVT_F32_F16:
189
- {
190
- TCGv_ptr fpst;
191
- TCGv_i32 ahp;
192
- if (!dc_isar_feature(aa32_fp16_spconv, s) ||
193
- q || (rd & 1)) {
194
- return 1;
195
- }
196
- fpst = get_fpstatus_ptr(true);
197
- ahp = get_ahp_flag();
198
- tmp3 = tcg_temp_new_i32();
199
- tmp = neon_load_reg(rm, 0);
200
- tmp2 = neon_load_reg(rm, 1);
201
- tcg_gen_ext16u_i32(tmp3, tmp);
202
- gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
203
- neon_store_reg(rd, 0, tmp3);
204
- tcg_gen_shri_i32(tmp, tmp, 16);
205
- gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
206
- neon_store_reg(rd, 1, tmp);
207
- tmp3 = tcg_temp_new_i32();
208
- tcg_gen_ext16u_i32(tmp3, tmp2);
209
- gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
210
- neon_store_reg(rd, 2, tmp3);
211
- tcg_gen_shri_i32(tmp2, tmp2, 16);
212
- gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
213
- neon_store_reg(rd, 3, tmp2);
214
- tcg_temp_free_i32(ahp);
215
- tcg_temp_free_ptr(fpst);
216
- break;
217
- }
218
case NEON_2RM_AESE: case NEON_2RM_AESMC:
219
if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
220
return 1;
133
--
221
--
134
2.20.1
222
2.20.1
135
223
136
224
diff view generated by jsdifflib
1
Implement the code which updates the FPCCR register on an
1
Convert to decodetree the insns in the Neon 2-reg-misc grouping which
2
exception entry where we are going to use lazy FP stacking.
2
we implement using gvec.
3
We have to defer to the NVIC to determine whether the
4
various exceptions are currently ready or not.
5
3
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20190416125744.27770-12-peter.maydell@linaro.org
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-8-peter.maydell@linaro.org
8
---
7
---
9
target/arm/cpu.h | 14 +++++++++
8
target/arm/neon-dp.decode | 11 +++++++
10
hw/intc/armv7m_nvic.c | 34 ++++++++++++++++++++++
9
target/arm/translate-neon.inc.c | 55 +++++++++++++++++++++++++++++++++
11
target/arm/helper.c | 67 ++++++++++++++++++++++++++++++++++++++++++-
10
target/arm/translate.c | 35 +++++----------------
12
3 files changed, 114 insertions(+), 1 deletion(-)
11
3 files changed, 74 insertions(+), 27 deletions(-)
13
12
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
15
--- a/target/arm/neon-dp.decode
17
+++ b/target/arm/cpu.h
16
+++ b/target/arm/neon-dp.decode
18
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_acknowledge_irq(void *opaque);
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
19
* (Ignoring -1, this is the same as the RETTOBASE value before completion.)
18
VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc
20
*/
19
VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc
21
int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure);
20
22
+/**
21
+ VMVN 1111 001 11 . 11 .. 00 .... 0 1011 . . 0 .... @2misc
23
+ * armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
22
+
24
+ * @opaque: the NVIC
23
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
25
+ * @irq: the exception number to mark pending
24
VPADAL_U 1111 001 11 . 11 .. 00 .... 0 1101 . . 0 .... @2misc
26
+ * @secure: false for non-banked exceptions or for the nonsecure
25
27
+ * version of a banked exception, true for the secure version of a banked
26
+ VCGT0 1111 001 11 . 11 .. 01 .... 0 0000 . . 0 .... @2misc
28
+ * exception.
27
+ VCGE0 1111 001 11 . 11 .. 01 .... 0 0001 . . 0 .... @2misc
29
+ *
28
+ VCEQ0 1111 001 11 . 11 .. 01 .... 0 0010 . . 0 .... @2misc
30
+ * Return whether an exception is "ready", i.e. whether the exception is
29
+ VCLE0 1111 001 11 . 11 .. 01 .... 0 0011 . . 0 .... @2misc
31
+ * enabled and is configured at a priority which would allow it to
30
+ VCLT0 1111 001 11 . 11 .. 01 .... 0 0100 . . 0 .... @2misc
32
+ * interrupt the current execution priority. This controls whether the
31
+
33
+ * RDY bit for it in the FPCCR is set.
32
+ VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc
34
+ */
33
+ VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc
35
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure);
34
+
36
/**
35
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
37
* armv7m_nvic_raw_execution_priority: return the raw execution priority
36
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
38
* @opaque: the NVIC
37
39
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
38
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
40
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/intc/armv7m_nvic.c
40
--- a/target/arm/translate-neon.inc.c
42
+++ b/hw/intc/armv7m_nvic.c
41
+++ b/target/arm/translate-neon.inc.c
43
@@ -XXX,XX +XXX,XX @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
42
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a)
44
return ret;
43
44
return true;
45
}
45
}
46
46
+
47
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
47
+static bool do_2misc_vec(DisasContext *s, arg_2misc *a, GVecGen2Fn *fn)
48
+{
48
+{
49
+ /*
49
+ int vec_size = a->q ? 16 : 8;
50
+ * Return whether an exception is "ready", i.e. it is enabled and is
50
+ int rd_ofs = neon_reg_offset(a->vd, 0);
51
+ * configured at a priority which would allow it to interrupt the
51
+ int rm_ofs = neon_reg_offset(a->vm, 0);
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
+
52
+
63
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
53
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
64
+ assert(!secure || banked);
54
+ return false;
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
+ }
55
+ }
74
+
56
+
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
57
+ /* UNDEF accesses to D16-D31 if they don't exist. */
58
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
59
+ ((a->vd | a->vm) & 0x10)) {
60
+ return false;
61
+ }
76
+
62
+
77
+ return vec->enabled &&
63
+ if (a->size == 3) {
78
+ exc_group_prio(s, vec->prio, secure) < running;
64
+ return false;
65
+ }
66
+
67
+ if ((a->vd | a->vm) & a->q) {
68
+ return false;
69
+ }
70
+
71
+ if (!vfp_access_check(s)) {
72
+ return true;
73
+ }
74
+
75
+ fn(a->size, rd_ofs, rm_ofs, vec_size, vec_size);
76
+
77
+ return true;
79
+}
78
+}
80
+
79
+
81
/* callback when external interrupt line is changed */
80
+#define DO_2MISC_VEC(INSN, FN) \
82
static void set_irq_level(void *opaque, int n, int level)
81
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
83
{
82
+ { \
84
diff --git a/target/arm/helper.c b/target/arm/helper.c
83
+ return do_2misc_vec(s, a, FN); \
85
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/helper.c
87
+++ b/target/arm/helper.c
88
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
89
env->thumb = addr & 1;
90
}
91
92
+static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
93
+ bool apply_splim)
94
+{
95
+ /*
96
+ * Like the pseudocode UpdateFPCCR: save state in FPCAR and FPCCR
97
+ * that we will need later in order to do lazy FP reg stacking.
98
+ */
99
+ bool is_secure = env->v7m.secure;
100
+ void *nvic = env->nvic;
101
+ /*
102
+ * Some bits are unbanked and live always in fpccr[M_REG_S]; some bits
103
+ * are banked and we want to update the bit in the bank for the
104
+ * current security state; and in one case we want to specifically
105
+ * update the NS banked version of a bit even if we are secure.
106
+ */
107
+ uint32_t *fpccr_s = &env->v7m.fpccr[M_REG_S];
108
+ uint32_t *fpccr_ns = &env->v7m.fpccr[M_REG_NS];
109
+ uint32_t *fpccr = &env->v7m.fpccr[is_secure];
110
+ bool hfrdy, bfrdy, mmrdy, ns_ufrdy, s_ufrdy, sfrdy, monrdy;
111
+
112
+ env->v7m.fpcar[is_secure] = frameptr & ~0x7;
113
+
114
+ if (apply_splim && arm_feature(env, ARM_FEATURE_V8)) {
115
+ bool splimviol;
116
+ uint32_t splim = v7m_sp_limit(env);
117
+ bool ign = armv7m_nvic_neg_prio_requested(nvic, is_secure) &&
118
+ (env->v7m.ccr[is_secure] & R_V7M_CCR_STKOFHFNMIGN_MASK);
119
+
120
+ splimviol = !ign && frameptr < splim;
121
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, SPLIMVIOL, splimviol);
122
+ }
84
+ }
123
+
85
+
124
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, LSPACT, 1);
86
+DO_2MISC_VEC(VNEG, tcg_gen_gvec_neg)
87
+DO_2MISC_VEC(VABS, tcg_gen_gvec_abs)
88
+DO_2MISC_VEC(VCEQ0, gen_gvec_ceq0)
89
+DO_2MISC_VEC(VCGT0, gen_gvec_cgt0)
90
+DO_2MISC_VEC(VCLE0, gen_gvec_cle0)
91
+DO_2MISC_VEC(VCGE0, gen_gvec_cge0)
92
+DO_2MISC_VEC(VCLT0, gen_gvec_clt0)
125
+
93
+
126
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, S, is_secure);
94
+static bool trans_VMVN(DisasContext *s, arg_2misc *a)
127
+
95
+{
128
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, USER, arm_current_el(env) == 0);
96
+ if (a->size != 0) {
129
+
97
+ return false;
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
+ }
98
+ }
99
+ return do_2misc_vec(s, a, tcg_gen_gvec_not);
155
+}
100
+}
156
+
101
diff --git a/target/arm/translate.c b/target/arm/translate.c
157
static bool v7m_push_stack(ARMCPU *cpu)
102
index XXXXXXX..XXXXXXX 100644
158
{
103
--- a/target/arm/translate.c
159
/* Do the "set up stack frame" part of exception entry,
104
+++ b/target/arm/translate.c
160
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
105
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
161
}
106
int size;
162
} else {
107
int pass;
163
/* Lazy stacking enabled, save necessary info to stack later */
108
int u;
164
- /* TODO : equivalent of UpdateFPCCR() pseudocode */
109
- int vec_size;
165
+ v7m_update_fpccr(env, frameptr + 0x20, true);
110
TCGv_i32 tmp, tmp2;
166
}
111
167
}
112
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
168
}
113
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
114
VFP_DREG_D(rd, insn);
115
VFP_DREG_M(rm, insn);
116
size = (insn >> 20) & 3;
117
- vec_size = q ? 16 : 8;
118
rd_ofs = neon_reg_offset(rd, 0);
119
rm_ofs = neon_reg_offset(rm, 0);
120
121
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
122
case NEON_2RM_VSHLL:
123
case NEON_2RM_VCVT_F16_F32:
124
case NEON_2RM_VCVT_F32_F16:
125
+ case NEON_2RM_VMVN:
126
+ case NEON_2RM_VNEG:
127
+ case NEON_2RM_VABS:
128
+ case NEON_2RM_VCEQ0:
129
+ case NEON_2RM_VCGT0:
130
+ case NEON_2RM_VCLE0:
131
+ case NEON_2RM_VCGE0:
132
+ case NEON_2RM_VCLT0:
133
/* handled by decodetree */
134
return 1;
135
case NEON_2RM_VTRN:
136
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
137
q ? gen_helper_crypto_sha256su0
138
: gen_helper_crypto_sha1su1);
139
break;
140
- case NEON_2RM_VMVN:
141
- tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
142
- break;
143
- case NEON_2RM_VNEG:
144
- tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
145
- break;
146
- case NEON_2RM_VABS:
147
- tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
148
- break;
149
-
150
- case NEON_2RM_VCEQ0:
151
- gen_gvec_ceq0(size, rd_ofs, rm_ofs, vec_size, vec_size);
152
- break;
153
- case NEON_2RM_VCGT0:
154
- gen_gvec_cgt0(size, rd_ofs, rm_ofs, vec_size, vec_size);
155
- break;
156
- case NEON_2RM_VCLE0:
157
- gen_gvec_cle0(size, rd_ofs, rm_ofs, vec_size, vec_size);
158
- break;
159
- case NEON_2RM_VCGE0:
160
- gen_gvec_cge0(size, rd_ofs, rm_ofs, vec_size, vec_size);
161
- break;
162
- case NEON_2RM_VCLT0:
163
- gen_gvec_clt0(size, rd_ofs, rm_ofs, vec_size, vec_size);
164
- break;
165
166
default:
167
elementwise:
169
--
168
--
170
2.20.1
169
2.20.1
171
170
172
171
diff view generated by jsdifflib
1
Implement the VLLDM instruction for v7M for the FPU present cas.
1
Convert the Neon-2-reg misc crypto ops (AESE, AESMC, SHA1H, SHA1SU1)
2
to 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-26-peter.maydell@linaro.org
6
Message-id: 20200616170844.13318-9-peter.maydell@linaro.org
6
---
7
---
7
target/arm/helper.h | 1 +
8
target/arm/neon-dp.decode | 12 ++++++++
8
target/arm/helper.c | 54 ++++++++++++++++++++++++++++++++++++++++++
9
target/arm/translate-neon.inc.c | 42 ++++++++++++++++++++++++++
9
target/arm/translate.c | 2 +-
10
target/arm/translate.c | 52 +++------------------------------
10
3 files changed, 56 insertions(+), 1 deletion(-)
11
3 files changed, 58 insertions(+), 48 deletions(-)
11
12
12
diff --git a/target/arm/helper.h b/target/arm/helper.h
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
13
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.h
15
--- a/target/arm/neon-dp.decode
15
+++ b/target/arm/helper.h
16
+++ b/target/arm/neon-dp.decode
16
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
17
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
18
&2misc vm=%vm_dp vd=%vd_dp
18
19
@2misc_q0 .... ... .. . .. size:2 .. .... . .... . . . .... \
19
DEF_HELPER_2(v7m_vlstm, void, env, i32)
20
&2misc vm=%vm_dp vd=%vd_dp q=0
20
+DEF_HELPER_2(v7m_vlldm, void, env, i32)
21
+ @2misc_q1 .... ... .. . .. size:2 .. .... . .... . . . .... \
21
22
+ &2misc vm=%vm_dp vd=%vd_dp q=1
22
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
23
23
24
VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
25
26
VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc
27
VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc
28
29
+ AESE 1111 001 11 . 11 .. 00 .... 0 0110 0 . 0 .... @2misc_q1
30
+ AESD 1111 001 11 . 11 .. 00 .... 0 0110 1 . 0 .... @2misc_q1
31
+ AESMC 1111 001 11 . 11 .. 00 .... 0 0111 0 . 0 .... @2misc_q1
32
+ AESIMC 1111 001 11 . 11 .. 00 .... 0 0111 1 . 0 .... @2misc_q1
33
+
34
VMVN 1111 001 11 . 11 .. 00 .... 0 1011 . . 0 .... @2misc
35
36
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
37
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
38
VCLE0 1111 001 11 . 11 .. 01 .... 0 0011 . . 0 .... @2misc
39
VCLT0 1111 001 11 . 11 .. 01 .... 0 0100 . . 0 .... @2misc
40
41
+ SHA1H 1111 001 11 . 11 .. 01 .... 0 0101 1 . 0 .... @2misc_q1
42
+
43
VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc
44
VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc
45
46
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
47
48
VSHLL 1111 001 11 . 11 .. 10 .... 0 0110 0 . 0 .... @2misc_q0
49
50
+ SHA1SU1 1111 001 11 . 11 .. 10 .... 0 0111 0 . 0 .... @2misc_q1
51
+ SHA256SU0 1111 001 11 . 11 .. 10 .... 0 0111 1 . 0 .... @2misc_q1
52
+
53
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
54
VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
55
]
56
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
25
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.c
58
--- a/target/arm/translate-neon.inc.c
27
+++ b/target/arm/helper.c
59
+++ b/target/arm/translate-neon.inc.c
28
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
60
@@ -XXX,XX +XXX,XX @@ static bool trans_VMVN(DisasContext *s, arg_2misc *a)
29
g_assert_not_reached();
61
}
62
return do_2misc_vec(s, a, tcg_gen_gvec_not);
30
}
63
}
31
32
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
33
+{
34
+ /* translate.c should never generate calls here in user-only mode */
35
+ g_assert_not_reached();
36
+}
37
+
64
+
38
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
65
+#define WRAP_2M_3_OOL_FN(WRAPNAME, FUNC, DATA) \
39
{
66
+ static void WRAPNAME(unsigned vece, uint32_t rd_ofs, \
40
/* The TT instructions can be used by unprivileged code, but in
67
+ uint32_t rm_ofs, uint32_t oprsz, \
41
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
68
+ uint32_t maxsz) \
42
env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
69
+ { \
43
}
70
+ tcg_gen_gvec_3_ool(rd_ofs, rd_ofs, rm_ofs, oprsz, maxsz, \
44
71
+ DATA, FUNC); \
45
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
46
+{
47
+ /* fptr is the value of Rn, the frame pointer we load the FP regs from */
48
+ assert(env->v7m.secure);
49
+
50
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
51
+ return;
52
+ }
72
+ }
53
+
73
+
54
+ /* Check access to the coprocessor is permitted */
74
+#define WRAP_2M_2_OOL_FN(WRAPNAME, FUNC, DATA) \
55
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
75
+ static void WRAPNAME(unsigned vece, uint32_t rd_ofs, \
56
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
76
+ uint32_t rm_ofs, uint32_t oprsz, \
77
+ uint32_t maxsz) \
78
+ { \
79
+ tcg_gen_gvec_2_ool(rd_ofs, rm_ofs, oprsz, maxsz, DATA, FUNC); \
57
+ }
80
+ }
58
+
81
+
59
+ if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
82
+WRAP_2M_3_OOL_FN(gen_AESE, gen_helper_crypto_aese, 0)
60
+ /* State in FP is still valid */
83
+WRAP_2M_3_OOL_FN(gen_AESD, gen_helper_crypto_aese, 1)
61
+ env->v7m.fpccr[M_REG_S] &= ~R_V7M_FPCCR_LSPACT_MASK;
84
+WRAP_2M_2_OOL_FN(gen_AESMC, gen_helper_crypto_aesmc, 0)
62
+ } else {
85
+WRAP_2M_2_OOL_FN(gen_AESIMC, gen_helper_crypto_aesmc, 1)
63
+ bool ts = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK;
86
+WRAP_2M_2_OOL_FN(gen_SHA1H, gen_helper_crypto_sha1h, 0)
64
+ int i;
87
+WRAP_2M_2_OOL_FN(gen_SHA1SU1, gen_helper_crypto_sha1su1, 0)
65
+ uint32_t fpscr;
88
+WRAP_2M_2_OOL_FN(gen_SHA256SU0, gen_helper_crypto_sha256su0, 0)
66
+
89
+
67
+ if (fptr & 7) {
90
+#define DO_2M_CRYPTO(INSN, FEATURE, SIZE) \
68
+ raise_exception_ra(env, EXCP_UNALIGNED, 0, 1, GETPC());
91
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
69
+ }
92
+ { \
70
+
93
+ if (!dc_isar_feature(FEATURE, s) || a->size != SIZE) { \
71
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
94
+ return false; \
72
+ uint32_t slo, shi;
95
+ } \
73
+ uint64_t dn;
96
+ return do_2misc_vec(s, a, gen_##INSN); \
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
+ }
97
+ }
89
+
98
+
90
+ env->v7m.control[M_REG_S] |= R_V7M_CONTROL_FPCA_MASK;
99
+DO_2M_CRYPTO(AESE, aa32_aes, 0)
91
+}
100
+DO_2M_CRYPTO(AESD, aa32_aes, 0)
92
+
101
+DO_2M_CRYPTO(AESMC, aa32_aes, 0)
93
static bool v7m_push_stack(ARMCPU *cpu)
102
+DO_2M_CRYPTO(AESIMC, aa32_aes, 0)
94
{
103
+DO_2M_CRYPTO(SHA1H, aa32_sha1, 2)
95
/* Do the "set up stack frame" part of exception entry,
104
+DO_2M_CRYPTO(SHA1SU1, aa32_sha1, 2)
105
+DO_2M_CRYPTO(SHA256SU0, aa32_sha2, 2)
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
106
diff --git a/target/arm/translate.c b/target/arm/translate.c
97
index XXXXXXX..XXXXXXX 100644
107
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate.c
108
--- a/target/arm/translate.c
99
+++ b/target/arm/translate.c
109
+++ b/target/arm/translate.c
100
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
110
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
101
TCGv_i32 fptr = load_reg(s, rn);
111
{
102
112
int op;
103
if (extract32(insn, 20, 1)) {
113
int q;
104
- /* VLLDM */
114
- int rd, rm, rd_ofs, rm_ofs;
105
+ gen_helper_v7m_vlldm(cpu_env, fptr);
115
+ int rd, rm;
106
} else {
116
int size;
107
gen_helper_v7m_vlstm(cpu_env, fptr);
117
int pass;
118
int u;
119
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
120
VFP_DREG_D(rd, insn);
121
VFP_DREG_M(rm, insn);
122
size = (insn >> 20) & 3;
123
- rd_ofs = neon_reg_offset(rd, 0);
124
- rm_ofs = neon_reg_offset(rm, 0);
125
126
if ((insn & (1 << 23)) == 0) {
127
/* Three register same length: handled by decodetree */
128
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
129
case NEON_2RM_VCLE0:
130
case NEON_2RM_VCGE0:
131
case NEON_2RM_VCLT0:
132
+ case NEON_2RM_AESE: case NEON_2RM_AESMC:
133
+ case NEON_2RM_SHA1H:
134
+ case NEON_2RM_SHA1SU1:
135
/* handled by decodetree */
136
return 1;
137
case NEON_2RM_VTRN:
138
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
139
goto elementwise;
108
}
140
}
141
break;
142
- case NEON_2RM_AESE: case NEON_2RM_AESMC:
143
- if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
144
- return 1;
145
- }
146
- /*
147
- * Bit 6 is the lowest opcode bit; it distinguishes
148
- * between encryption (AESE/AESMC) and decryption
149
- * (AESD/AESIMC).
150
- */
151
- if (op == NEON_2RM_AESE) {
152
- tcg_gen_gvec_3_ool(vfp_reg_offset(true, rd),
153
- vfp_reg_offset(true, rd),
154
- vfp_reg_offset(true, rm),
155
- 16, 16, extract32(insn, 6, 1),
156
- gen_helper_crypto_aese);
157
- } else {
158
- tcg_gen_gvec_2_ool(vfp_reg_offset(true, rd),
159
- vfp_reg_offset(true, rm),
160
- 16, 16, extract32(insn, 6, 1),
161
- gen_helper_crypto_aesmc);
162
- }
163
- break;
164
- case NEON_2RM_SHA1H:
165
- if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
166
- return 1;
167
- }
168
- tcg_gen_gvec_2_ool(rd_ofs, rm_ofs, 16, 16, 0,
169
- gen_helper_crypto_sha1h);
170
- break;
171
- case NEON_2RM_SHA1SU1:
172
- if ((rm | rd) & 1) {
173
- return 1;
174
- }
175
- /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
176
- if (q) {
177
- if (!dc_isar_feature(aa32_sha2, s)) {
178
- return 1;
179
- }
180
- } else if (!dc_isar_feature(aa32_sha1, s)) {
181
- return 1;
182
- }
183
- tcg_gen_gvec_2_ool(rd_ofs, rm_ofs, 16, 16, 0,
184
- q ? gen_helper_crypto_sha256su0
185
- : gen_helper_crypto_sha1su1);
186
- break;
187
188
default:
189
elementwise:
109
--
190
--
110
2.20.1
191
2.20.1
111
192
112
193
diff view generated by jsdifflib
1
Move the NS TBFLAG down from bit 19 to bit 6, which has not
1
The NeonGenOneOpFn typedef breaks with the pattern of the other
2
been used since commit c1e3781090b9d36c60 in 2015, when we
2
NeonGen*Fn typedefs, because it is a TCGv_i64 -> TCGv_i64 operation
3
started passing the entire MMU index in the TB flags rather
3
but it does not have '64' in its name. Rename it to NeonGenOne64OpFn,
4
than just a 'privilege level' bit.
4
so that the old name is available for a TCGv_i32 -> TCGv_i32 operation
5
5
(which we will need in a subsequent commit).
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
6
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20190416125744.27770-17-peter.maydell@linaro.org
9
Message-id: 20200616170844.13318-10-peter.maydell@linaro.org
13
---
10
---
14
target/arm/cpu.h | 11 ++++++-----
11
target/arm/translate.h | 2 +-
15
1 file changed, 6 insertions(+), 5 deletions(-)
12
target/arm/translate-a64.c | 4 ++--
13
2 files changed, 3 insertions(+), 3 deletions(-)
16
14
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
17
--- a/target/arm/translate.h
20
+++ b/target/arm/cpu.h
18
+++ b/target/arm/translate.h
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
19
@@ -XXX,XX +XXX,XX @@ typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
20
typedef void NeonGenTwoOpWidenFn(TCGv_i64, TCGv_i32, TCGv_i32);
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
21
typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
22
typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
25
+/*
23
-typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
26
+ * Indicates whether cp register reads and writes by guest code should access
24
+typedef void NeonGenOne64OpFn(TCGv_i64, TCGv_i64);
27
+ * the secure or nonsecure bank of banked registers; note that this is not
25
typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
28
+ * the same thing as the current security state of the processor!
26
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
29
+ */
27
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
30
+FIELD(TBFLAG_A32, NS, 6, 1)
28
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
31
FIELD(TBFLAG_A32, VFPEN, 7, 1)
29
index XXXXXXX..XXXXXXX 100644
32
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
30
--- a/target/arm/translate-a64.c
33
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
31
+++ b/target/arm/translate-a64.c
34
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
32
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_pairwise(DisasContext *s, int opcode, bool u,
35
* checks on the other bits at runtime
33
} else {
36
*/
34
for (pass = 0; pass < maxpass; pass++) {
37
FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
35
TCGv_i64 tcg_op = tcg_temp_new_i64();
38
-/* Indicates whether cp register reads and writes by guest code should access
36
- NeonGenOneOpFn *genfn;
39
- * the secure or nonsecure bank of banked registers; note that this is not
37
- static NeonGenOneOpFn * const fns[2][2] = {
40
- * the same thing as the current security state of the processor!
38
+ NeonGenOne64OpFn *genfn;
41
- */
39
+ static NeonGenOne64OpFn * const fns[2][2] = {
42
-FIELD(TBFLAG_A32, NS, 19, 1)
40
{ gen_helper_neon_addlp_s8, gen_helper_neon_addlp_u8 },
43
/* For M profile only, Handler (ie not Thread) mode */
41
{ gen_helper_neon_addlp_s16, gen_helper_neon_addlp_u16 },
44
FIELD(TBFLAG_A32, HANDLER, 21, 1)
42
};
45
/* For M profile only, whether we should generate stack-limit checks */
46
--
43
--
47
2.20.1
44
2.20.1
48
45
49
46
diff view generated by jsdifflib
1
Pushing registers to the stack for v7M needs to handle three cases:
1
All the other typedefs like these spell "Op" with a lowercase 'p';
2
* the "normal" case where we pend exceptions
2
remane the NeonGenTwoSingleOPFn and NeonGenTwoDoubleOPFn typedefs to
3
* an "ignore faults" case where we set FSR bits but
3
match.
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
4
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20190416125744.27770-23-peter.maydell@linaro.org
7
Message-id: 20200616170844.13318-11-peter.maydell@linaro.org
16
---
8
---
17
target/arm/helper.c | 118 +++++++++++++++++++++++++++++---------------
9
target/arm/translate.h | 4 ++--
18
1 file changed, 79 insertions(+), 39 deletions(-)
10
target/arm/translate-a64.c | 4 ++--
11
target/arm/translate-neon.inc.c | 2 +-
12
3 files changed, 5 insertions(+), 5 deletions(-)
19
13
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
16
--- a/target/arm/translate.h
23
+++ b/target/arm/helper.c
17
+++ b/target/arm/translate.h
24
@@ -XXX,XX +XXX,XX @@ static bool v7m_cpacr_pass(CPUARMState *env, bool is_secure, bool is_priv)
18
@@ -XXX,XX +XXX,XX @@ typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
25
}
19
typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
20
typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
21
typedef void NeonGenTwoOpWidenFn(TCGv_i64, TCGv_i32, TCGv_i32);
22
-typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
23
-typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
24
+typedef void NeonGenTwoSingleOpFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
25
+typedef void NeonGenTwoDoubleOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
26
typedef void NeonGenOne64OpFn(TCGv_i64, TCGv_i64);
27
typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
28
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
29
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate-a64.c
32
+++ b/target/arm/translate-a64.c
33
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
34
TCGv_i64 tcg_op = tcg_temp_new_i64();
35
TCGv_i64 tcg_zero = tcg_const_i64(0);
36
TCGv_i64 tcg_res = tcg_temp_new_i64();
37
- NeonGenTwoDoubleOPFn *genfn;
38
+ NeonGenTwoDoubleOpFn *genfn;
39
bool swap = false;
40
int pass;
41
42
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
43
TCGv_i32 tcg_op = tcg_temp_new_i32();
44
TCGv_i32 tcg_zero = tcg_const_i32(0);
45
TCGv_i32 tcg_res = tcg_temp_new_i32();
46
- NeonGenTwoSingleOPFn *genfn;
47
+ NeonGenTwoSingleOpFn *genfn;
48
bool swap = false;
49
int pass, maxpasses;
50
51
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/translate-neon.inc.c
54
+++ b/target/arm/translate-neon.inc.c
55
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL_U_2sh(DisasContext *s, arg_2reg_shift *a)
26
}
56
}
27
57
28
+/*
58
static bool do_fp_2sh(DisasContext *s, arg_2reg_shift *a,
29
+ * What kind of stack write are we doing? This affects how exceptions
59
- NeonGenTwoSingleOPFn *fn)
30
+ * generated during the stacking are treated.
60
+ NeonGenTwoSingleOpFn *fn)
31
+ */
32
+typedef enum StackingMode {
33
+ STACK_NORMAL,
34
+ STACK_IGNFAULTS,
35
+ STACK_LAZYFP,
36
+} StackingMode;
37
+
38
static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
39
- ARMMMUIdx mmu_idx, bool ignfault)
40
+ ARMMMUIdx mmu_idx, StackingMode mode)
41
{
61
{
42
CPUState *cs = CPU(cpu);
62
/* FP operations in 2-reg-and-shift group */
43
CPUARMState *env = &cpu->env;
63
TCGv_i32 tmp, shiftv;
44
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
45
&attrs, &prot, &page_size, &fi, NULL)) {
46
/* MPU/SAU lookup failed */
47
if (fi.type == ARMFault_QEMU_SFault) {
48
- qemu_log_mask(CPU_LOG_INT,
49
- "...SecureFault with SFSR.AUVIOL during stacking\n");
50
- env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK | R_V7M_SFSR_SFARVALID_MASK;
51
+ if (mode == STACK_LAZYFP) {
52
+ qemu_log_mask(CPU_LOG_INT,
53
+ "...SecureFault with SFSR.LSPERR "
54
+ "during lazy stacking\n");
55
+ env->v7m.sfsr |= R_V7M_SFSR_LSPERR_MASK;
56
+ } else {
57
+ qemu_log_mask(CPU_LOG_INT,
58
+ "...SecureFault with SFSR.AUVIOL "
59
+ "during stacking\n");
60
+ env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK;
61
+ }
62
+ env->v7m.sfsr |= R_V7M_SFSR_SFARVALID_MASK;
63
env->v7m.sfar = addr;
64
exc = ARMV7M_EXCP_SECURE;
65
exc_secure = false;
66
} else {
67
- qemu_log_mask(CPU_LOG_INT, "...MemManageFault with CFSR.MSTKERR\n");
68
- env->v7m.cfsr[secure] |= R_V7M_CFSR_MSTKERR_MASK;
69
+ if (mode == STACK_LAZYFP) {
70
+ qemu_log_mask(CPU_LOG_INT,
71
+ "...MemManageFault with CFSR.MLSPERR\n");
72
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MLSPERR_MASK;
73
+ } else {
74
+ qemu_log_mask(CPU_LOG_INT,
75
+ "...MemManageFault with CFSR.MSTKERR\n");
76
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MSTKERR_MASK;
77
+ }
78
exc = ARMV7M_EXCP_MEM;
79
exc_secure = secure;
80
}
81
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
82
attrs, &txres);
83
if (txres != MEMTX_OK) {
84
/* BusFault trying to write the data */
85
- qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.STKERR\n");
86
- env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_STKERR_MASK;
87
+ if (mode == STACK_LAZYFP) {
88
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.LSPERR\n");
89
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_LSPERR_MASK;
90
+ } else {
91
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.STKERR\n");
92
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_STKERR_MASK;
93
+ }
94
exc = ARMV7M_EXCP_BUS;
95
exc_secure = false;
96
goto pend_fault;
97
@@ -XXX,XX +XXX,XX @@ pend_fault:
98
* later if we have two derived exceptions.
99
* The only case when we must not pend the exception but instead
100
* throw it away is if we are doing the push of the callee registers
101
- * and we've already generated a derived exception. Even in this
102
- * case we will still update the fault status registers.
103
+ * and we've already generated a derived exception (this is indicated
104
+ * by the caller passing STACK_IGNFAULTS). Even in this case we will
105
+ * still update the fault status registers.
106
*/
107
- if (!ignfault) {
108
+ switch (mode) {
109
+ case STACK_NORMAL:
110
armv7m_nvic_set_pending_derived(env->nvic, exc, exc_secure);
111
+ break;
112
+ case STACK_LAZYFP:
113
+ armv7m_nvic_set_pending_lazyfp(env->nvic, exc, exc_secure);
114
+ break;
115
+ case STACK_IGNFAULTS:
116
+ break;
117
}
118
return false;
119
}
120
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
121
uint32_t limit;
122
bool want_psp;
123
uint32_t sig;
124
+ StackingMode smode = ignore_faults ? STACK_IGNFAULTS : STACK_NORMAL;
125
126
if (dotailchain) {
127
bool mode = lr & R_V7M_EXCRET_MODE_MASK;
128
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
129
*/
130
sig = v7m_integrity_sig(env, lr);
131
stacked_ok =
132
- v7m_stack_write(cpu, frameptr, sig, mmu_idx, ignore_faults) &&
133
- v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
134
- ignore_faults) &&
135
- v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
136
- ignore_faults) &&
137
- v7m_stack_write(cpu, frameptr + 0x10, env->regs[6], mmu_idx,
138
- ignore_faults) &&
139
- v7m_stack_write(cpu, frameptr + 0x14, env->regs[7], mmu_idx,
140
- ignore_faults) &&
141
- v7m_stack_write(cpu, frameptr + 0x18, env->regs[8], mmu_idx,
142
- ignore_faults) &&
143
- v7m_stack_write(cpu, frameptr + 0x1c, env->regs[9], mmu_idx,
144
- ignore_faults) &&
145
- v7m_stack_write(cpu, frameptr + 0x20, env->regs[10], mmu_idx,
146
- ignore_faults) &&
147
- v7m_stack_write(cpu, frameptr + 0x24, env->regs[11], mmu_idx,
148
- ignore_faults);
149
+ v7m_stack_write(cpu, frameptr, sig, mmu_idx, smode) &&
150
+ v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx, smode) &&
151
+ v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx, smode) &&
152
+ v7m_stack_write(cpu, frameptr + 0x10, env->regs[6], mmu_idx, smode) &&
153
+ v7m_stack_write(cpu, frameptr + 0x14, env->regs[7], mmu_idx, smode) &&
154
+ v7m_stack_write(cpu, frameptr + 0x18, env->regs[8], mmu_idx, smode) &&
155
+ v7m_stack_write(cpu, frameptr + 0x1c, env->regs[9], mmu_idx, smode) &&
156
+ v7m_stack_write(cpu, frameptr + 0x20, env->regs[10], mmu_idx, smode) &&
157
+ v7m_stack_write(cpu, frameptr + 0x24, env->regs[11], mmu_idx, smode);
158
159
/* Update SP regardless of whether any of the stack accesses failed. */
160
*frame_sp_p = frameptr;
161
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
162
* if it has higher priority).
163
*/
164
stacked_ok = stacked_ok &&
165
- v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, false) &&
166
- v7m_stack_write(cpu, frameptr + 4, env->regs[1], mmu_idx, false) &&
167
- v7m_stack_write(cpu, frameptr + 8, env->regs[2], mmu_idx, false) &&
168
- v7m_stack_write(cpu, frameptr + 12, env->regs[3], mmu_idx, false) &&
169
- v7m_stack_write(cpu, frameptr + 16, env->regs[12], mmu_idx, false) &&
170
- v7m_stack_write(cpu, frameptr + 20, env->regs[14], mmu_idx, false) &&
171
- v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
172
- v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
173
+ v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, STACK_NORMAL) &&
174
+ v7m_stack_write(cpu, frameptr + 4, env->regs[1],
175
+ mmu_idx, STACK_NORMAL) &&
176
+ v7m_stack_write(cpu, frameptr + 8, env->regs[2],
177
+ mmu_idx, STACK_NORMAL) &&
178
+ v7m_stack_write(cpu, frameptr + 12, env->regs[3],
179
+ mmu_idx, STACK_NORMAL) &&
180
+ v7m_stack_write(cpu, frameptr + 16, env->regs[12],
181
+ mmu_idx, STACK_NORMAL) &&
182
+ v7m_stack_write(cpu, frameptr + 20, env->regs[14],
183
+ mmu_idx, STACK_NORMAL) &&
184
+ v7m_stack_write(cpu, frameptr + 24, env->regs[15],
185
+ mmu_idx, STACK_NORMAL) &&
186
+ v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, STACK_NORMAL);
187
188
if (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) {
189
/* FPU is active, try to save its registers */
190
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
191
faddr += 8; /* skip the slot for the FPSCR */
192
}
193
stacked_ok = stacked_ok &&
194
- v7m_stack_write(cpu, faddr, slo, mmu_idx, false) &&
195
- v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, false);
196
+ v7m_stack_write(cpu, faddr, slo,
197
+ mmu_idx, STACK_NORMAL) &&
198
+ v7m_stack_write(cpu, faddr + 4, shi,
199
+ mmu_idx, STACK_NORMAL);
200
}
201
stacked_ok = stacked_ok &&
202
v7m_stack_write(cpu, frameptr + 0x60,
203
- vfp_get_fpscr(env), mmu_idx, false);
204
+ vfp_get_fpscr(env), mmu_idx, STACK_NORMAL);
205
if (cpacr_pass) {
206
for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
207
*aa32_vfp_dreg(env, i / 2) = 0;
208
--
64
--
209
2.20.1
65
2.20.1
210
66
211
67
diff view generated by jsdifflib
1
Correct the decode of the M-profile "coprocessor and
1
Make gen_swap_half() take a source and destination TCGv_i32 rather
2
floating-point instructions" space:
2
than modifying the input TCGv_i32; we're going to want to be able to
3
* op0 == 0b11 is always unallocated
3
use it with the more flexible function signature, and this also
4
* if the CPU has an FPU then all insns with op1 == 0b101
4
brings it into line with other functions like gen_rev16() and
5
are floating point and go to disas_vfp_insn()
5
gen_revsh().
6
7
For the moment we leave VLLDM and VLSTM as NOPs; in
8
a later commit we will fill in the proper implementation
9
for the case where an FPU is present.
10
6
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20190416125744.27770-7-peter.maydell@linaro.org
9
Message-id: 20200616170844.13318-12-peter.maydell@linaro.org
14
---
10
---
15
target/arm/translate.c | 26 ++++++++++++++++++++++----
11
target/arm/translate-neon.inc.c | 2 +-
16
1 file changed, 22 insertions(+), 4 deletions(-)
12
target/arm/translate.c | 10 +++++-----
13
2 files changed, 6 insertions(+), 6 deletions(-)
17
14
15
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-neon.inc.c
18
+++ b/target/arm/translate-neon.inc.c
19
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
20
tcg_gen_bswap32_i32(tmp[half], tmp[half]);
21
break;
22
case 1:
23
- gen_swap_half(tmp[half]);
24
+ gen_swap_half(tmp[half], tmp[half]);
25
break;
26
case 2:
27
break;
18
diff --git a/target/arm/translate.c b/target/arm/translate.c
28
diff --git a/target/arm/translate.c b/target/arm/translate.c
19
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate.c
30
--- a/target/arm/translate.c
21
+++ b/target/arm/translate.c
31
+++ b/target/arm/translate.c
22
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
32
@@ -XXX,XX +XXX,XX @@ static void gen_revsh(TCGv_i32 dest, TCGv_i32 var)
23
case 6: case 7: case 14: case 15:
33
}
24
/* Coprocessor. */
34
25
if (arm_dc_feature(s, ARM_FEATURE_M)) {
35
/* Swap low and high halfwords. */
26
- /* We don't currently implement M profile FP support,
36
-static void gen_swap_half(TCGv_i32 var)
27
- * so this entire space should give a NOCP fault, with
37
+static void gen_swap_half(TCGv_i32 dest, TCGv_i32 var)
28
- * the exception of the v8M VLLDM and VLSTM insns, which
38
{
29
- * must be NOPs in Secure state and UNDEF in Nonsecure state.
39
- tcg_gen_rotri_i32(var, var, 16);
30
+ /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
40
+ tcg_gen_rotri_i32(dest, var, 16);
31
+ if (extract32(insn, 24, 2) == 3) {
41
}
32
+ goto illegal_op; /* op0 = 0b11 : unallocated */
42
33
+ }
43
/* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
34
+
44
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
35
+ /*
45
case NEON_2RM_VREV32:
36
+ * Decode VLLDM and VLSTM first: these are nonstandard because:
46
switch (size) {
37
+ * * if there is no FPU then these insns must NOP in
47
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
38
+ * Secure state and UNDEF in Nonsecure state
48
- case 1: gen_swap_half(tmp); break;
39
+ * * if there is an FPU then these insns do not have
49
+ case 1: gen_swap_half(tmp, tmp); break;
40
+ * the usual behaviour that disas_vfp_insn() provides of
50
default: abort();
41
+ * being controlled by CPACR/NSACR enable bits or the
51
}
42
+ * lazy-stacking logic.
52
break;
43
*/
53
@@ -XXX,XX +XXX,XX @@ static bool op_smlad(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
44
if (arm_dc_feature(s, ARM_FEATURE_V8) &&
54
t1 = load_reg(s, a->rn);
45
(insn & 0xffa00f00) == 0xec200a00) {
55
t2 = load_reg(s, a->rm);
46
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
56
if (m_swap) {
47
/* Just NOP since FP support is not implemented */
57
- gen_swap_half(t2);
48
break;
58
+ gen_swap_half(t2, t2);
49
}
59
}
50
+ if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
60
gen_smul_dual(t1, t2);
51
+ ((insn >> 8) & 0xe) == 10) {
61
52
+ /* FP, and the CPU supports it */
62
@@ -XXX,XX +XXX,XX @@ static bool op_smlald(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
53
+ if (disas_vfp_insn(s, insn)) {
63
t1 = load_reg(s, a->rn);
54
+ goto illegal_op;
64
t2 = load_reg(s, a->rm);
55
+ }
65
if (m_swap) {
56
+ break;
66
- gen_swap_half(t2);
57
+ }
67
+ gen_swap_half(t2, t2);
58
+
68
}
59
/* All other insns: NOCP */
69
gen_smul_dual(t1, t2);
60
gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
70
61
default_exception_el(s));
62
--
71
--
63
2.20.1
72
2.20.1
64
73
65
74
diff view generated by jsdifflib
1
The M-profile FPCCR.ASPEN bit indicates that automatic floating-point
1
Convert the VREV32 and VREV16 insns in the Neon 2-reg-misc group
2
context preservation is enabled. Before executing any floating-point
2
to decodetree.
3
instruction, if FPCCR.ASPEN is set and the CONTROL FPCA/SFPA bits
4
indicate that there is no active floating point context then we
5
must create a new context (by initializing FPSCR and setting
6
FPCA/SFPA to indicate that the context is now active). In the
7
pseudocode this is handled by ExecuteFPCheck().
8
9
Implement this with a new TB flag which tracks whether we
10
need to create a new FP context.
11
3
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190416125744.27770-20-peter.maydell@linaro.org
6
Message-id: 20200616170844.13318-13-peter.maydell@linaro.org
15
---
7
---
16
target/arm/cpu.h | 2 ++
8
target/arm/translate.h | 1 +
17
target/arm/translate.h | 1 +
9
target/arm/neon-dp.decode | 2 ++
18
target/arm/helper.c | 13 +++++++++++++
10
target/arm/translate-neon.inc.c | 55 +++++++++++++++++++++++++++++++++
19
target/arm/translate.c | 29 +++++++++++++++++++++++++++++
11
target/arm/translate.c | 12 ++-----
20
4 files changed, 45 insertions(+)
12
4 files changed, 60 insertions(+), 10 deletions(-)
21
13
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
25
+++ b/target/arm/cpu.h
26
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
27
FIELD(TBFLAG_A32, VFPEN, 7, 1)
28
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
29
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
30
+/* For M profile only, set if we must create a new FP context */
31
+FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
32
/* For M profile only, set if FPCCR.S does not match current security state */
33
FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
34
/* For M profile only, Handler (ie not Thread) mode */
35
diff --git a/target/arm/translate.h b/target/arm/translate.h
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
36
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/translate.h
16
--- a/target/arm/translate.h
38
+++ b/target/arm/translate.h
17
+++ b/target/arm/translate.h
39
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
18
@@ -XXX,XX +XXX,XX @@ typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
40
bool v8m_secure; /* true if v8M and we're in Secure mode */
19
uint32_t, uint32_t, uint32_t);
41
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
20
42
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
21
/* Function prototype for gen_ functions for calling Neon helpers */
43
+ bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
22
+typedef void NeonGenOneOpFn(TCGv_i32, TCGv_i32);
44
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
23
typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
45
* so that top level loop can generate correct syndrome information.
24
typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
46
*/
25
typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
47
diff --git a/target/arm/helper.c b/target/arm/helper.c
26
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
48
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/helper.c
28
--- a/target/arm/neon-dp.decode
50
+++ b/target/arm/helper.c
29
+++ b/target/arm/neon-dp.decode
51
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
30
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
52
flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
31
&2misc vm=%vm_dp vd=%vd_dp q=1
53
}
32
54
33
VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
55
+ if (arm_feature(env, ARM_FEATURE_M) &&
34
+ VREV32 1111 001 11 . 11 .. 00 .... 0 0001 . . 0 .... @2misc
56
+ (env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) &&
35
+ VREV16 1111 001 11 . 11 .. 00 .... 0 0010 . . 0 .... @2misc
57
+ (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) ||
36
58
+ (env->v7m.secure &&
37
VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc
59
+ !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)))) {
38
VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc
60
+ /*
39
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
61
+ * ASPEN is set, but FPCA/SFPA indicate that there is no active
40
index XXXXXXX..XXXXXXX 100644
62
+ * FP context; we must create a new FP context before executing
41
--- a/target/arm/translate-neon.inc.c
63
+ * any FP insn.
42
+++ b/target/arm/translate-neon.inc.c
64
+ */
43
@@ -XXX,XX +XXX,XX @@ DO_2M_CRYPTO(AESIMC, aa32_aes, 0)
65
+ flags = FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED, 1);
44
DO_2M_CRYPTO(SHA1H, aa32_sha1, 2)
45
DO_2M_CRYPTO(SHA1SU1, aa32_sha1, 2)
46
DO_2M_CRYPTO(SHA256SU0, aa32_sha2, 2)
47
+
48
+static bool do_2misc(DisasContext *s, arg_2misc *a, NeonGenOneOpFn *fn)
49
+{
50
+ int pass;
51
+
52
+ /* Handle a 2-reg-misc operation by iterating 32 bits at a time */
53
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
54
+ return false;
66
+ }
55
+ }
67
+
56
+
68
*pflags = flags;
57
+ /* UNDEF accesses to D16-D31 if they don't exist. */
69
*cs_base = 0;
58
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
70
}
59
+ ((a->vd | a->vm) & 0x10)) {
60
+ return false;
61
+ }
62
+
63
+ if (!fn) {
64
+ return false;
65
+ }
66
+
67
+ if ((a->vd | a->vm) & a->q) {
68
+ return false;
69
+ }
70
+
71
+ if (!vfp_access_check(s)) {
72
+ return true;
73
+ }
74
+
75
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
76
+ TCGv_i32 tmp = neon_load_reg(a->vm, pass);
77
+ fn(tmp, tmp);
78
+ neon_store_reg(a->vd, pass, tmp);
79
+ }
80
+
81
+ return true;
82
+}
83
+
84
+static bool trans_VREV32(DisasContext *s, arg_2misc *a)
85
+{
86
+ static NeonGenOneOpFn * const fn[] = {
87
+ tcg_gen_bswap32_i32,
88
+ gen_swap_half,
89
+ NULL,
90
+ NULL,
91
+ };
92
+ return do_2misc(s, a, fn[a->size]);
93
+}
94
+
95
+static bool trans_VREV16(DisasContext *s, arg_2misc *a)
96
+{
97
+ if (a->size != 0) {
98
+ return false;
99
+ }
100
+ return do_2misc(s, a, gen_rev16);
101
+}
71
diff --git a/target/arm/translate.c b/target/arm/translate.c
102
diff --git a/target/arm/translate.c b/target/arm/translate.c
72
index XXXXXXX..XXXXXXX 100644
103
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/translate.c
104
--- a/target/arm/translate.c
74
+++ b/target/arm/translate.c
105
+++ b/target/arm/translate.c
75
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
106
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
76
/* Don't need to do this for any further FP insns in this TB */
107
case NEON_2RM_AESE: case NEON_2RM_AESMC:
77
s->v8m_fpccr_s_wrong = false;
108
case NEON_2RM_SHA1H:
78
}
109
case NEON_2RM_SHA1SU1:
79
+
110
+ case NEON_2RM_VREV32:
80
+ if (s->v7m_new_fp_ctxt_needed) {
111
+ case NEON_2RM_VREV16:
81
+ /*
112
/* handled by decodetree */
82
+ * Create new FP context by updating CONTROL.FPCA, CONTROL.SFPA
113
return 1;
83
+ * and the FPSCR.
114
case NEON_2RM_VTRN:
84
+ */
115
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
85
+ TCGv_i32 control, fpscr;
116
for (pass = 0; pass < (q ? 4 : 2); pass++) {
86
+ uint32_t bits = R_V7M_CONTROL_FPCA_MASK;
117
tmp = neon_load_reg(rm, pass);
87
+
118
switch (op) {
88
+ fpscr = load_cpu_field(v7m.fpdscr[s->v8m_secure]);
119
- case NEON_2RM_VREV32:
89
+ gen_helper_vfp_set_fpscr(cpu_env, fpscr);
120
- switch (size) {
90
+ tcg_temp_free_i32(fpscr);
121
- case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
91
+ /*
122
- case 1: gen_swap_half(tmp, tmp); break;
92
+ * We don't need to arrange to end the TB, because the only
123
- default: abort();
93
+ * parts of FPSCR which we cache in the TB flags are the VECLEN
124
- }
94
+ * and VECSTRIDE, and those don't exist for M-profile.
125
- break;
95
+ */
126
- case NEON_2RM_VREV16:
96
+
127
- gen_rev16(tmp, tmp);
97
+ if (s->v8m_secure) {
128
- break;
98
+ bits |= R_V7M_CONTROL_SFPA_MASK;
129
case NEON_2RM_VCLS:
99
+ }
130
switch (size) {
100
+ control = load_cpu_field(v7m.control[M_REG_S]);
131
case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
101
+ tcg_gen_ori_i32(control, control, bits);
102
+ store_cpu_field(control, v7m.control[M_REG_S]);
103
+ /* Don't need to do this for any further FP insns in this TB */
104
+ s->v7m_new_fp_ctxt_needed = false;
105
+ }
106
}
107
108
if (extract32(insn, 28, 4) == 0xf) {
109
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
110
regime_is_secure(env, dc->mmu_idx);
111
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
112
dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
113
+ dc->v7m_new_fp_ctxt_needed =
114
+ FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
115
dc->cp_regs = cpu->cp_regs;
116
dc->features = env->features;
117
118
--
132
--
119
2.20.1
133
2.20.1
120
134
121
135
diff view generated by jsdifflib
1
The only "system register" that M-profile floating point exposes
1
Convert the remaining ops in the Neon 2-reg-misc group which
2
via the VMRS/VMRS instructions is FPSCR, and it does not have
2
can be implemented simply with our do_2misc() helper.
3
the odd special case for rd==15. Add a check to ensure we only
4
expose FPSCR.
5
3
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-5-peter.maydell@linaro.org
6
Message-id: 20200616170844.13318-14-peter.maydell@linaro.org
9
---
7
---
10
target/arm/translate.c | 19 +++++++++++++++++--
8
target/arm/neon-dp.decode | 10 +++++
11
1 file changed, 17 insertions(+), 2 deletions(-)
9
target/arm/translate-neon.inc.c | 69 +++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 38 ++++--------------
11
3 files changed, 86 insertions(+), 31 deletions(-)
12
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
16
+++ b/target/arm/neon-dp.decode
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
18
AESMC 1111 001 11 . 11 .. 00 .... 0 0111 0 . 0 .... @2misc_q1
19
AESIMC 1111 001 11 . 11 .. 00 .... 0 0111 1 . 0 .... @2misc_q1
20
21
+ VCLS 1111 001 11 . 11 .. 00 .... 0 1000 . . 0 .... @2misc
22
+ VCLZ 1111 001 11 . 11 .. 00 .... 0 1001 . . 0 .... @2misc
23
+ VCNT 1111 001 11 . 11 .. 00 .... 0 1010 . . 0 .... @2misc
24
+
25
VMVN 1111 001 11 . 11 .. 00 .... 0 1011 . . 0 .... @2misc
26
27
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
28
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
29
VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc
30
VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc
31
32
+ VABS_F 1111 001 11 . 11 .. 01 .... 0 1110 . . 0 .... @2misc
33
+ VNEG_F 1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc
34
+
35
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
36
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
37
38
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
39
40
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
41
VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
42
+
43
+ VRECPE 1111 001 11 . 11 .. 11 .... 0 1000 . . 0 .... @2misc
44
+ VRSQRTE 1111 001 11 . 11 .. 11 .... 0 1001 . . 0 .... @2misc
45
]
46
47
# Subgroup for size != 0b11
48
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/translate-neon.inc.c
51
+++ b/target/arm/translate-neon.inc.c
52
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV16(DisasContext *s, arg_2misc *a)
53
}
54
return do_2misc(s, a, gen_rev16);
55
}
56
+
57
+static bool trans_VCLS(DisasContext *s, arg_2misc *a)
58
+{
59
+ static NeonGenOneOpFn * const fn[] = {
60
+ gen_helper_neon_cls_s8,
61
+ gen_helper_neon_cls_s16,
62
+ gen_helper_neon_cls_s32,
63
+ NULL,
64
+ };
65
+ return do_2misc(s, a, fn[a->size]);
66
+}
67
+
68
+static void do_VCLZ_32(TCGv_i32 rd, TCGv_i32 rm)
69
+{
70
+ tcg_gen_clzi_i32(rd, rm, 32);
71
+}
72
+
73
+static bool trans_VCLZ(DisasContext *s, arg_2misc *a)
74
+{
75
+ static NeonGenOneOpFn * const fn[] = {
76
+ gen_helper_neon_clz_u8,
77
+ gen_helper_neon_clz_u16,
78
+ do_VCLZ_32,
79
+ NULL,
80
+ };
81
+ return do_2misc(s, a, fn[a->size]);
82
+}
83
+
84
+static bool trans_VCNT(DisasContext *s, arg_2misc *a)
85
+{
86
+ if (a->size != 0) {
87
+ return false;
88
+ }
89
+ return do_2misc(s, a, gen_helper_neon_cnt_u8);
90
+}
91
+
92
+static bool trans_VABS_F(DisasContext *s, arg_2misc *a)
93
+{
94
+ if (a->size != 2) {
95
+ return false;
96
+ }
97
+ /* TODO: FP16 : size == 1 */
98
+ return do_2misc(s, a, gen_helper_vfp_abss);
99
+}
100
+
101
+static bool trans_VNEG_F(DisasContext *s, arg_2misc *a)
102
+{
103
+ if (a->size != 2) {
104
+ return false;
105
+ }
106
+ /* TODO: FP16 : size == 1 */
107
+ return do_2misc(s, a, gen_helper_vfp_negs);
108
+}
109
+
110
+static bool trans_VRECPE(DisasContext *s, arg_2misc *a)
111
+{
112
+ if (a->size != 2) {
113
+ return false;
114
+ }
115
+ return do_2misc(s, a, gen_helper_recpe_u32);
116
+}
117
+
118
+static bool trans_VRSQRTE(DisasContext *s, arg_2misc *a)
119
+{
120
+ if (a->size != 2) {
121
+ return false;
122
+ }
123
+ return do_2misc(s, a, gen_helper_rsqrte_u32);
124
+}
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
125
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
index XXXXXXX..XXXXXXX 100644
126
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
127
--- a/target/arm/translate.c
16
+++ b/target/arm/translate.c
128
+++ b/target/arm/translate.c
17
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
129
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
18
}
130
case NEON_2RM_SHA1SU1:
19
}
131
case NEON_2RM_VREV32:
20
} else { /* !dp */
132
case NEON_2RM_VREV16:
21
+ bool is_sysreg;
133
+ case NEON_2RM_VCLS:
22
+
134
+ case NEON_2RM_VCLZ:
23
if ((insn & 0x6f) != 0x00)
135
+ case NEON_2RM_VCNT:
136
+ case NEON_2RM_VABS_F:
137
+ case NEON_2RM_VNEG_F:
138
+ case NEON_2RM_VRECPE:
139
+ case NEON_2RM_VRSQRTE:
140
/* handled by decodetree */
24
return 1;
141
return 1;
25
rn = VFP_SREG_N(insn);
142
case NEON_2RM_VTRN:
26
+
143
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
27
+ is_sysreg = extract32(insn, 21, 1);
144
for (pass = 0; pass < (q ? 4 : 2); pass++) {
28
+
145
tmp = neon_load_reg(rm, pass);
29
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
146
switch (op) {
30
+ /*
147
- case NEON_2RM_VCLS:
31
+ * The only M-profile VFP vmrs/vmsr sysreg is FPSCR.
148
- switch (size) {
32
+ * Writes to R15 are UNPREDICTABLE; we choose to undef.
149
- case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
33
+ */
150
- case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
34
+ if (is_sysreg && (rd == 15 || (rn >> 1) != ARM_VFP_FPSCR)) {
151
- case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
35
+ return 1;
152
- default: abort();
36
+ }
153
- }
37
+ }
154
- break;
38
+
155
- case NEON_2RM_VCLZ:
39
if (insn & ARM_CP_RW_BIT) {
156
- switch (size) {
40
/* vfp->arm */
157
- case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
41
- if (insn & (1 << 21)) {
158
- case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
42
+ if (is_sysreg) {
159
- case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
43
/* system register */
160
- default: abort();
44
rn >>= 1;
161
- }
45
162
- break;
46
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
163
- case NEON_2RM_VCNT:
47
}
164
- gen_helper_neon_cnt_u8(tmp, tmp);
48
} else {
165
- break;
49
/* arm->vfp */
166
case NEON_2RM_VQABS:
50
- if (insn & (1 << 21)) {
167
switch (size) {
51
+ if (is_sysreg) {
168
case 0:
52
rn >>= 1;
169
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
53
/* system register */
170
tcg_temp_free_ptr(fpstatus);
54
switch (rn) {
171
break;
172
}
173
- case NEON_2RM_VABS_F:
174
- gen_helper_vfp_abss(tmp, tmp);
175
- break;
176
- case NEON_2RM_VNEG_F:
177
- gen_helper_vfp_negs(tmp, tmp);
178
- break;
179
case NEON_2RM_VSWP:
180
tmp2 = neon_load_reg(rd, pass);
181
neon_store_reg(rm, pass, tmp2);
182
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
183
tcg_temp_free_ptr(fpst);
184
break;
185
}
186
- case NEON_2RM_VRECPE:
187
- gen_helper_recpe_u32(tmp, tmp);
188
- break;
189
- case NEON_2RM_VRSQRTE:
190
- gen_helper_rsqrte_u32(tmp, tmp);
191
- break;
192
case NEON_2RM_VRECPE_F:
193
{
194
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
55
--
195
--
56
2.20.1
196
2.20.1
57
197
58
198
diff view generated by jsdifflib
1
The TailChain() pseudocode specifies that a tail chaining
1
Convert the Neon VQABS and VQNEG insns to decodetree.
2
exception should sanitize the excReturn all-ones bits and
2
Since these are the only ones which need cpu_env passing to
3
(if there is no FPU) the excReturn FType bits; we weren't
3
the helper, we wrap the helper rather than creating a whole
4
doing this.
4
new do_2misc_env() function.
5
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-14-peter.maydell@linaro.org
8
Message-id: 20200616170844.13318-15-peter.maydell@linaro.org
9
---
9
---
10
target/arm/helper.c | 8 ++++++++
10
target/arm/neon-dp.decode | 3 +++
11
1 file changed, 8 insertions(+)
11
target/arm/translate-neon.inc.c | 35 +++++++++++++++++++++++++++++++++
12
target/arm/translate.c | 30 ++--------------------------
13
3 files changed, 40 insertions(+), 28 deletions(-)
12
14
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
17
--- a/target/arm/neon-dp.decode
16
+++ b/target/arm/helper.c
18
+++ b/target/arm/neon-dp.decode
17
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
19
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
18
qemu_log_mask(CPU_LOG_INT, "...taking pending %s exception %d\n",
20
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
19
targets_secure ? "secure" : "nonsecure", exc);
21
VPADAL_U 1111 001 11 . 11 .. 00 .... 0 1101 . . 0 .... @2misc
20
22
21
+ if (dotailchain) {
23
+ VQABS 1111 001 11 . 11 .. 00 .... 0 1110 . . 0 .... @2misc
22
+ /* Sanitize LR FType and PREFIX bits */
24
+ VQNEG 1111 001 11 . 11 .. 00 .... 0 1111 . . 0 .... @2misc
23
+ if (!arm_feature(env, ARM_FEATURE_VFP)) {
25
+
24
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
26
VCGT0 1111 001 11 . 11 .. 01 .... 0 0000 . . 0 .... @2misc
25
+ }
27
VCGE0 1111 001 11 . 11 .. 01 .... 0 0001 . . 0 .... @2misc
26
+ lr = deposit32(lr, 24, 8, 0xff);
28
VCEQ0 1111 001 11 . 11 .. 01 .... 0 0010 . . 0 .... @2misc
29
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate-neon.inc.c
32
+++ b/target/arm/translate-neon.inc.c
33
@@ -XXX,XX +XXX,XX @@ static bool trans_VRSQRTE(DisasContext *s, arg_2misc *a)
34
}
35
return do_2misc(s, a, gen_helper_rsqrte_u32);
36
}
37
+
38
+#define WRAP_1OP_ENV_FN(WRAPNAME, FUNC) \
39
+ static void WRAPNAME(TCGv_i32 d, TCGv_i32 m) \
40
+ { \
41
+ FUNC(d, cpu_env, m); \
27
+ }
42
+ }
28
+
43
+
29
if (arm_feature(env, ARM_FEATURE_V8)) {
44
+WRAP_1OP_ENV_FN(gen_VQABS_s8, gen_helper_neon_qabs_s8)
30
if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
45
+WRAP_1OP_ENV_FN(gen_VQABS_s16, gen_helper_neon_qabs_s16)
31
(lr & R_V7M_EXCRET_S_MASK)) {
46
+WRAP_1OP_ENV_FN(gen_VQABS_s32, gen_helper_neon_qabs_s32)
47
+WRAP_1OP_ENV_FN(gen_VQNEG_s8, gen_helper_neon_qneg_s8)
48
+WRAP_1OP_ENV_FN(gen_VQNEG_s16, gen_helper_neon_qneg_s16)
49
+WRAP_1OP_ENV_FN(gen_VQNEG_s32, gen_helper_neon_qneg_s32)
50
+
51
+static bool trans_VQABS(DisasContext *s, arg_2misc *a)
52
+{
53
+ static NeonGenOneOpFn * const fn[] = {
54
+ gen_VQABS_s8,
55
+ gen_VQABS_s16,
56
+ gen_VQABS_s32,
57
+ NULL,
58
+ };
59
+ return do_2misc(s, a, fn[a->size]);
60
+}
61
+
62
+static bool trans_VQNEG(DisasContext *s, arg_2misc *a)
63
+{
64
+ static NeonGenOneOpFn * const fn[] = {
65
+ gen_VQNEG_s8,
66
+ gen_VQNEG_s16,
67
+ gen_VQNEG_s32,
68
+ NULL,
69
+ };
70
+ return do_2misc(s, a, fn[a->size]);
71
+}
72
diff --git a/target/arm/translate.c b/target/arm/translate.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/translate.c
75
+++ b/target/arm/translate.c
76
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
77
case NEON_2RM_VNEG_F:
78
case NEON_2RM_VRECPE:
79
case NEON_2RM_VRSQRTE:
80
+ case NEON_2RM_VQABS:
81
+ case NEON_2RM_VQNEG:
82
/* handled by decodetree */
83
return 1;
84
case NEON_2RM_VTRN:
85
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
86
for (pass = 0; pass < (q ? 4 : 2); pass++) {
87
tmp = neon_load_reg(rm, pass);
88
switch (op) {
89
- case NEON_2RM_VQABS:
90
- switch (size) {
91
- case 0:
92
- gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
93
- break;
94
- case 1:
95
- gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
96
- break;
97
- case 2:
98
- gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
99
- break;
100
- default: abort();
101
- }
102
- break;
103
- case NEON_2RM_VQNEG:
104
- switch (size) {
105
- case 0:
106
- gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
107
- break;
108
- case 1:
109
- gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
110
- break;
111
- case 2:
112
- gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
113
- break;
114
- default: abort();
115
- }
116
- break;
117
case NEON_2RM_VCGT0_F:
118
{
119
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
32
--
120
--
33
2.20.1
121
2.20.1
34
122
35
123
diff view generated by jsdifflib
1
The M-profile FPCCR.S bit indicates the security status of
1
Convert the Neon 2-reg-misc insns which are implemented with
2
the floating point context. In the pseudocode ExecuteFPCheck()
2
simple calls to functions that take the input, output and
3
function it is unconditionally set to match the current
3
fpstatus pointer.
4
security state whenever a floating point instruction is
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
4
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20190416125744.27770-19-peter.maydell@linaro.org
7
Message-id: 20200616170844.13318-16-peter.maydell@linaro.org
18
---
8
---
19
target/arm/cpu.h | 2 ++
9
target/arm/translate.h | 1 +
20
target/arm/translate.h | 1 +
10
target/arm/neon-dp.decode | 8 +++++
21
target/arm/helper.c | 5 +++++
11
target/arm/translate-neon.inc.c | 62 +++++++++++++++++++++++++++++++++
22
target/arm/translate.c | 20 ++++++++++++++++++++
12
target/arm/translate.c | 56 ++++-------------------------
23
4 files changed, 28 insertions(+)
13
4 files changed, 78 insertions(+), 49 deletions(-)
24
14
25
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/cpu.h
28
+++ b/target/arm/cpu.h
29
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
30
FIELD(TBFLAG_A32, VFPEN, 7, 1)
31
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
32
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
33
+/* For M profile only, set if FPCCR.S does not match current security state */
34
+FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
35
/* For M profile only, Handler (ie not Thread) mode */
36
FIELD(TBFLAG_A32, HANDLER, 21, 1)
37
/* For M profile only, whether we should generate stack-limit checks */
38
diff --git a/target/arm/translate.h b/target/arm/translate.h
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
39
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/translate.h
17
--- a/target/arm/translate.h
41
+++ b/target/arm/translate.h
18
+++ b/target/arm/translate.h
42
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
19
@@ -XXX,XX +XXX,XX @@ typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
43
bool v7m_handler_mode;
20
typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
44
bool v8m_secure; /* true if v8M and we're in Secure mode */
21
typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
45
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
22
typedef void NeonGenTwoOpWidenFn(TCGv_i64, TCGv_i32, TCGv_i32);
46
+ bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
23
+typedef void NeonGenOneSingleOpFn(TCGv_i32, TCGv_i32, TCGv_ptr);
47
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
24
typedef void NeonGenTwoSingleOpFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
48
* so that top level loop can generate correct syndrome information.
25
typedef void NeonGenTwoDoubleOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
49
*/
26
typedef void NeonGenOne64OpFn(TCGv_i64, TCGv_i64);
50
diff --git a/target/arm/helper.c b/target/arm/helper.c
27
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
51
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/helper.c
29
--- a/target/arm/neon-dp.decode
53
+++ b/target/arm/helper.c
30
+++ b/target/arm/neon-dp.decode
54
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
31
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
55
flags = FIELD_DP32(flags, TBFLAG_A32, STACKCHECK, 1);
32
SHA1SU1 1111 001 11 . 11 .. 10 .... 0 0111 0 . 0 .... @2misc_q1
56
}
33
SHA256SU0 1111 001 11 . 11 .. 10 .... 0 0111 1 . 0 .... @2misc_q1
57
34
58
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
35
+ VRINTX 1111 001 11 . 11 .. 10 .... 0 1001 . . 0 .... @2misc
59
+ FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S) != env->v7m.secure) {
36
+
60
+ flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
37
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
61
+ }
38
VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
62
+
39
63
*pflags = flags;
40
VRECPE 1111 001 11 . 11 .. 11 .... 0 1000 . . 0 .... @2misc
64
*cs_base = 0;
41
VRSQRTE 1111 001 11 . 11 .. 11 .... 0 1001 . . 0 .... @2misc
42
+ VRECPE_F 1111 001 11 . 11 .. 11 .... 0 1010 . . 0 .... @2misc
43
+ VRSQRTE_F 1111 001 11 . 11 .. 11 .... 0 1011 . . 0 .... @2misc
44
+ VCVT_FS 1111 001 11 . 11 .. 11 .... 0 1100 . . 0 .... @2misc
45
+ VCVT_FU 1111 001 11 . 11 .. 11 .... 0 1101 . . 0 .... @2misc
46
+ VCVT_SF 1111 001 11 . 11 .. 11 .... 0 1110 . . 0 .... @2misc
47
+ VCVT_UF 1111 001 11 . 11 .. 11 .... 0 1111 . . 0 .... @2misc
48
]
49
50
# Subgroup for size != 0b11
51
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/translate-neon.inc.c
54
+++ b/target/arm/translate-neon.inc.c
55
@@ -XXX,XX +XXX,XX @@ static bool trans_VQNEG(DisasContext *s, arg_2misc *a)
56
};
57
return do_2misc(s, a, fn[a->size]);
65
}
58
}
59
+
60
+static bool do_2misc_fp(DisasContext *s, arg_2misc *a,
61
+ NeonGenOneSingleOpFn *fn)
62
+{
63
+ int pass;
64
+ TCGv_ptr fpst;
65
+
66
+ /* Handle a 2-reg-misc operation by iterating 32 bits at a time */
67
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
68
+ return false;
69
+ }
70
+
71
+ /* UNDEF accesses to D16-D31 if they don't exist. */
72
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
73
+ ((a->vd | a->vm) & 0x10)) {
74
+ return false;
75
+ }
76
+
77
+ if (a->size != 2) {
78
+ /* TODO: FP16 will be the size == 1 case */
79
+ return false;
80
+ }
81
+
82
+ if ((a->vd | a->vm) & a->q) {
83
+ return false;
84
+ }
85
+
86
+ if (!vfp_access_check(s)) {
87
+ return true;
88
+ }
89
+
90
+ fpst = get_fpstatus_ptr(1);
91
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
92
+ TCGv_i32 tmp = neon_load_reg(a->vm, pass);
93
+ fn(tmp, tmp, fpst);
94
+ neon_store_reg(a->vd, pass, tmp);
95
+ }
96
+ tcg_temp_free_ptr(fpst);
97
+
98
+ return true;
99
+}
100
+
101
+#define DO_2MISC_FP(INSN, FUNC) \
102
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
103
+ { \
104
+ return do_2misc_fp(s, a, FUNC); \
105
+ }
106
+
107
+DO_2MISC_FP(VRECPE_F, gen_helper_recpe_f32)
108
+DO_2MISC_FP(VRSQRTE_F, gen_helper_rsqrte_f32)
109
+DO_2MISC_FP(VCVT_FS, gen_helper_vfp_sitos)
110
+DO_2MISC_FP(VCVT_FU, gen_helper_vfp_uitos)
111
+DO_2MISC_FP(VCVT_SF, gen_helper_vfp_tosizs)
112
+DO_2MISC_FP(VCVT_UF, gen_helper_vfp_touizs)
113
+
114
+static bool trans_VRINTX(DisasContext *s, arg_2misc *a)
115
+{
116
+ if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
117
+ return false;
118
+ }
119
+ return do_2misc_fp(s, a, gen_helper_rints_exact);
120
+}
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
121
diff --git a/target/arm/translate.c b/target/arm/translate.c
67
index XXXXXXX..XXXXXXX 100644
122
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate.c
123
--- a/target/arm/translate.c
69
+++ b/target/arm/translate.c
124
+++ b/target/arm/translate.c
70
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
125
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
71
}
126
case NEON_2RM_VRSQRTE:
72
}
127
case NEON_2RM_VQABS:
73
128
case NEON_2RM_VQNEG:
74
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
129
+ case NEON_2RM_VRECPE_F:
75
+ /* Handle M-profile lazy FP state mechanics */
130
+ case NEON_2RM_VRSQRTE_F:
76
+
131
+ case NEON_2RM_VCVT_FS:
77
+ /* Update ownership of FP context: set FPCCR.S to match current state */
132
+ case NEON_2RM_VCVT_FU:
78
+ if (s->v8m_fpccr_s_wrong) {
133
+ case NEON_2RM_VCVT_SF:
79
+ TCGv_i32 tmp;
134
+ case NEON_2RM_VCVT_UF:
80
+
135
+ case NEON_2RM_VRINTX:
81
+ tmp = load_cpu_field(v7m.fpccr[M_REG_S]);
136
/* handled by decodetree */
82
+ if (s->v8m_secure) {
137
return 1;
83
+ tcg_gen_ori_i32(tmp, tmp, R_V7M_FPCCR_S_MASK);
138
case NEON_2RM_VTRN:
84
+ } else {
139
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
85
+ tcg_gen_andi_i32(tmp, tmp, ~R_V7M_FPCCR_S_MASK);
140
tcg_temp_free_i32(tcg_rmode);
86
+ }
141
break;
87
+ store_cpu_field(tmp, v7m.fpccr[M_REG_S]);
142
}
88
+ /* Don't need to do this for any further FP insns in this TB */
143
- case NEON_2RM_VRINTX:
89
+ s->v8m_fpccr_s_wrong = false;
144
- {
90
+ }
145
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
91
+ }
146
- gen_helper_rints_exact(tmp, tmp, fpstatus);
92
+
147
- tcg_temp_free_ptr(fpstatus);
93
if (extract32(insn, 28, 4) == 0xf) {
148
- break;
94
/*
149
- }
95
* Encodings with T=1 (Thumb) or unconditional (ARM):
150
case NEON_2RM_VCVTAU:
96
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
151
case NEON_2RM_VCVTAS:
97
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
152
case NEON_2RM_VCVTNU:
98
regime_is_secure(env, dc->mmu_idx);
153
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
99
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
154
tcg_temp_free_ptr(fpst);
100
+ dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
155
break;
101
dc->cp_regs = cpu->cp_regs;
156
}
102
dc->features = env->features;
157
- case NEON_2RM_VRECPE_F:
103
158
- {
159
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
160
- gen_helper_recpe_f32(tmp, tmp, fpstatus);
161
- tcg_temp_free_ptr(fpstatus);
162
- break;
163
- }
164
- case NEON_2RM_VRSQRTE_F:
165
- {
166
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
167
- gen_helper_rsqrte_f32(tmp, tmp, fpstatus);
168
- tcg_temp_free_ptr(fpstatus);
169
- break;
170
- }
171
- case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
172
- {
173
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
174
- gen_helper_vfp_sitos(tmp, tmp, fpstatus);
175
- tcg_temp_free_ptr(fpstatus);
176
- break;
177
- }
178
- case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
179
- {
180
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
181
- gen_helper_vfp_uitos(tmp, tmp, fpstatus);
182
- tcg_temp_free_ptr(fpstatus);
183
- break;
184
- }
185
- case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
186
- {
187
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
188
- gen_helper_vfp_tosizs(tmp, tmp, fpstatus);
189
- tcg_temp_free_ptr(fpstatus);
190
- break;
191
- }
192
- case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
193
- {
194
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
195
- gen_helper_vfp_touizs(tmp, tmp, fpstatus);
196
- tcg_temp_free_ptr(fpstatus);
197
- break;
198
- }
199
default:
200
/* Reserved op values were caught by the
201
* neon_2rm_sizes[] check earlier.
104
--
202
--
105
2.20.1
203
2.20.1
106
204
107
205
diff view generated by jsdifflib
1
Handle floating point registers in exception entry.
1
Convert the fp-compare-with-zero insns in the Neon 2-reg-misc group to
2
This corresponds to the FP-specific parts of the pseudocode
2
decodetree.
3
functions ActivateException() and PushStack().
4
5
We defer the code corresponding to UpdateFPCCR() to a later patch.
6
3
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-11-peter.maydell@linaro.org
6
Message-id: 20200616170844.13318-17-peter.maydell@linaro.org
10
---
7
---
11
target/arm/helper.c | 98 +++++++++++++++++++++++++++++++++++++++++++--
8
target/arm/neon-dp.decode | 6 ++++
12
1 file changed, 95 insertions(+), 3 deletions(-)
9
target/arm/translate-neon.inc.c | 28 ++++++++++++++++++
10
target/arm/translate.c | 50 ++++-----------------------------
11
3 files changed, 39 insertions(+), 45 deletions(-)
13
12
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
15
--- a/target/arm/neon-dp.decode
17
+++ b/target/arm/helper.c
16
+++ b/target/arm/neon-dp.decode
18
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
19
switch_v7m_security_state(env, targets_secure);
18
VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc
20
write_v7m_control_spsel(env, 0);
19
VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc
21
arm_clear_exclusive(env);
20
22
+ /* Clear SFPA and FPCA (has no effect if no FPU) */
21
+ VCGT0_F 1111 001 11 . 11 .. 01 .... 0 1000 . . 0 .... @2misc
23
+ env->v7m.control[M_REG_S] &=
22
+ VCGE0_F 1111 001 11 . 11 .. 01 .... 0 1001 . . 0 .... @2misc
24
+ ~(R_V7M_CONTROL_FPCA_MASK | R_V7M_CONTROL_SFPA_MASK);
23
+ VCEQ0_F 1111 001 11 . 11 .. 01 .... 0 1010 . . 0 .... @2misc
25
/* Clear IT bits */
24
+ VCLE0_F 1111 001 11 . 11 .. 01 .... 0 1011 . . 0 .... @2misc
26
env->condexec_bits = 0;
25
+ VCLT0_F 1111 001 11 . 11 .. 01 .... 0 1100 . . 0 .... @2misc
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
+
26
+
35
+ if ((env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) &&
27
VABS_F 1111 001 11 . 11 .. 01 .... 0 1110 . . 0 .... @2misc
36
+ (env->v7m.secure || nsacr_cp10)) {
28
VNEG_F 1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc
37
+ if (env->v7m.secure &&
29
38
+ env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK) {
30
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
39
+ framesize = 0xa8;
31
index XXXXXXX..XXXXXXX 100644
40
+ } else {
32
--- a/target/arm/translate-neon.inc.c
41
+ framesize = 0x68;
33
+++ b/target/arm/translate-neon.inc.c
42
+ }
34
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX(DisasContext *s, arg_2misc *a)
43
+ } else {
35
}
44
+ framesize = 0x20;
36
return do_2misc_fp(s, a, gen_helper_rints_exact);
37
}
38
+
39
+#define WRAP_FP_CMP0_FWD(WRAPNAME, FUNC) \
40
+ static void WRAPNAME(TCGv_i32 d, TCGv_i32 m, TCGv_ptr fpst) \
41
+ { \
42
+ TCGv_i32 zero = tcg_const_i32(0); \
43
+ FUNC(d, m, zero, fpst); \
44
+ tcg_temp_free_i32(zero); \
45
+ }
45
+ }
46
46
+#define WRAP_FP_CMP0_REV(WRAPNAME, FUNC) \
47
/* Align stack pointer if the guest wants that */
47
+ static void WRAPNAME(TCGv_i32 d, TCGv_i32 m, TCGv_ptr fpst) \
48
if ((frameptr & 4) &&
48
+ { \
49
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
49
+ TCGv_i32 zero = tcg_const_i32(0); \
50
xpsr |= XPSR_SPREALIGN;
50
+ FUNC(d, zero, m, fpst); \
51
}
51
+ tcg_temp_free_i32(zero); \
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
+ }
52
+ }
59
+
53
+
60
+ frameptr -= framesize;
54
+#define DO_FP_CMP0(INSN, FUNC, REV) \
61
55
+ WRAP_FP_CMP0_##REV(gen_##INSN, FUNC) \
62
if (arm_feature(env, ARM_FEATURE_V8)) {
56
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
63
uint32_t limit = v7m_sp_limit(env);
57
+ { \
64
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
58
+ return do_2misc_fp(s, a, gen_##INSN); \
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
+ }
59
+ }
134
+
60
+
135
/*
61
+DO_FP_CMP0(VCGT0_F, gen_helper_neon_cgt_f32, FWD)
136
* If we broke a stack limit then SP was already updated earlier;
62
+DO_FP_CMP0(VCGE0_F, gen_helper_neon_cge_f32, FWD)
137
* otherwise we update SP regardless of whether any of the stack
63
+DO_FP_CMP0(VCEQ0_F, gen_helper_neon_ceq_f32, FWD)
138
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
64
+DO_FP_CMP0(VCLE0_F, gen_helper_neon_cge_f32, REV)
139
65
+DO_FP_CMP0(VCLT0_F, gen_helper_neon_cgt_f32, REV)
140
if (arm_feature(env, ARM_FEATURE_V8)) {
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
141
lr = R_V7M_EXCRET_RES1_MASK |
67
index XXXXXXX..XXXXXXX 100644
142
- R_V7M_EXCRET_DCRS_MASK |
68
--- a/target/arm/translate.c
143
- R_V7M_EXCRET_FTYPE_MASK;
69
+++ b/target/arm/translate.c
144
+ R_V7M_EXCRET_DCRS_MASK;
70
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
145
/* The S bit indicates whether we should return to Secure
71
case NEON_2RM_VCVT_SF:
146
* or NonSecure (ie our current state).
72
case NEON_2RM_VCVT_UF:
147
* The ES bit indicates whether we're taking this exception
73
case NEON_2RM_VRINTX:
148
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
74
+ case NEON_2RM_VCGT0_F:
149
if (env->v7m.secure) {
75
+ case NEON_2RM_VCGE0_F:
150
lr |= R_V7M_EXCRET_S_MASK;
76
+ case NEON_2RM_VCEQ0_F:
151
}
77
+ case NEON_2RM_VCLE0_F:
152
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
78
+ case NEON_2RM_VCLT0_F:
153
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
79
/* handled by decodetree */
154
+ }
80
return 1;
155
} else {
81
case NEON_2RM_VTRN:
156
lr = R_V7M_EXCRET_RES1_MASK |
82
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
157
R_V7M_EXCRET_S_MASK |
83
for (pass = 0; pass < (q ? 4 : 2); pass++) {
84
tmp = neon_load_reg(rm, pass);
85
switch (op) {
86
- case NEON_2RM_VCGT0_F:
87
- {
88
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
89
- tmp2 = tcg_const_i32(0);
90
- gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
91
- tcg_temp_free_i32(tmp2);
92
- tcg_temp_free_ptr(fpstatus);
93
- break;
94
- }
95
- case NEON_2RM_VCGE0_F:
96
- {
97
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
98
- tmp2 = tcg_const_i32(0);
99
- gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
100
- tcg_temp_free_i32(tmp2);
101
- tcg_temp_free_ptr(fpstatus);
102
- break;
103
- }
104
- case NEON_2RM_VCEQ0_F:
105
- {
106
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
107
- tmp2 = tcg_const_i32(0);
108
- gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
109
- tcg_temp_free_i32(tmp2);
110
- tcg_temp_free_ptr(fpstatus);
111
- break;
112
- }
113
- case NEON_2RM_VCLE0_F:
114
- {
115
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
116
- tmp2 = tcg_const_i32(0);
117
- gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
118
- tcg_temp_free_i32(tmp2);
119
- tcg_temp_free_ptr(fpstatus);
120
- break;
121
- }
122
- case NEON_2RM_VCLT0_F:
123
- {
124
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
125
- tmp2 = tcg_const_i32(0);
126
- gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
127
- tcg_temp_free_i32(tmp2);
128
- tcg_temp_free_ptr(fpstatus);
129
- break;
130
- }
131
case NEON_2RM_VSWP:
132
tmp2 = neon_load_reg(rd, pass);
133
neon_store_reg(rm, pass, tmp2);
158
--
134
--
159
2.20.1
135
2.20.1
160
136
161
137
diff view generated by jsdifflib
1
In the v7M architecture, if an exception is generated in the process
1
Convert the Neon 2-reg-misc VRINT insns to decodetree.
2
of doing the lazy stacking of FP registers, the handling of
2
Giving these insns their own do_vrint() function allows us
3
possible escalation to HardFault is treated differently to the normal
3
to change the rounding mode just once at the start and end
4
approach: it works based on the saved information about exception
4
rather than doing it for every element in the vector.
5
readiness that was stored in the FPCCR when the stack frame was
6
created. Provide a new function armv7m_nvic_set_pending_lazyfp()
7
which pends exceptions during lazy stacking, and implements
8
this logic.
9
10
This corresponds to the pseudocode TakePreserveFPException().
11
5
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190416125744.27770-22-peter.maydell@linaro.org
8
Message-id: 20200616170844.13318-18-peter.maydell@linaro.org
15
---
9
---
16
target/arm/cpu.h | 12 ++++++
10
target/arm/neon-dp.decode | 8 +++++
17
hw/intc/armv7m_nvic.c | 96 +++++++++++++++++++++++++++++++++++++++++++
11
target/arm/translate-neon.inc.c | 61 +++++++++++++++++++++++++++++++++
18
2 files changed, 108 insertions(+)
12
target/arm/translate.c | 31 +++--------------
13
3 files changed, 74 insertions(+), 26 deletions(-)
19
14
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
17
--- a/target/arm/neon-dp.decode
23
+++ b/target/arm/cpu.h
18
+++ b/target/arm/neon-dp.decode
24
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
19
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
25
* a different exception).
20
SHA1SU1 1111 001 11 . 11 .. 10 .... 0 0111 0 . 0 .... @2misc_q1
26
*/
21
SHA256SU0 1111 001 11 . 11 .. 10 .... 0 0111 1 . 0 .... @2misc_q1
27
void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
22
28
+/**
23
+ VRINTN 1111 001 11 . 11 .. 10 .... 0 1000 . . 0 .... @2misc
29
+ * armv7m_nvic_set_pending_lazyfp: mark this lazy FP exception as pending
24
VRINTX 1111 001 11 . 11 .. 10 .... 0 1001 . . 0 .... @2misc
30
+ * @opaque: the NVIC
25
+ VRINTA 1111 001 11 . 11 .. 10 .... 0 1010 . . 0 .... @2misc
31
+ * @irq: the exception number to mark pending
26
+ VRINTZ 1111 001 11 . 11 .. 10 .... 0 1011 . . 0 .... @2misc
32
+ * @secure: false for non-banked exceptions or for the nonsecure
27
33
+ * version of a banked exception, true for the secure version of a banked
28
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
34
+ * exception.
29
+
35
+ *
30
+ VRINTM 1111 001 11 . 11 .. 10 .... 0 1101 . . 0 .... @2misc
36
+ * Similar to armv7m_nvic_set_pending(), but specifically for exceptions
31
+
37
+ * generated in the course of lazy stacking of FP registers.
32
VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
38
+ */
33
39
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure);
34
+ VRINTP 1111 001 11 . 11 .. 10 .... 0 1111 . . 0 .... @2misc
40
/**
35
+
41
* armv7m_nvic_get_pending_irq_info: return highest priority pending
36
VRECPE 1111 001 11 . 11 .. 11 .... 0 1000 . . 0 .... @2misc
42
* exception, and whether it targets Secure state
37
VRSQRTE 1111 001 11 . 11 .. 11 .... 0 1001 . . 0 .... @2misc
43
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
38
VRECPE_F 1111 001 11 . 11 .. 11 .... 0 1010 . . 0 .... @2misc
39
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
44
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/intc/armv7m_nvic.c
41
--- a/target/arm/translate-neon.inc.c
46
+++ b/hw/intc/armv7m_nvic.c
42
+++ b/target/arm/translate-neon.inc.c
47
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
43
@@ -XXX,XX +XXX,XX @@ DO_FP_CMP0(VCGE0_F, gen_helper_neon_cge_f32, FWD)
48
do_armv7m_nvic_set_pending(opaque, irq, secure, true);
44
DO_FP_CMP0(VCEQ0_F, gen_helper_neon_ceq_f32, FWD)
49
}
45
DO_FP_CMP0(VCLE0_F, gen_helper_neon_cge_f32, REV)
50
46
DO_FP_CMP0(VCLT0_F, gen_helper_neon_cgt_f32, REV)
51
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
47
+
48
+static bool do_vrint(DisasContext *s, arg_2misc *a, int rmode)
52
+{
49
+{
53
+ /*
50
+ /*
54
+ * Pend an exception during lazy FP stacking. This differs
51
+ * Handle a VRINT* operation by iterating 32 bits at a time,
55
+ * from the usual exception pending because the logic for
52
+ * with a specified rounding mode in operation.
56
+ * whether we should escalate depends on the saved context
57
+ * in the FPCCR register, not on the current state of the CPU/NVIC.
58
+ */
53
+ */
59
+ NVICState *s = (NVICState *)opaque;
54
+ int pass;
60
+ bool banked = exc_is_banked(irq);
55
+ TCGv_ptr fpst;
61
+ VecInfo *vec;
56
+ TCGv_i32 tcg_rmode;
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
+
57
+
72
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
58
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
73
+ assert(!secure || banked);
59
+ !arm_dc_feature(s, ARM_FEATURE_V8)) {
74
+
60
+ return false;
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
76
+
77
+ targets_secure = banked ? secure : exc_targets_secure(s, irq);
78
+
79
+ switch (irq) {
80
+ case ARMV7M_EXCP_DEBUG:
81
+ if (!(fpccr_s & R_V7M_FPCCR_MONRDY_MASK)) {
82
+ /* Ignore DebugMonitor exception */
83
+ return;
84
+ }
85
+ break;
86
+ case ARMV7M_EXCP_MEM:
87
+ escalate = !(fpccr & R_V7M_FPCCR_MMRDY_MASK);
88
+ break;
89
+ case ARMV7M_EXCP_USAGE:
90
+ escalate = !(fpccr & R_V7M_FPCCR_UFRDY_MASK);
91
+ break;
92
+ case ARMV7M_EXCP_BUS:
93
+ escalate = !(fpccr_s & R_V7M_FPCCR_BFRDY_MASK);
94
+ break;
95
+ case ARMV7M_EXCP_SECURE:
96
+ escalate = !(fpccr_s & R_V7M_FPCCR_SFRDY_MASK);
97
+ break;
98
+ default:
99
+ g_assert_not_reached();
100
+ }
61
+ }
101
+
62
+
102
+ if (escalate) {
63
+ /* UNDEF accesses to D16-D31 if they don't exist. */
103
+ /*
64
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
104
+ * Escalate to HardFault: faults that initially targeted Secure
65
+ ((a->vd | a->vm) & 0x10)) {
105
+ * continue to do so, even if HF normally targets NonSecure.
66
+ return false;
106
+ */
107
+ irq = ARMV7M_EXCP_HARD;
108
+ if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY) &&
109
+ (targets_secure ||
110
+ !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK))) {
111
+ vec = &s->sec_vectors[irq];
112
+ } else {
113
+ vec = &s->vectors[irq];
114
+ }
115
+ }
67
+ }
116
+
68
+
117
+ if (!vec->enabled ||
69
+ if (a->size != 2) {
118
+ nvic_exec_prio(s) <= exc_group_prio(s, vec->prio, secure)) {
70
+ /* TODO: FP16 will be the size == 1 case */
119
+ if (!(fpccr_s & R_V7M_FPCCR_HFRDY_MASK)) {
71
+ return false;
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
+ }
72
+ }
129
+
73
+
130
+ if (escalate) {
74
+ if ((a->vd | a->vm) & a->q) {
131
+ s->cpu->env.v7m.hfsr |= R_V7M_HFSR_FORCED_MASK;
75
+ return false;
132
+ }
76
+ }
133
+ if (!vec->pending) {
77
+
134
+ vec->pending = 1;
78
+ if (!vfp_access_check(s)) {
135
+ /*
79
+ return true;
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
+ }
80
+ }
81
+
82
+ fpst = get_fpstatus_ptr(1);
83
+ tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
84
+ gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, cpu_env);
85
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
86
+ TCGv_i32 tmp = neon_load_reg(a->vm, pass);
87
+ gen_helper_rints(tmp, tmp, fpst);
88
+ neon_store_reg(a->vd, pass, tmp);
89
+ }
90
+ gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, cpu_env);
91
+ tcg_temp_free_i32(tcg_rmode);
92
+ tcg_temp_free_ptr(fpst);
93
+
94
+ return true;
145
+}
95
+}
146
+
96
+
147
/* Make pending IRQ active. */
97
+#define DO_VRINT(INSN, RMODE) \
148
void armv7m_nvic_acknowledge_irq(void *opaque)
98
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
149
{
99
+ { \
100
+ return do_vrint(s, a, RMODE); \
101
+ }
102
+
103
+DO_VRINT(VRINTN, FPROUNDING_TIEEVEN)
104
+DO_VRINT(VRINTA, FPROUNDING_TIEAWAY)
105
+DO_VRINT(VRINTZ, FPROUNDING_ZERO)
106
+DO_VRINT(VRINTM, FPROUNDING_NEGINF)
107
+DO_VRINT(VRINTP, FPROUNDING_POSINF)
108
diff --git a/target/arm/translate.c b/target/arm/translate.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/target/arm/translate.c
111
+++ b/target/arm/translate.c
112
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
113
case NEON_2RM_VCEQ0_F:
114
case NEON_2RM_VCLE0_F:
115
case NEON_2RM_VCLT0_F:
116
+ case NEON_2RM_VRINTN:
117
+ case NEON_2RM_VRINTA:
118
+ case NEON_2RM_VRINTM:
119
+ case NEON_2RM_VRINTP:
120
+ case NEON_2RM_VRINTZ:
121
/* handled by decodetree */
122
return 1;
123
case NEON_2RM_VTRN:
124
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
125
}
126
neon_store_reg(rm, pass, tmp2);
127
break;
128
- case NEON_2RM_VRINTN:
129
- case NEON_2RM_VRINTA:
130
- case NEON_2RM_VRINTM:
131
- case NEON_2RM_VRINTP:
132
- case NEON_2RM_VRINTZ:
133
- {
134
- TCGv_i32 tcg_rmode;
135
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
136
- int rmode;
137
-
138
- if (op == NEON_2RM_VRINTZ) {
139
- rmode = FPROUNDING_ZERO;
140
- } else {
141
- rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
142
- }
143
-
144
- tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
145
- gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
146
- cpu_env);
147
- gen_helper_rints(tmp, tmp, fpstatus);
148
- gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
149
- cpu_env);
150
- tcg_temp_free_ptr(fpstatus);
151
- tcg_temp_free_i32(tcg_rmode);
152
- break;
153
- }
154
case NEON_2RM_VCVTAU:
155
case NEON_2RM_VCVTAS:
156
case NEON_2RM_VCVTNU:
150
--
157
--
151
2.20.1
158
2.20.1
152
159
153
160
diff view generated by jsdifflib
1
The magic value pushed onto the callee stack as an integrity
1
Convert the VCVT instructions in the 2-reg-misc grouping to
2
check is different if floating point is present.
2
decodetree.
3
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20190416125744.27770-15-peter.maydell@linaro.org
6
Message-id: 20200616170844.13318-19-peter.maydell@linaro.org
7
---
7
---
8
target/arm/helper.c | 22 +++++++++++++++++++---
8
target/arm/neon-dp.decode | 9 +++++
9
1 file changed, 19 insertions(+), 3 deletions(-)
9
target/arm/translate-neon.inc.c | 70 +++++++++++++++++++++++++++++++++
10
10
target/arm/translate.c | 70 ++++-----------------------------
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
11
3 files changed, 87 insertions(+), 62 deletions(-)
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
15
--- a/target/arm/neon-dp.decode
14
+++ b/target/arm/helper.c
16
+++ b/target/arm/neon-dp.decode
15
@@ -XXX,XX +XXX,XX @@ load_fail:
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
16
return false;
18
17
}
19
VRINTP 1111 001 11 . 11 .. 10 .... 0 1111 . . 0 .... @2misc
18
20
19
+static uint32_t v7m_integrity_sig(CPUARMState *env, uint32_t lr)
21
+ VCVTAS 1111 001 11 . 11 .. 11 .... 0 0000 . . 0 .... @2misc
22
+ VCVTAU 1111 001 11 . 11 .. 11 .... 0 0001 . . 0 .... @2misc
23
+ VCVTNS 1111 001 11 . 11 .. 11 .... 0 0010 . . 0 .... @2misc
24
+ VCVTNU 1111 001 11 . 11 .. 11 .... 0 0011 . . 0 .... @2misc
25
+ VCVTPS 1111 001 11 . 11 .. 11 .... 0 0100 . . 0 .... @2misc
26
+ VCVTPU 1111 001 11 . 11 .. 11 .... 0 0101 . . 0 .... @2misc
27
+ VCVTMS 1111 001 11 . 11 .. 11 .... 0 0110 . . 0 .... @2misc
28
+ VCVTMU 1111 001 11 . 11 .. 11 .... 0 0111 . . 0 .... @2misc
29
+
30
VRECPE 1111 001 11 . 11 .. 11 .... 0 1000 . . 0 .... @2misc
31
VRSQRTE 1111 001 11 . 11 .. 11 .... 0 1001 . . 0 .... @2misc
32
VRECPE_F 1111 001 11 . 11 .. 11 .... 0 1010 . . 0 .... @2misc
33
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-neon.inc.c
36
+++ b/target/arm/translate-neon.inc.c
37
@@ -XXX,XX +XXX,XX @@ DO_VRINT(VRINTA, FPROUNDING_TIEAWAY)
38
DO_VRINT(VRINTZ, FPROUNDING_ZERO)
39
DO_VRINT(VRINTM, FPROUNDING_NEGINF)
40
DO_VRINT(VRINTP, FPROUNDING_POSINF)
41
+
42
+static bool do_vcvt(DisasContext *s, arg_2misc *a, int rmode, bool is_signed)
20
+{
43
+{
21
+ /*
44
+ /*
22
+ * Return the integrity signature value for the callee-saves
45
+ * Handle a VCVT* operation by iterating 32 bits at a time,
23
+ * stack frame section. @lr is the exception return payload/LR value
46
+ * with a specified rounding mode in operation.
24
+ * whose FType bit forms bit 0 of the signature if FP is present.
25
+ */
47
+ */
26
+ uint32_t sig = 0xfefa125a;
48
+ int pass;
27
+
49
+ TCGv_ptr fpst;
28
+ if (!arm_feature(env, ARM_FEATURE_VFP) || (lr & R_V7M_EXCRET_FTYPE_MASK)) {
50
+ TCGv_i32 tcg_rmode, tcg_shift;
29
+ sig |= 1;
51
+
30
+ }
52
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
31
+ return sig;
53
+ !arm_dc_feature(s, ARM_FEATURE_V8)) {
54
+ return false;
55
+ }
56
+
57
+ /* UNDEF accesses to D16-D31 if they don't exist. */
58
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
59
+ ((a->vd | a->vm) & 0x10)) {
60
+ return false;
61
+ }
62
+
63
+ if (a->size != 2) {
64
+ /* TODO: FP16 will be the size == 1 case */
65
+ return false;
66
+ }
67
+
68
+ if ((a->vd | a->vm) & a->q) {
69
+ return false;
70
+ }
71
+
72
+ if (!vfp_access_check(s)) {
73
+ return true;
74
+ }
75
+
76
+ fpst = get_fpstatus_ptr(1);
77
+ tcg_shift = tcg_const_i32(0);
78
+ tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
79
+ gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, cpu_env);
80
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
81
+ TCGv_i32 tmp = neon_load_reg(a->vm, pass);
82
+ if (is_signed) {
83
+ gen_helper_vfp_tosls(tmp, tmp, tcg_shift, fpst);
84
+ } else {
85
+ gen_helper_vfp_touls(tmp, tmp, tcg_shift, fpst);
86
+ }
87
+ neon_store_reg(a->vd, pass, tmp);
88
+ }
89
+ gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, cpu_env);
90
+ tcg_temp_free_i32(tcg_rmode);
91
+ tcg_temp_free_i32(tcg_shift);
92
+ tcg_temp_free_ptr(fpst);
93
+
94
+ return true;
32
+}
95
+}
33
+
96
+
34
static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
97
+#define DO_VCVT(INSN, RMODE, SIGNED) \
35
bool ignore_faults)
98
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
36
{
99
+ { \
37
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
100
+ return do_vcvt(s, a, RMODE, SIGNED); \
38
bool stacked_ok;
101
+ }
39
uint32_t limit;
102
+
40
bool want_psp;
103
+DO_VCVT(VCVTAU, FPROUNDING_TIEAWAY, false)
41
+ uint32_t sig;
104
+DO_VCVT(VCVTAS, FPROUNDING_TIEAWAY, true)
42
105
+DO_VCVT(VCVTNU, FPROUNDING_TIEEVEN, false)
43
if (dotailchain) {
106
+DO_VCVT(VCVTNS, FPROUNDING_TIEEVEN, true)
44
bool mode = lr & R_V7M_EXCRET_MODE_MASK;
107
+DO_VCVT(VCVTPU, FPROUNDING_POSINF, false)
45
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
108
+DO_VCVT(VCVTPS, FPROUNDING_POSINF, true)
46
/* Write as much of the stack frame as we can. A write failure may
109
+DO_VCVT(VCVTMU, FPROUNDING_NEGINF, false)
47
* cause us to pend a derived exception.
110
+DO_VCVT(VCVTMS, FPROUNDING_NEGINF, true)
48
*/
111
diff --git a/target/arm/translate.c b/target/arm/translate.c
49
+ sig = v7m_integrity_sig(env, lr);
112
index XXXXXXX..XXXXXXX 100644
50
stacked_ok =
113
--- a/target/arm/translate.c
51
- v7m_stack_write(cpu, frameptr, 0xfefa125b, mmu_idx, ignore_faults) &&
114
+++ b/target/arm/translate.c
52
+ v7m_stack_write(cpu, frameptr, sig, mmu_idx, ignore_faults) &&
115
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
53
v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
116
#define NEON_2RM_VCVT_SF 62
54
ignore_faults) &&
117
#define NEON_2RM_VCVT_UF 63
55
v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
118
56
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
119
-static bool neon_2rm_is_v8_op(int op)
57
if (return_to_secure &&
120
-{
58
((excret & R_V7M_EXCRET_ES_MASK) == 0 ||
121
- /* Return true if this neon 2reg-misc op is ARMv8 and up */
59
(excret & R_V7M_EXCRET_DCRS_MASK) == 0)) {
122
- switch (op) {
60
- uint32_t expected_sig = 0xfefa125b;
123
- case NEON_2RM_VRINTN:
61
uint32_t actual_sig;
124
- case NEON_2RM_VRINTA:
62
125
- case NEON_2RM_VRINTM:
63
pop_ok = v7m_stack_read(cpu, &actual_sig, frameptr, mmu_idx);
126
- case NEON_2RM_VRINTP:
64
127
- case NEON_2RM_VRINTZ:
65
- if (pop_ok && expected_sig != actual_sig) {
128
- case NEON_2RM_VRINTX:
66
+ if (pop_ok && v7m_integrity_sig(env, excret) != actual_sig) {
129
- case NEON_2RM_VCVTAU:
67
/* Take a SecureFault on the current stack */
130
- case NEON_2RM_VCVTAS:
68
env->v7m.sfsr |= R_V7M_SFSR_INVIS_MASK;
131
- case NEON_2RM_VCVTNU:
69
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
132
- case NEON_2RM_VCVTNS:
133
- case NEON_2RM_VCVTPU:
134
- case NEON_2RM_VCVTPS:
135
- case NEON_2RM_VCVTMU:
136
- case NEON_2RM_VCVTMS:
137
- return true;
138
- default:
139
- return false;
140
- }
141
-}
142
-
143
/* Each entry in this array has bit n set if the insn allows
144
* size value n (otherwise it will UNDEF). Since unallocated
145
* op values will have no bits set they always UNDEF.
146
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
147
if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
148
return 1;
149
}
150
- if (neon_2rm_is_v8_op(op) &&
151
- !arm_dc_feature(s, ARM_FEATURE_V8)) {
152
- return 1;
153
- }
154
if (q && ((rm | rd) & 1)) {
155
return 1;
156
}
157
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
158
case NEON_2RM_VRINTM:
159
case NEON_2RM_VRINTP:
160
case NEON_2RM_VRINTZ:
161
+ case NEON_2RM_VCVTAU:
162
+ case NEON_2RM_VCVTAS:
163
+ case NEON_2RM_VCVTNU:
164
+ case NEON_2RM_VCVTNS:
165
+ case NEON_2RM_VCVTPU:
166
+ case NEON_2RM_VCVTPS:
167
+ case NEON_2RM_VCVTMU:
168
+ case NEON_2RM_VCVTMS:
169
/* handled by decodetree */
170
return 1;
171
case NEON_2RM_VTRN:
172
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
173
}
174
neon_store_reg(rm, pass, tmp2);
175
break;
176
- case NEON_2RM_VCVTAU:
177
- case NEON_2RM_VCVTAS:
178
- case NEON_2RM_VCVTNU:
179
- case NEON_2RM_VCVTNS:
180
- case NEON_2RM_VCVTPU:
181
- case NEON_2RM_VCVTPS:
182
- case NEON_2RM_VCVTMU:
183
- case NEON_2RM_VCVTMS:
184
- {
185
- bool is_signed = !extract32(insn, 7, 1);
186
- TCGv_ptr fpst = get_fpstatus_ptr(1);
187
- TCGv_i32 tcg_rmode, tcg_shift;
188
- int rmode = fp_decode_rm[extract32(insn, 8, 2)];
189
-
190
- tcg_shift = tcg_const_i32(0);
191
- tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
192
- gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
193
- cpu_env);
194
-
195
- if (is_signed) {
196
- gen_helper_vfp_tosls(tmp, tmp,
197
- tcg_shift, fpst);
198
- } else {
199
- gen_helper_vfp_touls(tmp, tmp,
200
- tcg_shift, fpst);
201
- }
202
-
203
- gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
204
- cpu_env);
205
- tcg_temp_free_i32(tcg_rmode);
206
- tcg_temp_free_i32(tcg_shift);
207
- tcg_temp_free_ptr(fpst);
208
- break;
209
- }
210
default:
211
/* Reserved op values were caught by the
212
* neon_2rm_sizes[] check earlier.
70
--
213
--
71
2.20.1
214
2.20.1
72
215
73
216
diff view generated by jsdifflib
1
The M-profile architecture floating point system supports
1
Convert the Neon VSWP insn to decodetree. Since the new implementation
2
lazy FP state preservation, where FP registers are not
2
doesn't have to share a pass-loop with the other 2-reg-misc operations
3
pushed to the stack when an exception occurs but are instead
3
we can implement the swap with 64-bit accesses rather than 32-bits
4
only saved if and when the first FP instruction in the exception
4
(which brings us into line with the pseudocode and is more efficient).
5
handler is executed. Implement this in QEMU, corresponding
6
to the check of LSPACT in the pseudocode ExecuteFPCheck().
7
5
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20190416125744.27770-24-peter.maydell@linaro.org
8
Message-id: 20200616170844.13318-20-peter.maydell@linaro.org
11
---
9
---
12
target/arm/cpu.h | 3 ++
10
target/arm/neon-dp.decode | 2 ++
13
target/arm/helper.h | 2 +
11
target/arm/translate-neon.inc.c | 41 +++++++++++++++++++++++++++++++++
14
target/arm/translate.h | 1 +
12
target/arm/translate.c | 5 +---
15
target/arm/helper.c | 112 +++++++++++++++++++++++++++++++++++++++++
13
3 files changed, 44 insertions(+), 4 deletions(-)
16
target/arm/translate.c | 22 ++++++++
17
5 files changed, 140 insertions(+)
18
14
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
17
--- a/target/arm/neon-dp.decode
22
+++ b/target/arm/cpu.h
18
+++ b/target/arm/neon-dp.decode
23
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
24
#define EXCP_NOCP 17 /* v7M NOCP UsageFault */
20
VABS_F 1111 001 11 . 11 .. 01 .... 0 1110 . . 0 .... @2misc
25
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
21
VNEG_F 1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc
26
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
22
27
+#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
23
+ VSWP 1111 001 11 . 11 .. 10 .... 0 0000 . . 0 .... @2misc
28
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
24
+
29
25
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
30
#define ARMV7M_EXCP_RESET 1
26
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
31
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
27
32
FIELD(TBFLAG_A32, VFPEN, 7, 1)
28
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
33
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
34
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
35
+/* For M profile only, set if FPCCR.LSPACT is set */
36
+FIELD(TBFLAG_A32, LSPACT, 18, 1)
37
/* For M profile only, set if we must create a new FP context */
38
FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
39
/* For M profile only, set if FPCCR.S does not match current security state */
40
diff --git a/target/arm/helper.h b/target/arm/helper.h
41
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/helper.h
30
--- a/target/arm/translate-neon.inc.c
43
+++ b/target/arm/helper.h
31
+++ b/target/arm/translate-neon.inc.c
44
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(v7m_blxns, void, env, i32)
32
@@ -XXX,XX +XXX,XX @@ DO_VCVT(VCVTPU, FPROUNDING_POSINF, false)
45
33
DO_VCVT(VCVTPS, FPROUNDING_POSINF, true)
46
DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
34
DO_VCVT(VCVTMU, FPROUNDING_NEGINF, false)
47
35
DO_VCVT(VCVTMS, FPROUNDING_NEGINF, true)
48
+DEF_HELPER_1(v7m_preserve_fp_state, void, env)
49
+
36
+
50
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
37
+static bool trans_VSWP(DisasContext *s, arg_2misc *a)
51
52
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
53
diff --git a/target/arm/translate.h b/target/arm/translate.h
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/translate.h
56
+++ b/target/arm/translate.h
57
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
58
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
59
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
60
bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
61
+ bool v7m_lspact; /* FPCCR.LSPACT set */
62
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
63
* so that top level loop can generate correct syndrome information.
64
*/
65
diff --git a/target/arm/helper.c b/target/arm/helper.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/helper.c
68
+++ b/target/arm/helper.c
69
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
70
g_assert_not_reached();
71
}
72
73
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
74
+{
38
+{
75
+ /* translate.c should never generate calls here in user-only mode */
39
+ TCGv_i64 rm, rd;
76
+ g_assert_not_reached();
40
+ int pass;
77
+}
78
+
41
+
79
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
42
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
80
{
43
+ return false;
81
/* The TT instructions can be used by unprivileged code, but in
82
@@ -XXX,XX +XXX,XX @@ pend_fault:
83
return false;
84
}
85
86
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
87
+{
88
+ /*
89
+ * Preserve FP state (because LSPACT was set and we are about
90
+ * to execute an FP instruction). This corresponds to the
91
+ * PreserveFPState() pseudocode.
92
+ * We may throw an exception if the stacking fails.
93
+ */
94
+ ARMCPU *cpu = arm_env_get_cpu(env);
95
+ bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
96
+ bool negpri = !(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_HFRDY_MASK);
97
+ bool is_priv = !(env->v7m.fpccr[is_secure] & R_V7M_FPCCR_USER_MASK);
98
+ bool splimviol = env->v7m.fpccr[is_secure] & R_V7M_FPCCR_SPLIMVIOL_MASK;
99
+ uint32_t fpcar = env->v7m.fpcar[is_secure];
100
+ bool stacked_ok = true;
101
+ bool ts = is_secure && (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
102
+ bool take_exception;
103
+
104
+ /* Take the iothread lock as we are going to touch the NVIC */
105
+ qemu_mutex_lock_iothread();
106
+
107
+ /* Check the background context had access to the FPU */
108
+ if (!v7m_cpacr_pass(env, is_secure, is_priv)) {
109
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, is_secure);
110
+ env->v7m.cfsr[is_secure] |= R_V7M_CFSR_NOCP_MASK;
111
+ stacked_ok = false;
112
+ } else if (!is_secure && !extract32(env->v7m.nsacr, 10, 1)) {
113
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
114
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
115
+ stacked_ok = false;
116
+ }
44
+ }
117
+
45
+
118
+ if (!splimviol && stacked_ok) {
46
+ /* UNDEF accesses to D16-D31 if they don't exist. */
119
+ /* We only stack if the stack limit wasn't violated */
47
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
120
+ int i;
48
+ ((a->vd | a->vm) & 0x10)) {
121
+ ARMMMUIdx mmu_idx;
49
+ return false;
122
+
123
+ mmu_idx = arm_v7m_mmu_idx_all(env, is_secure, is_priv, negpri);
124
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
125
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
126
+ uint32_t faddr = fpcar + 4 * i;
127
+ uint32_t slo = extract64(dn, 0, 32);
128
+ uint32_t shi = extract64(dn, 32, 32);
129
+
130
+ if (i >= 16) {
131
+ faddr += 8; /* skip the slot for the FPSCR */
132
+ }
133
+ stacked_ok = stacked_ok &&
134
+ v7m_stack_write(cpu, faddr, slo, mmu_idx, STACK_LAZYFP) &&
135
+ v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, STACK_LAZYFP);
136
+ }
137
+
138
+ stacked_ok = stacked_ok &&
139
+ v7m_stack_write(cpu, fpcar + 0x40,
140
+ vfp_get_fpscr(env), mmu_idx, STACK_LAZYFP);
141
+ }
50
+ }
142
+
51
+
143
+ /*
52
+ if (a->size != 0) {
144
+ * We definitely pended an exception, but it's possible that it
53
+ return false;
145
+ * might not be able to be taken now. If its priority permits us
146
+ * to take it now, then we must not update the LSPACT or FP regs,
147
+ * but instead jump out to take the exception immediately.
148
+ * If it's just pending and won't be taken until the current
149
+ * handler exits, then we do update LSPACT and the FP regs.
150
+ */
151
+ take_exception = !stacked_ok &&
152
+ armv7m_nvic_can_take_pending_exception(env->nvic);
153
+
154
+ qemu_mutex_unlock_iothread();
155
+
156
+ if (take_exception) {
157
+ raise_exception_ra(env, EXCP_LAZYFP, 0, 1, GETPC());
158
+ }
54
+ }
159
+
55
+
160
+ env->v7m.fpccr[is_secure] &= ~R_V7M_FPCCR_LSPACT_MASK;
56
+ if ((a->vd | a->vm) & a->q) {
161
+
57
+ return false;
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
+ }
58
+ }
212
+
59
+
213
*pflags = flags;
60
+ if (!vfp_access_check(s)) {
214
*cs_base = 0;
61
+ return true;
215
}
62
+ }
63
+
64
+ rm = tcg_temp_new_i64();
65
+ rd = tcg_temp_new_i64();
66
+ for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
67
+ neon_load_reg64(rm, a->vm + pass);
68
+ neon_load_reg64(rd, a->vd + pass);
69
+ neon_store_reg64(rm, a->vd + pass);
70
+ neon_store_reg64(rd, a->vm + pass);
71
+ }
72
+ tcg_temp_free_i64(rm);
73
+ tcg_temp_free_i64(rd);
74
+
75
+ return true;
76
+}
216
diff --git a/target/arm/translate.c b/target/arm/translate.c
77
diff --git a/target/arm/translate.c b/target/arm/translate.c
217
index XXXXXXX..XXXXXXX 100644
78
index XXXXXXX..XXXXXXX 100644
218
--- a/target/arm/translate.c
79
--- a/target/arm/translate.c
219
+++ b/target/arm/translate.c
80
+++ b/target/arm/translate.c
220
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
81
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
221
if (arm_dc_feature(s, ARM_FEATURE_M)) {
82
case NEON_2RM_VCVTPS:
222
/* Handle M-profile lazy FP state mechanics */
83
case NEON_2RM_VCVTMU:
223
84
case NEON_2RM_VCVTMS:
224
+ /* Trigger lazy-state preservation if necessary */
85
+ case NEON_2RM_VSWP:
225
+ if (s->v7m_lspact) {
86
/* handled by decodetree */
226
+ /*
87
return 1;
227
+ * Lazy state saving affects external memory and also the NVIC,
88
case NEON_2RM_VTRN:
228
+ * so we must mark it as an IO operation for icount.
89
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
229
+ */
90
for (pass = 0; pass < (q ? 4 : 2); pass++) {
230
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
91
tmp = neon_load_reg(rm, pass);
231
+ gen_io_start();
92
switch (op) {
232
+ }
93
- case NEON_2RM_VSWP:
233
+ gen_helper_v7m_preserve_fp_state(cpu_env);
94
- tmp2 = neon_load_reg(rd, pass);
234
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
95
- neon_store_reg(rm, pass, tmp2);
235
+ gen_io_end();
96
- break;
236
+ }
97
case NEON_2RM_VTRN:
237
+ /*
98
tmp2 = neon_load_reg(rd, pass);
238
+ * If the preserve_fp_state helper doesn't throw an exception
99
switch (size) {
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
--
100
--
257
2.20.1
101
2.20.1
258
102
259
103
diff view generated by jsdifflib
1
Implement the VLSTM instruction for v7M for the FPU present case.
1
Convert the Neon VTRN insn to decodetree. This is the last insn in the
2
Neon data-processing group, so we can remove all the now-unused old
3
decoder framework.
4
5
It's possible that there's a more efficient implementation of
6
VTRN, but for this conversion we just copy the existing approach.
2
7
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-25-peter.maydell@linaro.org
10
Message-id: 20200616170844.13318-21-peter.maydell@linaro.org
6
---
11
---
7
target/arm/cpu.h | 2 +
12
target/arm/neon-dp.decode | 2 +-
8
target/arm/helper.h | 2 +
13
target/arm/translate-neon.inc.c | 90 ++++++++
9
target/arm/helper.c | 84 ++++++++++++++++++++++++++++++++++++++++++
14
target/arm/translate.c | 363 +-------------------------------
10
target/arm/translate.c | 15 +++++++-
15
3 files changed, 93 insertions(+), 362 deletions(-)
11
4 files changed, 102 insertions(+), 1 deletion(-)
12
16
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
19
--- a/target/arm/neon-dp.decode
16
+++ b/target/arm/cpu.h
20
+++ b/target/arm/neon-dp.decode
17
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
18
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
22
VNEG_F 1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc
19
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
23
20
#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
24
VSWP 1111 001 11 . 11 .. 10 .... 0 0000 . . 0 .... @2misc
21
+#define EXCP_LSERR 21 /* v8M LSERR SecureFault */
25
-
22
+#define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */
26
+ VTRN 1111 001 11 . 11 .. 10 .... 0 0001 . . 0 .... @2misc
23
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
27
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
24
28
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
25
#define ARMV7M_EXCP_RESET 1
29
26
diff --git a/target/arm/helper.h b/target/arm/helper.h
30
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
27
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/helper.h
32
--- a/target/arm/translate-neon.inc.c
29
+++ b/target/arm/helper.h
33
+++ b/target/arm/translate-neon.inc.c
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
34
@@ -XXX,XX +XXX,XX @@ static bool trans_VSWP(DisasContext *s, arg_2misc *a)
31
35
32
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
36
return true;
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
}
37
}
46
38
+static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
47
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
48
+{
39
+{
49
+ /* translate.c should never generate calls here in user-only mode */
40
+ TCGv_i32 rd, tmp;
50
+ g_assert_not_reached();
41
+
42
+ rd = tcg_temp_new_i32();
43
+ tmp = tcg_temp_new_i32();
44
+
45
+ tcg_gen_shli_i32(rd, t0, 8);
46
+ tcg_gen_andi_i32(rd, rd, 0xff00ff00);
47
+ tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
48
+ tcg_gen_or_i32(rd, rd, tmp);
49
+
50
+ tcg_gen_shri_i32(t1, t1, 8);
51
+ tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
52
+ tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
53
+ tcg_gen_or_i32(t1, t1, tmp);
54
+ tcg_gen_mov_i32(t0, rd);
55
+
56
+ tcg_temp_free_i32(tmp);
57
+ tcg_temp_free_i32(rd);
51
+}
58
+}
52
+
59
+
53
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
60
+static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
54
{
55
/* The TT instructions can be used by unprivileged code, but in
56
@@ -XXX,XX +XXX,XX @@ static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
57
}
58
}
59
60
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
61
+{
61
+{
62
+ /* fptr is the value of Rn, the frame pointer we store the FP regs to */
62
+ TCGv_i32 rd, tmp;
63
+ bool s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
63
+
64
+ bool lspact = env->v7m.fpccr[s] & R_V7M_FPCCR_LSPACT_MASK;
64
+ rd = tcg_temp_new_i32();
65
+
65
+ tmp = tcg_temp_new_i32();
66
+ assert(env->v7m.secure);
66
+
67
+
67
+ tcg_gen_shli_i32(rd, t0, 16);
68
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
68
+ tcg_gen_andi_i32(tmp, t1, 0xffff);
69
+ return;
69
+ tcg_gen_or_i32(rd, rd, tmp);
70
+ tcg_gen_shri_i32(t1, t1, 16);
71
+ tcg_gen_andi_i32(tmp, t0, 0xffff0000);
72
+ tcg_gen_or_i32(t1, t1, tmp);
73
+ tcg_gen_mov_i32(t0, rd);
74
+
75
+ tcg_temp_free_i32(tmp);
76
+ tcg_temp_free_i32(rd);
77
+}
78
+
79
+static bool trans_VTRN(DisasContext *s, arg_2misc *a)
80
+{
81
+ TCGv_i32 tmp, tmp2;
82
+ int pass;
83
+
84
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
85
+ return false;
70
+ }
86
+ }
71
+
87
+
72
+ /* Check access to the coprocessor is permitted */
88
+ /* UNDEF accesses to D16-D31 if they don't exist. */
73
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
89
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
74
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
90
+ ((a->vd | a->vm) & 0x10)) {
91
+ return false;
75
+ }
92
+ }
76
+
93
+
77
+ if (lspact) {
94
+ if ((a->vd | a->vm) & a->q) {
78
+ /* LSPACT should not be active when there is active FP state */
95
+ return false;
79
+ raise_exception_ra(env, EXCP_LSERR, 0, 1, GETPC());
80
+ }
96
+ }
81
+
97
+
82
+ if (fptr & 7) {
98
+ if (a->size == 3) {
83
+ raise_exception_ra(env, EXCP_UNALIGNED, 0, 1, GETPC());
99
+ return false;
84
+ }
100
+ }
85
+
101
+
86
+ /*
102
+ if (!vfp_access_check(s)) {
87
+ * Note that we do not use v7m_stack_write() here, because the
103
+ return true;
88
+ * accesses should not set the FSR bits for stacking errors if they
104
+ }
89
+ * fail. (In pseudocode terms, they are AccType_NORMAL, not AccType_STACK
105
+
90
+ * or AccType_LAZYFP). Faults in cpu_stl_data() will throw exceptions
106
+ if (a->size == 2) {
91
+ * and longjmp out.
107
+ for (pass = 0; pass < (a->q ? 4 : 2); pass += 2) {
92
+ */
108
+ tmp = neon_load_reg(a->vm, pass);
93
+ if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) {
109
+ tmp2 = neon_load_reg(a->vd, pass + 1);
94
+ bool ts = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK;
110
+ neon_store_reg(a->vm, pass, tmp2);
95
+ int i;
111
+ neon_store_reg(a->vd, pass + 1, tmp);
96
+
97
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
98
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
99
+ uint32_t faddr = fptr + 4 * i;
100
+ uint32_t slo = extract64(dn, 0, 32);
101
+ uint32_t shi = extract64(dn, 32, 32);
102
+
103
+ if (i >= 16) {
104
+ faddr += 8; /* skip the slot for the FPSCR */
105
+ }
106
+ cpu_stl_data(env, faddr, slo);
107
+ cpu_stl_data(env, faddr + 4, shi);
108
+ }
109
+ cpu_stl_data(env, fptr + 0x40, vfp_get_fpscr(env));
110
+
111
+ /*
112
+ * If TS is 0 then s0 to s15 and FPSCR are UNKNOWN; we choose to
113
+ * leave them unchanged, matching our choice in v7m_preserve_fp_state.
114
+ */
115
+ if (ts) {
116
+ for (i = 0; i < 32; i += 2) {
117
+ *aa32_vfp_dreg(env, i / 2) = 0;
118
+ }
119
+ vfp_set_fpscr(env, 0);
120
+ }
112
+ }
121
+ } else {
113
+ } else {
122
+ v7m_update_fpccr(env, fptr, false);
114
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
115
+ tmp = neon_load_reg(a->vm, pass);
116
+ tmp2 = neon_load_reg(a->vd, pass);
117
+ if (a->size == 0) {
118
+ gen_neon_trn_u8(tmp, tmp2);
119
+ } else {
120
+ gen_neon_trn_u16(tmp, tmp2);
121
+ }
122
+ neon_store_reg(a->vm, pass, tmp2);
123
+ neon_store_reg(a->vd, pass, tmp);
124
+ }
123
+ }
125
+ }
124
+
126
+ return true;
125
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
126
+}
127
+}
127
+
128
static bool v7m_push_stack(ARMCPU *cpu)
129
{
130
/* Do the "set up stack frame" part of exception entry,
131
@@ -XXX,XX +XXX,XX @@ static void arm_log_exception(int idx)
132
[EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
133
[EXCP_STKOF] = "v8M STKOF UsageFault",
134
[EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
135
+ [EXCP_LSERR] = "v8M LSERR UsageFault",
136
+ [EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
137
};
138
139
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
140
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
141
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
142
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_STKOF_MASK;
143
break;
144
+ case EXCP_LSERR:
145
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
146
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
147
+ break;
148
+ case EXCP_UNALIGNED:
149
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
150
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNALIGNED_MASK;
151
+ break;
152
case EXCP_SWI:
153
/* The PC already points to the next instruction. */
154
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC, env->v7m.secure);
155
diff --git a/target/arm/translate.c b/target/arm/translate.c
128
diff --git a/target/arm/translate.c b/target/arm/translate.c
156
index XXXXXXX..XXXXXXX 100644
129
index XXXXXXX..XXXXXXX 100644
157
--- a/target/arm/translate.c
130
--- a/target/arm/translate.c
158
+++ b/target/arm/translate.c
131
+++ b/target/arm/translate.c
132
@@ -XXX,XX +XXX,XX @@ static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
133
gen_rfe(s, pc, load_cpu_field(spsr));
134
}
135
136
-static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
137
-{
138
- TCGv_i32 rd, tmp;
139
-
140
- rd = tcg_temp_new_i32();
141
- tmp = tcg_temp_new_i32();
142
-
143
- tcg_gen_shli_i32(rd, t0, 8);
144
- tcg_gen_andi_i32(rd, rd, 0xff00ff00);
145
- tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
146
- tcg_gen_or_i32(rd, rd, tmp);
147
-
148
- tcg_gen_shri_i32(t1, t1, 8);
149
- tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
150
- tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
151
- tcg_gen_or_i32(t1, t1, tmp);
152
- tcg_gen_mov_i32(t0, rd);
153
-
154
- tcg_temp_free_i32(tmp);
155
- tcg_temp_free_i32(rd);
156
-}
157
-
158
-static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
159
-{
160
- TCGv_i32 rd, tmp;
161
-
162
- rd = tcg_temp_new_i32();
163
- tmp = tcg_temp_new_i32();
164
-
165
- tcg_gen_shli_i32(rd, t0, 16);
166
- tcg_gen_andi_i32(tmp, t1, 0xffff);
167
- tcg_gen_or_i32(rd, rd, tmp);
168
- tcg_gen_shri_i32(t1, t1, 16);
169
- tcg_gen_andi_i32(tmp, t0, 0xffff0000);
170
- tcg_gen_or_i32(t1, t1, tmp);
171
- tcg_gen_mov_i32(t0, rd);
172
-
173
- tcg_temp_free_i32(tmp);
174
- tcg_temp_free_i32(rd);
175
-}
176
-
177
-/* Symbolic constants for op fields for Neon 2-register miscellaneous.
178
- * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
179
- * table A7-13.
180
- */
181
-#define NEON_2RM_VREV64 0
182
-#define NEON_2RM_VREV32 1
183
-#define NEON_2RM_VREV16 2
184
-#define NEON_2RM_VPADDL 4
185
-#define NEON_2RM_VPADDL_U 5
186
-#define NEON_2RM_AESE 6 /* Includes AESD */
187
-#define NEON_2RM_AESMC 7 /* Includes AESIMC */
188
-#define NEON_2RM_VCLS 8
189
-#define NEON_2RM_VCLZ 9
190
-#define NEON_2RM_VCNT 10
191
-#define NEON_2RM_VMVN 11
192
-#define NEON_2RM_VPADAL 12
193
-#define NEON_2RM_VPADAL_U 13
194
-#define NEON_2RM_VQABS 14
195
-#define NEON_2RM_VQNEG 15
196
-#define NEON_2RM_VCGT0 16
197
-#define NEON_2RM_VCGE0 17
198
-#define NEON_2RM_VCEQ0 18
199
-#define NEON_2RM_VCLE0 19
200
-#define NEON_2RM_VCLT0 20
201
-#define NEON_2RM_SHA1H 21
202
-#define NEON_2RM_VABS 22
203
-#define NEON_2RM_VNEG 23
204
-#define NEON_2RM_VCGT0_F 24
205
-#define NEON_2RM_VCGE0_F 25
206
-#define NEON_2RM_VCEQ0_F 26
207
-#define NEON_2RM_VCLE0_F 27
208
-#define NEON_2RM_VCLT0_F 28
209
-#define NEON_2RM_VABS_F 30
210
-#define NEON_2RM_VNEG_F 31
211
-#define NEON_2RM_VSWP 32
212
-#define NEON_2RM_VTRN 33
213
-#define NEON_2RM_VUZP 34
214
-#define NEON_2RM_VZIP 35
215
-#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
216
-#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
217
-#define NEON_2RM_VSHLL 38
218
-#define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
219
-#define NEON_2RM_VRINTN 40
220
-#define NEON_2RM_VRINTX 41
221
-#define NEON_2RM_VRINTA 42
222
-#define NEON_2RM_VRINTZ 43
223
-#define NEON_2RM_VCVT_F16_F32 44
224
-#define NEON_2RM_VRINTM 45
225
-#define NEON_2RM_VCVT_F32_F16 46
226
-#define NEON_2RM_VRINTP 47
227
-#define NEON_2RM_VCVTAU 48
228
-#define NEON_2RM_VCVTAS 49
229
-#define NEON_2RM_VCVTNU 50
230
-#define NEON_2RM_VCVTNS 51
231
-#define NEON_2RM_VCVTPU 52
232
-#define NEON_2RM_VCVTPS 53
233
-#define NEON_2RM_VCVTMU 54
234
-#define NEON_2RM_VCVTMS 55
235
-#define NEON_2RM_VRECPE 56
236
-#define NEON_2RM_VRSQRTE 57
237
-#define NEON_2RM_VRECPE_F 58
238
-#define NEON_2RM_VRSQRTE_F 59
239
-#define NEON_2RM_VCVT_FS 60
240
-#define NEON_2RM_VCVT_FU 61
241
-#define NEON_2RM_VCVT_SF 62
242
-#define NEON_2RM_VCVT_UF 63
243
-
244
-/* Each entry in this array has bit n set if the insn allows
245
- * size value n (otherwise it will UNDEF). Since unallocated
246
- * op values will have no bits set they always UNDEF.
247
- */
248
-static const uint8_t neon_2rm_sizes[] = {
249
- [NEON_2RM_VREV64] = 0x7,
250
- [NEON_2RM_VREV32] = 0x3,
251
- [NEON_2RM_VREV16] = 0x1,
252
- [NEON_2RM_VPADDL] = 0x7,
253
- [NEON_2RM_VPADDL_U] = 0x7,
254
- [NEON_2RM_AESE] = 0x1,
255
- [NEON_2RM_AESMC] = 0x1,
256
- [NEON_2RM_VCLS] = 0x7,
257
- [NEON_2RM_VCLZ] = 0x7,
258
- [NEON_2RM_VCNT] = 0x1,
259
- [NEON_2RM_VMVN] = 0x1,
260
- [NEON_2RM_VPADAL] = 0x7,
261
- [NEON_2RM_VPADAL_U] = 0x7,
262
- [NEON_2RM_VQABS] = 0x7,
263
- [NEON_2RM_VQNEG] = 0x7,
264
- [NEON_2RM_VCGT0] = 0x7,
265
- [NEON_2RM_VCGE0] = 0x7,
266
- [NEON_2RM_VCEQ0] = 0x7,
267
- [NEON_2RM_VCLE0] = 0x7,
268
- [NEON_2RM_VCLT0] = 0x7,
269
- [NEON_2RM_SHA1H] = 0x4,
270
- [NEON_2RM_VABS] = 0x7,
271
- [NEON_2RM_VNEG] = 0x7,
272
- [NEON_2RM_VCGT0_F] = 0x4,
273
- [NEON_2RM_VCGE0_F] = 0x4,
274
- [NEON_2RM_VCEQ0_F] = 0x4,
275
- [NEON_2RM_VCLE0_F] = 0x4,
276
- [NEON_2RM_VCLT0_F] = 0x4,
277
- [NEON_2RM_VABS_F] = 0x4,
278
- [NEON_2RM_VNEG_F] = 0x4,
279
- [NEON_2RM_VSWP] = 0x1,
280
- [NEON_2RM_VTRN] = 0x7,
281
- [NEON_2RM_VUZP] = 0x7,
282
- [NEON_2RM_VZIP] = 0x7,
283
- [NEON_2RM_VMOVN] = 0x7,
284
- [NEON_2RM_VQMOVN] = 0x7,
285
- [NEON_2RM_VSHLL] = 0x7,
286
- [NEON_2RM_SHA1SU1] = 0x4,
287
- [NEON_2RM_VRINTN] = 0x4,
288
- [NEON_2RM_VRINTX] = 0x4,
289
- [NEON_2RM_VRINTA] = 0x4,
290
- [NEON_2RM_VRINTZ] = 0x4,
291
- [NEON_2RM_VCVT_F16_F32] = 0x2,
292
- [NEON_2RM_VRINTM] = 0x4,
293
- [NEON_2RM_VCVT_F32_F16] = 0x2,
294
- [NEON_2RM_VRINTP] = 0x4,
295
- [NEON_2RM_VCVTAU] = 0x4,
296
- [NEON_2RM_VCVTAS] = 0x4,
297
- [NEON_2RM_VCVTNU] = 0x4,
298
- [NEON_2RM_VCVTNS] = 0x4,
299
- [NEON_2RM_VCVTPU] = 0x4,
300
- [NEON_2RM_VCVTPS] = 0x4,
301
- [NEON_2RM_VCVTMU] = 0x4,
302
- [NEON_2RM_VCVTMS] = 0x4,
303
- [NEON_2RM_VRECPE] = 0x4,
304
- [NEON_2RM_VRSQRTE] = 0x4,
305
- [NEON_2RM_VRECPE_F] = 0x4,
306
- [NEON_2RM_VRSQRTE_F] = 0x4,
307
- [NEON_2RM_VCVT_FS] = 0x4,
308
- [NEON_2RM_VCVT_FU] = 0x4,
309
- [NEON_2RM_VCVT_SF] = 0x4,
310
- [NEON_2RM_VCVT_UF] = 0x4,
311
-};
312
-
313
static void gen_gvec_fn3_qc(uint32_t rd_ofs, uint32_t rn_ofs, uint32_t rm_ofs,
314
uint32_t opr_sz, uint32_t max_sz,
315
gen_helper_gvec_3_ptr *fn)
316
@@ -XXX,XX +XXX,XX @@ void gen_gvec_uaba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
317
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
318
}
319
320
-/* Translate a NEON data processing instruction. Return nonzero if the
321
- instruction is invalid.
322
- We process data in a mixture of 32-bit and 64-bit chunks.
323
- Mostly we use 32-bit chunks so we can use normal scalar instructions. */
324
-
325
-static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
326
-{
327
- int op;
328
- int q;
329
- int rd, rm;
330
- int size;
331
- int pass;
332
- int u;
333
- TCGv_i32 tmp, tmp2;
334
-
335
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
336
- return 1;
337
- }
338
-
339
- /* FIXME: this access check should not take precedence over UNDEF
340
- * for invalid encodings; we will generate incorrect syndrome information
341
- * for attempts to execute invalid vfp/neon encodings with FP disabled.
342
- */
343
- if (s->fp_excp_el) {
344
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
345
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
346
- return 0;
347
- }
348
-
349
- if (!s->vfp_enabled)
350
- return 1;
351
- q = (insn & (1 << 6)) != 0;
352
- u = (insn >> 24) & 1;
353
- VFP_DREG_D(rd, insn);
354
- VFP_DREG_M(rm, insn);
355
- size = (insn >> 20) & 3;
356
-
357
- if ((insn & (1 << 23)) == 0) {
358
- /* Three register same length: handled by decodetree */
359
- return 1;
360
- } else if (insn & (1 << 4)) {
361
- /* Two registers and shift or reg and imm: handled by decodetree */
362
- return 1;
363
- } else { /* (insn & 0x00800010 == 0x00800000) */
364
- if (size != 3) {
365
- /*
366
- * Three registers of different lengths, or two registers and
367
- * a scalar: handled by decodetree
368
- */
369
- return 1;
370
- } else { /* size == 3 */
371
- if (!u) {
372
- /* Extract: handled by decodetree */
373
- return 1;
374
- } else if ((insn & (1 << 11)) == 0) {
375
- /* Two register misc. */
376
- op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
377
- size = (insn >> 18) & 3;
378
- /* UNDEF for unknown op values and bad op-size combinations */
379
- if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
380
- return 1;
381
- }
382
- if (q && ((rm | rd) & 1)) {
383
- return 1;
384
- }
385
- switch (op) {
386
- case NEON_2RM_VREV64:
387
- case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
388
- case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
389
- case NEON_2RM_VUZP:
390
- case NEON_2RM_VZIP:
391
- case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
392
- case NEON_2RM_VSHLL:
393
- case NEON_2RM_VCVT_F16_F32:
394
- case NEON_2RM_VCVT_F32_F16:
395
- case NEON_2RM_VMVN:
396
- case NEON_2RM_VNEG:
397
- case NEON_2RM_VABS:
398
- case NEON_2RM_VCEQ0:
399
- case NEON_2RM_VCGT0:
400
- case NEON_2RM_VCLE0:
401
- case NEON_2RM_VCGE0:
402
- case NEON_2RM_VCLT0:
403
- case NEON_2RM_AESE: case NEON_2RM_AESMC:
404
- case NEON_2RM_SHA1H:
405
- case NEON_2RM_SHA1SU1:
406
- case NEON_2RM_VREV32:
407
- case NEON_2RM_VREV16:
408
- case NEON_2RM_VCLS:
409
- case NEON_2RM_VCLZ:
410
- case NEON_2RM_VCNT:
411
- case NEON_2RM_VABS_F:
412
- case NEON_2RM_VNEG_F:
413
- case NEON_2RM_VRECPE:
414
- case NEON_2RM_VRSQRTE:
415
- case NEON_2RM_VQABS:
416
- case NEON_2RM_VQNEG:
417
- case NEON_2RM_VRECPE_F:
418
- case NEON_2RM_VRSQRTE_F:
419
- case NEON_2RM_VCVT_FS:
420
- case NEON_2RM_VCVT_FU:
421
- case NEON_2RM_VCVT_SF:
422
- case NEON_2RM_VCVT_UF:
423
- case NEON_2RM_VRINTX:
424
- case NEON_2RM_VCGT0_F:
425
- case NEON_2RM_VCGE0_F:
426
- case NEON_2RM_VCEQ0_F:
427
- case NEON_2RM_VCLE0_F:
428
- case NEON_2RM_VCLT0_F:
429
- case NEON_2RM_VRINTN:
430
- case NEON_2RM_VRINTA:
431
- case NEON_2RM_VRINTM:
432
- case NEON_2RM_VRINTP:
433
- case NEON_2RM_VRINTZ:
434
- case NEON_2RM_VCVTAU:
435
- case NEON_2RM_VCVTAS:
436
- case NEON_2RM_VCVTNU:
437
- case NEON_2RM_VCVTNS:
438
- case NEON_2RM_VCVTPU:
439
- case NEON_2RM_VCVTPS:
440
- case NEON_2RM_VCVTMU:
441
- case NEON_2RM_VCVTMS:
442
- case NEON_2RM_VSWP:
443
- /* handled by decodetree */
444
- return 1;
445
- case NEON_2RM_VTRN:
446
- if (size == 2) {
447
- int n;
448
- for (n = 0; n < (q ? 4 : 2); n += 2) {
449
- tmp = neon_load_reg(rm, n);
450
- tmp2 = neon_load_reg(rd, n + 1);
451
- neon_store_reg(rm, n, tmp2);
452
- neon_store_reg(rd, n + 1, tmp);
453
- }
454
- } else {
455
- goto elementwise;
456
- }
457
- break;
458
-
459
- default:
460
- elementwise:
461
- for (pass = 0; pass < (q ? 4 : 2); pass++) {
462
- tmp = neon_load_reg(rm, pass);
463
- switch (op) {
464
- case NEON_2RM_VTRN:
465
- tmp2 = neon_load_reg(rd, pass);
466
- switch (size) {
467
- case 0: gen_neon_trn_u8(tmp, tmp2); break;
468
- case 1: gen_neon_trn_u16(tmp, tmp2); break;
469
- default: abort();
470
- }
471
- neon_store_reg(rm, pass, tmp2);
472
- break;
473
- default:
474
- /* Reserved op values were caught by the
475
- * neon_2rm_sizes[] check earlier.
476
- */
477
- abort();
478
- }
479
- neon_store_reg(rd, pass, tmp);
480
- }
481
- break;
482
- }
483
- } else {
484
- /* VTBL, VTBX, VDUP: handled by decodetree */
485
- return 1;
486
- }
487
- }
488
- }
489
- return 0;
490
-}
491
-
492
static int disas_coproc_insn(DisasContext *s, uint32_t insn)
493
{
494
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
495
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
496
}
497
/* fall back to legacy decoder */
498
499
- if (((insn >> 25) & 7) == 1) {
500
- /* NEON Data processing. */
501
- if (disas_neon_data_insn(s, insn)) {
502
- goto illegal_op;
503
- }
504
- return;
505
- }
506
if ((insn & 0x0e000f00) == 0x0c000100) {
507
if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
508
/* iWMMXt register transfer. */
159
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
509
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
160
if (!s->v8m_secure || (insn & 0x0040f0ff)) {
510
break;
161
goto illegal_op;
511
}
162
}
512
if (((insn >> 24) & 3) == 3) {
163
- /* Just NOP since FP support is not implemented */
513
- /* Translate into the equivalent ARM encoding. */
164
+
514
- insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
165
+ if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
515
- if (disas_neon_data_insn(s, insn)) {
166
+ TCGv_i32 fptr = load_reg(s, rn);
516
- goto illegal_op;
167
+
517
- }
168
+ if (extract32(insn, 20, 1)) {
518
+ /* Neon DP, but failed disas_neon_dp() */
169
+ /* VLLDM */
519
+ goto illegal_op;
170
+ } else {
520
} else if (((insn >> 8) & 0xe) == 10) {
171
+ gen_helper_v7m_vlstm(cpu_env, fptr);
521
/* VFP, but failed disas_vfp. */
172
+ }
522
goto illegal_op;
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
--
523
--
182
2.20.1
524
2.20.1
183
525
184
526
diff view generated by jsdifflib
1
Add a new helper function which returns the MMU index to use
1
The functions neon_element_offset(), neon_load_element(),
2
for v7M, where the caller specifies all of the security
2
neon_load_element64(), neon_store_element() and
3
state, privilege level and whether the execution priority
3
neon_store_element64() are used only in the translate-neon.inc.c
4
is negative, and reimplement the existing
4
file, so move their definitions there.
5
arm_v7m_mmu_idx_for_secstate_and_priv() in terms of it.
5
6
6
Since the .inc.c file is #included in translate.c this doesn't make
7
We are going to need this for the lazy-FP-stacking code.
7
much difference currently, but it's a more logical place to put the
8
functions and it might be helpful if we ever decide to try to make
9
the .inc.c files genuinely separate compilation units.
8
10
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20190416125744.27770-21-peter.maydell@linaro.org
13
Message-id: 20200616170844.13318-22-peter.maydell@linaro.org
12
---
14
---
13
target/arm/cpu.h | 7 +++++++
15
target/arm/translate-neon.inc.c | 101 ++++++++++++++++++++++++++++++++
14
target/arm/helper.c | 14 +++++++++++---
16
target/arm/translate.c | 101 --------------------------------
15
2 files changed, 18 insertions(+), 3 deletions(-)
17
2 files changed, 101 insertions(+), 101 deletions(-)
16
18
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
18
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
21
--- a/target/arm/translate-neon.inc.c
20
+++ b/target/arm/cpu.h
22
+++ b/target/arm/translate-neon.inc.c
21
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
23
@@ -XXX,XX +XXX,XX @@ static inline int rsub_8(DisasContext *s, int x)
22
}
24
#include "decode-neon-ls.inc.c"
25
#include "decode-neon-shared.inc.c"
26
27
+/* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
28
+ * where 0 is the least significant end of the register.
29
+ */
30
+static inline long
31
+neon_element_offset(int reg, int element, MemOp size)
32
+{
33
+ int element_size = 1 << size;
34
+ int ofs = element * element_size;
35
+#ifdef HOST_WORDS_BIGENDIAN
36
+ /* Calculate the offset assuming fully little-endian,
37
+ * then XOR to account for the order of the 8-byte units.
38
+ */
39
+ if (element_size < 8) {
40
+ ofs ^= 8 - element_size;
41
+ }
42
+#endif
43
+ return neon_reg_offset(reg, 0) + ofs;
44
+}
45
+
46
+static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
47
+{
48
+ long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
49
+
50
+ switch (mop) {
51
+ case MO_UB:
52
+ tcg_gen_ld8u_i32(var, cpu_env, offset);
53
+ break;
54
+ case MO_UW:
55
+ tcg_gen_ld16u_i32(var, cpu_env, offset);
56
+ break;
57
+ case MO_UL:
58
+ tcg_gen_ld_i32(var, cpu_env, offset);
59
+ break;
60
+ default:
61
+ g_assert_not_reached();
62
+ }
63
+}
64
+
65
+static void neon_load_element64(TCGv_i64 var, int reg, int ele, MemOp mop)
66
+{
67
+ long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
68
+
69
+ switch (mop) {
70
+ case MO_UB:
71
+ tcg_gen_ld8u_i64(var, cpu_env, offset);
72
+ break;
73
+ case MO_UW:
74
+ tcg_gen_ld16u_i64(var, cpu_env, offset);
75
+ break;
76
+ case MO_UL:
77
+ tcg_gen_ld32u_i64(var, cpu_env, offset);
78
+ break;
79
+ case MO_Q:
80
+ tcg_gen_ld_i64(var, cpu_env, offset);
81
+ break;
82
+ default:
83
+ g_assert_not_reached();
84
+ }
85
+}
86
+
87
+static void neon_store_element(int reg, int ele, MemOp size, TCGv_i32 var)
88
+{
89
+ long offset = neon_element_offset(reg, ele, size);
90
+
91
+ switch (size) {
92
+ case MO_8:
93
+ tcg_gen_st8_i32(var, cpu_env, offset);
94
+ break;
95
+ case MO_16:
96
+ tcg_gen_st16_i32(var, cpu_env, offset);
97
+ break;
98
+ case MO_32:
99
+ tcg_gen_st_i32(var, cpu_env, offset);
100
+ break;
101
+ default:
102
+ g_assert_not_reached();
103
+ }
104
+}
105
+
106
+static void neon_store_element64(int reg, int ele, MemOp size, TCGv_i64 var)
107
+{
108
+ long offset = neon_element_offset(reg, ele, size);
109
+
110
+ switch (size) {
111
+ case MO_8:
112
+ tcg_gen_st8_i64(var, cpu_env, offset);
113
+ break;
114
+ case MO_16:
115
+ tcg_gen_st16_i64(var, cpu_env, offset);
116
+ break;
117
+ case MO_32:
118
+ tcg_gen_st32_i64(var, cpu_env, offset);
119
+ break;
120
+ case MO_64:
121
+ tcg_gen_st_i64(var, cpu_env, offset);
122
+ break;
123
+ default:
124
+ g_assert_not_reached();
125
+ }
126
+}
127
+
128
static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
129
{
130
int opr_sz;
131
diff --git a/target/arm/translate.c b/target/arm/translate.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/target/arm/translate.c
134
+++ b/target/arm/translate.c
135
@@ -XXX,XX +XXX,XX @@ neon_reg_offset (int reg, int n)
136
return vfp_reg_offset(0, sreg);
23
}
137
}
24
138
25
+/*
139
-/* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
26
+ * Return the MMU index for a v7M CPU with all relevant information
140
- * where 0 is the least significant end of the register.
27
+ * manually specified.
141
- */
28
+ */
142
-static inline long
29
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
143
-neon_element_offset(int reg, int element, MemOp size)
30
+ bool secstate, bool priv, bool negpri);
144
-{
31
+
145
- int element_size = 1 << size;
32
/* Return the MMU index for a v7M CPU in the specified security and
146
- int ofs = element * element_size;
33
* privilege state.
147
-#ifdef HOST_WORDS_BIGENDIAN
34
*/
148
- /* Calculate the offset assuming fully little-endian,
35
diff --git a/target/arm/helper.c b/target/arm/helper.c
149
- * then XOR to account for the order of the 8-byte units.
36
index XXXXXXX..XXXXXXX 100644
150
- */
37
--- a/target/arm/helper.c
151
- if (element_size < 8) {
38
+++ b/target/arm/helper.c
152
- ofs ^= 8 - element_size;
39
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
153
- }
40
return 0;
154
-#endif
155
- return neon_reg_offset(reg, 0) + ofs;
156
-}
157
-
158
static TCGv_i32 neon_load_reg(int reg, int pass)
159
{
160
TCGv_i32 tmp = tcg_temp_new_i32();
161
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 neon_load_reg(int reg, int pass)
162
return tmp;
41
}
163
}
42
164
43
-ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
165
-static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
44
- bool secstate, bool priv)
166
-{
45
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
167
- long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
46
+ bool secstate, bool priv, bool negpri)
168
-
47
{
169
- switch (mop) {
48
ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
170
- case MO_UB:
49
171
- tcg_gen_ld8u_i32(var, cpu_env, offset);
50
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
172
- break;
51
mmu_idx |= ARM_MMU_IDX_M_PRIV;
173
- case MO_UW:
52
}
174
- tcg_gen_ld16u_i32(var, cpu_env, offset);
53
175
- break;
54
- if (armv7m_nvic_neg_prio_requested(env->nvic, secstate)) {
176
- case MO_UL:
55
+ if (negpri) {
177
- tcg_gen_ld_i32(var, cpu_env, offset);
56
mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
178
- break;
57
}
179
- default:
58
180
- g_assert_not_reached();
59
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
181
- }
60
return mmu_idx;
182
-}
183
-
184
-static void neon_load_element64(TCGv_i64 var, int reg, int ele, MemOp mop)
185
-{
186
- long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
187
-
188
- switch (mop) {
189
- case MO_UB:
190
- tcg_gen_ld8u_i64(var, cpu_env, offset);
191
- break;
192
- case MO_UW:
193
- tcg_gen_ld16u_i64(var, cpu_env, offset);
194
- break;
195
- case MO_UL:
196
- tcg_gen_ld32u_i64(var, cpu_env, offset);
197
- break;
198
- case MO_Q:
199
- tcg_gen_ld_i64(var, cpu_env, offset);
200
- break;
201
- default:
202
- g_assert_not_reached();
203
- }
204
-}
205
-
206
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
207
{
208
tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
209
tcg_temp_free_i32(var);
61
}
210
}
62
211
63
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
212
-static void neon_store_element(int reg, int ele, MemOp size, TCGv_i32 var)
64
+ bool secstate, bool priv)
213
-{
65
+{
214
- long offset = neon_element_offset(reg, ele, size);
66
+ bool negpri = armv7m_nvic_neg_prio_requested(env->nvic, secstate);
215
-
67
+
216
- switch (size) {
68
+ return arm_v7m_mmu_idx_all(env, secstate, priv, negpri);
217
- case MO_8:
69
+}
218
- tcg_gen_st8_i32(var, cpu_env, offset);
70
+
219
- break;
71
/* Return the MMU index for a v7M CPU in the specified security state */
220
- case MO_16:
72
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
221
- tcg_gen_st16_i32(var, cpu_env, offset);
73
{
222
- break;
223
- case MO_32:
224
- tcg_gen_st_i32(var, cpu_env, offset);
225
- break;
226
- default:
227
- g_assert_not_reached();
228
- }
229
-}
230
-
231
-static void neon_store_element64(int reg, int ele, MemOp size, TCGv_i64 var)
232
-{
233
- long offset = neon_element_offset(reg, ele, size);
234
-
235
- switch (size) {
236
- case MO_8:
237
- tcg_gen_st8_i64(var, cpu_env, offset);
238
- break;
239
- case MO_16:
240
- tcg_gen_st16_i64(var, cpu_env, offset);
241
- break;
242
- case MO_32:
243
- tcg_gen_st32_i64(var, cpu_env, offset);
244
- break;
245
- case MO_64:
246
- tcg_gen_st_i64(var, cpu_env, offset);
247
- break;
248
- default:
249
- g_assert_not_reached();
250
- }
251
-}
252
-
253
static inline void neon_load_reg64(TCGv_i64 var, int reg)
254
{
255
tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
74
--
256
--
75
2.20.1
257
2.20.1
76
258
77
259
diff view generated by jsdifflib
1
We are close to running out of TB flags for AArch32; we could
1
Since commit ba3e7926691ed3 it has been unnecessary for target code
2
start using the cs_base word, but before we do that we can
2
to call gen_io_end() after an IO instruction in icount mode; it is
3
economise on our usage by sharing the same bits for the VFP
3
sufficient to call gen_io_start() before it and to force the end of
4
VECSTRIDE field and the XScale XSCALE_CPAR field. This
4
the TB.
5
works because no XScale CPU ever had VFP.
5
6
Many now-unnecessary calls to gen_io_end() were removed in commit
7
9e9b10c6491153b, but some were missed or accidentally added later.
8
Remove unneeded calls from the arm target:
9
10
* the call in the handling of exception-return-via-LDM is
11
unnecessary, and the code is already forcing end-of-TB
12
* the call in the VFP access check code is more complicated:
13
we weren't ending the TB, so we need to add the code to
14
force that by setting DISAS_UPDATE
15
* the doc comment for ARM_CP_IO doesn't need to mention
16
gen_io_end() any more
6
17
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-18-peter.maydell@linaro.org
21
Reviewed-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
22
Message-id: 20200619170324.12093-1-peter.maydell@linaro.org
10
---
23
---
11
target/arm/cpu.h | 10 ++++++----
24
target/arm/cpu.h | 2 +-
12
target/arm/cpu.c | 7 +++++++
25
target/arm/translate-vfp.inc.c | 7 +++----
13
target/arm/helper.c | 6 +++++-
26
target/arm/translate.c | 3 ---
14
target/arm/translate.c | 9 +++++++--
27
3 files changed, 4 insertions(+), 8 deletions(-)
15
4 files changed, 25 insertions(+), 7 deletions(-)
16
28
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
29
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
31
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
32
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
33
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
34
* migration or KVM state synchronization. (Typically this is for "registers"
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
35
* which are actually used as instructions for cache maintenance and so on.)
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
36
* IO indicates that this register does I/O and therefore its accesses
25
+/*
37
- * need to be surrounded by gen_io_start()/gen_io_end(). In particular,
26
+ * We store the bottom two bits of the CPAR as TB flags and handle
38
+ * need to be marked with gen_io_start() and also end the TB. In particular,
27
+ * checks on the other bits at runtime. This shares the same bits as
39
* registers which implement clocks or timers require this.
28
+ * VECSTRIDE, which is OK as no XScale CPU has VFP.
40
* RAISES_EXC is for when the read or write hook might raise an exception;
29
+ */
41
* the generated code will synchronize the CPU state before calling the hook
30
+FIELD(TBFLAG_A32, XSCALE_CPAR, 4, 2)
42
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
31
/*
32
* Indicates whether cp register reads and writes by guest code should access
33
* the secure or nonsecure bank of banked registers; note that this is not
34
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
35
FIELD(TBFLAG_A32, VFPEN, 7, 1)
36
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
37
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
38
-/* We store the bottom two bits of the CPAR as TB flags and handle
39
- * checks on the other bits at runtime
40
- */
41
-FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
42
/* For M profile only, Handler (ie not Thread) mode */
43
FIELD(TBFLAG_A32, HANDLER, 21, 1)
44
/* For M profile only, whether we should generate stack-limit checks */
45
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
46
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/cpu.c
44
--- a/target/arm/translate-vfp.inc.c
48
+++ b/target/arm/cpu.c
45
+++ b/target/arm/translate-vfp.inc.c
49
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
46
@@ -XXX,XX +XXX,XX @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
50
set_feature(env, ARM_FEATURE_THUMB_DSP);
47
if (s->v7m_lspact) {
51
}
48
/*
52
49
* Lazy state saving affects external memory and also the NVIC,
53
+ /*
50
- * so we must mark it as an IO operation for icount.
54
+ * We rely on no XScale CPU having VFP so we can use the same bits in the
51
+ * so we must mark it as an IO operation for icount (and cause
55
+ * TB flags field for VECSTRIDE and XSCALE_CPAR.
52
+ * this to be the last insn in the TB).
56
+ */
53
*/
57
+ assert(!(arm_feature(env, ARM_FEATURE_VFP) &&
54
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
58
+ arm_feature(env, ARM_FEATURE_XSCALE)));
55
+ s->base.is_jmp = DISAS_UPDATE;
59
+
56
gen_io_start();
60
if (arm_feature(env, ARM_FEATURE_V7) &&
57
}
61
!arm_feature(env, ARM_FEATURE_M) &&
58
gen_helper_v7m_preserve_fp_state(cpu_env);
62
!arm_feature(env, ARM_FEATURE_PMSA)) {
59
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
63
diff --git a/target/arm/helper.c b/target/arm/helper.c
60
- gen_io_end();
64
index XXXXXXX..XXXXXXX 100644
61
- }
65
--- a/target/arm/helper.c
62
/*
66
+++ b/target/arm/helper.c
63
* If the preserve_fp_state helper doesn't throw an exception
67
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
64
* then it will clear LSPACT; we don't need to repeat this for
68
|| arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
69
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
70
}
71
- flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
72
+ /* Note that XSCALE_CPAR shares bits with VECSTRIDE */
73
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
74
+ flags = FIELD_DP32(flags, TBFLAG_A32,
75
+ XSCALE_CPAR, env->cp15.c15_cpar);
76
+ }
77
}
78
79
flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
80
diff --git a/target/arm/translate.c b/target/arm/translate.c
65
diff --git a/target/arm/translate.c b/target/arm/translate.c
81
index XXXXXXX..XXXXXXX 100644
66
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/translate.c
67
--- a/target/arm/translate.c
83
+++ b/target/arm/translate.c
68
+++ b/target/arm/translate.c
84
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
69
@@ -XXX,XX +XXX,XX @@ static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n)
85
dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
70
gen_io_start();
86
dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
71
}
87
dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
72
gen_helper_cpsr_write_eret(cpu_env, tmp);
88
- dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
73
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
89
- dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
74
- gen_io_end();
90
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
75
- }
91
+ dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
76
tcg_temp_free_i32(tmp);
92
+ dc->vec_stride = 0;
77
/* Must exit loop to check un-masked IRQs */
93
+ } else {
78
s->base.is_jmp = DISAS_EXIT;
94
+ dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
95
+ dc->c15_cpar = 0;
96
+ }
97
dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
98
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
99
regime_is_secure(env, dc->mmu_idx);
100
--
79
--
101
2.20.1
80
2.20.1
102
81
103
82
diff view generated by jsdifflib
1
In the stripe8() function we use a variable length array; however
1
In commit cfdb2c0c95ae9205b0 ("target/arm: Vectorize SABA/UABA") we
2
we know that the maximum length required is MAX_NUM_BUSSES. Use
2
replaced the old handling of SABA/UABA with a vectorized implementation
3
a fixed-length array and an assert instead.
3
which returns early rather than falling into the loop-ever-elements
4
code. We forgot to delete the part of the old looping code that
5
did the accumulate step, and Coverity correctly warns (CID 1428955)
6
that this code is now dead. Delete it.
4
7
8
Fixes: cfdb2c0c95ae9205b0
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Message-id: 20200619171547.29780-1-peter.maydell@linaro.org
9
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
10
Message-id: 20190328152635.2794-1-peter.maydell@linaro.org
11
---
13
---
12
hw/ssi/xilinx_spips.c | 6 ++++--
14
target/arm/translate-a64.c | 12 ------------
13
1 file changed, 4 insertions(+), 2 deletions(-)
15
1 file changed, 12 deletions(-)
14
16
15
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
17
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/ssi/xilinx_spips.c
19
--- a/target/arm/translate-a64.c
18
+++ b/hw/ssi/xilinx_spips.c
20
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_reset(DeviceState *d)
21
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
20
22
genfn(tcg_res, tcg_op1, tcg_op2);
21
static inline void stripe8(uint8_t *x, int num, bool dir)
23
}
22
{
24
23
- uint8_t r[num];
25
- if (opcode == 0xf) {
24
- memset(r, 0, sizeof(uint8_t) * num);
26
- /* SABA, UABA: accumulating ops */
25
+ uint8_t r[MAX_NUM_BUSSES];
27
- static NeonGenTwoOpFn * const fns[3] = {
26
int idx[2] = {0, 0};
28
- gen_helper_neon_add_u8,
27
int bit[2] = {0, 7};
29
- gen_helper_neon_add_u16,
28
int d = dir;
30
- tcg_gen_add_i32,
29
31
- };
30
+ assert(num <= MAX_NUM_BUSSES);
32
-
31
+ memset(r, 0, sizeof(uint8_t) * num);
33
- read_vec_element_i32(s, tcg_op1, rd, pass, MO_32);
32
+
34
- fns[size](tcg_res, tcg_op1, tcg_res);
33
for (idx[0] = 0; idx[0] < num; ++idx[0]) {
35
- }
34
for (bit[0] = 7; bit[0] >= 0; bit[0]--) {
36
-
35
r[idx[!d]] |= x[idx[d]] & 1 << bit[d] ? 1 << bit[!d] : 0;
37
write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
38
39
tcg_temp_free_i32(tcg_res);
36
--
40
--
37
2.20.1
41
2.20.1
38
42
39
43
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Since uWireSlave is only used in this new header, there is no
3
Add a trace event to see when a guest disable/enable the watchdog.
4
need to expose it via "qemu/typedefs.h".
5
4
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20200617072539.32686-2-f4bug@amsat.org
8
Message-id: 20190412165416.7977-9-philmd@redhat.com
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
include/hw/arm/omap.h | 6 +-----
10
hw/watchdog/cmsdk-apb-watchdog.c | 1 +
12
include/hw/devices.h | 15 ---------------
11
hw/watchdog/trace-events | 1 +
13
include/hw/input/tsc2xxx.h | 36 ++++++++++++++++++++++++++++++++++++
12
2 files changed, 2 insertions(+)
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
13
23
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
14
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
24
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/omap.h
16
--- a/hw/watchdog/cmsdk-apb-watchdog.c
26
+++ b/include/hw/arm/omap.h
17
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
18
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset,
19
break;
20
case A_WDOGLOCK:
21
s->lock = (value != WDOG_UNLOCK_VALUE);
22
+ trace_cmsdk_apb_watchdog_lock(s->lock);
23
break;
24
case A_WDOGITCR:
25
if (s->is_luminary) {
26
diff --git a/hw/watchdog/trace-events b/hw/watchdog/trace-events
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/watchdog/trace-events
29
+++ b/hw/watchdog/trace-events
27
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@
28
#include "exec/memory.h"
31
cmsdk_apb_watchdog_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
29
# define hw_omap_h        "omap.h"
32
cmsdk_apb_watchdog_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
30
#include "hw/irq.h"
33
cmsdk_apb_watchdog_reset(void) "CMSDK APB watchdog: reset"
31
+#include "hw/input/tsc2xxx.h"
34
+cmsdk_apb_watchdog_lock(uint32_t lock) "CMSDK APB watchdog: lock %" PRIu32
32
#include "target/arm/cpu-qom.h"
33
#include "qemu/log.h"
34
35
@@ -XXX,XX +XXX,XX @@ qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s);
36
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler);
37
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down);
38
39
-struct uWireSlave {
40
- uint16_t (*receive)(void *opaque);
41
- void (*send)(void *opaque, uint16_t data);
42
- void *opaque;
43
-};
44
struct omap_uwire_s;
45
void omap_uwire_attach(struct omap_uwire_s *s,
46
uWireSlave *slave, int chipselect);
47
diff --git a/include/hw/devices.h b/include/hw/devices.h
48
index XXXXXXX..XXXXXXX 100644
49
--- a/include/hw/devices.h
50
+++ b/include/hw/devices.h
51
@@ -XXX,XX +XXX,XX @@
52
/* Devices that have nowhere better to go. */
53
54
#include "hw/hw.h"
55
-#include "ui/console.h"
56
57
/* smc91c111.c */
58
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
59
@@ -XXX,XX +XXX,XX @@ void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
60
/* lan9118.c */
61
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
62
63
-/* tsc210x.c */
64
-uWireSlave *tsc2102_init(qemu_irq pint);
65
-uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
66
-I2SCodec *tsc210x_codec(uWireSlave *chip);
67
-uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
68
-void tsc210x_set_transform(uWireSlave *chip,
69
- MouseTransformInfo *info);
70
-void tsc210x_key_event(uWireSlave *chip, int key, int down);
71
-
72
-/* tsc2005.c */
73
-void *tsc2005_init(qemu_irq pintdav);
74
-uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
75
-void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
76
-
77
#endif
78
diff --git a/include/hw/input/tsc2xxx.h b/include/hw/input/tsc2xxx.h
79
new file mode 100644
80
index XXXXXXX..XXXXXXX
81
--- /dev/null
82
+++ b/include/hw/input/tsc2xxx.h
83
@@ -XXX,XX +XXX,XX @@
84
+/*
85
+ * TI touchscreen controller
86
+ *
87
+ * Copyright (c) 2006 Andrzej Zaborowski
88
+ * Copyright (C) 2008 Nokia Corporation
89
+ *
90
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
91
+ * See the COPYING file in the top-level directory.
92
+ */
93
+
94
+#ifndef HW_INPUT_TSC2XXX_H
95
+#define HW_INPUT_TSC2XXX_H
96
+
97
+#include "hw/irq.h"
98
+#include "ui/console.h"
99
+
100
+typedef struct uWireSlave {
101
+ uint16_t (*receive)(void *opaque);
102
+ void (*send)(void *opaque, uint16_t data);
103
+ void *opaque;
104
+} uWireSlave;
105
+
106
+/* tsc210x.c */
107
+uWireSlave *tsc2102_init(qemu_irq pint);
108
+uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
109
+I2SCodec *tsc210x_codec(uWireSlave *chip);
110
+uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
111
+void tsc210x_set_transform(uWireSlave *chip, MouseTransformInfo *info);
112
+void tsc210x_key_event(uWireSlave *chip, int key, int down);
113
+
114
+/* tsc2005.c */
115
+void *tsc2005_init(qemu_irq pintdav);
116
+uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
117
+void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
118
+
119
+#endif
120
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
121
index XXXXXXX..XXXXXXX 100644
122
--- a/include/qemu/typedefs.h
123
+++ b/include/qemu/typedefs.h
124
@@ -XXX,XX +XXX,XX @@ typedef struct RAMBlock RAMBlock;
125
typedef struct Range Range;
126
typedef struct SHPCDevice SHPCDevice;
127
typedef struct SSIBus SSIBus;
128
-typedef struct uWireSlave uWireSlave;
129
typedef struct VirtIODevice VirtIODevice;
130
typedef struct Visitor Visitor;
131
typedef void SaveStateHandler(QEMUFile *f, void *opaque);
132
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/hw/arm/nseries.c
135
+++ b/hw/arm/nseries.c
136
@@ -XXX,XX +XXX,XX @@
137
#include "ui/console.h"
138
#include "hw/boards.h"
139
#include "hw/i2c/i2c.h"
140
-#include "hw/devices.h"
141
#include "hw/display/blizzard.h"
142
+#include "hw/input/tsc2xxx.h"
143
#include "hw/misc/cbus.h"
144
#include "hw/misc/tmp105.h"
145
#include "hw/block/flash.h"
146
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
147
index XXXXXXX..XXXXXXX 100644
148
--- a/hw/arm/palm.c
149
+++ b/hw/arm/palm.c
150
@@ -XXX,XX +XXX,XX @@
151
#include "hw/arm/omap.h"
152
#include "hw/boards.h"
153
#include "hw/arm/arm.h"
154
-#include "hw/devices.h"
155
+#include "hw/input/tsc2xxx.h"
156
#include "hw/loader.h"
157
#include "exec/address-spaces.h"
158
#include "cpu.h"
159
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/hw/input/tsc2005.c
162
+++ b/hw/input/tsc2005.c
163
@@ -XXX,XX +XXX,XX @@
164
#include "hw/hw.h"
165
#include "qemu/timer.h"
166
#include "ui/console.h"
167
-#include "hw/devices.h"
168
+#include "hw/input/tsc2xxx.h"
169
#include "trace.h"
170
171
#define TSC_CUT_RESOLUTION(value, p)    ((value) >> (16 - (p ? 12 : 10)))
172
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
173
index XXXXXXX..XXXXXXX 100644
174
--- a/hw/input/tsc210x.c
175
+++ b/hw/input/tsc210x.c
176
@@ -XXX,XX +XXX,XX @@
177
#include "audio/audio.h"
178
#include "qemu/timer.h"
179
#include "ui/console.h"
180
-#include "hw/arm/omap.h"    /* For I2SCodec and uWireSlave */
181
-#include "hw/devices.h"
182
+#include "hw/arm/omap.h" /* For I2SCodec */
183
+#include "hw/input/tsc2xxx.h"
184
185
#define TSC_DATA_REGISTERS_PAGE        0x0
186
#define TSC_CONTROL_REGISTERS_PAGE    0x1
187
diff --git a/MAINTAINERS b/MAINTAINERS
188
index XXXXXXX..XXXXXXX 100644
189
--- a/MAINTAINERS
190
+++ b/MAINTAINERS
191
@@ -XXX,XX +XXX,XX @@ F: hw/input/tsc2005.c
192
F: hw/misc/cbus.c
193
F: hw/timer/twl92230.c
194
F: include/hw/display/blizzard.h
195
+F: include/hw/input/tsc2xxx.h
196
F: include/hw/misc/cbus.h
197
198
Palm
199
@@ -XXX,XX +XXX,XX @@ L: qemu-arm@nongnu.org
200
S: Odd Fixes
201
F: hw/arm/palm.c
202
F: hw/input/tsc210x.c
203
+F: include/hw/input/tsc2xxx.h
204
205
Raspberry Pi
206
M: Peter Maydell <peter.maydell@linaro.org>
207
--
35
--
208
2.20.1
36
2.20.1
209
37
210
38
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
Use self-explicit definitions instead of magic values.
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20190412165416.7977-7-philmd@redhat.com
6
Message-id: 20200617072539.32686-3-f4bug@amsat.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
---
9
include/hw/devices.h | 14 --------------
10
hw/i2c/versatile_i2c.c | 14 ++++++++++----
10
include/hw/misc/cbus.h | 32 ++++++++++++++++++++++++++++++++
11
1 file changed, 10 insertions(+), 4 deletions(-)
11
hw/arm/nseries.c | 1 +
12
hw/misc/cbus.c | 2 +-
13
MAINTAINERS | 1 +
14
5 files changed, 35 insertions(+), 15 deletions(-)
15
create mode 100644 include/hw/misc/cbus.h
16
12
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
13
diff --git a/hw/i2c/versatile_i2c.c b/hw/i2c/versatile_i2c.c
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/devices.h
15
--- a/hw/i2c/versatile_i2c.c
20
+++ b/include/hw/devices.h
16
+++ b/hw/i2c/versatile_i2c.c
21
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
22
/* stellaris_input.c */
23
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
24
25
-/* cbus.c */
26
-typedef struct {
27
- qemu_irq clk;
28
- qemu_irq dat;
29
- qemu_irq sel;
30
-} CBus;
31
-CBus *cbus_init(qemu_irq dat_out);
32
-void cbus_attach(CBus *bus, void *slave_opaque);
33
-
34
-void *retu_init(qemu_irq irq, int vilma);
35
-void *tahvo_init(qemu_irq irq, int betty);
36
-
37
-void retu_key_event(void *retu, int state);
38
-
39
#endif
40
diff --git a/include/hw/misc/cbus.h b/include/hw/misc/cbus.h
41
new file mode 100644
42
index XXXXXXX..XXXXXXX
43
--- /dev/null
44
+++ b/include/hw/misc/cbus.h
45
@@ -XXX,XX +XXX,XX @@
46
+/*
47
+ * CBUS three-pin bus and the Retu / Betty / Tahvo / Vilma / Avilma /
48
+ * Hinku / Vinku / Ahne / Pihi chips used in various Nokia platforms.
49
+ * Based on reverse-engineering of a linux driver.
50
+ *
51
+ * Copyright (C) 2008 Nokia Corporation
52
+ * Written by Andrzej Zaborowski
53
+ *
54
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
55
+ * See the COPYING file in the top-level directory.
56
+ */
57
+
58
+#ifndef HW_MISC_CBUS_H
59
+#define HW_MISC_CBUS_H
60
+
61
+#include "hw/irq.h"
62
+
63
+typedef struct {
64
+ qemu_irq clk;
65
+ qemu_irq dat;
66
+ qemu_irq sel;
67
+} CBus;
68
+
69
+CBus *cbus_init(qemu_irq dat_out);
70
+void cbus_attach(CBus *bus, void *slave_opaque);
71
+
72
+void *retu_init(qemu_irq irq, int vilma);
73
+void *tahvo_init(qemu_irq irq, int betty);
74
+
75
+void retu_key_event(void *retu, int state);
76
+
77
+#endif
78
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/hw/arm/nseries.c
81
+++ b/hw/arm/nseries.c
82
@@ -XXX,XX +XXX,XX @@
83
#include "hw/i2c/i2c.h"
84
#include "hw/devices.h"
85
#include "hw/display/blizzard.h"
86
+#include "hw/misc/cbus.h"
87
#include "hw/misc/tmp105.h"
88
#include "hw/block/flash.h"
89
#include "hw/hw.h"
90
diff --git a/hw/misc/cbus.c b/hw/misc/cbus.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/hw/misc/cbus.c
93
+++ b/hw/misc/cbus.c
94
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@
95
#include "qemu/osdep.h"
18
#include "qemu/osdep.h"
96
#include "hw/hw.h"
19
#include "hw/sysbus.h"
97
#include "hw/irq.h"
20
#include "hw/i2c/bitbang_i2c.h"
98
-#include "hw/devices.h"
21
+#include "hw/registerfields.h"
99
+#include "hw/misc/cbus.h"
22
#include "qemu/log.h"
100
#include "sysemu/sysemu.h"
23
#include "qemu/module.h"
101
24
102
//#define DEBUG
25
@@ -XXX,XX +XXX,XX @@ typedef struct VersatileI2CState {
103
diff --git a/MAINTAINERS b/MAINTAINERS
26
int in;
104
index XXXXXXX..XXXXXXX 100644
27
} VersatileI2CState;
105
--- a/MAINTAINERS
28
106
+++ b/MAINTAINERS
29
+REG32(CONTROL_GET, 0)
107
@@ -XXX,XX +XXX,XX @@ F: hw/input/tsc2005.c
30
+REG32(CONTROL_SET, 0)
108
F: hw/misc/cbus.c
31
+REG32(CONTROL_CLR, 4)
109
F: hw/timer/twl92230.c
32
+
110
F: include/hw/display/blizzard.h
33
static uint64_t versatile_i2c_read(void *opaque, hwaddr offset,
111
+F: include/hw/misc/cbus.h
34
unsigned size)
112
35
{
113
Palm
36
VersatileI2CState *s = (VersatileI2CState *)opaque;
114
M: Andrzej Zaborowski <balrogg@gmail.com>
37
38
- if (offset == 0) {
39
+ switch (offset) {
40
+ case A_CONTROL_SET:
41
return (s->out & 1) | (s->in << 1);
42
- } else {
43
+ default:
44
qemu_log_mask(LOG_GUEST_ERROR,
45
"%s: Bad offset 0x%x\n", __func__, (int)offset);
46
return -1;
47
@@ -XXX,XX +XXX,XX @@ static void versatile_i2c_write(void *opaque, hwaddr offset,
48
VersatileI2CState *s = (VersatileI2CState *)opaque;
49
50
switch (offset) {
51
- case 0:
52
+ case A_CONTROL_SET:
53
s->out |= value & 3;
54
break;
55
- case 4:
56
+ case A_CONTROL_CLR:
57
s->out &= ~value;
58
break;
59
default:
115
--
60
--
116
2.20.1
61
2.20.1
117
62
118
63
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
No code used the tc6393xb_gpio_in_get() and tc6393xb_gpio_out_set()
3
Use self-explicit definitions instead of magic values.
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: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20200617072539.32686-4-f4bug@amsat.org
9
Message-id: 20190412165416.7977-4-philmd@redhat.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
9
---
13
include/hw/devices.h | 3 ---
10
hw/i2c/versatile_i2c.c | 7 +++++--
14
hw/display/tc6393xb.c | 16 ----------------
11
1 file changed, 5 insertions(+), 2 deletions(-)
15
2 files changed, 19 deletions(-)
16
12
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
13
diff --git a/hw/i2c/versatile_i2c.c b/hw/i2c/versatile_i2c.c
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/devices.h
15
--- a/hw/i2c/versatile_i2c.c
20
+++ b/include/hw/devices.h
16
+++ b/hw/i2c/versatile_i2c.c
21
@@ -XXX,XX +XXX,XX @@ void retu_key_event(void *retu, int state);
17
@@ -XXX,XX +XXX,XX @@ REG32(CONTROL_GET, 0)
22
typedef struct TC6393xbState TC6393xbState;
18
REG32(CONTROL_SET, 0)
23
TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
19
REG32(CONTROL_CLR, 4)
24
uint32_t base, qemu_irq irq);
20
25
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
21
+#define SCL BIT(0)
26
- qemu_irq handler);
22
+#define SDA BIT(1)
27
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s);
23
+
28
qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
24
static uint64_t versatile_i2c_read(void *opaque, hwaddr offset,
29
25
unsigned size)
30
#endif
31
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/display/tc6393xb.c
34
+++ b/hw/display/tc6393xb.c
35
@@ -XXX,XX +XXX,XX @@ struct TC6393xbState {
36
blanked : 1;
37
};
38
39
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s)
40
-{
41
- return s->gpio_in;
42
-}
43
-
44
static void tc6393xb_gpio_set(void *opaque, int line, int level)
45
{
26
{
46
// TC6393xbState *s = opaque;
27
@@ -XXX,XX +XXX,XX @@ static void versatile_i2c_write(void *opaque, hwaddr offset,
47
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_gpio_set(void *opaque, int line, int level)
28
qemu_log_mask(LOG_GUEST_ERROR,
48
// FIXME: how does the chip reflect the GPIO input level change?
29
"%s: Bad offset 0x%x\n", __func__, (int)offset);
30
}
31
- bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SCL, (s->out & 1) != 0);
32
- s->in = bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SDA, (s->out & 2) != 0);
33
+ bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SCL, (s->out & SCL) != 0);
34
+ s->in = bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SDA, (s->out & SDA) != 0);
49
}
35
}
50
36
51
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
37
static const MemoryRegionOps versatile_i2c_ops = {
52
- qemu_irq handler)
53
-{
54
- if (line >= TC6393XB_GPIOS) {
55
- fprintf(stderr, "TC6393xb: no GPIO pin %d\n", line);
56
- return;
57
- }
58
-
59
- s->handler[line] = handler;
60
-}
61
-
62
static void tc6393xb_gpio_handler_update(TC6393xbState *s)
63
{
64
uint32_t level, diff;
65
--
38
--
66
2.20.1
39
2.20.1
67
40
68
41
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
'ARM SBCon two-wire serial bus interface' is the official
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
name describing the pair of registers used to bitbanging
5
Message-id: 20190412165416.7977-8-philmd@redhat.com
5
I2C in the Versatile boards.
6
7
Make the private VersatileI2CState structure as public
8
ArmSbconI2CState.
9
Add the TYPE_ARM_SBCON_I2C, alias to our current
10
TYPE_VERSATILE_I2C model.
11
Rename the memory region description as 'arm_sbcon_i2c'.
12
13
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20200617072539.32686-5-f4bug@amsat.org
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
17
---
8
include/hw/devices.h | 3 ---
18
include/hw/i2c/arm_sbcon_i2c.h | 35 ++++++++++++++++++++++++++++++++++
9
include/hw/input/gamepad.h | 19 +++++++++++++++++++
19
hw/i2c/versatile_i2c.c | 17 +++++------------
10
hw/arm/stellaris.c | 2 +-
20
MAINTAINERS | 1 +
11
hw/input/stellaris_input.c | 2 +-
21
3 files changed, 41 insertions(+), 12 deletions(-)
12
MAINTAINERS | 1 +
22
create mode 100644 include/hw/i2c/arm_sbcon_i2c.h
13
5 files changed, 22 insertions(+), 5 deletions(-)
14
create mode 100644 include/hw/input/gamepad.h
15
23
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
24
diff --git a/include/hw/i2c/arm_sbcon_i2c.h b/include/hw/i2c/arm_sbcon_i2c.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
25
new file mode 100644
30
index XXXXXXX..XXXXXXX
26
index XXXXXXX..XXXXXXX
31
--- /dev/null
27
--- /dev/null
32
+++ b/include/hw/input/gamepad.h
28
+++ b/include/hw/i2c/arm_sbcon_i2c.h
33
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@
34
+/*
30
+/*
35
+ * Gamepad style buttons connected to IRQ/GPIO lines
31
+ * ARM SBCon two-wire serial bus interface (I2C bitbang)
32
+ * a.k.a.
33
+ * ARM Versatile I2C controller
36
+ *
34
+ *
37
+ * Copyright (c) 2007 CodeSourcery.
35
+ * Copyright (c) 2006-2007 CodeSourcery.
38
+ * Written by Paul Brook
36
+ * Copyright (c) 2012 Oskar Andero <oskar.andero@gmail.com>
37
+ * Copyright (C) 2020 Philippe Mathieu-Daudé <f4bug@amsat.org>
39
+ *
38
+ *
40
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
39
+ * SPDX-License-Identifier: GPL-2.0-or-later
41
+ * See the COPYING file in the top-level directory.
42
+ */
40
+ */
41
+#ifndef HW_I2C_ARM_SBCON_H
42
+#define HW_I2C_ARM_SBCON_H
43
+
43
+
44
+#ifndef HW_INPUT_GAMEPAD_H
44
+#include "hw/sysbus.h"
45
+#define HW_INPUT_GAMEPAD_H
45
+#include "hw/i2c/bitbang_i2c.h"
46
+
46
+
47
+#include "hw/irq.h"
47
+#define TYPE_VERSATILE_I2C "versatile_i2c"
48
+#define TYPE_ARM_SBCON_I2C TYPE_VERSATILE_I2C
48
+
49
+
49
+/* stellaris_input.c */
50
+#define ARM_SBCON_I2C(obj) \
50
+void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
51
+ OBJECT_CHECK(ArmSbconI2CState, (obj), TYPE_ARM_SBCON_I2C)
51
+
52
+
52
+#endif
53
+typedef struct ArmSbconI2CState {
53
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
54
+ /*< private >*/
55
+ SysBusDevice parent_obj;
56
+ /*< public >*/
57
+
58
+ MemoryRegion iomem;
59
+ bitbang_i2c_interface bitbang;
60
+ int out;
61
+ int in;
62
+} ArmSbconI2CState;
63
+
64
+#endif /* HW_I2C_ARM_SBCON_H */
65
diff --git a/hw/i2c/versatile_i2c.c b/hw/i2c/versatile_i2c.c
54
index XXXXXXX..XXXXXXX 100644
66
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/arm/stellaris.c
67
--- a/hw/i2c/versatile_i2c.c
56
+++ b/hw/arm/stellaris.c
68
+++ b/hw/i2c/versatile_i2c.c
57
@@ -XXX,XX +XXX,XX @@
69
@@ -XXX,XX +XXX,XX @@
58
#include "hw/sysbus.h"
70
/*
59
#include "hw/ssi/ssi.h"
71
- * ARM Versatile I2C controller
60
#include "hw/arm/arm.h"
72
+ * ARM SBCon two-wire serial bus interface (I2C bitbang)
61
-#include "hw/devices.h"
73
+ * a.k.a. ARM Versatile I2C controller
62
#include "qemu/timer.h"
74
*
63
#include "hw/i2c/i2c.h"
75
* Copyright (c) 2006-2007 CodeSourcery.
64
#include "net/net.h"
76
* Copyright (c) 2012 Oskar Andero <oskar.andero@gmail.com>
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 @@
77
@@ -XXX,XX +XXX,XX @@
78
*/
78
*/
79
79
#include "qemu/osdep.h"
80
#include "qemu/osdep.h"
80
#include "hw/hw.h"
81
-#include "hw/sysbus.h"
81
-#include "hw/devices.h"
82
-#include "hw/i2c/bitbang_i2c.h"
82
+#include "hw/input/gamepad.h"
83
+#include "hw/i2c/arm_sbcon_i2c.h"
83
#include "ui/console.h"
84
#include "hw/registerfields.h"
84
85
#include "qemu/log.h"
85
typedef struct {
86
#include "qemu/module.h"
87
88
-#define TYPE_VERSATILE_I2C "versatile_i2c"
89
#define VERSATILE_I2C(obj) \
90
OBJECT_CHECK(VersatileI2CState, (obj), TYPE_VERSATILE_I2C)
91
92
-typedef struct VersatileI2CState {
93
- SysBusDevice parent_obj;
94
+typedef ArmSbconI2CState VersatileI2CState;
95
96
- MemoryRegion iomem;
97
- bitbang_i2c_interface bitbang;
98
- int out;
99
- int in;
100
-} VersatileI2CState;
101
102
REG32(CONTROL_GET, 0)
103
REG32(CONTROL_SET, 0)
104
@@ -XXX,XX +XXX,XX @@ static void versatile_i2c_init(Object *obj)
105
bus = i2c_init_bus(dev, "i2c");
106
bitbang_i2c_init(&s->bitbang, bus);
107
memory_region_init_io(&s->iomem, obj, &versatile_i2c_ops, s,
108
- "versatile_i2c", 0x1000);
109
+ "arm_sbcon_i2c", 0x1000);
110
sysbus_init_mmio(sbd, &s->iomem);
111
}
112
86
diff --git a/MAINTAINERS b/MAINTAINERS
113
diff --git a/MAINTAINERS b/MAINTAINERS
87
index XXXXXXX..XXXXXXX 100644
114
index XXXXXXX..XXXXXXX 100644
88
--- a/MAINTAINERS
115
--- a/MAINTAINERS
89
+++ b/MAINTAINERS
116
+++ b/MAINTAINERS
90
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
117
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
91
L: qemu-arm@nongnu.org
118
L: qemu-arm@nongnu.org
92
S: Maintained
119
S: Maintained
93
F: hw/*/stellaris*
120
F: hw/*/versatile*
94
+F: include/hw/input/gamepad.h
121
+F: include/hw/i2c/arm_sbcon_i2c.h
95
122
F: hw/misc/arm_sysctl.c
96
Versatile Express
123
F: docs/system/arm/versatile.rst
97
M: Peter Maydell <peter.maydell@linaro.org>
124
98
--
125
--
99
2.20.1
126
2.20.1
100
127
101
128
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
This commit finally deletes "hw/devices.h".
3
By using the TYPE_* definitions for devices, we can:
4
- quickly find where devices are used with 'git-grep'
5
- easily rename a device (one-line change).
4
6
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20200617072539.32686-6-f4bug@amsat.org
7
Message-id: 20190412165416.7977-13-philmd@redhat.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
11
---
10
include/hw/devices.h | 11 -----------
12
hw/arm/realview.c | 3 ++-
11
include/hw/net/smc91c111.h | 19 +++++++++++++++++++
13
hw/arm/versatilepb.c | 3 ++-
12
hw/arm/gumstix.c | 2 +-
14
hw/arm/vexpress.c | 3 ++-
13
hw/arm/integratorcp.c | 2 +-
15
3 files changed, 6 insertions(+), 3 deletions(-)
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
16
22
diff --git a/include/hw/devices.h b/include/hw/devices.h
23
deleted file mode 100644
24
index XXXXXXX..XXXXXXX
25
--- a/include/hw/devices.h
26
+++ /dev/null
27
@@ -XXX,XX +XXX,XX @@
28
-#ifndef QEMU_DEVICES_H
29
-#define QEMU_DEVICES_H
30
-
31
-/* Devices that have nowhere better to go. */
32
-
33
-#include "hw/hw.h"
34
-
35
-/* smc91c111.c */
36
-void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
37
-
38
-#endif
39
diff --git a/include/hw/net/smc91c111.h b/include/hw/net/smc91c111.h
40
new file mode 100644
41
index XXXXXXX..XXXXXXX
42
--- /dev/null
43
+++ b/include/hw/net/smc91c111.h
44
@@ -XXX,XX +XXX,XX @@
45
+/*
46
+ * SMSC 91C111 Ethernet interface emulation
47
+ *
48
+ * Copyright (c) 2005 CodeSourcery, LLC.
49
+ * Written by Paul Brook
50
+ *
51
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
52
+ * See the COPYING file in the top-level directory.
53
+ */
54
+
55
+#ifndef HW_NET_SMC91C111_H
56
+#define HW_NET_SMC91C111_H
57
+
58
+#include "hw/irq.h"
59
+#include "net/net.h"
60
+
61
+void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
62
+
63
+#endif
64
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/hw/arm/gumstix.c
67
+++ b/hw/arm/gumstix.c
68
@@ -XXX,XX +XXX,XX @@
69
#include "hw/arm/pxa.h"
70
#include "net/net.h"
71
#include "hw/block/flash.h"
72
-#include "hw/devices.h"
73
+#include "hw/net/smc91c111.h"
74
#include "hw/boards.h"
75
#include "exec/address-spaces.h"
76
#include "sysemu/qtest.h"
77
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/arm/integratorcp.c
80
+++ b/hw/arm/integratorcp.c
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
17
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
107
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
108
--- a/hw/arm/realview.c
19
--- a/hw/arm/realview.c
109
+++ b/hw/arm/realview.c
20
+++ b/hw/arm/realview.c
110
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
111
#include "hw/sysbus.h"
22
#include "hw/cpu/a9mpcore.h"
112
#include "hw/arm/arm.h"
23
#include "hw/intc/realview_gic.h"
113
#include "hw/arm/primecell.h"
24
#include "hw/irq.h"
114
-#include "hw/devices.h"
25
+#include "hw/i2c/arm_sbcon_i2c.h"
115
#include "hw/net/lan9118.h"
26
116
+#include "hw/net/smc91c111.h"
27
#define SMP_BOOT_ADDR 0xe0000000
117
#include "hw/pci/pci.h"
28
#define SMP_BOOTREG_ADDR 0x10000030
118
#include "net/net.h"
29
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
119
#include "sysemu/sysemu.h"
30
}
31
}
32
33
- dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL);
34
+ dev = sysbus_create_simple(TYPE_VERSATILE_I2C, 0x10002000, NULL);
35
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
36
i2c_create_slave(i2c, "ds1338", 0x68);
37
120
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
38
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
121
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
122
--- a/hw/arm/versatilepb.c
40
--- a/hw/arm/versatilepb.c
123
+++ b/hw/arm/versatilepb.c
41
+++ b/hw/arm/versatilepb.c
124
@@ -XXX,XX +XXX,XX @@
42
@@ -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"
43
#include "sysemu/sysemu.h"
132
#include "hw/pci/pci.h"
44
#include "hw/pci/pci.h"
133
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
45
#include "hw/i2c/i2c.h"
46
+#include "hw/i2c/arm_sbcon_i2c.h"
47
#include "hw/irq.h"
48
#include "hw/boards.h"
49
#include "exec/address-spaces.h"
50
@@ -XXX,XX +XXX,XX @@ static void versatile_init(MachineState *machine, int board_id)
51
/* Add PL031 Real Time Clock. */
52
sysbus_create_simple("pl031", 0x101e8000, pic[10]);
53
54
- dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL);
55
+ dev = sysbus_create_simple(TYPE_VERSATILE_I2C, 0x10002000, NULL);
56
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
57
i2c_create_slave(i2c, "ds1338", 0x68);
58
59
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
134
index XXXXXXX..XXXXXXX 100644
60
index XXXXXXX..XXXXXXX 100644
135
--- a/hw/net/smc91c111.c
61
--- a/hw/arm/vexpress.c
136
+++ b/hw/net/smc91c111.c
62
+++ b/hw/arm/vexpress.c
137
@@ -XXX,XX +XXX,XX @@
63
@@ -XXX,XX +XXX,XX @@
138
#include "qemu/osdep.h"
64
#include "hw/char/pl011.h"
139
#include "hw/sysbus.h"
65
#include "hw/cpu/a9mpcore.h"
140
#include "net/net.h"
66
#include "hw/cpu/a15mpcore.h"
141
-#include "hw/devices.h"
67
+#include "hw/i2c/arm_sbcon_i2c.h"
142
+#include "hw/net/smc91c111.h"
68
143
#include "qemu/log.h"
69
#define VEXPRESS_BOARD_ID 0x8e0
144
/* For crc32 */
70
#define VEXPRESS_FLASH_SIZE (64 * 1024 * 1024)
145
#include <zlib.h>
71
@@ -XXX,XX +XXX,XX @@ static void vexpress_common_init(MachineState *machine)
72
sysbus_create_simple("sp804", map[VE_TIMER01], pic[2]);
73
sysbus_create_simple("sp804", map[VE_TIMER23], pic[3]);
74
75
- dev = sysbus_create_simple("versatile_i2c", map[VE_SERIALDVI], NULL);
76
+ dev = sysbus_create_simple(TYPE_VERSATILE_I2C, map[VE_SERIALDVI], NULL);
77
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
78
i2c_create_slave(i2c, "sii9022", 0x39);
79
146
--
80
--
147
2.20.1
81
2.20.1
148
82
149
83
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Add an entries the Blizzard device in MAINTAINERS.
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
4
Message-id: 20200617072539.32686-7-f4bug@amsat.org
5
Reviewed-by: Thomas Huth <thuth@redhat.com>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
7
---
11
include/hw/devices.h | 7 -------
8
hw/arm/mps2.c | 5 ++++-
12
include/hw/display/blizzard.h | 22 ++++++++++++++++++++++
9
1 file changed, 4 insertions(+), 1 deletion(-)
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
10
19
diff --git a/include/hw/devices.h b/include/hw/devices.h
11
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
20
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/devices.h
13
--- a/hw/arm/mps2.c
22
+++ b/include/hw/devices.h
14
+++ b/hw/arm/mps2.c
23
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
15
@@ -XXX,XX +XXX,XX @@ typedef struct {
24
/* stellaris_input.c */
16
MemoryRegion blockram_m2;
25
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
17
MemoryRegion blockram_m3;
26
18
MemoryRegion sram;
27
-/* blizzard.c */
19
+ /* FPGA APB subsystem */
28
-void *s1d13745_init(qemu_irq gpio_int);
20
MPS2SCC scc;
29
-void s1d13745_write(void *opaque, int dc, uint16_t value);
21
+ /* CMSDK APB subsystem */
30
-void s1d13745_write_block(void *opaque, int dc,
22
CMSDKAPBDualTimer dualtimer;
31
- void *buf, size_t len, int pitch);
23
} MPS2MachineState;
32
-uint16_t s1d13745_read(void *opaque, int dc);
24
25
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
26
g_assert_not_reached();
27
}
28
29
+ /* CMSDK APB subsystem */
30
cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
31
cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK_FRQ);
33
-
32
-
34
/* cbus.c */
33
object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
35
typedef struct {
34
TYPE_CMSDK_APB_DUALTIMER);
36
qemu_irq clk;
35
qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
37
diff --git a/include/hw/display/blizzard.h b/include/hw/display/blizzard.h
36
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
38
new file mode 100644
37
qdev_get_gpio_in(armv7m, 10));
39
index XXXXXXX..XXXXXXX
38
sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000);
40
--- /dev/null
39
41
+++ b/include/hw/display/blizzard.h
40
+ /* FPGA APB subsystem */
42
@@ -XXX,XX +XXX,XX @@
41
object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
43
+/*
42
sccdev = DEVICE(&mms->scc);
44
+ * Epson S1D13744/S1D13745 (Blizzard/Hailstorm/Tornado) LCD/TV controller.
43
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
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
--
44
--
108
2.20.1
45
2.20.1
109
46
110
47
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Suggested-by: Markus Armbruster <armbru@redhat.com>
3
To differenciate with the CMSDK APB peripheral region,
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
rename this region 'CMSDK AHB peripheral region'.
5
Message-id: 20190412165416.7977-3-philmd@redhat.com
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20200617072539.32686-8-f4bug@amsat.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
10
---
9
hw/arm/nseries.c | 3 ++-
11
hw/arm/mps2.c | 3 ++-
10
1 file changed, 2 insertions(+), 1 deletion(-)
12
1 file changed, 2 insertions(+), 1 deletion(-)
11
13
12
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
14
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/nseries.c
16
--- a/hw/arm/mps2.c
15
+++ b/hw/arm/nseries.c
17
+++ b/hw/arm/mps2.c
16
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
17
#include "hw/boards.h"
19
*/
18
#include "hw/i2c/i2c.h"
20
create_unimplemented_device("CMSDK APB peripheral region @0x40000000",
19
#include "hw/devices.h"
21
0x40000000, 0x00010000);
20
+#include "hw/misc/tmp105.h"
22
- create_unimplemented_device("CMSDK peripheral region @0x40010000",
21
#include "hw/block/flash.h"
23
+ create_unimplemented_device("CMSDK AHB peripheral region @0x40010000",
22
#include "hw/hw.h"
24
0x40010000, 0x00010000);
23
#include "hw/bt.h"
25
create_unimplemented_device("Extra peripheral region @0x40020000",
24
@@ -XXX,XX +XXX,XX @@ static void n8x0_i2c_setup(struct n800_s *s)
26
0x40020000, 0x00010000);
25
qemu_register_powerdown_notifier(&n8x0_system_powerdown_notifier);
27
+
26
28
create_unimplemented_device("RESERVED 4", 0x40030000, 0x001D0000);
27
/* Attach a TMP105 PM chip (A0 wired to ground) */
29
create_unimplemented_device("VGA", 0x41000000, 0x0200000);
28
- dev = i2c_create_slave(i2c, "tmp105", N8X0_TMP105_ADDR);
29
+ dev = i2c_create_slave(i2c, TYPE_TMP105, N8X0_TMP105_ADDR);
30
qdev_connect_gpio_out(dev, 0, tmp_irq);
31
}
32
30
33
--
31
--
34
2.20.1
32
2.20.1
35
33
36
34
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
We already model the CMSDK APB watchdog device, let's use it!
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
5
Message-id: 20190412165416.7977-5-philmd@redhat.com
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20200617072539.32686-9-f4bug@amsat.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
include/hw/devices.h | 6 ------
11
hw/arm/mps2.c | 7 +++++++
9
include/hw/display/tc6393xb.h | 24 ++++++++++++++++++++++++
12
hw/arm/Kconfig | 1 +
10
hw/arm/tosa.c | 2 +-
13
2 files changed, 8 insertions(+)
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
14
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
15
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/devices.h
17
--- a/hw/arm/mps2.c
19
+++ b/include/hw/devices.h
18
+++ b/hw/arm/mps2.c
20
@@ -XXX,XX +XXX,XX @@ void *tahvo_init(qemu_irq irq, int betty);
19
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
21
20
sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
22
void retu_key_event(void *retu, int state);
21
qdev_get_gpio_in(armv7m, 10));
23
22
sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000);
24
-/* tc6393xb.c */
23
+ object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
25
-typedef struct TC6393xbState TC6393xbState;
24
+ TYPE_CMSDK_APB_WATCHDOG);
26
-TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
25
+ qdev_prop_set_uint32(DEVICE(&mms->watchdog), "wdogclk-frq", SYSCLK_FRQ);
27
- uint32_t base, qemu_irq irq);
26
+ sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
28
-qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
27
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->watchdog), 0,
29
-
28
+ qdev_get_gpio_in_named(armv7m, "NMI", 0));
30
#endif
29
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->watchdog), 0, 0x40008000);
31
diff --git a/include/hw/display/tc6393xb.h b/include/hw/display/tc6393xb.h
30
32
new file mode 100644
31
/* FPGA APB subsystem */
33
index XXXXXXX..XXXXXXX
32
object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
34
--- /dev/null
33
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
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
34
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/tosa.c
35
--- a/hw/arm/Kconfig
64
+++ b/hw/arm/tosa.c
36
+++ b/hw/arm/Kconfig
65
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@ config MPS2
66
#include "hw/hw.h"
38
select PL080 # DMA controller
67
#include "hw/arm/pxa.h"
39
select SPLIT_IRQ
68
#include "hw/arm/arm.h"
40
select UNIMP
69
-#include "hw/devices.h"
41
+ select CMSDK_APB_WATCHDOG
70
#include "hw/arm/sharpsl.h"
42
71
#include "hw/pcmcia.h"
43
config FSL_IMX7
72
#include "hw/boards.h"
44
bool
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
--
45
--
103
2.20.1
46
2.20.1
104
47
105
48
diff view generated by jsdifflib
1
Normally configure identifies the source path by looking
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
at the location where the configure script itself exists.
3
We also provide a --source-path option which lets the user
4
manually override this.
5
2
6
There isn't really an obvious use case for the --source-path
3
Register the GPIO peripherals as unimplemented to better
7
option, and in commit 927128222b0a91f56c13a in 2017 we
4
follow their accesses, for example booting Zephyr:
8
accidentally added some logic that looks at $source_path
9
before the command line option that overrides it has been
10
processed.
11
5
12
The fact that nobody complained suggests that there isn't
6
----------------
13
any use of this option and we aren't testing it either;
7
IN: arm_mps2_pinmux_init
14
remove it. This allows us to move the "make $source_path
8
0x00001160: f64f 0231 movw r2, #0xf831
15
absolute" logic up so that there is no window in the script
9
0x00001164: 4b06 ldr r3, [pc, #0x18]
16
where $source_path is set but not yet absolute.
10
0x00001166: 2000 movs r0, #0
11
0x00001168: 619a str r2, [r3, #0x18]
12
0x0000116a: f24c 426f movw r2, #0xc46f
13
0x0000116e: f503 5380 add.w r3, r3, #0x1000
14
0x00001172: 619a str r2, [r3, #0x18]
15
0x00001174: f44f 529e mov.w r2, #0x13c0
16
0x00001178: f503 5380 add.w r3, r3, #0x1000
17
0x0000117c: 619a str r2, [r3, #0x18]
18
0x0000117e: 4770 bx lr
19
cmsdk-ahb-gpio: unimplemented device write (size 4, value 0xf831, offset 0x18)
20
cmsdk-ahb-gpio: unimplemented device write (size 4, value 0xc46f, offset 0x18)
21
cmsdk-ahb-gpio: unimplemented device write (size 4, value 0x13c0, offset 0x18)
17
22
23
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
25
Message-id: 20200617072539.32686-10-f4bug@amsat.org
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
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
---
27
---
22
configure | 10 ++--------
28
hw/arm/mps2.c | 8 ++++++--
23
1 file changed, 2 insertions(+), 8 deletions(-)
29
1 file changed, 6 insertions(+), 2 deletions(-)
24
30
25
diff --git a/configure b/configure
31
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
26
index XXXXXXX..XXXXXXX 100755
32
index XXXXXXX..XXXXXXX 100644
27
--- a/configure
33
--- a/hw/arm/mps2.c
28
+++ b/configure
34
+++ b/hw/arm/mps2.c
29
@@ -XXX,XX +XXX,XX @@ ld_has() {
35
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
30
36
MemoryRegion *system_memory = get_system_memory();
31
# default parameters
37
MachineClass *mc = MACHINE_GET_CLASS(machine);
32
source_path=$(dirname "$0")
38
DeviceState *armv7m, *sccdev;
33
+# make source path absolute
39
+ int i;
34
+source_path=$(cd "$source_path"; pwd)
40
35
cpu=""
41
if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
36
iasl="iasl"
42
error_report("This board can only be used with CPU %s",
37
interp_prefix="/usr/gnemul/qemu-%M"
43
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
38
@@ -XXX,XX +XXX,XX @@ for opt do
44
*/
39
;;
45
Object *orgate;
40
--cxx=*) CXX="$optarg"
46
DeviceState *orgate_dev;
41
;;
47
- int i;
42
- --source-path=*) source_path="$optarg"
48
43
- ;;
49
orgate = object_new(TYPE_OR_IRQ);
44
--cpu=*) cpu="$optarg"
50
object_property_set_int(orgate, 6, "num-lines", &error_fatal);
45
;;
51
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
46
--extra-cflags=*) QEMU_CFLAGS="$QEMU_CFLAGS $optarg"
52
*/
47
@@ -XXX,XX +XXX,XX @@ if test "$debug_info" = "yes"; then
53
Object *orgate;
48
LDFLAGS="-g $LDFLAGS"
54
DeviceState *orgate_dev;
49
fi
55
- int i;
50
56
51
-# make source path absolute
57
orgate = object_new(TYPE_OR_IRQ);
52
-source_path=$(cd "$source_path"; pwd)
58
object_property_set_int(orgate, 10, "num-lines", &error_fatal);
53
-
59
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
54
# running configure in the source tree?
60
default:
55
# we know that's the case if configure is there.
61
g_assert_not_reached();
56
if test -f "./configure"; then
62
}
57
@@ -XXX,XX +XXX,XX @@ for opt do
63
+ for (i = 0; i < 4; i++) {
58
;;
64
+ static const hwaddr gpiobase[] = {0x40010000, 0x40011000,
59
--interp-prefix=*) interp_prefix="$optarg"
65
+ 0x40012000, 0x40013000};
60
;;
66
+ create_unimplemented_device("cmsdk-ahb-gpio", gpiobase[i], 0x1000);
61
- --source-path=*)
67
+ }
62
- ;;
68
63
--cross-prefix=*)
69
/* CMSDK APB subsystem */
64
;;
70
cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
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
--
71
--
75
2.20.1
72
2.20.1
76
73
77
74
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
Message-id: 20200617072539.32686-11-f4bug@amsat.org
5
Message-id: 20190412165416.7977-10-philmd@redhat.com
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
include/hw/devices.h | 3 ---
8
hw/arm/mps2.c | 9 +++++++++
9
include/hw/net/lan9118.h | 19 +++++++++++++++++++
9
1 file changed, 9 insertions(+)
10
hw/arm/kzm.c | 2 +-
11
hw/arm/mps2.c | 2 +-
12
hw/arm/realview.c | 1 +
13
hw/arm/vexpress.c | 2 +-
14
hw/net/lan9118.c | 2 +-
15
7 files changed, 24 insertions(+), 7 deletions(-)
16
create mode 100644 include/hw/net/lan9118.h
17
10
18
diff --git a/include/hw/devices.h b/include/hw/devices.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/devices.h
21
+++ b/include/hw/devices.h
22
@@ -XXX,XX +XXX,XX @@
23
/* smc91c111.c */
24
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
25
26
-/* lan9118.c */
27
-void lan9118_init(NICInfo *, uint32_t, qemu_irq);
28
-
29
#endif
30
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
31
new file mode 100644
32
index XXXXXXX..XXXXXXX
33
--- /dev/null
34
+++ b/include/hw/net/lan9118.h
35
@@ -XXX,XX +XXX,XX @@
36
+/*
37
+ * SMSC LAN9118 Ethernet interface emulation
38
+ *
39
+ * Copyright (c) 2009 CodeSourcery, LLC.
40
+ * Written by Paul Brook
41
+ *
42
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
43
+ * See the COPYING file in the top-level directory.
44
+ */
45
+
46
+#ifndef HW_NET_LAN9118_H
47
+#define HW_NET_LAN9118_H
48
+
49
+#include "hw/irq.h"
50
+#include "net/net.h"
51
+
52
+void lan9118_init(NICInfo *, uint32_t, qemu_irq);
53
+
54
+#endif
55
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/kzm.c
58
+++ b/hw/arm/kzm.c
59
@@ -XXX,XX +XXX,XX @@
60
#include "qemu/error-report.h"
61
#include "exec/address-spaces.h"
62
#include "net/net.h"
63
-#include "hw/devices.h"
64
+#include "hw/net/lan9118.h"
65
#include "hw/char/serial.h"
66
#include "sysemu/qtest.h"
67
68
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
11
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
69
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/arm/mps2.c
13
--- a/hw/arm/mps2.c
71
+++ b/hw/arm/mps2.c
14
+++ b/hw/arm/mps2.c
72
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@
73
#include "hw/timer/cmsdk-apb-timer.h"
16
#include "hw/timer/cmsdk-apb-timer.h"
74
#include "hw/timer/cmsdk-apb-dualtimer.h"
17
#include "hw/timer/cmsdk-apb-dualtimer.h"
75
#include "hw/misc/mps2-scc.h"
18
#include "hw/misc/mps2-scc.h"
76
-#include "hw/devices.h"
19
+#include "hw/misc/mps2-fpgaio.h"
77
+#include "hw/net/lan9118.h"
20
#include "hw/net/lan9118.h"
78
#include "net/net.h"
21
#include "net/net.h"
22
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
79
23
80
typedef enum MPS2FPGAType {
24
typedef enum MPS2FPGAType {
81
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
25
FPGA_AN385,
82
index XXXXXXX..XXXXXXX 100644
26
@@ -XXX,XX +XXX,XX @@ typedef struct {
83
--- a/hw/arm/realview.c
27
MemoryRegion sram;
84
+++ b/hw/arm/realview.c
28
/* FPGA APB subsystem */
85
@@ -XXX,XX +XXX,XX @@
29
MPS2SCC scc;
86
#include "hw/arm/arm.h"
30
+ MPS2FPGAIO fpgaio;
87
#include "hw/arm/primecell.h"
31
/* CMSDK APB subsystem */
88
#include "hw/devices.h"
32
CMSDKAPBDualTimer dualtimer;
89
+#include "hw/net/lan9118.h"
33
+ CMSDKAPBWatchdog watchdog;
90
#include "hw/pci/pci.h"
34
} MPS2MachineState;
91
#include "net/net.h"
35
92
#include "sysemu/sysemu.h"
36
#define TYPE_MPS2_MACHINE "mps2"
93
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
37
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
94
index XXXXXXX..XXXXXXX 100644
38
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
95
--- a/hw/arm/vexpress.c
39
sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
96
+++ b/hw/arm/vexpress.c
40
sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
97
@@ -XXX,XX +XXX,XX @@
41
+ object_initialize_child(OBJECT(mms), "fpgaio",
98
#include "hw/sysbus.h"
42
+ &mms->fpgaio, TYPE_MPS2_FPGAIO);
99
#include "hw/arm/arm.h"
43
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "prescale-clk", 25000000);
100
#include "hw/arm/primecell.h"
44
+ sysbus_realize(SYS_BUS_DEVICE(&mms->fpgaio), &error_fatal);
101
-#include "hw/devices.h"
45
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->fpgaio), 0, 0x40028000);
102
+#include "hw/net/lan9118.h"
46
103
#include "hw/i2c/i2c.h"
47
/* In hardware this is a LAN9220; the LAN9118 is software compatible
104
#include "net/net.h"
48
* except that it doesn't support the checksum-offload feature.
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
--
49
--
120
2.20.1
50
2.20.1
121
51
122
52
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
This device is used by both ARM (BCM2836, for raspi2) and AArch64
3
From 'Application Note AN385', chapter 3.9, SPI:
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
The SMM implements five PL022 SPI modules.
8
Message-id: 20190427133028.12874-1-philmd@redhat.com
6
7
Two pairs of modules share the same OR-gated IRQ.
8
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20200617072539.32686-12-f4bug@amsat.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
hw/dma/Makefile.objs | 2 +-
14
hw/arm/mps2.c | 24 ++++++++++++++++++++++++
13
1 file changed, 1 insertion(+), 1 deletion(-)
15
hw/arm/Kconfig | 6 +++---
16
2 files changed, 27 insertions(+), 3 deletions(-)
14
17
15
diff --git a/hw/dma/Makefile.objs b/hw/dma/Makefile.objs
18
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/dma/Makefile.objs
20
--- a/hw/arm/mps2.c
18
+++ b/hw/dma/Makefile.objs
21
+++ b/hw/arm/mps2.c
19
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zdma.o
22
@@ -XXX,XX +XXX,XX @@
20
23
#include "hw/timer/cmsdk-apb-dualtimer.h"
21
obj-$(CONFIG_OMAP) += omap_dma.o soc_dma.o
24
#include "hw/misc/mps2-scc.h"
22
obj-$(CONFIG_PXA2XX) += pxa2xx_dma.o
25
#include "hw/misc/mps2-fpgaio.h"
23
-obj-$(CONFIG_RASPI) += bcm2835_dma.o
26
+#include "hw/ssi/pl022.h"
24
+common-obj-$(CONFIG_RASPI) += bcm2835_dma.o
27
#include "hw/net/lan9118.h"
28
#include "net/net.h"
29
#include "hw/watchdog/cmsdk-apb-watchdog.h"
30
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
31
qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "prescale-clk", 25000000);
32
sysbus_realize(SYS_BUS_DEVICE(&mms->fpgaio), &error_fatal);
33
sysbus_mmio_map(SYS_BUS_DEVICE(&mms->fpgaio), 0, 0x40028000);
34
+ sysbus_create_simple(TYPE_PL022, 0x40025000, /* External ADC */
35
+ qdev_get_gpio_in(armv7m, 22));
36
+ for (i = 0; i < 2; i++) {
37
+ static const int spi_irqno[] = {11, 24};
38
+ static const hwaddr spibase[] = {0x40020000, /* APB */
39
+ 0x40021000, /* LCD */
40
+ 0x40026000, /* Shield0 */
41
+ 0x40027000}; /* Shield1 */
42
+ DeviceState *orgate_dev;
43
+ Object *orgate;
44
+ int j;
45
+
46
+ orgate = object_new(TYPE_OR_IRQ);
47
+ object_property_set_int(orgate, 2, "num-lines", &error_fatal);
48
+ orgate_dev = DEVICE(orgate);
49
+ qdev_realize(orgate_dev, NULL, &error_fatal);
50
+ qdev_connect_gpio_out(orgate_dev, 0,
51
+ qdev_get_gpio_in(armv7m, spi_irqno[i]));
52
+ for (j = 0; j < 2; j++) {
53
+ sysbus_create_simple(TYPE_PL022, spibase[2 * i + j],
54
+ qdev_get_gpio_in(orgate_dev, j));
55
+ }
56
+ }
57
58
/* In hardware this is a LAN9220; the LAN9118 is software compatible
59
* except that it doesn't support the checksum-offload feature.
60
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
61
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/arm/Kconfig
63
+++ b/hw/arm/Kconfig
64
@@ -XXX,XX +XXX,XX @@ config HIGHBANK
65
select ARM_TIMER # sp804
66
select ARM_V7M
67
select PL011 # UART
68
- select PL022 # Serial port
69
+ select PL022 # SPI
70
select PL031 # RTC
71
select PL061 # GPIO
72
select PL310 # cache controller
73
@@ -XXX,XX +XXX,XX @@ config STELLARIS
74
select CMSDK_APB_WATCHDOG
75
select I2C
76
select PL011 # UART
77
- select PL022 # Serial port
78
+ select PL022 # SPI
79
select PL061 # GPIO
80
select SSD0303 # OLED display
81
select SSD0323 # OLED display
82
@@ -XXX,XX +XXX,XX @@ config MPS2
83
select MPS2_FPGAIO
84
select MPS2_SCC
85
select OR_IRQ
86
- select PL022 # Serial port
87
+ select PL022 # SPI
88
select PL080 # DMA controller
89
select SPLIT_IRQ
90
select UNIMP
25
--
91
--
26
2.20.1
92
2.20.1
27
93
28
94
diff view generated by jsdifflib
1
Currently the code in v7m_push_stack() which detects a violation
1
From: Philippe Mathieu-Daudé <f4bug@amsat.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
From 'Application Note AN385', chapter 3.14:
4
5
The SMM implements a simple SBCon interface based on I2C.
6
7
There are 4 SBCon interfaces on the FPGA APB subsystem.
8
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20200617072539.32686-13-f4bug@amsat.org
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
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
---
13
---
14
target/arm/helper.c | 23 ++++++++++++++++++-----
14
hw/arm/mps2.c | 8 ++++++++
15
1 file changed, 18 insertions(+), 5 deletions(-)
15
hw/arm/Kconfig | 1 +
16
2 files changed, 9 insertions(+)
16
17
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
20
--- a/hw/arm/mps2.c
20
+++ b/target/arm/helper.c
21
+++ b/hw/arm/mps2.c
21
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
22
@@ -XXX,XX +XXX,XX @@
22
* should ignore further stack faults trying to process
23
#include "hw/misc/mps2-scc.h"
23
* that derived exception.)
24
#include "hw/misc/mps2-fpgaio.h"
24
*/
25
#include "hw/ssi/pl022.h"
25
- bool stacked_ok;
26
+#include "hw/i2c/arm_sbcon_i2c.h"
26
+ bool stacked_ok = true, limitviol = false;
27
#include "hw/net/lan9118.h"
27
CPUARMState *env = &cpu->env;
28
#include "net/net.h"
28
uint32_t xpsr = xpsr_read(env);
29
#include "hw/watchdog/cmsdk-apb-watchdog.h"
29
uint32_t frameptr = env->regs[13];
30
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
30
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
31
qdev_get_gpio_in(orgate_dev, j));
31
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
32
env->v7m.secure);
33
env->regs[13] = limit;
34
- return true;
35
+ /*
36
+ * We won't try to perform any further memory accesses but
37
+ * we must continue through the following code to check for
38
+ * permission faults during FPU state preservation, and we
39
+ * must update FPCCR if lazy stacking is enabled.
40
+ */
41
+ limitviol = true;
42
+ stacked_ok = false;
43
}
32
}
44
}
33
}
45
34
+ for (i = 0; i < 4; i++) {
46
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
35
+ static const hwaddr i2cbase[] = {0x40022000, /* Touch */
47
* (which may be taken in preference to the one we started with
36
+ 0x40023000, /* Audio */
48
* if it has higher priority).
37
+ 0x40029000, /* Shield0 */
49
*/
38
+ 0x4002a000}; /* Shield1 */
50
- stacked_ok =
39
+ sysbus_create_simple(TYPE_ARM_SBCON_I2C, i2cbase[i], NULL);
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
+ }
40
+ }
69
41
70
return !stacked_ok;
42
/* In hardware this is a LAN9220; the LAN9118 is software compatible
71
}
43
* except that it doesn't support the checksum-offload feature.
44
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/arm/Kconfig
47
+++ b/hw/arm/Kconfig
48
@@ -XXX,XX +XXX,XX @@ config MPS2
49
select SPLIT_IRQ
50
select UNIMP
51
select CMSDK_APB_WATCHDOG
52
+ select VERSATILE_I2C
53
54
config FSL_IMX7
55
bool
72
--
56
--
73
2.20.1
57
2.20.1
74
58
75
59
diff view generated by jsdifflib
1
If the floating point extension is present, then the SG instruction
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
must clear the CONTROL_S.SFPA bit. Implement this.
3
2
4
(On a no-FPU system the bit will always be zero, so we don't need
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
to make the clearing of the bit conditional on ARM_FEATURE_VFP.)
4
Message-id: 20200617072539.32686-14-f4bug@amsat.org
6
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-8-peter.maydell@linaro.org
10
---
7
---
11
target/arm/helper.c | 1 +
8
hw/arm/mps2.c | 1 +
12
1 file changed, 1 insertion(+)
9
1 file changed, 1 insertion(+)
13
10
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
11
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
15
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
13
--- a/hw/arm/mps2.c
17
+++ b/target/arm/helper.c
14
+++ b/hw/arm/mps2.c
18
@@ -XXX,XX +XXX,XX @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
15
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
19
qemu_log_mask(CPU_LOG_INT, "...really an SG instruction at 0x%08" PRIx32
16
0x4002a000}; /* Shield1 */
20
", executing it\n", env->regs[15]);
17
sysbus_create_simple(TYPE_ARM_SBCON_I2C, i2cbase[i], NULL);
21
env->regs[14] &= ~1;
18
}
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
19
+ create_unimplemented_device("i2s", 0x40024000, 0x400);
23
switch_v7m_security_state(env, true);
20
24
xpsr_write(env, 0, XPSR_IT);
21
/* In hardware this is a LAN9220; the LAN9118 is software compatible
25
env->regs[15] += 4;
22
* except that it doesn't support the checksum-offload feature.
26
--
23
--
27
2.20.1
24
2.20.1
28
25
29
26
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
From 'Application Note AN521', chapter 4.7:
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
5
Message-id: 20190412165416.7977-12-philmd@redhat.com
5
The SMM implements four SBCon serial modules:
6
7
One SBCon module for use by the Color LCD touch interface.
8
One SBCon module to configure the audio controller.
9
Two general purpose SBCon modules, that connect to the
10
Expansion headers J7 and J8, are intended for use with the
11
V2C-Shield1 which provide an I2C interface on the headers.
12
13
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20200617072539.32686-15-f4bug@amsat.org
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
17
---
8
include/hw/net/lan9118.h | 2 ++
18
hw/arm/mps2-tz.c | 23 ++++++++++++++++++-----
9
hw/arm/exynos4_boards.c | 3 ++-
19
1 file changed, 18 insertions(+), 5 deletions(-)
10
hw/arm/mps2-tz.c | 3 ++-
11
hw/net/lan9118.c | 1 -
12
4 files changed, 6 insertions(+), 3 deletions(-)
13
20
14
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/net/lan9118.h
17
+++ b/include/hw/net/lan9118.h
18
@@ -XXX,XX +XXX,XX @@
19
#include "hw/irq.h"
20
#include "net/net.h"
21
22
+#define TYPE_LAN9118 "lan9118"
23
+
24
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
25
26
#endif
27
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/exynos4_boards.c
30
+++ b/hw/arm/exynos4_boards.c
31
@@ -XXX,XX +XXX,XX @@
32
#include "hw/arm/arm.h"
33
#include "exec/address-spaces.h"
34
#include "hw/arm/exynos4210.h"
35
+#include "hw/net/lan9118.h"
36
#include "hw/boards.h"
37
38
#undef DEBUG
39
@@ -XXX,XX +XXX,XX @@ static void lan9215_init(uint32_t base, qemu_irq irq)
40
/* This should be a 9215 but the 9118 is close enough */
41
if (nd_table[0].used) {
42
qemu_check_nic_model(&nd_table[0], "lan9118");
43
- dev = qdev_create(NULL, "lan9118");
44
+ dev = qdev_create(NULL, TYPE_LAN9118);
45
qdev_set_nic_properties(dev, &nd_table[0]);
46
qdev_prop_set_uint32(dev, "mode_16bit", 1);
47
qdev_init_nofail(dev);
48
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
21
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
49
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/arm/mps2-tz.c
23
--- a/hw/arm/mps2-tz.c
51
+++ b/hw/arm/mps2-tz.c
24
+++ b/hw/arm/mps2-tz.c
52
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@
53
#include "hw/arm/armsse.h"
26
#include "hw/arm/armsse.h"
54
#include "hw/dma/pl080.h"
27
#include "hw/dma/pl080.h"
55
#include "hw/ssi/pl022.h"
28
#include "hw/ssi/pl022.h"
56
+#include "hw/net/lan9118.h"
29
+#include "hw/i2c/arm_sbcon_i2c.h"
30
#include "hw/net/lan9118.h"
57
#include "net/net.h"
31
#include "net/net.h"
58
#include "hw/core/split-irq.h"
32
#include "hw/core/split-irq.h"
59
33
@@ -XXX,XX +XXX,XX @@ typedef struct {
60
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
34
TZPPC ppc[5];
61
* except that it doesn't support the checksum-offload feature.
35
TZMPC ssram_mpc[3];
62
*/
36
PL022State spi[5];
63
qemu_check_nic_model(nd, "lan9118");
37
- UnimplementedDeviceState i2c[4];
64
- mms->lan9118 = qdev_create(NULL, "lan9118");
38
+ ArmSbconI2CState i2c[4];
65
+ mms->lan9118 = qdev_create(NULL, TYPE_LAN9118);
39
UnimplementedDeviceState i2s_audio;
66
qdev_set_nic_properties(mms->lan9118, nd);
40
UnimplementedDeviceState gpio[4];
67
qdev_init_nofail(mms->lan9118);
41
UnimplementedDeviceState gfx;
68
42
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
69
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
43
return sysbus_mmio_get_region(s, 0);
70
index XXXXXXX..XXXXXXX 100644
44
}
71
--- a/hw/net/lan9118.c
45
72
+++ b/hw/net/lan9118.c
46
+static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
73
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118_packet = {
47
+ const char *name, hwaddr size)
74
}
48
+{
75
};
49
+ ArmSbconI2CState *i2c = opaque;
76
50
+ SysBusDevice *s;
77
-#define TYPE_LAN9118 "lan9118"
51
+
78
#define LAN9118(obj) OBJECT_CHECK(lan9118_state, (obj), TYPE_LAN9118)
52
+ object_initialize_child(OBJECT(mms), name, i2c, TYPE_ARM_SBCON_I2C);
79
53
+ s = SYS_BUS_DEVICE(i2c);
80
typedef struct {
54
+ sysbus_realize(s, &error_fatal);
55
+ return sysbus_mmio_get_region(s, 0);
56
+}
57
+
58
static void mps2tz_common_init(MachineState *machine)
59
{
60
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
61
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
62
{ "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000 },
63
{ "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000 },
64
{ "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000 },
65
- { "i2c0", make_unimp_dev, &mms->i2c[0], 0x40207000, 0x1000 },
66
- { "i2c1", make_unimp_dev, &mms->i2c[1], 0x40208000, 0x1000 },
67
- { "i2c2", make_unimp_dev, &mms->i2c[2], 0x4020c000, 0x1000 },
68
- { "i2c3", make_unimp_dev, &mms->i2c[3], 0x4020d000, 0x1000 },
69
+ { "i2c0", make_i2c, &mms->i2c[0], 0x40207000, 0x1000 },
70
+ { "i2c1", make_i2c, &mms->i2c[1], 0x40208000, 0x1000 },
71
+ { "i2c2", make_i2c, &mms->i2c[2], 0x4020c000, 0x1000 },
72
+ { "i2c3", make_i2c, &mms->i2c[3], 0x4020d000, 0x1000 },
73
},
74
}, {
75
.name = "apb_ppcexp2",
81
--
76
--
82
2.20.1
77
2.20.1
83
78
84
79
diff view generated by jsdifflib
1
The M-profile floating point support has three associated config
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
registers: FPCAR, FPCCR and FPDSCR. It also makes the registers
2
3
CPACR and NSACR have behaviour other than reads-as-zero.
3
Since commit d70c996df23f, when enabling the PMU we get:
4
Add support for all of these as simple reads-as-written registers.
4
5
We will hook up actual functionality later.
5
$ qemu-system-aarch64 -cpu host,pmu=on -M virt,accel=kvm,gic-version=3
6
6
Segmentation fault (core dumped)
7
The main complexity here is handling the FPCCR register, which
7
8
has a mix of banked and unbanked bits.
8
Thread 1 "qemu-system-aar" received signal SIGSEGV, Segmentation fault.
9
9
0x0000aaaaaae356d0 in kvm_ioctl (s=0x0, type=44547) at accel/kvm/kvm-all.c:2588
10
Note that we don't share storage with the A-profile
10
2588 ret = ioctl(s->fd, type, arg);
11
cpu->cp15.nsacr and cpu->cp15.cpacr_el1, though the behaviour
11
(gdb) bt
12
is quite similar, for two reasons:
12
#0 0x0000aaaaaae356d0 in kvm_ioctl (s=0x0, type=44547) at accel/kvm/kvm-all.c:2588
13
* the M profile CPACR is banked between security states
13
#1 0x0000aaaaaae31568 in kvm_check_extension (s=0x0, extension=126) at accel/kvm/kvm-all.c:916
14
* it preserves the invariant that M profile uses no state
14
#2 0x0000aaaaaafce254 in kvm_arm_pmu_supported (cpu=0xaaaaac214ab0) at target/arm/kvm.c:213
15
inside the cp15 substruct
15
#3 0x0000aaaaaafc0f94 in arm_set_pmu (obj=0xaaaaac214ab0, value=true, errp=0xffffffffe438) at target/arm/cpu.c:1111
16
16
#4 0x0000aaaaab5533ac in property_set_bool (obj=0xaaaaac214ab0, v=0xaaaaac223a80, name=0xaaaaac11a970 "pmu", opaque=0xaaaaac222730, errp=0xffffffffe438) at qom/object.c:2170
17
#5 0x0000aaaaab5512f0 in object_property_set (obj=0xaaaaac214ab0, v=0xaaaaac223a80, name=0xaaaaac11a970 "pmu", errp=0xffffffffe438) at qom/object.c:1328
18
#6 0x0000aaaaab551e10 in object_property_parse (obj=0xaaaaac214ab0, string=0xaaaaac11b4c0 "on", name=0xaaaaac11a970 "pmu", errp=0xffffffffe438) at qom/object.c:1561
19
#7 0x0000aaaaab54ee8c in object_apply_global_props (obj=0xaaaaac214ab0, props=0xaaaaac018e20, errp=0xaaaaabd6fd88 <error_fatal>) at qom/object.c:407
20
#8 0x0000aaaaab1dd5a4 in qdev_prop_set_globals (dev=0xaaaaac214ab0) at hw/core/qdev-properties.c:1218
21
#9 0x0000aaaaab1d9fac in device_post_init (obj=0xaaaaac214ab0) at hw/core/qdev.c:1050
22
...
23
#15 0x0000aaaaab54f310 in object_initialize_with_type (obj=0xaaaaac214ab0, size=52208, type=0xaaaaabe237f0) at qom/object.c:512
24
#16 0x0000aaaaab54fa24 in object_new_with_type (type=0xaaaaabe237f0) at qom/object.c:687
25
#17 0x0000aaaaab54fa80 in object_new (typename=0xaaaaabe23970 "host-arm-cpu") at qom/object.c:702
26
#18 0x0000aaaaaaf04a74 in machvirt_init (machine=0xaaaaac0a8550) at hw/arm/virt.c:1770
27
#19 0x0000aaaaab1e8720 in machine_run_board_init (machine=0xaaaaac0a8550) at hw/core/machine.c:1138
28
#20 0x0000aaaaaaf95394 in qemu_init (argc=5, argv=0xffffffffea58, envp=0xffffffffea88) at softmmu/vl.c:4348
29
#21 0x0000aaaaaada3f74 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at softmmu/main.c:48
30
31
This is because in frame #2, cpu->kvm_state is still NULL
32
(the vCPU is not yet realized).
33
34
KVM has a hard requirement of all cores supporting the same
35
feature set. We only need to check if the accelerator supports
36
a feature, not each vCPU individually.
37
38
Fix by removing the 'CPUState *cpu' argument from the
39
kvm_arm_<FEATURE>_supported() functions.
40
41
Fixes: d70c996df23f ('Use CPUState::kvm_state in kvm_arm_pmu_supported')
42
Reported-by: Haibo Xu <haibo.xu@linaro.org>
43
Reviewed-by: Andrew Jones <drjones@redhat.com>
44
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
45
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
46
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
47
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
48
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
---
49
---
21
target/arm/cpu.h | 34 ++++++++++++
50
target/arm/kvm_arm.h | 21 +++++++++------------
22
hw/intc/armv7m_nvic.c | 125 ++++++++++++++++++++++++++++++++++++++++++
51
target/arm/cpu.c | 2 +-
23
target/arm/cpu.c | 5 ++
52
target/arm/cpu64.c | 10 +++++-----
24
target/arm/machine.c | 16 ++++++
53
target/arm/kvm.c | 4 ++--
25
4 files changed, 180 insertions(+)
54
target/arm/kvm64.c | 14 +++++---------
26
55
5 files changed, 22 insertions(+), 29 deletions(-)
27
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
56
28
index XXXXXXX..XXXXXXX 100644
57
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
29
--- a/target/arm/cpu.h
58
index XXXXXXX..XXXXXXX 100644
30
+++ b/target/arm/cpu.h
59
--- a/target/arm/kvm_arm.h
31
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
60
+++ b/target/arm/kvm_arm.h
32
uint32_t scr[M_REG_NUM_BANKS];
61
@@ -XXX,XX +XXX,XX @@ void kvm_arm_add_vcpu_properties(Object *obj);
33
uint32_t msplim[M_REG_NUM_BANKS];
62
34
uint32_t psplim[M_REG_NUM_BANKS];
63
/**
35
+ uint32_t fpcar[M_REG_NUM_BANKS];
64
* kvm_arm_aarch32_supported:
36
+ uint32_t fpccr[M_REG_NUM_BANKS];
65
- * @cs: CPUState
37
+ uint32_t fpdscr[M_REG_NUM_BANKS];
66
*
38
+ uint32_t cpacr[M_REG_NUM_BANKS];
67
- * Returns: true if the KVM VCPU can enable AArch32 mode
39
+ uint32_t nsacr;
68
+ * Returns: true if KVM can enable AArch32 mode
40
} v7m;
69
* and false otherwise.
41
42
/* Information associated with an exception about to be taken:
43
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_CSSELR, LEVEL, 1, 3)
44
*/
70
*/
45
FIELD(V7M_CSSELR, INDEX, 0, 4)
71
-bool kvm_arm_aarch32_supported(CPUState *cs);
46
72
+bool kvm_arm_aarch32_supported(void);
47
+/* v7M FPCCR bits */
73
48
+FIELD(V7M_FPCCR, LSPACT, 0, 1)
74
/**
49
+FIELD(V7M_FPCCR, USER, 1, 1)
75
* kvm_arm_pmu_supported:
50
+FIELD(V7M_FPCCR, S, 2, 1)
76
- * @cs: CPUState
51
+FIELD(V7M_FPCCR, THREAD, 3, 1)
77
*
52
+FIELD(V7M_FPCCR, HFRDY, 4, 1)
78
- * Returns: true if the KVM VCPU can enable its PMU
53
+FIELD(V7M_FPCCR, MMRDY, 5, 1)
79
+ * Returns: true if KVM can enable the PMU
54
+FIELD(V7M_FPCCR, BFRDY, 6, 1)
80
* and false otherwise.
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
*/
81
*/
79
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
82
-bool kvm_arm_pmu_supported(CPUState *cs);
80
index XXXXXXX..XXXXXXX 100644
83
+bool kvm_arm_pmu_supported(void);
81
--- a/hw/intc/armv7m_nvic.c
84
82
+++ b/hw/intc/armv7m_nvic.c
85
/**
83
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
86
* kvm_arm_sve_supported:
84
}
87
- * @cs: CPUState
85
case 0xd84: /* CSSELR */
88
*
86
return cpu->env.v7m.csselr[attrs.secure];
89
- * Returns true if the KVM VCPU can enable SVE and false otherwise.
87
+ case 0xd88: /* CPACR */
90
+ * Returns true if KVM can enable SVE and false otherwise.
88
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
91
*/
89
+ return 0;
92
-bool kvm_arm_sve_supported(CPUState *cs);
90
+ }
93
+bool kvm_arm_sve_supported(void);
91
+ return cpu->env.v7m.cpacr[attrs.secure];
94
92
+ case 0xd8c: /* NSACR */
95
/**
93
+ if (!attrs.secure || !arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
96
* kvm_arm_get_max_vm_ipa_size:
94
+ return 0;
97
@@ -XXX,XX +XXX,XX @@ static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
95
+ }
98
96
+ return cpu->env.v7m.nsacr;
99
static inline void kvm_arm_add_vcpu_properties(Object *obj) {}
97
/* TODO: Implement debug registers. */
100
98
case 0xd90: /* MPU_TYPE */
101
-static inline bool kvm_arm_aarch32_supported(CPUState *cs)
99
/* Unified MPU; if the MPU is not present this value is zero */
102
+static inline bool kvm_arm_aarch32_supported(void)
100
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
103
{
101
return 0;
104
return false;
102
}
105
}
103
return cpu->env.v7m.sfar;
106
104
+ case 0xf34: /* FPCCR */
107
-static inline bool kvm_arm_pmu_supported(CPUState *cs)
105
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
108
+static inline bool kvm_arm_pmu_supported(void)
106
+ return 0;
109
{
107
+ }
110
return false;
108
+ if (attrs.secure) {
111
}
109
+ return cpu->env.v7m.fpccr[M_REG_S];
112
110
+ } else {
113
-static inline bool kvm_arm_sve_supported(CPUState *cs)
111
+ /*
114
+static inline bool kvm_arm_sve_supported(void)
112
+ * NS can read LSPEN, CLRONRET and MONRDY. It can read
115
{
113
+ * BFRDY and HFRDY if AIRCR.BFHFNMINS != 0;
116
return false;
114
+ * other non-banked bits RAZ.
117
}
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
118
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
237
index XXXXXXX..XXXXXXX 100644
119
index XXXXXXX..XXXXXXX 100644
238
--- a/target/arm/cpu.c
120
--- a/target/arm/cpu.c
239
+++ b/target/arm/cpu.c
121
+++ b/target/arm/cpu.c
240
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
122
@@ -XXX,XX +XXX,XX @@ static void arm_set_pmu(Object *obj, bool value, Error **errp)
241
env->v7m.ccr[M_REG_S] |= R_V7M_CCR_UNALIGN_TRP_MASK;
123
ARMCPU *cpu = ARM_CPU(obj);
124
125
if (value) {
126
- if (kvm_enabled() && !kvm_arm_pmu_supported(CPU(cpu))) {
127
+ if (kvm_enabled() && !kvm_arm_pmu_supported()) {
128
error_setg(errp, "'pmu' feature not supported by KVM on this host");
129
return;
242
}
130
}
243
131
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
244
+ if (arm_feature(env, ARM_FEATURE_VFP)) {
132
index XXXXXXX..XXXXXXX 100644
245
+ env->v7m.fpccr[M_REG_NS] = R_V7M_FPCCR_ASPEN_MASK;
133
--- a/target/arm/cpu64.c
246
+ env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK |
134
+++ b/target/arm/cpu64.c
247
+ R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK;
135
@@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
248
+ }
136
249
/* Unlike A/R profile, M profile defines the reset LR value */
137
/* Collect the set of vector lengths supported by KVM. */
250
env->regs[14] = 0xffffffff;
138
bitmap_zero(kvm_supported, ARM_MAX_VQ);
251
139
- if (kvm_enabled() && kvm_arm_sve_supported(CPU(cpu))) {
252
diff --git a/target/arm/machine.c b/target/arm/machine.c
140
+ if (kvm_enabled() && kvm_arm_sve_supported()) {
253
index XXXXXXX..XXXXXXX 100644
141
kvm_arm_sve_get_vls(CPU(cpu), kvm_supported);
254
--- a/target/arm/machine.c
142
} else if (kvm_enabled()) {
255
+++ b/target/arm/machine.c
143
assert(!cpu_isar_feature(aa64_sve, cpu));
256
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_v8m = {
144
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
257
}
145
return;
258
};
146
}
259
147
260
+static const VMStateDescription vmstate_m_fp = {
148
- if (kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
261
+ .name = "cpu/m/fp",
149
+ if (kvm_enabled() && !kvm_arm_sve_supported()) {
262
+ .version_id = 1,
150
error_setg(errp, "cannot set sve-max-vq");
263
+ .minimum_version_id = 1,
151
error_append_hint(errp, "SVE not supported by KVM on this host\n");
264
+ .needed = vfp_needed,
152
return;
265
+ .fields = (VMStateField[]) {
153
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve_vq(Object *obj, Visitor *v, const char *name,
266
+ VMSTATE_UINT32_ARRAY(env.v7m.fpcar, ARMCPU, M_REG_NUM_BANKS),
154
return;
267
+ VMSTATE_UINT32_ARRAY(env.v7m.fpccr, ARMCPU, M_REG_NUM_BANKS),
155
}
268
+ VMSTATE_UINT32_ARRAY(env.v7m.fpdscr, ARMCPU, M_REG_NUM_BANKS),
156
269
+ VMSTATE_UINT32_ARRAY(env.v7m.cpacr, ARMCPU, M_REG_NUM_BANKS),
157
- if (value && kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
270
+ VMSTATE_UINT32(env.v7m.nsacr, ARMCPU),
158
+ if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
271
+ VMSTATE_END_OF_LIST()
159
error_setg(errp, "cannot enable %s", name);
272
+ }
160
error_append_hint(errp, "SVE not supported by KVM on this host\n");
273
+};
161
return;
274
+
162
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve(Object *obj, Visitor *v, const char *name,
275
static const VMStateDescription vmstate_m = {
163
return;
276
.name = "cpu/m",
164
}
277
.version_id = 4,
165
278
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
166
- if (value && kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
279
&vmstate_m_scr,
167
+ if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
280
&vmstate_m_other_sp,
168
error_setg(errp, "'sve' feature not supported by KVM on this host");
281
&vmstate_m_v8m,
169
return;
282
+ &vmstate_m_fp,
170
}
283
NULL
171
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_set_aarch64(Object *obj, bool value, Error **errp)
284
}
172
* uniform execution state like do_interrupt.
285
};
173
*/
174
if (value == false) {
175
- if (!kvm_enabled() || !kvm_arm_aarch32_supported(CPU(cpu))) {
176
+ if (!kvm_enabled() || !kvm_arm_aarch32_supported()) {
177
error_setg(errp, "'aarch64' feature cannot be disabled "
178
"unless KVM is enabled and 32-bit EL1 "
179
"is supported");
180
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
181
index XXXXXXX..XXXXXXX 100644
182
--- a/target/arm/kvm.c
183
+++ b/target/arm/kvm.c
184
@@ -XXX,XX +XXX,XX @@ void kvm_arm_add_vcpu_properties(Object *obj)
185
}
186
}
187
188
-bool kvm_arm_pmu_supported(CPUState *cpu)
189
+bool kvm_arm_pmu_supported(void)
190
{
191
- return kvm_check_extension(cpu->kvm_state, KVM_CAP_ARM_PMU_V3);
192
+ return kvm_check_extension(kvm_state, KVM_CAP_ARM_PMU_V3);
193
}
194
195
int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
196
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
197
index XXXXXXX..XXXXXXX 100644
198
--- a/target/arm/kvm64.c
199
+++ b/target/arm/kvm64.c
200
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
201
return true;
202
}
203
204
-bool kvm_arm_aarch32_supported(CPUState *cpu)
205
+bool kvm_arm_aarch32_supported(void)
206
{
207
- KVMState *s = KVM_STATE(current_accel());
208
-
209
- return kvm_check_extension(s, KVM_CAP_ARM_EL1_32BIT);
210
+ return kvm_check_extension(kvm_state, KVM_CAP_ARM_EL1_32BIT);
211
}
212
213
-bool kvm_arm_sve_supported(CPUState *cpu)
214
+bool kvm_arm_sve_supported(void)
215
{
216
- KVMState *s = KVM_STATE(current_accel());
217
-
218
- return kvm_check_extension(s, KVM_CAP_ARM_SVE);
219
+ return kvm_check_extension(kvm_state, KVM_CAP_ARM_SVE);
220
}
221
222
QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1);
223
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
224
env->features &= ~(1ULL << ARM_FEATURE_PMU);
225
}
226
if (cpu_isar_feature(aa64_sve, cpu)) {
227
- assert(kvm_arm_sve_supported(cs));
228
+ assert(kvm_arm_sve_supported());
229
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_SVE;
230
}
231
286
--
232
--
287
2.20.1
233
2.20.1
288
234
289
235
diff view generated by jsdifflib
1
The M-profile CONTROL register has two bits -- SFPA and FPCA --
1
From: Andrew Jones <drjones@redhat.com>
2
which relate to floating-point support, and should be RES0 otherwise.
3
Handle them correctly in the MSR/MRS register access code.
4
Neither is banked between security states, so they are stored
5
in v7m.control[M_REG_S] regardless of current security state.
6
2
3
Some cpu features may be enabled and disabled for all configurations
4
that support the feature. Let's test that.
5
6
A recent regression[*] inspired adding these tests.
7
8
[*] '-cpu host,pmu=on' caused a segfault
9
10
Signed-off-by: Andrew Jones <drjones@redhat.com>
11
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Message-id: 20200623090622.30365-2-philmd@redhat.com
13
Message-Id: <20200623082310.17577-1-drjones@redhat.com>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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-9-peter.maydell@linaro.org
10
---
16
---
11
target/arm/helper.c | 57 ++++++++++++++++++++++++++++++++++++++-------
17
tests/qtest/arm-cpu-features.c | 38 ++++++++++++++++++++++++++++++----
12
1 file changed, 49 insertions(+), 8 deletions(-)
18
1 file changed, 34 insertions(+), 4 deletions(-)
13
19
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
22
--- a/tests/qtest/arm-cpu-features.c
17
+++ b/target/arm/helper.c
23
+++ b/tests/qtest/arm-cpu-features.c
18
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
24
@@ -XXX,XX +XXX,XX @@ static bool resp_get_feature(QDict *resp, const char *feature)
19
return xpsr_read(env) & mask;
25
qobject_unref(_resp); \
20
break;
26
})
21
case 20: /* CONTROL */
27
22
- return env->v7m.control[env->v7m.secure];
28
-#define assert_feature(qts, cpu_type, feature, expected_value) \
23
+ {
29
+#define resp_assert_feature(resp, feature, expected_value) \
24
+ uint32_t value = env->v7m.control[env->v7m.secure];
30
({ \
25
+ if (!env->v7m.secure) {
31
- QDict *_resp, *_props; \
26
+ /* SFPA is RAZ/WI from NS; FPCA is stored in the M_REG_S bank */
32
+ QDict *_props; \
27
+ value |= env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK;
33
\
28
+ }
34
- _resp = do_query_no_props(qts, cpu_type); \
29
+ return value;
35
g_assert(_resp); \
30
+ }
36
g_assert(resp_has_props(_resp)); \
31
case 0x94: /* CONTROL_NS */
37
_props = resp_get_props(_resp); \
32
/* We have to handle this here because unprivileged Secure code
38
g_assert(qdict_get(_props, feature)); \
33
* can read the NS CONTROL register.
39
g_assert(qdict_get_bool(_props, feature) == (expected_value)); \
34
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
40
+})
35
if (!env->v7m.secure) {
41
+
36
return 0;
42
+#define assert_feature(qts, cpu_type, feature, expected_value) \
37
}
43
+({ \
38
- return env->v7m.control[M_REG_NS];
44
+ QDict *_resp; \
39
+ return env->v7m.control[M_REG_NS] |
45
+ \
40
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK);
46
+ _resp = do_query_no_props(qts, cpu_type); \
41
}
47
+ g_assert(_resp); \
42
48
+ resp_assert_feature(_resp, feature, expected_value); \
43
if (el == 0) {
49
+ qobject_unref(_resp); \
44
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
50
+})
45
*/
51
+
46
uint32_t mask = extract32(maskreg, 8, 4);
52
+#define assert_set_feature(qts, cpu_type, feature, value) \
47
uint32_t reg = extract32(maskreg, 0, 8);
53
+({ \
48
+ int cur_el = arm_current_el(env);
54
+ const char *_fmt = (value) ? "{ %s: true }" : "{ %s: false }"; \
49
55
+ QDict *_resp; \
50
- if (arm_current_el(env) == 0 && reg > 7) {
56
+ \
51
- /* only xPSR sub-fields may be written by unprivileged */
57
+ _resp = do_query(qts, cpu_type, _fmt, feature); \
52
+ if (cur_el == 0 && reg > 7 && reg != 20) {
58
+ g_assert(_resp); \
53
+ /*
59
+ resp_assert_feature(_resp, feature, value); \
54
+ * only xPSR sub-fields and CONTROL.SFPA may be written by
60
qobject_unref(_resp); \
55
+ * unprivileged code
61
})
56
+ */
62
63
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion(const void *data)
64
assert_error(qts, "host", "The CPU type 'host' requires KVM", NULL);
65
66
/* Test expected feature presence/absence for some cpu types */
67
- assert_has_feature_enabled(qts, "max", "pmu");
68
assert_has_feature_enabled(qts, "cortex-a15", "pmu");
69
assert_has_not_feature(qts, "cortex-a15", "aarch64");
70
71
+ /* Enabling and disabling pmu should always work. */
72
+ assert_has_feature_enabled(qts, "max", "pmu");
73
+ assert_set_feature(qts, "max", "pmu", false);
74
+ assert_set_feature(qts, "max", "pmu", true);
75
+
76
assert_has_not_feature(qts, "max", "kvm-no-adjvtime");
77
78
if (g_str_equal(qtest_get_arch(), "aarch64")) {
79
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
57
return;
80
return;
58
}
81
}
59
82
60
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
83
+ /* Enabling and disabling kvm-no-adjvtime should always work. */
61
env->v7m.control[M_REG_NS] &= ~R_V7M_CONTROL_NPRIV_MASK;
84
assert_has_feature_disabled(qts, "host", "kvm-no-adjvtime");
62
env->v7m.control[M_REG_NS] |= val & R_V7M_CONTROL_NPRIV_MASK;
85
+ assert_set_feature(qts, "host", "kvm-no-adjvtime", true);
63
}
86
+ assert_set_feature(qts, "host", "kvm-no-adjvtime", false);
64
+ /*
87
65
+ * SFPA is RAZ/WI from NS. FPCA is RO if NSACR.CP10 == 0,
88
if (g_str_equal(qtest_get_arch(), "aarch64")) {
66
+ * RES0 if the FPU is not present, and is stored in the S bank
89
bool kvm_supports_sve;
67
+ */
90
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
68
+ if (arm_feature(env, ARM_FEATURE_VFP) &&
91
char *error;
69
+ extract32(env->v7m.nsacr, 10, 1)) {
92
70
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
93
assert_has_feature_enabled(qts, "host", "aarch64");
71
+ env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK;
94
+
72
+ }
95
+ /* Enabling and disabling pmu should always work. */
73
return;
96
assert_has_feature_enabled(qts, "host", "pmu");
74
case 0x98: /* SP_NS */
97
+ assert_set_feature(qts, "host", "pmu", false);
75
{
98
+ assert_set_feature(qts, "host", "pmu", true);
76
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
99
77
env->v7m.faultmask[env->v7m.secure] = val & 1;
100
assert_error(qts, "cortex-a15",
78
break;
101
"We cannot guarantee the CPU type 'cortex-a15' works "
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
--
102
--
123
2.20.1
103
2.20.1
124
104
125
105
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
2
2
3
The SMMUNotifierNode struct is not necessary and brings extra
3
This adds support for memory(pc-dimm) hot remove on arm/virt that
4
complexity so let's remove it. We now directly track the SMMUDevices
4
uses acpi ged device.
5
which have registered IOMMU MR notifiers.
6
5
7
This is inspired from the same transformation on intel-iommu
6
NVDIMM hot removal is not yet supported.
8
done in commit b4a4ba0d68f50f218ee3957b6638dbee32a5eeef
9
("intel-iommu: remove IntelIOMMUNotifierNode")
10
7
11
Signed-off-by: Eric Auger <eric.auger@redhat.com>
8
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
12
Reviewed-by: Peter Xu <peterx@redhat.com>
9
Message-id: 20200622124157.20360-1-shameerali.kolothum.thodi@huawei.com
13
Message-id: 20190409160219.19026-1-eric.auger@redhat.com
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
Tested-by: Eric Auger <eric.auger@redhat.com>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
13
---
16
include/hw/arm/smmu-common.h | 8 ++------
14
hw/acpi/generic_event_device.c | 29 ++++++++++++++++
17
hw/arm/smmu-common.c | 6 +++---
15
hw/arm/virt.c | 62 ++++++++++++++++++++++++++++++++--
18
hw/arm/smmuv3.c | 28 +++++++---------------------
16
2 files changed, 89 insertions(+), 2 deletions(-)
19
3 files changed, 12 insertions(+), 30 deletions(-)
20
17
21
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
18
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
22
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/smmu-common.h
20
--- a/hw/acpi/generic_event_device.c
24
+++ b/include/hw/arm/smmu-common.h
21
+++ b/hw/acpi/generic_event_device.c
25
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUDevice {
22
@@ -XXX,XX +XXX,XX @@ static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,
26
AddressSpace as;
27
uint32_t cfg_cache_hits;
28
uint32_t cfg_cache_misses;
29
+ QLIST_ENTRY(SMMUDevice) next;
30
} SMMUDevice;
31
32
-typedef struct SMMUNotifierNode {
33
- SMMUDevice *sdev;
34
- QLIST_ENTRY(SMMUNotifierNode) next;
35
-} SMMUNotifierNode;
36
-
37
typedef struct SMMUPciBus {
38
PCIBus *bus;
39
SMMUDevice *pbdev[0]; /* Parent array is sparse, so dynamically alloc */
40
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUState {
41
GHashTable *iotlb;
42
SMMUPciBus *smmu_pcibus_by_bus_num[SMMU_PCI_BUS_MAX];
43
PCIBus *pci_bus;
44
- QLIST_HEAD(, SMMUNotifierNode) notifiers_list;
45
+ QLIST_HEAD(, SMMUDevice) devices_with_notifiers;
46
uint8_t bus_num;
47
PCIBus *primary_bus;
48
} SMMUState;
49
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/smmu-common.c
52
+++ b/hw/arm/smmu-common.c
53
@@ -XXX,XX +XXX,XX @@ inline void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
54
/* Unmap all notifiers of all mr's */
55
void smmu_inv_notifiers_all(SMMUState *s)
56
{
57
- SMMUNotifierNode *node;
58
+ SMMUDevice *sdev;
59
60
- QLIST_FOREACH(node, &s->notifiers_list, next) {
61
- smmu_inv_notifiers_mr(&node->sdev->iommu);
62
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
63
+ smmu_inv_notifiers_mr(&sdev->iommu);
64
}
23
}
65
}
24
}
66
25
67
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
26
+static void acpi_ged_unplug_request_cb(HotplugHandler *hotplug_dev,
27
+ DeviceState *dev, Error **errp)
28
+{
29
+ AcpiGedState *s = ACPI_GED(hotplug_dev);
30
+
31
+ if ((object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
32
+ !(object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)))) {
33
+ acpi_memory_unplug_request_cb(hotplug_dev, &s->memhp_state, dev, errp);
34
+ } else {
35
+ error_setg(errp, "acpi: device unplug request for unsupported device"
36
+ " type: %s", object_get_typename(OBJECT(dev)));
37
+ }
38
+}
39
+
40
+static void acpi_ged_unplug_cb(HotplugHandler *hotplug_dev,
41
+ DeviceState *dev, Error **errp)
42
+{
43
+ AcpiGedState *s = ACPI_GED(hotplug_dev);
44
+
45
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
46
+ acpi_memory_unplug_cb(&s->memhp_state, dev, errp);
47
+ } else {
48
+ error_setg(errp, "acpi: device unplug for unsupported device"
49
+ " type: %s", object_get_typename(OBJECT(dev)));
50
+ }
51
+}
52
+
53
static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
54
{
55
AcpiGedState *s = ACPI_GED(adev);
56
@@ -XXX,XX +XXX,XX @@ static void acpi_ged_class_init(ObjectClass *class, void *data)
57
dc->vmsd = &vmstate_acpi_ged;
58
59
hc->plug = acpi_ged_device_plug_cb;
60
+ hc->unplug_request = acpi_ged_unplug_request_cb;
61
+ hc->unplug = acpi_ged_unplug_cb;
62
63
adevc->send_event = acpi_ged_send_event;
64
}
65
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
68
index XXXXXXX..XXXXXXX 100644
66
index XXXXXXX..XXXXXXX 100644
69
--- a/hw/arm/smmuv3.c
67
--- a/hw/arm/virt.c
70
+++ b/hw/arm/smmuv3.c
68
+++ b/hw/arm/virt.c
71
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
69
@@ -XXX,XX +XXX,XX @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
72
/* invalidate an asid/iova tuple in all mr's */
73
static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova)
74
{
75
- SMMUNotifierNode *node;
76
+ SMMUDevice *sdev;
77
78
- QLIST_FOREACH(node, &s->notifiers_list, next) {
79
- IOMMUMemoryRegion *mr = &node->sdev->iommu;
80
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
81
+ IOMMUMemoryRegion *mr = &sdev->iommu;
82
IOMMUNotifier *n;
83
84
trace_smmuv3_inv_notifiers_iova(mr->parent_obj.name, asid, iova);
85
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
86
SMMUDevice *sdev = container_of(iommu, SMMUDevice, iommu);
87
SMMUv3State *s3 = sdev->smmu;
88
SMMUState *s = &(s3->smmu_state);
89
- SMMUNotifierNode *node = NULL;
90
- SMMUNotifierNode *next_node = NULL;
91
92
if (new & IOMMU_NOTIFIER_MAP) {
93
int bus_num = pci_bus_num(sdev->bus);
94
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
95
96
if (old == IOMMU_NOTIFIER_NONE) {
97
trace_smmuv3_notify_flag_add(iommu->parent_obj.name);
98
- node = g_malloc0(sizeof(*node));
99
- node->sdev = sdev;
100
- QLIST_INSERT_HEAD(&s->notifiers_list, node, next);
101
- return;
102
- }
103
-
104
- /* update notifier node with new flags */
105
- QLIST_FOREACH_SAFE(node, &s->notifiers_list, next, next_node) {
106
- if (node->sdev == sdev) {
107
- if (new == IOMMU_NOTIFIER_NONE) {
108
- trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
109
- QLIST_REMOVE(node, next);
110
- g_free(node);
111
- }
112
- return;
113
- }
114
+ QLIST_INSERT_HEAD(&s->devices_with_notifiers, sdev, next);
115
+ } else if (new == IOMMU_NOTIFIER_NONE) {
116
+ trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
117
+ QLIST_REMOVE(sdev, next);
118
}
70
}
119
}
71
}
120
72
73
+static void virt_dimm_unplug_request(HotplugHandler *hotplug_dev,
74
+ DeviceState *dev, Error **errp)
75
+{
76
+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
77
+ Error *local_err = NULL;
78
+
79
+ if (!vms->acpi_dev) {
80
+ error_setg(&local_err,
81
+ "memory hotplug is not enabled: missing acpi-ged device");
82
+ goto out;
83
+ }
84
+
85
+ if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
86
+ error_setg(&local_err,
87
+ "nvdimm device hot unplug is not supported yet.");
88
+ goto out;
89
+ }
90
+
91
+ hotplug_handler_unplug_request(HOTPLUG_HANDLER(vms->acpi_dev), dev,
92
+ &local_err);
93
+out:
94
+ error_propagate(errp, local_err);
95
+}
96
+
97
+static void virt_dimm_unplug(HotplugHandler *hotplug_dev,
98
+ DeviceState *dev, Error **errp)
99
+{
100
+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
101
+ Error *local_err = NULL;
102
+
103
+ hotplug_handler_unplug(HOTPLUG_HANDLER(vms->acpi_dev), dev, &local_err);
104
+ if (local_err) {
105
+ goto out;
106
+ }
107
+
108
+ pc_dimm_unplug(PC_DIMM(dev), MACHINE(vms));
109
+ qdev_unrealize(dev);
110
+
111
+out:
112
+ error_propagate(errp, local_err);
113
+}
114
+
115
static void virt_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev,
116
DeviceState *dev, Error **errp)
117
{
118
- error_setg(errp, "device unplug request for unsupported device"
119
- " type: %s", object_get_typename(OBJECT(dev)));
120
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
121
+ virt_dimm_unplug_request(hotplug_dev, dev, errp);
122
+ } else {
123
+ error_setg(errp, "device unplug request for unsupported device"
124
+ " type: %s", object_get_typename(OBJECT(dev)));
125
+ }
126
+}
127
+
128
+static void virt_machine_device_unplug_cb(HotplugHandler *hotplug_dev,
129
+ DeviceState *dev, Error **errp)
130
+{
131
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
132
+ virt_dimm_unplug(hotplug_dev, dev, errp);
133
+ } else {
134
+ error_setg(errp, "virt: device unplug for unsupported device"
135
+ " type: %s", object_get_typename(OBJECT(dev)));
136
+ }
137
}
138
139
static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
140
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
141
hc->pre_plug = virt_machine_device_pre_plug_cb;
142
hc->plug = virt_machine_device_plug_cb;
143
hc->unplug_request = virt_machine_device_unplug_request_cb;
144
+ hc->unplug = virt_machine_device_unplug_cb;
145
mc->numa_mem_supported = true;
146
mc->nvdimm_supported = true;
147
mc->auto_enable_numa_with_memhp = true;
121
--
148
--
122
2.20.1
149
2.20.1
123
150
124
151
diff view generated by jsdifflib