1
First pullreq for arm of the 4.1 series, since I'm back from
1
Another arm pullreq; nothing particularly exciting here.
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
8
-- PMM
3
-- PMM
9
4
10
The following changes since commit 413a99a92c13ec408dcf2adaa87918dc81e890c8:
11
5
12
Add Nios II semihosting support. (2019-04-29 16:09:51 +0100)
6
The following changes since commit e27d5b488ef08408691bfed61f34ee2858136287:
7
8
Merge remote-tracking branch 'remotes/juanquintela/tags/pull-migration-pull-request' into staging (2020-02-28 14:02:31 +0000)
13
9
14
are available in the Git repository at:
10
are available in the Git repository at:
15
11
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190429
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200228
17
13
18
for you to fetch changes up to 437cc27ddfded3bbab6afd5ac1761e0e195edba7:
14
for you to fetch changes up to 1904f9b5f1d94fe12fe021db6b504c87d684f6db:
19
15
20
hw/devices: Move SMSC 91C111 declaration into a new header (2019-04-29 17:57:21 +0100)
16
hw/intc/arm_gic_kvm: Don't assume kernel can provide a GICv2 (2020-02-28 16:14:57 +0000)
21
17
22
----------------------------------------------------------------
18
----------------------------------------------------------------
23
target-arm queue:
19
target-arm queue:
24
* remove "bag of random stuff" hw/devices.h header
20
* hw/arm: Use TYPE_PL011 to create serial port
25
* implement FPU for Cortex-M and enable it for Cortex-M4 and -M33
21
* target/arm: Set ID_MMFR4.HPDS for aarch64_max_initfn
26
* hw/dma: Compile the bcm2835_dma device as common object
22
* hw/arm/integratorcp: Map the audio codec controller
27
* configure: Remove --source-path option
23
* GICv2: Correctly implement the limited number of priority bits
28
* hw/ssi/xilinx_spips: Avoid variable length array
24
* target/arm: refactoring of VFP related feature checks and decode
29
* hw/arm/smmuv3: Remove SMMUNotifierNode
25
* xilinx_zynq: Fix USB port instantiation
26
* acceptance tests for n800, n810, integratorcp
27
* Implement v8.3-RCPC, v8.4-RCPC, v8.3-CCIDX
28
* arm_gic_kvm: Don't assume kernel can provide a GICv2
29
(provide better error message for user error)
30
30
31
----------------------------------------------------------------
31
----------------------------------------------------------------
32
Eric Auger (1):
32
Gavin Shan (1):
33
hw/arm/smmuv3: Remove SMMUNotifierNode
33
hw/arm: Use TYPE_PL011 to create serial port
34
34
35
Peter Maydell (28):
35
Guenter Roeck (2):
36
hw/ssi/xilinx_spips: Avoid variable length array
36
hw/arm/xilinx_zynq: Fix USB port instantiation
37
configure: Remove --source-path option
37
hw/usb/hcd-ehci-sysbus: Remove obsolete xlnx, ps7-usb class
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
38
65
Philippe Mathieu-Daudé (13):
39
Peter Maydell (5):
66
hw/dma: Compile the bcm2835_dma device as common object
40
target/arm: Fix wrong use of FIELD_EX32 on ID_AA64DFR0
67
hw/arm/aspeed: Use TYPE_TMP105/TYPE_PCA9552 instead of hardcoded string
41
target/arm: Implement v8.3-RCPC
68
hw/arm/nseries: Use TYPE_TMP105 instead of hardcoded string
42
target/arm: Implement v8.4-RCPC
69
hw/display/tc6393xb: Remove unused functions
43
target/arm: Implement ARMv8.3-CCIDX
70
hw/devices: Move TC6393XB declarations into a new header
44
hw/intc/arm_gic_kvm: Don't assume kernel can provide a GICv2
71
hw/devices: Move Blizzard declarations into a new header
72
hw/devices: Move CBus declarations into a new header
73
hw/devices: Move Gamepad declarations into a new header
74
hw/devices: Move TI touchscreen declarations into a new header
75
hw/devices: Move LAN9118 declarations into a new header
76
hw/net/ne2000-isa: Add guards to the header
77
hw/net/lan9118: Export TYPE_LAN9118 and use it instead of hardcoded string
78
hw/devices: Move SMSC 91C111 declaration into a new header
79
45
80
configure | 10 +-
46
Philippe Mathieu-Daudé (3):
81
hw/dma/Makefile.objs | 2 +-
47
hw/arm/integratorcp: Map the audio codec controller
82
include/hw/arm/omap.h | 6 +-
48
tests/acceptance: Extract boot_integratorcp() from test_integratorcp()
83
include/hw/arm/smmu-common.h | 8 +-
49
tests/acceptance/integratorcp: Verify Tux is displayed on framebuffer
84
include/hw/devices.h | 62 ---
85
include/hw/display/blizzard.h | 22 ++
86
include/hw/display/tc6393xb.h | 24 ++
87
include/hw/input/gamepad.h | 19 +
88
include/hw/input/tsc2xxx.h | 36 ++
89
include/hw/misc/cbus.h | 32 ++
90
include/hw/net/lan9118.h | 21 +
91
include/hw/net/ne2000-isa.h | 6 +
92
include/hw/net/smc91c111.h | 19 +
93
include/qemu/typedefs.h | 1 -
94
target/arm/cpu.h | 95 ++++-
95
target/arm/helper.h | 5 +
96
target/arm/translate.h | 3 +
97
hw/arm/aspeed.c | 13 +-
98
hw/arm/exynos4_boards.c | 3 +-
99
hw/arm/gumstix.c | 2 +-
100
hw/arm/integratorcp.c | 2 +-
101
hw/arm/kzm.c | 2 +-
102
hw/arm/mainstone.c | 2 +-
103
hw/arm/mps2-tz.c | 3 +-
104
hw/arm/mps2.c | 2 +-
105
hw/arm/nseries.c | 7 +-
106
hw/arm/palm.c | 2 +-
107
hw/arm/realview.c | 3 +-
108
hw/arm/smmu-common.c | 6 +-
109
hw/arm/smmuv3.c | 28 +-
110
hw/arm/stellaris.c | 2 +-
111
hw/arm/tosa.c | 2 +-
112
hw/arm/versatilepb.c | 2 +-
113
hw/arm/vexpress.c | 2 +-
114
hw/display/blizzard.c | 2 +-
115
hw/display/tc6393xb.c | 18 +-
116
hw/input/stellaris_input.c | 2 +-
117
hw/input/tsc2005.c | 2 +-
118
hw/input/tsc210x.c | 4 +-
119
hw/intc/armv7m_nvic.c | 261 +++++++++++++
120
hw/misc/cbus.c | 2 +-
121
hw/net/lan9118.c | 3 +-
122
hw/net/smc91c111.c | 2 +-
123
hw/ssi/xilinx_spips.c | 6 +-
124
target/arm/cpu.c | 20 +
125
target/arm/helper.c | 873 +++++++++++++++++++++++++++++++++++++++---
126
target/arm/machine.c | 16 +
127
target/arm/translate.c | 150 +++++++-
128
target/arm/vfp_helper.c | 8 +
129
MAINTAINERS | 7 +
130
50 files changed, 1595 insertions(+), 235 deletions(-)
131
delete mode 100644 include/hw/devices.h
132
create mode 100644 include/hw/display/blizzard.h
133
create mode 100644 include/hw/display/tc6393xb.h
134
create mode 100644 include/hw/input/gamepad.h
135
create mode 100644 include/hw/input/tsc2xxx.h
136
create mode 100644 include/hw/misc/cbus.h
137
create mode 100644 include/hw/net/lan9118.h
138
create mode 100644 include/hw/net/smc91c111.h
139
50
51
Richard Henderson (17):
52
target/arm: Set ID_MMFR4.HPDS for aarch64_max_initfn
53
target/arm: Add isar_feature_aa32_vfp_simd
54
target/arm: Rename isar_feature_aa32_fpdp_v2
55
target/arm: Add isar_feature_aa32_{fpsp_v2, fpsp_v3, fpdp_v3}
56
target/arm: Add isar_feature_aa64_fp_simd, isar_feature_aa32_vfp
57
target/arm: Perform fpdp_v2 check first
58
target/arm: Replace ARM_FEATURE_VFP3 checks with fp{sp, dp}_v3
59
target/arm: Add missing checks for fpsp_v2
60
target/arm: Replace ARM_FEATURE_VFP4 with isar_feature_aa32_simdfmac
61
target/arm: Remove ARM_FEATURE_VFP check from disas_vfp_insn
62
target/arm: Move VLLDM and VLSTM to vfp.decode
63
target/arm: Move the vfp decodetree calls next to the base isa
64
linux-user/arm: Replace ARM_FEATURE_VFP* tests for HWCAP
65
target/arm: Remove ARM_FEATURE_VFP*
66
target/arm: Add formats for some vfp 2 and 3-register insns
67
target/arm: Split VFM decode
68
target/arm: Split VMINMAXNM decode
69
70
Sai Pavan Boddu (3):
71
arm_gic: Mask the un-supported priority bits
72
cpu/a9mpcore: Set number of GIC priority bits to 5
73
cpu/arm11mpcore: Set number of GIC priority bits to 4
74
75
Thomas Huth (2):
76
tests/acceptance: Add a test for the N800 and N810 arm machines
77
tests/acceptance: Add a test for the integratorcp arm machine
78
79
include/hw/intc/arm_gic.h | 2 +
80
include/hw/intc/arm_gic_common.h | 1 +
81
target/arm/cpu.h | 88 +++++-
82
hw/arm/integratorcp.c | 1 +
83
hw/arm/sbsa-ref.c | 3 +-
84
hw/arm/virt.c | 3 +-
85
hw/arm/xilinx_zynq.c | 5 +-
86
hw/arm/xlnx-versal.c | 3 +-
87
hw/cpu/a9mpcore.c | 4 +
88
hw/cpu/arm11mpcore.c | 5 +
89
hw/intc/arm_gic.c | 33 +-
90
hw/intc/arm_gic_common.c | 1 +
91
hw/intc/arm_gic_kvm.c | 9 +
92
hw/intc/armv7m_nvic.c | 20 +-
93
hw/usb/hcd-ehci-sysbus.c | 17 -
94
linux-user/arm/signal.c | 4 +-
95
linux-user/elfload.c | 25 +-
96
target/arm/arch_dump.c | 11 +-
97
target/arm/cpu.c | 44 +--
98
target/arm/cpu64.c | 5 +-
99
target/arm/helper.c | 23 +-
100
target/arm/kvm32.c | 5 -
101
target/arm/kvm64.c | 1 -
102
target/arm/m_helper.c | 11 +-
103
target/arm/machine.c | 5 +-
104
target/arm/translate-a64.c | 114 +++++++
105
target/arm/translate-vfp.inc.c | 448 +++++++++++++++++----------
106
target/arm/translate.c | 122 ++------
107
MAINTAINERS | 2 +
108
hw/arm/Kconfig | 1 +
109
target/arm/vfp-uncond.decode | 12 +-
110
target/arm/vfp.decode | 153 ++++-----
111
tests/acceptance/machine_arm_integratorcp.py | 99 ++++++
112
tests/acceptance/machine_arm_n8x0.py | 49 +++
113
34 files changed, 865 insertions(+), 464 deletions(-)
114
create mode 100644 tests/acceptance/machine_arm_integratorcp.py
115
create mode 100644 tests/acceptance/machine_arm_n8x0.py
116
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Gavin Shan <gshan@redhat.com>
2
2
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
This uses TYPE_PL011 when creating the serial port so that the code
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
looks cleaner.
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
6
Message-id: 20190412165416.7977-11-philmd@redhat.com
6
Signed-off-by: Gavin Shan <gshan@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20200224222223.4128-1-gshan@redhat.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
11
---
9
include/hw/net/ne2000-isa.h | 6 ++++++
12
hw/arm/sbsa-ref.c | 3 ++-
10
1 file changed, 6 insertions(+)
13
hw/arm/virt.c | 3 ++-
14
hw/arm/xlnx-versal.c | 3 ++-
15
3 files changed, 6 insertions(+), 3 deletions(-)
11
16
12
diff --git a/include/hw/net/ne2000-isa.h b/include/hw/net/ne2000-isa.h
17
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/net/ne2000-isa.h
19
--- a/hw/arm/sbsa-ref.c
15
+++ b/include/hw/net/ne2000-isa.h
20
+++ b/hw/arm/sbsa-ref.c
16
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
17
* This work is licensed under the terms of the GNU GPL, version 2 or later.
22
#include "hw/pci-host/gpex.h"
18
* See the COPYING file in the top-level directory.
23
#include "hw/qdev-properties.h"
19
*/
24
#include "hw/usb.h"
20
+
25
+#include "hw/char/pl011.h"
21
+#ifndef HW_NET_NE2K_ISA_H
26
#include "net/net.h"
22
+#define HW_NET_NE2K_ISA_H
27
23
+
28
#define RAMLIMIT_GB 8192
24
#include "hw/hw.h"
29
@@ -XXX,XX +XXX,XX @@ static void create_uart(const SBSAMachineState *sms, int uart,
25
#include "hw/qdev.h"
30
{
26
#include "hw/isa/isa.h"
31
hwaddr base = sbsa_ref_memmap[uart].base;
27
@@ -XXX,XX +XXX,XX @@ static inline ISADevice *isa_ne2000_init(ISABus *bus, int base, int irq,
32
int irq = sbsa_ref_irqmap[uart];
28
}
33
- DeviceState *dev = qdev_create(NULL, "pl011");
29
return d;
34
+ DeviceState *dev = qdev_create(NULL, TYPE_PL011);
30
}
35
SysBusDevice *s = SYS_BUS_DEVICE(dev);
31
+
36
32
+#endif
37
qdev_prop_set_chr(dev, "chardev", chr);
38
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/virt.c
41
+++ b/hw/arm/virt.c
42
@@ -XXX,XX +XXX,XX @@
43
#include "hw/mem/nvdimm.h"
44
#include "hw/acpi/generic_event_device.h"
45
#include "hw/virtio/virtio-iommu.h"
46
+#include "hw/char/pl011.h"
47
48
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
49
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
50
@@ -XXX,XX +XXX,XX @@ static void create_uart(const VirtMachineState *vms, int uart,
51
int irq = vms->irqmap[uart];
52
const char compat[] = "arm,pl011\0arm,primecell";
53
const char clocknames[] = "uartclk\0apb_pclk";
54
- DeviceState *dev = qdev_create(NULL, "pl011");
55
+ DeviceState *dev = qdev_create(NULL, TYPE_PL011);
56
SysBusDevice *s = SYS_BUS_DEVICE(dev);
57
58
qdev_prop_set_chr(dev, "chardev", chr);
59
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/arm/xlnx-versal.c
62
+++ b/hw/arm/xlnx-versal.c
63
@@ -XXX,XX +XXX,XX @@
64
#include "hw/misc/unimp.h"
65
#include "hw/intc/arm_gicv3_common.h"
66
#include "hw/arm/xlnx-versal.h"
67
+#include "hw/char/pl011.h"
68
69
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
70
#define GEM_REVISION 0x40070106
71
@@ -XXX,XX +XXX,XX @@ static void versal_create_uarts(Versal *s, qemu_irq *pic)
72
DeviceState *dev;
73
MemoryRegion *mr;
74
75
- dev = qdev_create(NULL, "pl011");
76
+ dev = qdev_create(NULL, TYPE_PL011);
77
s->lpd.iou.uart[i] = SYS_BUS_DEVICE(dev);
78
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
79
object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
33
--
80
--
34
2.20.1
81
2.20.1
35
82
36
83
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Suggested-by: Markus Armbruster <armbru@redhat.com>
3
We had set this for aarch32-only in arm_max_initfn, but
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
failed to set the same bit for aarch64.
5
Message-id: 20190412165416.7977-3-philmd@redhat.com
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200218190958.745-2-richard.henderson@linaro.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
10
---
9
hw/arm/nseries.c | 3 ++-
11
target/arm/cpu64.c | 1 +
10
1 file changed, 2 insertions(+), 1 deletion(-)
12
1 file changed, 1 insertion(+)
11
13
12
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
14
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/nseries.c
16
--- a/target/arm/cpu64.c
15
+++ b/hw/arm/nseries.c
17
+++ b/target/arm/cpu64.c
16
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
17
#include "hw/boards.h"
19
cpu->isar.id_mmfr3 = u;
18
#include "hw/i2c/i2c.h"
20
19
#include "hw/devices.h"
21
u = cpu->isar.id_mmfr4;
20
+#include "hw/misc/tmp105.h"
22
+ u = FIELD_DP32(u, ID_MMFR4, HPDS, 1); /* AA32HPD */
21
#include "hw/block/flash.h"
23
u = FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
22
#include "hw/hw.h"
24
cpu->isar.id_mmfr4 = u;
23
#include "hw/bt.h"
24
@@ -XXX,XX +XXX,XX @@ static void n8x0_i2c_setup(struct n800_s *s)
25
qemu_register_powerdown_notifier(&n8x0_system_powerdown_notifier);
26
27
/* Attach a TMP105 PM chip (A0 wired to ground) */
28
- dev = i2c_create_slave(i2c, "tmp105", N8X0_TMP105_ADDR);
29
+ dev = i2c_create_slave(i2c, TYPE_TMP105, N8X0_TMP105_ADDR);
30
qdev_connect_gpio_out(dev, 0, tmp_irq);
31
}
32
25
33
--
26
--
34
2.20.1
27
2.20.1
35
28
36
29
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
The Linux kernel displays errors why trying to detect the PL041
4
audio interface:
4
5
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
6
Linux version 4.16.0 (linus@genomnajs) (gcc version 7.2.1 20171011 (Linaro GCC 7.2-2017.11)) #142 PREEMPT Wed May 9 13:24:55 CEST 2018
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00093177
7
Message-id: 20190412165416.7977-13-philmd@redhat.com
8
CPU: VIVT data cache, VIVT instruction cache
9
OF: fdt: Machine model: ARM Integrator/CP
10
...
11
OF: amba_device_add() failed (-19) for /fpga/aaci@1d000000
12
13
Since we have it already modelled, simply plug it.
14
15
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Message-id: 20200223233033.15371-2-f4bug@amsat.org
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
19
---
10
include/hw/devices.h | 11 -----------
20
hw/arm/integratorcp.c | 1 +
11
include/hw/net/smc91c111.h | 19 +++++++++++++++++++
21
hw/arm/Kconfig | 1 +
12
hw/arm/gumstix.c | 2 +-
22
2 files changed, 2 insertions(+)
13
hw/arm/integratorcp.c | 2 +-
14
hw/arm/mainstone.c | 2 +-
15
hw/arm/realview.c | 2 +-
16
hw/arm/versatilepb.c | 2 +-
17
hw/net/smc91c111.c | 2 +-
18
8 files changed, 25 insertions(+), 17 deletions(-)
19
delete mode 100644 include/hw/devices.h
20
create mode 100644 include/hw/net/smc91c111.h
21
23
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
24
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
78
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/arm/integratorcp.c
26
--- a/hw/arm/integratorcp.c
80
+++ b/hw/arm/integratorcp.c
27
+++ b/hw/arm/integratorcp.c
81
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@ static void integratorcp_init(MachineState *machine)
82
#include "qemu-common.h"
29
qdev_get_gpio_in_named(icp, ICP_GPIO_MMC_WPROT, 0));
83
#include "cpu.h"
30
qdev_connect_gpio_out(dev, 1,
84
#include "hw/sysbus.h"
31
qdev_get_gpio_in_named(icp, ICP_GPIO_MMC_CARDIN, 0));
85
-#include "hw/devices.h"
32
+ sysbus_create_varargs("pl041", 0x1d000000, pic[25], NULL);
86
#include "hw/boards.h"
33
87
#include "hw/arm/arm.h"
34
if (nd_table[0].used)
88
#include "hw/misc/arm_integrator_debug.h"
35
smc91c111_init(&nd_table[0], 0xc8000000, pic[27]);
89
+#include "hw/net/smc91c111.h"
36
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
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
37
index XXXXXXX..XXXXXXX 100644
95
--- a/hw/arm/mainstone.c
38
--- a/hw/arm/Kconfig
96
+++ b/hw/arm/mainstone.c
39
+++ b/hw/arm/Kconfig
97
@@ -XXX,XX +XXX,XX @@
40
@@ -XXX,XX +XXX,XX @@ config INTEGRATOR
98
#include "hw/arm/pxa.h"
41
select INTEGRATOR_DEBUG
99
#include "hw/arm/arm.h"
42
select PL011 # UART
100
#include "net/net.h"
43
select PL031 # RTC
101
-#include "hw/devices.h"
44
+ select PL041 # audio
102
+#include "hw/net/smc91c111.h"
45
select PL050 # keyboard/mouse
103
#include "hw/boards.h"
46
select PL110 # pl111 LCD controller
104
#include "hw/block/flash.h"
47
select PL181 # display
105
#include "hw/sysbus.h"
106
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/hw/arm/realview.c
109
+++ b/hw/arm/realview.c
110
@@ -XXX,XX +XXX,XX @@
111
#include "hw/sysbus.h"
112
#include "hw/arm/arm.h"
113
#include "hw/arm/primecell.h"
114
-#include "hw/devices.h"
115
#include "hw/net/lan9118.h"
116
+#include "hw/net/smc91c111.h"
117
#include "hw/pci/pci.h"
118
#include "net/net.h"
119
#include "sysemu/sysemu.h"
120
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
121
index XXXXXXX..XXXXXXX 100644
122
--- a/hw/arm/versatilepb.c
123
+++ b/hw/arm/versatilepb.c
124
@@ -XXX,XX +XXX,XX @@
125
#include "cpu.h"
126
#include "hw/sysbus.h"
127
#include "hw/arm/arm.h"
128
-#include "hw/devices.h"
129
+#include "hw/net/smc91c111.h"
130
#include "net/net.h"
131
#include "sysemu/sysemu.h"
132
#include "hw/pci/pci.h"
133
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/hw/net/smc91c111.c
136
+++ b/hw/net/smc91c111.c
137
@@ -XXX,XX +XXX,XX @@
138
#include "qemu/osdep.h"
139
#include "hw/sysbus.h"
140
#include "net/net.h"
141
-#include "hw/devices.h"
142
+#include "hw/net/smc91c111.h"
143
#include "qemu/log.h"
144
/* For crc32 */
145
#include <zlib.h>
146
--
48
--
147
2.20.1
49
2.20.1
148
50
149
51
diff view generated by jsdifflib
1
Like AArch64, M-profile floating point has no FPEXC enable
1
From: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
2
bit to gate floating point; so always set the VFPEN TB flag.
3
2
4
M-profile also has CPACR and NSACR similar to A-profile;
3
The GICv2 allows the implementation to implement a variable number
5
they behave slightly differently:
4
of priority bits; unimplemented bits in the priority registers
6
* the CPACR is banked between Secure and Non-Secure
5
are read as zeros, writes ignored. We were previously always
7
* if the NSACR forces a trap then this is taken to
6
implementing a full 8 bits of priority, which is allowed but not
8
the Secure state, not the Non-Secure state
7
what the real hardware typically does (which is usually to have
8
4 or 5 bits of priority).
9
9
10
Honour the CPACR and NSACR settings. The NSACR handling
10
Add a new device property to allow the number of implemented
11
requires us to borrow the exception.target_el field
11
property bits to be specified.
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
12
13
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
14
Message-id: 1582537164-764-2-git-send-email-sai.pavan.boddu@xilinx.com
15
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
[PMM: improved commit message]
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Message-id: 20190416125744.27770-6-peter.maydell@linaro.org
19
---
19
---
20
target/arm/helper.c | 55 +++++++++++++++++++++++++++++++++++++++---
20
include/hw/intc/arm_gic.h | 2 ++
21
target/arm/translate.c | 10 ++++++--
21
include/hw/intc/arm_gic_common.h | 1 +
22
2 files changed, 60 insertions(+), 5 deletions(-)
22
hw/intc/arm_gic.c | 33 ++++++++++++++++++++++++++++++--
23
hw/intc/arm_gic_common.c | 1 +
24
4 files changed, 35 insertions(+), 2 deletions(-)
23
25
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
26
diff --git a/include/hw/intc/arm_gic.h b/include/hw/intc/arm_gic.h
25
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.c
28
--- a/include/hw/intc/arm_gic.h
27
+++ b/target/arm/helper.c
29
+++ b/include/hw/intc/arm_gic.h
28
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
30
@@ -XXX,XX +XXX,XX @@
29
return target_el;
31
32
/* Number of SGI target-list bits */
33
#define GIC_TARGETLIST_BITS 8
34
+#define GIC_MAX_PRIORITY_BITS 8
35
+#define GIC_MIN_PRIORITY_BITS 4
36
37
#define TYPE_ARM_GIC "arm_gic"
38
#define ARM_GIC(obj) \
39
diff --git a/include/hw/intc/arm_gic_common.h b/include/hw/intc/arm_gic_common.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/include/hw/intc/arm_gic_common.h
42
+++ b/include/hw/intc/arm_gic_common.h
43
@@ -XXX,XX +XXX,XX @@ typedef struct GICState {
44
uint16_t priority_mask[GIC_NCPU_VCPU];
45
uint16_t running_priority[GIC_NCPU_VCPU];
46
uint16_t current_pending[GIC_NCPU_VCPU];
47
+ uint32_t n_prio_bits;
48
49
/* If we present the GICv2 without security extensions to a guest,
50
* the guest can configure the GICC_CTLR to configure group 1 binary point
51
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/hw/intc/arm_gic.c
54
+++ b/hw/intc/arm_gic.c
55
@@ -XXX,XX +XXX,XX @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu, MemTxAttrs attrs)
56
return ret;
30
}
57
}
31
58
32
+/*
59
+static uint32_t gic_fullprio_mask(GICState *s, int cpu)
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
+{
60
+{
38
+ switch (extract32(env->v7m.cpacr[is_secure], 20, 2)) {
61
+ /*
39
+ case 0:
62
+ * Return a mask word which clears the unimplemented priority
40
+ case 2: /* UNPREDICTABLE: we treat like 0 */
63
+ * bits from a priority value for an interrupt. (Not to be
41
+ return false;
64
+ * confused with the group priority, whose mask depends on BPR.)
42
+ case 1:
65
+ */
43
+ return is_priv;
66
+ int priBits;
44
+ case 3:
67
+
45
+ return true;
68
+ if (gic_is_vcpu(cpu)) {
46
+ default:
69
+ priBits = GIC_VIRT_MAX_GROUP_PRIO_BITS;
47
+ g_assert_not_reached();
70
+ } else {
71
+ priBits = s->n_prio_bits;
48
+ }
72
+ }
73
+ return ~0U << (8 - priBits);
49
+}
74
+}
50
+
75
+
51
static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
76
void gic_dist_set_priority(GICState *s, int cpu, int irq, uint8_t val,
52
ARMMMUIdx mmu_idx, bool ignfault)
77
MemTxAttrs attrs)
53
{
78
{
54
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
79
@@ -XXX,XX +XXX,XX @@ void gic_dist_set_priority(GICState *s, int cpu, int irq, uint8_t val,
55
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNDEFINSTR_MASK;
80
val = 0x80 | (val >> 1); /* Non-secure view */
56
break;
81
}
57
case EXCP_NOCP:
82
58
- armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
83
+ val &= gic_fullprio_mask(s, cpu);
59
- env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_NOCP_MASK;
60
+ {
61
+ /*
62
+ * NOCP might be directed to something other than the current
63
+ * security state if this fault is because of NSACR; we indicate
64
+ * the target security state using exception.target_el.
65
+ */
66
+ int target_secstate;
67
+
84
+
68
+ if (env->exception.target_el == 3) {
85
if (irq < GIC_INTERNAL) {
69
+ target_secstate = M_REG_S;
86
s->priority1[irq][cpu] = val;
70
+ } else {
87
} else {
71
+ target_secstate = env->v7m.secure;
88
@@ -XXX,XX +XXX,XX @@ static uint32_t gic_dist_get_priority(GICState *s, int cpu, int irq,
72
+ }
89
}
73
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, target_secstate);
90
prio = (prio << 1) & 0xff; /* Non-secure view */
74
+ env->v7m.cfsr[target_secstate] |= R_V7M_CFSR_NOCP_MASK;
75
break;
76
+ }
77
case EXCP_INVSTATE:
78
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
79
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVSTATE_MASK;
80
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
81
return 0;
82
}
91
}
83
92
- return prio;
84
+ if (arm_feature(env, ARM_FEATURE_M)) {
93
+ return prio & gic_fullprio_mask(s, cpu);
85
+ /* CPACR can cause a NOCP UsageFault taken to current security state */
94
}
86
+ if (!v7m_cpacr_pass(env, env->v7m.secure, cur_el != 0)) {
95
87
+ return 1;
96
static void gic_set_priority_mask(GICState *s, int cpu, uint8_t pmask,
88
+ }
97
@@ -XXX,XX +XXX,XX @@ static void gic_set_priority_mask(GICState *s, int cpu, uint8_t pmask,
89
+
98
return;
90
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) && !env->v7m.secure) {
99
}
91
+ if (!extract32(env->v7m.nsacr, 10, 1)) {
100
}
92
+ /* FP insns cause a NOCP UsageFault taken to Secure */
101
- s->priority_mask[cpu] = pmask;
93
+ return 3;
102
+ s->priority_mask[cpu] = pmask & gic_fullprio_mask(s, cpu);
94
+ }
103
}
95
+ }
104
96
+
105
static uint32_t gic_get_priority_mask(GICState *s, int cpu, MemTxAttrs attrs)
97
+ return 0;
106
@@ -XXX,XX +XXX,XX @@ static void arm_gic_realize(DeviceState *dev, Error **errp)
107
return;
108
}
109
110
+ if (s->n_prio_bits > GIC_MAX_PRIORITY_BITS ||
111
+ (s->virt_extn ? s->n_prio_bits < GIC_VIRT_MAX_GROUP_PRIO_BITS :
112
+ s->n_prio_bits < GIC_MIN_PRIORITY_BITS)) {
113
+ error_setg(errp, "num-priority-bits cannot be greater than %d"
114
+ " or less than %d", GIC_MAX_PRIORITY_BITS,
115
+ s->virt_extn ? GIC_VIRT_MAX_GROUP_PRIO_BITS :
116
+ GIC_MIN_PRIORITY_BITS);
117
+ return;
98
+ }
118
+ }
99
+
119
+
100
/* The CPACR controls traps to EL1, or PL1 if we're 32 bit:
120
/* This creates distributor, main CPU interface (s->cpuiomem[0]) and if
101
* 0, 2 : trap EL0 and EL1/PL1 accesses
121
* enabled, virtualization extensions related interfaces (main virtual
102
* 1 : trap only EL0 accesses
122
* interface (s->vifaceiomem[0]) and virtual CPU interface).
103
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
123
diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c
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
113
index XXXXXXX..XXXXXXX 100644
124
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/translate.c
125
--- a/hw/intc/arm_gic_common.c
115
+++ b/target/arm/translate.c
126
+++ b/hw/intc/arm_gic_common.c
116
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
127
@@ -XXX,XX +XXX,XX @@ static Property arm_gic_common_properties[] = {
117
* for attempts to execute invalid vfp/neon encodings with FP disabled.
128
DEFINE_PROP_BOOL("has-security-extensions", GICState, security_extn, 0),
118
*/
129
/* True if the GIC should implement the virtualization extensions */
119
if (s->fp_excp_el) {
130
DEFINE_PROP_BOOL("has-virtualization-extensions", GICState, virt_extn, 0),
120
- gen_exception_insn(s, 4, EXCP_UDEF,
131
+ DEFINE_PROP_UINT32("num-priority-bits", GICState, n_prio_bits, 8),
121
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
132
DEFINE_PROP_END_OF_LIST(),
122
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
133
};
123
+ gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
124
+ s->fp_excp_el);
125
+ } else {
126
+ gen_exception_insn(s, 4, EXCP_UDEF,
127
+ syn_fp_access_trap(1, 0xe, false),
128
+ s->fp_excp_el);
129
+ }
130
return 0;
131
}
132
134
133
--
135
--
134
2.20.1
136
2.20.1
135
137
136
138
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
2
2
3
This device is used by both ARM (BCM2836, for raspi2) and AArch64
3
All A9 CPUs have a GIC with 5 bits of priority.
4
(BCM2837, for raspi3) targets, and is not CPU-specific.
5
Move it to common object, so we build it once for all targets.
6
4
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
8
Message-id: 20190427133028.12874-1-philmd@redhat.com
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 1582537164-764-3-git-send-email-sai.pavan.boddu@xilinx.com
8
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
hw/dma/Makefile.objs | 2 +-
12
hw/cpu/a9mpcore.c | 4 ++++
13
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 4 insertions(+)
14
14
15
diff --git a/hw/dma/Makefile.objs b/hw/dma/Makefile.objs
15
diff --git a/hw/cpu/a9mpcore.c b/hw/cpu/a9mpcore.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/dma/Makefile.objs
17
--- a/hw/cpu/a9mpcore.c
18
+++ b/hw/dma/Makefile.objs
18
+++ b/hw/cpu/a9mpcore.c
19
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zdma.o
19
@@ -XXX,XX +XXX,XX @@
20
20
#include "hw/qdev-properties.h"
21
obj-$(CONFIG_OMAP) += omap_dma.o soc_dma.o
21
#include "hw/core/cpu.h"
22
obj-$(CONFIG_PXA2XX) += pxa2xx_dma.o
22
23
-obj-$(CONFIG_RASPI) += bcm2835_dma.o
23
+#define A9_GIC_NUM_PRIORITY_BITS 5
24
+common-obj-$(CONFIG_RASPI) += bcm2835_dma.o
24
+
25
static void a9mp_priv_set_irq(void *opaque, int irq, int level)
26
{
27
A9MPPrivState *s = (A9MPPrivState *)opaque;
28
@@ -XXX,XX +XXX,XX @@ static void a9mp_priv_realize(DeviceState *dev, Error **errp)
29
gicdev = DEVICE(&s->gic);
30
qdev_prop_set_uint32(gicdev, "num-cpu", s->num_cpu);
31
qdev_prop_set_uint32(gicdev, "num-irq", s->num_irq);
32
+ qdev_prop_set_uint32(gicdev, "num-priority-bits",
33
+ A9_GIC_NUM_PRIORITY_BITS);
34
35
/* Make the GIC's TZ support match the CPUs. We assume that
36
* either all the CPUs have TZ, or none do.
25
--
37
--
26
2.20.1
38
2.20.1
27
39
28
40
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
The GIC built into the ARM11MPCore is always implemented with 4
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
priority bits; set the GIC property accordingly.
5
Message-id: 20190412165416.7977-12-philmd@redhat.com
5
6
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 1582537164-764-4-git-send-email-sai.pavan.boddu@xilinx.com
9
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
[PMM: tweaked commit message]
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
13
---
8
include/hw/net/lan9118.h | 2 ++
14
hw/cpu/arm11mpcore.c | 5 +++++
9
hw/arm/exynos4_boards.c | 3 ++-
15
1 file changed, 5 insertions(+)
10
hw/arm/mps2-tz.c | 3 ++-
11
hw/net/lan9118.c | 1 -
12
4 files changed, 6 insertions(+), 3 deletions(-)
13
16
14
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
17
diff --git a/hw/cpu/arm11mpcore.c b/hw/cpu/arm11mpcore.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/net/lan9118.h
19
--- a/hw/cpu/arm11mpcore.c
17
+++ b/include/hw/net/lan9118.h
20
+++ b/hw/cpu/arm11mpcore.c
18
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
19
#include "hw/irq.h"
22
#include "hw/irq.h"
20
#include "net/net.h"
23
#include "hw/qdev-properties.h"
21
24
22
+#define TYPE_LAN9118 "lan9118"
25
+#define ARM11MPCORE_NUM_GIC_PRIORITY_BITS 4
26
27
static void mpcore_priv_set_irq(void *opaque, int irq, int level)
28
{
29
@@ -XXX,XX +XXX,XX @@ static void mpcore_priv_realize(DeviceState *dev, Error **errp)
30
31
qdev_prop_set_uint32(gicdev, "num-cpu", s->num_cpu);
32
qdev_prop_set_uint32(gicdev, "num-irq", s->num_irq);
33
+ qdev_prop_set_uint32(gicdev, "num-priority-bits",
34
+ ARM11MPCORE_NUM_GIC_PRIORITY_BITS);
23
+
35
+
24
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
36
+
25
37
object_property_set_bool(OBJECT(&s->gic), true, "realized", &err);
26
#endif
38
if (err != NULL) {
27
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
39
error_propagate(errp, err);
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/exynos4_boards.c
30
+++ b/hw/arm/exynos4_boards.c
31
@@ -XXX,XX +XXX,XX @@
32
#include "hw/arm/arm.h"
33
#include "exec/address-spaces.h"
34
#include "hw/arm/exynos4210.h"
35
+#include "hw/net/lan9118.h"
36
#include "hw/boards.h"
37
38
#undef DEBUG
39
@@ -XXX,XX +XXX,XX @@ static void lan9215_init(uint32_t base, qemu_irq irq)
40
/* This should be a 9215 but the 9118 is close enough */
41
if (nd_table[0].used) {
42
qemu_check_nic_model(&nd_table[0], "lan9118");
43
- dev = qdev_create(NULL, "lan9118");
44
+ dev = qdev_create(NULL, TYPE_LAN9118);
45
qdev_set_nic_properties(dev, &nd_table[0]);
46
qdev_prop_set_uint32(dev, "mode_16bit", 1);
47
qdev_init_nofail(dev);
48
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/arm/mps2-tz.c
51
+++ b/hw/arm/mps2-tz.c
52
@@ -XXX,XX +XXX,XX @@
53
#include "hw/arm/armsse.h"
54
#include "hw/dma/pl080.h"
55
#include "hw/ssi/pl022.h"
56
+#include "hw/net/lan9118.h"
57
#include "net/net.h"
58
#include "hw/core/split-irq.h"
59
60
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
61
* except that it doesn't support the checksum-offload feature.
62
*/
63
qemu_check_nic_model(nd, "lan9118");
64
- mms->lan9118 = qdev_create(NULL, "lan9118");
65
+ mms->lan9118 = qdev_create(NULL, TYPE_LAN9118);
66
qdev_set_nic_properties(mms->lan9118, nd);
67
qdev_init_nofail(mms->lan9118);
68
69
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/hw/net/lan9118.c
72
+++ b/hw/net/lan9118.c
73
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118_packet = {
74
}
75
};
76
77
-#define TYPE_LAN9118 "lan9118"
78
#define LAN9118(obj) OBJECT_CHECK(lan9118_state, (obj), TYPE_LAN9118)
79
80
typedef struct {
81
--
40
--
82
2.20.1
41
2.20.1
83
42
84
43
diff view generated by jsdifflib
1
The M-profile floating point support has three associated config
1
From: Richard Henderson <richard.henderson@linaro.org>
2
registers: FPCAR, FPCCR and FPDSCR. It also makes the registers
2
3
CPACR and NSACR have behaviour other than reads-as-zero.
3
Use this in the places that were checking ARM_FEATURE_VFP, and
4
Add support for all of these as simple reads-as-written registers.
4
are obviously testing for the existance of the register set
5
We will hook up actual functionality later.
5
as opposed to testing for some particular instruction extension.
6
6
7
The main complexity here is handling the FPCCR register, which
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
has a mix of banked and unbanked bits.
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
9
Message-id: 20200224222232.13807-2-richard.henderson@linaro.org
10
Note that we don't share storage with the A-profile
11
cpu->cp15.nsacr and cpu->cp15.cpacr_el1, though the behaviour
12
is quite similar, for two reasons:
13
* the M profile CPACR is banked between security states
14
* it preserves the invariant that M profile uses no state
15
inside the cp15 substruct
16
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
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
---
11
---
21
target/arm/cpu.h | 34 ++++++++++++
12
target/arm/cpu.h | 9 +++++++++
22
hw/intc/armv7m_nvic.c | 125 ++++++++++++++++++++++++++++++++++++++++++
13
hw/intc/armv7m_nvic.c | 20 ++++++++++----------
23
target/arm/cpu.c | 5 ++
14
linux-user/arm/signal.c | 4 ++--
24
target/arm/machine.c | 16 ++++++
15
target/arm/arch_dump.c | 11 ++++++-----
25
4 files changed, 180 insertions(+)
16
target/arm/cpu.c | 4 ++--
17
target/arm/helper.c | 4 ++--
18
target/arm/m_helper.c | 11 ++++++-----
19
7 files changed, 37 insertions(+), 26 deletions(-)
26
20
27
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
28
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/cpu.h
23
--- a/target/arm/cpu.h
30
+++ b/target/arm/cpu.h
24
+++ b/target/arm/cpu.h
31
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
25
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
32
uint32_t scr[M_REG_NUM_BANKS];
26
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
33
uint32_t msplim[M_REG_NUM_BANKS];
27
}
34
uint32_t psplim[M_REG_NUM_BANKS];
28
35
+ uint32_t fpcar[M_REG_NUM_BANKS];
29
+static inline bool isar_feature_aa32_vfp_simd(const ARMISARegisters *id)
36
+ uint32_t fpccr[M_REG_NUM_BANKS];
30
+{
37
+ uint32_t fpdscr[M_REG_NUM_BANKS];
31
+ /*
38
+ uint32_t cpacr[M_REG_NUM_BANKS];
32
+ * Return true if either VFP or SIMD is implemented.
39
+ uint32_t nsacr;
33
+ * In this case, a minimum of VFP w/ D0-D15.
40
} v7m;
34
+ */
41
35
+ return FIELD_EX32(id->mvfr0, MVFR0, SIMDREG) > 0;
42
/* Information associated with an exception about to be taken:
36
+}
43
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_CSSELR, LEVEL, 1, 3)
44
*/
45
FIELD(V7M_CSSELR, INDEX, 0, 4)
46
47
+/* v7M FPCCR bits */
48
+FIELD(V7M_FPCCR, LSPACT, 0, 1)
49
+FIELD(V7M_FPCCR, USER, 1, 1)
50
+FIELD(V7M_FPCCR, S, 2, 1)
51
+FIELD(V7M_FPCCR, THREAD, 3, 1)
52
+FIELD(V7M_FPCCR, HFRDY, 4, 1)
53
+FIELD(V7M_FPCCR, MMRDY, 5, 1)
54
+FIELD(V7M_FPCCR, BFRDY, 6, 1)
55
+FIELD(V7M_FPCCR, SFRDY, 7, 1)
56
+FIELD(V7M_FPCCR, MONRDY, 8, 1)
57
+FIELD(V7M_FPCCR, SPLIMVIOL, 9, 1)
58
+FIELD(V7M_FPCCR, UFRDY, 10, 1)
59
+FIELD(V7M_FPCCR, RES0, 11, 15)
60
+FIELD(V7M_FPCCR, TS, 26, 1)
61
+FIELD(V7M_FPCCR, CLRONRETS, 27, 1)
62
+FIELD(V7M_FPCCR, CLRONRET, 28, 1)
63
+FIELD(V7M_FPCCR, LSPENS, 29, 1)
64
+FIELD(V7M_FPCCR, LSPEN, 30, 1)
65
+FIELD(V7M_FPCCR, ASPEN, 31, 1)
66
+/* These bits are banked. Others are non-banked and live in the M_REG_S bank */
67
+#define R_V7M_FPCCR_BANKED_MASK \
68
+ (R_V7M_FPCCR_LSPACT_MASK | \
69
+ R_V7M_FPCCR_USER_MASK | \
70
+ R_V7M_FPCCR_THREAD_MASK | \
71
+ R_V7M_FPCCR_MMRDY_MASK | \
72
+ R_V7M_FPCCR_SPLIMVIOL_MASK | \
73
+ R_V7M_FPCCR_UFRDY_MASK | \
74
+ R_V7M_FPCCR_ASPEN_MASK)
75
+
37
+
76
/*
38
static inline bool isar_feature_aa32_simd_r32(const ARMISARegisters *id)
77
* System register ID fields.
39
{
78
*/
40
/* Return true if D16-D31 are implemented */
79
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
41
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
80
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
81
--- a/hw/intc/armv7m_nvic.c
43
--- a/hw/intc/armv7m_nvic.c
82
+++ b/hw/intc/armv7m_nvic.c
44
+++ b/hw/intc/armv7m_nvic.c
83
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
45
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
84
}
85
case 0xd84: /* CSSELR */
46
case 0xd84: /* CSSELR */
86
return cpu->env.v7m.csselr[attrs.secure];
47
return cpu->env.v7m.csselr[attrs.secure];
87
+ case 0xd88: /* CPACR */
48
case 0xd88: /* CPACR */
88
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
49
- if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
89
+ return 0;
50
+ if (!cpu_isar_feature(aa32_vfp_simd, cpu)) {
90
+ }
51
return 0;
91
+ return cpu->env.v7m.cpacr[attrs.secure];
52
}
92
+ case 0xd8c: /* NSACR */
53
return cpu->env.v7m.cpacr[attrs.secure];
93
+ if (!attrs.secure || !arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
54
case 0xd8c: /* NSACR */
94
+ return 0;
55
- if (!attrs.secure || !arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
95
+ }
56
+ if (!attrs.secure || !cpu_isar_feature(aa32_vfp_simd, cpu)) {
96
+ return cpu->env.v7m.nsacr;
57
return 0;
97
/* TODO: Implement debug registers. */
58
}
98
case 0xd90: /* MPU_TYPE */
59
return cpu->env.v7m.nsacr;
99
/* Unified MPU; if the MPU is not present this value is zero */
100
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
60
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
101
return 0;
102
}
61
}
103
return cpu->env.v7m.sfar;
62
return cpu->env.v7m.sfar;
104
+ case 0xf34: /* FPCCR */
63
case 0xf34: /* FPCCR */
105
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
64
- if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
106
+ return 0;
65
+ if (!cpu_isar_feature(aa32_vfp_simd, cpu)) {
107
+ }
66
return 0;
108
+ if (attrs.secure) {
67
}
109
+ return cpu->env.v7m.fpccr[M_REG_S];
68
if (attrs.secure) {
110
+ } else {
69
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
111
+ /*
70
return value;
112
+ * NS can read LSPEN, CLRONRET and MONRDY. It can read
71
}
113
+ * BFRDY and HFRDY if AIRCR.BFHFNMINS != 0;
72
case 0xf38: /* FPCAR */
114
+ * other non-banked bits RAZ.
73
- if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
115
+ * TODO: MONRDY should RAZ/WI if DEMCR.SDME is set.
74
+ if (!cpu_isar_feature(aa32_vfp_simd, cpu)) {
116
+ */
75
return 0;
117
+ uint32_t value = cpu->env.v7m.fpccr[M_REG_S];
76
}
118
+ uint32_t mask = R_V7M_FPCCR_LSPEN_MASK |
77
return cpu->env.v7m.fpcar[attrs.secure];
119
+ R_V7M_FPCCR_CLRONRET_MASK |
78
case 0xf3c: /* FPDSCR */
120
+ R_V7M_FPCCR_MONRDY_MASK;
79
- if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
121
+
80
+ if (!cpu_isar_feature(aa32_vfp_simd, cpu)) {
122
+ if (s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
81
return 0;
123
+ mask |= R_V7M_FPCCR_BFRDY_MASK | R_V7M_FPCCR_HFRDY_MASK;
82
}
124
+ }
83
return cpu->env.v7m.fpdscr[attrs.secure];
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,
84
@@ -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;
85
}
146
}
86
break;
147
break;
87
case 0xd88: /* CPACR */
148
+ case 0xd88: /* CPACR */
88
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
149
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
89
+ if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
150
+ /* We implement only the Floating Point extension's CP10/CP11 */
90
/* We implement only the Floating Point extension's CP10/CP11 */
151
+ cpu->env.v7m.cpacr[attrs.secure] = value & (0xf << 20);
91
cpu->env.v7m.cpacr[attrs.secure] = value & (0xf << 20);
152
+ }
92
}
153
+ break;
93
break;
154
+ case 0xd8c: /* NSACR */
94
case 0xd8c: /* NSACR */
155
+ if (attrs.secure && arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
95
- if (attrs.secure && arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
156
+ /* We implement only the Floating Point extension's CP10/CP11 */
96
+ if (attrs.secure && cpu_isar_feature(aa32_vfp_simd, cpu)) {
157
+ cpu->env.v7m.nsacr = value & (3 << 10);
97
/* We implement only the Floating Point extension's CP10/CP11 */
158
+ }
98
cpu->env.v7m.nsacr = value & (3 << 10);
159
+ break;
99
}
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,
100
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
164
}
101
break;
165
break;
102
}
166
}
103
case 0xf34: /* FPCCR */
167
+ case 0xf34: /* FPCCR */
104
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
168
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
105
+ if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
169
+ /* Not all bits here are banked. */
106
/* Not all bits here are banked. */
170
+ uint32_t fpccr_s;
107
uint32_t fpccr_s;
171
+
108
172
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
109
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
173
+ /* Don't allow setting of bits not present in v7M */
110
}
174
+ value &= (R_V7M_FPCCR_LSPACT_MASK |
111
break;
175
+ R_V7M_FPCCR_USER_MASK |
112
case 0xf38: /* FPCAR */
176
+ R_V7M_FPCCR_THREAD_MASK |
113
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
177
+ R_V7M_FPCCR_HFRDY_MASK |
114
+ if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
178
+ R_V7M_FPCCR_MMRDY_MASK |
115
value &= ~7;
179
+ R_V7M_FPCCR_BFRDY_MASK |
116
cpu->env.v7m.fpcar[attrs.secure] = value;
180
+ R_V7M_FPCCR_MONRDY_MASK |
117
}
181
+ R_V7M_FPCCR_LSPEN_MASK |
118
break;
182
+ R_V7M_FPCCR_ASPEN_MASK);
119
case 0xf3c: /* FPDSCR */
183
+ }
120
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
184
+ value &= ~R_V7M_FPCCR_RES0_MASK;
121
+ if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
185
+
122
value &= 0x07c00000;
186
+ if (!attrs.secure) {
123
cpu->env.v7m.fpdscr[attrs.secure] = value;
187
+ /* Some non-banked bits are configurably writable by NS */
124
}
188
+ fpccr_s = cpu->env.v7m.fpccr[M_REG_S];
125
diff --git a/linux-user/arm/signal.c b/linux-user/arm/signal.c
189
+ if (!(fpccr_s & R_V7M_FPCCR_LSPENS_MASK)) {
126
index XXXXXXX..XXXXXXX 100644
190
+ uint32_t lspen = FIELD_EX32(value, V7M_FPCCR, LSPEN);
127
--- a/linux-user/arm/signal.c
191
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, LSPEN, lspen);
128
+++ b/linux-user/arm/signal.c
192
+ }
129
@@ -XXX,XX +XXX,XX @@ static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
193
+ if (!(fpccr_s & R_V7M_FPCCR_CLRONRETS_MASK)) {
130
setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
194
+ uint32_t cor = FIELD_EX32(value, V7M_FPCCR, CLRONRET);
131
/* Save coprocessor signal frame. */
195
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, CLRONRET, cor);
132
regspace = uc->tuc_regspace;
196
+ }
133
- if (arm_feature(env, ARM_FEATURE_VFP)) {
197
+ if ((s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
134
+ if (cpu_isar_feature(aa32_vfp_simd, env_archcpu(env))) {
198
+ uint32_t hfrdy = FIELD_EX32(value, V7M_FPCCR, HFRDY);
135
regspace = setup_sigframe_v2_vfp(regspace, env);
199
+ uint32_t bfrdy = FIELD_EX32(value, V7M_FPCCR, BFRDY);
136
}
200
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, HFRDY, hfrdy);
137
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
201
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, BFRDY, bfrdy);
138
@@ -XXX,XX +XXX,XX @@ static int do_sigframe_return_v2(CPUARMState *env,
202
+ }
139
203
+ /* TODO MONRDY should RAZ/WI if DEMCR.SDME is set */
140
/* Restore coprocessor signal frame */
204
+ {
141
regspace = uc->tuc_regspace;
205
+ uint32_t monrdy = FIELD_EX32(value, V7M_FPCCR, MONRDY);
142
- if (arm_feature(env, ARM_FEATURE_VFP)) {
206
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, MONRDY, monrdy);
143
+ if (cpu_isar_feature(aa32_vfp_simd, env_archcpu(env))) {
207
+ }
144
regspace = restore_sigframe_v2_vfp(env, regspace);
208
+
145
if (!regspace) {
209
+ /*
146
return 1;
210
+ * All other non-banked bits are RAZ/WI from NS; write
147
diff --git a/target/arm/arch_dump.c b/target/arm/arch_dump.c
211
+ * just the banked bits to fpccr[M_REG_NS].
148
index XXXXXXX..XXXXXXX 100644
212
+ */
149
--- a/target/arm/arch_dump.c
213
+ value &= R_V7M_FPCCR_BANKED_MASK;
150
+++ b/target/arm/arch_dump.c
214
+ cpu->env.v7m.fpccr[M_REG_NS] = value;
151
@@ -XXX,XX +XXX,XX @@ int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
215
+ } else {
152
int cpuid, void *opaque)
216
+ fpccr_s = value;
153
{
217
+ }
154
struct arm_note note;
218
+ cpu->env.v7m.fpccr[M_REG_S] = fpccr_s;
155
- CPUARMState *env = &ARM_CPU(cs)->env;
219
+ }
156
+ ARMCPU *cpu = ARM_CPU(cs);
220
+ break;
157
+ CPUARMState *env = &cpu->env;
221
+ case 0xf38: /* FPCAR */
158
DumpState *s = opaque;
222
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
159
- int ret, i, fpvalid = !!arm_feature(env, ARM_FEATURE_VFP);
223
+ value &= ~7;
160
+ int ret, i;
224
+ cpu->env.v7m.fpcar[attrs.secure] = value;
161
+ bool fpvalid = cpu_isar_feature(aa32_vfp_simd, cpu);
225
+ }
162
226
+ break;
163
arm_note_init(&note, s, "CORE", 5, NT_PRSTATUS, sizeof(note.prstatus));
227
+ case 0xf3c: /* FPDSCR */
164
228
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
165
@@ -XXX,XX +XXX,XX @@ int cpu_get_dump_info(ArchDumpInfo *info,
229
+ value &= 0x07c00000;
166
ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
230
+ cpu->env.v7m.fpdscr[attrs.secure] = value;
167
{
231
+ }
168
ARMCPU *cpu = ARM_CPU(first_cpu);
232
+ break;
169
- CPUARMState *env = &cpu->env;
233
case 0xf50: /* ICIALLU */
170
size_t note_size;
234
case 0xf58: /* ICIMVAU */
171
235
case 0xf5c: /* DCIMVAC */
172
if (class == ELFCLASS64) {
173
@@ -XXX,XX +XXX,XX @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
174
note_size += AARCH64_PRFPREG_NOTE_SIZE;
175
#ifdef TARGET_AARCH64
176
if (cpu_isar_feature(aa64_sve, cpu)) {
177
- note_size += AARCH64_SVE_NOTE_SIZE(env);
178
+ note_size += AARCH64_SVE_NOTE_SIZE(&cpu->env);
179
}
180
#endif
181
} else {
182
note_size = ARM_PRSTATUS_NOTE_SIZE;
183
- if (arm_feature(env, ARM_FEATURE_VFP)) {
184
+ if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
185
note_size += ARM_VFP_NOTE_SIZE;
186
}
187
}
236
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
188
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
237
index XXXXXXX..XXXXXXX 100644
189
index XXXXXXX..XXXXXXX 100644
238
--- a/target/arm/cpu.c
190
--- a/target/arm/cpu.c
239
+++ b/target/arm/cpu.c
191
+++ b/target/arm/cpu.c
240
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
192
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
241
env->v7m.ccr[M_REG_S] |= R_V7M_CCR_UNALIGN_TRP_MASK;
193
env->v7m.ccr[M_REG_S] |= R_V7M_CCR_UNALIGN_TRP_MASK;
242
}
194
}
243
195
244
+ if (arm_feature(env, ARM_FEATURE_VFP)) {
196
- if (arm_feature(env, ARM_FEATURE_VFP)) {
245
+ env->v7m.fpccr[M_REG_NS] = R_V7M_FPCCR_ASPEN_MASK;
197
+ if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
246
+ env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK |
198
env->v7m.fpccr[M_REG_NS] = R_V7M_FPCCR_ASPEN_MASK;
247
+ R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK;
199
env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK |
248
+ }
200
R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK;
249
/* Unlike A/R profile, M profile defines the reset LR value */
201
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_dump_state(CPUState *cs, FILE *f, int flags)
250
env->regs[14] = 0xffffffff;
202
int numvfpregs = 0;
251
203
if (cpu_isar_feature(aa32_simd_r32, cpu)) {
252
diff --git a/target/arm/machine.c b/target/arm/machine.c
204
numvfpregs = 32;
253
index XXXXXXX..XXXXXXX 100644
205
- } else if (arm_feature(env, ARM_FEATURE_VFP)) {
254
--- a/target/arm/machine.c
206
+ } else if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
255
+++ b/target/arm/machine.c
207
numvfpregs = 16;
256
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_v8m = {
208
}
257
}
209
for (i = 0; i < numvfpregs; i++) {
258
};
210
diff --git a/target/arm/helper.c b/target/arm/helper.c
259
211
index XXXXXXX..XXXXXXX 100644
260
+static const VMStateDescription vmstate_m_fp = {
212
--- a/target/arm/helper.c
261
+ .name = "cpu/m/fp",
213
+++ b/target/arm/helper.c
262
+ .version_id = 1,
214
@@ -XXX,XX +XXX,XX @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
263
+ .minimum_version_id = 1,
215
* ASEDIS [31] and D32DIS [30] are both UNK/SBZP without VFP.
264
+ .needed = vfp_needed,
216
* TRCDIS [28] is RAZ/WI since we do not implement a trace macrocell.
265
+ .fields = (VMStateField[]) {
217
*/
266
+ VMSTATE_UINT32_ARRAY(env.v7m.fpcar, ARMCPU, M_REG_NUM_BANKS),
218
- if (arm_feature(env, ARM_FEATURE_VFP)) {
267
+ VMSTATE_UINT32_ARRAY(env.v7m.fpccr, ARMCPU, M_REG_NUM_BANKS),
219
+ if (cpu_isar_feature(aa32_vfp_simd, env_archcpu(env))) {
268
+ VMSTATE_UINT32_ARRAY(env.v7m.fpdscr, ARMCPU, M_REG_NUM_BANKS),
220
/* VFP coprocessor: cp10 & cp11 [23:20] */
269
+ VMSTATE_UINT32_ARRAY(env.v7m.cpacr, ARMCPU, M_REG_NUM_BANKS),
221
mask |= (1 << 31) | (1 << 30) | (0xf << 20);
270
+ VMSTATE_UINT32(env.v7m.nsacr, ARMCPU),
222
271
+ VMSTATE_END_OF_LIST()
223
@@ -XXX,XX +XXX,XX @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
272
+ }
224
} else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
273
+};
225
gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
274
+
226
35, "arm-vfp3.xml", 0);
275
static const VMStateDescription vmstate_m = {
227
- } else if (arm_feature(env, ARM_FEATURE_VFP)) {
276
.name = "cpu/m",
228
+ } else if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
277
.version_id = 4,
229
gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
278
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
230
19, "arm-vfp.xml", 0);
279
&vmstate_m_scr,
231
}
280
&vmstate_m_other_sp,
232
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
281
&vmstate_m_v8m,
233
index XXXXXXX..XXXXXXX 100644
282
+ &vmstate_m_fp,
234
--- a/target/arm/m_helper.c
283
NULL
235
+++ b/target/arm/m_helper.c
284
}
236
@@ -XXX,XX +XXX,XX @@ static uint32_t v7m_integrity_sig(CPUARMState *env, uint32_t lr)
285
};
237
*/
238
uint32_t sig = 0xfefa125a;
239
240
- if (!arm_feature(env, ARM_FEATURE_VFP) || (lr & R_V7M_EXCRET_FTYPE_MASK)) {
241
+ if (!cpu_isar_feature(aa32_vfp_simd, env_archcpu(env))
242
+ || (lr & R_V7M_EXCRET_FTYPE_MASK)) {
243
sig |= 1;
244
}
245
return sig;
246
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
247
248
if (dotailchain) {
249
/* Sanitize LR FType and PREFIX bits */
250
- if (!arm_feature(env, ARM_FEATURE_VFP)) {
251
+ if (!cpu_isar_feature(aa32_vfp_simd, cpu)) {
252
lr |= R_V7M_EXCRET_FTYPE_MASK;
253
}
254
lr = deposit32(lr, 24, 8, 0xff);
255
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
256
257
ftype = excret & R_V7M_EXCRET_FTYPE_MASK;
258
259
- if (!arm_feature(env, ARM_FEATURE_VFP) && !ftype) {
260
+ if (!ftype && !cpu_isar_feature(aa32_vfp_simd, cpu)) {
261
qemu_log_mask(LOG_GUEST_ERROR, "M profile: zero FTYPE in exception "
262
"exit PC value 0x%" PRIx32 " is UNPREDICTABLE "
263
"if FPU not present\n",
264
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
265
* SFPA is RAZ/WI from NS. FPCA is RO if NSACR.CP10 == 0,
266
* RES0 if the FPU is not present, and is stored in the S bank
267
*/
268
- if (arm_feature(env, ARM_FEATURE_VFP) &&
269
+ if (cpu_isar_feature(aa32_vfp_simd, env_archcpu(env)) &&
270
extract32(env->v7m.nsacr, 10, 1)) {
271
env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
272
env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK;
273
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
274
env->v7m.control[env->v7m.secure] &= ~R_V7M_CONTROL_NPRIV_MASK;
275
env->v7m.control[env->v7m.secure] |= val & R_V7M_CONTROL_NPRIV_MASK;
276
}
277
- if (arm_feature(env, ARM_FEATURE_VFP)) {
278
+ if (cpu_isar_feature(aa32_vfp_simd, env_archcpu(env))) {
279
/*
280
* SFPA is RAZ/WI from NS or if no FPU.
281
* FPCA is RO if NSACR.CP10 == 0, RES0 if the FPU is not present.
286
--
282
--
287
2.20.1
283
2.20.1
288
284
289
285
diff view generated by jsdifflib
1
The M-profile FPCCR.ASPEN bit indicates that automatic floating-point
1
From: Richard Henderson <richard.henderson@linaro.org>
2
context preservation is enabled. Before executing any floating-point
2
3
instruction, if FPCCR.ASPEN is set and the CONTROL FPCA/SFPA bits
3
The old name, isar_feature_aa32_fpdp, does not reflect
4
indicate that there is no active floating point context then we
4
that the test includes VFPv2. We will introduce another
5
must create a new context (by initializing FPSCR and setting
5
feature tests for VFPv3.
6
FPCA/SFPA to indicate that the context is now active). In the
6
7
pseudocode this is handled by ExecuteFPCheck().
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Implement this with a new TB flag which tracks whether we
9
Message-id: 20200224222232.13807-3-richard.henderson@linaro.org
10
need to create a new FP context.
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190416125744.27770-20-peter.maydell@linaro.org
15
---
11
---
16
target/arm/cpu.h | 2 ++
12
target/arm/cpu.h | 4 ++--
17
target/arm/translate.h | 1 +
13
target/arm/translate-vfp.inc.c | 40 +++++++++++++++++-----------------
18
target/arm/helper.c | 13 +++++++++++++
14
2 files changed, 22 insertions(+), 22 deletions(-)
19
target/arm/translate.c | 29 +++++++++++++++++++++++++++++
20
4 files changed, 45 insertions(+)
21
15
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
18
--- a/target/arm/cpu.h
25
+++ b/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
26
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
20
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fpshvec(const ARMISARegisters *id)
27
FIELD(TBFLAG_A32, VFPEN, 7, 1)
21
return FIELD_EX32(id->mvfr0, MVFR0, FPSHVEC) > 0;
28
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
22
}
29
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
23
30
+/* For M profile only, set if we must create a new FP context */
24
-static inline bool isar_feature_aa32_fpdp(const ARMISARegisters *id)
31
+FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
25
+static inline bool isar_feature_aa32_fpdp_v2(const ARMISARegisters *id)
32
/* For M profile only, set if FPCCR.S does not match current security state */
26
{
33
FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
27
- /* Return true if CPU supports double precision floating point */
34
/* For M profile only, Handler (ie not Thread) mode */
28
+ /* Return true if CPU supports double precision floating point, VFPv2 */
35
diff --git a/target/arm/translate.h b/target/arm/translate.h
29
return FIELD_EX32(id->mvfr0, MVFR0, FPDP) > 0;
30
}
31
32
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
36
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/translate.h
34
--- a/target/arm/translate-vfp.inc.c
38
+++ b/target/arm/translate.h
35
+++ b/target/arm/translate-vfp.inc.c
39
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
40
bool v8m_secure; /* true if v8M and we're in Secure mode */
37
return false;
41
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
38
}
42
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
39
43
+ bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
40
- if (dp && !dc_isar_feature(aa32_fpdp, s)) {
44
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
41
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
45
* so that top level loop can generate correct syndrome information.
42
return false;
46
*/
43
}
47
diff --git a/target/arm/helper.c b/target/arm/helper.c
44
48
index XXXXXXX..XXXXXXX 100644
45
@@ -XXX,XX +XXX,XX @@ static bool trans_VMINMAXNM(DisasContext *s, arg_VMINMAXNM *a)
49
--- a/target/arm/helper.c
46
return false;
50
+++ b/target/arm/helper.c
47
}
51
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
48
52
flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
49
- if (dp && !dc_isar_feature(aa32_fpdp, s)) {
53
}
50
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
54
51
return false;
55
+ if (arm_feature(env, ARM_FEATURE_M) &&
52
}
56
+ (env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) &&
53
57
+ (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) ||
54
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
58
+ (env->v7m.secure &&
55
return false;
59
+ !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)))) {
56
}
60
+ /*
57
61
+ * ASPEN is set, but FPCA/SFPA indicate that there is no active
58
- if (dp && !dc_isar_feature(aa32_fpdp, s)) {
62
+ * FP context; we must create a new FP context before executing
59
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
63
+ * any FP insn.
60
return false;
64
+ */
61
}
65
+ flags = FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED, 1);
62
66
+ }
63
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
67
+
64
return false;
68
*pflags = flags;
65
}
69
*cs_base = 0;
66
70
}
67
- if (dp && !dc_isar_feature(aa32_fpdp, s)) {
71
diff --git a/target/arm/translate.c b/target/arm/translate.c
68
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
72
index XXXXXXX..XXXXXXX 100644
69
return false;
73
--- a/target/arm/translate.c
70
}
74
+++ b/target/arm/translate.c
71
75
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
72
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
76
/* Don't need to do this for any further FP insns in this TB */
73
return false;
77
s->v8m_fpccr_s_wrong = false;
74
}
78
}
75
79
+
76
- if (!dc_isar_feature(aa32_fpdp, s)) {
80
+ if (s->v7m_new_fp_ctxt_needed) {
77
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
81
+ /*
78
return false;
82
+ * Create new FP context by updating CONTROL.FPCA, CONTROL.SFPA
79
}
83
+ * and the FPSCR.
80
84
+ */
81
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
85
+ TCGv_i32 control, fpscr;
82
return false;
86
+ uint32_t bits = R_V7M_CONTROL_FPCA_MASK;
83
}
87
+
84
88
+ fpscr = load_cpu_field(v7m.fpdscr[s->v8m_secure]);
85
- if (!dc_isar_feature(aa32_fpdp, s)) {
89
+ gen_helper_vfp_set_fpscr(cpu_env, fpscr);
86
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
90
+ tcg_temp_free_i32(fpscr);
87
return false;
91
+ /*
88
}
92
+ * We don't need to arrange to end the TB, because the only
89
93
+ * parts of FPSCR which we cache in the TB flags are the VECLEN
90
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
94
+ * and VECSTRIDE, and those don't exist for M-profile.
91
return false;
95
+ */
92
}
96
+
93
97
+ if (s->v8m_secure) {
94
- if (!dc_isar_feature(aa32_fpdp, s)) {
98
+ bits |= R_V7M_CONTROL_SFPA_MASK;
95
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
99
+ }
96
return false;
100
+ control = load_cpu_field(v7m.control[M_REG_S]);
97
}
101
+ tcg_gen_ori_i32(control, control, bits);
98
102
+ store_cpu_field(control, v7m.control[M_REG_S]);
99
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
103
+ /* Don't need to do this for any further FP insns in this TB */
100
return false;
104
+ s->v7m_new_fp_ctxt_needed = false;
101
}
105
+ }
102
106
}
103
- if (!dc_isar_feature(aa32_fpdp, s)) {
107
104
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
108
if (extract32(insn, 28, 4) == 0xf) {
105
return false;
109
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
106
}
110
regime_is_secure(env, dc->mmu_idx);
107
111
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
108
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
112
dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
109
return false;
113
+ dc->v7m_new_fp_ctxt_needed =
110
}
114
+ FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
111
115
dc->cp_regs = cpu->cp_regs;
112
- if (!dc_isar_feature(aa32_fpdp, s)) {
116
dc->features = env->features;
113
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
114
return false;
115
}
116
117
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
118
return false;
119
}
120
121
- if (!dc_isar_feature(aa32_fpdp, s)) {
122
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
123
return false;
124
}
125
126
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
127
return false;
128
}
129
130
- if (!dc_isar_feature(aa32_fpdp, s)) {
131
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
132
return false;
133
}
134
135
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
136
return false;
137
}
138
139
- if (!dc_isar_feature(aa32_fpdp, s)) {
140
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
141
return false;
142
}
143
144
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
145
return false;
146
}
147
148
- if (!dc_isar_feature(aa32_fpdp, s)) {
149
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
150
return false;
151
}
152
153
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
154
return false;
155
}
156
157
- if (!dc_isar_feature(aa32_fpdp, s)) {
158
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
159
return false;
160
}
161
162
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
163
return false;
164
}
165
166
- if (!dc_isar_feature(aa32_fpdp, s)) {
167
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
168
return false;
169
}
170
171
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
172
return false;
173
}
174
175
- if (!dc_isar_feature(aa32_fpdp, s)) {
176
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
177
return false;
178
}
179
180
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
181
return false;
182
}
183
184
- if (!dc_isar_feature(aa32_fpdp, s)) {
185
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
186
return false;
187
}
188
189
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
190
return false;
191
}
192
193
- if (!dc_isar_feature(aa32_fpdp, s)) {
194
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
195
return false;
196
}
197
198
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
199
return false;
200
}
201
202
- if (!dc_isar_feature(aa32_fpdp, s)) {
203
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
204
return false;
205
}
206
207
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
208
return false;
209
}
210
211
- if (!dc_isar_feature(aa32_fpdp, s)) {
212
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
213
return false;
214
}
117
215
118
--
216
--
119
2.20.1
217
2.20.1
120
218
121
219
diff view generated by jsdifflib
1
The M-profile architecture floating point system supports
1
From: Richard Henderson <richard.henderson@linaro.org>
2
lazy FP state preservation, where FP registers are not
3
pushed to the stack when an exception occurs but are instead
4
only saved if and when the first FP instruction in the exception
5
handler is executed. Implement this in QEMU, corresponding
6
to the check of LSPACT in the pseudocode ExecuteFPCheck().
7
2
3
We will shortly use these to test for VFPv2 and VFPv3
4
in different situations.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200224222232.13807-4-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20190416125744.27770-24-peter.maydell@linaro.org
11
---
10
---
12
target/arm/cpu.h | 3 ++
11
target/arm/cpu.h | 18 ++++++++++++++++++
13
target/arm/helper.h | 2 +
12
1 file changed, 18 insertions(+)
14
target/arm/translate.h | 1 +
15
target/arm/helper.c | 112 +++++++++++++++++++++++++++++++++++++++++
16
target/arm/translate.c | 22 ++++++++
17
5 files changed, 140 insertions(+)
18
13
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
16
--- a/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fpshvec(const ARMISARegisters *id)
24
#define EXCP_NOCP 17 /* v7M NOCP UsageFault */
19
return FIELD_EX32(id->mvfr0, MVFR0, FPSHVEC) > 0;
25
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
26
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
27
+#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
28
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
29
30
#define ARMV7M_EXCP_RESET 1
31
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
32
FIELD(TBFLAG_A32, VFPEN, 7, 1)
33
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
34
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
35
+/* For M profile only, set if FPCCR.LSPACT is set */
36
+FIELD(TBFLAG_A32, LSPACT, 18, 1)
37
/* For M profile only, set if we must create a new FP context */
38
FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
39
/* For M profile only, set if FPCCR.S does not match current security state */
40
diff --git a/target/arm/helper.h b/target/arm/helper.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/helper.h
43
+++ b/target/arm/helper.h
44
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(v7m_blxns, void, env, i32)
45
46
DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
47
48
+DEF_HELPER_1(v7m_preserve_fp_state, void, env)
49
+
50
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
51
52
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
53
diff --git a/target/arm/translate.h b/target/arm/translate.h
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/translate.h
56
+++ b/target/arm/translate.h
57
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
58
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
59
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
60
bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
61
+ bool v7m_lspact; /* FPCCR.LSPACT set */
62
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
63
* so that top level loop can generate correct syndrome information.
64
*/
65
diff --git a/target/arm/helper.c b/target/arm/helper.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/helper.c
68
+++ b/target/arm/helper.c
69
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
70
g_assert_not_reached();
71
}
20
}
72
21
73
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
22
+static inline bool isar_feature_aa32_fpsp_v2(const ARMISARegisters *id)
74
+{
23
+{
75
+ /* translate.c should never generate calls here in user-only mode */
24
+ /* Return true if CPU supports single precision floating point, VFPv2 */
76
+ g_assert_not_reached();
25
+ return FIELD_EX32(id->mvfr0, MVFR0, FPSP) > 0;
77
+}
26
+}
78
+
27
+
79
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
28
+static inline bool isar_feature_aa32_fpsp_v3(const ARMISARegisters *id)
80
{
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
+{
29
+{
88
+ /*
30
+ /* Return true if CPU supports single precision floating point, VFPv3 */
89
+ * Preserve FP state (because LSPACT was set and we are about
31
+ return FIELD_EX32(id->mvfr0, MVFR0, FPSP) >= 2;
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
+ }
117
+
118
+ if (!splimviol && stacked_ok) {
119
+ /* We only stack if the stack limit wasn't violated */
120
+ int i;
121
+ ARMMMUIdx mmu_idx;
122
+
123
+ mmu_idx = arm_v7m_mmu_idx_all(env, is_secure, is_priv, negpri);
124
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
125
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
126
+ uint32_t faddr = fpcar + 4 * i;
127
+ uint32_t slo = extract64(dn, 0, 32);
128
+ uint32_t shi = extract64(dn, 32, 32);
129
+
130
+ if (i >= 16) {
131
+ faddr += 8; /* skip the slot for the FPSCR */
132
+ }
133
+ stacked_ok = stacked_ok &&
134
+ v7m_stack_write(cpu, faddr, slo, mmu_idx, STACK_LAZYFP) &&
135
+ v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, STACK_LAZYFP);
136
+ }
137
+
138
+ stacked_ok = stacked_ok &&
139
+ v7m_stack_write(cpu, fpcar + 0x40,
140
+ vfp_get_fpscr(env), mmu_idx, STACK_LAZYFP);
141
+ }
142
+
143
+ /*
144
+ * We definitely pended an exception, but it's possible that it
145
+ * might not be able to be taken now. If its priority permits us
146
+ * to take it now, then we must not update the LSPACT or FP regs,
147
+ * but instead jump out to take the exception immediately.
148
+ * If it's just pending and won't be taken until the current
149
+ * handler exits, then we do update LSPACT and the FP regs.
150
+ */
151
+ take_exception = !stacked_ok &&
152
+ armv7m_nvic_can_take_pending_exception(env->nvic);
153
+
154
+ qemu_mutex_unlock_iothread();
155
+
156
+ if (take_exception) {
157
+ raise_exception_ra(env, EXCP_LAZYFP, 0, 1, GETPC());
158
+ }
159
+
160
+ env->v7m.fpccr[is_secure] &= ~R_V7M_FPCCR_LSPACT_MASK;
161
+
162
+ if (ts) {
163
+ /* Clear s0 to s31 and the FPSCR */
164
+ int i;
165
+
166
+ for (i = 0; i < 32; i += 2) {
167
+ *aa32_vfp_dreg(env, i / 2) = 0;
168
+ }
169
+ vfp_set_fpscr(env, 0);
170
+ }
171
+ /*
172
+ * Otherwise s0 to s15 and FPSCR are UNKNOWN; we choose to leave them
173
+ * unchanged.
174
+ */
175
+}
32
+}
176
+
33
+
177
/* Write to v7M CONTROL.SPSEL bit for the specified security bank.
34
static inline bool isar_feature_aa32_fpdp_v2(const ARMISARegisters *id)
178
* This may change the current stack pointer between Main and Process
35
{
179
* stack pointers if it is done for the CONTROL register for the current
36
/* Return true if CPU supports double precision floating point, VFPv2 */
180
@@ -XXX,XX +XXX,XX @@ static void arm_log_exception(int idx)
37
return FIELD_EX32(id->mvfr0, MVFR0, FPDP) > 0;
181
[EXCP_NOCP] = "v7M NOCP UsageFault",
38
}
182
[EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
39
183
[EXCP_STKOF] = "v8M STKOF UsageFault",
40
+static inline bool isar_feature_aa32_fpdp_v3(const ARMISARegisters *id)
184
+ [EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
41
+{
185
};
42
+ /* Return true if CPU supports double precision floating point, VFPv3 */
186
43
+ return FIELD_EX32(id->mvfr0, MVFR0, FPDP) >= 2;
187
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
44
+}
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
+
45
+
208
+ if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) {
46
/*
209
+ flags = FIELD_DP32(flags, TBFLAG_A32, LSPACT, 1);
47
* We always set the FP and SIMD FP16 fields to indicate identical
210
+ }
48
* levels of support (assuming SIMD is implemented at all), so
211
+ }
212
+
213
*pflags = flags;
214
*cs_base = 0;
215
}
216
diff --git a/target/arm/translate.c b/target/arm/translate.c
217
index XXXXXXX..XXXXXXX 100644
218
--- a/target/arm/translate.c
219
+++ b/target/arm/translate.c
220
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
221
if (arm_dc_feature(s, ARM_FEATURE_M)) {
222
/* Handle M-profile lazy FP state mechanics */
223
224
+ /* Trigger lazy-state preservation if necessary */
225
+ if (s->v7m_lspact) {
226
+ /*
227
+ * Lazy state saving affects external memory and also the NVIC,
228
+ * so we must mark it as an IO operation for icount.
229
+ */
230
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
231
+ gen_io_start();
232
+ }
233
+ gen_helper_v7m_preserve_fp_state(cpu_env);
234
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
235
+ gen_io_end();
236
+ }
237
+ /*
238
+ * If the preserve_fp_state helper doesn't throw an exception
239
+ * then it will clear LSPACT; we don't need to repeat this for
240
+ * any further FP insns in this TB.
241
+ */
242
+ s->v7m_lspact = false;
243
+ }
244
+
245
/* Update ownership of FP context: set FPCCR.S to match current state */
246
if (s->v8m_fpccr_s_wrong) {
247
TCGv_i32 tmp;
248
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
249
dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
250
dc->v7m_new_fp_ctxt_needed =
251
FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
252
+ dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_A32, LSPACT);
253
dc->cp_regs = cpu->cp_regs;
254
dc->features = env->features;
255
256
--
49
--
257
2.20.1
50
2.20.1
258
51
259
52
diff view generated by jsdifflib
1
Implement the code which updates the FPCCR register on an
1
From: Richard Henderson <richard.henderson@linaro.org>
2
exception entry where we are going to use lazy FP stacking.
3
We have to defer to the NVIC to determine whether the
4
various exceptions are currently ready or not.
5
2
3
We cannot easily create "any" functions for these, because the
4
ID_AA64PFR0 fields for FP and SIMD signal "enabled" with zero.
5
Which means that an aarch32-only cpu will return incorrect results
6
when testing the aarch64 registers.
7
8
To use these, we must either have context or additionally test
9
vs ARM_FEATURE_AARCH64.
10
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20200224222232.13807-5-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20190416125744.27770-12-peter.maydell@linaro.org
8
---
15
---
9
target/arm/cpu.h | 14 +++++++++
16
target/arm/cpu.h | 11 +++++++++++
10
hw/intc/armv7m_nvic.c | 34 ++++++++++++++++++++++
17
target/arm/cpu.c | 9 ++++++---
11
target/arm/helper.c | 67 ++++++++++++++++++++++++++++++++++++++++++-
18
target/arm/machine.c | 5 +++--
12
3 files changed, 114 insertions(+), 1 deletion(-)
19
3 files changed, 20 insertions(+), 5 deletions(-)
13
20
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
23
--- a/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
24
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_acknowledge_irq(void *opaque);
25
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fpdp_v3(const ARMISARegisters *id)
19
* (Ignoring -1, this is the same as the RETTOBASE value before completion.)
26
return FIELD_EX32(id->mvfr0, MVFR0, FPDP) >= 2;
20
*/
21
int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure);
22
+/**
23
+ * armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
24
+ * @opaque: the NVIC
25
+ * @irq: the exception number to mark pending
26
+ * @secure: false for non-banked exceptions or for the nonsecure
27
+ * version of a banked exception, true for the secure version of a banked
28
+ * exception.
29
+ *
30
+ * Return whether an exception is "ready", i.e. whether the exception is
31
+ * enabled and is configured at a priority which would allow it to
32
+ * interrupt the current execution priority. This controls whether the
33
+ * RDY bit for it in the FPCCR is set.
34
+ */
35
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure);
36
/**
37
* armv7m_nvic_raw_execution_priority: return the raw execution priority
38
* @opaque: the NVIC
39
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/intc/armv7m_nvic.c
42
+++ b/hw/intc/armv7m_nvic.c
43
@@ -XXX,XX +XXX,XX @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
44
return ret;
45
}
27
}
46
28
47
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
29
+static inline bool isar_feature_aa32_vfp(const ARMISARegisters *id)
48
+{
30
+{
49
+ /*
31
+ return isar_feature_aa32_fpsp_v2(id) || isar_feature_aa32_fpdp_v2(id);
50
+ * Return whether an exception is "ready", i.e. it is enabled and is
51
+ * configured at a priority which would allow it to interrupt the
52
+ * current execution priority.
53
+ *
54
+ * irq and secure have the same semantics as for armv7m_nvic_set_pending():
55
+ * for non-banked exceptions secure is always false; for banked exceptions
56
+ * it indicates which of the exceptions is required.
57
+ */
58
+ NVICState *s = (NVICState *)opaque;
59
+ bool banked = exc_is_banked(irq);
60
+ VecInfo *vec;
61
+ int running = nvic_exec_prio(s);
62
+
63
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
64
+ assert(!secure || banked);
65
+
66
+ /*
67
+ * HardFault is an odd special case: we always check against -1,
68
+ * even if we're secure and HardFault has priority -3; we never
69
+ * need to check for enabled state.
70
+ */
71
+ if (irq == ARMV7M_EXCP_HARD) {
72
+ return running > -1;
73
+ }
74
+
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
76
+
77
+ return vec->enabled &&
78
+ exc_group_prio(s, vec->prio, secure) < running;
79
+}
32
+}
80
+
33
+
81
/* callback when external interrupt line is changed */
34
/*
82
static void set_irq_level(void *opaque, int n, int level)
35
* We always set the FP and SIMD FP16 fields to indicate identical
83
{
36
* levels of support (assuming SIMD is implemented at all), so
84
diff --git a/target/arm/helper.c b/target/arm/helper.c
37
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_dcpodp(const ARMISARegisters *id)
85
index XXXXXXX..XXXXXXX 100644
38
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) >= 2;
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
}
39
}
91
40
92
+static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
41
+static inline bool isar_feature_aa64_fp_simd(const ARMISARegisters *id)
93
+ bool apply_splim)
94
+{
42
+{
95
+ /*
43
+ /* We always set the AdvSIMD and FP fields identically. */
96
+ * Like the pseudocode UpdateFPCCR: save state in FPCAR and FPCCR
44
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) != 0xf;
97
+ * that we will need later in order to do lazy FP reg stacking.
98
+ */
99
+ bool is_secure = env->v7m.secure;
100
+ void *nvic = env->nvic;
101
+ /*
102
+ * Some bits are unbanked and live always in fpccr[M_REG_S]; some bits
103
+ * are banked and we want to update the bit in the bank for the
104
+ * current security state; and in one case we want to specifically
105
+ * update the NS banked version of a bit even if we are secure.
106
+ */
107
+ uint32_t *fpccr_s = &env->v7m.fpccr[M_REG_S];
108
+ uint32_t *fpccr_ns = &env->v7m.fpccr[M_REG_NS];
109
+ uint32_t *fpccr = &env->v7m.fpccr[is_secure];
110
+ bool hfrdy, bfrdy, mmrdy, ns_ufrdy, s_ufrdy, sfrdy, monrdy;
111
+
112
+ env->v7m.fpcar[is_secure] = frameptr & ~0x7;
113
+
114
+ if (apply_splim && arm_feature(env, ARM_FEATURE_V8)) {
115
+ bool splimviol;
116
+ uint32_t splim = v7m_sp_limit(env);
117
+ bool ign = armv7m_nvic_neg_prio_requested(nvic, is_secure) &&
118
+ (env->v7m.ccr[is_secure] & R_V7M_CCR_STKOFHFNMIGN_MASK);
119
+
120
+ splimviol = !ign && frameptr < splim;
121
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, SPLIMVIOL, splimviol);
122
+ }
123
+
124
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, LSPACT, 1);
125
+
126
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, S, is_secure);
127
+
128
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, USER, arm_current_el(env) == 0);
129
+
130
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, THREAD,
131
+ !arm_v7m_is_handler_mode(env));
132
+
133
+ hfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_HARD, false);
134
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, HFRDY, hfrdy);
135
+
136
+ bfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_BUS, false);
137
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, BFRDY, bfrdy);
138
+
139
+ mmrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_MEM, is_secure);
140
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, MMRDY, mmrdy);
141
+
142
+ ns_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, false);
143
+ *fpccr_ns = FIELD_DP32(*fpccr_ns, V7M_FPCCR, UFRDY, ns_ufrdy);
144
+
145
+ monrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_DEBUG, false);
146
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, MONRDY, monrdy);
147
+
148
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
149
+ s_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, true);
150
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, UFRDY, s_ufrdy);
151
+
152
+ sfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_SECURE, false);
153
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, SFRDY, sfrdy);
154
+ }
155
+}
45
+}
156
+
46
+
157
static bool v7m_push_stack(ARMCPU *cpu)
47
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
158
{
48
{
159
/* Do the "set up stack frame" part of exception entry,
49
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
160
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
50
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
161
}
51
index XXXXXXX..XXXXXXX 100644
162
} else {
52
--- a/target/arm/cpu.c
163
/* Lazy stacking enabled, save necessary info to stack later */
53
+++ b/target/arm/cpu.c
164
- /* TODO : equivalent of UpdateFPCCR() pseudocode */
54
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
165
+ v7m_update_fpccr(env, frameptr + 0x20, true);
55
* KVM does not currently allow us to lie to the guest about its
166
}
56
* ID/feature registers, so the guest always sees what the host has.
167
}
57
*/
168
}
58
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
59
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)
60
+ ? cpu_isar_feature(aa64_fp_simd, cpu)
61
+ : cpu_isar_feature(aa32_vfp, cpu)) {
62
cpu->has_vfp = true;
63
if (!kvm_enabled()) {
64
qdev_property_add_static(DEVICE(obj), &arm_cpu_has_vfp_property);
65
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
66
* We rely on no XScale CPU having VFP so we can use the same bits in the
67
* TB flags field for VECSTRIDE and XSCALE_CPAR.
68
*/
69
- assert(!(arm_feature(env, ARM_FEATURE_VFP) &&
70
- arm_feature(env, ARM_FEATURE_XSCALE)));
71
+ assert(arm_feature(&cpu->env, ARM_FEATURE_AARCH64) ||
72
+ !cpu_isar_feature(aa32_vfp_simd, cpu) ||
73
+ !arm_feature(env, ARM_FEATURE_XSCALE));
74
75
if (arm_feature(env, ARM_FEATURE_V7) &&
76
!arm_feature(env, ARM_FEATURE_M) &&
77
diff --git a/target/arm/machine.c b/target/arm/machine.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/machine.c
80
+++ b/target/arm/machine.c
81
@@ -XXX,XX +XXX,XX @@
82
static bool vfp_needed(void *opaque)
83
{
84
ARMCPU *cpu = opaque;
85
- CPUARMState *env = &cpu->env;
86
87
- return arm_feature(env, ARM_FEATURE_VFP);
88
+ return (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)
89
+ ? cpu_isar_feature(aa64_fp_simd, cpu)
90
+ : cpu_isar_feature(aa32_vfp_simd, cpu));
91
}
92
93
static int get_fpscr(QEMUFile *f, void *opaque, size_t size,
169
--
94
--
170
2.20.1
95
2.20.1
171
96
172
97
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
Shuffle the order of the checks so that we test the ISA
4
Reviewed-by: Cédric Le Goater <clg@kaod.org>
4
before we test anything else, such as the register arguments.
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20190412165416.7977-2-philmd@redhat.com
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200224222232.13807-7-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
hw/arm/aspeed.c | 13 +++++++++----
11
target/arm/translate-vfp.inc.c | 140 +++++++++++++++++----------------
11
1 file changed, 9 insertions(+), 4 deletions(-)
12
1 file changed, 71 insertions(+), 69 deletions(-)
12
13
13
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
14
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/aspeed.c
16
--- a/target/arm/translate-vfp.inc.c
16
+++ b/hw/arm/aspeed.c
17
+++ b/target/arm/translate-vfp.inc.c
17
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
18
#include "hw/arm/aspeed_soc.h"
19
return false;
19
#include "hw/boards.h"
20
}
20
#include "hw/i2c/smbus_eeprom.h"
21
21
+#include "hw/misc/pca9552.h"
22
- /* UNDEF accesses to D16-D31 if they don't exist */
22
+#include "hw/misc/tmp105.h"
23
- if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
23
#include "qemu/log.h"
24
- ((a->vm | a->vn | a->vd) & 0x10)) {
24
#include "sysemu/block-backend.h"
25
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
25
#include "hw/loader.h"
26
return false;
26
@@ -XXX,XX +XXX,XX @@ static void ast2500_evb_i2c_init(AspeedBoardState *bmc)
27
}
27
eeprom_buf);
28
28
29
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
29
/* The AST2500 EVB expects a LM75 but a TMP105 is compatible */
30
+ /* UNDEF accesses to D16-D31 if they don't exist */
30
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7), "tmp105", 0x4d);
31
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
31
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7),
32
+ ((a->vm | a->vn | a->vd) & 0x10)) {
32
+ TYPE_TMP105, 0x4d);
33
return false;
33
34
}
34
/* The AST2500 EVB does not have an RTC. Let's pretend that one is
35
35
* plugged on the I2C bus header */
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VMINMAXNM(DisasContext *s, arg_VMINMAXNM *a)
36
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
37
return false;
37
AspeedSoCState *soc = &bmc->soc;
38
}
38
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
39
39
40
- /* UNDEF accesses to D16-D31 if they don't exist */
40
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), "pca9552", 0x60);
41
- if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
41
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), TYPE_PCA9552,
42
- ((a->vm | a->vn | a->vd) & 0x10)) {
42
+ 0x60);
43
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
43
44
return false;
44
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), "tmp423", 0x4c);
45
}
45
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 5), "tmp423", 0x4c);
46
46
47
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
47
/* The Witherspoon expects a TMP275 but a TMP105 is compatible */
48
+ /* UNDEF accesses to D16-D31 if they don't exist */
48
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), "tmp105", 0x4a);
49
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
49
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), TYPE_TMP105,
50
+ ((a->vm | a->vn | a->vd) & 0x10)) {
50
+ 0x4a);
51
return false;
51
52
}
52
/* The witherspoon board expects Epson RX8900 I2C RTC but a ds1338 is
53
53
* good enough */
54
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
54
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
55
return false;
55
56
}
56
smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), 0x51,
57
57
eeprom_buf);
58
- /* UNDEF accesses to D16-D31 if they don't exist */
58
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "pca9552",
59
- if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
59
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), TYPE_PCA9552,
60
- ((a->vm | a->vd) & 0x10)) {
60
0x60);
61
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
61
}
62
return false;
63
}
64
65
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
66
+ /* UNDEF accesses to D16-D31 if they don't exist */
67
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
68
+ ((a->vm | a->vd) & 0x10)) {
69
return false;
70
}
71
72
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
73
return false;
74
}
75
76
- /* UNDEF accesses to D16-D31 if they don't exist */
77
- if (dp && !dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
78
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
79
return false;
80
}
81
82
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
83
+ /* UNDEF accesses to D16-D31 if they don't exist */
84
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
85
return false;
86
}
87
88
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
89
TCGv_i64 f0, f1, fd;
90
TCGv_ptr fpst;
91
92
- /* UNDEF accesses to D16-D31 if they don't exist */
93
- if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vn | vm) & 0x10)) {
94
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
95
return false;
96
}
97
98
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
99
+ /* UNDEF accesses to D16-D31 if they don't exist */
100
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vn | vm) & 0x10)) {
101
return false;
102
}
103
104
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
105
int veclen = s->vec_len;
106
TCGv_i64 f0, fd;
107
108
- /* UNDEF accesses to D16-D31 if they don't exist */
109
- if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vm) & 0x10)) {
110
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
111
return false;
112
}
113
114
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
115
+ /* UNDEF accesses to D16-D31 if they don't exist */
116
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vm) & 0x10)) {
117
return false;
118
}
119
120
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
121
return false;
122
}
123
124
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
125
+ /* UNDEF accesses to D16-D31 if they don't exist. */
126
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
127
+ ((a->vd | a->vn | a->vm) & 0x10)) {
128
return false;
129
}
130
131
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
132
133
vd = a->vd;
134
135
- /* UNDEF accesses to D16-D31 if they don't exist. */
136
- if (!dc_isar_feature(aa32_simd_r32, s) && (vd & 0x10)) {
137
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
138
return false;
139
}
140
141
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
142
+ /* UNDEF accesses to D16-D31 if they don't exist. */
143
+ if (!dc_isar_feature(aa32_simd_r32, s) && (vd & 0x10)) {
144
return false;
145
}
146
147
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
148
{
149
TCGv_i64 vd, vm;
150
151
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
152
+ return false;
153
+ }
154
+
155
/* Vm/M bits must be zero for the Z variant */
156
if (a->z && a->vm != 0) {
157
return false;
158
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
159
return false;
160
}
161
162
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
163
- return false;
164
- }
165
-
166
if (!vfp_access_check(s)) {
167
return true;
168
}
169
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
170
TCGv_i32 tmp;
171
TCGv_i64 vd;
172
173
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
174
+ return false;
175
+ }
176
+
177
if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
178
return false;
179
}
180
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
181
return false;
182
}
183
184
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
185
- return false;
186
- }
187
-
188
if (!vfp_access_check(s)) {
189
return true;
190
}
191
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
192
TCGv_i32 tmp;
193
TCGv_i64 vm;
194
195
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
196
+ return false;
197
+ }
198
+
199
if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
200
return false;
201
}
202
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
203
return false;
204
}
205
206
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
207
- return false;
208
- }
209
-
210
if (!vfp_access_check(s)) {
211
return true;
212
}
213
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
214
TCGv_ptr fpst;
215
TCGv_i64 tmp;
216
217
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
218
+ return false;
219
+ }
220
+
221
if (!dc_isar_feature(aa32_vrint, s)) {
222
return false;
223
}
224
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
225
return false;
226
}
227
228
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
229
- return false;
230
- }
231
-
232
if (!vfp_access_check(s)) {
233
return true;
234
}
235
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
236
TCGv_i64 tmp;
237
TCGv_i32 tcg_rmode;
238
239
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
240
+ return false;
241
+ }
242
+
243
if (!dc_isar_feature(aa32_vrint, s)) {
244
return false;
245
}
246
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
247
return false;
248
}
249
250
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
251
- return false;
252
- }
253
-
254
if (!vfp_access_check(s)) {
255
return true;
256
}
257
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
258
TCGv_ptr fpst;
259
TCGv_i64 tmp;
260
261
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
262
+ return false;
263
+ }
264
+
265
if (!dc_isar_feature(aa32_vrint, s)) {
266
return false;
267
}
268
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
269
return false;
270
}
271
272
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
273
- return false;
274
- }
275
-
276
if (!vfp_access_check(s)) {
277
return true;
278
}
279
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
280
TCGv_i64 vd;
281
TCGv_i32 vm;
282
283
- /* UNDEF accesses to D16-D31 if they don't exist. */
284
- if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
285
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
286
return false;
287
}
288
289
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
290
+ /* UNDEF accesses to D16-D31 if they don't exist. */
291
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
292
return false;
293
}
294
295
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
296
TCGv_i64 vm;
297
TCGv_i32 vd;
298
299
- /* UNDEF accesses to D16-D31 if they don't exist. */
300
- if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
301
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
302
return false;
303
}
304
305
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
306
+ /* UNDEF accesses to D16-D31 if they don't exist. */
307
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
308
return false;
309
}
310
311
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
312
TCGv_i64 vd;
313
TCGv_ptr fpst;
314
315
- /* UNDEF accesses to D16-D31 if they don't exist. */
316
- if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
317
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
318
return false;
319
}
320
321
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
322
+ /* UNDEF accesses to D16-D31 if they don't exist. */
323
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
324
return false;
325
}
326
327
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
328
TCGv_i32 vd;
329
TCGv_i64 vm;
330
331
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
332
+ return false;
333
+ }
334
+
335
if (!dc_isar_feature(aa32_jscvt, s)) {
336
return false;
337
}
338
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
339
return false;
340
}
341
342
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
343
- return false;
344
- }
345
-
346
if (!vfp_access_check(s)) {
347
return true;
348
}
349
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
350
TCGv_ptr fpst;
351
int frac_bits;
352
353
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
354
+ return false;
355
+ }
356
+
357
if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
358
return false;
359
}
360
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
361
return false;
362
}
363
364
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
365
- return false;
366
- }
367
-
368
if (!vfp_access_check(s)) {
369
return true;
370
}
371
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
372
TCGv_i64 vm;
373
TCGv_ptr fpst;
374
375
- /* UNDEF accesses to D16-D31 if they don't exist. */
376
- if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
377
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
378
return false;
379
}
380
381
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
382
+ /* UNDEF accesses to D16-D31 if they don't exist. */
383
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
384
return false;
385
}
62
386
63
--
387
--
64
2.20.1
388
2.20.1
65
389
66
390
diff view generated by jsdifflib
1
The M-profile FPCCR.S bit indicates the security status of
1
From: Richard Henderson <richard.henderson@linaro.org>
2
the floating point context. In the pseudocode ExecuteFPCheck()
3
function it is unconditionally set to match the current
4
security state whenever a floating point instruction is
5
executed.
6
2
7
Implement this by adding a new TB flag which tracks whether
3
Sort this check to the start of a trans_* function.
8
FPCCR.S is different from the current security state, so
4
Merge this with any existing test for fpdp_v2.
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
5
12
Note that we will add the handling for the other work done
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
by ExecuteFPCheck() in later commits.
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200224222232.13807-8-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/translate-vfp.inc.c | 24 ++++++++----------------
12
1 file changed, 8 insertions(+), 16 deletions(-)
14
13
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20190416125744.27770-19-peter.maydell@linaro.org
18
---
19
target/arm/cpu.h | 2 ++
20
target/arm/translate.h | 1 +
21
target/arm/helper.c | 5 +++++
22
target/arm/translate.c | 20 ++++++++++++++++++++
23
4 files changed, 28 insertions(+)
24
25
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
26
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/cpu.h
16
--- a/target/arm/translate-vfp.inc.c
28
+++ b/target/arm/cpu.h
17
+++ b/target/arm/translate-vfp.inc.c
29
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
18
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
30
FIELD(TBFLAG_A32, VFPEN, 7, 1)
19
* VFPv2 allows access to FPSID from userspace; VFPv3 restricts
31
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
20
* all ID registers to privileged access only.
32
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
21
*/
33
+/* For M profile only, set if FPCCR.S does not match current security state */
22
- if (IS_USER(s) && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
34
+FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
23
+ if (IS_USER(s) && dc_isar_feature(aa32_fpsp_v3, s)) {
35
/* For M profile only, Handler (ie not Thread) mode */
24
return false;
36
FIELD(TBFLAG_A32, HANDLER, 21, 1)
25
}
37
/* For M profile only, whether we should generate stack-limit checks */
26
ignore_vfp_enabled = true;
38
diff --git a/target/arm/translate.h b/target/arm/translate.h
27
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
39
index XXXXXXX..XXXXXXX 100644
28
case ARM_VFP_FPINST:
40
--- a/target/arm/translate.h
29
case ARM_VFP_FPINST2:
41
+++ b/target/arm/translate.h
30
/* Not present in VFPv3 */
42
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
31
- if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
43
bool v7m_handler_mode;
32
+ if (IS_USER(s) || dc_isar_feature(aa32_fpsp_v3, s)) {
44
bool v8m_secure; /* true if v8M and we're in Secure mode */
33
return false;
45
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
34
}
46
+ bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
35
break;
47
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
48
* so that top level loop can generate correct syndrome information.
37
49
*/
38
vd = a->vd;
50
diff --git a/target/arm/helper.c b/target/arm/helper.c
39
51
index XXXXXXX..XXXXXXX 100644
40
- if (!dc_isar_feature(aa32_fpshvec, s) &&
52
--- a/target/arm/helper.c
41
- (veclen != 0 || s->vec_stride != 0)) {
53
+++ b/target/arm/helper.c
42
+ if (!dc_isar_feature(aa32_fpsp_v3, s)) {
54
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
43
return false;
55
flags = FIELD_DP32(flags, TBFLAG_A32, STACKCHECK, 1);
56
}
44
}
57
45
58
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
46
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
59
+ FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S) != env->v7m.secure) {
47
+ if (!dc_isar_feature(aa32_fpshvec, s) &&
60
+ flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
48
+ (veclen != 0 || s->vec_stride != 0)) {
61
+ }
49
return false;
62
+
63
*pflags = flags;
64
*cs_base = 0;
65
}
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate.c
69
+++ b/target/arm/translate.c
70
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
71
}
72
}
50
}
73
51
74
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
52
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
75
+ /* Handle M-profile lazy FP state mechanics */
53
76
+
54
vd = a->vd;
77
+ /* Update ownership of FP context: set FPCCR.S to match current state */
55
78
+ if (s->v8m_fpccr_s_wrong) {
56
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
79
+ TCGv_i32 tmp;
57
+ if (!dc_isar_feature(aa32_fpdp_v3, s)) {
80
+
58
return false;
81
+ tmp = load_cpu_field(v7m.fpccr[M_REG_S]);
59
}
82
+ if (s->v8m_secure) {
60
83
+ tcg_gen_ori_i32(tmp, tmp, R_V7M_FPCCR_S_MASK);
61
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
84
+ } else {
62
return false;
85
+ tcg_gen_andi_i32(tmp, tmp, ~R_V7M_FPCCR_S_MASK);
63
}
86
+ }
64
87
+ store_cpu_field(tmp, v7m.fpccr[M_REG_S]);
65
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
88
+ /* Don't need to do this for any further FP insns in this TB */
66
- return false;
89
+ s->v8m_fpccr_s_wrong = false;
67
- }
90
+ }
68
-
91
+ }
69
if (!vfp_access_check(s)) {
92
+
70
return true;
93
if (extract32(insn, 28, 4) == 0xf) {
71
}
94
/*
72
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
95
* Encodings with T=1 (Thumb) or unconditional (ARM):
73
TCGv_ptr fpst;
96
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
74
int frac_bits;
97
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
75
98
regime_is_secure(env, dc->mmu_idx);
76
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
99
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
77
+ if (!dc_isar_feature(aa32_fpsp_v3, s)) {
100
+ dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
78
return false;
101
dc->cp_regs = cpu->cp_regs;
79
}
102
dc->features = env->features;
80
81
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
82
TCGv_ptr fpst;
83
int frac_bits;
84
85
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
86
- return false;
87
- }
88
-
89
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
90
+ if (!dc_isar_feature(aa32_fpdp_v3, s)) {
91
return false;
92
}
103
93
104
--
94
--
105
2.20.1
95
2.20.1
106
96
107
97
diff view generated by jsdifflib
1
Handle floating point registers in exception entry.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
This corresponds to the FP-specific parts of the pseudocode
2
3
functions ActivateException() and PushStack().
3
We will eventually remove the early ARM_FEATURE_VFP test,
4
4
so add a proper test for each trans_* that does not already
5
We defer the code corresponding to UpdateFPCCR() to a later patch.
5
have another ISA test.
6
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200224222232.13807-9-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-11-peter.maydell@linaro.org
10
---
11
---
11
target/arm/helper.c | 98 +++++++++++++++++++++++++++++++++++++++++++--
12
target/arm/translate-vfp.inc.c | 78 ++++++++++++++++++++++++++++++----
12
1 file changed, 95 insertions(+), 3 deletions(-)
13
1 file changed, 69 insertions(+), 9 deletions(-)
13
14
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
--- a/target/arm/translate-vfp.inc.c
17
+++ b/target/arm/helper.c
18
+++ b/target/arm/translate-vfp.inc.c
18
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
19
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
19
switch_v7m_security_state(env, targets_secure);
20
int pass;
20
write_v7m_control_spsel(env, 0);
21
uint32_t offset;
21
arm_clear_exclusive(env);
22
22
+ /* Clear SFPA and FPCA (has no effect if no FPU) */
23
+ /* SIZE == 2 is a VFP instruction; otherwise NEON. */
23
+ env->v7m.control[M_REG_S] &=
24
+ if (a->size == 2
24
+ ~(R_V7M_CONTROL_FPCA_MASK | R_V7M_CONTROL_SFPA_MASK);
25
+ ? !dc_isar_feature(aa32_fpsp_v2, s)
25
/* Clear IT bits */
26
+ : !arm_dc_feature(s, ARM_FEATURE_NEON)) {
26
env->condexec_bits = 0;
27
+ return false;
27
env->regs[14] = lr;
28
+ }
28
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
29
+
29
uint32_t xpsr = xpsr_read(env);
30
/* UNDEF accesses to D16-D31 if they don't exist */
30
uint32_t frameptr = env->regs[13];
31
if (!dc_isar_feature(aa32_simd_r32, s) && (a->vn & 0x10)) {
31
ARMMMUIdx mmu_idx = arm_mmu_idx(env);
32
return false;
32
+ uint32_t framesize;
33
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
33
+ bool nsacr_cp10 = extract32(env->v7m.nsacr, 10, 1);
34
pass = extract32(offset, 2, 1);
34
+
35
offset = extract32(offset, 0, 2) * 8;
35
+ if ((env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) &&
36
36
+ (env->v7m.secure || nsacr_cp10)) {
37
- if (a->size != 2 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
37
+ if (env->v7m.secure &&
38
- return false;
38
+ env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK) {
39
- }
39
+ framesize = 0xa8;
40
-
40
+ } else {
41
if (!vfp_access_check(s)) {
41
+ framesize = 0x68;
42
return true;
42
+ }
43
}
43
+ } else {
44
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
44
+ framesize = 0x20;
45
int pass;
45
+ }
46
uint32_t offset;
46
47
47
/* Align stack pointer if the guest wants that */
48
+ /* SIZE == 2 is a VFP instruction; otherwise NEON. */
48
if ((frameptr & 4) &&
49
+ if (a->size == 2
49
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
50
+ ? !dc_isar_feature(aa32_fpsp_v2, s)
50
xpsr |= XPSR_SPREALIGN;
51
+ : !arm_dc_feature(s, ARM_FEATURE_NEON)) {
51
}
52
+ return false;
52
53
+ }
53
- frameptr -= 0x20;
54
+
54
+ xpsr &= ~XPSR_SFPA;
55
/* UNDEF accesses to D16-D31 if they don't exist */
55
+ if (env->v7m.secure &&
56
if (!dc_isar_feature(aa32_simd_r32, s) && (a->vn & 0x10)) {
56
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
57
return false;
57
+ xpsr |= XPSR_SFPA;
58
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
58
+ }
59
pass = extract32(offset, 2, 1);
59
+
60
offset = extract32(offset, 0, 2) * 8;
60
+ frameptr -= framesize;
61
61
62
- if (a->size != 2 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
62
if (arm_feature(env, ARM_FEATURE_V8)) {
63
- return false;
63
uint32_t limit = v7m_sp_limit(env);
64
- }
64
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
65
-
65
v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
66
if (!vfp_access_check(s)) {
66
v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
67
return true;
67
68
}
68
+ if (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) {
69
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
69
+ /* FPU is active, try to save its registers */
70
TCGv_i32 tmp;
70
+ bool fpccr_s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
71
bool ignore_vfp_enabled = false;
71
+ bool lspact = env->v7m.fpccr[fpccr_s] & R_V7M_FPCCR_LSPACT_MASK;
72
72
+
73
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
73
+ if (lspact && arm_feature(env, ARM_FEATURE_M_SECURITY)) {
74
+ return false;
74
+ qemu_log_mask(CPU_LOG_INT,
75
+ }
75
+ "...SecureFault because LSPACT and FPCA both set\n");
76
+
76
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
77
if (arm_dc_feature(s, ARM_FEATURE_M)) {
77
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
78
/*
78
+ } else if (!env->v7m.secure && !nsacr_cp10) {
79
* The only M-profile VFP vmrs/vmsr sysreg is FPSCR.
79
+ qemu_log_mask(CPU_LOG_INT,
80
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_single(DisasContext *s, arg_VMOV_single *a)
80
+ "...Secure UsageFault with CFSR.NOCP because "
81
{
81
+ "NSACR.CP10 prevents stacking FP regs\n");
82
TCGv_i32 tmp;
82
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
83
83
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
84
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
84
+ } else {
85
+ return false;
85
+ if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) {
86
+ }
86
+ /* Lazy stacking disabled, save registers now */
87
+
87
+ int i;
88
if (!vfp_access_check(s)) {
88
+ bool cpacr_pass = v7m_cpacr_pass(env, env->v7m.secure,
89
return true;
89
+ arm_current_el(env) != 0);
90
}
90
+
91
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_sp(DisasContext *s, arg_VMOV_64_sp *a)
91
+ if (stacked_ok && !cpacr_pass) {
92
{
92
+ /*
93
TCGv_i32 tmp;
93
+ * Take UsageFault if CPACR forbids access. The pseudocode
94
94
+ * here does a full CheckCPEnabled() but we know the NSACR
95
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
95
+ * check can never fail as we have already handled that.
96
+ return false;
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
+ }
97
+ }
134
+
98
+
135
/*
99
/*
136
* If we broke a stack limit then SP was already updated earlier;
100
* VMOV between two general-purpose registers and two single precision
137
* otherwise we update SP regardless of whether any of the stack
101
* floating point registers
138
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
102
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a)
139
103
140
if (arm_feature(env, ARM_FEATURE_V8)) {
104
/*
141
lr = R_V7M_EXCRET_RES1_MASK |
105
* VMOV between two general-purpose registers and one double precision
142
- R_V7M_EXCRET_DCRS_MASK |
106
- * floating point register
143
- R_V7M_EXCRET_FTYPE_MASK;
107
+ * floating point register. Note that this does not require support
144
+ R_V7M_EXCRET_DCRS_MASK;
108
+ * for double precision arithmetic.
145
/* The S bit indicates whether we should return to Secure
109
*/
146
* or NonSecure (ie our current state).
110
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
147
* The ES bit indicates whether we're taking this exception
111
+ return false;
148
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
112
+ }
149
if (env->v7m.secure) {
113
150
lr |= R_V7M_EXCRET_S_MASK;
114
/* UNDEF accesses to D16-D31 if they don't exist */
151
}
115
if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
152
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
116
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
153
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
117
uint32_t offset;
154
+ }
118
TCGv_i32 addr, tmp;
155
} else {
119
156
lr = R_V7M_EXCRET_RES1_MASK |
120
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
157
R_V7M_EXCRET_S_MASK |
121
+ return false;
122
+ }
123
+
124
if (!vfp_access_check(s)) {
125
return true;
126
}
127
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
128
TCGv_i32 addr;
129
TCGv_i64 tmp;
130
131
+ /* Note that this does not require support for double arithmetic. */
132
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
133
+ return false;
134
+ }
135
+
136
/* UNDEF accesses to D16-D31 if they don't exist */
137
if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
138
return false;
139
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_sp(DisasContext *s, arg_VLDM_VSTM_sp *a)
140
TCGv_i32 addr, tmp;
141
int i, n;
142
143
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
144
+ return false;
145
+ }
146
+
147
n = a->imm;
148
149
if (n == 0 || (a->vd + n) > 32) {
150
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a)
151
TCGv_i64 tmp;
152
int i, n;
153
154
+ /* Note that this does not require support for double arithmetic. */
155
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
156
+ return false;
157
+ }
158
+
159
n = a->imm >> 1;
160
161
if (n == 0 || (a->vd + n) > 32 || n > 16) {
162
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_sp(DisasContext *s, VFPGen3OpSPFn *fn,
163
TCGv_i32 f0, f1, fd;
164
TCGv_ptr fpst;
165
166
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
167
+ return false;
168
+ }
169
+
170
if (!dc_isar_feature(aa32_fpshvec, s) &&
171
(veclen != 0 || s->vec_stride != 0)) {
172
return false;
173
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
174
int veclen = s->vec_len;
175
TCGv_i32 f0, fd;
176
177
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
178
+ return false;
179
+ }
180
+
181
if (!dc_isar_feature(aa32_fpshvec, s) &&
182
(veclen != 0 || s->vec_stride != 0)) {
183
return false;
184
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_sp(DisasContext *s, arg_VCMP_sp *a)
185
{
186
TCGv_i32 vd, vm;
187
188
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
189
+ return false;
190
+ }
191
+
192
/* Vm/M bits must be zero for the Z variant */
193
if (a->z && a->vm != 0) {
194
return false;
195
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_sp(DisasContext *s, arg_VCVT_int_sp *a)
196
TCGv_i32 vm;
197
TCGv_ptr fpst;
198
199
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
200
+ return false;
201
+ }
202
+
203
if (!vfp_access_check(s)) {
204
return true;
205
}
206
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp_int(DisasContext *s, arg_VCVT_sp_int *a)
207
TCGv_i32 vm;
208
TCGv_ptr fpst;
209
210
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
211
+ return false;
212
+ }
213
+
214
if (!vfp_access_check(s)) {
215
return true;
216
}
158
--
217
--
159
2.20.1
218
2.20.1
160
219
161
220
diff view generated by jsdifflib
1
We are close to running out of TB flags for AArch32; we could
1
From: Richard Henderson <richard.henderson@linaro.org>
2
start using the cs_base word, but before we do that we can
3
economise on our usage by sharing the same bits for the VFP
4
VECSTRIDE field and the XScale XSCALE_CPAR field. This
5
works because no XScale CPU ever had VFP.
6
2
3
All remaining tests for VFP4 are for fused multiply-add insns.
4
5
Since the MVFR1 field is used for both VFP and NEON, move its adjustment
6
from the !has_neon block to the (!has_vfp && !has_neon) block.
7
8
Test for vfp of the appropraite width alongside the test for simdfmac
9
within translate-vfp.inc.c. Within disas_neon_data_insn, we have
10
already tested for ARM_FEATURE_NEON.
11
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 20200224222232.13807-10-richard.henderson@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-18-peter.maydell@linaro.org
10
---
16
---
11
target/arm/cpu.h | 10 ++++++----
17
target/arm/cpu.h | 12 ++++++++++++
12
target/arm/cpu.c | 7 +++++++
18
target/arm/cpu.c | 6 +++++-
13
target/arm/helper.c | 6 +++++-
19
target/arm/translate-vfp.inc.c | 22 ++++++++++++++++++----
14
target/arm/translate.c | 9 +++++++--
20
target/arm/translate.c | 2 +-
15
4 files changed, 25 insertions(+), 7 deletions(-)
21
4 files changed, 36 insertions(+), 6 deletions(-)
16
22
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
25
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
26
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
27
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fp16_dpconv(const ARMISARegisters *id)
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
28
return FIELD_EX32(id->mvfr1, MVFR1, FPHP) > 1;
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
29
}
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
30
25
+/*
31
+/*
26
+ * We store the bottom two bits of the CPAR as TB flags and handle
32
+ * Note that this ID register field covers both VFP and Neon FMAC,
27
+ * checks on the other bits at runtime. This shares the same bits as
33
+ * so should usually be tested in combination with some other
28
+ * VECSTRIDE, which is OK as no XScale CPU has VFP.
34
+ * check that confirms the presence of whichever of VFP or Neon is
35
+ * relevant, to avoid accidentally enabling a Neon feature on
36
+ * a VFP-no-Neon core or vice-versa.
29
+ */
37
+ */
30
+FIELD(TBFLAG_A32, XSCALE_CPAR, 4, 2)
38
+static inline bool isar_feature_aa32_simdfmac(const ARMISARegisters *id)
31
/*
39
+{
32
* Indicates whether cp register reads and writes by guest code should access
40
+ return FIELD_EX32(id->mvfr1, MVFR1, SIMDFMAC) != 0;
33
* the secure or nonsecure bank of banked registers; note that this is not
41
+}
34
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
42
+
35
FIELD(TBFLAG_A32, VFPEN, 7, 1)
43
static inline bool isar_feature_aa32_vsel(const ARMISARegisters *id)
36
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
44
{
37
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
45
return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 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
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
46
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/cpu.c
48
--- a/target/arm/cpu.c
48
+++ b/target/arm/cpu.c
49
+++ b/target/arm/cpu.c
49
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
50
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
50
set_feature(env, ARM_FEATURE_THUMB_DSP);
51
u = FIELD_DP32(u, MVFR1, SIMDINT, 0);
52
u = FIELD_DP32(u, MVFR1, SIMDSP, 0);
53
u = FIELD_DP32(u, MVFR1, SIMDHP, 0);
54
- u = FIELD_DP32(u, MVFR1, SIMDFMAC, 0);
55
cpu->isar.mvfr1 = u;
56
57
u = cpu->isar.mvfr2;
58
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
59
u = cpu->isar.mvfr0;
60
u = FIELD_DP32(u, MVFR0, SIMDREG, 0);
61
cpu->isar.mvfr0 = u;
62
+
63
+ /* Despite the name, this field covers both VFP and Neon */
64
+ u = cpu->isar.mvfr1;
65
+ u = FIELD_DP32(u, MVFR1, SIMDFMAC, 0);
66
+ cpu->isar.mvfr1 = u;
51
}
67
}
52
68
69
if (arm_feature(env, ARM_FEATURE_M) && !cpu->has_dsp) {
70
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/arm/translate-vfp.inc.c
73
+++ b/target/arm/translate-vfp.inc.c
74
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_sp(DisasContext *s, arg_VFM_sp *a)
75
76
/*
77
* Present in VFPv4 only.
78
+ * Note that we can't rely on the SIMDFMAC check alone, because
79
+ * in a Neon-no-VFP core that ID register field will be non-zero.
80
+ */
81
+ if (!dc_isar_feature(aa32_simdfmac, s) ||
82
+ !dc_isar_feature(aa32_fpsp_v2, s)) {
83
+ return false;
84
+ }
53
+ /*
85
+ /*
54
+ * We rely on no XScale CPU having VFP so we can use the same bits in the
86
* In v7A, UNPREDICTABLE with non-zero vector length/stride; from
55
+ * TB flags field for VECSTRIDE and XSCALE_CPAR.
87
* v8A, must UNDEF. We choose to UNDEF for both v7A and v8A.
88
*/
89
- if (!arm_dc_feature(s, ARM_FEATURE_VFP4) ||
90
- (s->vec_len != 0 || s->vec_stride != 0)) {
91
+ if (s->vec_len != 0 || s->vec_stride != 0) {
92
return false;
93
}
94
95
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
96
97
/*
98
* Present in VFPv4 only.
99
+ * Note that we can't rely on the SIMDFMAC check alone, because
100
+ * in a Neon-no-VFP core that ID register field will be non-zero.
56
+ */
101
+ */
57
+ assert(!(arm_feature(env, ARM_FEATURE_VFP) &&
102
+ if (!dc_isar_feature(aa32_simdfmac, s) ||
58
+ arm_feature(env, ARM_FEATURE_XSCALE)));
103
+ !dc_isar_feature(aa32_fpdp_v2, s)) {
59
+
104
+ return false;
60
if (arm_feature(env, ARM_FEATURE_V7) &&
105
+ }
61
!arm_feature(env, ARM_FEATURE_M) &&
106
+ /*
62
!arm_feature(env, ARM_FEATURE_PMSA)) {
107
* In v7A, UNPREDICTABLE with non-zero vector length/stride; from
63
diff --git a/target/arm/helper.c b/target/arm/helper.c
108
* v8A, must UNDEF. We choose to UNDEF for both v7A and v8A.
64
index XXXXXXX..XXXXXXX 100644
109
*/
65
--- a/target/arm/helper.c
110
- if (!arm_dc_feature(s, ARM_FEATURE_VFP4) ||
66
+++ b/target/arm/helper.c
111
- (s->vec_len != 0 || s->vec_stride != 0)) {
67
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
112
+ if (s->vec_len != 0 || s->vec_stride != 0) {
68
|| arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
113
return false;
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
}
114
}
78
115
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
116
diff --git a/target/arm/translate.c b/target/arm/translate.c
81
index XXXXXXX..XXXXXXX 100644
117
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/translate.c
118
--- a/target/arm/translate.c
83
+++ b/target/arm/translate.c
119
+++ b/target/arm/translate.c
84
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
120
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
85
dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
121
}
86
dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
122
break;
87
dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
123
case NEON_3R_VFM_VQRDMLSH:
88
- dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
124
- if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
89
- dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
125
+ if (!dc_isar_feature(aa32_simdfmac, s)) {
90
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
126
return 1;
91
+ dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
127
}
92
+ dc->vec_stride = 0;
128
break;
93
+ } else {
94
+ dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
95
+ dc->c15_cpar = 0;
96
+ }
97
dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
98
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
99
regime_is_secure(env, dc->mmu_idx);
100
--
129
--
101
2.20.1
130
2.20.1
102
131
103
132
diff view generated by jsdifflib
1
Correct the decode of the M-profile "coprocessor and
1
From: Richard Henderson <richard.henderson@linaro.org>
2
floating-point instructions" space:
3
* op0 == 0b11 is always unallocated
4
* if the CPU has an FPU then all insns with op1 == 0b101
5
are floating point and go to disas_vfp_insn()
6
2
7
For the moment we leave VLLDM and VLSTM as NOPs; in
3
We now have proper ISA checks within each trans_* function.
8
a later commit we will fill in the proper implementation
9
for the case where an FPU is present.
10
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200224222232.13807-11-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20190416125744.27770-7-peter.maydell@linaro.org
14
---
9
---
15
target/arm/translate.c | 26 ++++++++++++++++++++++----
10
target/arm/translate.c | 4 ----
16
1 file changed, 22 insertions(+), 4 deletions(-)
11
1 file changed, 4 deletions(-)
17
12
18
diff --git a/target/arm/translate.c b/target/arm/translate.c
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate.c
15
--- a/target/arm/translate.c
21
+++ b/target/arm/translate.c
16
+++ b/target/arm/translate.c
22
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
17
@@ -XXX,XX +XXX,XX @@ static void gen_neon_dup_high16(TCGv_i32 var)
23
case 6: case 7: case 14: case 15:
18
*/
24
/* Coprocessor. */
19
static int disas_vfp_insn(DisasContext *s, uint32_t insn)
25
if (arm_dc_feature(s, ARM_FEATURE_M)) {
20
{
26
- /* We don't currently implement M profile FP support,
21
- if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
27
- * so this entire space should give a NOCP fault, with
22
- return 1;
28
- * the exception of the v8M VLLDM and VLSTM insns, which
23
- }
29
- * must be NOPs in Secure state and UNDEF in Nonsecure state.
24
-
30
+ /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
25
/*
31
+ if (extract32(insn, 24, 2) == 3) {
26
* If the decodetree decoder handles this insn it will always
32
+ goto illegal_op; /* op0 = 0b11 : unallocated */
27
* emit code to either execute the insn or generate an appropriate
33
+ }
34
+
35
+ /*
36
+ * Decode VLLDM and VLSTM first: these are nonstandard because:
37
+ * * if there is no FPU then these insns must NOP in
38
+ * Secure state and UNDEF in Nonsecure state
39
+ * * if there is an FPU then these insns do not have
40
+ * the usual behaviour that disas_vfp_insn() provides of
41
+ * being controlled by CPACR/NSACR enable bits or the
42
+ * lazy-stacking logic.
43
*/
44
if (arm_dc_feature(s, ARM_FEATURE_V8) &&
45
(insn & 0xffa00f00) == 0xec200a00) {
46
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
47
/* Just NOP since FP support is not implemented */
48
break;
49
}
50
+ if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
51
+ ((insn >> 8) & 0xe) == 10) {
52
+ /* FP, and the CPU supports it */
53
+ if (disas_vfp_insn(s, insn)) {
54
+ goto illegal_op;
55
+ }
56
+ break;
57
+ }
58
+
59
/* All other insns: NOCP */
60
gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
61
default_exception_el(s));
62
--
28
--
63
2.20.1
29
2.20.1
64
30
65
31
diff view generated by jsdifflib
1
Implement the VLLDM instruction for v7M for the FPU present cas.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Now that we no longer have an early check for ARM_FEATURE_VFP,
4
we can use the proper ISA check in trans_VLLDM_VLSTM.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20200224222232.13807-12-richard.henderson@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-26-peter.maydell@linaro.org
6
---
10
---
7
target/arm/helper.h | 1 +
11
target/arm/translate-vfp.inc.c | 39 +++++++++++++++++++++++++
8
target/arm/helper.c | 54 ++++++++++++++++++++++++++++++++++++++++++
12
target/arm/translate.c | 53 ++++++----------------------------
9
target/arm/translate.c | 2 +-
13
target/arm/vfp.decode | 2 ++
10
3 files changed, 56 insertions(+), 1 deletion(-)
14
3 files changed, 50 insertions(+), 44 deletions(-)
11
15
12
diff --git a/target/arm/helper.h b/target/arm/helper.h
16
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.h
18
--- a/target/arm/translate-vfp.inc.c
15
+++ b/target/arm/helper.h
19
+++ b/target/arm/translate-vfp.inc.c
16
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
20
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
17
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
21
tcg_temp_free_ptr(fpst);
18
22
return true;
19
DEF_HELPER_2(v7m_vlstm, void, env, i32)
20
+DEF_HELPER_2(v7m_vlldm, void, env, i32)
21
22
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
23
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.c
27
+++ b/target/arm/helper.c
28
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
29
g_assert_not_reached();
30
}
23
}
31
24
+
32
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
25
+/*
26
+ * Decode VLLDM and VLSTM are nonstandard because:
27
+ * * if there is no FPU then these insns must NOP in
28
+ * Secure state and UNDEF in Nonsecure state
29
+ * * if there is an FPU then these insns do not have
30
+ * the usual behaviour that vfp_access_check() provides of
31
+ * being controlled by CPACR/NSACR enable bits or the
32
+ * lazy-stacking logic.
33
+ */
34
+static bool trans_VLLDM_VLSTM(DisasContext *s, arg_VLLDM_VLSTM *a)
33
+{
35
+{
34
+ /* translate.c should never generate calls here in user-only mode */
36
+ TCGv_i32 fptr;
35
+ g_assert_not_reached();
36
+}
37
+
37
+
38
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
38
+ if (!arm_dc_feature(s, ARM_FEATURE_M) ||
39
{
39
+ !arm_dc_feature(s, ARM_FEATURE_V8)) {
40
/* The TT instructions can be used by unprivileged code, but in
40
+ return false;
41
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
41
+ }
42
env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
42
+ /* If not secure, UNDEF. */
43
}
43
+ if (!s->v8m_secure) {
44
44
+ return false;
45
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
45
+ }
46
+{
46
+ /* If no fpu, NOP. */
47
+ /* fptr is the value of Rn, the frame pointer we load the FP regs from */
47
+ if (!dc_isar_feature(aa32_vfp, s)) {
48
+ assert(env->v7m.secure);
48
+ return true;
49
+
50
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
51
+ return;
52
+ }
49
+ }
53
+
50
+
54
+ /* Check access to the coprocessor is permitted */
51
+ fptr = load_reg(s, a->rn);
55
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
52
+ if (a->l) {
56
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
53
+ gen_helper_v7m_vlldm(cpu_env, fptr);
54
+ } else {
55
+ gen_helper_v7m_vlstm(cpu_env, fptr);
57
+ }
56
+ }
57
+ tcg_temp_free_i32(fptr);
58
+
58
+
59
+ if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
59
+ /* End the TB, because we have updated FP control bits */
60
+ /* State in FP is still valid */
60
+ s->base.is_jmp = DISAS_UPDATE;
61
+ env->v7m.fpccr[M_REG_S] &= ~R_V7M_FPCCR_LSPACT_MASK;
61
+ return true;
62
+ } else {
63
+ bool ts = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK;
64
+ int i;
65
+ uint32_t fpscr;
66
+
67
+ if (fptr & 7) {
68
+ raise_exception_ra(env, EXCP_UNALIGNED, 0, 1, GETPC());
69
+ }
70
+
71
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
72
+ uint32_t slo, shi;
73
+ uint64_t dn;
74
+ uint32_t faddr = fptr + 4 * i;
75
+
76
+ if (i >= 16) {
77
+ faddr += 8; /* skip the slot for the FPSCR */
78
+ }
79
+
80
+ slo = cpu_ldl_data(env, faddr);
81
+ shi = cpu_ldl_data(env, faddr + 4);
82
+
83
+ dn = (uint64_t) shi << 32 | slo;
84
+ *aa32_vfp_dreg(env, i / 2) = dn;
85
+ }
86
+ fpscr = cpu_ldl_data(env, fptr + 0x40);
87
+ vfp_set_fpscr(env, fpscr);
88
+ }
89
+
90
+ env->v7m.control[M_REG_S] |= R_V7M_CONTROL_FPCA_MASK;
91
+}
62
+}
92
+
93
static bool v7m_push_stack(ARMCPU *cpu)
94
{
95
/* Do the "set up stack frame" part of exception entry,
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
63
diff --git a/target/arm/translate.c b/target/arm/translate.c
97
index XXXXXXX..XXXXXXX 100644
64
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate.c
65
--- a/target/arm/translate.c
99
+++ b/target/arm/translate.c
66
+++ b/target/arm/translate.c
100
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
67
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
101
TCGv_i32 fptr = load_reg(s, rn);
68
goto illegal_op; /* op0 = 0b11 : unallocated */
102
69
}
103
if (extract32(insn, 20, 1)) {
70
104
- /* VLLDM */
71
- /*
105
+ gen_helper_v7m_vlldm(cpu_env, fptr);
72
- * Decode VLLDM and VLSTM first: these are nonstandard because:
106
} else {
73
- * * if there is no FPU then these insns must NOP in
107
gen_helper_v7m_vlstm(cpu_env, fptr);
74
- * Secure state and UNDEF in Nonsecure state
108
}
75
- * * if there is an FPU then these insns do not have
76
- * the usual behaviour that disas_vfp_insn() provides of
77
- * being controlled by CPACR/NSACR enable bits or the
78
- * lazy-stacking logic.
79
- */
80
- if (arm_dc_feature(s, ARM_FEATURE_V8) &&
81
- (insn & 0xffa00f00) == 0xec200a00) {
82
- /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
83
- * - VLLDM, VLSTM
84
- * We choose to UNDEF if the RAZ bits are non-zero.
85
- */
86
- if (!s->v8m_secure || (insn & 0x0040f0ff)) {
87
+ if (disas_vfp_insn(s, insn)) {
88
+ if (((insn >> 8) & 0xe) == 10 &&
89
+ dc_isar_feature(aa32_fpsp_v2, s)) {
90
+ /* FP, and the CPU supports it */
91
goto illegal_op;
92
+ } else {
93
+ /* All other insns: NOCP */
94
+ gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
95
+ syn_uncategorized(),
96
+ default_exception_el(s));
97
}
98
-
99
- if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
100
- uint32_t rn = (insn >> 16) & 0xf;
101
- TCGv_i32 fptr = load_reg(s, rn);
102
-
103
- if (extract32(insn, 20, 1)) {
104
- gen_helper_v7m_vlldm(cpu_env, fptr);
105
- } else {
106
- gen_helper_v7m_vlstm(cpu_env, fptr);
107
- }
108
- tcg_temp_free_i32(fptr);
109
-
110
- /* End the TB, because we have updated FP control bits */
111
- s->base.is_jmp = DISAS_UPDATE;
112
- }
113
- break;
114
}
115
- if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
116
- ((insn >> 8) & 0xe) == 10) {
117
- /* FP, and the CPU supports it */
118
- if (disas_vfp_insn(s, insn)) {
119
- goto illegal_op;
120
- }
121
- break;
122
- }
123
-
124
- /* All other insns: NOCP */
125
- gen_exception_insn(s, s->pc_curr, EXCP_NOCP, syn_uncategorized(),
126
- default_exception_el(s));
127
break;
128
}
129
if ((insn & 0xfe000a00) == 0xfc000800
130
diff --git a/target/arm/vfp.decode b/target/arm/vfp.decode
131
index XXXXXXX..XXXXXXX 100644
132
--- a/target/arm/vfp.decode
133
+++ b/target/arm/vfp.decode
134
@@ -XXX,XX +XXX,XX @@ VCVT_sp_int ---- 1110 1.11 110 s:1 .... 1010 rz:1 1.0 .... \
135
vd=%vd_sp vm=%vm_sp
136
VCVT_dp_int ---- 1110 1.11 110 s:1 .... 1011 rz:1 1.0 .... \
137
vd=%vd_sp vm=%vm_dp
138
+
139
+VLLDM_VLSTM 1110 1100 001 l:1 rn:4 0000 1010 0000 0000
109
--
140
--
110
2.20.1
141
2.20.1
111
142
112
143
diff view generated by jsdifflib
1
The only "system register" that M-profile floating point exposes
1
From: Richard Henderson <richard.henderson@linaro.org>
2
via the VMRS/VMRS instructions is FPSCR, and it does not have
3
the odd special case for rd==15. Add a check to ensure we only
4
expose FPSCR.
5
2
3
Have the calls adjacent as an intermediate step toward
4
actually merging the decodes.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20200224222232.13807-13-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-5-peter.maydell@linaro.org
9
---
10
---
10
target/arm/translate.c | 19 +++++++++++++++++--
11
target/arm/translate.c | 83 +++++++++++++++---------------------------
11
1 file changed, 17 insertions(+), 2 deletions(-)
12
1 file changed, 29 insertions(+), 54 deletions(-)
12
13
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
16
--- a/target/arm/translate.c
16
+++ b/target/arm/translate.c
17
+++ b/target/arm/translate.c
17
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
18
@@ -XXX,XX +XXX,XX @@ static void gen_neon_dup_high16(TCGv_i32 var)
18
}
19
tcg_temp_free_i32(tmp);
19
}
20
}
20
} else { /* !dp */
21
21
+ bool is_sysreg;
22
-/*
22
+
23
- * Disassemble a VFP instruction. Returns nonzero if an error occurred
23
if ((insn & 0x6f) != 0x00)
24
- * (ie. an undefined instruction).
24
return 1;
25
- */
25
rn = VFP_SREG_N(insn);
26
-static int disas_vfp_insn(DisasContext *s, uint32_t insn)
26
+
27
-{
27
+ is_sysreg = extract32(insn, 21, 1);
28
- /*
28
+
29
- * If the decodetree decoder handles this insn it will always
29
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
30
- * emit code to either execute the insn or generate an appropriate
30
+ /*
31
- * exception; so we don't need to ever return non-zero to tell
31
+ * The only M-profile VFP vmrs/vmsr sysreg is FPSCR.
32
- * the calling code to emit an UNDEF exception.
32
+ * Writes to R15 are UNPREDICTABLE; we choose to undef.
33
- */
33
+ */
34
- if (extract32(insn, 28, 4) == 0xf) {
34
+ if (is_sysreg && (rd == 15 || (rn >> 1) != ARM_VFP_FPSCR)) {
35
- if (disas_vfp_uncond(s, insn)) {
35
+ return 1;
36
- return 0;
36
+ }
37
- }
37
+ }
38
- } else {
38
+
39
- if (disas_vfp(s, insn)) {
39
if (insn & ARM_CP_RW_BIT) {
40
- return 0;
40
/* vfp->arm */
41
- }
41
- if (insn & (1 << 21)) {
42
- }
42
+ if (is_sysreg) {
43
- /* If the decodetree decoder didn't handle this insn, it must be UNDEF */
43
/* system register */
44
- return 1;
44
rn >>= 1;
45
-}
45
46
-
46
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
47
static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
47
}
48
{
48
} else {
49
#ifndef CONFIG_USER_ONLY
49
/* arm->vfp */
50
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
50
- if (insn & (1 << 21)) {
51
ARCH(5);
51
+ if (is_sysreg) {
52
52
rn >>= 1;
53
/* Unconditional instructions. */
53
/* system register */
54
- if (disas_a32_uncond(s, insn)) {
54
switch (rn) {
55
+ /* TODO: Perhaps merge these into one decodetree output file. */
56
+ if (disas_a32_uncond(s, insn) ||
57
+ disas_vfp_uncond(s, insn)) {
58
return;
59
}
60
/* fall back to legacy decoder */
61
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
62
}
63
return;
64
}
65
- if ((insn & 0x0f000e10) == 0x0e000a00) {
66
- /* VFP. */
67
- if (disas_vfp_insn(s, insn)) {
68
- goto illegal_op;
69
- }
70
- return;
71
- }
72
if ((insn & 0x0e000f00) == 0x0c000100) {
73
if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
74
/* iWMMXt register transfer. */
75
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
76
arm_skip_unless(s, cond);
77
}
78
79
- if (disas_a32(s, insn)) {
80
+ /* TODO: Perhaps merge these into one decodetree output file. */
81
+ if (disas_a32(s, insn) ||
82
+ disas_vfp(s, insn)) {
83
return;
84
}
85
/* fall back to legacy decoder */
86
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
87
case 0xd:
88
case 0xe:
89
if (((insn >> 8) & 0xe) == 10) {
90
- /* VFP. */
91
- if (disas_vfp_insn(s, insn)) {
92
- goto illegal_op;
93
- }
94
- } else if (disas_coproc_insn(s, insn)) {
95
+ /* VFP, but failed disas_vfp. */
96
+ goto illegal_op;
97
+ }
98
+ if (disas_coproc_insn(s, insn)) {
99
/* Coprocessor. */
100
goto illegal_op;
101
}
102
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
103
ARCH(6T2);
104
}
105
106
- if (disas_t32(s, insn)) {
107
+ /*
108
+ * TODO: Perhaps merge these into one decodetree output file.
109
+ * Note disas_vfp is written for a32 with cond field in the
110
+ * top nibble. The t32 encoding requires 0xe in the top nibble.
111
+ */
112
+ if (disas_t32(s, insn) ||
113
+ disas_vfp_uncond(s, insn) ||
114
+ ((insn >> 28) == 0xe && disas_vfp(s, insn))) {
115
return;
116
}
117
/* fall back to legacy decoder */
118
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
119
goto illegal_op; /* op0 = 0b11 : unallocated */
120
}
121
122
- if (disas_vfp_insn(s, insn)) {
123
- if (((insn >> 8) & 0xe) == 10 &&
124
- dc_isar_feature(aa32_fpsp_v2, s)) {
125
- /* FP, and the CPU supports it */
126
- goto illegal_op;
127
- } else {
128
- /* All other insns: NOCP */
129
- gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
130
- syn_uncategorized(),
131
- default_exception_el(s));
132
- }
133
+ if (((insn >> 8) & 0xe) == 10 &&
134
+ dc_isar_feature(aa32_fpsp_v2, s)) {
135
+ /* FP, and the CPU supports it */
136
+ goto illegal_op;
137
+ } else {
138
+ /* All other insns: NOCP */
139
+ gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
140
+ syn_uncategorized(),
141
+ default_exception_el(s));
142
}
143
break;
144
}
145
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
146
goto illegal_op;
147
}
148
} else if (((insn >> 8) & 0xe) == 10) {
149
- if (disas_vfp_insn(s, insn)) {
150
- goto illegal_op;
151
- }
152
+ /* VFP, but failed disas_vfp. */
153
+ goto illegal_op;
154
} else {
155
if (insn & (1 << 28))
156
goto illegal_op;
55
--
157
--
56
2.20.1
158
2.20.1
57
159
58
160
diff view generated by jsdifflib
1
Handle floating point registers in exception return.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
This corresponds to pseudocode functions ValidateExceptionReturn(),
3
ExceptionReturn(), PopStack() and ConsumeExcStackFrame().
4
2
3
Use isar feature tests instead of feature bit tests.
4
5
Although none of QEMUs current cpus have VFPv3 without D32,
6
replace the large comment explaining why with one line that
7
sets ARM_HWCAP_ARM_VFPv3D16 under the correct conditions.
8
Mirror the test sequence used in the linux kernel.
9
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20200224222232.13807-14-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190416125744.27770-16-peter.maydell@linaro.org
8
---
14
---
9
target/arm/helper.c | 142 +++++++++++++++++++++++++++++++++++++++++++-
15
linux-user/elfload.c | 23 +++++++++++++----------
10
1 file changed, 141 insertions(+), 1 deletion(-)
16
1 file changed, 13 insertions(+), 10 deletions(-)
11
17
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
13
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
20
--- a/linux-user/elfload.c
15
+++ b/target/arm/helper.c
21
+++ b/linux-user/elfload.c
16
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
22
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
17
bool rettobase = false;
23
18
bool exc_secure = false;
24
/* EDSP is in v5TE and above, but all our v5 CPUs are v5TE */
19
bool return_to_secure;
25
GET_FEATURE(ARM_FEATURE_V5, ARM_HWCAP_ARM_EDSP);
20
+ bool ftype;
26
- GET_FEATURE(ARM_FEATURE_VFP, ARM_HWCAP_ARM_VFP);
21
+ bool restore_s16_s31;
27
GET_FEATURE(ARM_FEATURE_IWMMXT, ARM_HWCAP_ARM_IWMMXT);
22
28
GET_FEATURE(ARM_FEATURE_THUMB2EE, ARM_HWCAP_ARM_THUMBEE);
23
/* If we're not in Handler mode then jumps to magic exception-exit
29
GET_FEATURE(ARM_FEATURE_NEON, ARM_HWCAP_ARM_NEON);
24
* addresses don't have magic behaviour. However for the v8M
30
- GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPv3);
25
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
31
GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
26
excret);
32
- GET_FEATURE(ARM_FEATURE_VFP4, ARM_HWCAP_ARM_VFPv4);
27
}
33
+ GET_FEATURE(ARM_FEATURE_LPAE, ARM_HWCAP_ARM_LPAE);
28
34
GET_FEATURE_ID(aa32_arm_div, ARM_HWCAP_ARM_IDIVA);
29
+ ftype = excret & R_V7M_EXCRET_FTYPE_MASK;
35
GET_FEATURE_ID(aa32_thumb_div, ARM_HWCAP_ARM_IDIVT);
36
- /* All QEMU's VFPv3 CPUs have 32 registers, see VFP_DREG in translate.c.
37
- * Note that the ARM_HWCAP_ARM_VFPv3D16 bit is always the inverse of
38
- * ARM_HWCAP_ARM_VFPD32 (and so always clear for QEMU); it is unrelated
39
- * to our VFP_FP16 feature bit.
40
- */
41
- GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPD32);
42
- GET_FEATURE(ARM_FEATURE_LPAE, ARM_HWCAP_ARM_LPAE);
43
+ GET_FEATURE_ID(aa32_vfp, ARM_HWCAP_ARM_VFP);
30
+
44
+
31
+ if (!arm_feature(env, ARM_FEATURE_VFP) && !ftype) {
45
+ if (cpu_isar_feature(aa32_fpsp_v3, cpu) ||
32
+ qemu_log_mask(LOG_GUEST_ERROR, "M profile: zero FTYPE in exception "
46
+ cpu_isar_feature(aa32_fpdp_v3, cpu)) {
33
+ "exit PC value 0x%" PRIx32 " is UNPREDICTABLE "
47
+ hwcaps |= ARM_HWCAP_ARM_VFPv3;
34
+ "if FPU not present\n",
48
+ if (cpu_isar_feature(aa32_simd_r32, cpu)) {
35
+ excret);
49
+ hwcaps |= ARM_HWCAP_ARM_VFPD32;
36
+ ftype = true;
37
+ }
38
+
39
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
40
/* EXC_RETURN.ES validation check (R_SMFL). We must do this before
41
* we pick which FAULTMASK to clear.
42
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
43
*/
44
write_v7m_control_spsel_for_secstate(env, return_to_sp_process, exc_secure);
45
46
+ /*
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 {
50
+ } else {
60
+ /* Clear s0..s15 and FPSCR */
51
+ hwcaps |= ARM_HWCAP_ARM_VFPv3D16;
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
+ }
52
+ }
68
+ }
53
+ }
69
+
54
+ GET_FEATURE_ID(aa32_simdfmac, ARM_HWCAP_ARM_VFPv4);
70
if (sfault) {
55
71
env->v7m.sfsr |= R_V7M_SFSR_INVER_MASK;
56
return hwcaps;
72
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
57
}
73
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
74
}
75
}
76
77
+ if (!ftype) {
78
+ /* FP present and we need to handle it */
79
+ if (!return_to_secure &&
80
+ (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK)) {
81
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
82
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
83
+ qemu_log_mask(CPU_LOG_INT,
84
+ "...taking SecureFault on existing stackframe: "
85
+ "Secure LSPACT set but exception return is "
86
+ "not to secure state\n");
87
+ v7m_exception_taken(cpu, excret, true, false);
88
+ return;
89
+ }
90
+
91
+ restore_s16_s31 = return_to_secure &&
92
+ (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
93
+
94
+ if (env->v7m.fpccr[return_to_secure] & R_V7M_FPCCR_LSPACT_MASK) {
95
+ /* State in FPU is still valid, just clear LSPACT */
96
+ env->v7m.fpccr[return_to_secure] &= ~R_V7M_FPCCR_LSPACT_MASK;
97
+ } else {
98
+ int i;
99
+ uint32_t fpscr;
100
+ bool cpacr_pass, nsacr_pass;
101
+
102
+ cpacr_pass = v7m_cpacr_pass(env, return_to_secure,
103
+ return_to_priv);
104
+ nsacr_pass = return_to_secure ||
105
+ extract32(env->v7m.nsacr, 10, 1);
106
+
107
+ if (!cpacr_pass) {
108
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
109
+ return_to_secure);
110
+ env->v7m.cfsr[return_to_secure] |= R_V7M_CFSR_NOCP_MASK;
111
+ qemu_log_mask(CPU_LOG_INT,
112
+ "...taking UsageFault on existing "
113
+ "stackframe: CPACR.CP10 prevents unstacking "
114
+ "FP regs\n");
115
+ v7m_exception_taken(cpu, excret, true, false);
116
+ return;
117
+ } else if (!nsacr_pass) {
118
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, true);
119
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_INVPC_MASK;
120
+ qemu_log_mask(CPU_LOG_INT,
121
+ "...taking Secure UsageFault on existing "
122
+ "stackframe: NSACR.CP10 prevents unstacking "
123
+ "FP regs\n");
124
+ v7m_exception_taken(cpu, excret, true, false);
125
+ return;
126
+ }
127
+
128
+ for (i = 0; i < (restore_s16_s31 ? 32 : 16); i += 2) {
129
+ uint32_t slo, shi;
130
+ uint64_t dn;
131
+ uint32_t faddr = frameptr + 0x20 + 4 * i;
132
+
133
+ if (i >= 16) {
134
+ faddr += 8; /* Skip the slot for the FPSCR */
135
+ }
136
+
137
+ pop_ok = pop_ok &&
138
+ v7m_stack_read(cpu, &slo, faddr, mmu_idx) &&
139
+ v7m_stack_read(cpu, &shi, faddr + 4, mmu_idx);
140
+
141
+ if (!pop_ok) {
142
+ break;
143
+ }
144
+
145
+ dn = (uint64_t)shi << 32 | slo;
146
+ *aa32_vfp_dreg(env, i / 2) = dn;
147
+ }
148
+ pop_ok = pop_ok &&
149
+ v7m_stack_read(cpu, &fpscr, frameptr + 0x60, mmu_idx);
150
+ if (pop_ok) {
151
+ vfp_set_fpscr(env, fpscr);
152
+ }
153
+ if (!pop_ok) {
154
+ /*
155
+ * These regs are 0 if security extension present;
156
+ * otherwise merely UNKNOWN. We zero always.
157
+ */
158
+ for (i = 0; i < (restore_s16_s31 ? 32 : 16); i += 2) {
159
+ *aa32_vfp_dreg(env, i / 2) = 0;
160
+ }
161
+ vfp_set_fpscr(env, 0);
162
+ }
163
+ }
164
+ }
165
+ env->v7m.control[M_REG_S] = FIELD_DP32(env->v7m.control[M_REG_S],
166
+ V7M_CONTROL, FPCA, !ftype);
167
+
168
/* Commit to consuming the stack frame */
169
frameptr += 0x20;
170
+ if (!ftype) {
171
+ frameptr += 0x48;
172
+ if (restore_s16_s31) {
173
+ frameptr += 0x40;
174
+ }
175
+ }
176
/* Undo stack alignment (the SPREALIGN bit indicates that the original
177
* pre-exception SP was not 8-aligned and we added a padding word to
178
* align it, so we undo this by ORing in the bit that increases it
179
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
180
*frame_sp_p = frameptr;
181
}
182
/* This xpsr_write() will invalidate frame_sp_p as it may switch stack */
183
- xpsr_write(env, xpsr, ~XPSR_SPREALIGN);
184
+ xpsr_write(env, xpsr, ~(XPSR_SPREALIGN | XPSR_SFPA));
185
+
186
+ if (env->v7m.secure) {
187
+ bool sfpa = xpsr & XPSR_SFPA;
188
+
189
+ env->v7m.control[M_REG_S] = FIELD_DP32(env->v7m.control[M_REG_S],
190
+ V7M_CONTROL, SFPA, sfpa);
191
+ }
192
193
/* The restored xPSR exception field will be zero if we're
194
* resuming in Thread mode. If that doesn't match what the
195
--
58
--
196
2.20.1
59
2.20.1
197
60
198
61
diff view generated by jsdifflib
1
Enable the FPU by default for the Cortex-M4 and Cortex-M33.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
We have converted all tests against these features
4
to ISAR tests.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200224222232.13807-15-richard.henderson@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-27-peter.maydell@linaro.org
6
---
10
---
7
target/arm/cpu.c | 8 ++++++++
11
target/arm/cpu.h | 3 ---
8
1 file changed, 8 insertions(+)
12
target/arm/cpu.c | 25 -------------------------
9
13
target/arm/cpu64.c | 3 ---
14
target/arm/kvm32.c | 5 -----
15
target/arm/kvm64.c | 1 -
16
5 files changed, 37 deletions(-)
17
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
23
* mapping in linux-user/elfload.c:get_elf_hwcap().
24
*/
25
enum arm_features {
26
- ARM_FEATURE_VFP,
27
ARM_FEATURE_AUXCR, /* ARM1026 Auxiliary control register. */
28
ARM_FEATURE_XSCALE, /* Intel XScale extensions. */
29
ARM_FEATURE_IWMMXT, /* Intel iwMMXt extension. */
30
@@ -XXX,XX +XXX,XX @@ enum arm_features {
31
ARM_FEATURE_V7,
32
ARM_FEATURE_THUMB2,
33
ARM_FEATURE_PMSA, /* no MMU; may have Memory Protection Unit */
34
- ARM_FEATURE_VFP3,
35
ARM_FEATURE_NEON,
36
ARM_FEATURE_M, /* Microcontroller profile. */
37
ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */
38
@@ -XXX,XX +XXX,XX @@ enum arm_features {
39
ARM_FEATURE_V5,
40
ARM_FEATURE_STRONGARM,
41
ARM_FEATURE_VAPA, /* cp15 VA to PA lookups */
42
- ARM_FEATURE_VFP4, /* VFPv4 (implies that NEON is v2) */
43
ARM_FEATURE_GENERIC_TIMER,
44
ARM_FEATURE_MVFR, /* Media and VFP Feature Registers 0 and 1 */
45
ARM_FEATURE_DUMMY_C15_REGS, /* RAZ/WI all of cp15 crn=15 */
10
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
46
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
11
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
12
--- a/target/arm/cpu.c
48
--- a/target/arm/cpu.c
13
+++ b/target/arm/cpu.c
49
+++ b/target/arm/cpu.c
50
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
51
if (arm_feature(&cpu->env, ARM_FEATURE_M)) {
52
set_feature(&cpu->env, ARM_FEATURE_PMSA);
53
}
54
- /* Similarly for the VFP feature bits */
55
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP4)) {
56
- set_feature(&cpu->env, ARM_FEATURE_VFP3);
57
- }
58
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP3)) {
59
- set_feature(&cpu->env, ARM_FEATURE_VFP);
60
- }
61
62
if (arm_feature(&cpu->env, ARM_FEATURE_CBAR) ||
63
arm_feature(&cpu->env, ARM_FEATURE_CBAR_RO)) {
64
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
65
uint64_t t;
66
uint32_t u;
67
68
- unset_feature(env, ARM_FEATURE_VFP);
69
- unset_feature(env, ARM_FEATURE_VFP3);
70
- unset_feature(env, ARM_FEATURE_VFP4);
71
-
72
t = cpu->isar.id_aa64isar1;
73
t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 0);
74
cpu->isar.id_aa64isar1 = t;
75
@@ -XXX,XX +XXX,XX @@ static void arm926_initfn(Object *obj)
76
77
cpu->dtb_compatible = "arm,arm926";
78
set_feature(&cpu->env, ARM_FEATURE_V5);
79
- set_feature(&cpu->env, ARM_FEATURE_VFP);
80
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
81
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
82
cpu->midr = 0x41069265;
83
@@ -XXX,XX +XXX,XX @@ static void arm1026_initfn(Object *obj)
84
85
cpu->dtb_compatible = "arm,arm1026";
86
set_feature(&cpu->env, ARM_FEATURE_V5);
87
- set_feature(&cpu->env, ARM_FEATURE_VFP);
88
set_feature(&cpu->env, ARM_FEATURE_AUXCR);
89
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
90
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
91
@@ -XXX,XX +XXX,XX @@ static void arm1136_r2_initfn(Object *obj)
92
93
cpu->dtb_compatible = "arm,arm1136";
94
set_feature(&cpu->env, ARM_FEATURE_V6);
95
- set_feature(&cpu->env, ARM_FEATURE_VFP);
96
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
97
set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
98
set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
99
@@ -XXX,XX +XXX,XX @@ static void arm1136_initfn(Object *obj)
100
cpu->dtb_compatible = "arm,arm1136";
101
set_feature(&cpu->env, ARM_FEATURE_V6K);
102
set_feature(&cpu->env, ARM_FEATURE_V6);
103
- set_feature(&cpu->env, ARM_FEATURE_VFP);
104
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
105
set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
106
set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
107
@@ -XXX,XX +XXX,XX @@ static void arm1176_initfn(Object *obj)
108
109
cpu->dtb_compatible = "arm,arm1176";
110
set_feature(&cpu->env, ARM_FEATURE_V6K);
111
- set_feature(&cpu->env, ARM_FEATURE_VFP);
112
set_feature(&cpu->env, ARM_FEATURE_VAPA);
113
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
114
set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
115
@@ -XXX,XX +XXX,XX @@ static void arm11mpcore_initfn(Object *obj)
116
117
cpu->dtb_compatible = "arm,arm11mpcore";
118
set_feature(&cpu->env, ARM_FEATURE_V6K);
119
- set_feature(&cpu->env, ARM_FEATURE_VFP);
120
set_feature(&cpu->env, ARM_FEATURE_VAPA);
121
set_feature(&cpu->env, ARM_FEATURE_MPIDR);
122
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
14
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
123
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
15
set_feature(&cpu->env, ARM_FEATURE_M);
124
set_feature(&cpu->env, ARM_FEATURE_M);
16
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
125
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
17
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
126
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
18
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
127
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
19
cpu->midr = 0x410fc240; /* r0p0 */
128
cpu->midr = 0x410fc240; /* r0p0 */
20
cpu->pmsav7_dregion = 8;
129
cpu->pmsav7_dregion = 8;
21
+ cpu->isar.mvfr0 = 0x10110021;
130
cpu->isar.mvfr0 = 0x10110021;
22
+ cpu->isar.mvfr1 = 0x11000011;
131
@@ -XXX,XX +XXX,XX @@ static void cortex_m7_initfn(Object *obj)
23
+ cpu->isar.mvfr2 = 0x00000000;
132
set_feature(&cpu->env, ARM_FEATURE_M);
24
cpu->id_pfr0 = 0x00000030;
133
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
25
cpu->id_pfr1 = 0x00000200;
134
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
26
cpu->id_dfr0 = 0x00100000;
135
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
136
cpu->midr = 0x411fc272; /* r1p2 */
137
cpu->pmsav7_dregion = 8;
138
cpu->isar.mvfr0 = 0x10110221;
27
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
139
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
28
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
140
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
29
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
141
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
30
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
142
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
31
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
143
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
32
cpu->midr = 0x410fd213; /* r0p3 */
144
cpu->midr = 0x410fd213; /* r0p3 */
33
cpu->pmsav7_dregion = 16;
145
cpu->pmsav7_dregion = 16;
34
cpu->sau_sregion = 8;
146
cpu->sau_sregion = 8;
35
+ cpu->isar.mvfr0 = 0x10110021;
147
@@ -XXX,XX +XXX,XX @@ static void cortex_r5f_initfn(Object *obj)
36
+ cpu->isar.mvfr1 = 0x11000011;
148
ARMCPU *cpu = ARM_CPU(obj);
37
+ cpu->isar.mvfr2 = 0x00000040;
149
38
cpu->id_pfr0 = 0x00000030;
150
cortex_r5_initfn(obj);
39
cpu->id_pfr1 = 0x00000210;
151
- set_feature(&cpu->env, ARM_FEATURE_VFP3);
40
cpu->id_dfr0 = 0x00200000;
152
cpu->isar.mvfr0 = 0x10110221;
153
cpu->isar.mvfr1 = 0x00000011;
154
}
155
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
156
157
cpu->dtb_compatible = "arm,cortex-a8";
158
set_feature(&cpu->env, ARM_FEATURE_V7);
159
- set_feature(&cpu->env, ARM_FEATURE_VFP3);
160
set_feature(&cpu->env, ARM_FEATURE_NEON);
161
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
162
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
163
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
164
165
cpu->dtb_compatible = "arm,cortex-a9";
166
set_feature(&cpu->env, ARM_FEATURE_V7);
167
- set_feature(&cpu->env, ARM_FEATURE_VFP3);
168
set_feature(&cpu->env, ARM_FEATURE_NEON);
169
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
170
set_feature(&cpu->env, ARM_FEATURE_EL3);
171
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
172
173
cpu->dtb_compatible = "arm,cortex-a7";
174
set_feature(&cpu->env, ARM_FEATURE_V7VE);
175
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
176
set_feature(&cpu->env, ARM_FEATURE_NEON);
177
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
178
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
179
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
180
181
cpu->dtb_compatible = "arm,cortex-a15";
182
set_feature(&cpu->env, ARM_FEATURE_V7VE);
183
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
184
set_feature(&cpu->env, ARM_FEATURE_NEON);
185
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
186
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
187
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
188
index XXXXXXX..XXXXXXX 100644
189
--- a/target/arm/cpu64.c
190
+++ b/target/arm/cpu64.c
191
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
192
193
cpu->dtb_compatible = "arm,cortex-a57";
194
set_feature(&cpu->env, ARM_FEATURE_V8);
195
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
196
set_feature(&cpu->env, ARM_FEATURE_NEON);
197
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
198
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
199
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
200
201
cpu->dtb_compatible = "arm,cortex-a53";
202
set_feature(&cpu->env, ARM_FEATURE_V8);
203
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
204
set_feature(&cpu->env, ARM_FEATURE_NEON);
205
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
206
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
207
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
208
209
cpu->dtb_compatible = "arm,cortex-a72";
210
set_feature(&cpu->env, ARM_FEATURE_V8);
211
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
212
set_feature(&cpu->env, ARM_FEATURE_NEON);
213
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
214
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
215
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
216
index XXXXXXX..XXXXXXX 100644
217
--- a/target/arm/kvm32.c
218
+++ b/target/arm/kvm32.c
219
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
220
* bits, but a few must be tested.
221
*/
222
set_feature(&features, ARM_FEATURE_V7VE);
223
- set_feature(&features, ARM_FEATURE_VFP3);
224
set_feature(&features, ARM_FEATURE_GENERIC_TIMER);
225
226
if (extract32(id_pfr0, 12, 4) == 1) {
227
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
228
if (extract32(ahcf->isar.mvfr1, 12, 4) == 1) {
229
set_feature(&features, ARM_FEATURE_NEON);
230
}
231
- if (extract32(ahcf->isar.mvfr1, 28, 4) == 1) {
232
- /* FMAC support implies VFPv4 */
233
- set_feature(&features, ARM_FEATURE_VFP4);
234
- }
235
236
ahcf->features = features;
237
238
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
239
index XXXXXXX..XXXXXXX 100644
240
--- a/target/arm/kvm64.c
241
+++ b/target/arm/kvm64.c
242
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
243
* feature bits.
244
*/
245
set_feature(&features, ARM_FEATURE_V8);
246
- set_feature(&features, ARM_FEATURE_VFP4);
247
set_feature(&features, ARM_FEATURE_NEON);
248
set_feature(&features, ARM_FEATURE_AARCH64);
249
set_feature(&features, ARM_FEATURE_PMU);
41
--
250
--
42
2.20.1
251
2.20.1
43
252
44
253
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
Those vfp instructions without extra opcode fields can
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
share a common @format for brevity.
5
Message-id: 20190412165416.7977-10-philmd@redhat.com
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200224222232.13807-16-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
include/hw/devices.h | 3 ---
11
target/arm/vfp.decode | 134 ++++++++++++++++--------------------------
9
include/hw/net/lan9118.h | 19 +++++++++++++++++++
12
1 file changed, 52 insertions(+), 82 deletions(-)
10
hw/arm/kzm.c | 2 +-
13
11
hw/arm/mps2.c | 2 +-
14
diff --git a/target/arm/vfp.decode b/target/arm/vfp.decode
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
18
diff --git a/include/hw/devices.h b/include/hw/devices.h
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/devices.h
16
--- a/target/arm/vfp.decode
21
+++ b/include/hw/devices.h
17
+++ b/target/arm/vfp.decode
22
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@
23
/* smc91c111.c */
19
24
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
20
%vmov_imm 16:4 0:4
25
21
26
-/* lan9118.c */
22
+@vfp_dnm_s ................................ vm=%vm_sp vn=%vn_sp vd=%vd_sp
27
-void lan9118_init(NICInfo *, uint32_t, qemu_irq);
23
+@vfp_dnm_d ................................ vm=%vm_dp vn=%vn_dp vd=%vd_dp
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
+
24
+
46
+#ifndef HW_NET_LAN9118_H
25
+@vfp_dm_ss ................................ vm=%vm_sp vd=%vd_sp
47
+#define HW_NET_LAN9118_H
26
+@vfp_dm_dd ................................ vm=%vm_dp vd=%vd_dp
27
+@vfp_dm_ds ................................ vm=%vm_sp vd=%vd_dp
28
+@vfp_dm_sd ................................ vm=%vm_dp vd=%vd_sp
48
+
29
+
49
+#include "hw/irq.h"
30
# VMOV scalar to general-purpose register; note that this does
50
+#include "net/net.h"
31
# include some Neon cases.
51
+
32
VMOV_to_gp ---- 1110 u:1 1. 1 .... rt:4 1011 ... 1 0000 \
52
+void lan9118_init(NICInfo *, uint32_t, qemu_irq);
33
@@ -XXX,XX +XXX,XX @@ VDUP ---- 1110 1 b:1 q:1 0 .... rt:4 1011 . 0 e:1 1 0000 \
53
+
34
vn=%vn_dp
54
+#endif
35
55
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
36
VMSR_VMRS ---- 1110 111 l:1 reg:4 rt:4 1010 0001 0000
56
index XXXXXXX..XXXXXXX 100644
37
-VMOV_single ---- 1110 000 l:1 .... rt:4 1010 . 001 0000 \
57
--- a/hw/arm/kzm.c
38
- vn=%vn_sp
58
+++ b/hw/arm/kzm.c
39
+VMOV_single ---- 1110 000 l:1 .... rt:4 1010 . 001 0000 vn=%vn_sp
59
@@ -XXX,XX +XXX,XX @@
40
60
#include "qemu/error-report.h"
41
-VMOV_64_sp ---- 1100 010 op:1 rt2:4 rt:4 1010 00.1 .... \
61
#include "exec/address-spaces.h"
42
- vm=%vm_sp
62
#include "net/net.h"
43
-VMOV_64_dp ---- 1100 010 op:1 rt2:4 rt:4 1011 00.1 .... \
63
-#include "hw/devices.h"
44
- vm=%vm_dp
64
+#include "hw/net/lan9118.h"
45
+VMOV_64_sp ---- 1100 010 op:1 rt2:4 rt:4 1010 00.1 .... vm=%vm_sp
65
#include "hw/char/serial.h"
46
+VMOV_64_dp ---- 1100 010 op:1 rt2:4 rt:4 1011 00.1 .... vm=%vm_dp
66
#include "sysemu/qtest.h"
47
67
48
# Note that the half-precision variants of VLDR and VSTR are
68
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
49
# not part of this decodetree at all because they have bits [9:8] == 0b01
69
index XXXXXXX..XXXXXXX 100644
50
-VLDR_VSTR_sp ---- 1101 u:1 .0 l:1 rn:4 .... 1010 imm:8 \
70
--- a/hw/arm/mps2.c
51
- vd=%vd_sp
71
+++ b/hw/arm/mps2.c
52
-VLDR_VSTR_dp ---- 1101 u:1 .0 l:1 rn:4 .... 1011 imm:8 \
72
@@ -XXX,XX +XXX,XX @@
53
- vd=%vd_dp
73
#include "hw/timer/cmsdk-apb-timer.h"
54
+VLDR_VSTR_sp ---- 1101 u:1 .0 l:1 rn:4 .... 1010 imm:8 vd=%vd_sp
74
#include "hw/timer/cmsdk-apb-dualtimer.h"
55
+VLDR_VSTR_dp ---- 1101 u:1 .0 l:1 rn:4 .... 1011 imm:8 vd=%vd_dp
75
#include "hw/misc/mps2-scc.h"
56
76
-#include "hw/devices.h"
57
# We split the load/store multiple up into two patterns to avoid
77
+#include "hw/net/lan9118.h"
58
# overlap with other insns in the "Advanced SIMD load/store and 64-bit move"
78
#include "net/net.h"
59
@@ -XXX,XX +XXX,XX @@ VLDM_VSTM_dp ---- 1101 0.1 l:1 rn:4 .... 1011 imm:8 \
79
60
vd=%vd_dp p=1 u=0 w=1
80
typedef enum MPS2FPGAType {
61
81
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
62
# 3-register VFP data-processing; bits [23,21:20,6] identify the operation.
82
index XXXXXXX..XXXXXXX 100644
63
-VMLA_sp ---- 1110 0.00 .... .... 1010 .0.0 .... \
83
--- a/hw/arm/realview.c
64
- vm=%vm_sp vn=%vn_sp vd=%vd_sp
84
+++ b/hw/arm/realview.c
65
-VMLA_dp ---- 1110 0.00 .... .... 1011 .0.0 .... \
85
@@ -XXX,XX +XXX,XX @@
66
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
86
#include "hw/arm/arm.h"
67
+VMLA_sp ---- 1110 0.00 .... .... 1010 .0.0 .... @vfp_dnm_s
87
#include "hw/arm/primecell.h"
68
+VMLA_dp ---- 1110 0.00 .... .... 1011 .0.0 .... @vfp_dnm_d
88
#include "hw/devices.h"
69
89
+#include "hw/net/lan9118.h"
70
-VMLS_sp ---- 1110 0.00 .... .... 1010 .1.0 .... \
90
#include "hw/pci/pci.h"
71
- vm=%vm_sp vn=%vn_sp vd=%vd_sp
91
#include "net/net.h"
72
-VMLS_dp ---- 1110 0.00 .... .... 1011 .1.0 .... \
92
#include "sysemu/sysemu.h"
73
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
93
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
74
+VMLS_sp ---- 1110 0.00 .... .... 1010 .1.0 .... @vfp_dnm_s
94
index XXXXXXX..XXXXXXX 100644
75
+VMLS_dp ---- 1110 0.00 .... .... 1011 .1.0 .... @vfp_dnm_d
95
--- a/hw/arm/vexpress.c
76
96
+++ b/hw/arm/vexpress.c
77
-VNMLS_sp ---- 1110 0.01 .... .... 1010 .0.0 .... \
97
@@ -XXX,XX +XXX,XX @@
78
- vm=%vm_sp vn=%vn_sp vd=%vd_sp
98
#include "hw/sysbus.h"
79
-VNMLS_dp ---- 1110 0.01 .... .... 1011 .0.0 .... \
99
#include "hw/arm/arm.h"
80
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
100
#include "hw/arm/primecell.h"
81
+VNMLS_sp ---- 1110 0.01 .... .... 1010 .0.0 .... @vfp_dnm_s
101
-#include "hw/devices.h"
82
+VNMLS_dp ---- 1110 0.01 .... .... 1011 .0.0 .... @vfp_dnm_d
102
+#include "hw/net/lan9118.h"
83
103
#include "hw/i2c/i2c.h"
84
-VNMLA_sp ---- 1110 0.01 .... .... 1010 .1.0 .... \
104
#include "net/net.h"
85
- vm=%vm_sp vn=%vn_sp vd=%vd_sp
105
#include "sysemu/sysemu.h"
86
-VNMLA_dp ---- 1110 0.01 .... .... 1011 .1.0 .... \
106
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
87
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
107
index XXXXXXX..XXXXXXX 100644
88
+VNMLA_sp ---- 1110 0.01 .... .... 1010 .1.0 .... @vfp_dnm_s
108
--- a/hw/net/lan9118.c
89
+VNMLA_dp ---- 1110 0.01 .... .... 1011 .1.0 .... @vfp_dnm_d
109
+++ b/hw/net/lan9118.c
90
110
@@ -XXX,XX +XXX,XX @@
91
-VMUL_sp ---- 1110 0.10 .... .... 1010 .0.0 .... \
111
#include "hw/sysbus.h"
92
- vm=%vm_sp vn=%vn_sp vd=%vd_sp
112
#include "net/net.h"
93
-VMUL_dp ---- 1110 0.10 .... .... 1011 .0.0 .... \
113
#include "net/eth.h"
94
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
114
-#include "hw/devices.h"
95
+VMUL_sp ---- 1110 0.10 .... .... 1010 .0.0 .... @vfp_dnm_s
115
+#include "hw/net/lan9118.h"
96
+VMUL_dp ---- 1110 0.10 .... .... 1011 .0.0 .... @vfp_dnm_d
116
#include "sysemu/sysemu.h"
97
117
#include "hw/ptimer.h"
98
-VNMUL_sp ---- 1110 0.10 .... .... 1010 .1.0 .... \
118
#include "qemu/log.h"
99
- vm=%vm_sp vn=%vn_sp vd=%vd_sp
100
-VNMUL_dp ---- 1110 0.10 .... .... 1011 .1.0 .... \
101
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
102
+VNMUL_sp ---- 1110 0.10 .... .... 1010 .1.0 .... @vfp_dnm_s
103
+VNMUL_dp ---- 1110 0.10 .... .... 1011 .1.0 .... @vfp_dnm_d
104
105
-VADD_sp ---- 1110 0.11 .... .... 1010 .0.0 .... \
106
- vm=%vm_sp vn=%vn_sp vd=%vd_sp
107
-VADD_dp ---- 1110 0.11 .... .... 1011 .0.0 .... \
108
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
109
+VADD_sp ---- 1110 0.11 .... .... 1010 .0.0 .... @vfp_dnm_s
110
+VADD_dp ---- 1110 0.11 .... .... 1011 .0.0 .... @vfp_dnm_d
111
112
-VSUB_sp ---- 1110 0.11 .... .... 1010 .1.0 .... \
113
- vm=%vm_sp vn=%vn_sp vd=%vd_sp
114
-VSUB_dp ---- 1110 0.11 .... .... 1011 .1.0 .... \
115
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
116
+VSUB_sp ---- 1110 0.11 .... .... 1010 .1.0 .... @vfp_dnm_s
117
+VSUB_dp ---- 1110 0.11 .... .... 1011 .1.0 .... @vfp_dnm_d
118
119
-VDIV_sp ---- 1110 1.00 .... .... 1010 .0.0 .... \
120
- vm=%vm_sp vn=%vn_sp vd=%vd_sp
121
-VDIV_dp ---- 1110 1.00 .... .... 1011 .0.0 .... \
122
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
123
+VDIV_sp ---- 1110 1.00 .... .... 1010 .0.0 .... @vfp_dnm_s
124
+VDIV_dp ---- 1110 1.00 .... .... 1011 .0.0 .... @vfp_dnm_d
125
126
VFM_sp ---- 1110 1.01 .... .... 1010 . o2:1 . 0 .... \
127
vm=%vm_sp vn=%vn_sp vd=%vd_sp o1=1
128
@@ -XXX,XX +XXX,XX @@ VMOV_imm_sp ---- 1110 1.11 .... .... 1010 0000 .... \
129
VMOV_imm_dp ---- 1110 1.11 .... .... 1011 0000 .... \
130
vd=%vd_dp imm=%vmov_imm
131
132
-VMOV_reg_sp ---- 1110 1.11 0000 .... 1010 01.0 .... \
133
- vd=%vd_sp vm=%vm_sp
134
-VMOV_reg_dp ---- 1110 1.11 0000 .... 1011 01.0 .... \
135
- vd=%vd_dp vm=%vm_dp
136
+VMOV_reg_sp ---- 1110 1.11 0000 .... 1010 01.0 .... @vfp_dm_ss
137
+VMOV_reg_dp ---- 1110 1.11 0000 .... 1011 01.0 .... @vfp_dm_dd
138
139
-VABS_sp ---- 1110 1.11 0000 .... 1010 11.0 .... \
140
- vd=%vd_sp vm=%vm_sp
141
-VABS_dp ---- 1110 1.11 0000 .... 1011 11.0 .... \
142
- vd=%vd_dp vm=%vm_dp
143
+VABS_sp ---- 1110 1.11 0000 .... 1010 11.0 .... @vfp_dm_ss
144
+VABS_dp ---- 1110 1.11 0000 .... 1011 11.0 .... @vfp_dm_dd
145
146
-VNEG_sp ---- 1110 1.11 0001 .... 1010 01.0 .... \
147
- vd=%vd_sp vm=%vm_sp
148
-VNEG_dp ---- 1110 1.11 0001 .... 1011 01.0 .... \
149
- vd=%vd_dp vm=%vm_dp
150
+VNEG_sp ---- 1110 1.11 0001 .... 1010 01.0 .... @vfp_dm_ss
151
+VNEG_dp ---- 1110 1.11 0001 .... 1011 01.0 .... @vfp_dm_dd
152
153
-VSQRT_sp ---- 1110 1.11 0001 .... 1010 11.0 .... \
154
- vd=%vd_sp vm=%vm_sp
155
-VSQRT_dp ---- 1110 1.11 0001 .... 1011 11.0 .... \
156
- vd=%vd_dp vm=%vm_dp
157
+VSQRT_sp ---- 1110 1.11 0001 .... 1010 11.0 .... @vfp_dm_ss
158
+VSQRT_dp ---- 1110 1.11 0001 .... 1011 11.0 .... @vfp_dm_dd
159
160
VCMP_sp ---- 1110 1.11 010 z:1 .... 1010 e:1 1.0 .... \
161
vd=%vd_sp vm=%vm_sp
162
@@ -XXX,XX +XXX,XX @@ VCVT_f32_f16 ---- 1110 1.11 0010 .... 1010 t:1 1.0 .... \
163
VCVT_f64_f16 ---- 1110 1.11 0010 .... 1011 t:1 1.0 .... \
164
vd=%vd_dp vm=%vm_sp
165
166
-# VCVTB and VCVTT to f16: Vd format is always vd_sp; Vm format depends on size bit
167
+# VCVTB and VCVTT to f16: Vd format is always vd_sp;
168
+# Vm format depends on size bit
169
VCVT_f16_f32 ---- 1110 1.11 0011 .... 1010 t:1 1.0 .... \
170
vd=%vd_sp vm=%vm_sp
171
VCVT_f16_f64 ---- 1110 1.11 0011 .... 1011 t:1 1.0 .... \
172
vd=%vd_sp vm=%vm_dp
173
174
-VRINTR_sp ---- 1110 1.11 0110 .... 1010 01.0 .... \
175
- vd=%vd_sp vm=%vm_sp
176
-VRINTR_dp ---- 1110 1.11 0110 .... 1011 01.0 .... \
177
- vd=%vd_dp vm=%vm_dp
178
+VRINTR_sp ---- 1110 1.11 0110 .... 1010 01.0 .... @vfp_dm_ss
179
+VRINTR_dp ---- 1110 1.11 0110 .... 1011 01.0 .... @vfp_dm_dd
180
181
-VRINTZ_sp ---- 1110 1.11 0110 .... 1010 11.0 .... \
182
- vd=%vd_sp vm=%vm_sp
183
-VRINTZ_dp ---- 1110 1.11 0110 .... 1011 11.0 .... \
184
- vd=%vd_dp vm=%vm_dp
185
+VRINTZ_sp ---- 1110 1.11 0110 .... 1010 11.0 .... @vfp_dm_ss
186
+VRINTZ_dp ---- 1110 1.11 0110 .... 1011 11.0 .... @vfp_dm_dd
187
188
-VRINTX_sp ---- 1110 1.11 0111 .... 1010 01.0 .... \
189
- vd=%vd_sp vm=%vm_sp
190
-VRINTX_dp ---- 1110 1.11 0111 .... 1011 01.0 .... \
191
- vd=%vd_dp vm=%vm_dp
192
+VRINTX_sp ---- 1110 1.11 0111 .... 1010 01.0 .... @vfp_dm_ss
193
+VRINTX_dp ---- 1110 1.11 0111 .... 1011 01.0 .... @vfp_dm_dd
194
195
-# VCVT between single and double: Vm precision depends on size; Vd is its reverse
196
-VCVT_sp ---- 1110 1.11 0111 .... 1010 11.0 .... \
197
- vd=%vd_dp vm=%vm_sp
198
-VCVT_dp ---- 1110 1.11 0111 .... 1011 11.0 .... \
199
- vd=%vd_sp vm=%vm_dp
200
+# VCVT between single and double:
201
+# Vm precision depends on size; Vd is its reverse
202
+VCVT_sp ---- 1110 1.11 0111 .... 1010 11.0 .... @vfp_dm_ds
203
+VCVT_dp ---- 1110 1.11 0111 .... 1011 11.0 .... @vfp_dm_sd
204
205
# VCVT from integer to floating point: Vm always single; Vd depends on size
206
VCVT_int_sp ---- 1110 1.11 1000 .... 1010 s:1 1.0 .... \
207
@@ -XXX,XX +XXX,XX @@ VCVT_int_dp ---- 1110 1.11 1000 .... 1011 s:1 1.0 .... \
208
vd=%vd_dp vm=%vm_sp
209
210
# VJCVT is always dp to sp
211
-VJCVT ---- 1110 1.11 1001 .... 1011 11.0 .... \
212
- vd=%vd_sp vm=%vm_dp
213
+VJCVT ---- 1110 1.11 1001 .... 1011 11.0 .... @vfp_dm_sd
214
215
# VCVT between floating-point and fixed-point. The immediate value
216
# is in the same format as a Vm single-precision register number.
119
--
217
--
120
2.20.1
218
2.20.1
121
219
122
220
diff view generated by jsdifflib
1
The magic value pushed onto the callee stack as an integrity
1
From: Richard Henderson <richard.henderson@linaro.org>
2
check is different if floating point is present.
3
2
3
Passing the raw o1 and o2 fields from the manual is less
4
instructive than it might be. Do the full decode and let
5
the trans_* functions pass in booleans to a helper.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200224222232.13807-17-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20190416125744.27770-15-peter.maydell@linaro.org
7
---
11
---
8
target/arm/helper.c | 22 +++++++++++++++++++---
12
target/arm/translate-vfp.inc.c | 52 ++++++++++++++++++++++++++++++----
9
1 file changed, 19 insertions(+), 3 deletions(-)
13
target/arm/vfp.decode | 17 +++++------
14
2 files changed, 55 insertions(+), 14 deletions(-)
10
15
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
18
--- a/target/arm/translate-vfp.inc.c
14
+++ b/target/arm/helper.c
19
+++ b/target/arm/translate-vfp.inc.c
15
@@ -XXX,XX +XXX,XX @@ load_fail:
20
@@ -XXX,XX +XXX,XX @@ static bool trans_VDIV_dp(DisasContext *s, arg_VDIV_dp *a)
16
return false;
21
return do_vfp_3op_dp(s, gen_helper_vfp_divd, a->vd, a->vn, a->vm, false);
17
}
22
}
18
23
19
+static uint32_t v7m_integrity_sig(CPUARMState *env, uint32_t lr)
24
-static bool trans_VFM_sp(DisasContext *s, arg_VFM_sp *a)
25
+static bool do_vfm_sp(DisasContext *s, arg_VFMA_sp *a, bool neg_n, bool neg_d)
26
{
27
/*
28
* VFNMA : fd = muladd(-fd, fn, fm)
29
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_sp(DisasContext *s, arg_VFM_sp *a)
30
31
neon_load_reg32(vn, a->vn);
32
neon_load_reg32(vm, a->vm);
33
- if (a->o2) {
34
+ if (neg_n) {
35
/* VFNMS, VFMS */
36
gen_helper_vfp_negs(vn, vn);
37
}
38
neon_load_reg32(vd, a->vd);
39
- if (a->o1 & 1) {
40
+ if (neg_d) {
41
/* VFNMA, VFNMS */
42
gen_helper_vfp_negs(vd, vd);
43
}
44
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_sp(DisasContext *s, arg_VFM_sp *a)
45
return true;
46
}
47
48
-static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
49
+static bool trans_VFMA_sp(DisasContext *s, arg_VFMA_sp *a)
20
+{
50
+{
21
+ /*
51
+ return do_vfm_sp(s, a, false, false);
22
+ * Return the integrity signature value for the callee-saves
23
+ * stack frame section. @lr is the exception return payload/LR value
24
+ * whose FType bit forms bit 0 of the signature if FP is present.
25
+ */
26
+ uint32_t sig = 0xfefa125a;
27
+
28
+ if (!arm_feature(env, ARM_FEATURE_VFP) || (lr & R_V7M_EXCRET_FTYPE_MASK)) {
29
+ sig |= 1;
30
+ }
31
+ return sig;
32
+}
52
+}
33
+
53
+
34
static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
54
+static bool trans_VFMS_sp(DisasContext *s, arg_VFMS_sp *a)
35
bool ignore_faults)
55
+{
56
+ return do_vfm_sp(s, a, true, false);
57
+}
58
+
59
+static bool trans_VFNMA_sp(DisasContext *s, arg_VFNMA_sp *a)
60
+{
61
+ return do_vfm_sp(s, a, false, true);
62
+}
63
+
64
+static bool trans_VFNMS_sp(DisasContext *s, arg_VFNMS_sp *a)
65
+{
66
+ return do_vfm_sp(s, a, true, true);
67
+}
68
+
69
+static bool do_vfm_dp(DisasContext *s, arg_VFMA_dp *a, bool neg_n, bool neg_d)
36
{
70
{
37
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
71
/*
38
bool stacked_ok;
72
* VFNMA : fd = muladd(-fd, fn, fm)
39
uint32_t limit;
73
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
40
bool want_psp;
74
41
+ uint32_t sig;
75
neon_load_reg64(vn, a->vn);
42
76
neon_load_reg64(vm, a->vm);
43
if (dotailchain) {
77
- if (a->o2) {
44
bool mode = lr & R_V7M_EXCRET_MODE_MASK;
78
+ if (neg_n) {
45
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
79
/* VFNMS, VFMS */
46
/* Write as much of the stack frame as we can. A write failure may
80
gen_helper_vfp_negd(vn, vn);
47
* cause us to pend a derived exception.
81
}
48
*/
82
neon_load_reg64(vd, a->vd);
49
+ sig = v7m_integrity_sig(env, lr);
83
- if (a->o1 & 1) {
50
stacked_ok =
84
+ if (neg_d) {
51
- v7m_stack_write(cpu, frameptr, 0xfefa125b, mmu_idx, ignore_faults) &&
85
/* VFNMA, VFNMS */
52
+ v7m_stack_write(cpu, frameptr, sig, mmu_idx, ignore_faults) &&
86
gen_helper_vfp_negd(vd, vd);
53
v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
87
}
54
ignore_faults) &&
88
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
55
v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
89
return true;
56
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
90
}
57
if (return_to_secure &&
91
58
((excret & R_V7M_EXCRET_ES_MASK) == 0 ||
92
+static bool trans_VFMA_dp(DisasContext *s, arg_VFMA_dp *a)
59
(excret & R_V7M_EXCRET_DCRS_MASK) == 0)) {
93
+{
60
- uint32_t expected_sig = 0xfefa125b;
94
+ return do_vfm_dp(s, a, false, false);
61
uint32_t actual_sig;
95
+}
62
96
+
63
pop_ok = v7m_stack_read(cpu, &actual_sig, frameptr, mmu_idx);
97
+static bool trans_VFMS_dp(DisasContext *s, arg_VFMS_dp *a)
64
98
+{
65
- if (pop_ok && expected_sig != actual_sig) {
99
+ return do_vfm_dp(s, a, true, false);
66
+ if (pop_ok && v7m_integrity_sig(env, excret) != actual_sig) {
100
+}
67
/* Take a SecureFault on the current stack */
101
+
68
env->v7m.sfsr |= R_V7M_SFSR_INVIS_MASK;
102
+static bool trans_VFNMA_dp(DisasContext *s, arg_VFNMA_dp *a)
69
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
103
+{
104
+ return do_vfm_dp(s, a, false, true);
105
+}
106
+
107
+static bool trans_VFNMS_dp(DisasContext *s, arg_VFNMS_dp *a)
108
+{
109
+ return do_vfm_dp(s, a, true, true);
110
+}
111
+
112
static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
113
{
114
uint32_t delta_d = 0;
115
diff --git a/target/arm/vfp.decode b/target/arm/vfp.decode
116
index XXXXXXX..XXXXXXX 100644
117
--- a/target/arm/vfp.decode
118
+++ b/target/arm/vfp.decode
119
@@ -XXX,XX +XXX,XX @@ VSUB_dp ---- 1110 0.11 .... .... 1011 .1.0 .... @vfp_dnm_d
120
VDIV_sp ---- 1110 1.00 .... .... 1010 .0.0 .... @vfp_dnm_s
121
VDIV_dp ---- 1110 1.00 .... .... 1011 .0.0 .... @vfp_dnm_d
122
123
-VFM_sp ---- 1110 1.01 .... .... 1010 . o2:1 . 0 .... \
124
- vm=%vm_sp vn=%vn_sp vd=%vd_sp o1=1
125
-VFM_dp ---- 1110 1.01 .... .... 1011 . o2:1 . 0 .... \
126
- vm=%vm_dp vn=%vn_dp vd=%vd_dp o1=1
127
-VFM_sp ---- 1110 1.10 .... .... 1010 . o2:1 . 0 .... \
128
- vm=%vm_sp vn=%vn_sp vd=%vd_sp o1=2
129
-VFM_dp ---- 1110 1.10 .... .... 1011 . o2:1 . 0 .... \
130
- vm=%vm_dp vn=%vn_dp vd=%vd_dp o1=2
131
+VFMA_sp ---- 1110 1.10 .... .... 1010 .0. 0 .... @vfp_dnm_s
132
+VFMS_sp ---- 1110 1.10 .... .... 1010 .1. 0 .... @vfp_dnm_s
133
+VFNMA_sp ---- 1110 1.01 .... .... 1010 .0. 0 .... @vfp_dnm_s
134
+VFNMS_sp ---- 1110 1.01 .... .... 1010 .1. 0 .... @vfp_dnm_s
135
+
136
+VFMA_dp ---- 1110 1.10 .... .... 1011 .0.0 .... @vfp_dnm_d
137
+VFMS_dp ---- 1110 1.10 .... .... 1011 .1.0 .... @vfp_dnm_d
138
+VFNMA_dp ---- 1110 1.01 .... .... 1011 .0.0 .... @vfp_dnm_d
139
+VFNMS_dp ---- 1110 1.01 .... .... 1011 .1.0 .... @vfp_dnm_d
140
141
VMOV_imm_sp ---- 1110 1.11 .... .... 1010 0000 .... \
142
vd=%vd_sp imm=%vmov_imm
70
--
143
--
71
2.20.1
144
2.20.1
72
145
73
146
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The SMMUNotifierNode struct is not necessary and brings extra
3
Passing the raw op field from the manual is less instructive
4
complexity so let's remove it. We now directly track the SMMUDevices
4
than it might be. Do the full decode and use the existing
5
which have registered IOMMU MR notifiers.
5
helpers to perform the expansion.
6
6
7
This is inspired from the same transformation on intel-iommu
7
Since these are v8 insns, VECLEN+VECSTRIDE are already RES0.
8
done in commit b4a4ba0d68f50f218ee3957b6638dbee32a5eeef
9
("intel-iommu: remove IntelIOMMUNotifierNode")
10
8
11
Signed-off-by: Eric Auger <eric.auger@redhat.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Peter Xu <peterx@redhat.com>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20190409160219.19026-1-eric.auger@redhat.com
11
Message-id: 20200224222232.13807-18-richard.henderson@linaro.org
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
target/arm/translate-vfp.inc.c | 109 +++++++++++----------------------
17
hw/arm/smmu-common.c | 6 +++---
15
target/arm/vfp-uncond.decode | 12 ++--
18
hw/arm/smmuv3.c | 28 +++++++---------------------
16
2 files changed, 44 insertions(+), 77 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/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
22
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/smmu-common.h
20
--- a/target/arm/translate-vfp.inc.c
24
+++ b/include/hw/arm/smmu-common.h
21
+++ b/target/arm/translate-vfp.inc.c
25
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUDevice {
22
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
26
AddressSpace as;
23
return true;
27
uint32_t cfg_cache_hits;
24
}
28
uint32_t cfg_cache_misses;
25
29
+ QLIST_ENTRY(SMMUDevice) next;
26
-static bool trans_VMINMAXNM(DisasContext *s, arg_VMINMAXNM *a)
30
} SMMUDevice;
27
-{
31
28
- uint32_t rd, rn, rm;
32
-typedef struct SMMUNotifierNode {
29
- bool dp = a->dp;
33
- SMMUDevice *sdev;
30
- bool vmin = a->op;
34
- QLIST_ENTRY(SMMUNotifierNode) next;
31
- TCGv_ptr fpst;
35
-} SMMUNotifierNode;
36
-
32
-
37
typedef struct SMMUPciBus {
33
- if (!dc_isar_feature(aa32_vminmaxnm, s)) {
38
PCIBus *bus;
34
- return false;
39
SMMUDevice *pbdev[0]; /* Parent array is sparse, so dynamically alloc */
40
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUState {
41
GHashTable *iotlb;
42
SMMUPciBus *smmu_pcibus_by_bus_num[SMMU_PCI_BUS_MAX];
43
PCIBus *pci_bus;
44
- QLIST_HEAD(, SMMUNotifierNode) notifiers_list;
45
+ QLIST_HEAD(, SMMUDevice) devices_with_notifiers;
46
uint8_t bus_num;
47
PCIBus *primary_bus;
48
} SMMUState;
49
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/smmu-common.c
52
+++ b/hw/arm/smmu-common.c
53
@@ -XXX,XX +XXX,XX @@ inline void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
54
/* Unmap all notifiers of all mr's */
55
void smmu_inv_notifiers_all(SMMUState *s)
56
{
57
- SMMUNotifierNode *node;
58
+ SMMUDevice *sdev;
59
60
- QLIST_FOREACH(node, &s->notifiers_list, next) {
61
- smmu_inv_notifiers_mr(&node->sdev->iommu);
62
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
63
+ smmu_inv_notifiers_mr(&sdev->iommu);
64
}
65
}
66
67
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/hw/arm/smmuv3.c
70
+++ b/hw/arm/smmuv3.c
71
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
72
/* invalidate an asid/iova tuple in all mr's */
73
static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova)
74
{
75
- SMMUNotifierNode *node;
76
+ SMMUDevice *sdev;
77
78
- QLIST_FOREACH(node, &s->notifiers_list, next) {
79
- IOMMUMemoryRegion *mr = &node->sdev->iommu;
80
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
81
+ IOMMUMemoryRegion *mr = &sdev->iommu;
82
IOMMUNotifier *n;
83
84
trace_smmuv3_inv_notifiers_iova(mr->parent_obj.name, asid, iova);
85
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
86
SMMUDevice *sdev = container_of(iommu, SMMUDevice, iommu);
87
SMMUv3State *s3 = sdev->smmu;
88
SMMUState *s = &(s3->smmu_state);
89
- SMMUNotifierNode *node = NULL;
90
- SMMUNotifierNode *next_node = NULL;
91
92
if (new & IOMMU_NOTIFIER_MAP) {
93
int bus_num = pci_bus_num(sdev->bus);
94
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
95
96
if (old == IOMMU_NOTIFIER_NONE) {
97
trace_smmuv3_notify_flag_add(iommu->parent_obj.name);
98
- node = g_malloc0(sizeof(*node));
99
- node->sdev = sdev;
100
- QLIST_INSERT_HEAD(&s->notifiers_list, node, next);
101
- return;
102
- }
35
- }
103
-
36
-
104
- /* update notifier node with new flags */
37
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
105
- QLIST_FOREACH_SAFE(node, &s->notifiers_list, next, next_node) {
38
- return false;
106
- if (node->sdev == sdev) {
39
- }
107
- if (new == IOMMU_NOTIFIER_NONE) {
40
-
108
- trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
41
- /* UNDEF accesses to D16-D31 if they don't exist */
109
- QLIST_REMOVE(node, next);
42
- if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
110
- g_free(node);
43
- ((a->vm | a->vn | a->vd) & 0x10)) {
111
- }
44
- return false;
112
- return;
45
- }
46
-
47
- rd = a->vd;
48
- rn = a->vn;
49
- rm = a->vm;
50
-
51
- if (!vfp_access_check(s)) {
52
- return true;
53
- }
54
-
55
- fpst = get_fpstatus_ptr(0);
56
-
57
- if (dp) {
58
- TCGv_i64 frn, frm, dest;
59
-
60
- frn = tcg_temp_new_i64();
61
- frm = tcg_temp_new_i64();
62
- dest = tcg_temp_new_i64();
63
-
64
- neon_load_reg64(frn, rn);
65
- neon_load_reg64(frm, rm);
66
- if (vmin) {
67
- gen_helper_vfp_minnumd(dest, frn, frm, fpst);
68
- } else {
69
- gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
113
- }
70
- }
114
+ QLIST_INSERT_HEAD(&s->devices_with_notifiers, sdev, next);
71
- neon_store_reg64(dest, rd);
115
+ } else if (new == IOMMU_NOTIFIER_NONE) {
72
- tcg_temp_free_i64(frn);
116
+ trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
73
- tcg_temp_free_i64(frm);
117
+ QLIST_REMOVE(sdev, next);
74
- tcg_temp_free_i64(dest);
118
}
75
- } else {
76
- TCGv_i32 frn, frm, dest;
77
-
78
- frn = tcg_temp_new_i32();
79
- frm = tcg_temp_new_i32();
80
- dest = tcg_temp_new_i32();
81
-
82
- neon_load_reg32(frn, rn);
83
- neon_load_reg32(frm, rm);
84
- if (vmin) {
85
- gen_helper_vfp_minnums(dest, frn, frm, fpst);
86
- } else {
87
- gen_helper_vfp_maxnums(dest, frn, frm, fpst);
88
- }
89
- neon_store_reg32(dest, rd);
90
- tcg_temp_free_i32(frn);
91
- tcg_temp_free_i32(frm);
92
- tcg_temp_free_i32(dest);
93
- }
94
-
95
- tcg_temp_free_ptr(fpst);
96
- return true;
97
-}
98
-
99
/*
100
* Table for converting the most common AArch32 encoding of
101
* rounding mode to arm_fprounding order (which matches the
102
@@ -XXX,XX +XXX,XX @@ static bool trans_VDIV_dp(DisasContext *s, arg_VDIV_dp *a)
103
return do_vfp_3op_dp(s, gen_helper_vfp_divd, a->vd, a->vn, a->vm, false);
119
}
104
}
120
105
106
+static bool trans_VMINNM_sp(DisasContext *s, arg_VMINNM_sp *a)
107
+{
108
+ if (!dc_isar_feature(aa32_vminmaxnm, s)) {
109
+ return false;
110
+ }
111
+ return do_vfp_3op_sp(s, gen_helper_vfp_minnums,
112
+ a->vd, a->vn, a->vm, false);
113
+}
114
+
115
+static bool trans_VMAXNM_sp(DisasContext *s, arg_VMAXNM_sp *a)
116
+{
117
+ if (!dc_isar_feature(aa32_vminmaxnm, s)) {
118
+ return false;
119
+ }
120
+ return do_vfp_3op_sp(s, gen_helper_vfp_maxnums,
121
+ a->vd, a->vn, a->vm, false);
122
+}
123
+
124
+static bool trans_VMINNM_dp(DisasContext *s, arg_VMINNM_dp *a)
125
+{
126
+ if (!dc_isar_feature(aa32_vminmaxnm, s)) {
127
+ return false;
128
+ }
129
+ return do_vfp_3op_dp(s, gen_helper_vfp_minnumd,
130
+ a->vd, a->vn, a->vm, false);
131
+}
132
+
133
+static bool trans_VMAXNM_dp(DisasContext *s, arg_VMAXNM_dp *a)
134
+{
135
+ if (!dc_isar_feature(aa32_vminmaxnm, s)) {
136
+ return false;
137
+ }
138
+ return do_vfp_3op_dp(s, gen_helper_vfp_maxnumd,
139
+ a->vd, a->vn, a->vm, false);
140
+}
141
+
142
static bool do_vfm_sp(DisasContext *s, arg_VFMA_sp *a, bool neg_n, bool neg_d)
143
{
144
/*
145
diff --git a/target/arm/vfp-uncond.decode b/target/arm/vfp-uncond.decode
146
index XXXXXXX..XXXXXXX 100644
147
--- a/target/arm/vfp-uncond.decode
148
+++ b/target/arm/vfp-uncond.decode
149
@@ -XXX,XX +XXX,XX @@
150
%vd_dp 22:1 12:4
151
%vd_sp 12:4 22:1
152
153
+@vfp_dnm_s ................................ vm=%vm_sp vn=%vn_sp vd=%vd_sp
154
+@vfp_dnm_d ................................ vm=%vm_dp vn=%vn_dp vd=%vd_dp
155
+
156
VSEL 1111 1110 0. cc:2 .... .... 1010 .0.0 .... \
157
vm=%vm_sp vn=%vn_sp vd=%vd_sp dp=0
158
VSEL 1111 1110 0. cc:2 .... .... 1011 .0.0 .... \
159
vm=%vm_dp vn=%vn_dp vd=%vd_dp dp=1
160
161
-VMINMAXNM 1111 1110 1.00 .... .... 1010 . op:1 .0 .... \
162
- vm=%vm_sp vn=%vn_sp vd=%vd_sp dp=0
163
-VMINMAXNM 1111 1110 1.00 .... .... 1011 . op:1 .0 .... \
164
- vm=%vm_dp vn=%vn_dp vd=%vd_dp dp=1
165
+VMAXNM_sp 1111 1110 1.00 .... .... 1010 .0.0 .... @vfp_dnm_s
166
+VMINNM_sp 1111 1110 1.00 .... .... 1010 .1.0 .... @vfp_dnm_s
167
+
168
+VMAXNM_dp 1111 1110 1.00 .... .... 1011 .0.0 .... @vfp_dnm_d
169
+VMINNM_dp 1111 1110 1.00 .... .... 1011 .1.0 .... @vfp_dnm_d
170
171
VRINT 1111 1110 1.11 10 rm:2 .... 1010 01.0 .... \
172
vm=%vm_sp vd=%vd_sp dp=0
121
--
173
--
122
2.20.1
174
2.20.1
123
175
124
176
diff view generated by jsdifflib
Deleted patch
1
In the stripe8() function we use a variable length array; however
2
we know that the maximum length required is MAX_NUM_BUSSES. Use
3
a fixed-length array and an assert instead.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
10
Message-id: 20190328152635.2794-1-peter.maydell@linaro.org
11
---
12
hw/ssi/xilinx_spips.c | 6 ++++--
13
1 file changed, 4 insertions(+), 2 deletions(-)
14
15
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/ssi/xilinx_spips.c
18
+++ b/hw/ssi/xilinx_spips.c
19
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_reset(DeviceState *d)
20
21
static inline void stripe8(uint8_t *x, int num, bool dir)
22
{
23
- uint8_t r[num];
24
- memset(r, 0, sizeof(uint8_t) * num);
25
+ uint8_t r[MAX_NUM_BUSSES];
26
int idx[2] = {0, 0};
27
int bit[2] = {0, 7};
28
int d = dir;
29
30
+ assert(num <= MAX_NUM_BUSSES);
31
+ memset(r, 0, sizeof(uint8_t) * num);
32
+
33
for (idx[0] = 0; idx[0] < num; ++idx[0]) {
34
for (bit[0] = 7; bit[0] >= 0; bit[0]--) {
35
r[idx[!d]] |= x[idx[d]] & 1 << bit[d] ? 1 << bit[!d] : 0;
36
--
37
2.20.1
38
39
diff view generated by jsdifflib
Deleted patch
1
Normally configure identifies the source path by looking
2
at the location where the configure script itself exists.
3
We also provide a --source-path option which lets the user
4
manually override this.
5
1
6
There isn't really an obvious use case for the --source-path
7
option, and in commit 927128222b0a91f56c13a in 2017 we
8
accidentally added some logic that looks at $source_path
9
before the command line option that overrides it has been
10
processed.
11
12
The fact that nobody complained suggests that there isn't
13
any use of this option and we aren't testing it either;
14
remove it. This allows us to move the "make $source_path
15
absolute" logic up so that there is no window in the script
16
where $source_path is set but not yet absolute.
17
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
20
Message-id: 20190318134019.23729-1-peter.maydell@linaro.org
21
---
22
configure | 10 ++--------
23
1 file changed, 2 insertions(+), 8 deletions(-)
24
25
diff --git a/configure b/configure
26
index XXXXXXX..XXXXXXX 100755
27
--- a/configure
28
+++ b/configure
29
@@ -XXX,XX +XXX,XX @@ ld_has() {
30
31
# default parameters
32
source_path=$(dirname "$0")
33
+# make source path absolute
34
+source_path=$(cd "$source_path"; pwd)
35
cpu=""
36
iasl="iasl"
37
interp_prefix="/usr/gnemul/qemu-%M"
38
@@ -XXX,XX +XXX,XX @@ for opt do
39
;;
40
--cxx=*) CXX="$optarg"
41
;;
42
- --source-path=*) source_path="$optarg"
43
- ;;
44
--cpu=*) cpu="$optarg"
45
;;
46
--extra-cflags=*) QEMU_CFLAGS="$QEMU_CFLAGS $optarg"
47
@@ -XXX,XX +XXX,XX @@ if test "$debug_info" = "yes"; then
48
LDFLAGS="-g $LDFLAGS"
49
fi
50
51
-# make source path absolute
52
-source_path=$(cd "$source_path"; pwd)
53
-
54
# running configure in the source tree?
55
# we know that's the case if configure is there.
56
if test -f "./configure"; then
57
@@ -XXX,XX +XXX,XX @@ for opt do
58
;;
59
--interp-prefix=*) interp_prefix="$optarg"
60
;;
61
- --source-path=*)
62
- ;;
63
--cross-prefix=*)
64
;;
65
--cc=*)
66
@@ -XXX,XX +XXX,XX @@ $(echo Available targets: $default_target_list | \
67
--target-list-exclude=LIST exclude a set of targets from the default target-list
68
69
Advanced options (experts only):
70
- --source-path=PATH path of source code [$source_path]
71
--cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]
72
--cc=CC use C compiler CC [$cc]
73
--iasl=IASL use ACPI compiler IASL [$iasl]
74
--
75
2.20.1
76
77
diff view generated by jsdifflib
Deleted patch
1
Enforce that for M-profile various FPSCR bits which are RES0 there
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
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-2-peter.maydell@linaro.org
9
---
10
target/arm/vfp_helper.c | 8 ++++++++
11
1 file changed, 8 insertions(+)
12
13
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/vfp_helper.c
16
+++ b/target/arm/vfp_helper.c
17
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
18
val &= ~FPCR_FZ16;
19
}
20
21
+ if (arm_feature(env, ARM_FEATURE_M)) {
22
+ /*
23
+ * M profile FPSCR is RES0 for the QC, STRIDE, FZ16, LEN bits
24
+ * and also for the trapped-exception-handling bits IxE.
25
+ */
26
+ val &= 0xf7c0009f;
27
+ }
28
+
29
/*
30
* We don't implement trapped exception handling, so the
31
* trap enable bits, IDE|IXE|UFE|OFE|DZE|IOE are all RAZ/WI (not RES0!)
32
--
33
2.20.1
34
35
diff view generated by jsdifflib
Deleted patch
1
For M-profile the MVFR* ID registers are memory mapped, in the
2
range we implement via the NVIC. Allow them to be read.
3
(If the CPU has no FPU, these registers are defined to be RAZ.)
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190416125744.27770-3-peter.maydell@linaro.org
8
---
9
hw/intc/armv7m_nvic.c | 6 ++++++
10
1 file changed, 6 insertions(+)
11
12
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/intc/armv7m_nvic.c
15
+++ b/hw/intc/armv7m_nvic.c
16
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
17
return 0;
18
}
19
return cpu->env.v7m.sfar;
20
+ case 0xf40: /* MVFR0 */
21
+ return cpu->isar.mvfr0;
22
+ case 0xf44: /* MVFR1 */
23
+ return cpu->isar.mvfr1;
24
+ case 0xf48: /* MVFR2 */
25
+ return cpu->isar.mvfr2;
26
default:
27
bad_offset:
28
qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
29
--
30
2.20.1
31
32
diff view generated by jsdifflib
Deleted patch
1
If the floating point extension is present, then the SG instruction
2
must clear the CONTROL_S.SFPA bit. Implement this.
3
1
4
(On a no-FPU system the bit will always be zero, so we don't need
5
to make the clearing of the bit conditional on ARM_FEATURE_VFP.)
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-8-peter.maydell@linaro.org
10
---
11
target/arm/helper.c | 1 +
12
1 file changed, 1 insertion(+)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
19
qemu_log_mask(CPU_LOG_INT, "...really an SG instruction at 0x%08" PRIx32
20
", executing it\n", env->regs[15]);
21
env->regs[14] &= ~1;
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
23
switch_v7m_security_state(env, true);
24
xpsr_write(env, 0, XPSR_IT);
25
env->regs[15] += 4;
26
--
27
2.20.1
28
29
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
Since uWireSlave is only used in this new header, there is no
3
USB ports on Xilinx Zync must be instantiated as TYPE_CHIPIDEA to work.
4
need to expose it via "qemu/typedefs.h".
4
Linux expects and checks various chipidea registers, which do not exist
5
with the basic ehci emulation. This patch series fixes the problem.
5
6
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
7
Without this patch, USB ports fail to instantiate under Linux.
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
8
Message-id: 20190412165416.7977-9-philmd@redhat.com
9
ci_hdrc ci_hdrc.0: doesn't support host
10
ci_hdrc ci_hdrc.0: no supported roles
11
12
With this patch, USB ports are instantiated, and it is possible
13
to boot from USB drive.
14
15
ci_hdrc ci_hdrc.0: EHCI Host Controller
16
ci_hdrc ci_hdrc.0: new USB bus registered, assigned bus number 1
17
ci_hdrc ci_hdrc.0: USB 2.0 started, EHCI 1.00
18
usb 1-1: new full-speed USB device number 2 using ci_hdrc
19
usb 1-1: not running at top speed; connect to a high speed hub
20
usb 1-1: config 1 interface 0 altsetting 0 endpoint 0x81 has invalid maxpacket 512, setting to 64
21
usb 1-1: config 1 interface 0 altsetting 0 endpoint 0x2 has invalid maxpacket 512, setting to 64
22
usb-storage 1-1:1.0: USB Mass Storage device detected
23
scsi host0: usb-storage 1-1:1.0
24
25
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
26
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
27
Message-id: 20200215122354.13706-2-linux@roeck-us.net
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
29
---
11
include/hw/arm/omap.h | 6 +-----
30
hw/arm/xilinx_zynq.c | 5 +++--
12
include/hw/devices.h | 15 ---------------
31
1 file changed, 3 insertions(+), 2 deletions(-)
13
include/hw/input/tsc2xxx.h | 36 ++++++++++++++++++++++++++++++++++++
14
include/qemu/typedefs.h | 1 -
15
hw/arm/nseries.c | 2 +-
16
hw/arm/palm.c | 2 +-
17
hw/input/tsc2005.c | 2 +-
18
hw/input/tsc210x.c | 4 ++--
19
MAINTAINERS | 2 ++
20
9 files changed, 44 insertions(+), 26 deletions(-)
21
create mode 100644 include/hw/input/tsc2xxx.h
22
32
23
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
33
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
24
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/omap.h
35
--- a/hw/arm/xilinx_zynq.c
26
+++ b/include/hw/arm/omap.h
36
+++ b/hw/arm/xilinx_zynq.c
27
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@
28
#include "exec/memory.h"
29
# define hw_omap_h        "omap.h"
30
#include "hw/irq.h"
31
+#include "hw/input/tsc2xxx.h"
32
#include "target/arm/cpu-qom.h"
33
#include "qemu/log.h"
34
35
@@ -XXX,XX +XXX,XX @@ qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s);
36
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler);
37
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down);
38
39
-struct uWireSlave {
40
- uint16_t (*receive)(void *opaque);
41
- void (*send)(void *opaque, uint16_t data);
42
- void *opaque;
43
-};
44
struct omap_uwire_s;
45
void omap_uwire_attach(struct omap_uwire_s *s,
46
uWireSlave *slave, int chipselect);
47
diff --git a/include/hw/devices.h b/include/hw/devices.h
48
index XXXXXXX..XXXXXXX 100644
49
--- a/include/hw/devices.h
50
+++ b/include/hw/devices.h
51
@@ -XXX,XX +XXX,XX @@
52
/* Devices that have nowhere better to go. */
53
54
#include "hw/hw.h"
55
-#include "ui/console.h"
56
57
/* smc91c111.c */
58
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
59
@@ -XXX,XX +XXX,XX @@ void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
60
/* lan9118.c */
61
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
62
63
-/* tsc210x.c */
64
-uWireSlave *tsc2102_init(qemu_irq pint);
65
-uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
66
-I2SCodec *tsc210x_codec(uWireSlave *chip);
67
-uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
68
-void tsc210x_set_transform(uWireSlave *chip,
69
- MouseTransformInfo *info);
70
-void tsc210x_key_event(uWireSlave *chip, int key, int down);
71
-
72
-/* tsc2005.c */
73
-void *tsc2005_init(qemu_irq pintdav);
74
-uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
75
-void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
76
-
77
#endif
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"
38
#include "hw/loader.h"
157
#include "exec/address-spaces.h"
39
#include "hw/misc/zynq-xadc.h"
158
#include "cpu.h"
40
#include "hw/ssi/ssi.h"
159
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
41
+#include "hw/usb/chipidea.h"
160
index XXXXXXX..XXXXXXX 100644
42
#include "qemu/error-report.h"
161
--- a/hw/input/tsc2005.c
43
#include "hw/sd/sdhci.h"
162
+++ b/hw/input/tsc2005.c
44
#include "hw/char/cadence_uart.h"
163
@@ -XXX,XX +XXX,XX @@
45
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
164
#include "hw/hw.h"
46
zynq_init_spi_flashes(0xE0007000, pic[81-IRQ_OFFSET], false);
165
#include "qemu/timer.h"
47
zynq_init_spi_flashes(0xE000D000, pic[51-IRQ_OFFSET], true);
166
#include "ui/console.h"
48
167
-#include "hw/devices.h"
49
- sysbus_create_simple("xlnx,ps7-usb", 0xE0002000, pic[53-IRQ_OFFSET]);
168
+#include "hw/input/tsc2xxx.h"
50
- sysbus_create_simple("xlnx,ps7-usb", 0xE0003000, pic[76-IRQ_OFFSET]);
169
#include "trace.h"
51
+ sysbus_create_simple(TYPE_CHIPIDEA, 0xE0002000, pic[53 - IRQ_OFFSET]);
170
52
+ sysbus_create_simple(TYPE_CHIPIDEA, 0xE0003000, pic[76 - IRQ_OFFSET]);
171
#define TSC_CUT_RESOLUTION(value, p)    ((value) >> (16 - (p ? 12 : 10)))
53
172
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
54
cadence_uart_create(0xE0000000, pic[59 - IRQ_OFFSET], serial_hd(0));
173
index XXXXXXX..XXXXXXX 100644
55
cadence_uart_create(0xE0001000, pic[82 - IRQ_OFFSET], serial_hd(1));
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
--
56
--
208
2.20.1
57
2.20.1
209
58
210
59
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
No code used the tc6393xb_gpio_in_get() and tc6393xb_gpio_out_set()
3
Xilinx USB devices are now instantiated through TYPE_CHIPIDEA,
4
functions since their introduction in commit 88d2c950b002. Time to
4
and xlnx support in the EHCI code is no longer needed.
5
remove them.
6
5
7
Suggested-by: Markus Armbruster <armbru@redhat.com>
6
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
9
Message-id: 20190412165416.7977-4-philmd@redhat.com
8
Message-id: 20200215122354.13706-3-linux@roeck-us.net
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
include/hw/devices.h | 3 ---
11
hw/usb/hcd-ehci-sysbus.c | 17 -----------------
14
hw/display/tc6393xb.c | 16 ----------------
12
1 file changed, 17 deletions(-)
15
2 files changed, 19 deletions(-)
16
13
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
14
diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/devices.h
16
--- a/hw/usb/hcd-ehci-sysbus.c
20
+++ b/include/hw/devices.h
17
+++ b/hw/usb/hcd-ehci-sysbus.c
21
@@ -XXX,XX +XXX,XX @@ void retu_key_event(void *retu, int state);
18
@@ -XXX,XX +XXX,XX @@ static const TypeInfo ehci_platform_type_info = {
22
typedef struct TC6393xbState TC6393xbState;
19
.class_init = ehci_platform_class_init,
23
TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
24
uint32_t base, qemu_irq irq);
25
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
26
- qemu_irq handler);
27
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s);
28
qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
29
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
};
20
};
38
21
39
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s)
22
-static void ehci_xlnx_class_init(ObjectClass *oc, void *data)
40
-{
23
-{
41
- return s->gpio_in;
24
- SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc);
25
- DeviceClass *dc = DEVICE_CLASS(oc);
26
-
27
- set_bit(DEVICE_CATEGORY_USB, dc->categories);
28
- sec->capsbase = 0x100;
29
- sec->opregbase = 0x140;
42
-}
30
-}
43
-
31
-
44
static void tc6393xb_gpio_set(void *opaque, int line, int level)
32
-static const TypeInfo ehci_xlnx_type_info = {
33
- .name = "xlnx,ps7-usb",
34
- .parent = TYPE_SYS_BUS_EHCI,
35
- .class_init = ehci_xlnx_class_init,
36
-};
37
-
38
static void ehci_exynos4210_class_init(ObjectClass *oc, void *data)
45
{
39
{
46
// TC6393xbState *s = opaque;
40
SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc);
47
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_gpio_set(void *opaque, int line, int level)
41
@@ -XXX,XX +XXX,XX @@ static void ehci_sysbus_register_types(void)
48
// FIXME: how does the chip reflect the GPIO input level change?
49
}
50
51
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
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
{
42
{
64
uint32_t level, diff;
43
type_register_static(&ehci_type_info);
44
type_register_static(&ehci_platform_type_info);
45
- type_register_static(&ehci_xlnx_type_info);
46
type_register_static(&ehci_exynos4210_type_info);
47
type_register_static(&ehci_tegra2_type_info);
48
type_register_static(&ehci_ppc4xx_type_info);
65
--
49
--
66
2.20.1
50
2.20.1
67
51
68
52
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
Old kernels from the Meego project can be used to check that Linux
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
is at least starting on these machines.
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
6
Message-id: 20190412165416.7977-7-philmd@redhat.com
6
Signed-off-by: Thomas Huth <thuth@redhat.com>
7
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20200225172501.29609-2-philmd@redhat.com
12
Message-Id: <20200129131920.22302-1-thuth@redhat.com>
13
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
15
---
9
include/hw/devices.h | 14 --------------
16
MAINTAINERS | 1 +
10
include/hw/misc/cbus.h | 32 ++++++++++++++++++++++++++++++++
17
tests/acceptance/machine_arm_n8x0.py | 49 ++++++++++++++++++++++++++++
11
hw/arm/nseries.c | 1 +
18
2 files changed, 50 insertions(+)
12
hw/misc/cbus.c | 2 +-
19
create mode 100644 tests/acceptance/machine_arm_n8x0.py
13
MAINTAINERS | 1 +
14
5 files changed, 35 insertions(+), 15 deletions(-)
15
create mode 100644 include/hw/misc/cbus.h
16
20
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/devices.h
20
+++ b/include/hw/devices.h
21
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
22
/* stellaris_input.c */
23
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
24
25
-/* cbus.c */
26
-typedef struct {
27
- qemu_irq clk;
28
- qemu_irq dat;
29
- qemu_irq sel;
30
-} CBus;
31
-CBus *cbus_init(qemu_irq dat_out);
32
-void cbus_attach(CBus *bus, void *slave_opaque);
33
-
34
-void *retu_init(qemu_irq irq, int vilma);
35
-void *tahvo_init(qemu_irq irq, int betty);
36
-
37
-void retu_key_event(void *retu, int state);
38
-
39
#endif
40
diff --git a/include/hw/misc/cbus.h b/include/hw/misc/cbus.h
41
new file mode 100644
42
index XXXXXXX..XXXXXXX
43
--- /dev/null
44
+++ b/include/hw/misc/cbus.h
45
@@ -XXX,XX +XXX,XX @@
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 @@
95
#include "qemu/osdep.h"
96
#include "hw/hw.h"
97
#include "hw/irq.h"
98
-#include "hw/devices.h"
99
+#include "hw/misc/cbus.h"
100
#include "sysemu/sysemu.h"
101
102
//#define DEBUG
103
diff --git a/MAINTAINERS b/MAINTAINERS
21
diff --git a/MAINTAINERS b/MAINTAINERS
104
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
105
--- a/MAINTAINERS
23
--- a/MAINTAINERS
106
+++ b/MAINTAINERS
24
+++ b/MAINTAINERS
107
@@ -XXX,XX +XXX,XX @@ F: hw/input/tsc2005.c
25
@@ -XXX,XX +XXX,XX @@ F: hw/rtc/twl92230.c
108
F: hw/misc/cbus.c
109
F: hw/timer/twl92230.c
110
F: include/hw/display/blizzard.h
26
F: include/hw/display/blizzard.h
111
+F: include/hw/misc/cbus.h
27
F: include/hw/input/tsc2xxx.h
28
F: include/hw/misc/cbus.h
29
+F: tests/acceptance/machine_arm_n8x0.py
112
30
113
Palm
31
Palm
114
M: Andrzej Zaborowski <balrogg@gmail.com>
32
M: Andrzej Zaborowski <balrogg@gmail.com>
33
diff --git a/tests/acceptance/machine_arm_n8x0.py b/tests/acceptance/machine_arm_n8x0.py
34
new file mode 100644
35
index XXXXXXX..XXXXXXX
36
--- /dev/null
37
+++ b/tests/acceptance/machine_arm_n8x0.py
38
@@ -XXX,XX +XXX,XX @@
39
+# Functional test that boots a Linux kernel and checks the console
40
+#
41
+# Copyright (c) 2020 Red Hat, Inc.
42
+#
43
+# Author:
44
+# Thomas Huth <thuth@redhat.com>
45
+#
46
+# This work is licensed under the terms of the GNU GPL, version 2 or
47
+# later. See the COPYING file in the top-level directory.
48
+
49
+import os
50
+
51
+from avocado import skipUnless
52
+from avocado_qemu import Test
53
+from avocado_qemu import wait_for_console_pattern
54
+
55
+class N8x0Machine(Test):
56
+ """Boots the Linux kernel and checks that the console is operational"""
57
+
58
+ timeout = 90
59
+
60
+ def __do_test_n8x0(self):
61
+ kernel_url = ('http://stskeeps.subnetmask.net/meego-n8x0/'
62
+ 'meego-arm-n8x0-1.0.80.20100712.1431-'
63
+ 'vmlinuz-2.6.35~rc4-129.1-n8x0')
64
+ kernel_hash = 'e9d5ab8d7548923a0061b6fbf601465e479ed269'
65
+ kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
66
+
67
+ self.vm.set_console(console_index=1)
68
+ self.vm.add_args('-kernel', kernel_path,
69
+ '-append', 'printk.time=0 console=ttyS1')
70
+ self.vm.launch()
71
+ wait_for_console_pattern(self, 'TSC2005 driver initializing')
72
+
73
+ @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
74
+ def test_n800(self):
75
+ """
76
+ :avocado: tags=arch:arm
77
+ :avocado: tags=machine:n800
78
+ """
79
+ self.__do_test_n8x0()
80
+
81
+ @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
82
+ def test_n810(self):
83
+ """
84
+ :avocado: tags=arch:arm
85
+ :avocado: tags=machine:n810
86
+ """
87
+ self.__do_test_n8x0()
115
--
88
--
116
2.20.1
89
2.20.1
117
90
118
91
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
There is a kernel and initrd available on github which we can use
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
for testing this machine.
5
Message-id: 20190412165416.7977-8-philmd@redhat.com
5
6
Signed-off-by: Thomas Huth <thuth@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20200225172501.29609-3-philmd@redhat.com
12
Message-Id: <20200131170233.14584-1-thuth@redhat.com>
13
[PMD: Renamed test method, moved description from class to method]
14
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
16
---
8
include/hw/devices.h | 3 ---
17
MAINTAINERS | 1 +
9
include/hw/input/gamepad.h | 19 +++++++++++++++++++
18
tests/acceptance/machine_arm_integratorcp.py | 43 ++++++++++++++++++++
10
hw/arm/stellaris.c | 2 +-
19
2 files changed, 44 insertions(+)
11
hw/input/stellaris_input.c | 2 +-
20
create mode 100644 tests/acceptance/machine_arm_integratorcp.py
12
MAINTAINERS | 1 +
13
5 files changed, 22 insertions(+), 5 deletions(-)
14
create mode 100644 include/hw/input/gamepad.h
15
21
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/devices.h
19
+++ b/include/hw/devices.h
20
@@ -XXX,XX +XXX,XX @@ void *tsc2005_init(qemu_irq pintdav);
21
uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
22
void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
23
24
-/* stellaris_input.c */
25
-void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
26
-
27
#endif
28
diff --git a/include/hw/input/gamepad.h b/include/hw/input/gamepad.h
29
new file mode 100644
30
index XXXXXXX..XXXXXXX
31
--- /dev/null
32
+++ b/include/hw/input/gamepad.h
33
@@ -XXX,XX +XXX,XX @@
34
+/*
35
+ * Gamepad style buttons connected to IRQ/GPIO lines
36
+ *
37
+ * Copyright (c) 2007 CodeSourcery.
38
+ * Written by Paul Brook
39
+ *
40
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
41
+ * See the COPYING file in the top-level directory.
42
+ */
43
+
44
+#ifndef HW_INPUT_GAMEPAD_H
45
+#define HW_INPUT_GAMEPAD_H
46
+
47
+#include "hw/irq.h"
48
+
49
+/* stellaris_input.c */
50
+void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
51
+
52
+#endif
53
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/arm/stellaris.c
56
+++ b/hw/arm/stellaris.c
57
@@ -XXX,XX +XXX,XX @@
58
#include "hw/sysbus.h"
59
#include "hw/ssi/ssi.h"
60
#include "hw/arm/arm.h"
61
-#include "hw/devices.h"
62
#include "qemu/timer.h"
63
#include "hw/i2c/i2c.h"
64
#include "net/net.h"
65
@@ -XXX,XX +XXX,XX @@
66
#include "sysemu/sysemu.h"
67
#include "hw/arm/armv7m.h"
68
#include "hw/char/pl011.h"
69
+#include "hw/input/gamepad.h"
70
#include "hw/watchdog/cmsdk-apb-watchdog.h"
71
#include "hw/misc/unimp.h"
72
#include "cpu.h"
73
diff --git a/hw/input/stellaris_input.c b/hw/input/stellaris_input.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/input/stellaris_input.c
76
+++ b/hw/input/stellaris_input.c
77
@@ -XXX,XX +XXX,XX @@
78
*/
79
#include "qemu/osdep.h"
80
#include "hw/hw.h"
81
-#include "hw/devices.h"
82
+#include "hw/input/gamepad.h"
83
#include "ui/console.h"
84
85
typedef struct {
86
diff --git a/MAINTAINERS b/MAINTAINERS
22
diff --git a/MAINTAINERS b/MAINTAINERS
87
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
88
--- a/MAINTAINERS
24
--- a/MAINTAINERS
89
+++ b/MAINTAINERS
25
+++ b/MAINTAINERS
90
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
26
@@ -XXX,XX +XXX,XX @@ S: Maintained
91
L: qemu-arm@nongnu.org
27
F: hw/arm/integratorcp.c
92
S: Maintained
28
F: hw/misc/arm_integrator_debug.c
93
F: hw/*/stellaris*
29
F: include/hw/misc/arm_integrator_debug.h
94
+F: include/hw/input/gamepad.h
30
+F: tests/acceptance/machine_arm_integratorcp.py
95
31
96
Versatile Express
32
MCIMX6UL EVK / i.MX6ul
97
M: Peter Maydell <peter.maydell@linaro.org>
33
M: Peter Maydell <peter.maydell@linaro.org>
34
diff --git a/tests/acceptance/machine_arm_integratorcp.py b/tests/acceptance/machine_arm_integratorcp.py
35
new file mode 100644
36
index XXXXXXX..XXXXXXX
37
--- /dev/null
38
+++ b/tests/acceptance/machine_arm_integratorcp.py
39
@@ -XXX,XX +XXX,XX @@
40
+# Functional test that boots a Linux kernel and checks the console
41
+#
42
+# Copyright (c) 2020 Red Hat, Inc.
43
+#
44
+# Author:
45
+# Thomas Huth <thuth@redhat.com>
46
+#
47
+# This work is licensed under the terms of the GNU GPL, version 2 or
48
+# later. See the COPYING file in the top-level directory.
49
+
50
+import os
51
+
52
+from avocado import skipUnless
53
+from avocado_qemu import Test
54
+from avocado_qemu import wait_for_console_pattern
55
+
56
+class IntegratorMachine(Test):
57
+
58
+ timeout = 90
59
+
60
+ @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
61
+ def test_integratorcp_console(self):
62
+ """
63
+ Boots the Linux kernel and checks that the console is operational
64
+ :avocado: tags=arch:arm
65
+ :avocado: tags=machine:integratorcp
66
+ """
67
+ kernel_url = ('https://github.com/zayac/qemu-arm/raw/master/'
68
+ 'arm-test/kernel/zImage.integrator')
69
+ kernel_hash = '0d7adba893c503267c946a3cbdc63b4b54f25468'
70
+ kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
71
+
72
+ initrd_url = ('https://github.com/zayac/qemu-arm/raw/master/'
73
+ 'arm-test/kernel/arm_root.img')
74
+ initrd_hash = 'b51e4154285bf784e017a37586428332d8c7bd8b'
75
+ initrd_path = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
76
+
77
+ self.vm.set_console()
78
+ self.vm.add_args('-kernel', kernel_path,
79
+ '-initrd', initrd_path,
80
+ '-append', 'printk.time=0 console=ttyAMA0')
81
+ self.vm.launch()
82
+ wait_for_console_pattern(self, 'Log in as root')
98
--
83
--
99
2.20.1
84
2.20.1
100
85
101
86
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
As we want to re-use this code, extract it as a new function.
4
Since we are using the PL011 serial console, add a Avocado tag
5
to ease filtering of tests.
4
6
5
Reviewed-by: Thomas Huth <thuth@redhat.com>
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
8
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20190412165416.7977-6-philmd@redhat.com
10
Message-id: 20200225172501.29609-4-philmd@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
include/hw/devices.h | 7 -------
13
tests/acceptance/machine_arm_integratorcp.py | 18 +++++++++++-------
12
include/hw/display/blizzard.h | 22 ++++++++++++++++++++++
14
1 file changed, 11 insertions(+), 7 deletions(-)
13
hw/arm/nseries.c | 1 +
14
hw/display/blizzard.c | 2 +-
15
MAINTAINERS | 2 ++
16
5 files changed, 26 insertions(+), 8 deletions(-)
17
create mode 100644 include/hw/display/blizzard.h
18
15
19
diff --git a/include/hw/devices.h b/include/hw/devices.h
16
diff --git a/tests/acceptance/machine_arm_integratorcp.py b/tests/acceptance/machine_arm_integratorcp.py
20
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/devices.h
18
--- a/tests/acceptance/machine_arm_integratorcp.py
22
+++ b/include/hw/devices.h
19
+++ b/tests/acceptance/machine_arm_integratorcp.py
23
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
20
@@ -XXX,XX +XXX,XX @@ class IntegratorMachine(Test):
24
/* stellaris_input.c */
21
25
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
22
timeout = 90
26
23
27
-/* blizzard.c */
24
- @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
28
-void *s1d13745_init(qemu_irq gpio_int);
25
- def test_integratorcp_console(self):
29
-void s1d13745_write(void *opaque, int dc, uint16_t value);
26
- """
30
-void s1d13745_write_block(void *opaque, int dc,
27
- Boots the Linux kernel and checks that the console is operational
31
- void *buf, size_t len, int pitch);
28
- :avocado: tags=arch:arm
32
-uint16_t s1d13745_read(void *opaque, int dc);
29
- :avocado: tags=machine:integratorcp
33
-
30
- """
34
/* cbus.c */
31
+ def boot_integratorcp(self):
35
typedef struct {
32
kernel_url = ('https://github.com/zayac/qemu-arm/raw/master/'
36
qemu_irq clk;
33
'arm-test/kernel/zImage.integrator')
37
diff --git a/include/hw/display/blizzard.h b/include/hw/display/blizzard.h
34
kernel_hash = '0d7adba893c503267c946a3cbdc63b4b54f25468'
38
new file mode 100644
35
@@ -XXX,XX +XXX,XX @@ class IntegratorMachine(Test):
39
index XXXXXXX..XXXXXXX
36
'-initrd', initrd_path,
40
--- /dev/null
37
'-append', 'printk.time=0 console=ttyAMA0')
41
+++ b/include/hw/display/blizzard.h
38
self.vm.launch()
42
@@ -XXX,XX +XXX,XX @@
43
+/*
44
+ * Epson S1D13744/S1D13745 (Blizzard/Hailstorm/Tornado) LCD/TV controller.
45
+ *
46
+ * Copyright (C) 2008 Nokia Corporation
47
+ * Written by Andrzej Zaborowski
48
+ *
49
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
50
+ * See the COPYING file in the top-level directory.
51
+ */
52
+
39
+
53
+#ifndef HW_DISPLAY_BLIZZARD_H
40
+ @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
54
+#define HW_DISPLAY_BLIZZARD_H
41
+ def test_integratorcp_console(self):
55
+
42
+ """
56
+#include "hw/irq.h"
43
+ Boots the Linux kernel and checks that the console is operational
57
+
44
+ :avocado: tags=arch:arm
58
+void *s1d13745_init(qemu_irq gpio_int);
45
+ :avocado: tags=machine:integratorcp
59
+void s1d13745_write(void *opaque, int dc, uint16_t value);
46
+ :avocado: tags=device:pl011
60
+void s1d13745_write_block(void *opaque, int dc,
47
+ """
61
+ void *buf, size_t len, int pitch);
48
+ self.boot_integratorcp()
62
+uint16_t s1d13745_read(void *opaque, int dc);
49
wait_for_console_pattern(self, 'Log in as root')
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
--
50
--
108
2.20.1
51
2.20.1
109
52
110
53
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
Add a test that verifies the Tux logo is displayed on the framebuffer.
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
5
Message-id: 20190412165416.7977-5-philmd@redhat.com
5
We simply follow the OpenCV "Template Matching with Multiple Objects"
6
tutorial, replacing Lionel Messi by Tux:
7
https://docs.opencv.org/4.2.0/d4/dc6/tutorial_py_template_matching.html
8
9
When OpenCV and NumPy are installed, this test can be run using:
10
11
$ AVOCADO_ALLOW_UNTRUSTED_CODE=hmmm \
12
avocado --show=app,framebuffer run -t device:framebuffer \
13
tests/acceptance/machine_arm_integratorcp.py
14
JOB ID : 8c46b0f8269242e87d738247883ea2a470df949e
15
JOB LOG : avocado/job-results/job-2020-01-31T21.38-8c46b0f/job.log
16
(1/1) tests/acceptance/machine_arm_integratorcp.py:IntegratorMachine.test_framebuffer_tux_logo:
17
framebuffer: found Tux at position [x, y] = (0, 0)
18
PASS (3.96 s)
19
RESULTS : PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0
20
JOB TIME : 4.23 s
21
22
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
23
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
24
Message-id: 20200225172501.29609-5-philmd@redhat.com
25
Message-Id: <20200131211102.29612-3-f4bug@amsat.org>
26
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
28
---
8
include/hw/devices.h | 6 ------
29
tests/acceptance/machine_arm_integratorcp.py | 52 ++++++++++++++++++++
9
include/hw/display/tc6393xb.h | 24 ++++++++++++++++++++++++
30
1 file changed, 52 insertions(+)
10
hw/arm/tosa.c | 2 +-
11
hw/display/tc6393xb.c | 2 +-
12
MAINTAINERS | 1 +
13
5 files changed, 27 insertions(+), 8 deletions(-)
14
create mode 100644 include/hw/display/tc6393xb.h
15
31
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
32
diff --git a/tests/acceptance/machine_arm_integratorcp.py b/tests/acceptance/machine_arm_integratorcp.py
17
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/devices.h
34
--- a/tests/acceptance/machine_arm_integratorcp.py
19
+++ b/include/hw/devices.h
35
+++ b/tests/acceptance/machine_arm_integratorcp.py
20
@@ -XXX,XX +XXX,XX @@ void *tahvo_init(qemu_irq irq, int betty);
21
22
void retu_key_event(void *retu, int state);
23
24
-/* tc6393xb.c */
25
-typedef struct TC6393xbState TC6393xbState;
26
-TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
27
- uint32_t base, qemu_irq irq);
28
-qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
29
-
30
#endif
31
diff --git a/include/hw/display/tc6393xb.h b/include/hw/display/tc6393xb.h
32
new file mode 100644
33
index XXXXXXX..XXXXXXX
34
--- /dev/null
35
+++ b/include/hw/display/tc6393xb.h
36
@@ -XXX,XX +XXX,XX @@
36
@@ -XXX,XX +XXX,XX @@
37
+/*
37
# later. See the COPYING file in the top-level directory.
38
+ * Toshiba TC6393XB I/O Controller.
38
39
+ * Found in Sharp Zaurus SL-6000 (tosa) or some
39
import os
40
+ * Toshiba e-Series PDAs.
40
+import logging
41
+ *
41
42
+ * Copyright (c) 2007 Hervé Poussineau
42
from avocado import skipUnless
43
+ *
43
from avocado_qemu import Test
44
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
44
from avocado_qemu import wait_for_console_pattern
45
+ * See the COPYING file in the top-level directory.
45
46
+ */
47
+
46
+
48
+#ifndef HW_DISPLAY_TC6393XB_H
47
+NUMPY_AVAILABLE = True
49
+#define HW_DISPLAY_TC6393XB_H
48
+try:
49
+ import numpy as np
50
+except ImportError:
51
+ NUMPY_AVAILABLE = False
50
+
52
+
51
+#include "exec/memory.h"
53
+CV2_AVAILABLE = True
52
+#include "hw/irq.h"
54
+try:
55
+ import cv2
56
+except ImportError:
57
+ CV2_AVAILABLE = False
53
+
58
+
54
+typedef struct TC6393xbState TC6393xbState;
55
+
59
+
56
+TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
60
class IntegratorMachine(Test):
57
+ uint32_t base, qemu_irq irq);
61
58
+qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
62
timeout = 90
63
@@ -XXX,XX +XXX,XX @@ class IntegratorMachine(Test):
64
"""
65
self.boot_integratorcp()
66
wait_for_console_pattern(self, 'Log in as root')
59
+
67
+
60
+#endif
68
+ @skipUnless(NUMPY_AVAILABLE, 'Python NumPy not installed')
61
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
69
+ @skipUnless(CV2_AVAILABLE, 'Python OpenCV not installed')
62
index XXXXXXX..XXXXXXX 100644
70
+ @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
63
--- a/hw/arm/tosa.c
71
+ def test_framebuffer_tux_logo(self):
64
+++ b/hw/arm/tosa.c
72
+ """
65
@@ -XXX,XX +XXX,XX @@
73
+ Boot Linux and verify the Tux logo is displayed on the framebuffer.
66
#include "hw/hw.h"
74
+ :avocado: tags=arch:arm
67
#include "hw/arm/pxa.h"
75
+ :avocado: tags=machine:integratorcp
68
#include "hw/arm/arm.h"
76
+ :avocado: tags=device:pl110
69
-#include "hw/devices.h"
77
+ :avocado: tags=device:framebuffer
70
#include "hw/arm/sharpsl.h"
78
+ """
71
#include "hw/pcmcia.h"
79
+ screendump_path = os.path.join(self.workdir, "screendump.pbm")
72
#include "hw/boards.h"
80
+ tuxlogo_url = ('https://github.com/torvalds/linux/raw/v2.6.12/'
73
+#include "hw/display/tc6393xb.h"
81
+ 'drivers/video/logo/logo_linux_vga16.ppm')
74
#include "hw/i2c/i2c.h"
82
+ tuxlogo_hash = '3991c2ddbd1ddaecda7601f8aafbcf5b02dc86af'
75
#include "hw/ssi/ssi.h"
83
+ tuxlogo_path = self.fetch_asset(tuxlogo_url, asset_hash=tuxlogo_hash)
76
#include "hw/sysbus.h"
84
+
77
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
85
+ self.boot_integratorcp()
78
index XXXXXXX..XXXXXXX 100644
86
+ framebuffer_ready = 'Console: switching to colour frame buffer device'
79
--- a/hw/display/tc6393xb.c
87
+ wait_for_console_pattern(self, framebuffer_ready)
80
+++ b/hw/display/tc6393xb.c
88
+ self.vm.command('human-monitor-command', command_line='stop')
81
@@ -XXX,XX +XXX,XX @@
89
+ self.vm.command('human-monitor-command',
82
#include "qapi/error.h"
90
+ command_line='screendump %s' % screendump_path)
83
#include "qemu/host-utils.h"
91
+ logger = logging.getLogger('framebuffer')
84
#include "hw/hw.h"
92
+
85
-#include "hw/devices.h"
93
+ cpu_count = 1
86
+#include "hw/display/tc6393xb.h"
94
+ match_threshold = 0.92
87
#include "hw/block/flash.h"
95
+ screendump_bgr = cv2.imread(screendump_path)
88
#include "ui/console.h"
96
+ screendump_gray = cv2.cvtColor(screendump_bgr, cv2.COLOR_BGR2GRAY)
89
#include "ui/pixel_ops.h"
97
+ result = cv2.matchTemplate(screendump_gray, cv2.imread(tuxlogo_path, 0),
90
diff --git a/MAINTAINERS b/MAINTAINERS
98
+ cv2.TM_CCOEFF_NORMED)
91
index XXXXXXX..XXXXXXX 100644
99
+ loc = np.where(result >= match_threshold)
92
--- a/MAINTAINERS
100
+ tux_count = 0
93
+++ b/MAINTAINERS
101
+ for tux_count, pt in enumerate(zip(*loc[::-1]), start=1):
94
@@ -XXX,XX +XXX,XX @@ F: hw/misc/mst_fpga.c
102
+ logger.debug('found Tux at position [x, y] = %s', pt)
95
F: hw/misc/max111x.c
103
+ self.assertGreaterEqual(tux_count, cpu_count)
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
--
104
--
103
2.20.1
105
2.20.1
104
106
105
107
diff view generated by jsdifflib
1
Move the NS TBFLAG down from bit 19 to bit 6, which has not
1
We missed an instance of using FIELD_EX32 on a 64-bit ID
2
been used since commit c1e3781090b9d36c60 in 2015, when we
2
register, in isar_feature_aa64_pmu_8_4(). Fix it.
3
started passing the entire MMU index in the TB flags rather
4
than just a 'privilege level' bit.
5
6
This rearrangement is not strictly necessary, but means that
7
we can put M-profile-only bits next to each other rather
8
than scattered across the flag word.
9
3
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20190416125744.27770-17-peter.maydell@linaro.org
7
Message-id: 20200224172846.13053-2-peter.maydell@linaro.org
13
---
8
---
14
target/arm/cpu.h | 11 ++++++-----
9
target/arm/cpu.h | 4 ++--
15
1 file changed, 6 insertions(+), 5 deletions(-)
10
1 file changed, 2 insertions(+), 2 deletions(-)
16
11
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
14
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
15
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
16
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_pmu_8_1(const ARMISARegisters *id)
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
17
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
18
static inline bool isar_feature_aa64_pmu_8_4(const ARMISARegisters *id)
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
19
{
25
+/*
20
- return FIELD_EX32(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 5 &&
26
+ * Indicates whether cp register reads and writes by guest code should access
21
- FIELD_EX32(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
27
+ * the secure or nonsecure bank of banked registers; note that this is not
22
+ return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 5 &&
28
+ * the same thing as the current security state of the processor!
23
+ FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
29
+ */
24
}
30
+FIELD(TBFLAG_A32, NS, 6, 1)
25
31
FIELD(TBFLAG_A32, VFPEN, 7, 1)
26
/*
32
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
33
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
34
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
35
* checks on the other bits at runtime
36
*/
37
FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
38
-/* Indicates whether cp register reads and writes by guest code should access
39
- * the secure or nonsecure bank of banked registers; note that this is not
40
- * the same thing as the current security state of the processor!
41
- */
42
-FIELD(TBFLAG_A32, NS, 19, 1)
43
/* For M profile only, Handler (ie not Thread) mode */
44
FIELD(TBFLAG_A32, HANDLER, 21, 1)
45
/* For M profile only, whether we should generate stack-limit checks */
46
--
27
--
47
2.20.1
28
2.20.1
48
29
49
30
diff view generated by jsdifflib
1
Implement the VLSTM instruction for v7M for the FPU present case.
1
The v8.3-RCPC extension implements three new load instructions
2
which provide slightly weaker consistency guarantees than the
3
existing load-acquire operations. For QEMU we choose to simply
4
implement them with a full LDAQ barrier.
2
5
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-25-peter.maydell@linaro.org
8
Message-id: 20200224172846.13053-3-peter.maydell@linaro.org
6
---
9
---
7
target/arm/cpu.h | 2 +
10
target/arm/cpu.h | 5 +++++
8
target/arm/helper.h | 2 +
11
linux-user/elfload.c | 1 +
9
target/arm/helper.c | 84 ++++++++++++++++++++++++++++++++++++++++++
12
target/arm/cpu64.c | 1 +
10
target/arm/translate.c | 15 +++++++-
13
target/arm/translate-a64.c | 24 ++++++++++++++++++++++++
11
4 files changed, 102 insertions(+), 1 deletion(-)
14
4 files changed, 31 insertions(+)
12
15
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
18
--- a/target/arm/cpu.h
16
+++ b/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_pmu_8_4(const ARMISARegisters *id)
18
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
21
FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
19
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
20
#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
21
+#define EXCP_LSERR 21 /* v8M LSERR SecureFault */
22
+#define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */
23
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
24
25
#define ARMV7M_EXCP_RESET 1
26
diff --git a/target/arm/helper.h b/target/arm/helper.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/helper.h
29
+++ b/target/arm/helper.h
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
31
32
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
33
34
+DEF_HELPER_2(v7m_vlstm, void, env, i32)
35
+
36
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
37
38
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
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
}
22
}
46
23
47
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
24
+static inline bool isar_feature_aa64_rcpc_8_3(const ARMISARegisters *id)
48
+{
25
+{
49
+ /* translate.c should never generate calls here in user-only mode */
26
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) != 0;
50
+ g_assert_not_reached();
51
+}
27
+}
52
+
28
+
53
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
29
/*
54
{
30
* Feature tests for "does this exist in either 32-bit or 64-bit?"
55
/* The TT instructions can be used by unprivileged code, but in
31
*/
56
@@ -XXX,XX +XXX,XX @@ static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
32
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/linux-user/elfload.c
35
+++ b/linux-user/elfload.c
36
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
37
GET_FEATURE_ID(aa64_sb, ARM_HWCAP_A64_SB);
38
GET_FEATURE_ID(aa64_condm_4, ARM_HWCAP_A64_FLAGM);
39
GET_FEATURE_ID(aa64_dcpop, ARM_HWCAP_A64_DCPOP);
40
+ GET_FEATURE_ID(aa64_rcpc_8_3, ARM_HWCAP_A64_LRCPC);
41
42
return hwcaps;
43
}
44
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/cpu64.c
47
+++ b/target/arm/cpu64.c
48
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
49
t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
50
t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
51
t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1);
52
+ t = FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 1); /* ARMv8.3-RCPC */
53
cpu->isar.id_aa64isar1 = t;
54
55
t = cpu->isar.id_aa64pfr0;
56
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/translate-a64.c
59
+++ b/target/arm/translate-a64.c
60
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
61
int rs = extract32(insn, 16, 5);
62
int rn = extract32(insn, 5, 5);
63
int o3_opc = extract32(insn, 12, 4);
64
+ bool r = extract32(insn, 22, 1);
65
+ bool a = extract32(insn, 23, 1);
66
TCGv_i64 tcg_rs, clean_addr;
67
AtomicThreeOpFn *fn;
68
69
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
70
case 010: /* SWP */
71
fn = tcg_gen_atomic_xchg_i64;
72
break;
73
+ case 014: /* LDAPR, LDAPRH, LDAPRB */
74
+ if (!dc_isar_feature(aa64_rcpc_8_3, s) ||
75
+ rs != 31 || a != 1 || r != 0) {
76
+ unallocated_encoding(s);
77
+ return;
78
+ }
79
+ break;
80
default:
81
unallocated_encoding(s);
82
return;
83
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
84
gen_check_sp_alignment(s);
57
}
85
}
58
}
86
clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn));
59
60
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
61
+{
62
+ /* fptr is the value of Rn, the frame pointer we store the FP regs to */
63
+ bool s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
64
+ bool lspact = env->v7m.fpccr[s] & R_V7M_FPCCR_LSPACT_MASK;
65
+
87
+
66
+ assert(env->v7m.secure);
88
+ if (o3_opc == 014) {
67
+
89
+ /*
68
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
90
+ * LDAPR* are a special case because they are a simple load, not a
91
+ * fetch-and-do-something op.
92
+ * The architectural consistency requirements here are weaker than
93
+ * full load-acquire (we only need "load-acquire processor consistent"),
94
+ * but we choose to implement them as full LDAQ.
95
+ */
96
+ do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, false, false,
97
+ true, rt, disas_ldst_compute_iss_sf(size, false, 0), true);
98
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
69
+ return;
99
+ return;
70
+ }
100
+ }
71
+
101
+
72
+ /* Check access to the coprocessor is permitted */
102
tcg_rs = read_cpu_reg(s, rs, true);
73
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
103
74
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
104
if (o3_opc == 1) { /* LDCLR */
75
+ }
76
+
77
+ if (lspact) {
78
+ /* LSPACT should not be active when there is active FP state */
79
+ raise_exception_ra(env, EXCP_LSERR, 0, 1, GETPC());
80
+ }
81
+
82
+ if (fptr & 7) {
83
+ raise_exception_ra(env, EXCP_UNALIGNED, 0, 1, GETPC());
84
+ }
85
+
86
+ /*
87
+ * Note that we do not use v7m_stack_write() here, because the
88
+ * accesses should not set the FSR bits for stacking errors if they
89
+ * fail. (In pseudocode terms, they are AccType_NORMAL, not AccType_STACK
90
+ * or AccType_LAZYFP). Faults in cpu_stl_data() will throw exceptions
91
+ * and longjmp out.
92
+ */
93
+ if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) {
94
+ bool ts = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK;
95
+ int i;
96
+
97
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
98
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
99
+ uint32_t faddr = fptr + 4 * i;
100
+ uint32_t slo = extract64(dn, 0, 32);
101
+ uint32_t shi = extract64(dn, 32, 32);
102
+
103
+ if (i >= 16) {
104
+ faddr += 8; /* skip the slot for the FPSCR */
105
+ }
106
+ cpu_stl_data(env, faddr, slo);
107
+ cpu_stl_data(env, faddr + 4, shi);
108
+ }
109
+ cpu_stl_data(env, fptr + 0x40, vfp_get_fpscr(env));
110
+
111
+ /*
112
+ * If TS is 0 then s0 to s15 and FPSCR are UNKNOWN; we choose to
113
+ * leave them unchanged, matching our choice in v7m_preserve_fp_state.
114
+ */
115
+ if (ts) {
116
+ for (i = 0; i < 32; i += 2) {
117
+ *aa32_vfp_dreg(env, i / 2) = 0;
118
+ }
119
+ vfp_set_fpscr(env, 0);
120
+ }
121
+ } else {
122
+ v7m_update_fpccr(env, fptr, false);
123
+ }
124
+
125
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
126
+}
127
+
128
static bool v7m_push_stack(ARMCPU *cpu)
129
{
130
/* Do the "set up stack frame" part of exception entry,
131
@@ -XXX,XX +XXX,XX @@ static void arm_log_exception(int idx)
132
[EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
133
[EXCP_STKOF] = "v8M STKOF UsageFault",
134
[EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
135
+ [EXCP_LSERR] = "v8M LSERR UsageFault",
136
+ [EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
137
};
138
139
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
140
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
141
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
142
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_STKOF_MASK;
143
break;
144
+ case EXCP_LSERR:
145
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
146
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
147
+ break;
148
+ case EXCP_UNALIGNED:
149
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
150
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNALIGNED_MASK;
151
+ break;
152
case EXCP_SWI:
153
/* The PC already points to the next instruction. */
154
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC, env->v7m.secure);
155
diff --git a/target/arm/translate.c b/target/arm/translate.c
156
index XXXXXXX..XXXXXXX 100644
157
--- a/target/arm/translate.c
158
+++ b/target/arm/translate.c
159
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
160
if (!s->v8m_secure || (insn & 0x0040f0ff)) {
161
goto illegal_op;
162
}
163
- /* Just NOP since FP support is not implemented */
164
+
165
+ if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
166
+ TCGv_i32 fptr = load_reg(s, rn);
167
+
168
+ if (extract32(insn, 20, 1)) {
169
+ /* VLLDM */
170
+ } else {
171
+ gen_helper_v7m_vlstm(cpu_env, fptr);
172
+ }
173
+ tcg_temp_free_i32(fptr);
174
+
175
+ /* End the TB, because we have updated FP control bits */
176
+ s->base.is_jmp = DISAS_UPDATE;
177
+ }
178
break;
179
}
180
if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
181
--
105
--
182
2.20.1
106
2.20.1
183
107
184
108
diff view generated by jsdifflib
1
In the v7M architecture, if an exception is generated in the process
1
The v8.4-RCPC extension implements some new instructions:
2
of doing the lazy stacking of FP registers, the handling of
2
* LDAPUR, LDAPURB, LDAPURH, LDAPRSB, LDAPRSH, LDAPRSW
3
possible escalation to HardFault is treated differently to the normal
3
* STLUR, STLURB, STLURH
4
approach: it works based on the saved information about exception
5
readiness that was stored in the FPCCR when the stack frame was
6
created. Provide a new function armv7m_nvic_set_pending_lazyfp()
7
which pends exceptions during lazy stacking, and implements
8
this logic.
9
4
10
This corresponds to the pseudocode TakePreserveFPException().
5
These are all in a new subgroup of encodings that sits below the
6
top-level "Loads and Stores" group in the Arm ARM.
7
8
The STLUR* instructions have standard store-release semantics; the
9
LDAPUR* have Load-AcquirePC semantics, but (as with LDAPR*) we choose
10
to implement them as the slightly stronger Load-Acquire.
11
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190416125744.27770-22-peter.maydell@linaro.org
14
Message-id: 20200224172846.13053-4-peter.maydell@linaro.org
15
---
15
---
16
target/arm/cpu.h | 12 ++++++
16
target/arm/cpu.h | 5 +++
17
hw/intc/armv7m_nvic.c | 96 +++++++++++++++++++++++++++++++++++++++++++
17
linux-user/elfload.c | 1 +
18
2 files changed, 108 insertions(+)
18
target/arm/cpu64.c | 2 +-
19
target/arm/translate-a64.c | 90 ++++++++++++++++++++++++++++++++++++++
20
4 files changed, 97 insertions(+), 1 deletion(-)
19
21
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
24
--- a/target/arm/cpu.h
23
+++ b/target/arm/cpu.h
25
+++ b/target/arm/cpu.h
24
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
26
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_rcpc_8_3(const ARMISARegisters *id)
25
* a different exception).
27
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) != 0;
28
}
29
30
+static inline bool isar_feature_aa64_rcpc_8_4(const ARMISARegisters *id)
31
+{
32
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) >= 2;
33
+}
34
+
35
/*
36
* Feature tests for "does this exist in either 32-bit or 64-bit?"
26
*/
37
*/
27
void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
38
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
28
+/**
39
index XXXXXXX..XXXXXXX 100644
29
+ * armv7m_nvic_set_pending_lazyfp: mark this lazy FP exception as pending
40
--- a/linux-user/elfload.c
30
+ * @opaque: the NVIC
41
+++ b/linux-user/elfload.c
31
+ * @irq: the exception number to mark pending
42
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
32
+ * @secure: false for non-banked exceptions or for the nonsecure
43
GET_FEATURE_ID(aa64_condm_4, ARM_HWCAP_A64_FLAGM);
33
+ * version of a banked exception, true for the secure version of a banked
44
GET_FEATURE_ID(aa64_dcpop, ARM_HWCAP_A64_DCPOP);
34
+ * exception.
45
GET_FEATURE_ID(aa64_rcpc_8_3, ARM_HWCAP_A64_LRCPC);
46
+ GET_FEATURE_ID(aa64_rcpc_8_4, ARM_HWCAP_A64_ILRCPC);
47
48
return hwcaps;
49
}
50
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/cpu64.c
53
+++ b/target/arm/cpu64.c
54
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
55
t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
56
t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
57
t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1);
58
- t = FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 1); /* ARMv8.3-RCPC */
59
+ t = FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 2); /* ARMv8.4-RCPC */
60
cpu->isar.id_aa64isar1 = t;
61
62
t = cpu->isar.id_aa64pfr0;
63
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/translate-a64.c
66
+++ b/target/arm/translate-a64.c
67
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_pac(DisasContext *s, uint32_t insn,
68
}
69
}
70
71
+/*
72
+ * LDAPR/STLR (unscaled immediate)
35
+ *
73
+ *
36
+ * Similar to armv7m_nvic_set_pending(), but specifically for exceptions
74
+ * 31 30 24 22 21 12 10 5 0
37
+ * generated in the course of lazy stacking of FP registers.
75
+ * +------+-------------+-----+---+--------+-----+----+-----+
76
+ * | size | 0 1 1 0 0 1 | opc | 0 | imm9 | 0 0 | Rn | Rt |
77
+ * +------+-------------+-----+---+--------+-----+----+-----+
78
+ *
79
+ * Rt: source or destination register
80
+ * Rn: base register
81
+ * imm9: unscaled immediate offset
82
+ * opc: 00: STLUR*, 01/10/11: various LDAPUR*
83
+ * size: size of load/store
38
+ */
84
+ */
39
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure);
85
+static void disas_ldst_ldapr_stlr(DisasContext *s, uint32_t insn)
40
/**
41
* armv7m_nvic_get_pending_irq_info: return highest priority pending
42
* exception, and whether it targets Secure state
43
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/intc/armv7m_nvic.c
46
+++ b/hw/intc/armv7m_nvic.c
47
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
48
do_armv7m_nvic_set_pending(opaque, irq, secure, true);
49
}
50
51
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
52
+{
86
+{
53
+ /*
87
+ int rt = extract32(insn, 0, 5);
54
+ * Pend an exception during lazy FP stacking. This differs
88
+ int rn = extract32(insn, 5, 5);
55
+ * from the usual exception pending because the logic for
89
+ int offset = sextract32(insn, 12, 9);
56
+ * whether we should escalate depends on the saved context
90
+ int opc = extract32(insn, 22, 2);
57
+ * in the FPCCR register, not on the current state of the CPU/NVIC.
91
+ int size = extract32(insn, 30, 2);
58
+ */
92
+ TCGv_i64 clean_addr, dirty_addr;
59
+ NVICState *s = (NVICState *)opaque;
93
+ bool is_store = false;
60
+ bool banked = exc_is_banked(irq);
94
+ bool is_signed = false;
61
+ VecInfo *vec;
95
+ bool extend = false;
62
+ bool targets_secure;
96
+ bool iss_sf;
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
+
97
+
72
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
98
+ if (!dc_isar_feature(aa64_rcpc_8_4, s)) {
73
+ assert(!secure || banked);
99
+ unallocated_encoding(s);
100
+ return;
101
+ }
74
+
102
+
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
103
+ switch (opc) {
76
+
104
+ case 0: /* STLURB */
77
+ targets_secure = banked ? secure : exc_targets_secure(s, irq);
105
+ is_store = true;
78
+
106
+ break;
79
+ switch (irq) {
107
+ case 1: /* LDAPUR* */
80
+ case ARMV7M_EXCP_DEBUG:
108
+ break;
81
+ if (!(fpccr_s & R_V7M_FPCCR_MONRDY_MASK)) {
109
+ case 2: /* LDAPURS* 64-bit variant */
82
+ /* Ignore DebugMonitor exception */
110
+ if (size == 3) {
111
+ unallocated_encoding(s);
83
+ return;
112
+ return;
84
+ }
113
+ }
114
+ is_signed = true;
85
+ break;
115
+ break;
86
+ case ARMV7M_EXCP_MEM:
116
+ case 3: /* LDAPURS* 32-bit variant */
87
+ escalate = !(fpccr & R_V7M_FPCCR_MMRDY_MASK);
117
+ if (size > 1) {
88
+ break;
118
+ unallocated_encoding(s);
89
+ case ARMV7M_EXCP_USAGE:
119
+ return;
90
+ escalate = !(fpccr & R_V7M_FPCCR_UFRDY_MASK);
120
+ }
91
+ break;
121
+ is_signed = true;
92
+ case ARMV7M_EXCP_BUS:
122
+ extend = true; /* zero-extend 32->64 after signed load */
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;
123
+ break;
98
+ default:
124
+ default:
99
+ g_assert_not_reached();
125
+ g_assert_not_reached();
100
+ }
126
+ }
101
+
127
+
102
+ if (escalate) {
128
+ iss_sf = disas_ldst_compute_iss_sf(size, is_signed, opc);
103
+ /*
129
+
104
+ * Escalate to HardFault: faults that initially targeted Secure
130
+ if (rn == 31) {
105
+ * continue to do so, even if HF normally targets NonSecure.
131
+ gen_check_sp_alignment(s);
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
+ }
132
+ }
116
+
133
+
117
+ if (!vec->enabled ||
134
+ dirty_addr = read_cpu_reg_sp(s, rn, 1);
118
+ nvic_exec_prio(s) <= exc_group_prio(s, vec->prio, secure)) {
135
+ tcg_gen_addi_i64(dirty_addr, dirty_addr, offset);
119
+ if (!(fpccr_s & R_V7M_FPCCR_HFRDY_MASK)) {
136
+ clean_addr = clean_data_tbi(s, dirty_addr);
120
+ /*
121
+ * We want to escalate to HardFault but the context the
122
+ * FP state belongs to prevents the exception pre-empting.
123
+ */
124
+ cpu_abort(&s->cpu->parent_obj,
125
+ "Lockup: can't escalate to HardFault during "
126
+ "lazy FP register stacking\n");
127
+ }
128
+ }
129
+
137
+
130
+ if (escalate) {
138
+ if (is_store) {
131
+ s->cpu->env.v7m.hfsr |= R_V7M_HFSR_FORCED_MASK;
139
+ /* Store-Release semantics */
132
+ }
140
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
133
+ if (!vec->pending) {
141
+ do_gpr_st(s, cpu_reg(s, rt), clean_addr, size, true, rt, iss_sf, true);
134
+ vec->pending = 1;
142
+ } else {
135
+ /*
143
+ /*
136
+ * We do not call nvic_irq_update(), because we know our caller
144
+ * Load-AcquirePC semantics; we implement as the slightly more
137
+ * is going to handle causing us to take the exception by
145
+ * restrictive Load-Acquire.
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
+ */
146
+ */
143
+ nvic_recompute_state(s);
147
+ do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, is_signed, extend,
148
+ true, rt, iss_sf, true);
149
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
144
+ }
150
+ }
145
+}
151
+}
146
+
152
+
147
/* Make pending IRQ active. */
153
/* Load/store register (all forms) */
148
void armv7m_nvic_acknowledge_irq(void *opaque)
154
static void disas_ldst_reg(DisasContext *s, uint32_t insn)
149
{
155
{
156
@@ -XXX,XX +XXX,XX @@ static void disas_ldst(DisasContext *s, uint32_t insn)
157
case 0x0d: /* AdvSIMD load/store single structure */
158
disas_ldst_single_struct(s, insn);
159
break;
160
+ case 0x19: /* LDAPR/STLR (unscaled immediate) */
161
+ if (extract32(insn, 10, 2) != 0 ||
162
+ extract32(insn, 21, 1) != 0) {
163
+ unallocated_encoding(s);
164
+ break;
165
+ }
166
+ disas_ldst_ldapr_stlr(s, insn);
167
+ break;
168
default:
169
unallocated_encoding(s);
170
break;
150
--
171
--
151
2.20.1
172
2.20.1
152
173
153
174
diff view generated by jsdifflib
1
Add a new helper function which returns the MMU index to use
1
The ARMv8.3-CCIDX extension makes the CCSIDR_EL1 system ID registers
2
for v7M, where the caller specifies all of the security
2
have a format that uses the full 64 bit width of the register, and
3
state, privilege level and whether the execution priority
3
adds a new CCSIDR2 register so AArch32 can get at the high 32 bits.
4
is negative, and reimplement the existing
5
arm_v7m_mmu_idx_for_secstate_and_priv() in terms of it.
6
4
7
We are going to need this for the lazy-FP-stacking code.
5
QEMU doesn't implement caches, so we just treat these ID registers as
6
opaque values that are set to the correct constant values for each
7
CPU. The only thing we need to do is allow 64-bit values in our
8
cssidr[] array and provide the CCSIDR2 accessors.
9
10
We don't set the CCIDX field in our 'max' CPU because the CCSIDR
11
constant values we use are the same as the ones used by the
12
Cortex-A57 and they are in the old 32-bit format. This means
13
that the extra regdef added here is unused currently, but it
14
means that whenever in the future we add a CPU that does need
15
the new 64-bit format it will just work when we set the cssidr
16
values and the ID registers for it.
8
17
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20190416125744.27770-21-peter.maydell@linaro.org
20
Message-id: 20200224182626.29252-1-peter.maydell@linaro.org
12
---
21
---
13
target/arm/cpu.h | 7 +++++++
22
target/arm/cpu.h | 17 ++++++++++++++++-
14
target/arm/helper.c | 14 +++++++++++---
23
target/arm/helper.c | 19 +++++++++++++++++++
15
2 files changed, 18 insertions(+), 3 deletions(-)
24
2 files changed, 35 insertions(+), 1 deletion(-)
16
25
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
26
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
28
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
29
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
30
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
22
}
31
/* The elements of this array are the CCSIDR values for each cache,
32
* in the order L1DCache, L1ICache, L2DCache, L2ICache, etc.
33
*/
34
- uint32_t ccsidr[16];
35
+ uint64_t ccsidr[16];
36
uint64_t reset_cbar;
37
uint32_t reset_auxcr;
38
bool reset_hivecs;
39
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_ac2(const ARMISARegisters *id)
40
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, AC2) != 0;
23
}
41
}
24
42
25
+/*
43
+static inline bool isar_feature_aa32_ccidx(const ARMISARegisters *id)
26
+ * Return the MMU index for a v7M CPU with all relevant information
44
+{
27
+ * manually specified.
45
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, CCIDX) != 0;
28
+ */
46
+}
29
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
30
+ bool secstate, bool priv, bool negpri);
31
+
47
+
32
/* Return the MMU index for a v7M CPU in the specified security and
48
/*
33
* privilege state.
49
* 64-bit feature tests via id registers.
50
*/
51
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_rcpc_8_4(const ARMISARegisters *id)
52
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) >= 2;
53
}
54
55
+static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
56
+{
57
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
58
+}
59
+
60
/*
61
* Feature tests for "does this exist in either 32-bit or 64-bit?"
62
*/
63
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_pmu_8_4(const ARMISARegisters *id)
64
return isar_feature_aa64_pmu_8_4(id) || isar_feature_aa32_pmu_8_4(id);
65
}
66
67
+static inline bool isar_feature_any_ccidx(const ARMISARegisters *id)
68
+{
69
+ return isar_feature_aa64_ccidx(id) || isar_feature_aa32_ccidx(id);
70
+}
71
+
72
/*
73
* Forward to the above feature tests given an ARMCPU pointer.
34
*/
74
*/
35
diff --git a/target/arm/helper.c b/target/arm/helper.c
75
diff --git a/target/arm/helper.c b/target/arm/helper.c
36
index XXXXXXX..XXXXXXX 100644
76
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper.c
77
--- a/target/arm/helper.c
38
+++ b/target/arm/helper.c
78
+++ b/target/arm/helper.c
39
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
79
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo predinv_reginfo[] = {
40
return 0;
80
REGINFO_SENTINEL
41
}
81
};
42
82
43
-ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
83
+static uint64_t ccsidr2_read(CPUARMState *env, const ARMCPRegInfo *ri)
44
- bool secstate, bool priv)
45
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
46
+ bool secstate, bool priv, bool negpri)
47
{
48
ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
49
50
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
51
mmu_idx |= ARM_MMU_IDX_M_PRIV;
52
}
53
54
- if (armv7m_nvic_neg_prio_requested(env->nvic, secstate)) {
55
+ if (negpri) {
56
mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
57
}
58
59
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
60
return mmu_idx;
61
}
62
63
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
64
+ bool secstate, bool priv)
65
+{
84
+{
66
+ bool negpri = armv7m_nvic_neg_prio_requested(env->nvic, secstate);
85
+ /* Read the high 32 bits of the current CCSIDR */
67
+
86
+ return extract64(ccsidr_read(env, ri), 32, 32);
68
+ return arm_v7m_mmu_idx_all(env, secstate, priv, negpri);
69
+}
87
+}
70
+
88
+
71
/* Return the MMU index for a v7M CPU in the specified security state */
89
+static const ARMCPRegInfo ccsidr2_reginfo[] = {
72
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
90
+ { .name = "CCSIDR2", .state = ARM_CP_STATE_BOTH,
91
+ .opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 2,
92
+ .access = PL1_R,
93
+ .accessfn = access_aa64_tid2,
94
+ .readfn = ccsidr2_read, .type = ARM_CP_NO_RAW },
95
+ REGINFO_SENTINEL
96
+};
97
+
98
static CPAccessResult access_aa64_tid3(CPUARMState *env, const ARMCPRegInfo *ri,
99
bool isread)
73
{
100
{
101
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
102
define_arm_cp_regs(cpu, predinv_reginfo);
103
}
104
105
+ if (cpu_isar_feature(any_ccidx, cpu)) {
106
+ define_arm_cp_regs(cpu, ccsidr2_reginfo);
107
+ }
108
+
109
#ifndef CONFIG_USER_ONLY
110
/*
111
* Register redirections and aliases must be done last,
74
--
112
--
75
2.20.1
113
2.20.1
76
114
77
115
diff view generated by jsdifflib
1
The M-profile CONTROL register has two bits -- SFPA and FPCA --
1
In our KVM GICv2 realize function, we try to cope with old kernels
2
which relate to floating-point support, and should be RES0 otherwise.
2
that don't provide the device control API (KVM_CAP_DEVICE_CTRL): we
3
Handle them correctly in the MSR/MRS register access code.
3
try to use the device control, and if that fails we fall back to
4
Neither is banked between security states, so they are stored
4
assuming that the kernel has the old style KVM_CREATE_IRQCHIP and
5
in v7m.control[M_REG_S] regardless of current security state.
5
that it will provide a GICv2.
6
7
This doesn't cater for the possibility of a kernel and hardware which
8
only provide a GICv3, which is very common now. On that setup we
9
will abort() later on in kvm_arm_pmu_set_irq() when we try to wire up
10
an interrupt to the GIC we failed to create:
11
12
qemu-system-aarch64: PMU: KVM_SET_DEVICE_ATTR: Invalid argument
13
qemu-system-aarch64: failed to set irq for PMU
14
Aborted
15
16
If the kernel advertises KVM_CAP_DEVICE_CTRL we should trust it if it
17
says it can't create a GICv2, rather than assuming it has one. We
18
can then produce a more helpful error message including a hint about
19
the most probable reason for the failure.
20
21
If the kernel doesn't advertise KVM_CAP_DEVICE_CTRL then it is truly
22
ancient by this point but we might as well still fall back to a
23
KVM_CREATE_IRQCHIP GICv2.
24
25
With this patch then the user misconfiguration which previously
26
caused an abort now prints:
27
qemu-system-aarch64: Initialization of device kvm-arm-gic failed: error creating in-kernel VGIC: No such device
28
Perhaps the host CPU does not support GICv2?
6
29
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
31
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20190416125744.27770-9-peter.maydell@linaro.org
32
Reviewed-by: Andrew Jones <drjones@redhat.com>
33
Tested-by: Andrew Jones <drjones@redhat.com>
34
Message-id: 20200225182435.1131-1-peter.maydell@linaro.org
10
---
35
---
11
target/arm/helper.c | 57 ++++++++++++++++++++++++++++++++++++++-------
36
hw/intc/arm_gic_kvm.c | 9 +++++++++
12
1 file changed, 49 insertions(+), 8 deletions(-)
37
1 file changed, 9 insertions(+)
13
38
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
39
diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c
15
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
41
--- a/hw/intc/arm_gic_kvm.c
17
+++ b/target/arm/helper.c
42
+++ b/hw/intc/arm_gic_kvm.c
18
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
43
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
19
return xpsr_read(env) & mask;
44
KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true,
20
break;
45
&error_abort);
21
case 20: /* CONTROL */
22
- return env->v7m.control[env->v7m.secure];
23
+ {
24
+ uint32_t value = env->v7m.control[env->v7m.secure];
25
+ if (!env->v7m.secure) {
26
+ /* SFPA is RAZ/WI from NS; FPCA is stored in the M_REG_S bank */
27
+ value |= env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK;
28
+ }
29
+ return value;
30
+ }
31
case 0x94: /* CONTROL_NS */
32
/* We have to handle this here because unprivileged Secure code
33
* can read the NS CONTROL register.
34
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
35
if (!env->v7m.secure) {
36
return 0;
37
}
46
}
38
- return env->v7m.control[M_REG_NS];
47
+ } else if (kvm_check_extension(kvm_state, KVM_CAP_DEVICE_CTRL)) {
39
+ return env->v7m.control[M_REG_NS] |
48
+ error_setg_errno(errp, -ret, "error creating in-kernel VGIC");
40
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK);
49
+ error_append_hint(errp,
41
}
50
+ "Perhaps the host CPU does not support GICv2?\n");
42
51
} else if (ret != -ENODEV && ret != -ENOTSUP) {
43
if (el == 0) {
44
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
45
*/
46
uint32_t mask = extract32(maskreg, 8, 4);
47
uint32_t reg = extract32(maskreg, 0, 8);
48
+ int cur_el = arm_current_el(env);
49
50
- if (arm_current_el(env) == 0 && reg > 7) {
51
- /* only xPSR sub-fields may be written by unprivileged */
52
+ if (cur_el == 0 && reg > 7 && reg != 20) {
53
+ /*
52
+ /*
54
+ * only xPSR sub-fields and CONTROL.SFPA may be written by
53
+ * Very ancient kernel without KVM_CAP_DEVICE_CTRL: assume that
55
+ * unprivileged code
54
+ * ENODEV or ENOTSUP mean "can't create GICv2 with KVM_CREATE_DEVICE",
55
+ * and that we will get a GICv2 via KVM_CREATE_IRQCHIP.
56
+ */
56
+ */
57
error_setg_errno(errp, -ret, "error creating in-kernel VGIC");
57
return;
58
return;
58
}
59
}
59
60
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
61
env->v7m.control[M_REG_NS] &= ~R_V7M_CONTROL_NPRIV_MASK;
62
env->v7m.control[M_REG_NS] |= val & R_V7M_CONTROL_NPRIV_MASK;
63
}
64
+ /*
65
+ * SFPA is RAZ/WI from NS. FPCA is RO if NSACR.CP10 == 0,
66
+ * RES0 if the FPU is not present, and is stored in the S bank
67
+ */
68
+ if (arm_feature(env, ARM_FEATURE_VFP) &&
69
+ extract32(env->v7m.nsacr, 10, 1)) {
70
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
71
+ env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK;
72
+ }
73
return;
74
case 0x98: /* SP_NS */
75
{
76
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
77
env->v7m.faultmask[env->v7m.secure] = val & 1;
78
break;
79
case 20: /* CONTROL */
80
- /* Writing to the SPSEL bit only has an effect if we are in
81
+ /*
82
+ * Writing to the SPSEL bit only has an effect if we are in
83
* thread mode; other bits can be updated by any privileged code.
84
* write_v7m_control_spsel() deals with updating the SPSEL bit in
85
* env->v7m.control, so we only need update the others.
86
* For v7M, we must just ignore explicit writes to SPSEL in handler
87
* mode; for v8M the write is permitted but will have no effect.
88
+ * All these bits are writes-ignored from non-privileged code,
89
+ * except for SFPA.
90
*/
91
- if (arm_feature(env, ARM_FEATURE_V8) ||
92
- !arm_v7m_is_handler_mode(env)) {
93
+ if (cur_el > 0 && (arm_feature(env, ARM_FEATURE_V8) ||
94
+ !arm_v7m_is_handler_mode(env))) {
95
write_v7m_control_spsel(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 0);
96
}
97
- if (arm_feature(env, ARM_FEATURE_M_MAIN)) {
98
+ if (cur_el > 0 && arm_feature(env, ARM_FEATURE_M_MAIN)) {
99
env->v7m.control[env->v7m.secure] &= ~R_V7M_CONTROL_NPRIV_MASK;
100
env->v7m.control[env->v7m.secure] |= val & R_V7M_CONTROL_NPRIV_MASK;
101
}
102
+ if (arm_feature(env, ARM_FEATURE_VFP)) {
103
+ /*
104
+ * SFPA is RAZ/WI from NS or if no FPU.
105
+ * FPCA is RO if NSACR.CP10 == 0, RES0 if the FPU is not present.
106
+ * Both are stored in the S bank.
107
+ */
108
+ if (env->v7m.secure) {
109
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
110
+ env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_SFPA_MASK;
111
+ }
112
+ if (cur_el > 0 &&
113
+ (env->v7m.secure || !arm_feature(env, ARM_FEATURE_M_SECURITY) ||
114
+ extract32(env->v7m.nsacr, 10, 1))) {
115
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
116
+ env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK;
117
+ }
118
+ }
119
break;
120
default:
121
bad_reg:
122
--
60
--
123
2.20.1
61
2.20.1
124
62
125
63
diff view generated by jsdifflib
Deleted patch
1
Currently the code in v7m_push_stack() which detects a violation
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
1
10
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
---
14
target/arm/helper.c | 23 ++++++++++++++++++-----
15
1 file changed, 18 insertions(+), 5 deletions(-)
16
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
20
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
22
* should ignore further stack faults trying to process
23
* that derived exception.)
24
*/
25
- bool stacked_ok;
26
+ bool stacked_ok = true, limitviol = false;
27
CPUARMState *env = &cpu->env;
28
uint32_t xpsr = xpsr_read(env);
29
uint32_t frameptr = env->regs[13];
30
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
31
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
32
env->v7m.secure);
33
env->regs[13] = limit;
34
- return true;
35
+ /*
36
+ * We won't try to perform any further memory accesses but
37
+ * we must continue through the following code to check for
38
+ * permission faults during FPU state preservation, and we
39
+ * must update FPCCR if lazy stacking is enabled.
40
+ */
41
+ limitviol = true;
42
+ stacked_ok = false;
43
}
44
}
45
46
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
47
* (which may be taken in preference to the one we started with
48
* if it has higher priority).
49
*/
50
- stacked_ok =
51
+ stacked_ok = stacked_ok &&
52
v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, false) &&
53
v7m_stack_write(cpu, frameptr + 4, env->regs[1], mmu_idx, false) &&
54
v7m_stack_write(cpu, frameptr + 8, env->regs[2], mmu_idx, false) &&
55
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
56
v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
57
v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
58
59
- /* Update SP regardless of whether any of the stack accesses failed. */
60
- env->regs[13] = frameptr;
61
+ /*
62
+ * If we broke a stack limit then SP was already updated earlier;
63
+ * otherwise we update SP regardless of whether any of the stack
64
+ * accesses failed or we took some other kind of fault.
65
+ */
66
+ if (!limitviol) {
67
+ env->regs[13] = frameptr;
68
+ }
69
70
return !stacked_ok;
71
}
72
--
73
2.20.1
74
75
diff view generated by jsdifflib
Deleted patch
1
For v8M floating point support, transitions from Secure
2
to Non-secure state via BLNS and BLXNS must clear the
3
CONTROL.SFPA bit. (This corresponds to the pseudocode
4
BranchToNS() function.)
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-13-peter.maydell@linaro.org
9
---
10
target/arm/helper.c | 4 ++++
11
1 file changed, 4 insertions(+)
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest)
18
/* translate.c should have made BXNS UNDEF unless we're secure */
19
assert(env->v7m.secure);
20
21
+ if (!(dest & 1)) {
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
23
+ }
24
switch_v7m_security_state(env, dest & 1);
25
env->thumb = 1;
26
env->regs[15] = dest & ~1;
27
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
28
*/
29
write_v7m_exception(env, 1);
30
}
31
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
32
switch_v7m_security_state(env, 0);
33
env->thumb = 1;
34
env->regs[15] = dest;
35
--
36
2.20.1
37
38
diff view generated by jsdifflib
Deleted patch
1
The TailChain() pseudocode specifies that a tail chaining
2
exception should sanitize the excReturn all-ones bits and
3
(if there is no FPU) the excReturn FType bits; we weren't
4
doing this.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-14-peter.maydell@linaro.org
9
---
10
target/arm/helper.c | 8 ++++++++
11
1 file changed, 8 insertions(+)
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
18
qemu_log_mask(CPU_LOG_INT, "...taking pending %s exception %d\n",
19
targets_secure ? "secure" : "nonsecure", exc);
20
21
+ if (dotailchain) {
22
+ /* Sanitize LR FType and PREFIX bits */
23
+ if (!arm_feature(env, ARM_FEATURE_VFP)) {
24
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
25
+ }
26
+ lr = deposit32(lr, 24, 8, 0xff);
27
+ }
28
+
29
if (arm_feature(env, ARM_FEATURE_V8)) {
30
if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
31
(lr & R_V7M_EXCRET_S_MASK)) {
32
--
33
2.20.1
34
35
diff view generated by jsdifflib
Deleted patch
1
Pushing registers to the stack for v7M needs to handle three cases:
2
* the "normal" case where we pend exceptions
3
* an "ignore faults" case where we set FSR bits but
4
do not pend exceptions (this is used when we are
5
handling some kinds of derived exception on exception entry)
6
* a "lazy FP stacking" case, where different FSR bits
7
are set and the exception is pended differently
8
1
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
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20190416125744.27770-23-peter.maydell@linaro.org
16
---
17
target/arm/helper.c | 118 +++++++++++++++++++++++++++++---------------
18
1 file changed, 79 insertions(+), 39 deletions(-)
19
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
23
+++ b/target/arm/helper.c
24
@@ -XXX,XX +XXX,XX @@ static bool v7m_cpacr_pass(CPUARMState *env, bool is_secure, bool is_priv)
25
}
26
}
27
28
+/*
29
+ * What kind of stack write are we doing? This affects how exceptions
30
+ * generated during the stacking are treated.
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
{
42
CPUState *cs = CPU(cpu);
43
CPUARMState *env = &cpu->env;
44
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
45
&attrs, &prot, &page_size, &fi, NULL)) {
46
/* MPU/SAU lookup failed */
47
if (fi.type == ARMFault_QEMU_SFault) {
48
- qemu_log_mask(CPU_LOG_INT,
49
- "...SecureFault with SFSR.AUVIOL during stacking\n");
50
- env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK | R_V7M_SFSR_SFARVALID_MASK;
51
+ if (mode == STACK_LAZYFP) {
52
+ qemu_log_mask(CPU_LOG_INT,
53
+ "...SecureFault with SFSR.LSPERR "
54
+ "during lazy stacking\n");
55
+ env->v7m.sfsr |= R_V7M_SFSR_LSPERR_MASK;
56
+ } else {
57
+ qemu_log_mask(CPU_LOG_INT,
58
+ "...SecureFault with SFSR.AUVIOL "
59
+ "during stacking\n");
60
+ env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK;
61
+ }
62
+ env->v7m.sfsr |= R_V7M_SFSR_SFARVALID_MASK;
63
env->v7m.sfar = addr;
64
exc = ARMV7M_EXCP_SECURE;
65
exc_secure = false;
66
} else {
67
- qemu_log_mask(CPU_LOG_INT, "...MemManageFault with CFSR.MSTKERR\n");
68
- env->v7m.cfsr[secure] |= R_V7M_CFSR_MSTKERR_MASK;
69
+ if (mode == STACK_LAZYFP) {
70
+ qemu_log_mask(CPU_LOG_INT,
71
+ "...MemManageFault with CFSR.MLSPERR\n");
72
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MLSPERR_MASK;
73
+ } else {
74
+ qemu_log_mask(CPU_LOG_INT,
75
+ "...MemManageFault with CFSR.MSTKERR\n");
76
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MSTKERR_MASK;
77
+ }
78
exc = ARMV7M_EXCP_MEM;
79
exc_secure = secure;
80
}
81
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
82
attrs, &txres);
83
if (txres != MEMTX_OK) {
84
/* BusFault trying to write the data */
85
- qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.STKERR\n");
86
- env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_STKERR_MASK;
87
+ if (mode == STACK_LAZYFP) {
88
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.LSPERR\n");
89
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_LSPERR_MASK;
90
+ } else {
91
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.STKERR\n");
92
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_STKERR_MASK;
93
+ }
94
exc = ARMV7M_EXCP_BUS;
95
exc_secure = false;
96
goto pend_fault;
97
@@ -XXX,XX +XXX,XX @@ pend_fault:
98
* later if we have two derived exceptions.
99
* The only case when we must not pend the exception but instead
100
* throw it away is if we are doing the push of the callee registers
101
- * and we've already generated a derived exception. Even in this
102
- * case we will still update the fault status registers.
103
+ * and we've already generated a derived exception (this is indicated
104
+ * by the caller passing STACK_IGNFAULTS). Even in this case we will
105
+ * still update the fault status registers.
106
*/
107
- if (!ignfault) {
108
+ switch (mode) {
109
+ case STACK_NORMAL:
110
armv7m_nvic_set_pending_derived(env->nvic, exc, exc_secure);
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
--
209
2.20.1
210
211
diff view generated by jsdifflib